diff --git a/include/mdbtools.h b/include/mdbtools.h index 306ebce..356f4bf 100644 --- a/include/mdbtools.h +++ b/include/mdbtools.h @@ -204,7 +204,7 @@ typedef struct { guint16 tab_first_dpg_offset; guint16 tab_cols_start_offset; guint16 tab_ridx_entry_size; - guint16 col_fixed_offset; + guint16 col_flags_offset; guint16 col_size_offset; guint16 col_num_offset; guint16 tab_col_entry_size; @@ -280,6 +280,8 @@ typedef struct { /* numerics only */ int col_prec; int col_scale; + unsigned char is_long_auto; + unsigned char is_uuid_auto; MdbProperties *props; /* info needed for handling deleted/added columns */ int fixed_offset; @@ -460,6 +462,7 @@ extern void mdb_init_backends(); extern void mdb_register_backend(MdbBackendType *backend, char* (*quote_name)(const char*), char *backend_name); extern void mdb_remove_backends(); extern int mdb_set_default_backend(MdbHandle *mdb, const char *backend_name); +extern char *mdb_get_sequences(MdbCatalogEntry *entry, char *namespace, int sanitize); extern char *mdb_get_relationships(MdbHandle *mdb); /* sargs.c */ diff --git a/src/libmdb/backend.c b/src/libmdb/backend.c index d688ad4..0820bd5 100644 --- a/src/libmdb/backend.c +++ b/src/libmdb/backend.c @@ -274,6 +274,89 @@ int mdb_set_default_backend(MdbHandle *mdb, const char *backend_name) } } +/** + * mdb_get_sequences + * @mdb: Handle to open MDB database file + * + * Generates sequences and set default values + * + * Returns: a string stating that relationships are not supported for the + * selected backend, or a string containing SQL commands for setting up + * the sequences, tailored for the selected backend. + * Returns NULL on last iteration. + * The caller is responsible for freeing this string. + */ +char *mdb_get_sequences(MdbCatalogEntry *entry, char *namespace, int sanitize) +{ + MdbTableDef *table; + MdbHandle *mdb = entry->mdb; + int i; + int backend = 0; /* Backends: 1=oracle, 2=postgres */ + const char *quoted_table_name; + char *result = NULL; + char tmp[4*512+512]; /* maximum size is 4 quoted names + some constants */ + + + if (is_init == 1) { /* the second time through */ + is_init = 0; + return NULL; + } + is_init = 1; + /* the first time through */ + + if (!strcmp(mdb->backend_name, "postgres")) { + backend = 2; + } else { + return (char *) g_strconcat( + "-- sequences are not supported for ", + mdb->backend_name, NULL); + } + + /* get the columns */ + table = mdb_read_table (entry); + + /* get the columns */ + mdb_read_columns (table); + + if (sanitize) + quoted_table_name = sanitize_name(table->name); + else + quoted_table_name = mdb->default_backend->quote_name(table->name); + + for (i = 0; i < table->num_cols; i++) { + MdbColumn *col; + col = g_ptr_array_index (table->columns, i); + if (col->is_long_auto) { + const char *quoted_column_name; + char sequence_name[256+1+256+4+1]; + const char *quoted_sequence_name; + quoted_column_name = mdb->default_backend->quote_name(col->name); + sprintf(sequence_name, "%s_%s_seq", entry->object_name, col->name); + quoted_sequence_name = mdb->default_backend->quote_name(sequence_name); + sprintf (tmp, "CREATE SEQUENCE %s OWNED BY %s.%s;\n", quoted_sequence_name, quoted_table_name, quoted_column_name); + if (result) { + result = realloc(result, strlen(result) + strlen(tmp) + 1); /* sentry */ + strcat(result, tmp); + } else + result = strdup(tmp); + /* after that point, result can't be NULL any more */ + + sprintf (tmp, "ALTER TABLE %s ALTER COLUMN %s SET DEFAULT pg_catalog.nextval('%s');\n\n", + quoted_table_name, quoted_column_name, quoted_sequence_name); + result = realloc(result, strlen(result) + strlen(tmp) + 1); /* sentry */ + strcat(result, tmp); + + free((void*)quoted_column_name); + free((void*)quoted_sequence_name); + } + } + + if (!result) + is_init = 0; + return result; +} + + /** * mdb_get_relationships * @mdb: Handle to open MDB database file diff --git a/src/libmdb/file.c b/src/libmdb/file.c index 697f423..663129b 100644 --- a/src/libmdb/file.c +++ b/src/libmdb/file.c @@ -35,7 +35,7 @@ typedef struct { guint16 tab_first_dpg_offset; guint16 tab_cols_start_offset; guint16 tab_ridx_entry_size; - guint16 col_fixed_offset; + guint16 col_flags_offset; guint16 col_size_offset; guint16 col_num_offset; guint16 tab_col_entry_size; diff --git a/src/libmdb/table.c b/src/libmdb/table.c index 64e3ccb..be311b3 100644 --- a/src/libmdb/table.c +++ b/src/libmdb/table.c @@ -249,10 +249,12 @@ GPtrArray *mdb_read_columns(MdbTableDef *table) pcol->col_scale = col[12]; } - // col_fixed_offset == 13 or 15 - pcol->is_fixed = col[fmt->col_fixed_offset] & 0x01 ? 1 : 0; + // col_flags_offset == 13 or 15 + pcol->is_fixed = col[fmt->col_flags_offset] & 0x01 ? 1 : 0; + pcol->is_long_auto = col[fmt->col_flags_offset] & 0x04 ? 1 : 0; + pcol->is_uuid_auto = col[fmt->col_flags_offset] & 0x40 ? 1 : 0; - // col_fixed_offset == 13 or 15 + // tab_col_offset_fixed == 14 or 21 pcol->fixed_offset = mdb_get_int16(col, fmt->tab_col_offset_fixed); //fprintf(stdout,"fixed column offset %d\n",pcol->fixed_offset); //fprintf(stdout,"col type %s\n",pcol->is_fixed ? "fixed" : "variable"); diff --git a/src/util/mdb-schema.c b/src/util/mdb-schema.c index 6fd36db..8ec3f84 100644 --- a/src/util/mdb-schema.c +++ b/src/util/mdb-schema.c @@ -128,7 +128,9 @@ generate_table_schema(MdbCatalogEntry *entry, char *namespace, int sanitize) unsigned int i; MdbColumn *col; char* table_name; + char* quoted_table_name; char* quoted_name; + char* sql_sequences; if (namespace) { table_name = malloc(strlen(namespace)+strlen(entry->object_name)+1); @@ -139,20 +141,18 @@ generate_table_schema(MdbCatalogEntry *entry, char *namespace, int sanitize) table_name = strdup(entry->object_name); } if (sanitize) - quoted_name = sanitize_name(table_name); + quoted_table_name = sanitize_name(table_name); else - quoted_name = mdb->default_backend->quote_name(table_name); + quoted_table_name = mdb->default_backend->quote_name(table_name); free(table_name); /* drop the table if it exists */ - fprintf (stdout, "DROP TABLE %s;\n", quoted_name); + fprintf (stdout, "DROP TABLE %s;\n", quoted_table_name); /* create the table */ - fprintf (stdout, "CREATE TABLE %s\n", quoted_name); + fprintf (stdout, "CREATE TABLE %s\n", quoted_table_name); fprintf (stdout, " (\n"); - free(quoted_name); - table = mdb_read_table (entry); /* get the columns */ @@ -188,8 +188,36 @@ generate_table_schema(MdbCatalogEntry *entry, char *namespace, int sanitize) } /* for */ fprintf (stdout, ");\n"); + + fprintf (stdout, "-- CREATE SEQUENCES ...\n"); + fprintf (stdout, "\n"); + + while ((sql_sequences = mdb_get_sequences(entry, namespace, sanitize))) + fprintf(stdout, sql_sequences); + + /* + for (i = 0; i < table->num_cols; i++) { + col = g_ptr_array_index (table->columns, i); + if (col->is_long_auto) { + char sequence_name[256+1+256+4]; // FIXME + char *quoted_column_name; + quoted_column_name = mdb->default_backend->quote_name(col->name); + sprintf(sequence_name, "%s_%s_seq", entry->object_name, col->name); + quoted_name = mdb->default_backend->quote_name(sequence_name); + fprintf (stdout, "CREATE SEQUENCE %s;\n", quoted_name); + fprintf (stdout, "ALTER TABLE %s ALTER COLUMN %s SET DEFAULT pg_catalog.nextval('%s');\n", + quoted_table_name, quoted_column_name, quoted_name); + free(quoted_column_name); + free(quoted_name); + } + + } + */ + fprintf (stdout, "-- CREATE ANY INDEXES ...\n"); fprintf (stdout, "\n"); + free(quoted_table_name); + mdb_free_tabledef (table); }