r18424 - gnucash/trunk/src - Fix bug 593581 - 2.3.5: Save to MySQL still fails with date error

Phil Longstaff plongstaff at code.gnucash.org
Thu Nov 19 20:20:47 EST 2009


Author: plongstaff
Date: 2009-11-19 20:20:47 -0500 (Thu, 19 Nov 2009)
New Revision: 18424
Trac: http://svn.gnucash.org/trac/changeset/18424

Modified:
   gnucash/trunk/src/backend/sql/gnc-backend-sql.c
   gnucash/trunk/src/backend/sql/gnc-transaction-sql.c
   gnucash/trunk/src/business/business-core/sql/gnc-entry-sql.c
   gnucash/trunk/src/business/business-core/sql/gnc-invoice-sql.c
Log:
Fix bug 593581 -  2.3.5: Save to MySQL still fails with date error

After the change storing date-time values as a TIMESTAMP, a Timespec value of 0 could be stored in
mysql (I'm in EST timezone) because it converted to "19700101000000" which is "19700101050000" UTC
which is in the valid TIMESTAMP range of >= "19700101000001".  However, someone in UTC couldn't
store that value because it is treated as in the local timezone, and for someone in UK, it is out of
range.

This change changes 0 Timespec values to NULL db values.  Slots already allow NULL TIMESPEC values.
There are a few places where the db schema needs to be changed to allow NULL values.


Modified: gnucash/trunk/src/backend/sql/gnc-backend-sql.c
===================================================================
--- gnucash/trunk/src/backend/sql/gnc-backend-sql.c	2009-11-19 19:51:20 UTC (rev 18423)
+++ gnucash/trunk/src/backend/sql/gnc-backend-sql.c	2009-11-20 01:20:47 UTC (rev 18424)
@@ -1608,17 +1608,19 @@
     } else {
 		if( G_VALUE_HOLDS_STRING( val ) ) {
 			const gchar* s = g_value_get_string( val );
-			gchar* buf;
-			buf = g_strdup_printf( "%c%c%c%c-%c%c-%c%c %c%c:%c%c:%c%c",
-									s[0], s[1], s[2], s[3],
-									s[4], s[5],
-									s[6], s[7],
-									s[8], s[9],
-									s[10], s[11],
-									s[12], s[13] );
-		    ts = gnc_iso8601_to_timespec_gmt( buf );
-			(*ts_setter)( pObject, ts );
-			g_free( buf );
+			if( s != NULL ) {
+			    gchar* buf;
+			    buf = g_strdup_printf( "%c%c%c%c-%c%c-%c%c %c%c:%c%c:%c%c",
+									    s[0], s[1], s[2], s[3],
+									    s[4], s[5],
+									    s[6], s[7],
+									    s[8], s[9],
+									    s[10], s[11],
+									    s[12], s[13] );
+		        ts = gnc_iso8601_to_timespec_gmt( buf );
+			    (*ts_setter)( pObject, ts );
+			    g_free( buf );
+		    }
 
 		} else {
 			PWARN( "Unknown timespec type: %s", G_VALUE_TYPE_NAME( val ) );
@@ -1660,11 +1662,13 @@
 	g_return_if_fail( ts_getter != NULL );
     ts = (*ts_getter)( pObject );
 
-    datebuf = gnc_sql_convert_timespec_to_string( be, ts );
     value = g_new0( GValue, 1 );
 	g_assert( value != NULL );
     (void)g_value_init( value, G_TYPE_STRING );
-	g_value_take_string( value, datebuf );
+	if( ts.tv_sec != 0 || ts.tv_nsec != 0 ) {
+        datebuf = gnc_sql_convert_timespec_to_string( be, ts );
+	    g_value_take_string( value, datebuf );
+    }
 
 	(*pList) = g_slist_append( (*pList), value );
 }
@@ -1756,9 +1760,9 @@
 
     value = g_new0( GValue, 1 );
 	g_assert( value != NULL );
+    (void)g_value_init( value, G_TYPE_STRING );
     getter = gnc_sql_get_getter( obj_name, table_row );
 	if( getter != NULL ) {
-    	(void)g_value_init( value, G_TYPE_STRING );
     	date = (GDate*)(*getter)( pObject, NULL );
 		if( g_date_valid( date ) ) {
 			buf = g_strdup_printf( "%04d%02d%02d",

Modified: gnucash/trunk/src/backend/sql/gnc-transaction-sql.c
===================================================================
--- gnucash/trunk/src/backend/sql/gnc-transaction-sql.c	2009-11-19 19:51:20 UTC (rev 18423)
+++ gnucash/trunk/src/backend/sql/gnc-transaction-sql.c	2009-11-20 01:20:47 UTC (rev 18424)
@@ -60,7 +60,7 @@
 #define TRANSACTION_TABLE "transactions"
 #define TX_TABLE_VERSION 2
 #define SPLIT_TABLE "splits"
-#define SPLIT_TABLE_VERSION 3
+#define SPLIT_TABLE_VERSION 4
 
 typedef struct {
     /*@ dependent @*/ GncSqlBackend* be;
@@ -107,7 +107,7 @@
     { "action",          CT_STRING,       SPLIT_MAX_ACTION_LEN, COL_NNUL,          NULL, SPLIT_ACTION },
     { "reconcile_state", CT_STRING,       1,                    COL_NNUL,          NULL, NULL,
 			(QofAccessFunc)get_split_reconcile_state, set_split_reconcile_state },
-    { "reconcile_date",  CT_TIMESPEC,     0,                    COL_NNUL,          NULL, NULL,
+    { "reconcile_date",  CT_TIMESPEC,     0,                    0,                 NULL, NULL,
 			(QofAccessFunc)xaccSplitRetDateReconciledTS, (QofSetterFunc)set_split_reconcile_date },
     { "value",           CT_NUMERIC,      0,                    COL_NNUL,          NULL, SPLIT_VALUE },
     { "quantity",        CT_NUMERIC,      0,                    COL_NNUL,          NULL, SPLIT_AMOUNT },
@@ -495,6 +495,12 @@
 			if( !ok ) {
 				PERR( "Unable to create index\n" );
 			}
+
+			/* fallthrough */
+
+		case 3:
+		    /* Split reconcile_date can be NULL */
+		    gnc_sql_upgrade_table( be, SPLIT_TABLE, split_col_table );
 		}
 		(void)gnc_sql_set_table_version( be, SPLIT_TABLE, SPLIT_TABLE_VERSION );
     }

Modified: gnucash/trunk/src/business/business-core/sql/gnc-entry-sql.c
===================================================================
--- gnucash/trunk/src/business/business-core/sql/gnc-entry-sql.c	2009-11-19 19:51:20 UTC (rev 18423)
+++ gnucash/trunk/src/business/business-core/sql/gnc-entry-sql.c	2009-11-20 01:20:47 UTC (rev 18424)
@@ -53,7 +53,7 @@
 static QofLogModule log_module = G_LOG_DOMAIN;
 
 #define TABLE_NAME "entries"
-#define TABLE_VERSION 2
+#define TABLE_VERSION 3
 #define MAX_DESCRIPTION_LEN 2048
 #define MAX_ACTION_LEN 2048
 #define MAX_NOTES_LEN 2048
@@ -66,7 +66,7 @@
 {
 	{ "guid",          CT_GUID,        0,                   COL_NNUL|COL_PKEY, "guid" },
 	{ "date",          CT_TIMESPEC,    0,                   COL_NNUL,          NULL, ENTRY_DATE },
-	{ "entered",       CT_TIMESPEC,    0,                   COL_NNUL,          NULL, ENTRY_DATE_ENTERED },
+	{ "date_entered",  CT_TIMESPEC,    0,                   0,                 NULL, ENTRY_DATE_ENTERED },
 	{ "description",   CT_STRING,      MAX_DESCRIPTION_LEN, 0,                 NULL, ENTRY_DESC },
 	{ "action",        CT_STRING,      MAX_ACTION_LEN,      0,                 NULL, ENTRY_ACTION },
 	{ "notes",         CT_STRING,      MAX_NOTES_LEN,       0,                 NULL, ENTRY_NOTES },
@@ -182,8 +182,11 @@
 	version = gnc_sql_get_table_version( be, TABLE_NAME );
     if( version == 0 ) {
         gnc_sql_create_table( be, TABLE_NAME, TABLE_VERSION, col_table );
-    } else if( version == 1 ) {
-		/* Upgrade 64 bit int handling */
+    } else if( version < TABLE_VERSION ) {
+		/* Upgrade:
+		    1->2: 64 bit int handling
+			2->3: "entered" -> "date_entered", and it can be NULL
+		*/
 		gnc_sql_upgrade_table( be, TABLE_NAME, col_table );
 		gnc_sql_set_table_version( be, TABLE_NAME, TABLE_VERSION );
     }

Modified: gnucash/trunk/src/business/business-core/sql/gnc-invoice-sql.c
===================================================================
--- gnucash/trunk/src/business/business-core/sql/gnc-invoice-sql.c	2009-11-19 19:51:20 UTC (rev 18423)
+++ gnucash/trunk/src/business/business-core/sql/gnc-invoice-sql.c	2009-11-20 01:20:47 UTC (rev 18424)
@@ -51,7 +51,7 @@
 static QofLogModule log_module = G_LOG_DOMAIN;
 
 #define TABLE_NAME "invoices"
-#define TABLE_VERSION 2
+#define TABLE_VERSION 3
 
 #define MAX_ID_LEN 2048
 #define MAX_NOTES_LEN 2048
@@ -61,7 +61,7 @@
 {
 	{ "guid",         CT_GUID,         0,                  COL_NNUL|COL_PKEY, "guid" },
 	{ "id",           CT_STRING,       MAX_ID_LEN,         COL_NNUL,          NULL, INVOICE_ID },
-	{ "date_opened",  CT_TIMESPEC,     0,                  COL_NNUL,          NULL, INVOICE_OPENED },
+	{ "date_opened",  CT_TIMESPEC,     0,                  0,                 NULL, INVOICE_OPENED },
 	{ "date_posted",  CT_TIMESPEC,     0,                  0,                 NULL, INVOICE_POSTED },
 	{ "notes",        CT_STRING,       MAX_NOTES_LEN,      COL_NNUL,          NULL, INVOICE_NOTES },
 	{ "active",       CT_BOOLEAN,      0,                  COL_NNUL,          NULL, QOF_PARAM_ACTIVE },
@@ -147,8 +147,11 @@
 	version = gnc_sql_get_table_version( be, TABLE_NAME );
     if( version == 0 ) {
         gnc_sql_create_table( be, TABLE_NAME, TABLE_VERSION, col_table );
-    } else if( version == 1 ) {
-		/* Upgrade 64 bit int handling */
+    } else if( version < TABLE_VERSION ) {
+		/* Upgrade:
+		     1->2: 64 bit int handling
+			 2->3: invoice open date can be NULL
+		*/
 		gnc_sql_upgrade_table( be, TABLE_NAME, col_table );
 		gnc_sql_set_table_version( be, TABLE_NAME, TABLE_VERSION );
     }



More information about the gnucash-changes mailing list