mdbtools/src/gmdb2/sql.c

322 lines
9.2 KiB
C
Raw Normal View History

#include "gmdb.h"
#if SQL
typedef struct GMdbSQLWindow {
GtkWidget *window;
GtkWidget *textbox;
GtkWidget *combo;
GtkWidget *clist;
GtkWidget *scroll;
GtkWidget *ctree;
GtkCTreeNode *current_node;
GList *history;
} GMdbSQLWindow;
GList *window_list;
extern GtkWidget *app;
extern MdbHandle *mdb;
extern MdbSQL *sql;
GtkCTreeNode *gmdb_sql_ctree_populate(MdbHandle *mdb, GMdbSQLWindow *sqlwin);
/* callbacks */
gint
gmdb_sql_close(GtkList *list, GtkWidget *w, GMdbSQLWindow *sqlwin)
{
window_list = g_list_remove(window_list, sql);
g_free(sql);
return FALSE;
}
void
gmdb_sql_tree_select_cb(GtkCTree *tree, GList *node, gint column, GMdbSQLWindow *sqlwin)
{
sqlwin->current_node = node;
}
void
gmdb_sql_dnd_dataget_cb(
GtkWidget *w, GdkDragContext *dc,
GtkSelectionData *selection_data, guint info, guint t,
GMdbSQLWindow *sqlwin)
{
gchar tablename[256];
gchar *text[2];
gtk_ctree_get_node_info(GTK_CTREE(sqlwin->ctree), sqlwin->current_node, text, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
//strcpy(tablename, "Shippers");
gtk_selection_data_set(
selection_data,
GDK_SELECTION_TYPE_STRING,
8, /* 8 bits per character. */
text[0], strlen(text[0]));
}
void gmdb_sql_dnd_datareceived_cb(
GtkWidget *w,
GdkDragContext *dc,
gint x, gint y,
GtkSelectionData *selection_data,
guint info, guint t,
GMdbSQLWindow *sqlwin)
{
gchar *buf, *lastbuf;
GtkTextIter iter, start, end;
GtkTextBuffer *txtbuffer;
int len;
buf = selection_data->data;
txtbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(sqlwin->textbox));
if (gtk_text_buffer_get_char_count(txtbuffer)==0) {
gtk_text_buffer_get_iter_at_offset (txtbuffer, &iter, 0);
gtk_text_buffer_insert(txtbuffer, &iter, "select * from ", 14);
}
#if 0
len = gtk_text_buffer_get_char_count(txtbuffer);
gtk_text_buffer_get_iter_at_offset (txtbuffer, &end, len);
gtk_text_buffer_get_iter_at_offset (txtbuffer, &start, len - strlen(buf));
lastbuf = gtk_text_buffer_get_text(txtbuffer, &start, &end, FALSE);
printf("last buf %s\n", lastbuf);
if (strcmp(buf,lastbuf)) {
//gtk_text_buffer_insert_at_cursor(txtbuffer,buf,strlen(buf));
}
#endif
gtk_widget_grab_focus(GTK_WIDGET(sqlwin->textbox));
}
void
gmdb_sql_select_hist_cb(GtkList *list, GtkWidget *w, GMdbSQLWindow *sqlwin)
{
guint child_num;
gchar *buf;
GtkTextBuffer *txtbuffer;
child_num = gtk_list_child_position(list, w);
buf = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(sqlwin->combo)->entry));
txtbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(sqlwin->textbox));
gtk_text_buffer_set_text(txtbuffer, buf, strlen(buf));
}
void
gmdb_sql_execute_cb(GtkWidget *w, GMdbSQLWindow *sqlwin)
{
guint len;
gchar *buf;
gchar *bound_data[256];
int i;
MdbSQLColumn *sqlcol;
gchar *titles[256];
GtkTextBuffer *txtbuffer;
GtkTextIter start, end;
/* stuff this query on the history */
txtbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(sqlwin->textbox));
len = gtk_text_buffer_get_char_count(txtbuffer);
gtk_text_buffer_get_iter_at_offset (txtbuffer, &start, 0);
gtk_text_buffer_get_iter_at_offset (txtbuffer, &end, len);
buf = gtk_text_buffer_get_text(txtbuffer, &start, &end, FALSE);
sqlwin->history = g_list_prepend(sqlwin->history, g_strdup(buf));
gtk_combo_set_popdown_strings(GTK_COMBO(sqlwin->combo), sqlwin->history);
/* ok now execute it */
g_input_ptr = buf;
/* begin unsafe */
_mdb_sql(sql);
if (yyparse()) {
/* end unsafe */
gmdb_info_msg("Couldn't parse SQL");
mdb_sql_reset(sql);
return;
}
for (i=0;i<sql->num_columns;i++) {
bound_data[i] = (char *) malloc(MDB_BIND_SIZE);
bound_data[i][0] = '\0';
mdbsql_bind_column(sql, i+1, bound_data[i]);
sqlcol = g_ptr_array_index(sql->columns,i);
titles[i] = sqlcol->name;
}
if (sqlwin->clist) {
gtk_container_remove(GTK_CONTAINER(sqlwin->scroll), sqlwin->clist);
}
sqlwin->clist = gtk_clist_new_with_titles(sql->num_columns, titles);
gtk_container_add(GTK_CONTAINER(sqlwin->scroll),sqlwin->clist);
gtk_widget_show(sqlwin->clist);
while(mdb_fetch_row(sql->cur_table)) {
gtk_clist_append(GTK_CLIST(sqlwin->clist), bound_data);
}
/* free the memory used to bind */
for (i=0;i<sql->num_columns;i++) {
free(bound_data[i]);
}
mdb_sql_reset(sql);
g_free(buf);
}
void
gmdb_sql_new_window_cb(GtkWidget *w, gpointer data)
{
GtkWidget *hpane;
GtkWidget *vpane;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *scroll;
GtkWidget *button;
GtkWidget *frame1;
GtkTargetEntry src;
GMdbSQLWindow *sqlwin;
GtkWindow *txtbuffer;
GtkCTreeNode *node;
if (!mdb) {
gmdb_info_msg("No database is open.");
return;
}
sqlwin = g_malloc0(sizeof(GMdbSQLWindow));
sqlwin->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(sqlwin->window), "Query Tool");
gtk_widget_set_usize(sqlwin->window, 400,300);
gtk_widget_show(sqlwin->window);
gtk_signal_connect (GTK_OBJECT (sqlwin->window), "delete_event",
GTK_SIGNAL_FUNC (gmdb_sql_close), sqlwin);
vpane = gtk_vpaned_new();
gtk_widget_show(vpane);
gtk_paned_set_position(GTK_PANED(vpane), 100);
gtk_paned_set_gutter_size(GTK_PANED(vpane), 12);
gtk_container_add(GTK_CONTAINER(sqlwin->window), vpane);
hpane = gtk_hpaned_new();
gtk_widget_show(hpane);
gtk_paned_set_position(GTK_PANED(hpane), 100);
gtk_paned_set_gutter_size(GTK_PANED(hpane), 12);
gtk_container_add(GTK_CONTAINER(vpane), hpane);
scroll = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
gtk_widget_show (scroll);
gtk_container_add(GTK_CONTAINER(hpane), scroll);
sqlwin->ctree = gtk_ctree_new (1, 0);
gtk_widget_show (sqlwin->ctree);
gtk_container_add (GTK_CONTAINER (scroll), sqlwin->ctree);
gtk_signal_connect ( GTK_OBJECT (sqlwin->ctree),
"tree-select-row", GTK_SIGNAL_FUNC (gmdb_sql_tree_select_cb), sqlwin);
vbox = gtk_vbox_new(FALSE,0);
gtk_widget_show (vbox);
gtk_container_add(GTK_CONTAINER(hpane), vbox);
frame1 = gtk_frame_new (NULL);
gtk_frame_set_shadow_type(GTK_FRAME(frame1), GTK_SHADOW_IN);
gtk_widget_show (frame1);
gtk_box_pack_start (GTK_BOX (vbox), frame1, TRUE, TRUE, 0);
sqlwin->textbox = gtk_text_view_new();
gtk_widget_show (sqlwin->textbox);
gtk_container_add(GTK_CONTAINER(frame1), sqlwin->textbox);
#if 0
gtk_signal_connect ( GTK_OBJECT (sqlwin->textbox),
"activate", GTK_SIGNAL_FUNC (gmdb_sql_execute_cb), sqlwin);
#endif
hbox = gtk_hbox_new(FALSE,0);
gtk_widget_show (hbox);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
sqlwin->combo = gtk_combo_new();
gtk_widget_show (sqlwin->combo);
gtk_box_pack_start (GTK_BOX (hbox), sqlwin->combo, TRUE, TRUE, 0);
gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(sqlwin->combo)->entry), FALSE);
gtk_signal_connect ( GTK_OBJECT (GTK_COMBO(sqlwin->combo)->list),
"select-child", GTK_SIGNAL_FUNC (gmdb_sql_select_hist_cb), sqlwin);
button = gtk_button_new_with_label("Execute");
gtk_widget_show (button);
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 5);
gtk_signal_connect ( GTK_OBJECT (button),
"clicked", GTK_SIGNAL_FUNC (gmdb_sql_execute_cb), sqlwin);
sqlwin->scroll = gtk_scrolled_window_new(NULL,NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sqlwin->scroll),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_widget_show (sqlwin->scroll);
gtk_container_add(GTK_CONTAINER(vpane), sqlwin->scroll);
sqlwin->clist = gtk_clist_new(1);
gtk_widget_show(sqlwin->clist);
gtk_container_add(GTK_CONTAINER(sqlwin->scroll),sqlwin->clist);
/* populate first level of tree */
node = gmdb_sql_ctree_populate(mdb, sqlwin);
gtk_ctree_select(sqlwin->ctree, node);
src.target = "table";
src.flags = 0;
src.info = 1;
gtk_drag_source_set( sqlwin->ctree, GDK_BUTTON1_MASK, &src, 1, GDK_ACTION_COPY);
gtk_drag_dest_set( sqlwin->textbox,
//GTK_DEST_DEFAULT_MOTION |
GTK_DEST_DEFAULT_HIGHLIGHT ,
// GTK_DEST_DEFAULT_DROP,
&src, 1, GDK_ACTION_COPY | GDK_ACTION_MOVE);
gtk_signal_connect( GTK_OBJECT(sqlwin->ctree), "drag_data_get",
GTK_SIGNAL_FUNC(gmdb_sql_dnd_dataget_cb), sqlwin);
gtk_signal_connect( GTK_OBJECT(sqlwin->textbox), "drag_data_received",
GTK_SIGNAL_FUNC(gmdb_sql_dnd_datareceived_cb), sqlwin);
gtk_widget_grab_focus(GTK_WIDGET(sqlwin->textbox));
/* add this one to the window list */
window_list = g_list_append(window_list, sql);
}
/* functions */
GtkCTreeNode *
gmdb_sql_ctree_populate(MdbHandle *mdb, GMdbSQLWindow *sqlwin)
{
int i;
MdbCatalogEntry *entry;
gchar *text[2];
GtkCTreeNode *node, *first_node = NULL;
/* loop over each entry in the catalog */
for (i=0; i < mdb->num_catalog; i++) {
entry = g_ptr_array_index (mdb->catalog, i);
/* if it's a table */
if (entry->object_type == MDB_TABLE) {
/* skip the MSys tables */
if (strncmp (entry->object_name, "MSys", 4)) {
/* add table to tab */
text[0] = entry->object_name;
text[1] = "";
node = gtk_ctree_insert_node(GTK_CTREE(sqlwin->ctree), NULL, NULL, text, 0, NULL, NULL, NULL, NULL, FALSE, FALSE);
if (! first_node) first_node = node;
}
} /* if MDB_TABLE */
} /* for */
return first_node;
}
#else
void
gmdb_sql_new_window_cb(GtkWidget *w, gpointer data)
{
gmdb_info_msg("SQL support was not built in.\nRun configure with the --enable-sql option.");
}
#endif