Improved patch for SQLite3 backend
Jarl Friis <[email protected]> Thu, 08 Nov 2007 21:37:21 +0100
| Newsgroups | gmane.comp.db.mdb-tools.devel |
|---|---|
| Organization | Gavia Technologies ApS |
| Message-ID | <[email protected]> |
This patch is improved to be aware of the SQLite ODBC type mapping. Jarl -- Jarl Friis Gavia Technologies ApS Omøgade 8, 2.sal 2100 København Ø. Denmark Phone: +45 26 13 20 90 E-mail: [email protected] LinkedIn: www.linkedin.com/in/jarlfriis ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ mdbtools-dev mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/mdbtools-dev
mdbtools-sqlite.patch
(text/x-patch, 15.8 KB)
Index: include/mdbtools.h
===================================================================
RCS file: /cvsroot/mdbtools/mdbtools/include/mdbtools.h,v
retrieving revision 1.81
diff -w -u -r1.81 mdbtools.h
--- include/mdbtools.h 5 Mar 2007 23:34:47 -0000 1.81
+++ include/mdbtools.h 8 Nov 2007 20:33:29 -0000
@@ -412,6 +412,7 @@
extern GPtrArray *mdb_read_catalog(MdbHandle *mdb, int obj_type);
extern void mdb_dump_catalog(MdbHandle *mdb, int obj_type);
extern char *mdb_get_objtype_string(int obj_type);
+extern char *mdb_sanitize_name(char *str, int sanitize);
/* table.c */
extern MdbTableDef *mdb_alloc_tabledef(MdbCatalogEntry *entry);
Index: src/libmdb/backend.c
===================================================================
RCS file: /cvsroot/mdbtools/mdbtools/src/libmdb/backend.c,v
retrieving revision 1.25
diff -w -u -r1.25 backend.c
--- src/libmdb/backend.c 17 Oct 2005 12:04:34 -0000 1.25
+++ src/libmdb/backend.c 8 Nov 2007 20:33:30 -0000
@@ -58,6 +58,27 @@
MdbBackendType_STRUCT_ELEMENT("Numeric",1,1,0)
};
+ /* SQLite3 data types being SQLite ODBC aware*/
+static MdbBackendType mdb_sqlite3_types[] = {
+ MdbBackendType_STRUCT_ELEMENT("Sqlite3_Unknown 0x00", 0,0,0),
+ MdbBackendType_STRUCT_ELEMENT("BOOLEAN", 0,0,0),
+ MdbBackendType_STRUCT_ELEMENT("TINYINT", 0,0,0),
+ MdbBackendType_STRUCT_ELEMENT("INTEGER", 0,0,0),
+ MdbBackendType_STRUCT_ELEMENT("BIGINT", 0,0,0),
+ MdbBackendType_STRUCT_ELEMENT("NUMERIC", 0,0,0),
+ MdbBackendType_STRUCT_ELEMENT("INTEGER", 0,0,0),
+ MdbBackendType_STRUCT_ELEMENT("DOUBLE", 0,0,0),
+ MdbBackendType_STRUCT_ELEMENT("DATETIME", 0,0,1),
+ MdbBackendType_STRUCT_ELEMENT("BLOB", 0,0,0),
+ MdbBackendType_STRUCT_ELEMENT("TEXT", 1,0,1),
+ MdbBackendType_STRUCT_ELEMENT("BLOB", 1,0,1),
+ MdbBackendType_STRUCT_ELEMENT("MEMO",1,0,1),
+ MdbBackendType_STRUCT_ELEMENT("Sqlite3_Unknown 0x0d",0,0,0),
+ MdbBackendType_STRUCT_ELEMENT("Sqlite3_Unknown 0x0e",0,0,0),
+ MdbBackendType_STRUCT_ELEMENT("INTEGER",0,0,0),
+ MdbBackendType_STRUCT_ELEMENT("NUMERIC",1,1,0)
+};
+
/* Oracle data types */
static MdbBackendType mdb_oracle_types[] = {
MdbBackendType_STRUCT_ELEMENT("Oracle_Unknown 0x00",0,0,0),
@@ -176,6 +197,7 @@
mdb_register_backend(mdb_oracle_types, "oracle");
mdb_register_backend(mdb_postgres_types, "postgres");
mdb_register_backend(mdb_mysql_types, "mysql");
+ mdb_register_backend(mdb_sqlite3_types, "sqlite3");
}
void mdb_register_backend(MdbBackendType *backend_type, char *backend_name)
{
Index: src/libmdb/catalog.c
===================================================================
RCS file: /cvsroot/mdbtools/mdbtools/src/libmdb/catalog.c,v
retrieving revision 1.30
diff -w -u -r1.30 catalog.c
--- src/libmdb/catalog.c 17 Jun 2005 02:42:18 -0000 1.30
+++ src/libmdb/catalog.c 8 Nov 2007 20:33:30 -0000
@@ -137,3 +137,41 @@
return;
}
+char *mdb_sanitize_name(char *str, int sanitize)
+{
+
+ static char* keywords[] = { "group",
+ "table",
+ "default",
+ NULL };//TODO: This list is probably specific to the backend.
+ static char namebuf[256];
+ static char lowernamebuf[256];
+ char *p = namebuf;
+ char *lp = lowernamebuf;
+
+ if (!sanitize)
+ return str;
+
+ while (*str) {
+ *p = isalnum(*str) ? *str : '_';
+ *lp = tolower(*p);
+ p++;
+ lp++;
+ str++;
+ }
+ *lp = 0;
+
+ int accepted = 1;
+ int j = 0;
+ while(accepted && (keywords[j] != NULL)){
+ accepted = strcmp(lowernamebuf, keywords[j]) == 0 ? 0 : 1;
+ ++j;
+ }
+ if(!accepted){
+ *p = '_';
+ ++p;
+ }
+ *p = 0;
+
+ return namebuf;
+}
Index: src/util/mdb-export.c
===================================================================
RCS file: /cvsroot/mdbtools/mdbtools/src/util/mdb-export.c,v
retrieving revision 1.31
diff -w -u -r1.31 mdb-export.c
--- src/util/mdb-export.c 6 Mar 2007 01:16:54 -0000 1.31
+++ src/util/mdb-export.c 8 Nov 2007 20:33:30 -0000
@@ -28,9 +28,43 @@
#define is_text_type(x) (x==MDB_TEXT || x==MDB_MEMO || x==MDB_SDATETIME)
-static char *sanitize_name(char *str, int sanitize);
static char *escapes(char *s);
+typedef struct
+{
+ char *table_name;
+ char *delimiter;
+ char *row_delimiter;
+ char *quote_char;
+ char *escape_char;
+ char header_row;
+ char quote_text;
+ char insert_statements;
+ char sanitize;
+} mdb_export_context;
+
+void mdb_export_context_ctor(mdb_export_context * const context)
+{
+ context->table_name = NULL;
+ context->delimiter = NULL;
+ context->row_delimiter = NULL;
+ context->quote_char = NULL;
+ context->escape_char = NULL;
+ context->header_row = 1;
+ context->quote_text = 1;
+ context->insert_statements = 0;
+ context->sanitize = 0;
+}
+
+void mdb_export_context_dtor(mdb_export_context * const context)
+{
+ if(context->table_name) g_free(context->table_name);
+ g_free (context->delimiter);
+ g_free (context->row_delimiter);
+ g_free (context->quote_char);
+ if (context->escape_char) g_free (context->escape_char);
+}
+
void
print_col(gchar *col_val, int quote_text, int col_type, char *quote_char, char *escape_char)
{
@@ -54,75 +88,150 @@
fprintf(stdout,"%s",col_val);
}
}
+
+void
+export_table(mdb_export_context const * const context, MdbHandle * const mdb, MdbTableDef * const table){
+ MdbColumn *col;
+ char **bound_values;
+ int *bound_lens;
+ unsigned int j;
+
+ 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;j<table->num_cols;j++) {
+ bound_values[j] = (char *) g_malloc0(MDB_BIND_SIZE);
+ mdb_bind_column(table, j+1, bound_values[j], &bound_lens[j]);
+ }
+ if (context->header_row) {
+ col=g_ptr_array_index(table->columns,0);
+ fprintf(stdout,"%s",mdb_sanitize_name(col->name,context->sanitize));
+ for (j=1;j<table->num_cols;j++) {
+ col=g_ptr_array_index(table->columns,j);
+ fprintf(stdout,context->delimiter);
+ fprintf(stdout,"%s",mdb_sanitize_name(col->name,context->sanitize));
+ }
+ fprintf(stdout,"\n");
+ }
+
+ while(mdb_fetch_row(table)) {
+
+ if (context->insert_statements) {
+ fprintf(stdout, "INSERT INTO %s (",
+ mdb_sanitize_name(table->name ,context->sanitize));
+ for (j=0;j<table->num_cols;j++) {
+ if (j>0) fprintf(stdout, ", ");
+ col=g_ptr_array_index(table->columns,j);
+ fprintf(stdout,"%s", mdb_sanitize_name(col->name,context->sanitize));
+ }
+ fprintf(stdout, ") VALUES (");
+ }
+
+ for (j=0;j<table->num_cols;j++) {
+ col=g_ptr_array_index(table->columns,j);
+ if ((col->col_type == MDB_OLE)
+ && ((j==0) || (col->cur_value_len))) {
+ mdb_ole_read(mdb, col, bound_values[j], MDB_BIND_SIZE);
+ }
+ if (j>0) {
+ fprintf(stdout,context->delimiter);
+ }
+ if (context->insert_statements && !bound_lens[j]) {
+ print_col("NULL",0,col->col_type, context->quote_char, context->escape_char);
+ } else {
+ print_col(bound_values[j], context->quote_text, col->col_type, context->quote_char, context->escape_char);
+ }
+ }
+ if (context->insert_statements) fprintf(stdout,");");
+ fprintf(stdout, context->row_delimiter);
+ }
+ for (j=0;j<table->num_cols;j++) {
+ g_free(bound_values[j]);
+ }
+ g_free(bound_values);
+ g_free(bound_lens);
+}
+
+void export_all_tables(mdb_export_context const * const context, MdbHandle * const mdb){
+ unsigned int i;
+ MdbCatalogEntry *entry;
+ MdbTableDef *table;
+
+ for (i=0; i < mdb->num_catalog; i++) {
+ entry = g_ptr_array_index (mdb->catalog, i);
+ if (entry->object_type == MDB_TABLE) {
+ if (mdb_is_user_table(entry)) {
+ table = mdb_read_table_by_name(mdb, entry->object_name, MDB_TABLE);
+ export_table(context, mdb, table);
+ mdb_free_tabledef(table);
+ }
+ }
+ }
+
+}
+
int
main(int argc, char **argv)
{
unsigned int j;
MdbHandle *mdb;
MdbTableDef *table;
- MdbColumn *col;
- char **bound_values;
- int *bound_lens;
- char *delimiter = NULL;
- char *row_delimiter = NULL;
- char *quote_char = NULL;
- char *escape_char = NULL;
- char header_row = 1;
- char quote_text = 1;
- char insert_statements = 0;
- char sanitize = 0;
+ mdb_export_context context;
int opt;
+ mdb_export_context_ctor(&context);
while ((opt=getopt(argc, argv, "HQq:X:d:D:R:IS"))!=-1) {
switch (opt) {
case 'H':
- header_row = 0;
+ context.header_row = 0;
break;
case 'Q':
- quote_text = 0;
+ context.quote_text = 0;
break;
case 'q':
- quote_char = (char *) g_strdup(optarg);
+ context.quote_char = (char *) g_strdup(optarg);
break;
case 'd':
- delimiter = escapes(optarg);
+ context.delimiter = escapes(optarg);
break;
case 'R':
- row_delimiter = escapes(optarg);
+ context.row_delimiter = escapes(optarg);
break;
case 'I':
- insert_statements = 1;
- header_row = 0;
+ context.insert_statements = 1;
+ context.header_row = 0;
break;
case 'S':
- sanitize = 1;
+ context.sanitize = 1;
break;
case 'D':
mdb_set_date_fmt(optarg);
break;
case 'X':
- escape_char = (char *) g_strdup(optarg);
+ context.escape_char = (char *) g_strdup(optarg);
break;
default:
break;
}
}
- if (!quote_char) {
- quote_char = (char *) g_strdup("\"");
+ if (!context.quote_char) {
+ context.quote_char = (char *) g_strdup("\"");
}
- if (!delimiter) {
- delimiter = (char *) g_strdup(",");
+ if (!context.delimiter) {
+ context.delimiter = (char *) g_strdup(",");
}
- if (!row_delimiter) {
- row_delimiter = (char *) g_strdup("\n");
+ if (!context.row_delimiter) {
+ context.row_delimiter = (char *) g_strdup("\n");
}
/*
** optind is now the position of the first non-option arg,
** see getopt(3)
*/
- if (argc-optind < 2) {
- fprintf(stderr,"Usage: %s [options] <file> <table>\n",argv[0]);
+ if (argc-optind < 1) {
+ fprintf(stderr,"Usage: %s [options] <file> [<table>]\n",argv[0]);
fprintf(stderr,"where options are:\n");
fprintf(stderr," -H supress header row\n");
fprintf(stderr," -Q don't wrap text-like fields in quotes\n");
@@ -133,123 +242,47 @@
fprintf(stderr," -S Sanitize names (replace spaces etc. with underscore)\n");
fprintf(stderr," -q <char> Use <char> to wrap text-like fields. Default is \".\n");
fprintf(stderr," -X <char> Use <char> to escape quoted characters within a field. Default is doubling.\n");
- g_free (delimiter);
- g_free (row_delimiter);
- g_free (quote_char);
- if (escape_char) g_free (escape_char);
+ mdb_export_context_dtor(&context);
exit(1);
}
mdb_init();
if (!(mdb = mdb_open(argv[optind], MDB_NOFLAGS))) {
- g_free (delimiter);
- g_free (row_delimiter);
- g_free (quote_char);
- if (escape_char) g_free (escape_char);
+ mdb_export_context_dtor(&context);
mdb_exit();
exit(1);
}
- table = mdb_read_table_by_name(mdb, argv[argc-1], MDB_TABLE);
+ if(optind+2 == argc){
+ context.table_name = g_strdup(argv[optind+1]);
+ table = mdb_read_table_by_name(mdb, context.table_name, MDB_TABLE);
if (!table) {
- fprintf(stderr, "Error: Table %s does not exist in this database.\n", argv[argc-1]);
- g_free (delimiter);
- g_free (row_delimiter);
- g_free (quote_char);
- if (escape_char) g_free (escape_char);
+ fprintf(stderr, "Error: Table %s does not exist in this database.\n", context.table_name);
+ mdb_export_context_dtor(&context);
mdb_close(mdb);
mdb_exit();
exit(1);
}
- 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;j<table->num_cols;j++) {
- bound_values[j] = (char *) g_malloc0(MDB_BIND_SIZE);
- mdb_bind_column(table, j+1, bound_values[j], &bound_lens[j]);
- }
- if (header_row) {
- col=g_ptr_array_index(table->columns,0);
- fprintf(stdout,"%s",sanitize_name(col->name,sanitize));
- for (j=1;j<table->num_cols;j++) {
- col=g_ptr_array_index(table->columns,j);
- fprintf(stdout,delimiter);
- fprintf(stdout,"%s",sanitize_name(col->name,sanitize));
- }
- fprintf(stdout,"\n");
- }
-
- while(mdb_fetch_row(table)) {
-
- if (insert_statements) {
- fprintf(stdout, "INSERT INTO %s (",
- sanitize_name(argv[optind + 1],sanitize));
- for (j=0;j<table->num_cols;j++) {
- if (j>0) fprintf(stdout, ", ");
- col=g_ptr_array_index(table->columns,j);
- fprintf(stdout,"%s", sanitize_name(col->name,sanitize));
- }
- fprintf(stdout, ") VALUES (");
- }
-
- for (j=0;j<table->num_cols;j++) {
- col=g_ptr_array_index(table->columns,j);
- if ((col->col_type == MDB_OLE)
- && ((j==0) || (col->cur_value_len))) {
- mdb_ole_read(mdb, col, bound_values[j], MDB_BIND_SIZE);
- }
- if (j>0) {
- fprintf(stdout,delimiter);
- }
- if (insert_statements && !bound_lens[j]) {
- print_col("NULL",0,col->col_type, quote_char, escape_char);
+ export_table(&context, mdb, table);
+ mdb_free_tabledef(table);
} else {
- print_col(bound_values[j], quote_text, col->col_type, quote_char, escape_char);
- }
- }
- if (insert_statements) fprintf(stdout,")");
- fprintf(stdout, row_delimiter);
+ /* read the catalog */
+ if (!mdb_read_catalog (mdb, MDB_TABLE)) {
+ fprintf(stderr,"File does not appear to be an Access database\n");
+ exit(1);
}
- for (j=0;j<table->num_cols;j++) {
- g_free(bound_values[j]);
+ export_all_tables(&context, mdb);
}
- g_free(bound_values);
- g_free(bound_lens);
- mdb_free_tabledef(table);
- g_free (delimiter);
- g_free (row_delimiter);
- g_free (quote_char);
- if (escape_char) g_free (escape_char);
+ mdb_export_context_dtor(&context);
mdb_close(mdb);
mdb_exit();
exit(0);
}
-static char *sanitize_name(char *str, int sanitize)
-{
- static char namebuf[256];
- char *p = namebuf;
-
- if (!sanitize)
- return str;
-
- while (*str) {
- *p = isalnum(*str) ? *str : '_';
- p++;
- str++;
- }
-
- *p = 0;
-
- return namebuf;
-}
-
static char *escapes(char *s)
{
char *d = (char *) g_strdup(s);
Index: src/util/mdb-schema.c
===================================================================
RCS file: /cvsroot/mdbtools/mdbtools/src/util/mdb-schema.c,v
retrieving revision 1.21
diff -w -u -r1.21 mdb-schema.c
--- src/util/mdb-schema.c 17 Jun 2005 02:39:45 -0000 1.21
+++ src/util/mdb-schema.c 8 Nov 2007 20:33:30 -0000
@@ -24,7 +24,6 @@
#include "dmalloc.h"
#endif
-static char *sanitize_name(char *str, int sanitize);
static void generate_table_schema(MdbCatalogEntry *entry, char *namespace, int sanitize);
int
@@ -131,11 +130,11 @@
/* drop the table if it exists */
fprintf (stdout, "DROP TABLE %s%s;\n", (namespace) ? namespace : "",
- sanitize_name(entry->object_name, sanitize));
+ mdb_sanitize_name(entry->object_name, sanitize));
/* create the table */
fprintf (stdout, "CREATE TABLE %s%s\n", (namespace) ? namespace : "",
- sanitize_name(entry->object_name, sanitize));
+ mdb_sanitize_name(entry->object_name, sanitize));
fprintf (stdout, " (\n");
table = mdb_read_table (entry);
@@ -148,7 +147,7 @@
for (i = 0; i < table->num_cols; i++) {
col = g_ptr_array_index (table->columns, i);
- fprintf (stdout, "\t%s\t\t\t%s", sanitize_name(col->name,sanitize),
+ fprintf (stdout, "\t%s\t\t\t%s", mdb_sanitize_name(col->name,sanitize),
mdb_get_coltype_string (mdb->default_backend, col->col_type));
if (mdb_coltype_takes_length(mdb->default_backend,
@@ -174,22 +173,4 @@
mdb_free_tabledef (table);
}
-static char *sanitize_name(char *str, int sanitize)
-{
- static char namebuf[256];
- char *p = namebuf;
-
- if (!sanitize)
- return str;
-
- while (*str) {
- *p = isalnum(*str) ? *str : '_';
- p++;
- str++;
- }
-
- *p = 0;
-
- return namebuf;
-}