From 5af21c133b7a82d51d3e4bcff7fc87287686da87 Mon Sep 17 00:00:00 2001 From: Phil Longstaff Date: Sun, 9 Aug 2009 22:25:22 +0000 Subject: [PATCH] Handle creation of autoinc columns correctly git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@18241 57a11ea4-9604-0410-9ed3-97b8803252fd --- src/backend/dbi/gnc-backend-dbi.c | 251 ++++++++++++++---------------- src/backend/sql/gnc-backend-sql.h | 4 +- 2 files changed, 119 insertions(+), 136 deletions(-) diff --git a/src/backend/dbi/gnc-backend-dbi.c b/src/backend/dbi/gnc-backend-dbi.c index f355cb2f11..16e90aece5 100644 --- a/src/backend/dbi/gnc-backend-dbi.c +++ b/src/backend/dbi/gnc-backend-dbi.c @@ -67,46 +67,38 @@ static QofLogModule log_module = G_LOG_DOMAIN; typedef gchar* (*CREATE_TABLE_DDL_FN)( GncSqlConnection* conn, const gchar* table_name, const GList* col_info_list ); -typedef const gchar* (*GET_COLUMN_TYPE_NAME_FN)( GType type, gint size ); typedef GSList* (*GET_TABLE_LIST_FN)( dbi_conn conn, const gchar* dbname ); typedef struct { CREATE_TABLE_DDL_FN create_table_ddl; - GET_COLUMN_TYPE_NAME_FN get_column_type_name; GET_TABLE_LIST_FN get_table_list; } provider_functions_t; static /*@ null @*/ gchar* conn_create_table_ddl_sqlite3( GncSqlConnection* conn, const gchar* table_name, const GList* col_info_list ); -static /*@ observer @*/ const gchar* get_column_type_name_sqlite3( GType type, gint size ); static GSList* conn_get_table_list( dbi_conn conn, const gchar* dbname ); static provider_functions_t provider_sqlite3 = { conn_create_table_ddl_sqlite3, - get_column_type_name_sqlite3, conn_get_table_list }; static /*@ null @*/ gchar* conn_create_table_ddl_mysql( GncSqlConnection* conn, const gchar* table_name, const GList* col_info_list ); -static /*@ observer @*/ const gchar* get_column_type_name_mysql( GType type, gint size ); static provider_functions_t provider_mysql = { conn_create_table_ddl_mysql, - get_column_type_name_mysql, conn_get_table_list }; static /*@ null @*/ gchar* conn_create_table_ddl_pgsql( GncSqlConnection* conn, const gchar* table_name, const GList* col_info_list ); -static /*@ observer @*/ const gchar* get_column_type_name_pgsql( GType type, gint size ); static GSList* conn_get_table_list_pgsql( dbi_conn conn, const gchar* dbname ); static provider_functions_t provider_pgsql = { conn_create_table_ddl_pgsql, - get_column_type_name_pgsql, conn_get_table_list_pgsql }; @@ -1345,124 +1337,6 @@ conn_commit_transaction( /*@ unused @*/ GncSqlConnection* conn ) return TRUE; } -static /*@ observer @*/ const gchar* -get_column_type_name_sqlite3( GType type, /*@ unused @*/ gint size ) -{ - switch( type ) { - case G_TYPE_INT: - return "integer"; - - case G_TYPE_INT64: - return "bigint"; - - case G_TYPE_DOUBLE: - return "real"; - - case G_TYPE_STRING: - return "text"; - - default: - PERR( "Unknown GType: %s\n", g_type_name( type ) ); - return ""; - } -} - -static /*@ observer @*/ const gchar* -get_column_type_name_mysql( GType type, /*@ unused @*/ gint size ) -{ - switch( type ) { - case G_TYPE_INT: - return "integer"; - - case G_TYPE_INT64: - return "bigint"; - - case G_TYPE_DOUBLE: - return "double"; - - case G_TYPE_STRING: - return "varchar"; - - default: - PERR( "Unknown GType: %s\n", g_type_name( type ) ); - return ""; - } -} - -static /*@ observer @*/ const gchar* -get_column_type_name_pgsql( GType type, /*@ unused @*/ gint size ) -{ - switch( type ) { - case G_TYPE_INT: - return "integer"; - - case G_TYPE_INT64: - return "int8"; - - case G_TYPE_DOUBLE: - return "double precision"; - - case G_TYPE_STRING: - return "varchar"; - - default: - PERR( "Unknown GType: %s\n", g_type_name( type ) ); - return ""; - } -} - -static /*@ observer @*/ const gchar* -conn_get_column_type_name( GncSqlConnection* conn, GType type, /*@ unused @*/ gint size ) -{ - GncDbiSqlConnection* dbi_conn = (GncDbiSqlConnection*)conn; - - if( dbi_conn->provider != NULL && dbi_conn->provider->get_column_type_name != NULL ) { - return dbi_conn->provider->get_column_type_name( type, size ); - } else { - PERR( "Unknown provider type\n" ); - return ""; - } -} - -static /*@ null @*/ gchar* -conn_create_table_ddl_sqlite3( GncSqlConnection* conn, - const gchar* table_name, - const GList* col_info_list ) -{ - GString* ddl; - const GList* list_node; - guint col_num; - - g_return_val_if_fail( conn != NULL, NULL ); - g_return_val_if_fail( table_name != NULL, NULL ); - g_return_val_if_fail( col_info_list != NULL, NULL ); - - ddl = g_string_new( "" ); - g_string_printf( ddl, "CREATE TABLE %s (", table_name ); - for( list_node = col_info_list, col_num = 0; list_node != NULL; - list_node = list_node->next, col_num++ ) { - GncSqlColumnInfo* info = (GncSqlColumnInfo*)(list_node->data); - - if( col_num != 0 ) { - (void)g_string_append( ddl, ", " ); - } - g_string_append_printf( ddl, "%s %s", info->name, - gnc_sql_connection_get_column_type_name( conn, info->type, info->size ) ); - if( info->size != 0 ) { - (void)g_string_append_printf( ddl, "(%d)", info->size ); - } - if( info->is_primary_key ) { - (void)g_string_append( ddl, " PRIMARY KEY" ); - } - if( !info->null_allowed ) { - (void)g_string_append( ddl, " NOT NULL" ); - } - } - (void)g_string_append( ddl, ")" ); - - return g_string_free( ddl, FALSE ); -} - static /*@ null @*/ gchar* create_index_ddl( GncSqlConnection* conn, const gchar* index_name, @@ -1491,12 +1365,14 @@ create_index_ddl( GncSqlConnection* conn, } static /*@ null @*/ gchar* -conn_create_table_ddl_mysql( GncSqlConnection* conn, const gchar* table_name, - const GList* col_info_list ) +conn_create_table_ddl_sqlite3( GncSqlConnection* conn, + const gchar* table_name, + const GList* col_info_list ) { GString* ddl; const GList* list_node; guint col_num; + gchar* type_name; g_return_val_if_fail( conn != NULL, NULL ); g_return_val_if_fail( table_name != NULL, NULL ); @@ -1511,8 +1387,90 @@ conn_create_table_ddl_mysql( GncSqlConnection* conn, const gchar* table_name, if( col_num != 0 ) { (void)g_string_append( ddl, ", " ); } - g_string_append_printf( ddl, "%s %s", info->name, - gnc_sql_connection_get_column_type_name( conn, info->type, info->size ) ); + switch( info->type ) { + case G_TYPE_INT: + type_name = "integer"; + break; + + case G_TYPE_INT64: + type_name = "bigint"; + break; + + case G_TYPE_DOUBLE: + type_name = "real"; + break; + + case G_TYPE_STRING: + type_name = "text"; + break; + + default: + PERR( "Unknown GType: %s\n", g_type_name( info->type ) ); + type_name = ""; + } + g_string_append_printf( ddl, "%s %s", info->name, type_name ); + if( info->size != 0 ) { + (void)g_string_append_printf( ddl, "(%d)", info->size ); + } + if( info->is_primary_key ) { + (void)g_string_append( ddl, " PRIMARY KEY" ); + } + if( info->is_autoinc ) { + (void)g_string_append( ddl, " AUTOINCREMENT" ); + } + if( !info->null_allowed ) { + (void)g_string_append( ddl, " NOT NULL" ); + } + } + (void)g_string_append( ddl, ")" ); + + return g_string_free( ddl, FALSE ); +} + +static /*@ null @*/ gchar* +conn_create_table_ddl_mysql( GncSqlConnection* conn, const gchar* table_name, + const GList* col_info_list ) +{ + GString* ddl; + const GList* list_node; + guint col_num; + gchar* type_name; + + g_return_val_if_fail( conn != NULL, NULL ); + g_return_val_if_fail( table_name != NULL, NULL ); + g_return_val_if_fail( col_info_list != NULL, NULL ); + + ddl = g_string_new( "" ); + g_string_printf( ddl, "CREATE TABLE %s (", table_name ); + for( list_node = col_info_list, col_num = 0; list_node != NULL; + list_node = list_node->next, col_num++ ) { + GncSqlColumnInfo* info = (GncSqlColumnInfo*)(list_node->data); + + if( col_num != 0 ) { + (void)g_string_append( ddl, ", " ); + } + switch( info->type ) { + case G_TYPE_INT: + type_name = "integer"; + break; + + case G_TYPE_INT64: + type_name = "bigint"; + break; + + case G_TYPE_DOUBLE: + type_name = "double"; + break; + + case G_TYPE_STRING: + type_name = "varchar"; + break; + + default: + PERR( "Unknown GType: %s\n", g_type_name( info->type ) ); + type_name = ""; + } + g_string_append_printf( ddl, "%s %s", info->name, type_name ); if( info->size != 0 ) { g_string_append_printf( ddl, "(%d)", info->size ); } @@ -1522,6 +1480,9 @@ conn_create_table_ddl_mysql( GncSqlConnection* conn, const gchar* table_name, if( info->is_primary_key ) { (void)g_string_append( ddl, " PRIMARY KEY" ); } + if( info->is_autoinc ) { + (void)g_string_append( ddl, " AUTO_INCREMENT" ); + } if( !info->null_allowed ) { (void)g_string_append( ddl, " NOT NULL" ); } @@ -1538,6 +1499,7 @@ conn_create_table_ddl_pgsql( GncSqlConnection* conn, const gchar* table_name, GString* ddl; const GList* list_node; guint col_num; + gchar* type_name; gboolean is_unicode = FALSE; g_return_val_if_fail( conn != NULL, NULL ); @@ -1553,8 +1515,32 @@ conn_create_table_ddl_pgsql( GncSqlConnection* conn, const gchar* table_name, if( col_num != 0 ) { (void)g_string_append( ddl, ", " ); } - g_string_append_printf( ddl, "%s %s", info->name, - gnc_sql_connection_get_column_type_name( conn, info->type, info->size ) ); + switch( info->type ) { + case G_TYPE_INT: + if( info->is_autoinc ) { + type_name = "sequence"; + } else { + type_name = "integer"; + } + break; + + case G_TYPE_INT64: + type_name = "int8"; + break; + + case G_TYPE_DOUBLE: + type_name = "double precision"; + break; + + case G_TYPE_STRING: + type_name = "varchar"; + break; + + default: + PERR( "Unknown GType: %s\n", g_type_name( info->type ) ); + type_name = ""; + } + g_string_append_printf( ddl, "%s %s", info->name, type_name ); if( info->size != 0 ) { g_string_append_printf( ddl, "(%d)", info->size ); } @@ -1721,7 +1707,6 @@ create_dbi_connection( /*@ observer @*/ provider_functions_t* provider, dbi_conn->base.beginTransaction = conn_begin_transaction; dbi_conn->base.rollbackTransaction = conn_rollback_transaction; dbi_conn->base.commitTransaction = conn_commit_transaction; - dbi_conn->base.getColumnTypeName = conn_get_column_type_name; dbi_conn->base.createTable = conn_create_table; dbi_conn->base.createIndex = conn_create_index; dbi_conn->base.quoteString = conn_quote_string; diff --git a/src/backend/sql/gnc-backend-sql.h b/src/backend/sql/gnc-backend-sql.h index b0dd4860c4..a197afec48 100644 --- a/src/backend/sql/gnc-backend-sql.h +++ b/src/backend/sql/gnc-backend-sql.h @@ -166,7 +166,6 @@ struct GncSqlConnection gboolean (*beginTransaction)( GncSqlConnection* ); /**< Returns TRUE if successful, FALSE if error */ gboolean (*rollbackTransaction)( GncSqlConnection* ); /**< Returns TRUE if successful, FALSE if error */ gboolean (*commitTransaction)( GncSqlConnection* ); /**< Returns TRUE if successful, FALSE if error */ - const gchar* (*getColumnTypeName)( GncSqlConnection*, GType, gint size ); gboolean (*createTable)( GncSqlConnection*, const gchar*, const GList* ); /**< Returns TRUE if successful, FALSE if error */ gboolean (*createIndex)( GncSqlConnection*, const gchar*, const gchar*, const GncSqlColumnTableEntry* ); /**< Returns TRUE if successful, FALSE if error */ gchar* (*quoteString)( const GncSqlConnection*, gchar* ); @@ -186,8 +185,6 @@ struct GncSqlConnection (CONN)->rollbackTransaction(CONN) #define gnc_sql_connection_commit_transaction(CONN) \ (CONN)->commitTransaction(CONN) -#define gnc_sql_connection_get_column_type_name(CONN,TYPE,SIZE) \ - (CONN)->getColumnTypeName(CONN,TYPE,SIZE) #define gnc_sql_connection_create_table(CONN,NAME,COLLIST) \ (CONN)->createTable(CONN,NAME,COLLIST) #define gnc_sql_connection_create_index(CONN,INDEXNAME,TABLENAME,COLTABLE) \ @@ -284,6 +281,7 @@ typedef struct { GType type; /**< Column basic type */ gint size; /**< Column size (string types) */ gboolean is_unicode; /**< Column is unicode (string types) */ + gboolean is_autoinc; /**< Column is autoinc (int type) */ gboolean is_primary_key; /**< Column is the primary key */ gboolean null_allowed; /**< Column allows NULL values */ } GncSqlColumnInfo;