/* * dbMetrix Database Tool v0.1 * Copyright (c) 1998 David E. Storey * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include "config.h" #include "global.h" #define DBX_SOLID(conn) (dbx_Solid *)conn typedef struct { HENV henv; HDBC hdbc; HSTMT hstmt; char *dsn; char *user; char *pass; } dbx_Solid; /* prototypes */ void close_Solid(dataSource *dbconn); void create_Solid_addDialog(GtkWidget *dWindow, GtkWidget *notebook, int *curpage); void create_Solid_dsEntry(GtkWidget *widget); void error_Solid(dbx_Solid *conn); void init_Solid(void); void query_Solid(dataSource *conn, char *query); void refresh_Solid(GtkWidget *treeItem, gpointer data); void close_Solid(dataSource *dbconn) { dbx_Solid *conn = DBX_SOLID(dbconn->info); SQLDisconnect(conn->hdbc); SQLFreeConnect(conn->hdbc); SQLFreeEnv(conn->henv); g_free(conn->dsn); g_free(conn->user); g_free(conn->pass); } void create_Solid_addDialog(GtkWidget *dWindow, GtkWidget *notebook, int *curpage) { dbx_Dialog entries[] = { {"Data Source:", "Solid_DSN", FALSE}, {"Username:", "Solid_User", FALSE}, {"Password:", "Solid_Pass", TRUE}, }; create_dialogs(dWindow, notebook, curpage, Solid, "Solid", entries, sizeof(entries)/sizeof(entries[0])); } void create_Solid_dsEntry(GtkWidget *widget) { dbx_Solid *dbconn; char *dsn, *user, *pass; char name[256]; RETCODE rc; dsn = get_entry_text(widget, "Solid_DSN", FALSE); user = get_entry_text(widget, "Solid_User", FALSE); pass = get_entry_text(widget, "Solid_Pass", TRUE); if (!user || !pass) { s_print("You must provide a valid Username and Password for Solid"); /* otherwise, Solid will segfault, nice huh? */ return; } g_snprintf(name, 256, "solid://%s:%s", user, dsn); /* check for another entry in the same tree */ if (fetch_ds_key(name)) return; /* connect to server */ dbconn = DBX_SOLID(g_malloc(sizeof(dbx_Solid))); dbconn->henv = NULL; dbconn->hdbc = NULL; dbconn->hstmt = NULL; SQLAllocEnv(&dbconn->henv); error_Solid(dbconn); SQLAllocConnect(dbconn->henv, &dbconn->hdbc); error_Solid(dbconn); SQLSetConnectOption(dbconn->hdbc, SQL_TRANSLATE_OPTION, SQL_SOLID_XLATOPT_ANSI); error_Solid(dbconn); rc = SQLConnect(dbconn->hdbc, (UCHAR *)dsn, SQL_NTS, (UCHAR *)user, SQL_NTS, (UCHAR *)pass, SQL_NTS); if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) { dbconn->dsn = g_strdup(dsn); dbconn->user = g_strdup(user); dbconn->pass = g_strdup(pass); /* create tree Item */ ds_add(name, dbconn, Solid, Database); } else { error_Solid(dbconn); SQLFreeConnect(dbconn->hdbc); SQLFreeEnv(dbconn->henv); g_free(dbconn); } } void error_Solid(dbx_Solid *dbconn) { UCHAR SQLstate[256]; SDWORD errorcode; UCHAR errormsg[SQL_MAX_MESSAGE_LENGTH]; SWORD msglen; RETCODE rc; rc = SQLError(dbconn->henv, dbconn->hdbc, dbconn->hstmt, SQLstate, &errorcode, errormsg, SQL_MAX_MESSAGE_LENGTH - 1, &msglen); if (rc != SQL_NO_DATA_FOUND) s_print((char *)errormsg); } void query_Solid(dataSource *conn, char *query) { dbx_Solid *dbconn; HSTMT result; RETCODE rc; SWORD status; if (conn && query) dbconn = DBX_SOLID(conn->info); else return; status = SQLAllocStmt(dbconn->hdbc, &result); rc = SQLExecDirect(result, (UCHAR *)query, SQL_NTS); if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) { } } void refresh_Solid(GtkWidget *treeItem, gpointer data) { node_ds *nodeInfo = (node_ds *)data; dbx_Solid *dbconn = DBX_SOLID(nodeInfo->conn->info); RETCODE rc = SQL_ERROR; char szName[128] = {'\0'}; SDWORD cbName; rc = SQLAllocStmt(dbconn->hdbc, &dbconn->hstmt); if (rc == SQL_ERROR) return; switch(nodeInfo->type) { case Host: break; case Database: rc = SQLExecDirect(dbconn->hstmt, (UCHAR *)"SELECT TABLE_NAME FROM SYS_TABLES WHERE TABLE_SCHEMA != '_SYSTEM'", SQL_NTS); SQLBindCol(dbconn->hstmt, 1, SQL_C_CHAR, szName, 128, &cbName); break; case Table: if (!pref_get("dstree.table.show_fields")) break; rc = SQLColumns(dbconn->hstmt, (UCHAR *)NULL, 0, (UCHAR *)NULL, 0, (UCHAR *)nodeInfo->name, SQL_NTS, (UCHAR *)NULL, 0); SQLBindCol(dbconn->hstmt, 4, SQL_C_CHAR, szName, 128, &cbName); break; case Field: break; } if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) { int i = 0; while (1) { rc = SQLFetch(dbconn->hstmt); if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) { if (!GTK_TREE_ITEM_SUBTREE(treeItem)) add_subtree(treeItem); tree_refresh(treeItem, nodeInfo, i, szName); i++; /* this just about killed me! */ } else break; } } SQLFreeStmt(dbconn->hstmt, SQL_DROP); dbconn->hstmt = NULL; } void init_Solid(void) { dbxMenuEntry solidMenuDB[] = { {"disconnect", NULL, DBX_SIGNAL_FUNC(ds_close), (gpointer)TRUE} }; dsMenus[Solid].database = set_menu(solidMenuDB, sizeof(solidMenuDB)/sizeof(solidMenuDB[0])); dsFuncs[Solid].close = close_Solid; dsFuncs[Solid].create_dsEntry = create_Solid_dsEntry; dsFuncs[Solid].create_dsDialog = create_Solid_addDialog; dsFuncs[Solid].exec_query = query_Solid; dsFuncs[Solid].refresh = refresh_Solid; }