/* * 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 "config.h" #include "global.h" #define DBX_MSQL(conn) (dbx_mSQL *)conn typedef enum { DBX_MSQL_SHUTDOWN, DBX_MSQL_RELOADACLS, DBX_MSQL_TABLE_DELETE } dbx_mSQL_enums; typedef struct { int conn; char *host; } dbx_mSQL; /* prototypes */ void close_mSQL(dataSource *conn); int create_db_mSQL(dataSource *conn, char *database); int drop_db_mSQL(dataSource *conn, char *database); void refresh_mSQL(GtkWidget *treeItem, gpointer data); void create_mSQL_addDialog(GtkWidget *dWindow, GtkWidget *notebook, int *curpage); void create_mSQL_dsEntry(GtkWidget *widget); void query_mSQL(dataSource *conn, char *query); GtkWidget *result_mSQL(m_result *result, int nIdCOl, void(*cb)()); void init_mSQL(void); void close_mSQL(dataSource *conn) { dbx_mSQL *dbconn = DBX_MSQL(conn->info); msqlClose(dbconn->conn); g_free(dbconn->host); } int create_db_mSQL(dataSource *conn, char *database) { dbx_mSQL *dbconn = DBX_MSQL(conn->info); if (msqlCreateDB(dbconn->conn, database) < 0) { s_print(msqlErrMsg); return(FALSE); } return(TRUE); } void create_mSQL_addDialog(GtkWidget *dWindow, GtkWidget *notebook, int *curpage) { dbx_Dialog entries[] = { {"Host:", "mSQL_Host", FALSE} }; create_dialogs(dWindow, notebook, curpage, mSQL, "mSQL", entries, sizeof(entries)/sizeof(entries[0])); } void create_mSQL_dsEntry(GtkWidget *widget) { char *host, name[256]; dbx_mSQL *dbconn; host = get_entry_text(widget, "mSQL_Host", FALSE); g_snprintf(name, 256, "msql://%s", host ? host : "localhost"); /* check for another entry in the tree */ if (fetch_ds_key(name)) return; dbconn = DBX_MSQL(g_malloc(sizeof(dbx_mSQL))); /* connect to server */ if ((dbconn->conn = msqlConnect(host)) != -1) { dbconn->host = g_strdup(host); /* create tree Item */ ds_add(name, dbconn, mSQL, Host); } else { s_print(msqlErrMsg); g_free(dbconn); } } int drop_db_mSQL(dataSource *conn, char *database) { dbx_mSQL *dbconn = DBX_MSQL(conn->info); if (msqlDropDB(dbconn->conn, database) == -1) { s_print(msqlErrMsg); return(FALSE); } return(TRUE); } void misc_mSQL(GtkWidget *widget, gpointer data) { char message[256]; GtkWidget *treeItem = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(dbTree), "selected"); node_ds *nodeInfo = (node_ds *)gtk_object_get_data(GTK_OBJECT(treeItem), "info"); dbx_mSQL *dbconn = DBX_MSQL(nodeInfo->conn->info); switch((int)data) { case DBX_MSQL_SHUTDOWN: if (msqlShutdown(dbconn->conn) >= 0) ds_close(treeItem, treeItem); else s_print(msqlErrMsg); break; case DBX_MSQL_RELOADACLS: if(msqlReloadAcls(dbconn->conn) >= 0) { g_snprintf(message, 256, "Successfully reloaded ACL table for %s", nodeInfo->name); s_print(message); } else s_print(msqlErrMsg); break; case DBX_MSQL_TABLE_DELETE: if (msqlSelectDB(dbconn->conn, nodeInfo->parent->name) >= 0) { g_snprintf(message, 256, "DROP TABLE %s", nodeInfo->name); if (msqlQuery(dbconn->conn, message) >= 0) { g_snprintf(message, 256, "Table '%s', dropped", nodeInfo->name); s_print(message); ds_prune_tree((gpointer)treeItem, NULL); } else s_print(msqlErrMsg); } else s_print(msqlErrMsg); break; } } void properties_mSQL_host(GtkWidget *widget, gpointer data) { GtkWidget *frame; GtkWidget *notebook; GtkWidget *label; GtkWidget *tLayout; char protocol[256]; frame = new_dialog("mSQL Properties", "mSQL Server Properties"); notebook = gtk_notebook_new(); gtk_notebook_set_show_tabs(GTK_NOTEBOOK(notebook), TRUE); gtk_container_add(GTK_CONTAINER(frame), notebook); gtk_widget_show(notebook); tLayout = gtk_table_new(10, 2, FALSE); gtk_table_set_row_spacings(GTK_TABLE(tLayout), 1); gtk_table_set_col_spacings(GTK_TABLE(tLayout), 3); gtk_container_border_width(GTK_CONTAINER(tLayout), 4); label = gtk_label_new("Information"); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), tLayout, label); gtk_widget_show(tLayout); label = gtk_label_new("Host Info:"); gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); gtk_table_attach(GTK_TABLE(tLayout), label, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(label); label = gtk_label_new(msqlGetHostInfo()); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach(GTK_TABLE(tLayout), label, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(label); label = gtk_label_new("Server Info:"); gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); gtk_table_attach(GTK_TABLE(tLayout), label, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(label); label = gtk_label_new(msqlGetServerInfo()); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach(GTK_TABLE(tLayout), label, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(label); label = gtk_label_new("Protocol:"); gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); gtk_table_attach(GTK_TABLE(tLayout), label, 0, 1, 2, 3, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(label); g_snprintf(protocol, 256, "%d", msqlGetProtoInfo()); label = gtk_label_new(protocol); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach(GTK_TABLE(tLayout), label, 1, 2, 2, 3, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(label); } void query_mSQL(dataSource *conn, char *query) { dbx_mSQL *dbconn; m_result *result; if (conn && query) dbconn = DBX_MSQL(conn->info); else return; if (msqlQuery(dbconn->conn, query) == -1) { s_print(msqlErrMsg); return; } result = msqlStoreResult(); if (result) { query_window(result_mSQL(result, -1, NULL)); msqlFreeResult(result); } } void refresh_mSQL(GtkWidget *treeItem, gpointer data) { node_ds *nodeInfo = (node_ds *)data; dbx_mSQL *dbconn = DBX_MSQL(nodeInfo->conn->info); m_result *result = NULL; switch(nodeInfo->type) { case Host: result = msqlListDBs(dbconn->conn); break; case Database: if (msqlSelectDB(dbconn->conn, nodeInfo->name) == -1) break; result = msqlListTables(dbconn->conn); break; case Table: if (!pref_get("dstree.table.show_fields")) break; if (msqlSelectDB(dbconn->conn, nodeInfo->parent->name) == -1) break; result = msqlListFields(dbconn->conn, nodeInfo->name); break; case Field: break; } if (result) { int i; int n = nodeInfo->type == Table ? msqlNumFields(result) : msqlNumRows(result); if (n > 0) add_subtree(treeItem); for (i = 0; i < n; i++) { if (nodeInfo->type == Table) { m_field *field = msqlFetchField(result); tree_refresh(treeItem, nodeInfo, i, field->name); } else { m_row row = msqlFetchRow(result); tree_refresh(treeItem, nodeInfo, i, row[0]); } } msqlFreeResult(result); } } GtkWidget * result_mSQL(m_result *result, int nIdCol, void(*cb)()) { GtkWidget *clist; unsigned *maxflengths; int i, total = 0; if (!result || !msqlNumRows(result)) return(NULL); maxflengths = (unsigned *)calloc(msqlNumFields(result), sizeof(unsigned)); clist = gtk_clist_new(msqlNumFields(result)); for (i = 0; i < msqlNumFields(result); i++) { m_field *field = msqlFetchField(result); gtk_clist_set_column_title(GTK_CLIST(clist), i, field->name); maxflengths[i] = field->name ? strlen(field->name) : 0; } for (i = 0; i < msqlNumRows(result); i++) { m_row row = msqlFetchRow(result); int j; gtk_clist_append(GTK_CLIST(clist), row); if (nIdCol >= 0) gtk_clist_set_row_data(GTK_CLIST(clist), i, (gpointer)atol(row[nIdCol])); for (j = 0; j < msqlNumFields(result); j++) { int length = strlen(row[j]); if (length > maxflengths[j]) maxflengths[j] = length; } } for (i = 0; i < msqlNumFields(result); i++) { total += maxflengths[i] * 8; gtk_clist_set_column_width(GTK_CLIST(clist), i, maxflengths[i] * 8); } gtk_object_set_data(GTK_OBJECT(clist), "width", (gpointer)total); gtk_object_set_data(GTK_OBJECT(clist), "height", (gpointer)msqlNumRows(result)); free(maxflengths); return(clist); } void init_mSQL(void) { dbxMenuEntry msqlMenuHost[] = { {"create database", NULL, DBX_SIGNAL_FUNC(create_dbDialog), (gpointer)mSQL}, {"reload", NULL, DBX_SIGNAL_FUNC(misc_mSQL), (gpointer)DBX_MSQL_RELOADACLS}, {"shutdown", NULL, DBX_SIGNAL_FUNC(misc_mSQL), (gpointer)DBX_MSQL_SHUTDOWN}, {"disconnect", NULL, DBX_SIGNAL_FUNC(ds_close), (gpointer)TRUE}, {NULL, NULL, NULL, NULL}, {"properties...", NULL, DBX_SIGNAL_FUNC(properties_mSQL_host), NULL} }; dbxMenuEntry msqlMenuDB[] = { {"create table", NULL, NULL, NULL}, {"drop database", NULL, DBX_SIGNAL_FUNC(drop_db), (gpointer)mSQL} }; dbxMenuEntry msqlMenuTable[] = { {"delete", NULL, DBX_SIGNAL_FUNC(misc_mSQL), (gpointer)DBX_MSQL_TABLE_DELETE} }; dsMenus[mSQL].host = set_menu(msqlMenuHost, sizeof(msqlMenuHost)/sizeof(msqlMenuHost[0])); dsMenus[mSQL].database = set_menu(msqlMenuDB, sizeof(msqlMenuDB)/sizeof(msqlMenuDB[0])); dsMenus[mSQL].table = set_menu(msqlMenuTable, sizeof(msqlMenuTable)/sizeof(msqlMenuTable[0])); dsFuncs[mSQL].close = close_mSQL; dsFuncs[mSQL].create_db = create_db_mSQL; dsFuncs[mSQL].create_dsEntry = create_mSQL_dsEntry; dsFuncs[mSQL].create_dsDialog = create_mSQL_addDialog; dsFuncs[mSQL].drop_db = drop_db_mSQL; dsFuncs[mSQL].exec_query = query_mSQL; dsFuncs[mSQL].refresh = refresh_mSQL; }