diff --git a/include/mdbtools.h b/include/mdbtools.h index d5ce7dd..efc0900 100644 --- a/include/mdbtools.h +++ b/include/mdbtools.h @@ -168,6 +168,13 @@ enum { }; #define MDB_SHEXP_DEFAULT (MDB_SHEXP_CST_NOTNULL | MDB_SHEXP_COMMENTS | MDB_SHEXP_INDEXES | MDB_SHEXP_RELATIONS) +/* csv export binary options */ +enum { + MDB_BINEXPORT_STRIP, + MDB_BINEXPORT_RAW, + MDB_BINEXPORT_OCTAL +}; + #define IS_JET4(mdb) (mdb->f->jet_version==MDB_VER_JET4) /* obsolete */ #define IS_JET3(mdb) (mdb->f->jet_version==MDB_VER_JET3) diff --git a/src/gmdb2/gladefiles/gmdb-export.glade b/src/gmdb2/gladefiles/gmdb-export.glade index 062e46f..9e6ade5 100644 --- a/src/gmdb2/gladefiles/gmdb-export.glade +++ b/src/gmdb2/gladefiles/gmdb-export.glade @@ -57,34 +57,6 @@ - - - True - 0 - <b>Quotes:</b> - True - - - 3 - 4 - GTK_FILL - - - - - - True - 0 - <b>Quote Character:</b> - True - - - 4 - 5 - GTK_FILL - - - True @@ -140,18 +112,6 @@ 2 - - - True - - - - 1 - 2 - 3 - 4 - - True @@ -164,18 +124,6 @@ 3 - - - True - - - - 1 - 2 - 4 - 5 - - True @@ -202,6 +150,58 @@ 6 + + + True + 0 + <b>Quote Character:</b> + True + + + 3 + 4 + GTK_FILL + + + + + + True + + + + 1 + 2 + 3 + 4 + + + + + True + 0 + <b>Escape Character:</b> + True + + + 4 + 5 + GTK_FILL + + + + + + True + + + + 1 + 2 + 4 + 5 + + 2 diff --git a/src/gmdb2/gmdb.h b/src/gmdb2/gmdb.h index ec0c5d1..ae70227 100644 --- a/src/gmdb2/gmdb.h +++ b/src/gmdb2/gmdb.h @@ -81,16 +81,16 @@ void gmdb_table_init_popup (GtkWidget*); void gmdb_table_set_sensitive(gboolean b); /* table_export.c */ -void gmdb_export_help_cb(GtkWidget *w, gpointer data); -void gmdb_table_export_button_cb(GtkWidget *w, gpointer data); -void gmdb_print_quote(FILE *outfile, int need_quote, char quotechar, char *colsep, char *str); void gmdb_export_get_delimiter(GladeXML *xml, gchar *delimiter, int max_buf); void gmdb_export_get_lineterm(GladeXML *xml, gchar *lineterm, int max_buf); -int gmdb_export_get_quote(GladeXML *xml); -char gmdb_export_get_quotechar(GladeXML *xml); +void gmdb_export_get_quotechar(GladeXML *xml, gchar *quotechar, int max_buf); +void gmdb_export_get_escapechar(GladeXML *xml, gchar *escapechar, int max_buf); int gmdb_export_get_binmode(GladeXML *xml); int gmdb_export_get_headers(GladeXML *xml); gchar *gmdb_export_get_filepath(GladeXML *xml); +void gmdb_export_help_cb(GtkWidget *w, gpointer data); +void gmdb_print_col(FILE *outfile, gchar *col_val, int quote_text, int col_type, int bin_len, char *quote_char, char *escape_char, int bin_mode); +void gmdb_table_export_button_cb(GtkWidget *w, gpointer data); extern MdbSQL *sql; diff --git a/src/gmdb2/sql.c b/src/gmdb2/sql.c index db5e5e9..1a52a1c 100644 --- a/src/gmdb2/sql.c +++ b/src/gmdb2/sql.c @@ -51,35 +51,40 @@ gchar* gmdb_export_get_filepath (GladeXML*); /* from table_export.c */ static void gmdb_sql_write_rslt_cb(GtkWidget *w, GladeXML *xml) { + /* We need to re-run the whole query because some information is not stored + * in the TreeStore, such as column types. + */ gchar *file_path; GladeXML *sql_xml; GtkWidget *filesel, *dlg; FILE *outfile; int i; int need_headers = 0; - int need_quote = 0; gchar delimiter[11]; - gchar quotechar; - //TODO int binmode; + gchar quotechar[5]; + gchar escape_char[5]; + int bin_mode; gchar lineterm[5]; - gchar *str; - int rows=0, n_columns; - GtkWidget *treeview; - GtkTreeViewColumn *col; - GList *glist; - GtkTreeModel *store; - GtkTreeIter iter; - GValue value = { 0, }; - - filesel = glade_xml_get_widget (xml, "export_dialog"); - sql_xml = g_object_get_data(G_OBJECT(filesel), "sql_xml"); - //printf("sql_xml %p\n",sql_xml); - gmdb_export_get_delimiter(xml, delimiter, 10); - gmdb_export_get_lineterm(xml, lineterm, 5); - need_quote = gmdb_export_get_quote(xml); - quotechar = gmdb_export_get_quotechar(xml); - //TODO binmode = gmdb_export_get_binmode(xml); + guint len; + gchar *buf; + GtkTextIter start, end; + GtkTextBuffer *txtbuffer; + GtkWidget *textview; + char **bound_values; + int *bound_lens; + MdbSQLColumn *sqlcol; + long row; + char *value; + size_t length; + MdbTableDef *table; + MdbColumn *col = NULL; + + gmdb_export_get_delimiter(xml, delimiter, sizeof(delimiter)); + gmdb_export_get_lineterm(xml, lineterm, sizeof(lineterm)); + gmdb_export_get_quotechar(xml, quotechar, sizeof(quotechar)); + gmdb_export_get_escapechar(xml, escape_char, sizeof(escape_char)); + bin_mode = gmdb_export_get_binmode(xml); need_headers = gmdb_export_get_headers(xml); file_path = gmdb_export_get_filepath(xml); @@ -92,53 +97,104 @@ gmdb_sql_write_rslt_cb(GtkWidget *w, GladeXML *xml) return; } - treeview = glade_xml_get_widget (sql_xml, "sql_results"); - glist = gtk_tree_view_get_columns(GTK_TREE_VIEW(treeview)); - i = 0; - if (need_headers) { - while ((col = g_list_nth_data(glist, i))) { - gchar *title; - if (i>0) fputs(delimiter, outfile); - title = g_strdup(gtk_tree_view_column_get_title(col)); - gmdb_print_quote(outfile, need_quote, quotechar, - delimiter, title); - fputs(title, outfile); - gmdb_print_quote(outfile, need_quote, quotechar, - delimiter, title); - g_free(title); - i++; - } - fputs(lineterm, outfile); - g_list_free(glist); + /* Get SQL */ + filesel = glade_xml_get_widget (xml, "export_dialog"); + sql_xml = g_object_get_data(G_OBJECT(filesel), "sql_xml"); + //printf("sql_xml %p\n",sql_xml); + textview = glade_xml_get_widget(sql_xml, "sql_textview"); + txtbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)); + 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); + + + /* ok now execute it */ + mdb_sql_run_query(sql, buf); + if (mdb_sql_has_error(sql)) { + GtkWidget* dlg = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (w)), + GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE, + "%s", mdb_sql_last_error(sql)); + gtk_dialog_run (GTK_DIALOG (dlg)); + gtk_widget_destroy (dlg); + mdb_sql_reset(sql); + + fclose(outfile); + gtk_widget_destroy(filesel); + return; } - store = gtk_tree_view_get_model(GTK_TREE_VIEW(treeview)); - gtk_tree_model_get_iter_first(store, &iter); - rows=0; - g_value_init (&value, G_TYPE_STRING); - do { - rows++; - n_columns = gtk_tree_model_get_n_columns(store); - for (i=0; i < n_columns; i++) { - if (i>0) fputs(delimiter, outfile); - gtk_tree_model_get_value(store, &iter, i, &value); - str = (gchar *) g_value_get_string(&value); - gmdb_print_quote(outfile, need_quote, quotechar, delimiter, str); - fputs(str, outfile); - gmdb_print_quote(outfile, need_quote, quotechar, delimiter, str); - g_value_unset(&value); + bound_values = (char **) g_malloc(sql->num_columns * sizeof(char *)); + bound_lens = (int *) g_malloc(sql->num_columns * sizeof(int)); + + for (i=0; inum_columns; i++) { + /* bind columns */ + bound_values[i] = (char *) g_malloc0(MDB_BIND_SIZE); + mdb_sql_bind_column(sql, i+1, bound_values[i], &bound_lens[i]); + + /* display column titles */ + if (need_headers) { + if (i>0) + fputs(delimiter, outfile); + sqlcol = g_ptr_array_index(sql->columns,i); + gmdb_print_col(outfile, sqlcol->name, quotechar[0]!='\0', MDB_TEXT, 0, quotechar, escape_char, bin_mode); + } + } + + row = 0; + while (mdb_fetch_row(sql->cur_table)) { + row++; + for (i=0; inum_columns; i++) { + if (i>0) + fputs(delimiter, outfile); + + sqlcol = g_ptr_array_index(sql->columns, i); + + /* Find col matching sqlcol */ + table = sql->cur_table; + for (i=0; inum_cols; i++) { + col = g_ptr_array_index(table->columns, i); + if (!strcasecmp(sqlcol->name, col->name)) + break; + } + /* assert(i!=table->num_cols). Can't happen, already checked. */ + + /* Don't quote NULLs */ + if (bound_lens[i] && sqlcol->bind_type != MDB_OLE) { + if (col->col_type == MDB_OLE) { + value = mdb_ole_read_full(mdb, col, &length); + } else { + value = bound_values[i]; + length = bound_lens[i]; + } + gmdb_print_col(outfile, value, quotechar[0]!='\0', col->col_type, length, quotechar, escape_char, bin_mode); + if (col->col_type == MDB_OLE) + free(value); + } } fputs(lineterm, outfile); - } while (gtk_tree_model_iter_next(store, &iter)); + } + + /* free the memory used to bind */ + for (i=0; inum_columns; i++) { + g_free(bound_values[i]); + } + + mdb_sql_reset(sql); + g_free(buf); fclose(outfile); - gtk_widget_destroy(filesel); + dlg = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (w)), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE, - _("%d rows successfully exported."), rows); + _("%ld rows successfully exported."), row); gtk_dialog_run (GTK_DIALOG (dlg)); gtk_widget_destroy (dlg); + + gtk_widget_destroy(filesel); } + + static void gmdb_sql_results_cb(GtkWidget *w, GladeXML *xml) { @@ -337,6 +393,7 @@ gmdb_sql_select_hist_cb(GtkComboBox *combobox, GladeXML *xml) static void gmdb_sql_execute_cb(GtkWidget *w, GladeXML *xml) { + guint len; gchar *buf; gchar *bound_data[256]; @@ -364,7 +421,7 @@ gmdb_sql_execute_cb(GtkWidget *w, GladeXML *xml) textview = glade_xml_get_widget(xml, "sql_textview"); combobox = glade_xml_get_widget(xml, "sql_combo"); txtbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)); - len = gtk_text_buffer_get_char_count(txtbuffer); + 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); diff --git a/src/gmdb2/table_export.c b/src/gmdb2/table_export.c index eeaa784..0ebeb05 100644 --- a/src/gmdb2/table_export.c +++ b/src/gmdb2/table_export.c @@ -42,22 +42,12 @@ MdbCatalogEntry *cat_entry; #define NEVER "Never" #define AUTOMAT "Automatic (where necessary)" +#define NOQUOTE "Don't quote" + #define BIN_STRIP "Strip" #define BIN_RAW "Raw" #define BIN_OCTAL "Octal" -void -gmdb_print_quote(FILE *outfile, int need_quote, char quotechar, char *colsep, char *str) -{ - if (need_quote==1) { - fprintf(outfile, "%c", quotechar); - } else if (need_quote==-1) { - if (strstr(str,colsep)) { - fprintf(outfile, "%c", quotechar); - } - } -} - void gmdb_export_get_delimiter(GladeXML *xml, gchar *delimiter, int max_buf) { @@ -66,16 +56,22 @@ gmdb_export_get_delimiter(GladeXML *xml, gchar *delimiter, int max_buf) combobox = GTK_COMBO_BOX(glade_xml_get_widget(xml, "sep_combo")); str = gtk_combo_box_get_active_text(combobox); - if (!strcmp(str,COMMA)) { strcpy(delimiter, ","); } - else if (!strcmp(str,TAB)) { strcpy(delimiter, "\t"); } - else if (!strcmp(str,SPACE)) { strcpy(delimiter, " "); } - else if (!strcmp(str,COLON)) { strcpy(delimiter, ":"); } - else if (!strcmp(str,SEMICOLON)) { strcpy(delimiter, ";"); } - else if (!strcmp(str,PIPE)) { strcpy(delimiter, "|"); } - else { - strncpy(delimiter,str, 10); - delimiter[10]='\0'; - } + if (!strcmp(str,COMMA)) + strncpy(delimiter, ",", max_buf); + else if (!strcmp(str,TAB)) + strncpy(delimiter, "\t", max_buf); + else if (!strcmp(str,SPACE)) + strncpy(delimiter, " ", max_buf); + else if (!strcmp(str,COLON)) + strncpy(delimiter, ":", max_buf); + else if (!strcmp(str,SEMICOLON)) + strncpy(delimiter, ";", max_buf); + else if (!strcmp(str,PIPE)) + strncpy(delimiter, "|", max_buf); + else + strncpy(delimiter, str, max_buf); + if (max_buf) + delimiter[max_buf-1] = '\0'; } void @@ -86,39 +82,43 @@ gmdb_export_get_lineterm(GladeXML *xml, gchar *lineterm, int max_buf) combobox = GTK_COMBO_BOX(glade_xml_get_widget(xml, "term_combo")); str = gtk_combo_box_get_active_text (combobox); - if (!strcmp(str,LF)) { strcpy(lineterm, "\n"); } - else if (!strcmp(str,CR)) { strcpy(lineterm, "\r"); } - else if (!strcmp(str,CRLF)) { strcpy(lineterm, "\r\n"); } + if (!strcmp(str,LF)) + strncpy(lineterm, "\n", max_buf); + else if (!strcmp(str,CR)) + strncpy(lineterm, "\r", max_buf); + else if (!strcmp(str,CRLF)) + strncpy(lineterm, "\r\n", max_buf); + if (max_buf) + lineterm[max_buf-1] = '\0'; } -int -gmdb_export_get_quote(GladeXML *xml) -{ - GtkComboBox *combobox; - int need_quote = 0; - gchar *str; - - combobox = GTK_COMBO_BOX(glade_xml_get_widget(xml, "quote_combo")); - str = gtk_combo_box_get_active_text (combobox); - if (!strcmp(str,ALWAYS)) { need_quote = 1; } - else if (!strcmp(str,NEVER)) { need_quote = 0; } - else if (!strcmp(str,AUTOMAT)) { need_quote = -1; } - - return need_quote; -} - -char -gmdb_export_get_quotechar(GladeXML *xml) +void +gmdb_export_get_quotechar(GladeXML *xml, gchar *quotechar, int max_buf) { GtkComboBox *combobox; gchar *str; - char quotechar; combobox = GTK_COMBO_BOX(glade_xml_get_widget(xml, "qchar_combo")); str = gtk_combo_box_get_active_text (combobox); - quotechar = str[0]; + if (!strcmp(str, NOQUOTE)) + quotechar[0] = '\0'; /* Quoting disabled */ + else + strncpy(quotechar, str, max_buf); + if (max_buf) + quotechar[max_buf-1] = '\0'; +} - return quotechar; +void +gmdb_export_get_escapechar(GladeXML *xml, gchar *escapechar, int max_buf) +{ + GtkComboBox *combobox; + gchar *str; + + combobox = GTK_COMBO_BOX(glade_xml_get_widget(xml, "escchar_combo")); + str = gtk_combo_box_get_active_text (combobox); + strncpy(escapechar, str, max_buf); + if (max_buf) + escapechar[max_buf-1] = '\0'; } int @@ -130,9 +130,12 @@ gmdb_export_get_binmode(GladeXML *xml) combobox = GTK_COMBO_BOX(glade_xml_get_widget(xml, "bin_combo")); str = gtk_combo_box_get_active_text (combobox); - if (!strcmp(str,BIN_STRIP)) return 1; - else if (!strcmp(str,BIN_OCTAL)) return 2; - else return 0; + if (!strcmp(str,BIN_STRIP)) + return MDB_BINEXPORT_STRIP; + else if (!strcmp(str,BIN_OCTAL)) + return MDB_BINEXPORT_OCTAL; + else + return MDB_BINEXPORT_RAW; } @@ -167,31 +170,83 @@ gmdb_export_help_cb(GtkWidget *w, gpointer data) g_error_free (error); } } + +/* That function is a duplicate of the one in util/mdb-export.c + * They should be merged and moved in libmdb (backend.c) + */ +#define is_quote_type(x) (x==MDB_TEXT || x==MDB_OLE || x==MDB_MEMO || x==MDB_DATETIME || x==MDB_BINARY || x==MDB_REPID) +#define is_binary_type(x) (x==MDB_OLE || x==MDB_BINARY || x==MDB_REPID) +//#define DONT_ESCAPE_ESCAPE +void +gmdb_print_col(FILE *outfile, gchar *col_val, int quote_text, int col_type, int bin_len, char *quote_char, char *escape_char, int bin_mode) +{ + size_t quote_len = strlen(quote_char); /* multibyte */ + + size_t orig_escape_len = escape_char ? strlen(escape_char) : 0; + + /* double the quote char if no escape char passed */ + if (!escape_char) + escape_char = quote_char; + + if (quote_text && is_quote_type(col_type)) { + fputs(quote_char, outfile); + while (1) { + if (is_binary_type(col_type)) { + if (bin_mode == MDB_BINEXPORT_STRIP) + break; + if (!bin_len--) + break; + } else /* use \0 sentry */ + if (!*col_val) + break; + + if (quote_len && !strncmp(col_val, quote_char, quote_len)) { + fprintf(outfile, "%s%s", escape_char, quote_char); + col_val += quote_len; +#ifndef DONT_ESCAPE_ESCAPE + } else if (orig_escape_len && !strncmp(col_val, escape_char, orig_escape_len)) { + fprintf(outfile, "%s%s", escape_char, escape_char); + col_val += orig_escape_len; +#endif + } else if (is_binary_type(col_type) && *col_val <= 0 && bin_mode == MDB_BINEXPORT_OCTAL) + fprintf(outfile, "\\%03o", *(unsigned char*)col_val++); + else + putc(*col_val++, outfile); + } + fputs(quote_char, outfile); + } else + fputs(col_val, outfile); +} + + void gmdb_table_export_button_cb(GtkWidget *w, gpointer data) { gchar *file_path; FILE *outfile; -gchar *bound_data[256]; +char **bound_values; +int *bound_lens; MdbTableDef *table; MdbColumn *col; int i; int need_headers = 0; -int need_quote = 0; gchar delimiter[11]; -gchar quotechar; +gchar quotechar[5]; +gchar escape_char[5]; gchar lineterm[5]; -int binmode = 1; +int bin_mode = MDB_BINEXPORT_RAW; int rows=0; +char *value; +size_t length; GtkWidget *exportwin, *dlg; - gmdb_export_get_delimiter(exportwin_xml, delimiter, 10); - gmdb_export_get_lineterm(exportwin_xml, lineterm, 5); - need_quote = gmdb_export_get_quote(exportwin_xml); - quotechar = gmdb_export_get_quotechar(exportwin_xml); + gmdb_export_get_delimiter(exportwin_xml, delimiter, sizeof(delimiter)); + gmdb_export_get_lineterm(exportwin_xml, lineterm, sizeof(lineterm)); + gmdb_export_get_quotechar(exportwin_xml, quotechar, sizeof(quotechar)); + gmdb_export_get_escapechar(exportwin_xml, escape_char, sizeof(escape_char)); need_headers = gmdb_export_get_headers(exportwin_xml); - binmode = gmdb_export_get_binmode(exportwin_xml); + bin_mode = gmdb_export_get_binmode(exportwin_xml); file_path = gmdb_export_get_filepath(exportwin_xml); // printf("file path %s\n",file_path); @@ -209,18 +264,19 @@ int rows=0; mdb_read_columns(table); mdb_rewind_table(table); + bound_values = (char **) g_malloc(table->num_cols * sizeof(char *)); + bound_lens = (int *) g_malloc(table->num_cols * sizeof(int)); for (i=0;inum_cols;i++) { /* bind columns */ - bound_data[i] = (char *) g_malloc0(MDB_BIND_SIZE); - mdb_bind_column(table, i+1, bound_data[i], NULL); + bound_values[i] = (char *) g_malloc0(MDB_BIND_SIZE); + mdb_bind_column(table, i+1, bound_values[i], &bound_lens[i]); /* display column titles */ - col=g_ptr_array_index(table->columns,i); - if (need_headers) { - if (i>0) fputs(delimiter, outfile); - gmdb_print_quote(outfile, need_quote, quotechar, delimiter, col->name); - fputs(col->name, outfile); - gmdb_print_quote(outfile, need_quote, quotechar, delimiter, col->name); + if (need_headers) { + if (i>0) + fputs(delimiter, outfile); + col=g_ptr_array_index(table->columns,i); + gmdb_print_col(outfile, col->name, quotechar[0]!='\0', MDB_TEXT, 0, quotechar, escape_char, bin_mode); } } if (need_headers) fputs(lineterm, outfile); @@ -228,10 +284,21 @@ int rows=0; /* fetch those rows! */ while(mdb_fetch_row(table)) { for (i=0;inum_cols;i++) { - if (i>0) fputs(delimiter, outfile); - gmdb_print_quote(outfile, need_quote, quotechar, delimiter, bound_data[i]); - fputs(bound_data[i], outfile); - gmdb_print_quote(outfile, need_quote, quotechar, delimiter, bound_data[i]); + if (i>0) + fputs(delimiter, outfile); + col=g_ptr_array_index(table->columns,i); + /* Don't quote NULLs */ + if (bound_lens[i]) { + if (col->col_type == MDB_OLE) { + value = mdb_ole_read_full(mdb, col, &length); + } else { + value = bound_values[i]; + length = bound_lens[i]; + } + gmdb_print_col(outfile, value, quotechar[0]!='\0', col->col_type, length, quotechar, escape_char, bin_mode); + if (col->col_type == MDB_OLE) + free(value); + } } fputs(lineterm, outfile); rows++; @@ -239,8 +306,10 @@ int rows=0; /* free the memory used to bind */ for (i=0;inum_cols;i++) { - g_free(bound_data[i]); + g_free(bound_values[i]); } + g_free(bound_values); + g_free(bound_lens); fclose(outfile); exportwin = glade_xml_get_widget (exportwin_xml, "export_dialog"); @@ -282,16 +351,15 @@ gmdb_table_export_populate_dialog(GladeXML *xml) gtk_combo_box_append_text(combobox, PIPE); gtk_combo_box_set_active(combobox, 0); - combobox = GTK_COMBO_BOX(glade_xml_get_widget(xml, "quote_combo")); - gtk_combo_box_append_text(combobox, ALWAYS); - gtk_combo_box_append_text(combobox, NEVER); - gtk_combo_box_append_text(combobox, AUTOMAT); - gtk_combo_box_set_active(combobox, 0); - combobox = GTK_COMBO_BOX(glade_xml_get_widget(xml, "qchar_combo")); gtk_combo_box_append_text(combobox, "\""); gtk_combo_box_append_text(combobox, "'"); gtk_combo_box_append_text(combobox, "`"); + gtk_combo_box_append_text(combobox, NOQUOTE); + gtk_combo_box_set_active(combobox, 0); + + combobox = GTK_COMBO_BOX(glade_xml_get_widget(xml, "escchar_combo")); + gtk_combo_box_append_text(combobox, "\\"); gtk_combo_box_set_active(combobox, 0); combobox = GTK_COMBO_BOX(glade_xml_get_widget(xml, "bin_combo")); diff --git a/src/util/mdb-export.c b/src/util/mdb-export.c index 09d1560..1487a78 100644 --- a/src/util/mdb-export.c +++ b/src/util/mdb-export.c @@ -28,15 +28,13 @@ #define is_quote_type(x) (x==MDB_TEXT || x==MDB_OLE || x==MDB_MEMO || x==MDB_DATETIME || x==MDB_BINARY || x==MDB_REPID) #define is_binary_type(x) (x==MDB_OLE || x==MDB_BINARY || x==MDB_REPID) -#define BIN_MODE_STRIP 0 -#define BIN_MODE_RAW 1 -#define BIN_MODE_OCTAL 2 - static char *escapes(char *s); //#define DONT_ESCAPE_ESCAPE static void print_col(FILE *outfile, gchar *col_val, int quote_text, int col_type, int bin_len, char *quote_char, char *escape_char, int bin_mode) +/* quote_text: Don't quote if 0. + */ { size_t quote_len = strlen(quote_char); /* multibyte */ @@ -50,7 +48,7 @@ print_col(FILE *outfile, gchar *col_val, int quote_text, int col_type, int bin_l fputs(quote_char, outfile); while (1) { if (is_binary_type(col_type)) { - if (bin_mode == BIN_MODE_STRIP) + if (bin_mode == MDB_BINEXPORT_STRIP) break; if (!bin_len--) break; @@ -66,7 +64,7 @@ print_col(FILE *outfile, gchar *col_val, int quote_text, int col_type, int bin_l fprintf(outfile, "%s%s", escape_char, escape_char); col_val += orig_escape_len; #endif - } else if (is_binary_type(col_type) && *col_val <= 0 && bin_mode == BIN_MODE_OCTAL) + } else if (is_binary_type(col_type) && *col_val <= 0 && bin_mode == MDB_BINEXPORT_OCTAL) fprintf(outfile, "\\%03o", *(unsigned char*)col_val++); else putc(*col_val++, outfile); @@ -78,12 +76,13 @@ print_col(FILE *outfile, gchar *col_val, int quote_text, int col_type, int bin_l int main(int argc, char **argv) { - unsigned int j; + unsigned int i; MdbHandle *mdb; MdbTableDef *table; MdbColumn *col; char **bound_values; int *bound_lens; + FILE *outfile = stdout; char *delimiter = NULL; char *row_delimiter = NULL; char *quote_char = NULL; @@ -92,7 +91,7 @@ main(int argc, char **argv) char quote_text = 1; char *insert_dialect = NULL; char *namespace = NULL; - int bin_mode = BIN_MODE_RAW; + int bin_mode = MDB_BINEXPORT_RAW; int opt; char *value; size_t length; @@ -129,11 +128,11 @@ main(int argc, char **argv) break; case 'b': if (!strcmp(optarg, "strip")) - bin_mode = BIN_MODE_STRIP; + bin_mode = MDB_BINEXPORT_STRIP; else if (!strcmp(optarg, "raw")) - bin_mode = BIN_MODE_RAW; + bin_mode = MDB_BINEXPORT_RAW; else if (!strcmp(optarg, "octal")) - bin_mode = BIN_MODE_OCTAL; + bin_mode = MDB_BINEXPORT_OCTAL; else { fprintf(stderr, "Invalid binary mode\n"); exit(1); @@ -203,23 +202,25 @@ main(int argc, char **argv) exit(1); } + /* read table */ mdb_read_columns(table); mdb_rewind_table(table); bound_values = (char **) g_malloc(table->num_cols * sizeof(char *)); bound_lens = (int *) g_malloc(table->num_cols * sizeof(int)); - for (j=0;jnum_cols;j++) { - bound_values[j] = (char *) g_malloc0(MDB_BIND_SIZE); - mdb_bind_column(table, j+1, bound_values[j], &bound_lens[j]); + for (i=0;inum_cols;i++) { + /* bind columns */ + bound_values[i] = (char *) g_malloc0(MDB_BIND_SIZE); + mdb_bind_column(table, i+1, bound_values[i], &bound_lens[i]); } if (header_row) { - for (j=0; jnum_cols; j++) { - col=g_ptr_array_index(table->columns,j); - if (j) - fputs(delimiter, stdout); - fputs(col->name, stdout); + for (i=0; inum_cols; i++) { + col=g_ptr_array_index(table->columns,i); + if (i) + fputs(delimiter, outfile); + fputs(col->name, outfile); } - fputs("\n", stdout); + fputs(row_delimiter, outfile); } while(mdb_fetch_row(table)) { @@ -227,42 +228,45 @@ main(int argc, char **argv) if (insert_dialect) { char *quoted_name; quoted_name = mdb->default_backend->quote_schema_name(namespace, argv[optind + 1]); - fprintf(stdout, "INSERT INTO %s (", quoted_name); + fprintf(outfile, "INSERT INTO %s (", quoted_name); free(quoted_name); - for (j=0;jnum_cols;j++) { - if (j>0) fputs(", ", stdout); - col=g_ptr_array_index(table->columns,j); + for (i=0;inum_cols;i++) { + if (i>0) fputs(", ", outfile); + col=g_ptr_array_index(table->columns,i); quoted_name = mdb->default_backend->quote_schema_name(NULL, col->name); - fputs(quoted_name, stdout); + fputs(quoted_name, outfile); free(quoted_name); } - fputs(") VALUES (", stdout); + fputs(") VALUES (", outfile); } - for (j=0;jnum_cols;j++) { - if (j>0) - fputs(delimiter, stdout); - col=g_ptr_array_index(table->columns,j); - if (!bound_lens[j]) { + for (i=0;inum_cols;i++) { + if (i>0) + fputs(delimiter, outfile); + col=g_ptr_array_index(table->columns,i); + if (!bound_lens[i]) { + /* Don't quote NULLs */ if (insert_dialect) - fputs("NULL", stdout); + fputs("NULL", outfile); } else { if (col->col_type == MDB_OLE) { value = mdb_ole_read_full(mdb, col, &length); } else { - value = bound_values[j]; - length = bound_lens[j]; + value = bound_values[i]; + length = bound_lens[i]; } - print_col(stdout, value, quote_text, col->col_type, length, quote_char, escape_char, bin_mode); + print_col(outfile, value, quote_text, col->col_type, length, quote_char, escape_char, bin_mode); if (col->col_type == MDB_OLE) free(value); } } - if (insert_dialect) fputs(");", stdout); - fputs(row_delimiter, stdout); + if (insert_dialect) fputs(");", outfile); + fputs(row_delimiter, outfile); } - for (j=0;jnum_cols;j++) { - g_free(bound_values[j]); + + /* free the memory used to bind */ + for (i=0;inum_cols;i++) { + g_free(bound_values[i]); } g_free(bound_values); g_free(bound_lens);