Save timespec values into 'timestamp' in mysql and pgsql.

NOTE: with this change, the format of the tables has changed.


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@18248 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Phil Longstaff
2009-08-14 01:58:36 +00:00
parent ae4199adfc
commit a4ae2b6609
6 changed files with 82 additions and 57 deletions
+30 -19
View File
@@ -82,6 +82,7 @@ static provider_functions_t provider_sqlite3 =
conn_create_table_ddl_sqlite3,
conn_get_table_list
};
#define SQLITE3_TIMESPEC_STR_FORMAT "%04d%02d%02d%02d%02d%02d"
static /*@ null @*/ gchar* conn_create_table_ddl_mysql( GncSqlConnection* conn,
const gchar* table_name,
@@ -91,6 +92,7 @@ static provider_functions_t provider_mysql =
conn_create_table_ddl_mysql,
conn_get_table_list
};
#define MYSQL_TIMESPEC_STR_FORMAT "%04d%02d%02d%02d%02d%02d"
static /*@ null @*/ gchar* conn_create_table_ddl_pgsql( GncSqlConnection* conn,
const gchar* table_name,
@@ -101,6 +103,7 @@ static provider_functions_t provider_pgsql =
conn_create_table_ddl_pgsql,
conn_get_table_list_pgsql
};
#define PGSQL_TIMESPEC_STR_FORMAT "%04d%02d%02d %02d%02d%02d"
static /*@ null @*/ gchar* create_index_ddl( GncSqlConnection* conn,
const gchar* index_name,
@@ -247,6 +250,7 @@ gnc_dbi_sqlite3_session_begin( QofBackend *qbe, QofSession *session,
gnc_sql_connection_dispose( be->sql_be.conn );
}
be->sql_be.conn = create_dbi_connection( GNC_DBI_PROVIDER_SQLITE, qbe, be->conn );
be->sql_be.timespec_format = SQLITE3_TIMESPEC_STR_FORMAT;
LEAVE (" ");
}
@@ -430,6 +434,7 @@ gnc_dbi_mysql_session_begin( QofBackend* qbe, QofSession *session,
}
be->sql_be.conn = create_dbi_connection( GNC_DBI_PROVIDER_MYSQL, qbe, be->conn );
}
be->sql_be.timespec_format = MYSQL_TIMESPEC_STR_FORMAT;
exit:
if( dsn != NULL ) {
g_free( dsn );
@@ -566,6 +571,7 @@ gnc_dbi_postgres_session_begin( QofBackend *qbe, QofSession *session,
}
be->sql_be.conn = create_dbi_connection( GNC_DBI_PROVIDER_PGSQL, qbe, be->conn );
}
be->sql_be.timespec_format = PGSQL_TIMESPEC_STR_FORMAT;
exit:
if( dsn != NULL ) {
g_free( dsn );
@@ -1387,18 +1393,17 @@ conn_create_table_ddl_sqlite3( GncSqlConnection* conn,
if( col_num != 0 ) {
(void)g_string_append( ddl, ", " );
}
if( info->type == G_TYPE_INT ) {
if( info->type == BCT_INT ) {
type_name = "integer";
} else if( info->type == G_TYPE_INT64 ) {
} else if( info->type == BCT_INT64 ) {
type_name = "bigint";
} else if( info->type == G_TYPE_DOUBLE ) {
} else if( info->type == BCT_DOUBLE ) {
type_name = "real";
} else if( info->type == G_TYPE_STRING ) {
type_name = "text";
} else if( info->type == G_TYPE_DATE ) {
} else if( info->type == BCT_STRING || info->type == BCT_DATE
|| info->type == BCT_DATETIME ) {
type_name = "text";
} else {
PERR( "Unknown GType: %s\n", g_type_name( info->type ) );
PERR( "Unknown column type: %d\n", info->type );
type_name = "";
}
g_string_append_printf( ddl, "%s %s", info->name, type_name );
@@ -1442,19 +1447,22 @@ conn_create_table_ddl_mysql( GncSqlConnection* conn, const gchar* table_name,
if( col_num != 0 ) {
(void)g_string_append( ddl, ", " );
}
if( info->type == G_TYPE_INT ) {
if( info->type == BCT_INT ) {
type_name = "integer";
} else if( info->type == G_TYPE_INT64 ) {
} else if( info->type == BCT_INT64 ) {
type_name = "bigint";
} else if( info->type == G_TYPE_DOUBLE ) {
} else if( info->type == BCT_DOUBLE ) {
type_name = "double";
} else if( info->type == G_TYPE_STRING ) {
} else if( info->type == BCT_STRING ) {
type_name = "varchar";
} else if( info->type == G_TYPE_DATE ) {
} else if( info->type == BCT_DATE ) {
info->size = 0;
type_name = "date";
} else if( info->type == BCT_DATETIME ) {
info->size = 0;
type_name = "timestamp";
} else {
PERR( "Unknown GType: %s\n", g_type_name( info->type ) );
PERR( "Unknown column type: %d\n", info->type );
type_name = "";
}
g_string_append_printf( ddl, "%s %s", info->name, type_name );
@@ -1502,23 +1510,26 @@ conn_create_table_ddl_pgsql( GncSqlConnection* conn, const gchar* table_name,
if( col_num != 0 ) {
(void)g_string_append( ddl, ", " );
}
if( info->type == G_TYPE_INT ) {
if( info->type == BCT_INT ) {
if( info->is_autoinc ) {
type_name = "serial";
} else {
type_name = "integer";
}
} else if( info->type == G_TYPE_INT64 ) {
} else if( info->type == BCT_INT64 ) {
type_name = "int8";
} else if( info->type == G_TYPE_DOUBLE ) {
} else if( info->type == BCT_DOUBLE ) {
type_name = "double precision";
} else if( info->type == G_TYPE_STRING ) {
} else if( info->type == BCT_STRING ) {
type_name = "varchar";
} else if( info->type == G_TYPE_DATE ) {
} else if( info->type == BCT_DATE ) {
info->size = 0;
type_name = "date";
} else if( info->type == BCT_DATETIME ) {
info->size = 0;
type_name = "timestamp without time zone";
} else {
PERR( "Unknown GType: %s\n", g_type_name( info->type ) );
PERR( "Unknown column type: %d\n", info->type );
type_name = "";
}
g_string_append_printf( ddl, "%s %s", info->name, type_name );
+13 -13
View File
@@ -997,7 +997,7 @@ gnc_sql_add_subtable_colnames_to_list( const GncSqlColumnTableEntry* table_row,
}
static GncSqlColumnInfo*
create_column_info( const GncSqlColumnTableEntry* table_row, GType type,
create_column_info( const GncSqlColumnTableEntry* table_row, GncSqlBasicColumnType type,
gint size, gboolean is_unicode )
{
GncSqlColumnInfo* info;
@@ -1050,7 +1050,7 @@ add_string_col_info_to_list( const GncSqlBackend* be, const GncSqlColumnTableEnt
g_return_if_fail( table_row != NULL );
g_return_if_fail( pList != NULL );
info = create_column_info( table_row, G_TYPE_STRING, table_row->size, TRUE );
info = create_column_info( table_row, BCT_STRING, table_row->size, TRUE );
*pList = g_list_append( *pList, info );
}
@@ -1136,7 +1136,7 @@ add_int_col_info_to_list( const GncSqlBackend* be, const GncSqlColumnTableEntry*
g_return_if_fail( table_row != NULL );
g_return_if_fail( pList != NULL );
info = create_column_info( table_row, G_TYPE_INT, 0, FALSE );
info = create_column_info( table_row, BCT_INT, 0, FALSE );
*pList = g_list_append( *pList, info );
}
@@ -1220,7 +1220,7 @@ add_boolean_col_info_to_list( const GncSqlBackend* be, const GncSqlColumnTableEn
g_return_if_fail( table_row != NULL );
g_return_if_fail( pList != NULL );
info = create_column_info( table_row, G_TYPE_INT, 0, FALSE );
info = create_column_info( table_row, BCT_INT, 0, FALSE );
*pList = g_list_append( *pList, info );
}
@@ -1297,7 +1297,7 @@ add_int64_col_info_to_list( const GncSqlBackend* be, const GncSqlColumnTableEntr
g_return_if_fail( table_row != NULL );
g_return_if_fail( pList != NULL );
info = create_column_info( table_row, G_TYPE_INT64, 0, FALSE );
info = create_column_info( table_row, BCT_INT64, 0, FALSE );
*pList = g_list_append( *pList, info );
}
@@ -1376,7 +1376,7 @@ add_double_col_info_to_list( const GncSqlBackend* be, const GncSqlColumnTableEnt
g_return_if_fail( table_row != NULL );
g_return_if_fail( pList != NULL );
info = create_column_info( table_row, G_TYPE_DOUBLE, 0, FALSE );
info = create_column_info( table_row, BCT_DOUBLE, 0, FALSE );
*pList = g_list_append( *pList, info );
}
@@ -1461,7 +1461,7 @@ add_guid_col_info_to_list( const GncSqlBackend* be, const GncSqlColumnTableEntry
g_return_if_fail( table_row != NULL );
g_return_if_fail( pList != NULL );
info = create_column_info( table_row, G_TYPE_STRING, GUID_ENCODING_LENGTH, FALSE );
info = create_column_info( table_row, BCT_STRING, GUID_ENCODING_LENGTH, FALSE );
*pList = g_list_append( *pList, info );
}
@@ -1559,7 +1559,7 @@ typedef void (*TimespecSetterFunc)( const gpointer, Timespec );
#define TIMESPEC_COL_SIZE (4+2+2+2+2+2)
gchar*
gnc_sql_convert_timespec_to_string( Timespec ts )
gnc_sql_convert_timespec_to_string( const GncSqlBackend* be, Timespec ts )
{
time_t time;
struct tm* tm;
@@ -1572,7 +1572,7 @@ gnc_sql_convert_timespec_to_string( Timespec ts )
if( tm->tm_year < 60 ) year = tm->tm_year + 2000;
else year = tm->tm_year + 1900;
datebuf = g_strdup_printf( TIMESPEC_STR_FORMAT,
datebuf = g_strdup_printf( be->timespec_format,
year, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec );
return datebuf;
}
@@ -1627,7 +1627,7 @@ add_timespec_col_info_to_list( const GncSqlBackend* be, const GncSqlColumnTableE
g_return_if_fail( table_row != NULL );
g_return_if_fail( pList != NULL );
info = create_column_info( table_row, G_TYPE_STRING, TIMESPEC_COL_SIZE, FALSE );
info = create_column_info( table_row, BCT_DATETIME, TIMESPEC_COL_SIZE, FALSE );
*pList = g_list_append( *pList, info );
}
@@ -1651,7 +1651,7 @@ 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( ts );
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 );
@@ -1725,7 +1725,7 @@ add_date_col_info_to_list( const GncSqlBackend* be, const GncSqlColumnTableEntry
g_return_if_fail( table_row != NULL );
g_return_if_fail( pList != NULL );
info = create_column_info( table_row, G_TYPE_DATE, DATE_COL_SIZE, FALSE );
info = create_column_info( table_row, BCT_DATE, DATE_COL_SIZE, FALSE );
*pList = g_list_append( *pList, info );
}
@@ -1836,7 +1836,7 @@ add_numeric_col_info_to_list( const GncSqlBackend* be, const GncSqlColumnTableEn
info = g_new0( GncSqlColumnInfo, 1 );
g_assert( info != NULL );
info->name = buf;
info->type = G_TYPE_INT64;
info->type = BCT_INT64;
info->is_primary_key = ((table_row->flags & COL_PKEY) != 0) ? TRUE : FALSE;
info->null_allowed = ((table_row->flags & COL_NNUL) != 0) ? FALSE : TRUE;
info->is_unicode = FALSE;
+29 -15
View File
@@ -65,15 +65,16 @@ typedef struct GncSqlConnection GncSqlConnection;
*/
struct GncSqlBackend
{
QofBackend be; /**< QOF backend */
GncSqlConnection* conn; /**< SQL connection */
QofBackend be; /**< QOF backend */
GncSqlConnection* conn; /**< SQL connection */
/*@ dependent @*/ QofBook *primary_book; /**< The primary, main open book */
gboolean loading; /**< We are performing an initial load */
gboolean in_query; /**< We are processing a query */
gboolean is_pristine_db; /**< Are we saving to a new pristine db? */
gint obj_total; /**< Total # of objects (for percentage calculation) */
gint operations_done; /**< Number of operations (save/load) done */
GHashTable* versions; /**< Version number for each table */
gboolean loading; /**< We are performing an initial load */
gboolean in_query; /**< We are processing a query */
gboolean is_pristine_db; /**< Are we saving to a new pristine db? */
gint obj_total; /**< Total # of objects (for percentage calculation) */
gint operations_done; /**< Number of operations (save/load) done */
GHashTable* versions; /**< Version number for each table */
const gchar* timespec_format; /**< Format string for SQL for timespec values */
};
typedef struct GncSqlBackend GncSqlBackend;
@@ -270,6 +271,18 @@ typedef struct
#define GNC_SQL_BACKEND "gnc:sql:1"
#define GNC_SQL_BACKEND_VERSION 1
/**
* Basic column type
*/
typedef enum {
BCT_STRING,
BCT_INT,
BCT_INT64,
BCT_DATE,
BCT_DOUBLE,
BCT_DATETIME
} GncSqlBasicColumnType;
/**
* @struct GncSqlColumnInfo
*
@@ -278,12 +291,12 @@ typedef struct
*/
typedef struct {
/*@ only @*/ const gchar* name; /**< Column name */
GType type; /**< Column basic type */
gint size; /**< Column size (string types) */
gboolean is_unicode; /**< Column is unicode (string types) */
gboolean is_autoinc; /**< Column is autoinc (int type) */
gboolean is_primary_key; /**< Column is the primary key */
gboolean null_allowed; /**< Column allows NULL values */
GncSqlBasicColumnType type; /**< Column basic type */
gint size; /**< Column size (string types) */
gboolean is_unicode; /**< Column is unicode (string types) */
gboolean is_autoinc; /**< Column is autoinc (int type) */
gboolean is_primary_key; /**< Column is the primary key */
gboolean null_allowed; /**< Column allows NULL values */
} GncSqlColumnInfo;
// Type for conversion of db row to object.
@@ -679,10 +692,11 @@ gint64 gnc_sql_get_integer_value( const GValue* value );
/**
* Converts a Timespec value to a string value for the database.
*
* @param be SQL backend
* @param ts Timespec to be converted
* @return String representation of the Timespec
*/
gchar* gnc_sql_convert_timespec_to_string( Timespec ts );
gchar* gnc_sql_convert_timespec_to_string( const GncSqlBackend* be, Timespec ts );
/**
* Upgrades a table to a new structure. The upgrade is done by creating a new table with
+7 -7
View File
@@ -795,7 +795,7 @@ convert_query_comparison_to_sql( QofQueryPredData* pPredData, gboolean isInverte
}
static void
convert_query_term_to_sql( const gchar* fieldName, QofQueryTerm* pTerm, GString* sql )
convert_query_term_to_sql( const GncSqlBackend* be, const gchar* fieldName, QofQueryTerm* pTerm, GString* sql )
{
GSList* pParamPath;
QofQueryPredData* pPredData;
@@ -912,7 +912,7 @@ convert_query_term_to_sql( const gchar* fieldName, QofQueryTerm* pTerm, GString*
query_date_t date_data = (query_date_t)pPredData;
gchar* datebuf;
datebuf = gnc_sql_convert_timespec_to_string( date_data->date );
datebuf = gnc_sql_convert_timespec_to_string( be, date_data->date );
g_string_append_printf( sql, "'%s'", datebuf );
} else if( strcmp( pPredData->type_name, QOF_TYPE_INT32 ) == 0 ) {
@@ -998,13 +998,13 @@ compile_split_query( GncSqlBackend* be, QofQuery* query )
if( strcmp( paramPath->data, SPLIT_ACCOUNT ) == 0
&& strcmp( paramPath->next->data, QOF_PARAM_GUID ) == 0 ) {
convert_query_term_to_sql( "s.account_guid", term, sql );
convert_query_term_to_sql( be, "s.account_guid", term, sql );
#if SIMPLE_QUERY_COMPILATION
goto done_compiling_query;
#endif
} else if( strcmp( paramPath->data, SPLIT_RECONCILE ) == 0 ) {
convert_query_term_to_sql( "s.reconcile_state", term, sql );
convert_query_term_to_sql( be, "s.reconcile_state", term, sql );
} else if( strcmp( paramPath->data, SPLIT_TRANS ) == 0 ) {
#if 0
@@ -1014,15 +1014,15 @@ compile_split_query( GncSqlBackend* be, QofQuery* query )
}
#endif
if( strcmp( paramPath->next->data, TRANS_DATE_POSTED ) == 0 ) {
convert_query_term_to_sql( "t.post_date", term, sql );
convert_query_term_to_sql( be, "t.post_date", term, sql );
} else if( strcmp( paramPath->next->data, TRANS_DESCRIPTION ) == 0 ) {
convert_query_term_to_sql( "t.description", term, sql );
convert_query_term_to_sql( be, "t.description", term, sql );
} else {
unknownPath = TRUE;
}
} else if( strcmp( paramPath->data, SPLIT_VALUE ) == 0 ) {
convert_query_term_to_sql( "s.value_num/s.value_denom", term, sql );
convert_query_term_to_sql( be, "s.value_num/s.value_denom", term, sql );
} else {
unknownPath = TRUE;
@@ -121,7 +121,7 @@ add_address_col_info_to_list( const GncSqlBackend* be, const GncSqlColumnTableEn
buf = g_strdup_printf( "%s_%s", table_row->col_name, subtable_row->col_name );
info = g_new0( GncSqlColumnInfo, 1 );
info->name = buf;
info->type = G_TYPE_STRING;
info->type = BCT_STRING;
info->size = subtable_row->size;
info->is_primary_key = (table_row->flags & COL_PKEY) ? TRUE : FALSE;
info->null_allowed = (table_row->flags & COL_NNUL) ? FALSE : TRUE;
@@ -166,7 +166,7 @@ add_owner_col_info_to_list( const GncSqlBackend* be, const GncSqlColumnTableEntr
buf = g_strdup_printf( "%s_type", table_row->col_name );
info = g_new0( GncSqlColumnInfo, 1 );
info->name = buf;
info->type = G_TYPE_INT;
info->type = BCT_INT;
info->is_primary_key = (table_row->flags & COL_PKEY) ? TRUE : FALSE;
info->null_allowed = (table_row->flags & COL_NNUL) ? FALSE : TRUE;
info->size = table_row->size;
@@ -176,7 +176,7 @@ add_owner_col_info_to_list( const GncSqlBackend* be, const GncSqlColumnTableEntr
buf = g_strdup_printf( "%s_guid", table_row->col_name );
info = g_new0( GncSqlColumnInfo, 1 );
info->name = buf;
info->type = G_TYPE_STRING;
info->type = BCT_STRING;
info->size = GUID_ENCODING_LENGTH;
info->is_primary_key = (table_row->flags & COL_PKEY) ? TRUE : FALSE;
info->null_allowed = (table_row->flags & COL_NNUL) ? FALSE : TRUE;