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);