mirror of
https://github.com/mdbtools/mdbtools.git
synced 2026-03-10 00:20:54 +08:00
added man pages for utils.
lots of gmdb2 work. added statistics collection.
This commit is contained in:
@@ -20,7 +20,7 @@
|
||||
extern GtkWidget *app;
|
||||
extern MdbHandle *mdb;
|
||||
|
||||
GladeXML *debugwin_xml;
|
||||
GList *debug_list = NULL;
|
||||
|
||||
#define LINESZ 77
|
||||
|
||||
@@ -134,6 +134,88 @@ GtkWidget *textview;
|
||||
}
|
||||
}
|
||||
void
|
||||
gmdb_debug_jump_cb(GtkWidget *w, GladeXML *xml)
|
||||
{
|
||||
GtkTextView *textview;
|
||||
GtkTextMark *mark;
|
||||
GtkTextBuffer *txtbuffer;
|
||||
GtkTextIter start, end;
|
||||
GtkWidget *entry;
|
||||
gchar *text;
|
||||
gchar page[12];
|
||||
gchar digits[4][3];
|
||||
gchar *hex_digit;
|
||||
int i, num_digits = 0;
|
||||
|
||||
textview = (GtkTextView *) glade_xml_get_widget (xml, "debug_textview");
|
||||
txtbuffer = gtk_text_view_get_buffer(textview);
|
||||
if (!gtk_text_buffer_get_selection_bounds(txtbuffer, &start, &end)) {
|
||||
/* FIX ME -- replace with text in status bar */
|
||||
fprintf(stderr, "Nothing selected\n");
|
||||
return;
|
||||
}
|
||||
text = g_strdup(gtk_text_buffer_get_text(txtbuffer, &start, &end, FALSE));
|
||||
fprintf(stderr, "selected text = %s\n",text);
|
||||
hex_digit = strtok(text, " ");
|
||||
strcpy(page, "0x");
|
||||
do {
|
||||
if (strlen(hex_digit)>2) {
|
||||
fprintf(stderr, "Not a hex value\n");
|
||||
return;
|
||||
}
|
||||
strcpy(digits[num_digits++],hex_digit);
|
||||
} while (num_digits < 4 && (hex_digit = strtok(NULL," ")));
|
||||
for (i=num_digits-1;i>=0;i--) {
|
||||
strcat(page, digits[i]);
|
||||
}
|
||||
g_free(text);
|
||||
fprintf(stderr, "going to page %s\n",page);
|
||||
entry = glade_xml_get_widget (xml, "debug_entry");
|
||||
gtk_entry_set_text(GTK_ENTRY(entry),page);
|
||||
gmdb_debug_display_cb(w, xml);
|
||||
}
|
||||
void
|
||||
gmdb_debug_jump_msb_cb(GtkWidget *w, GladeXML *xml)
|
||||
{
|
||||
GtkTextView *textview;
|
||||
GtkTextMark *mark;
|
||||
GtkTextBuffer *txtbuffer;
|
||||
GtkTextIter start, end;
|
||||
GtkWidget *entry;
|
||||
gchar *text;
|
||||
gchar page[12];
|
||||
gchar digits[4][3];
|
||||
gchar *hex_digit;
|
||||
int i, num_digits = 0;
|
||||
|
||||
textview = (GtkTextView *) glade_xml_get_widget (xml, "debug_textview");
|
||||
txtbuffer = gtk_text_view_get_buffer(textview);
|
||||
if (!gtk_text_buffer_get_selection_bounds(txtbuffer, &start, &end)) {
|
||||
/* FIX ME -- replace with text in status bar */
|
||||
fprintf(stderr, "Nothing selected\n");
|
||||
return;
|
||||
}
|
||||
text = g_strdup(gtk_text_buffer_get_text(txtbuffer, &start, &end, FALSE));
|
||||
fprintf(stderr, "selected text = %s\n",text);
|
||||
hex_digit = strtok(text, " ");
|
||||
strcpy(page, "0x");
|
||||
do {
|
||||
if (strlen(hex_digit)>2) {
|
||||
fprintf(stderr, "Not a hex value\n");
|
||||
return;
|
||||
}
|
||||
strcpy(digits[num_digits++],hex_digit);
|
||||
} while (num_digits < 4 && (hex_digit = strtok(NULL," ")));
|
||||
for (i=0;i<num_digits;i++) {
|
||||
strcat(page, digits[i]);
|
||||
}
|
||||
g_free(text);
|
||||
fprintf(stderr, "going to page %s\n",page);
|
||||
entry = glade_xml_get_widget (xml, "debug_entry");
|
||||
gtk_entry_set_text(GTK_ENTRY(entry),page);
|
||||
gmdb_debug_display_cb(w, xml);
|
||||
}
|
||||
void
|
||||
gmdb_debug_display_cb(GtkWidget *w, GladeXML *xml)
|
||||
{
|
||||
int page;
|
||||
@@ -309,6 +391,37 @@ GtkCTreeNode *node;
|
||||
gmdb_debug_add_item(store, parent, str, offset+4, offset+7);
|
||||
}
|
||||
void
|
||||
gmdb_debug_dissect_index2(GtkTreeStore *store, GtkTreeIter *parent, char *fbuf, int offset)
|
||||
{
|
||||
gchar str[100];
|
||||
GtkCTreeNode *node;
|
||||
int mod=0;
|
||||
unsigned char flags;
|
||||
gchar flagstr[100]; /* If adding flags increase this */
|
||||
|
||||
snprintf(str, 100, "Column mask");
|
||||
gmdb_debug_add_item(store, parent, str, offset, offset+29);
|
||||
snprintf(str, 100, "Unknown");
|
||||
gmdb_debug_add_item(store, parent, str, offset+30, offset+33);
|
||||
snprintf(str, 100, "Root index page");
|
||||
gmdb_debug_add_item(store, parent, str, offset+34, offset+37);
|
||||
flags = fbuf[offset+38];
|
||||
if (flags & MDB_IDX_UNIQUE) {
|
||||
strcat(flagstr, "Unique"); mod++;
|
||||
}
|
||||
if (flags & MDB_IDX_IGNORENULLS) {
|
||||
if (mod) strcat(flagstr, ",");
|
||||
strcat(flagstr, "Ignore Nulls"); mod++;
|
||||
}
|
||||
if (flags & MDB_IDX_REQUIRED) {
|
||||
if (mod) strcat(flagstr, ",");
|
||||
strcat(flagstr, "Required");
|
||||
}
|
||||
if (!mod) strcpy(flagstr, "None");
|
||||
snprintf(str, 100, "Index Flags (%s)", flagstr);
|
||||
gmdb_debug_add_item(store, parent, str, offset+38, offset+38);
|
||||
}
|
||||
void
|
||||
gmdb_debug_add_page_ptr(GtkTreeStore *store, GtkTreeIter *parent, char *fbuf, const char *label, int offset)
|
||||
{
|
||||
gchar str[100];
|
||||
@@ -334,6 +447,7 @@ int i;
|
||||
snprintf(str, 100, "Num columns: %u", num_cols);
|
||||
gmdb_debug_add_item(store, parent, str, offset, offset);
|
||||
bitmask_sz = ((num_cols-1) / 8) + 1;
|
||||
printf("bitmask_sz %d\n", bitmask_sz);
|
||||
var_cols_loc = end - bitmask_sz;
|
||||
var_cols = fbuf[var_cols_loc];
|
||||
fixed_end = offset + fbuf[var_cols_loc - 1] - 1; /* work even if 0 b/c of EOD */
|
||||
@@ -357,6 +471,20 @@ int i;
|
||||
snprintf(str, 100, "Null mask");
|
||||
gmdb_debug_add_item(store, parent, str, var_cols_loc + 1, end);
|
||||
}
|
||||
void
|
||||
gmdb_debug_dissect_index_pg(GtkTreeStore *store, char *fbuf, int offset, int len)
|
||||
{
|
||||
gchar str[100];
|
||||
guint32 tdef;
|
||||
|
||||
snprintf(str, 100, "Page free space: %u",
|
||||
get_uint16(&fbuf[offset+2]));
|
||||
gmdb_debug_add_item(store, NULL, str, offset+2, offset+3);
|
||||
tdef = get_uint32(&fbuf[offset+4]);
|
||||
snprintf(str, 100, "Parents TDEF page: 0x%06x (%lu)", tdef,tdef);
|
||||
gmdb_debug_add_item(store, NULL, str, offset+4, offset+7);
|
||||
}
|
||||
|
||||
void
|
||||
gmdb_debug_dissect_leaf_pg(GtkTreeStore *store, char *fbuf, int offset, int len)
|
||||
{
|
||||
@@ -484,7 +612,7 @@ GtkTreeIter *node, *container;
|
||||
for (i=0;i<num_idx;i++) {
|
||||
snprintf(str, 100, "Index %d", i+1);
|
||||
node = gmdb_debug_add_item(store, container, str, newbase+(i*39), newbase+(i*39)+38);
|
||||
//gmdb_debug_dissect_index2(store, container, fbuf, newbase+(i*39));
|
||||
gmdb_debug_dissect_index2(store, node, fbuf, newbase+(i*39));
|
||||
}
|
||||
newbase += num_idx * 39;
|
||||
container = gmdb_debug_add_item(store, NULL, "Index definition 2", -1, -1);
|
||||
@@ -528,7 +656,7 @@ gchar str[100];
|
||||
gmdb_debug_dissect_tabledef_pg(store, fbuf, 0, len);
|
||||
break;
|
||||
case 0x03:
|
||||
//gmdb_debug_dissect_dbpage(store, fbuf, 1, len);
|
||||
gmdb_debug_dissect_index_pg(store, fbuf, 0, len);
|
||||
break;
|
||||
case 0x04:
|
||||
gmdb_debug_dissect_leaf_pg(store, fbuf, 0, len);
|
||||
@@ -623,9 +751,26 @@ void
|
||||
gmdb_debug_close_cb(GtkWidget *w, GladeXML *xml)
|
||||
{
|
||||
GtkWidget *win;
|
||||
|
||||
debug_list = g_list_remove(debug_list, xml);
|
||||
win = glade_xml_get_widget (xml, "debug_window");
|
||||
if (win) gtk_widget_destroy(win);
|
||||
return FALSE;
|
||||
}
|
||||
void
|
||||
gmdb_debug_close_all()
|
||||
{
|
||||
GladeXML *xml;
|
||||
GtkWidget *win;
|
||||
|
||||
while (xml = g_list_nth_data(debug_list, 0)) {
|
||||
printf("fetching %ld from list\n", xml);
|
||||
win = glade_xml_get_widget (xml, "debug_window");
|
||||
debug_list = g_list_remove(debug_list, xml);
|
||||
if (win) gtk_widget_destroy(win);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gmdb_debug_new_cb(GtkWidget *w, gpointer *data)
|
||||
{
|
||||
@@ -633,12 +778,15 @@ GtkTextView *textview;
|
||||
guint32 page;
|
||||
GtkWidget *entry, *mi, *button, *debugwin;
|
||||
gchar text[20];
|
||||
GladeXML *debugwin_xml;
|
||||
|
||||
/* load the interface */
|
||||
debugwin_xml = glade_xml_new("gladefiles/gmdb-debug.glade", NULL, NULL);
|
||||
/* connect the signals in the interface */
|
||||
glade_xml_signal_autoconnect(debugwin_xml);
|
||||
|
||||
debug_list = g_list_append(debug_list, debugwin_xml);
|
||||
|
||||
/* set signals with user data, anyone know how to do this in glade? */
|
||||
entry = glade_xml_get_widget (debugwin_xml, "debug_entry");
|
||||
g_signal_connect (G_OBJECT (entry), "activate",
|
||||
@@ -647,7 +795,22 @@ gchar text[20];
|
||||
mi = glade_xml_get_widget (debugwin_xml, "close_menu");
|
||||
g_signal_connect (G_OBJECT (mi), "activate",
|
||||
G_CALLBACK (gmdb_debug_close_cb), debugwin_xml);
|
||||
|
||||
button = glade_xml_get_widget (debugwin_xml, "close_button");
|
||||
g_signal_connect (G_OBJECT (button), "clicked",
|
||||
G_CALLBACK (gmdb_debug_close_cb), debugwin_xml);
|
||||
|
||||
mi = glade_xml_get_widget (debugwin_xml, "menu_page");
|
||||
g_signal_connect (G_OBJECT (mi), "activate",
|
||||
G_CALLBACK (gmdb_debug_jump_cb), debugwin_xml);
|
||||
mi = glade_xml_get_widget (debugwin_xml, "menu_page_msb");
|
||||
g_signal_connect (G_OBJECT (mi), "activate",
|
||||
G_CALLBACK (gmdb_debug_jump_msb_cb), debugwin_xml);
|
||||
|
||||
button = glade_xml_get_widget (debugwin_xml, "jump_button");
|
||||
g_signal_connect (G_OBJECT (button), "clicked",
|
||||
G_CALLBACK (gmdb_debug_jump_cb), debugwin_xml);
|
||||
|
||||
button = glade_xml_get_widget (debugwin_xml, "debug_button");
|
||||
g_signal_connect (G_OBJECT (button), "clicked",
|
||||
G_CALLBACK (gmdb_debug_display_cb), debugwin_xml);
|
||||
|
||||
@@ -156,4 +156,6 @@ void
|
||||
gmdb_file_close_cb(GtkWidget *button, gpointer data)
|
||||
{
|
||||
gmdb_reset_widgets();
|
||||
gmdb_debug_close_all();
|
||||
gmdb_sql_close_all();
|
||||
}
|
||||
|
||||
@@ -37,6 +37,22 @@
|
||||
<child>
|
||||
<widget class="GtkMenu" id="file1_menu">
|
||||
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="new1">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock_item">GNOMEUIINFO_MENU_NEW_ITEM</property>
|
||||
<property name="label" translatable="yes">_New</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="gmdb_debug_new_cb" last_modification_time="Fri, 03 Jan 2003 13:11:43 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkMenuItem" id="separator1">
|
||||
<property name="visible">True</property>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="close_menu">
|
||||
<property name="visible">True</property>
|
||||
@@ -48,6 +64,58 @@
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkMenuItem" id="view1">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock_item">GNOMEUIINFO_MENU_VIEW_TREE</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkMenu" id="view1_menu">
|
||||
|
||||
<child>
|
||||
<widget class="GtkMenuItem" id="menu_back">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">_Back</property>
|
||||
<property name="use_underline">True</property>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="menu_forward">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock_item">GNOMEUIINFO_MENU_NEW_ITEM</property>
|
||||
<property name="label" translatable="yes">_Forward</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="on_menu_forward_activate" last_modification_time="Fri, 03 Jan 2003 15:27:51 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkMenuItem" id="separator2">
|
||||
<property name="visible">True</property>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkMenuItem" id="menu_page">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">_Selected Page</property>
|
||||
<property name="use_underline">True</property>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkMenuItem" id="menu_page_msb">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Selected Page (_MSB)</property>
|
||||
<property name="use_underline">True</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkMenuItem" id="help1">
|
||||
<property name="visible">True</property>
|
||||
@@ -60,7 +128,7 @@
|
||||
<widget class="GtkImageMenuItem" id="about1">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock_item">GNOMEUIINFO_MENU_ABOUT_ITEM</property>
|
||||
<signal name="activate" handler="gmdb_about_cb" last_modification_time="Sat, 21 Dec 2002 18:17:10 GMT"/>
|
||||
<signal name="activate" handler="gmdb_about_cb" last_modification_time="Fri, 03 Jan 2003 13:11:09 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
@@ -79,6 +147,80 @@
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="BonoboDockItem" id="bonobodockitem2">
|
||||
<property name="visible">True</property>
|
||||
<property name="shadow_type">GTK_SHADOW_OUT</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkToolbar" id="toolbar1">
|
||||
<property name="border_width">1</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
|
||||
<property name="toolbar_style">GTK_TOOLBAR_ICONS</property>
|
||||
<property name="tooltips">True</property>
|
||||
|
||||
<child>
|
||||
<widget class="button" id="button4">
|
||||
<property name="visible">True</property>
|
||||
<property name="label">gtk-new</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="clicked" handler="gmdb_debug_new_cb" last_modification_time="Fri, 03 Jan 2003 13:12:52 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="button" id="back_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="tooltip" translatable="yes">New File</property>
|
||||
<property name="label">gtk-go-back</property>
|
||||
<property name="use_stock">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="new_group">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="button" id="forward_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="tooltip" translatable="yes">Open File</property>
|
||||
<property name="label">gtk-go-forward</property>
|
||||
<property name="use_stock">True</property>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="button" id="jump_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="label">gtk-jump-to</property>
|
||||
<property name="use_stock">True</property>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="button" id="close_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="tooltip" translatable="yes">Save File</property>
|
||||
<property name="label">gtk-close</property>
|
||||
<property name="use_stock">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="new_group">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="placement">BONOBO_DOCK_TOP</property>
|
||||
<property name="band">1</property>
|
||||
<property name="position">0</property>
|
||||
<property name="offset">0</property>
|
||||
<property name="behavior">BONOBO_DOCK_ITEM_BEH_EXCLUSIVE</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox1">
|
||||
<property name="visible">True</property>
|
||||
@@ -87,20 +229,19 @@
|
||||
|
||||
<child>
|
||||
<widget class="GtkFrame" id="frame1">
|
||||
<property name="border_width">8</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="label_yalign">0.5</property>
|
||||
<property name="shadow_type">GTK_SHADOW_NONE</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox3">
|
||||
<widget class="GtkHBox" id="hbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">12</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label3">
|
||||
<widget class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Page Number</property>
|
||||
<property name="use_underline">False</property>
|
||||
@@ -185,10 +326,35 @@
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox2">
|
||||
<widget class="GtkHPaned" id="hpaned1">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
<property name="can_focus">True</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkScrolledWindow" id="scrolledwindow1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="shadow_type">GTK_SHADOW_NONE</property>
|
||||
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkTreeView" id="debug_treeview">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="headers_visible">False</property>
|
||||
<property name="rules_hint">False</property>
|
||||
<property name="reorderable">False</property>
|
||||
<property name="enable_search">True</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="shrink">True</property>
|
||||
<property name="resize">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkScrolledWindow" id="scrolledwindow2">
|
||||
@@ -200,82 +366,26 @@
|
||||
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkViewport" id="viewport1">
|
||||
<widget class="GtkTextView" id="debug_textview">
|
||||
<property name="visible">True</property>
|
||||
<property name="shadow_type">GTK_SHADOW_IN</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkHPaned" id="hpaned1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkScrolledWindow" id="scrolledwindow3">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="shadow_type">GTK_SHADOW_NONE</property>
|
||||
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkTreeView" id="debug_treeview">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="headers_visible">False</property>
|
||||
<property name="rules_hint">False</property>
|
||||
<property name="reorderable">False</property>
|
||||
<property name="enable_search">True</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="shrink">True</property>
|
||||
<property name="resize">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkScrolledWindow" id="scrolledwindow4">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="shadow_type">GTK_SHADOW_NONE</property>
|
||||
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkTextView" id="debug_textview">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="editable">True</property>
|
||||
<property name="justification">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap_mode">GTK_WRAP_NONE</property>
|
||||
<property name="cursor_visible">True</property>
|
||||
<property name="pixels_above_lines">0</property>
|
||||
<property name="pixels_below_lines">0</property>
|
||||
<property name="pixels_inside_wrap">0</property>
|
||||
<property name="left_margin">0</property>
|
||||
<property name="right_margin">0</property>
|
||||
<property name="indent">0</property>
|
||||
<property name="text" translatable="yes"></property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="shrink">True</property>
|
||||
<property name="resize">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="editable">True</property>
|
||||
<property name="justification">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap_mode">GTK_WRAP_NONE</property>
|
||||
<property name="cursor_visible">True</property>
|
||||
<property name="pixels_above_lines">0</property>
|
||||
<property name="pixels_below_lines">0</property>
|
||||
<property name="pixels_inside_wrap">0</property>
|
||||
<property name="left_margin">0</property>
|
||||
<property name="right_margin">0</property>
|
||||
<property name="indent">0</property>
|
||||
<property name="text" translatable="yes"></property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="shrink">True</property>
|
||||
<property name="resize">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
@@ -30,8 +30,7 @@ typedef struct GMdbSQLWindow {
|
||||
GList *history;
|
||||
} GMdbSQLWindow;
|
||||
|
||||
GList *window_list;
|
||||
GladeXML *sqlwin_xml;
|
||||
GList *sql_list;
|
||||
|
||||
extern GtkWidget *app;
|
||||
extern MdbHandle *mdb;
|
||||
@@ -39,20 +38,25 @@ extern MdbSQL *sql;
|
||||
|
||||
void gmdb_sql_tree_populate(MdbHandle *mdb, GladeXML *xml);
|
||||
|
||||
/* callbacks */
|
||||
#if 0
|
||||
gint
|
||||
gmdb_sql_close_cb(GtkList *list, GtkWidget *w, GMdbSQLWindow *sqlwin)
|
||||
void
|
||||
gmdb_sql_close_all()
|
||||
{
|
||||
window_list = g_list_remove(window_list, sql);
|
||||
g_free(sql);
|
||||
return FALSE;
|
||||
GladeXML *xml;
|
||||
GtkWidget *win;
|
||||
|
||||
while (xml = g_list_nth_data(sql_list, 0)) {
|
||||
win = glade_xml_get_widget (xml, "sql_window");
|
||||
sql_list = g_list_remove(sql_list, xml);
|
||||
if (win) gtk_widget_destroy(win);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* callbacks */
|
||||
void
|
||||
gmdb_sql_close_cb(GtkWidget *w, GladeXML *xml)
|
||||
{
|
||||
GtkWidget *win;
|
||||
sql_list = g_list_remove(sql_list, xml);
|
||||
win = glade_xml_get_widget (xml, "sql_window");
|
||||
if (win) gtk_widget_destroy(win);
|
||||
}
|
||||
@@ -71,7 +75,7 @@ GtkTreeStore *store;
|
||||
GtkTreeView *tree;
|
||||
GtkTreeIter *iter, iter2;
|
||||
|
||||
tree = (GtkTreeView *) glade_xml_get_widget(sqlwin_xml, "sql_treeview");
|
||||
tree = (GtkTreeView *) glade_xml_get_widget(xml, "sql_treeview");
|
||||
select = gtk_tree_view_get_selection(GTK_TREE_VIEW (tree));
|
||||
store = (GtkTreeStore *) gtk_tree_view_get_model(tree);
|
||||
gtk_tree_selection_get_selected (select, NULL, &iter2);
|
||||
@@ -221,12 +225,15 @@ gmdb_sql_new_cb(GtkWidget *w, gpointer data)
|
||||
{
|
||||
GtkTargetEntry src;
|
||||
GtkWidget *mi, *but;
|
||||
GladeXML *sqlwin_xml;
|
||||
|
||||
/* load the interface */
|
||||
sqlwin_xml = glade_xml_new("gladefiles/gmdb-sql.glade", NULL, NULL);
|
||||
/* connect the signals in the interface */
|
||||
glade_xml_signal_autoconnect(sqlwin_xml);
|
||||
|
||||
sql_list = g_list_append(sql_list, sqlwin_xml);
|
||||
|
||||
mi = glade_xml_get_widget (sqlwin_xml, "close_menu");
|
||||
g_signal_connect (G_OBJECT (mi), "activate",
|
||||
G_CALLBACK (gmdb_sql_close_cb), sqlwin_xml);
|
||||
@@ -290,7 +297,7 @@ int i;
|
||||
MdbCatalogEntry *entry;
|
||||
GtkTreeIter *iter1, *iter2;
|
||||
|
||||
GtkWidget *tree = glade_xml_get_widget(sqlwin_xml, "sql_treeview");
|
||||
GtkWidget *tree = glade_xml_get_widget(xml, "sql_treeview");
|
||||
GtkTreeStore *store = (GtkTreeStore *) gtk_tree_view_get_model(GTK_TREE_VIEW(tree));
|
||||
|
||||
/* loop over each entry in the catalog */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
lib_LTLIBRARIES = libmdb.la
|
||||
libmdb_la_SOURCES= catalog.c mem.c file.c kkd.c table.c data.c dump.c backend.c money.c sargs.c index.c like.c write.c
|
||||
libmdb_la_SOURCES= catalog.c mem.c file.c kkd.c table.c data.c dump.c backend.c money.c sargs.c index.c like.c write.c stats.c
|
||||
INCLUDES = -I$(top_srcdir)/include $(GLIB_CFLAGS)
|
||||
LIBS = $(GLIB_LIBS)
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include "time.h"
|
||||
#include "math.h"
|
||||
|
||||
#define MDB_DEBUG_OLE 1
|
||||
|
||||
char *mdb_money_to_string(MdbHandle *mdb, int start, char *s);
|
||||
static int _mdb_attempt_bind(MdbHandle *mdb,
|
||||
MdbColumn *col, unsigned char isnull, int offset, int len);
|
||||
@@ -561,7 +563,7 @@ guint16 len, cur;
|
||||
ole_row = mdb->pg_buf[start+4];
|
||||
|
||||
lval_pg = mdb_get_int24(mdb, start+5);
|
||||
#if MDB_DEBUG
|
||||
#if MDB_DEBUG_OLE
|
||||
printf("Reading LVAL page %06x\n", lval_pg);
|
||||
#endif
|
||||
if(mdb_read_alt_pg(mdb, lval_pg) != mdb->fmt->pg_size) {
|
||||
@@ -576,7 +578,7 @@ guint16 len, cur;
|
||||
row_stop = mdb->fmt->pg_size - 1;
|
||||
}
|
||||
row_start = mdb_get_int16(mdb, 10 + ole_row * 2);
|
||||
#if MDB_DEBUG
|
||||
#if MDB_DEBUG_OLE
|
||||
printf("row num %d row start %d row stop %d\n", ole_row, row_start, row_stop);
|
||||
#endif
|
||||
len = row_stop - row_start;
|
||||
@@ -587,7 +589,7 @@ guint16 len, cur;
|
||||
} else if (ole_flags == 0x0000) {
|
||||
ole_row = mdb->pg_buf[start+4];
|
||||
lval_pg = mdb_get_int24(mdb, start+5);
|
||||
#if MDB_DEBUG
|
||||
#if MDB_DEBUG_OLE
|
||||
printf("Reading LVAL page %06x\n", lval_pg);
|
||||
#endif
|
||||
/* swap the alt and regular page buffers, so we can call get_int16 */
|
||||
@@ -604,7 +606,7 @@ guint16 len, cur;
|
||||
row_stop = mdb->fmt->pg_size - 1;
|
||||
}
|
||||
row_start = mdb_get_int16(mdb, 10 + ole_row * 2);
|
||||
#if MDB_DEBUG
|
||||
#if MDB_DEBUG_OLE
|
||||
printf("row num %d row start %d row stop %d\n", ole_row, row_start, row_stop);
|
||||
#endif
|
||||
len = row_stop - row_start;
|
||||
|
||||
@@ -51,6 +51,7 @@ int j,pos;
|
||||
/* fprintf(stderr,"Couldn't open file %s\n",filename); */
|
||||
return NULL;
|
||||
}
|
||||
mdb->f->refs++;
|
||||
if (!mdb_read_pg(mdb, 0)) {
|
||||
fprintf(stderr,"Couldn't read first page.\n");
|
||||
return NULL;
|
||||
@@ -87,9 +88,30 @@ MdbHandle *mdb_open(char *filename)
|
||||
void mdb_close(MdbHandle *mdb)
|
||||
{
|
||||
if (mdb->f) {
|
||||
mdb_free_file(mdb->f);
|
||||
mdb->f->refs--;
|
||||
if (mdb->f->refs<=0) mdb_free_file(mdb->f);
|
||||
}
|
||||
}
|
||||
MdbHandle *mdb_clone_handle(MdbHandle *mdb)
|
||||
{
|
||||
MdbHandle *newmdb;
|
||||
MdbCatalogEntry *entry;
|
||||
int i;
|
||||
|
||||
newmdb = mdb_alloc_handle();
|
||||
memcpy(newmdb, mdb, sizeof(MdbHandle));
|
||||
newmdb->stats = NULL;
|
||||
newmdb->catalog = g_array_new(FALSE,FALSE,sizeof(MdbCatalogEntry));
|
||||
for (i=0;i<mdb->num_catalog;i++) {
|
||||
entry = g_ptr_array_index(mdb->catalog,i);
|
||||
newmdb->catalog = g_array_append_val(newmdb->catalog, entry);
|
||||
}
|
||||
mdb->backend_name = NULL;
|
||||
if (mdb->f) {
|
||||
mdb->f->refs++;
|
||||
}
|
||||
return newmdb;
|
||||
}
|
||||
|
||||
/*
|
||||
** mdb_read a wrapper for read that bails if anything is wrong
|
||||
@@ -121,6 +143,9 @@ off_t offset = pg * mdb->fmt->pg_size;
|
||||
fprintf(stderr,"offset %lu is beyond EOF\n",offset);
|
||||
return 0;
|
||||
}
|
||||
if (mdb->stats && mdb->stats->collect)
|
||||
mdb->stats->pg_reads++;
|
||||
|
||||
lseek(mdb->f->fd, offset, SEEK_SET);
|
||||
len = read(mdb->f->fd,pg_buf,mdb->fmt->pg_size);
|
||||
if (len==-1) {
|
||||
@@ -166,6 +191,20 @@ int i;
|
||||
return i;
|
||||
|
||||
}
|
||||
gint32 mdb_get_int24_msb(MdbHandle *mdb, int offset)
|
||||
{
|
||||
gint32 l;
|
||||
unsigned char *c;
|
||||
|
||||
if (offset <0 || offset+3 > mdb->fmt->pg_size) return -1;
|
||||
c = &mdb->pg_buf[offset];
|
||||
l =c[0]; l<<=8;
|
||||
l+=c[1]; l<<=8;
|
||||
l+=c[2];
|
||||
|
||||
mdb->cur_pos+=3;
|
||||
return l;
|
||||
}
|
||||
gint32 mdb_get_int24(MdbHandle *mdb, int offset)
|
||||
{
|
||||
gint32 l;
|
||||
|
||||
@@ -126,7 +126,7 @@ int i;
|
||||
for (i=0;i<idx->num_keys;i++) {
|
||||
marker = mdb->pg_buf[cur_pos++];
|
||||
col=g_ptr_array_index(table->columns,idx->key_col_num[i]-1);
|
||||
printf("column %d coltype %d col_size %d\n",i,col->col_type, mdb_col_fixed_size(col));
|
||||
printf("column %d coltype %d col_size %d (%d)\n",i,col->col_type, mdb_col_fixed_size(col), col->col_size);
|
||||
}
|
||||
}
|
||||
void mdb_index_dump(MdbTableDef *table, MdbIndex *idx)
|
||||
|
||||
@@ -30,6 +30,16 @@ void mdb_exit()
|
||||
g_hash_table_destroy(mdb_backends);
|
||||
}
|
||||
|
||||
MdbStatistics *mdb_alloc_stats(MdbHandle *mdb)
|
||||
{
|
||||
mdb->stats = g_malloc0(sizeof(MdbStatistics));
|
||||
return mdb->stats;
|
||||
}
|
||||
void mdb_free_stats(MdbHandle *mdb)
|
||||
{
|
||||
g_free(mdb->stats);
|
||||
mdb->stats = NULL;
|
||||
}
|
||||
MdbFile *mdb_alloc_file()
|
||||
{
|
||||
MdbHandle *f;
|
||||
@@ -60,8 +70,9 @@ void mdb_free_handle(MdbHandle *mdb)
|
||||
{
|
||||
if (!mdb) return;
|
||||
|
||||
if (mdb->stats) mdb_free_stats(mdb);
|
||||
if (mdb->catalog) mdb_free_catalog(mdb);
|
||||
if (mdb->f) mdb_free_file(mdb->f);
|
||||
if (mdb->f && mdb->f->refs<=0) mdb_free_file(mdb->f);
|
||||
if (mdb->backend_name) free(mdb->backend_name);
|
||||
free(mdb);
|
||||
}
|
||||
|
||||
43
src/libmdb/stats.c
Normal file
43
src/libmdb/stats.c
Normal file
@@ -0,0 +1,43 @@
|
||||
/* MDB Tools - A library for reading MS Access database files
|
||||
* Copyright (C) 2000 Brian Bruns
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "mdbtools.h"
|
||||
|
||||
void
|
||||
mdb_stats_on(MdbHandle *mdb)
|
||||
{
|
||||
if (!mdb->stats)
|
||||
mdb_alloc_stats(mdb);
|
||||
|
||||
mdb->stats->collect = TRUE;
|
||||
}
|
||||
void
|
||||
mdb_stats_off(MdbHandle *mdb)
|
||||
{
|
||||
if (!mdb->stats) return;
|
||||
|
||||
mdb->stats->collect = FALSE;
|
||||
}
|
||||
void
|
||||
mdb_dump_stats(MdbHandle *mdb)
|
||||
{
|
||||
if (!mdb->stats) return;
|
||||
|
||||
fprintf(stdout, "Physical Page Reads: %lu\n", mdb->stats->pg_reads);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
bin_PROGRAMS = mdb-export mdb-array mdb-schema mdb-tables mdb-parsecsv mdb-header mdb-sql mdb-ver prtable prcat prdata prkkd prdump prole updrow
|
||||
bin_PROGRAMS = mdb-export mdb-array mdb-schema mdb-tables mdb-parsecsv mdb-header mdb-sql mdb-ver prtable prcat prdata prkkd prdump prole updrow prindex
|
||||
LIBS = $(GLIB_LIBS) $(READLINE_LIBS) @LEXLIB@
|
||||
INCLUDES = -I$(top_srcdir)/include $(GLIB_CFLAGS)
|
||||
LDADD = ../libmdb/libmdb.la
|
||||
|
||||
@@ -24,8 +24,16 @@
|
||||
#include <string.h>
|
||||
#include "mdbsql.h"
|
||||
|
||||
void dump_results(MdbSQL *sql);
|
||||
void dump_results_pp(MdbSQL *sql);
|
||||
|
||||
#if SQL
|
||||
|
||||
int headers = 1;
|
||||
int footers = 1;
|
||||
int pretty_print = 1;
|
||||
char *delimiter;
|
||||
|
||||
#ifndef HAVE_READLINE
|
||||
char *readline(char *prompt)
|
||||
{
|
||||
@@ -65,6 +73,166 @@ int parse(MdbSQL *sql, char *buf)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
do_set_cmd(MdbSQL *sql, char *s)
|
||||
{
|
||||
char *level1, *level2;
|
||||
level1 = strtok(s, " \t\n");
|
||||
if (!strcmp(level1,"stats")) {
|
||||
level2 = strtok(NULL, " \t");
|
||||
if (!strcmp(level2,"on")) {
|
||||
mdb_stats_on(sql->mdb);
|
||||
} else if (!strcmp(level2,"off")) {
|
||||
mdb_stats_off(sql->mdb);
|
||||
mdb_dump_stats(sql->mdb);
|
||||
} else {
|
||||
printf("Unknown stats option %s\n", level2);
|
||||
}
|
||||
} else {
|
||||
printf("Unknown set command %s\n", level1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
run_query(MdbSQL *sql, char *mybuf)
|
||||
{
|
||||
if (!parse(sql, mybuf) && sql->cur_table) {
|
||||
mdbsql_bind_all(sql);
|
||||
if (pretty_print)
|
||||
dump_results_pp(sql);
|
||||
else
|
||||
dump_results(sql);
|
||||
}
|
||||
}
|
||||
|
||||
void print_value(char *v, int sz, int first)
|
||||
{
|
||||
int i;
|
||||
int vlen;
|
||||
|
||||
if (first) {
|
||||
fprintf(stdout,"|");
|
||||
}
|
||||
vlen = strlen(v);
|
||||
for (i=0;i<sz;i++) {
|
||||
fprintf(stdout,"%c",i >= vlen ? ' ' : v[i]);
|
||||
}
|
||||
fprintf(stdout,"|");
|
||||
}
|
||||
static void print_break(int sz, int first)
|
||||
{
|
||||
int i;
|
||||
if (first) {
|
||||
fprintf(stdout,"+");
|
||||
}
|
||||
for (i=0;i<sz;i++) {
|
||||
fprintf(stdout,"-");
|
||||
}
|
||||
fprintf(stdout,"+");
|
||||
}
|
||||
void
|
||||
dump_results(MdbSQL *sql)
|
||||
{
|
||||
int j;
|
||||
MdbSQLColumn *sqlcol;
|
||||
unsigned long row_count = 0;
|
||||
|
||||
if (headers) {
|
||||
for (j=0;j<sql->num_columns-1;j++) {
|
||||
sqlcol = g_ptr_array_index(sql->columns,j);
|
||||
fprintf(stdout, "%s%s", sqlcol->name, delimiter);
|
||||
}
|
||||
sqlcol = g_ptr_array_index(sql->columns,sql->num_columns-1);
|
||||
fprintf(stdout, "%s", sqlcol->name);
|
||||
fprintf(stdout,"\n");
|
||||
}
|
||||
while(mdb_fetch_row(sql->cur_table)) {
|
||||
row_count++;
|
||||
for (j=0;j<sql->num_columns-1;j++) {
|
||||
sqlcol = g_ptr_array_index(sql->columns,j);
|
||||
fprintf(stdout, "%s%s", sql->bound_values[j], delimiter);
|
||||
}
|
||||
sqlcol = g_ptr_array_index(sql->columns,sql->num_columns-1);
|
||||
fprintf(stdout, "%s", sql->bound_values[sql->num_columns-1]);
|
||||
fprintf(stdout,"\n");
|
||||
}
|
||||
if (footers) {
|
||||
if (!row_count)
|
||||
fprintf(stdout, "No Rows retrieved\n");
|
||||
else if (row_count==1)
|
||||
fprintf(stdout, "1 Row retrieved\n");
|
||||
else
|
||||
fprintf(stdout, "%d Rows retrieved\n", row_count);
|
||||
}
|
||||
mdb_sql_reset(sql);
|
||||
}
|
||||
|
||||
void
|
||||
dump_results_pp(MdbSQL *sql)
|
||||
{
|
||||
int j;
|
||||
MdbSQLColumn *sqlcol;
|
||||
unsigned long row_count = 0;
|
||||
|
||||
/* print header */
|
||||
if (headers) {
|
||||
for (j=0;j<sql->num_columns;j++) {
|
||||
sqlcol = g_ptr_array_index(sql->columns,j);
|
||||
print_break(sqlcol->disp_size, !j);
|
||||
}
|
||||
fprintf(stdout,"\n");
|
||||
for (j=0;j<sql->num_columns;j++) {
|
||||
sqlcol = g_ptr_array_index(sql->columns,j);
|
||||
print_value(sqlcol->name,sqlcol->disp_size,!j);
|
||||
}
|
||||
fprintf(stdout,"\n");
|
||||
}
|
||||
|
||||
for (j=0;j<sql->num_columns;j++) {
|
||||
sqlcol = g_ptr_array_index(sql->columns,j);
|
||||
print_break(sqlcol->disp_size, !j);
|
||||
}
|
||||
fprintf(stdout,"\n");
|
||||
|
||||
/* print each row */
|
||||
while(mdb_fetch_row(sql->cur_table)) {
|
||||
row_count++;
|
||||
for (j=0;j<sql->num_columns;j++) {
|
||||
sqlcol = g_ptr_array_index(sql->columns,j);
|
||||
print_value(sql->bound_values[j],sqlcol->disp_size,!j);
|
||||
}
|
||||
fprintf(stdout,"\n");
|
||||
}
|
||||
|
||||
/* footer */
|
||||
for (j=0;j<sql->num_columns;j++) {
|
||||
sqlcol = g_ptr_array_index(sql->columns,j);
|
||||
print_break(sqlcol->disp_size, !j);
|
||||
}
|
||||
fprintf(stdout,"\n");
|
||||
if (footers) {
|
||||
if (!row_count)
|
||||
fprintf(stdout, "No Rows retrieved\n");
|
||||
else if (row_count==1)
|
||||
fprintf(stdout, "1 Row retrieved\n");
|
||||
else
|
||||
fprintf(stdout, "%d Rows retrieved\n", row_count);
|
||||
}
|
||||
|
||||
/* clean up */
|
||||
for (j=0;j<sql->num_columns;j++) {
|
||||
if (sql->bound_values[j]) free(sql->bound_values[j]);
|
||||
}
|
||||
|
||||
/* the column and table names are no good now */
|
||||
mdb_sql_reset(sql);
|
||||
}
|
||||
|
||||
void myexit(int r)
|
||||
{
|
||||
free(delimiter);
|
||||
exit(r);
|
||||
}
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
char *s;
|
||||
@@ -74,11 +242,54 @@ char *mybuf;
|
||||
int bufsz = 4096;
|
||||
int done = 0;
|
||||
MdbSQL *sql;
|
||||
int opt;
|
||||
FILE *in = NULL, *out = NULL;
|
||||
|
||||
|
||||
if (!isatty(fileno(stdin))) {
|
||||
in = stdin;
|
||||
}
|
||||
while ((opt=getopt(argc, argv, "hfpd:i:o:"))!=-1) {
|
||||
switch (opt) {
|
||||
case 'd':
|
||||
delimiter = malloc(strlen(optarg)+1);
|
||||
strcpy(delimiter, optarg);
|
||||
break;
|
||||
case 'p':
|
||||
pretty_print=0;
|
||||
break;
|
||||
case 'H':
|
||||
headers=0;
|
||||
break;
|
||||
case 'F':
|
||||
footers=0;
|
||||
break;
|
||||
case 'i':
|
||||
if (!strcmp(optarg, "stdin"))
|
||||
in = stdin;
|
||||
else if (!(in = fopen(optarg, "r"))) {
|
||||
fprintf(stderr,"Unable to open file %s\n", optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'o':
|
||||
if (!(out = fopen(optarg, "w"))) {
|
||||
fprintf(stderr,"Unable to open file %s\n", optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stdout,"Unknown option.\nUsage: %s [-HFp] [-d <delimiter>] [-i <file>] [-o <file>] [<database>]\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if (!delimiter) {
|
||||
delimiter = strdup("\t");
|
||||
}
|
||||
/* initialize the SQL engine */
|
||||
sql = mdb_sql_init();
|
||||
if (argc>1) {
|
||||
mdb_sql_open(sql, argv[1]);
|
||||
if (argc>optind) {
|
||||
mdb_sql_open(sql, argv[optind]);
|
||||
}
|
||||
|
||||
/* give the buffer an initial size */
|
||||
@@ -86,15 +297,20 @@ MdbSQL *sql;
|
||||
mybuf = (char *) malloc(bufsz);
|
||||
mybuf[0]='\0';
|
||||
|
||||
sprintf(prompt,"1 => ");
|
||||
s=readline(prompt);
|
||||
if (in) {
|
||||
s=malloc(256);
|
||||
if (!fgets(s, 256, in)) myexit(0);
|
||||
} else {
|
||||
sprintf(prompt,"1 => ");
|
||||
s=readline(prompt);
|
||||
}
|
||||
while (!done) {
|
||||
if (!strcmp(s,"go")) {
|
||||
if (line==1 && !strncmp(s,"set ", 4)) {
|
||||
do_set_cmd(sql, &s[4]);
|
||||
line = 0;
|
||||
if (!parse(sql, mybuf) && sql->cur_table) {
|
||||
mdbsql_bind_all(sql);
|
||||
mdbsql_dump_results(sql);
|
||||
}
|
||||
} else if (!strcmp(s,"go")) {
|
||||
line = 0;
|
||||
run_query(sql, mybuf);
|
||||
mybuf[0]='\0';
|
||||
} else if (!strcmp(s,"reset")) {
|
||||
line = 0;
|
||||
@@ -109,16 +325,27 @@ MdbSQL *sql;
|
||||
/* preserve line numbering for the parser */
|
||||
strcat(mybuf,"\n");
|
||||
}
|
||||
sprintf(prompt,"%d => ",++line);
|
||||
free(s);
|
||||
s=readline(prompt);
|
||||
if (in) {
|
||||
s=malloc(256);
|
||||
if (!fgets(s, 256, in)) {
|
||||
/* if we have something in the buffer, run it */
|
||||
if (strlen(mybuf))
|
||||
run_query(sql, mybuf);
|
||||
myexit(0);
|
||||
}
|
||||
if (s[strlen(s)-1]=='\n') s[strlen(s)-1]=0;
|
||||
} else {
|
||||
sprintf(prompt,"%d => ",++line);
|
||||
s=readline(prompt);
|
||||
}
|
||||
if (!strcmp(s,"exit") || !strcmp(s,"quit") || !strcmp(s,"bye")) {
|
||||
done = 1;
|
||||
}
|
||||
}
|
||||
mdb_sql_exit(sql);
|
||||
|
||||
exit(0);
|
||||
myexit(0);
|
||||
}
|
||||
#else
|
||||
int main(int argc, char **argv)
|
||||
|
||||
@@ -74,7 +74,7 @@ char *sargname = NULL;
|
||||
void dump_ole(MdbTableDef *table, char *colname, char *sargname)
|
||||
{
|
||||
int i, found = 0;
|
||||
char ole_data[12000];
|
||||
char ole_data[200000];
|
||||
int len;
|
||||
MdbColumn *col;
|
||||
MdbSarg sarg;
|
||||
|
||||
Reference in New Issue
Block a user