mirror of
https://github.com/mdbtools/mdbtools.git
synced 2025-06-28 15:39:02 +08:00
Added support for name normalisation when generating code for PostgreSQL so that generated artefact names are consistently exported in lowercase.
This commit is contained in:
parent
ce4cf5acbf
commit
afc6f4888b
@ -39,6 +39,7 @@ typedef const void * gconstpointer;
|
||||
typedef uint8_t guint8;
|
||||
typedef guint32 GQuark;
|
||||
typedef guint32 gunichar;
|
||||
typedef signed int gssize;
|
||||
|
||||
typedef guint (*GHashFunc)(gconstpointer);
|
||||
typedef int (*GCompareFunc)(gconstpointer, gconstpointer);
|
||||
@ -143,6 +144,7 @@ void g_printerr(const gchar *format, ...);
|
||||
gint g_unichar_to_utf8(gunichar c, gchar *dst);
|
||||
gchar *g_locale_to_utf8(const gchar *opsysstring, size_t len,
|
||||
size_t *bytes_read, size_t *bytes_written, GError **error);
|
||||
gchar *g_utf8_strdown(const gchar *str, gssize len);
|
||||
|
||||
/* GString */
|
||||
GString *g_string_new(const gchar *init);
|
||||
|
@ -235,6 +235,7 @@ typedef struct {
|
||||
const char *table_comment_statement;
|
||||
const char *per_table_comment_statement;
|
||||
gchar* (*quote_schema_name)(const gchar*, const gchar*);
|
||||
gchar* (*normalise_case)(const gchar*);
|
||||
} MdbBackend;
|
||||
|
||||
typedef struct {
|
||||
@ -569,7 +570,8 @@ void mdb_register_backend(MdbHandle *mdb, char *backend_name, guint32 capabiliti
|
||||
const char *drop_statement, const char *constaint_not_empty_statement,
|
||||
const char *column_comment_statement, const char *per_column_comment_statement,
|
||||
const char *table_comment_statement, const char *per_table_comment_statement,
|
||||
gchar* (*quote_schema_name)(const gchar*, const gchar*));
|
||||
gchar* (*quote_schema_name)(const gchar*, const gchar*),
|
||||
gchar* (*normalise_case)(const gchar*));
|
||||
int mdb_set_default_backend(MdbHandle *mdb, const char *backend_name);
|
||||
int mdb_print_schema(MdbHandle *mdb, FILE *outfile, char *tabname, char *dbnamespace, guint32 export_options);
|
||||
void mdb_print_col(FILE *outfile, gchar *col_val, int quote_text, int col_type, int bin_len, char *quote_char, char *escape_char, int flags);
|
||||
|
@ -155,6 +155,37 @@ enum {
|
||||
|
||||
static void mdb_drop_backend(gpointer key, gpointer value, gpointer data);
|
||||
|
||||
|
||||
gchar *passthrough_unchanged(const gchar *str) {
|
||||
return (gchar *)str;
|
||||
}
|
||||
|
||||
gchar *to_lower_case(const gchar *str) {
|
||||
return g_utf8_strdown(str, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience function to replace an input string with its database specific normalised version.
|
||||
*
|
||||
* This function throws away the input string after normalisation, freeing its memory, and replaces it with a new
|
||||
* normalised version allocated on the stack.
|
||||
*
|
||||
* @param mdb Database specific MDB handle containing pointers to utility methods
|
||||
* @param str string to normalise
|
||||
* @return a pointer to the normalised version of the input string
|
||||
*/
|
||||
gchar *normalise_and_replace(MdbHandle *mdb, gchar **str) {
|
||||
gchar *normalised_str = mdb->default_backend->normalise_case(*str);
|
||||
if (normalised_str != *str) {
|
||||
/* Free and replace the old string only and only if a new string was created at a different memory location
|
||||
* so that we can account for the case where strings a just passed through unchanged.
|
||||
*/
|
||||
free(*str);
|
||||
*str = normalised_str;
|
||||
}
|
||||
return *str;
|
||||
}
|
||||
|
||||
static gchar*
|
||||
quote_generic(const gchar *value, gchar quote_char, gchar escape_char) {
|
||||
gchar *result, *pr;
|
||||
@ -310,7 +341,8 @@ void mdb_init_backends(MdbHandle *mdb)
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
quote_schema_name_bracket_merge);
|
||||
quote_schema_name_bracket_merge,
|
||||
passthrough_unchanged);
|
||||
mdb_register_backend(mdb, "sybase",
|
||||
MDB_SHEXP_DROPTABLE|MDB_SHEXP_CST_NOTNULL|MDB_SHEXP_CST_NOTEMPTY|MDB_SHEXP_COMMENTS|MDB_SHEXP_DEFVALUES,
|
||||
mdb_sybase_types, &mdb_sybase_shortdate_type, NULL,
|
||||
@ -325,7 +357,8 @@ void mdb_init_backends(MdbHandle *mdb)
|
||||
NULL,
|
||||
"COMMENT ON TABLE %s IS %s;\n",
|
||||
NULL,
|
||||
quote_schema_name_dquote);
|
||||
quote_schema_name_dquote,
|
||||
passthrough_unchanged);
|
||||
mdb_register_backend(mdb, "oracle",
|
||||
MDB_SHEXP_DROPTABLE|MDB_SHEXP_CST_NOTNULL|MDB_SHEXP_COMMENTS|MDB_SHEXP_INDEXES|MDB_SHEXP_RELATIONS|MDB_SHEXP_DEFVALUES,
|
||||
mdb_oracle_types, &mdb_oracle_shortdate_type, NULL,
|
||||
@ -340,7 +373,8 @@ void mdb_init_backends(MdbHandle *mdb)
|
||||
NULL,
|
||||
"COMMENT ON TABLE %s IS %s;\n",
|
||||
NULL,
|
||||
quote_schema_name_dquote);
|
||||
quote_schema_name_dquote,
|
||||
passthrough_unchanged);
|
||||
mdb_register_backend(mdb, "postgres",
|
||||
MDB_SHEXP_DROPTABLE|MDB_SHEXP_CST_NOTNULL|MDB_SHEXP_CST_NOTEMPTY|MDB_SHEXP_COMMENTS|MDB_SHEXP_INDEXES|MDB_SHEXP_RELATIONS|MDB_SHEXP_DEFVALUES|MDB_SHEXP_BULK_INSERT,
|
||||
mdb_postgres_types, &mdb_postgres_shortdate_type, &mdb_postgres_serial_type,
|
||||
@ -355,7 +389,8 @@ void mdb_init_backends(MdbHandle *mdb)
|
||||
NULL,
|
||||
"COMMENT ON TABLE %s IS %s;\n",
|
||||
NULL,
|
||||
quote_schema_name_dquote);
|
||||
quote_schema_name_dquote,
|
||||
to_lower_case);
|
||||
mdb_register_backend(mdb, "mysql",
|
||||
MDB_SHEXP_DROPTABLE|MDB_SHEXP_CST_NOTNULL|MDB_SHEXP_CST_NOTEMPTY|MDB_SHEXP_INDEXES|MDB_SHEXP_RELATIONS|MDB_SHEXP_DEFVALUES|MDB_SHEXP_BULK_INSERT,
|
||||
mdb_mysql_types, &mdb_mysql_shortdate_type, &mdb_mysql_serial_type,
|
||||
@ -370,7 +405,8 @@ void mdb_init_backends(MdbHandle *mdb)
|
||||
"COMMENT %s",
|
||||
NULL,
|
||||
"COMMENT %s",
|
||||
quote_schema_name_rquotes_merge);
|
||||
quote_schema_name_rquotes_merge,
|
||||
passthrough_unchanged);
|
||||
mdb_register_backend(mdb, "sqlite",
|
||||
MDB_SHEXP_DROPTABLE|MDB_SHEXP_DEFVALUES|MDB_SHEXP_BULK_INSERT,
|
||||
mdb_sqlite_types, NULL, NULL,
|
||||
@ -385,7 +421,8 @@ void mdb_init_backends(MdbHandle *mdb)
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
quote_schema_name_rquotes_merge);
|
||||
quote_schema_name_rquotes_merge,
|
||||
passthrough_unchanged);
|
||||
}
|
||||
|
||||
void mdb_register_backend(MdbHandle *mdb, char *backend_name, guint32 capabilities,
|
||||
@ -400,7 +437,8 @@ void mdb_register_backend(MdbHandle *mdb, char *backend_name, guint32 capabiliti
|
||||
const char *per_column_comment_statement,
|
||||
const char *table_comment_statement,
|
||||
const char *per_table_comment_statement,
|
||||
gchar* (*quote_schema_name)(const gchar*, const gchar*))
|
||||
gchar* (*quote_schema_name)(const gchar*, const gchar*),
|
||||
gchar* (*normalise_case)(const gchar*))
|
||||
{
|
||||
MdbBackend *backend = g_malloc0(sizeof(MdbBackend));
|
||||
backend->capabilities = capabilities;
|
||||
@ -420,6 +458,7 @@ void mdb_register_backend(MdbHandle *mdb, char *backend_name, guint32 capabiliti
|
||||
backend->table_comment_statement = table_comment_statement;
|
||||
backend->per_table_comment_statement = per_table_comment_statement;
|
||||
backend->quote_schema_name = quote_schema_name;
|
||||
backend->normalise_case = normalise_case;
|
||||
g_hash_table_insert(mdb->backends, backend_name, backend);
|
||||
}
|
||||
|
||||
@ -548,6 +587,7 @@ mdb_print_indexes(FILE* outfile, MdbTableDef *table, char *dbnamespace)
|
||||
fprintf (outfile, "-- CREATE INDEXES ...\n");
|
||||
|
||||
quoted_table_name = mdb->default_backend->quote_schema_name(dbnamespace, table->name);
|
||||
quoted_table_name = mdb->default_backend->normalise_case(quoted_table_name);
|
||||
|
||||
for (i=0;i<table->num_idxs;i++) {
|
||||
idx = g_ptr_array_index (table->indices, i);
|
||||
@ -569,6 +609,8 @@ mdb_print_indexes(FILE* outfile, MdbTableDef *table, char *dbnamespace)
|
||||
quoted_name = mdb->default_backend->quote_schema_name(dbnamespace, index_name);
|
||||
}
|
||||
|
||||
quoted_name = normalise_and_replace(mdb, "ed_name);
|
||||
|
||||
if (idx->index_type==1) {
|
||||
switch (backend) {
|
||||
case MDB_BACKEND_ORACLE:
|
||||
@ -604,6 +646,7 @@ mdb_print_indexes(FILE* outfile, MdbTableDef *table, char *dbnamespace)
|
||||
fprintf(outfile, ", ");
|
||||
col=g_ptr_array_index(table->columns,idx->key_col_num[j]-1);
|
||||
quoted_name = mdb->default_backend->quote_schema_name(NULL, col->name);
|
||||
quoted_name = normalise_and_replace(mdb, "ed_name);
|
||||
fprintf (outfile, "%s", quoted_name);
|
||||
if (idx->index_type!=1 && idx->key_col_order[j])
|
||||
/* no DESC for primary keys */
|
||||
@ -711,8 +754,11 @@ mdb_get_relationships(MdbHandle *mdb, const gchar *dbnamespace, const char* tabl
|
||||
* be namespaced.
|
||||
*/
|
||||
quoted_constraint_name = mdb->default_backend->quote_schema_name(NULL, constraint_name);
|
||||
quoted_constraint_name = normalise_and_replace(mdb, "ed_constraint_name);
|
||||
quoted_column_1 = mdb->default_backend->quote_schema_name(NULL, bound[0]);
|
||||
quoted_column_1 = normalise_and_replace(mdb, "ed_column_1);
|
||||
quoted_column_2 = mdb->default_backend->quote_schema_name(NULL, bound[2]);
|
||||
quoted_column_2 = normalise_and_replace(mdb, "ed_column_2);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -795,6 +841,7 @@ generate_table_schema(FILE *outfile, MdbCatalogEntry *entry, char *dbnamespace,
|
||||
const char *prop_value;
|
||||
|
||||
quoted_table_name = mdb->default_backend->quote_schema_name(dbnamespace, entry->object_name);
|
||||
quoted_table_name = normalise_and_replace(mdb, "ed_table_name);
|
||||
|
||||
/* drop the table if it exists */
|
||||
if (export_options & MDB_SHEXP_DROPTABLE)
|
||||
@ -814,6 +861,7 @@ generate_table_schema(FILE *outfile, MdbCatalogEntry *entry, char *dbnamespace,
|
||||
col = g_ptr_array_index (table->columns, i);
|
||||
|
||||
quoted_name = mdb->default_backend->quote_schema_name(NULL, col->name);
|
||||
quoted_name = normalise_and_replace(mdb, "ed_name);
|
||||
fprintf (outfile, "\t%s\t\t\t%s", quoted_name,
|
||||
mdb_get_colbacktype_string (col));
|
||||
g_free(quoted_name);
|
||||
@ -916,6 +964,7 @@ generate_table_schema(FILE *outfile, MdbCatalogEntry *entry, char *dbnamespace,
|
||||
continue;
|
||||
|
||||
quoted_name = mdb->default_backend->quote_schema_name(NULL, col->name);
|
||||
quoted_name = normalise_and_replace(mdb, "ed_name);
|
||||
|
||||
if (export_options & MDB_SHEXP_CST_NOTEMPTY) {
|
||||
prop_value = mdb_col_get_prop(col, "AllowZeroLength");
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include <errno.h>
|
||||
#include <wctype.h>
|
||||
#ifdef HAVE_ICONV
|
||||
#include <iconv.h>
|
||||
#endif
|
||||
@ -259,6 +260,30 @@ gchar *g_locale_to_utf8(const gchar *opsysstring, size_t len,
|
||||
return utf8;
|
||||
}
|
||||
|
||||
gchar *g_utf8_strdown(const gchar *str, gssize len) {
|
||||
gssize i = 0;
|
||||
if (len == -1)
|
||||
len = strlen(str);
|
||||
gchar *lower = malloc(len+1);
|
||||
while (i<len) {
|
||||
wchar_t u = 0;
|
||||
uint8_t c = str[i];
|
||||
if ((c & 0xF0) == 0xE0) {
|
||||
u = (c & 0x0F) << 12;
|
||||
u += (str[i+1] & 0x3F) << 6;
|
||||
u += (str[i+2] & 0x3F);
|
||||
} else if ((c & 0xE0) == 0xC0) {
|
||||
u = (c & 0x1F) << 6;
|
||||
u += (str[i+1] & 0x3F);
|
||||
} else {
|
||||
u = (c & 0x7F);
|
||||
}
|
||||
i += g_unichar_to_utf8(towlower(u), &lower[i]);
|
||||
}
|
||||
lower[len] = '\0';
|
||||
return lower;
|
||||
}
|
||||
|
||||
/* GHashTable */
|
||||
|
||||
typedef struct MyNode {
|
||||
|
@ -226,12 +226,14 @@ main(int argc, char **argv)
|
||||
counter = 0; // reset to 0, prevent overflow on extremely large data sets.
|
||||
char *quoted_name;
|
||||
quoted_name = mdb->default_backend->quote_schema_name(namespace, table_name);
|
||||
quoted_name = mdb->default_backend->normalise_case(quoted_name);
|
||||
fprintf(outfile, "INSERT INTO %s (", quoted_name);
|
||||
free(quoted_name);
|
||||
for (i = 0; i < table->num_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);
|
||||
quoted_name = mdb->default_backend->normalise_case(quoted_name);
|
||||
fputs(quoted_name, outfile);
|
||||
free(quoted_name);
|
||||
}
|
||||
@ -284,12 +286,14 @@ main(int argc, char **argv)
|
||||
if (insert_dialect) {
|
||||
char *quoted_name;
|
||||
quoted_name = mdb->default_backend->quote_schema_name(namespace, table_name);
|
||||
quoted_name = mdb->default_backend->normalise_case(quoted_name);
|
||||
fprintf(outfile, "INSERT INTO %s (", quoted_name);
|
||||
free(quoted_name);
|
||||
for (i = 0; i < table->num_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);
|
||||
quoted_name = mdb->default_backend->normalise_case(quoted_name);
|
||||
fputs(quoted_name, outfile);
|
||||
free(quoted_name);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user