r23177 - gnucash/branches/2.4/src/backend - [r23174]Bug #674862 - 2038 bug in libdbi
John Ralls
jralls at code.gnucash.org
Thu Sep 19 12:32:26 EDT 2013
Author: jralls
Date: 2013-09-19 12:32:25 -0400 (Thu, 19 Sep 2013)
New Revision: 23177
Trac: http://svn.gnucash.org/trac/changeset/23177
Modified:
gnucash/branches/2.4/src/backend/dbi/gnc-backend-dbi.c
gnucash/branches/2.4/src/backend/sql/gnc-backend-sql.c
Log:
[r23174]Bug #674862 - 2038 bug in libdbi
Retrieve the numerical value directly from the dbi_result and use
it to create the Timespec or GDate.
NB: In Gnucash 2.4 there are plenty of other 2038 bugs due to reliance
on the libc time functions. This has been corrected in trunk.
Modified: gnucash/branches/2.4/src/backend/dbi/gnc-backend-dbi.c
===================================================================
--- gnucash/branches/2.4/src/backend/dbi/gnc-backend-dbi.c 2013-09-18 10:13:14 UTC (rev 23176)
+++ gnucash/branches/2.4/src/backend/dbi/gnc-backend-dbi.c 2013-09-19 16:32:25 UTC (rev 23177)
@@ -66,6 +66,9 @@
#define GETPID() getpid()
#endif
+/* For direct access to dbi data structs, sadly needed for datetime */
+#include <dbi/dbi-dev.h>
+
#define GNC_HOST_NAME_MAX 255
#define TRANSACTION_NAME "trans"
@@ -2007,8 +2010,6 @@
gushort type;
guint attrs;
GValue* value;
- time_t time;
- struct tm tm_struct;
type = dbi_result_get_field_type( dbi_row->result, col_name );
attrs = dbi_result_get_field_attribs( dbi_row->result, col_name );
@@ -2048,26 +2049,20 @@
{
return NULL;
}
- time = dbi_result_get_datetime( dbi_row->result, col_name );
- /* Protect gmtime from time values < 0 to work around a mingw
- bug that fills struct_tm with garbage values which in turn
- creates a string that GDate can't parse. */
- if (time >= 0)
- {
- (void)gmtime_r( &time, &tm_struct );
- (void)g_value_init( value, G_TYPE_STRING );
- g_value_take_string( value,
- g_strdup_printf( "%d%02d%02d%02d%02d%02d",
- 1900 + tm_struct.tm_year,
- tm_struct.tm_mon + 1,
- tm_struct.tm_mday,
- tm_struct.tm_hour,
- tm_struct.tm_min,
- tm_struct.tm_sec ) );
- }
else
- g_value_take_string (value, "19691231235959");
-
+ {
+ /* A seriously evil hack to work around libdbi bug #15
+ * https://sourceforge.net/p/libdbi/bugs/15/. When libdbi
+ * v0.9 is widely available this can be replaced with
+ * dbi_result_get_as_longlong.
+ */
+ dbi_result_t *result = (dbi_result_t*)(dbi_row->result);
+ guint64 row = dbi_result_get_currow (result);
+ guint idx = dbi_result_get_field_idx (result, col_name) - 1;
+ gint64 time = result->rows[row]->field_values[idx].d_datetime;
+ (void)g_value_init( value, G_TYPE_INT64 );
+ g_value_set_int64 (value, time);
+ }
break;
default:
PERR( "Field %s: unknown DBI_TYPE: %d\n", col_name, type );
Modified: gnucash/branches/2.4/src/backend/sql/gnc-backend-sql.c
===================================================================
--- gnucash/branches/2.4/src/backend/sql/gnc-backend-sql.c 2013-09-18 10:13:14 UTC (rev 23176)
+++ gnucash/branches/2.4/src/backend/sql/gnc-backend-sql.c 2013-09-19 16:32:25 UTC (rev 23177)
@@ -1951,8 +1951,13 @@
}
else
{
- if ( G_VALUE_HOLDS_STRING( val ) )
+ if ( G_VALUE_HOLDS_INT64( val ) )
{
+ ts.tv_sec = g_value_get_int64 (val);
+ isOK = TRUE;
+ }
+ else if (G_VALUE_HOLDS_STRING (val))
+ {
const gchar* s = g_value_get_string( val );
if ( s != NULL )
{
@@ -1968,7 +1973,6 @@
g_free( buf );
isOK = TRUE;
}
-
}
else
{
@@ -2060,7 +2064,6 @@
const GncSqlColumnTableEntry* table_row )
{
const GValue* val;
- GDate* date;
g_return_if_fail( be != NULL );
g_return_if_fail( row != NULL );
@@ -2071,11 +2074,28 @@
val = gnc_sql_row_get_value_at_col_name( row, table_row->col_name );
if ( val != NULL )
{
- if ( G_VALUE_HOLDS_STRING( val ) )
+ if (G_VALUE_HOLDS_INT64 (val))
+ {
+ Timespec ts = {0, 0};
+ GDate date;
+ ts.tv_sec = g_value_get_int64 (val);
+ date = timespec_to_gdate (ts);
+
+ if ( table_row->gobj_param_name != NULL )
+ {
+ g_object_set( pObject, table_row->gobj_param_name,
+ &date, NULL );
+ }
+ else
+ {
+ (*setter)( pObject, &date );
+ }
+ }
+ else if ( G_VALUE_HOLDS_STRING( val ) )
{
// Format of date is YYYYMMDD
const gchar* s = g_value_get_string( val );
-
+ GDate *date;
if ( s != NULL )
{
gchar buf[5];
More information about the gnucash-changes
mailing list