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.


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@18424 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Phil Longstaff 2009-11-20 01:20:47 +00:00
parent 6a7221cc3b
commit 3a7399da2e
4 changed files with 40 additions and 24 deletions

View File

@ -1608,17 +1608,19 @@ load_timespec( const GncSqlBackend* be, GncSqlRow* row,
} 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 @@ add_gvalue_timespec_to_slist( const GncSqlBackend* be, QofIdTypeConst obj_name,
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 @@ add_gvalue_date_to_slist( const GncSqlBackend* be, QofIdTypeConst obj_name,
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",

View File

@ -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 @@ static const GncSqlColumnTableEntry split_col_table[] =
{ "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 @@ create_transaction_tables( GncSqlBackend* be )
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 );
}

View File

@ -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 @@ static GncSqlColumnTableEntry col_table[] =
{
{ "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 @@ create_entry_tables( GncSqlBackend* be )
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 );
}

View File

@ -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 @@ static GncSqlColumnTableEntry col_table[] =
{
{ "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 @@ create_invoice_tables( GncSqlBackend* be )
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 );
}