From 633c1a75d1be08ed8d75dc4bdee4a7672cb61949 Mon Sep 17 00:00:00 2001 From: Phil Longstaff Date: Sat, 13 Sep 2008 18:49:57 +0000 Subject: [PATCH] If current lots version has account_guid constraint that it can't be null, remove it and bump table version number. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@17505 57a11ea4-9604-0410-9ed3-97b8803252fd --- src/backend/sql/gnc-backend-sql.c | 53 +++++++++++++------------------ src/backend/sql/gnc-backend-sql.h | 40 +++++++++++++++++++++-- src/backend/sql/gnc-lots-sql.c | 26 ++++++++++++++- 3 files changed, 85 insertions(+), 34 deletions(-) diff --git a/src/backend/sql/gnc-backend-sql.c b/src/backend/sql/gnc-backend-sql.c index ff00b04eb5..771d44b6cd 100644 --- a/src/backend/sql/gnc-backend-sql.c +++ b/src/backend/sql/gnc-backend-sql.c @@ -815,10 +815,6 @@ gnc_sql_init_object_handlers( void ) /* ================================================================= */ -static void register_table_version( const GncSqlBackend* be, const gchar* table_name, gint version ); -static gint get_table_version( const GncSqlBackend* be, const gchar* table_name ); - -/* ================================================================= */ static gint64 get_integer_value( const GValue* value ) { @@ -1972,8 +1968,8 @@ gnc_sql_execute_select_sql( const GncSqlBackend* be, gchar* sql ) return result; } -static gint -execute_nonselect_sql( const GncSqlBackend* be, gchar* sql ) +gint +gnc_sql_execute_nonselect_sql( const GncSqlBackend* be, gchar* sql ) { GncSqlStatement* stmt; gint result; @@ -2363,11 +2359,18 @@ gnc_sql_create_table( const GncSqlBackend* be, const gchar* table_name, ok = create_table( be, table_name, col_table ); if( ok ) { - register_table_version( be, table_name, table_version ); + (void)gnc_sql_set_table_version( be, table_name, table_version ); } return ok; } +gboolean +gnc_sql_create_temp_table( const GncSqlBackend* be, const gchar* table_name, + const GncSqlColumnTableEntry* col_table ) +{ + return create_table( be, table_name, col_table ); +} + void gnc_sql_create_index( const GncSqlBackend* be, const gchar* index_name, const gchar* table_name, @@ -2397,8 +2400,8 @@ gnc_sql_get_table_version( const GncSqlBackend* be, const gchar* table_name ) return 0; } - return get_table_version( be, table_name ); - } + return GPOINTER_TO_INT(g_hash_table_lookup( be->versions, table_name )); +} /* ================================================================= */ #define VERSION_TABLE_NAME "versions" @@ -2496,18 +2499,19 @@ gnc_sql_finalize_version_info( GncSqlBackend* be ) * @param be Backend struct * @param table_name Table name * @param version Version number + * @return TRUE if successful, FALSE if unsuccessful */ -static void -register_table_version( const GncSqlBackend* be, const gchar* table_name, gint version ) +gboolean +gnc_sql_set_table_version( const GncSqlBackend* be, const gchar* table_name, gint version ) { gchar* sql; gint cur_version; - g_return_if_fail( be != NULL ); - g_return_if_fail( table_name != NULL ); - g_return_if_fail( version > 0 ); + g_return_val_if_fail( be != NULL, FALSE ); + g_return_val_if_fail( table_name != NULL, FALSE ); + g_return_val_if_fail( version > 0, FALSE ); - cur_version = get_table_version( be, table_name ); + cur_version = gnc_sql_get_table_version( be, table_name ); if( cur_version != version ) { if( cur_version == 0 ) { sql = g_strdup_printf( "INSERT INTO %s VALUES('%s',%d)", VERSION_TABLE_NAME, @@ -2517,25 +2521,12 @@ register_table_version( const GncSqlBackend* be, const gchar* table_name, gint v VERSION_COL_NAME, version, TABLE_COL_NAME, table_name ); } - execute_nonselect_sql( be, sql ); + (void)gnc_sql_execute_nonselect_sql( be, sql ); } g_hash_table_insert( be->versions, g_strdup( table_name ), GINT_TO_POINTER(version) ); + + return TRUE; } -/** - * Returns the registered version number for a table. - * - * @param be Backend struct - * @param table_name Table name - * @return Version number - */ -static gint -get_table_version( const GncSqlBackend* be, const gchar* table_name ) -{ - g_return_val_if_fail( be != NULL, 0 ); - g_return_val_if_fail( table_name != NULL, 0 ); - - return GPOINTER_TO_INT(g_hash_table_lookup( be->versions, table_name )); -} /* ========================== END OF FILE ===================== */ diff --git a/src/backend/sql/gnc-backend-sql.h b/src/backend/sql/gnc-backend-sql.h index 2cd92160ee..592d78b8a4 100644 --- a/src/backend/sql/gnc-backend-sql.h +++ b/src/backend/sql/gnc-backend-sql.h @@ -434,6 +434,15 @@ GncSqlResult* gnc_sql_execute_select_statement( GncSqlBackend* be, GncSqlStateme */ GncSqlResult* gnc_sql_execute_select_sql( const GncSqlBackend* be, gchar* sql ); +/** + * Executes an SQL non-SELECT statement from an SQL char string. + * + * @param be SQL backend struct + * @param sql SQL non-SELECT string + * @returns Number of rows affected + */ +gint gnc_sql_execute_nonselect_sql( const GncSqlBackend* be, gchar* sql ); + /** * Creates a statement from an SQL char string. * @@ -480,6 +489,18 @@ gboolean gnc_sql_object_is_it_in_db( GncSqlBackend* be, */ gint gnc_sql_get_table_version( const GncSqlBackend* be, const gchar* table_name ); +/** + * Sets the version number for a DB table. + * + * @param be SQL backend struct + * @param table_name Table name + * @param table_version Table version + * @return TRUE if successful, FALSE if unsuccessful + */ +gboolean gnc_sql_set_table_version( const GncSqlBackend* be, + const gchar* table_name, + gint table_version ); + /** * Creates a table in the database * @@ -489,8 +510,23 @@ gint gnc_sql_get_table_version( const GncSqlBackend* be, const gchar* table_name * @param col_table DB table description * @return TRUE if successful, FALSE if unsuccessful */ -gboolean gnc_sql_create_table( const GncSqlBackend* be, const gchar* table_name, - gint table_version, const GncSqlColumnTableEntry* col_table ); +gboolean gnc_sql_create_table( const GncSqlBackend* be, + const gchar* table_name, + gint table_version, + const GncSqlColumnTableEntry* col_table ); + +/** + * Creates a temporary table in the database. A temporary table does not + * have a version number added to the versions table. + * + * @param be SQL backend struct + * @param table_name Table name + * @param col_table DB table description + * @return TRUE if successful, FALSE if unsuccessful + */ +gboolean gnc_sql_create_temp_table( const GncSqlBackend* be, + const gchar* table_name, + const GncSqlColumnTableEntry* col_table ); /** * Creates an index in the database diff --git a/src/backend/sql/gnc-lots-sql.c b/src/backend/sql/gnc-lots-sql.c index 90aae61276..352ef9243c 100644 --- a/src/backend/sql/gnc-lots-sql.c +++ b/src/backend/sql/gnc-lots-sql.c @@ -41,7 +41,7 @@ static QofLogModule log_module = G_LOG_DOMAIN; #define TABLE_NAME "lots" -#define TABLE_VERSION 1 +#define TABLE_VERSION 2 static gpointer get_lot_account( gpointer pObject, const QofParam* param ); static void set_lot_account( gpointer pObject, gpointer pValue ); @@ -157,7 +157,31 @@ create_lots_tables( GncSqlBackend* be ) version = gnc_sql_get_table_version( be, TABLE_NAME ); if( version == 0 ) { + /* The table doesn't exist, so create it */ gnc_sql_create_table( be, TABLE_NAME, TABLE_VERSION, col_table ); + } else if( version == 1 ) { + /* Version 1 -> 2 removes the 'NOT NULL' constraint on the account_guid + field. + + Create a temporary table, copy the data from the old table, delete the + old table, then rename the new one. */ + gchar* sql; +#define TEMP_TABLE_NAME "lots_new" + GncSqlStatement* stmt; + + gnc_sql_create_temp_table( be, TEMP_TABLE_NAME, col_table ); + sql = g_strdup_printf( "INSERT INTO %s SELECT * FROM %s", + TEMP_TABLE_NAME, TABLE_NAME ); + (void)gnc_sql_execute_nonselect_sql( be, sql ); + + sql = g_strdup_printf( "DROP TABLE %s", TABLE_NAME ); + (void)gnc_sql_execute_nonselect_sql( be, sql ); + + sql = g_strdup_printf( "ALTER TABLE %s RENAME TO %s", + TEMP_TABLE_NAME, TABLE_NAME ); + (void)gnc_sql_execute_nonselect_sql( be, sql ); + + gnc_sql_set_table_version( be, TABLE_NAME, TABLE_VERSION ); } }