AUDIT: r23174 - gnucash/trunk/src/backend - Bug 674862 - 2038 bug in libdbi
John Ralls
jralls at code.gnucash.org
Tue Sep 17 19:26:11 EDT 2013
Author: jralls
Date: 2013-09-17 19:26:10 -0400 (Tue, 17 Sep 2013)
New Revision: 23174
Trac: http://svn.gnucash.org/trac/changeset/23174
Modified:
gnucash/trunk/src/backend/dbi/gnc-backend-dbi.c
gnucash/trunk/src/backend/sql/gnc-backend-sql.c
Log:
Bug 674862 - 2038 bug in libdbi
Retrieve the numerical value directly from the dbi_result and use
it to create the Timespec or GDate.
BP
Modified: gnucash/trunk/src/backend/dbi/gnc-backend-dbi.c
===================================================================
--- gnucash/trunk/src/backend/dbi/gnc-backend-dbi.c 2013-09-17 23:25:43 UTC (rev 23173)
+++ gnucash/trunk/src/backend/dbi/gnc-backend-dbi.c 2013-09-17 23:26:10 UTC (rev 23174)
@@ -65,6 +65,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"
@@ -2008,7 +2011,6 @@
gushort type;
guint attrs;
GValue* value;
- time64 time;
type = dbi_result_get_field_type( dbi_row->result, col_name );
attrs = dbi_result_get_field_attribs( dbi_row->result, col_name );
@@ -2048,27 +2050,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)
- {
- struct tm *tm_struct = gnc_gmtime (&time);
- (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));
- gnc_tm_free (tm_struct);
- }
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;
+ time64 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/trunk/src/backend/sql/gnc-backend-sql.c
===================================================================
--- gnucash/trunk/src/backend/sql/gnc-backend-sql.c 2013-09-17 23:25:43 UTC (rev 23173)
+++ gnucash/trunk/src/backend/sql/gnc-backend-sql.c 2013-09-17 23:26:10 UTC (rev 23174)
@@ -1938,8 +1938,13 @@
}
else
{
- if ( G_VALUE_HOLDS_STRING( val ) )
+ if ( G_VALUE_HOLDS_INT64( val ) )
{
+ timespecFromTime64 (&ts, (time64)(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 )
{
@@ -1955,7 +1960,6 @@
g_free( buf );
isOK = TRUE;
}
-
}
else
{
@@ -2047,7 +2051,6 @@
const GncSqlColumnTableEntry* table_row )
{
const GValue* val;
- GDate* date;
g_return_if_fail( be != NULL );
g_return_if_fail( row != NULL );
@@ -2058,11 +2061,30 @@
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))
+ {
+ gint64 time = g_value_get_int64 (val);
+ GDateTime *gdt = g_date_time_new_from_unix_utc (time);
+ gint day, month, year;
+ GDate *date;
+ g_date_time_get_ymd (gdt, &year, &month, &day);
+ date = g_date_new_dmy (day, month, year);
+ g_date_time_unref (gdt);
+ if ( table_row->gobj_param_name != NULL )
+ {
+ g_object_set( pObject, table_row->gobj_param_name, date, NULL );
+ }
+ else
+ {
+ (*setter)( pObject, date );
+ }
+ g_date_free( 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