mirror of
https://github.com/mdbtools/mdbtools.git
synced 2026-03-10 00:20:54 +08:00
New useful function (generate_table_schemas) for Windows but not only
This commit is contained in:
@@ -538,6 +538,7 @@ extern LIBMDB_DLL MDB_DEPRECATED(void, mdb_init_backends());
|
|||||||
extern LIBMDB_DLL void mdb_register_backend(char *backend_name, guint32 capabilities, MdbBackendType *backend_type, MdbBackendType *type_shortdate, MdbBackendType *type_autonum, const char *short_now, const char *long_now, const char *charset_statement, const char *drop_statement, const char *constaint_not_empty_statement, const char *column_comment_statement, const char *table_comment_statement, gchar* (*quote_schema_name)(const gchar*, const gchar*));
|
extern LIBMDB_DLL void mdb_register_backend(char *backend_name, guint32 capabilities, MdbBackendType *backend_type, MdbBackendType *type_shortdate, MdbBackendType *type_autonum, const char *short_now, const char *long_now, const char *charset_statement, const char *drop_statement, const char *constaint_not_empty_statement, const char *column_comment_statement, const char *table_comment_statement, gchar* (*quote_schema_name)(const gchar*, const gchar*));
|
||||||
extern LIBMDB_DLL MDB_DEPRECATED(void, mdb_remove_backends());
|
extern LIBMDB_DLL MDB_DEPRECATED(void, mdb_remove_backends());
|
||||||
extern LIBMDB_DLL int mdb_set_default_backend(MdbHandle *mdb, const char *backend_name);
|
extern LIBMDB_DLL int mdb_set_default_backend(MdbHandle *mdb, const char *backend_name);
|
||||||
|
extern LIBMDB_DLL void generate_table_schemas(char *buf, unsigned int *bi, unsigned int *bsize, MdbCatalogEntry *entry, char *dbnamespace, guint32 export_options);
|
||||||
extern LIBMDB_DLL void mdb_print_schema(MdbHandle *mdb, FILE *outfile, char *tabname, char *dbnamespace, guint32 export_options);
|
extern LIBMDB_DLL void mdb_print_schema(MdbHandle *mdb, FILE *outfile, char *tabname, char *dbnamespace, guint32 export_options);
|
||||||
|
|
||||||
/* sargs.c */
|
/* sargs.c */
|
||||||
|
|||||||
@@ -596,6 +596,121 @@ mdb_print_indexes(FILE* outfile, MdbTableDef *table, char *dbnamespace)
|
|||||||
g_free(quoted_table_name);
|
g_free(quoted_table_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mdb_print_indexes
|
||||||
|
* @buf: Where to print the sql
|
||||||
|
* @bi: Index into buf
|
||||||
|
* @bsize: Size of buf
|
||||||
|
* @table: Table to process
|
||||||
|
* @dbnamespace: Target namespace/schema name
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
mdb_print_indexess(char* buf, unsigned int *bi, unsigned int *bsize, MdbTableDef *table, char *dbnamespace)
|
||||||
|
{
|
||||||
|
unsigned int i, j;
|
||||||
|
char* quoted_table_name;
|
||||||
|
char* index_name;
|
||||||
|
char* quoted_name;
|
||||||
|
int backend;
|
||||||
|
MdbHandle* mdb = table->entry->mdb;
|
||||||
|
MdbIndex *idx;
|
||||||
|
MdbColumn *col;
|
||||||
|
|
||||||
|
if (!strcmp(mdb->backend_name, "postgres")) {
|
||||||
|
backend = MDB_BACKEND_POSTGRES;
|
||||||
|
} else if (!strcmp(mdb->backend_name, "mysql")) {
|
||||||
|
backend = MDB_BACKEND_MYSQL;
|
||||||
|
} else {
|
||||||
|
*bi += sprintf(buf + *bi, "-- Indexes are not implemented for %s\n\n", mdb->backend_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read indexes */
|
||||||
|
mdb_read_indices(table);
|
||||||
|
|
||||||
|
*bi += sprintf(buf + *bi, "-- CREATE INDEXES ...\n");
|
||||||
|
|
||||||
|
quoted_table_name = mdb->default_backend->quote_schema_name(dbnamespace, table->name);
|
||||||
|
|
||||||
|
for (i=0;i<table->num_idxs;i++) {
|
||||||
|
|
||||||
|
if (*bi > *bsize/2) { //extend the buffer if needed
|
||||||
|
char *b;
|
||||||
|
*bsize *= 2;
|
||||||
|
b = (char*) g_realloc(buf, *bsize);
|
||||||
|
buf = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
idx = (MdbIndex*) g_ptr_array_index (table->indices, i);
|
||||||
|
if (idx->index_type==2)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
index_name = (char*) malloc(strlen(table->name)+strlen(idx->name)+5+1);
|
||||||
|
strcpy(index_name, table->name);
|
||||||
|
if (idx->index_type==1)
|
||||||
|
strcat(index_name, "_pkey");
|
||||||
|
else {
|
||||||
|
strcat(index_name, "_");
|
||||||
|
strcat(index_name, idx->name);
|
||||||
|
strcat(index_name, "_idx");
|
||||||
|
}
|
||||||
|
quoted_name = mdb->default_backend->quote_schema_name(dbnamespace, index_name);
|
||||||
|
if (idx->index_type==1) {
|
||||||
|
switch (backend) {
|
||||||
|
case MDB_BACKEND_POSTGRES:
|
||||||
|
*bi += sprintf(buf + *bi, "ALTER TABLE %s ADD CONSTRAINT %s PRIMARY KEY (", quoted_table_name, quoted_name);
|
||||||
|
break;
|
||||||
|
case MDB_BACKEND_MYSQL:
|
||||||
|
*bi += sprintf(buf + *bi, "ALTER TABLE %s ADD PRIMARY KEY (", quoted_table_name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (backend) {
|
||||||
|
case MDB_BACKEND_POSTGRES:
|
||||||
|
*bi += sprintf(buf + *bi, "CREATE");
|
||||||
|
if (idx->flags & MDB_IDX_UNIQUE)
|
||||||
|
*bi += sprintf(buf + *bi, " UNIQUE");
|
||||||
|
*bi += sprintf(buf + *bi, " INDEX %s ON %s (", quoted_name, quoted_table_name);
|
||||||
|
break;
|
||||||
|
case MDB_BACKEND_MYSQL:
|
||||||
|
*bi += sprintf(buf + *bi, "ALTER TABLE %s ADD", quoted_table_name);
|
||||||
|
if (idx->flags & MDB_IDX_UNIQUE)
|
||||||
|
*bi += sprintf(buf + *bi, " UNIQUE");
|
||||||
|
*bi += sprintf(buf + *bi, " INDEX %s (", quoted_name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_free(quoted_name); //changed from free
|
||||||
|
free(index_name);
|
||||||
|
|
||||||
|
for (j=0;j<idx->num_keys;j++) {
|
||||||
|
|
||||||
|
if (*bi > *bsize/2) { //extend the buffer if needed
|
||||||
|
char *b;
|
||||||
|
*bsize *= 2;
|
||||||
|
b = (char*) g_realloc(buf, *bsize);
|
||||||
|
buf = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j)
|
||||||
|
*bi += sprintf(buf + *bi, ", ");
|
||||||
|
col= (MdbColumn*) g_ptr_array_index(table->columns,idx->key_col_num[j]-1);
|
||||||
|
quoted_name = mdb->default_backend->quote_schema_name(NULL, col->name);
|
||||||
|
*bi += sprintf(buf + *bi, "%s", quoted_name);
|
||||||
|
if (idx->index_type!=1 && idx->key_col_order[j])
|
||||||
|
/* no DESC for primary keys */
|
||||||
|
*bi += sprintf(buf + *bi, " DESC");
|
||||||
|
|
||||||
|
g_free(quoted_name); //changed from free
|
||||||
|
|
||||||
|
}
|
||||||
|
*bi += sprintf(buf + *bi, ");\n");
|
||||||
|
}
|
||||||
|
*bi += sprintf(buf + *bi, "\n");
|
||||||
|
|
||||||
|
g_free(quoted_table_name);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mdb_get_relationships
|
* mdb_get_relationships
|
||||||
* @mdb: Handle to open MDB database file
|
* @mdb: Handle to open MDB database file
|
||||||
@@ -884,6 +999,177 @@ generate_table_schema(FILE *outfile, MdbCatalogEntry *entry, char *dbnamespace,
|
|||||||
mdb_free_tabledef (table);
|
mdb_free_tabledef (table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Does the same as the above but putting the data in buf.
|
||||||
|
* In Windows there is no way to write to memory through a FILE pointer, and writing to disk slows down a lot
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
generate_table_schemas(char *buf, unsigned int *bi, unsigned int *bsize, MdbCatalogEntry *entry, char *dbnamespace, guint32 export_options)
|
||||||
|
{
|
||||||
|
MdbTableDef *table;
|
||||||
|
MdbHandle *mdb = entry->mdb;
|
||||||
|
MdbColumn *col;
|
||||||
|
unsigned int i;
|
||||||
|
char* quoted_table_name;
|
||||||
|
char* quoted_name;
|
||||||
|
MdbProperties *props;
|
||||||
|
const char *prop_value;
|
||||||
|
|
||||||
|
quoted_table_name = mdb->default_backend->quote_schema_name(dbnamespace, entry->object_name);
|
||||||
|
|
||||||
|
/* drop the table if it exists */
|
||||||
|
if (export_options & MDB_SHEXP_DROPTABLE)
|
||||||
|
*bi = sprintf (buf, mdb->default_backend->drop_statement, quoted_table_name);
|
||||||
|
|
||||||
|
/* create the table */
|
||||||
|
*bi += sprintf(buf + *bi, "CREATE TABLE %s (", quoted_table_name);
|
||||||
|
|
||||||
|
table = mdb_read_table (entry);
|
||||||
|
|
||||||
|
/* get the columns */
|
||||||
|
mdb_read_columns (table);
|
||||||
|
|
||||||
|
/* loop over the columns, dumping the names and types */
|
||||||
|
for (i = 0; i < table->num_cols; i++) {
|
||||||
|
|
||||||
|
if (*bi > *bsize/2) { //extend the buffer if needed
|
||||||
|
char *b;
|
||||||
|
*bsize *= 2;
|
||||||
|
b = (char*) g_realloc(buf, *bsize);
|
||||||
|
buf = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
col = (MdbColumn*) g_ptr_array_index (table->columns, i);
|
||||||
|
|
||||||
|
quoted_name = mdb->default_backend->quote_schema_name(NULL, col->name);
|
||||||
|
*bi += sprintf(buf + *bi, "%s %s", quoted_name,
|
||||||
|
mdb_get_colbacktype_string (col));
|
||||||
|
g_free(quoted_name); //changed from free
|
||||||
|
|
||||||
|
if (mdb_colbacktype_takes_length(col)) {
|
||||||
|
|
||||||
|
/* more portable version from DW patch */
|
||||||
|
if (col->col_size == 0)
|
||||||
|
*bi += sprintf(buf + *bi, " (255)");
|
||||||
|
else
|
||||||
|
*bi += sprintf(buf + *bi, " (%d)", col->col_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (export_options & MDB_SHEXP_CST_NOTNULL) {
|
||||||
|
if (col->col_type == MDB_BOOL) {
|
||||||
|
/* access booleans are never null */
|
||||||
|
*bi += sprintf(buf + *bi, " NOT NULL");
|
||||||
|
} else {
|
||||||
|
const gchar *not_null = mdb_col_get_prop(col, "Required");
|
||||||
|
if (not_null && not_null[0]=='y')
|
||||||
|
*bi += sprintf(buf + *bi, " NOT NULL");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (export_options & MDB_SHEXP_DEFVALUES) {
|
||||||
|
int done = 0;
|
||||||
|
if (col->props) {
|
||||||
|
gchar *defval = (gchar*) g_hash_table_lookup(col->props->hash, "DefaultValue");
|
||||||
|
if (defval) {
|
||||||
|
size_t def_len = strlen(defval);
|
||||||
|
*bi += sprintf(buf + *bi, " DEFAULT ");
|
||||||
|
/* ugly hack to detect the type */
|
||||||
|
if (defval[0]=='"' && defval[def_len-1]=='"') {
|
||||||
|
/* this is a string */
|
||||||
|
gchar *output_default = (gchar*) malloc(def_len-1);
|
||||||
|
gchar *output_default_escaped;
|
||||||
|
memcpy(output_default, defval+1, def_len-2);
|
||||||
|
output_default[def_len-2] = 0;
|
||||||
|
output_default_escaped = quote_with_squotes(output_default);
|
||||||
|
*bi += sprintf(buf + *bi, output_default_escaped);
|
||||||
|
g_free(output_default_escaped);
|
||||||
|
free(output_default);
|
||||||
|
} else if (!strcmp(defval, "Yes"))
|
||||||
|
*bi += sprintf(buf + *bi, "TRUE");
|
||||||
|
else if (!strcmp(defval, "No"))
|
||||||
|
*bi += sprintf(buf + *bi, "FALSE");
|
||||||
|
else if (!strcasecmp(defval, "date()")) {
|
||||||
|
if (!strcmp(mdb_col_get_prop(col, "Format"), "Short Date"))
|
||||||
|
*bi += sprintf(buf + *bi, mdb->default_backend->short_now);
|
||||||
|
else
|
||||||
|
*bi += sprintf(buf + *bi, mdb->default_backend->long_now);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*bi += sprintf(buf + *bi, defval);
|
||||||
|
done = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!done && col->col_type == MDB_BOOL)
|
||||||
|
/* access booleans are false by default */
|
||||||
|
*bi += sprintf(buf + *bi, " DEFAULT FALSE");
|
||||||
|
}
|
||||||
|
if (i < table->num_cols - 1)
|
||||||
|
*bi += sprintf(buf + *bi, ", ");
|
||||||
|
} /* for */
|
||||||
|
|
||||||
|
*bi += sprintf(buf + *bi, ");");
|
||||||
|
|
||||||
|
/* Add the constraints on columns */
|
||||||
|
for (i = 0; i < table->num_cols; i++) {
|
||||||
|
|
||||||
|
if (*bi > *bsize/2) { //extend the buffer if needed
|
||||||
|
char *b;
|
||||||
|
*bsize *= 2;
|
||||||
|
b = (char*) g_realloc(buf, *bsize);
|
||||||
|
buf = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
col = (MdbColumn*) g_ptr_array_index (table->columns, i);
|
||||||
|
props = col->props;
|
||||||
|
if (!props)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
quoted_name = mdb->default_backend->quote_schema_name(NULL, col->name);
|
||||||
|
|
||||||
|
if (export_options & MDB_SHEXP_CST_NOTEMPTY) {
|
||||||
|
prop_value = mdb_col_get_prop(col, "AllowZeroLength");
|
||||||
|
if (prop_value && prop_value[0]=='n')
|
||||||
|
*bi += sprintf(buf + *bi,
|
||||||
|
mdb->default_backend->constaint_not_empty_statement,
|
||||||
|
quoted_table_name, quoted_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (export_options & MDB_SHEXP_COMMENTS) {
|
||||||
|
prop_value = mdb_col_get_prop(col, "Description");
|
||||||
|
if (prop_value) {
|
||||||
|
char *comment = quote_with_squotes(prop_value);
|
||||||
|
*bi += sprintf(buf + *bi,
|
||||||
|
mdb->default_backend->column_comment_statement,
|
||||||
|
quoted_table_name, quoted_name, comment);
|
||||||
|
g_free(comment); //changed from free
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free(quoted_name); //changed from free
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the constraints on table */
|
||||||
|
if (export_options & MDB_SHEXP_COMMENTS) {
|
||||||
|
prop_value = mdb_table_get_prop(table, "Description");
|
||||||
|
if (prop_value) {
|
||||||
|
char *comment = quote_with_squotes(prop_value);
|
||||||
|
*bi += sprintf(buf + *bi,
|
||||||
|
mdb->default_backend->table_comment_statement,
|
||||||
|
quoted_table_name, comment);
|
||||||
|
g_free(comment); //changed from free
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//*bi += sprintf(buf + *bi, "\n");
|
||||||
|
|
||||||
|
|
||||||
|
if (export_options & MDB_SHEXP_INDEXES)
|
||||||
|
// prints all the indexes of that table
|
||||||
|
mdb_print_indexess(buf, bi, bsize, table, dbnamespace);
|
||||||
|
|
||||||
|
g_free(quoted_table_name); //changed from free
|
||||||
|
|
||||||
|
mdb_free_tabledef (table);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
mdb_print_schema(MdbHandle *mdb, FILE *outfile, char *tabname, char *dbnamespace, guint32 export_options)
|
mdb_print_schema(MdbHandle *mdb, FILE *outfile, char *tabname, char *dbnamespace, guint32 export_options)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user