r15334 - gnucash/branches/gda-dev/src/backend/gda - Add missing files
Phil Longstaff
plongstaff at cvs.gnucash.org
Tue Jan 9 15:59:04 EST 2007
Author: plongstaff
Date: 2007-01-09 15:59:02 -0500 (Tue, 09 Jan 2007)
New Revision: 15334
Trac: http://svn.gnucash.org/trac/changeset/15334
Added:
gnucash/branches/gda-dev/src/backend/gda/gnc-backend-util-gda.c
gnucash/branches/gda-dev/src/backend/gda/gnc-backend-util-gda.h
Log:
Add missing files
Added: gnucash/branches/gda-dev/src/backend/gda/gnc-backend-util-gda.c
===================================================================
--- gnucash/branches/gda-dev/src/backend/gda/gnc-backend-util-gda.c 2007-01-09 20:32:32 UTC (rev 15333)
+++ gnucash/branches/gda-dev/src/backend/gda/gnc-backend-util-gda.c 2007-01-09 20:59:02 UTC (rev 15334)
@@ -0,0 +1,1412 @@
+/********************************************************************
+ * gnc-backend-util-gda.c: load and save data to SQL via libgda *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License as *
+ * published by the Free Software Foundation; either version 2 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact: *
+ * *
+ * Free Software Foundation Voice: +1-617-542-5942 *
+ * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
+ * Boston, MA 02110-1301, USA gnu at gnu.org *
+\********************************************************************/
+/** @file gnc-backend-util-gda.c
+ * @brief load and save data to SQL - utility functions
+ * @author Copyright (c) 2006 Phil Longstaff <plongstaff at rogers.com>
+ *
+ * This file implements the top-level QofBackend API for saving/
+ * restoring data to/from an SQL db using libgda
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <libgda/libgda.h>
+
+#include "qof.h"
+#include "qofquery-p.h"
+#include "qofquerycore-p.h"
+#include "TransLog.h"
+#include "gnc-engine.h"
+
+#include "gnc-backend-util-gda.h"
+#include "gnc-gconf-utils.h"
+
+static const gchar* convert_search_obj( QofIdType objType );
+static void gnc_gda_init_object_handlers( void );
+static void add_table_column( GdaServerProvider* server, GdaConnection* cnn,
+ xmlNodePtr array_data, const gchar* arg, const gchar* dbms_type,
+ gint size, gint flags );
+
+typedef struct {
+ QofIdType searchObj;
+ gpointer pCompiledQuery;
+} gnc_gda_query_info;
+
+/* callback structure */
+typedef struct {
+ gboolean ok;
+ GncGdaBackend* be;
+ QofInstance* inst;
+ QofQuery* pQuery;
+ gpointer pCompiledQuery;
+ gnc_gda_query_info* pQueryInfo;
+} gda_backend;
+
+static QofLogModule log_module = GNC_MOD_BACKEND;
+
+typedef void (*GNC_GDA_LOAD_FN)( GdaDataModel* pModel, gint row,
+ QofSetterFunc setter, gpointer pObject,
+ const col_cvt_t* table );
+typedef void (*GNC_GDA_CREATE_COL_FN)( GdaServerProvider* server,
+ GdaConnection* cnn, xmlNodePtr array_data,
+ const col_cvt_t* table_row );
+typedef void (*GNC_GDA_GET_GVALUE_QUERY_FN)( GncGdaBackend* be,
+ QofIdTypeConst obj_name, gpointer pObject,
+ const col_cvt_t* table_row, GdaQuery* query );
+typedef GdaQueryCondition* (*GNC_GDA_GET_GVALUE_COND_FN)( GncGdaBackend* be,
+ QofIdTypeConst obj_name, gpointer pObject,
+ const col_cvt_t* table_row, GdaQuery* query );
+
+typedef struct {
+ GNC_GDA_LOAD_FN load_fn;
+ GNC_GDA_CREATE_COL_FN create_col_fn;
+ GNC_GDA_GET_GVALUE_QUERY_FN get_gvalue_query_fn;
+ GNC_GDA_GET_GVALUE_COND_FN get_gvalue_cond_fn;
+} col_type_handler_t;
+
+
+/* ================================================================= */
+static void
+add_field_to_query( GdaQuery* query, const gchar* col_name, const GValue* value )
+{
+ GdaQueryField* field;
+ GdaQueryField* field_value;
+
+ field = gda_query_field_field_new( query, col_name );
+ gda_query_field_set_visible( field, TRUE );
+
+ field_value = gda_query_field_value_new( query, G_VALUE_TYPE(value) );
+ gda_query_field_set_visible( field_value, TRUE );
+ gda_query_field_value_set_value( GDA_QUERY_FIELD_VALUE(field_value), value );
+ g_object_set( field, "value-provider", field_value, NULL );
+ g_object_unref( G_OBJECT(field_value) );
+
+ gda_entity_add_field( GDA_ENTITY(query), GDA_ENTITY_FIELD(field) );
+ g_object_unref( G_OBJECT(field) );
+}
+
+GdaQueryCondition*
+gnc_gda_create_condition_from_field( GdaQuery* query, const gchar* col_name,
+ const GValue* value )
+{
+ GdaQueryCondition* cond;
+ GdaQueryField* key;
+ GdaQueryField* key_value;
+
+ cond = gda_query_condition_new( query, GDA_QUERY_CONDITION_LEAF_EQUAL );
+
+ key = gda_query_field_field_new( query, col_name );
+ gda_query_field_set_visible( key, TRUE );
+ gda_query_condition_leaf_set_operator( cond,
+ GDA_QUERY_CONDITION_OP_LEFT,
+ GDA_QUERY_FIELD(key) );
+ g_object_unref( G_OBJECT(key) );
+
+ key_value = gda_query_field_value_new( query, G_VALUE_TYPE(value) );
+ gda_query_field_set_visible( key_value, TRUE );
+ gda_query_condition_leaf_set_operator( cond, GDA_QUERY_CONDITION_OP_RIGHT,
+ GDA_QUERY_FIELD(key_value) );
+ g_object_unref( G_OBJECT(key_value) );
+
+ gda_query_field_value_set_value( GDA_QUERY_FIELD_VALUE(key_value), value );
+
+ return cond;
+}
+/* ----------------------------------------------------------------- */
+static QofAccessFunc
+get_getter( QofIdTypeConst obj_name, const col_cvt_t* table_row )
+{
+ QofAccessFunc getter;
+
+ if( table_row->param_name != NULL ) {
+ getter = qof_class_get_parameter_getter( obj_name,
+ table_row->param_name );
+ } else {
+ getter = table_row->getter;
+ }
+
+ return getter;
+}
+
+static void
+load_string( GdaDataModel* pModel, gint row,
+ QofSetterFunc setter, gpointer pObject,
+ const col_cvt_t* table )
+{
+ const GValue* val;
+ const gchar* s;
+
+ val = gda_data_model_get_value_at_col_name( pModel, table->col_name, row );
+ if( gda_value_is_null( val ) ) {
+ s = NULL;
+ } else {
+ s = g_value_get_string( val );
+ }
+ (*setter)( pObject, (const gpointer)s );
+}
+
+static void
+get_gvalue_string( GncGdaBackend* be, QofIdTypeConst obj_name,
+ gpointer pObject, const col_cvt_t* table_row, GValue* value )
+{
+ QofAccessFunc getter;
+ gchar* s;
+
+ memset( value, 0, sizeof( GValue ) );
+ getter = get_getter( obj_name, table_row );
+ s = (gchar*)(*getter)( pObject, NULL );
+ if( s ) {
+ g_value_init( value, G_TYPE_STRING );
+ g_value_set_string( value, s );
+ }
+}
+
+static void
+get_gvalue_string_for_query( GncGdaBackend* be, QofIdTypeConst obj_name,
+ gpointer pObject, const col_cvt_t* table_row, GdaQuery* query )
+{
+ GValue value;
+
+ get_gvalue_string( be, obj_name, pObject, table_row, &value );
+ add_field_to_query( query, table_row->col_name, &value );
+}
+
+static GdaQueryCondition*
+get_gvalue_string_cond( GncGdaBackend* be, QofIdTypeConst obj_name,
+ gpointer pObject, const col_cvt_t* table_row, GdaQuery* query )
+{
+ GValue value;
+
+ get_gvalue_string( be, obj_name, pObject, table_row, &value );
+ return gnc_gda_create_condition_from_field( query, table_row->col_name,
+ &value );
+}
+
+static void
+create_string_col( GdaServerProvider* server, GdaConnection* cnn,
+ xmlNodePtr array_data, const col_cvt_t* table_row )
+{
+ const gchar* dbms_type;
+
+ dbms_type = gda_server_provider_get_default_dbms_type( server,
+ cnn, G_TYPE_STRING );
+ add_table_column( server, cnn, array_data, table_row->col_name,
+ dbms_type, table_row->size, table_row->flags );
+}
+
+static col_type_handler_t string_handler
+ = { load_string, create_string_col,
+ get_gvalue_string_for_query, get_gvalue_string_cond };
+/* ----------------------------------------------------------------- */
+
+static void
+load_int( GdaDataModel* pModel, gint row,
+ QofSetterFunc setter, gpointer pObject,
+ const col_cvt_t* table )
+{
+ const GValue* val;
+ gint int_value;
+
+ val = gda_data_model_get_value_at_col_name( pModel, table->col_name, row );
+ if( gda_value_is_null( val ) ) {
+ int_value = 0;
+ } else {
+ int_value = g_value_get_int( val );
+ }
+ (*setter)( pObject, (gpointer)int_value );
+}
+
+static void
+get_gvalue_int( GncGdaBackend* be, QofIdTypeConst obj_name,
+ gpointer pObject, const col_cvt_t* table_row, GValue* value )
+{
+ gint int_value;
+ QofAccessFunc getter;
+
+ memset( value, 0, sizeof( GValue ) );
+
+ getter = get_getter( obj_name, table_row );
+ int_value = (gint)(*getter)( pObject, NULL );
+ g_value_init( value, G_TYPE_INT );
+ g_value_set_int( value, int_value );
+}
+
+static void
+get_gvalue_int_for_query( GncGdaBackend* be, QofIdTypeConst obj_name,
+ gpointer pObject, const col_cvt_t* table_row, GdaQuery* query )
+{
+ GValue value;
+
+ get_gvalue_int( be, obj_name, pObject, table_row, &value );
+ add_field_to_query( query, table_row->col_name, &value );
+}
+
+static GdaQueryCondition*
+get_gvalue_int_cond( GncGdaBackend* be, QofIdTypeConst obj_name,
+ gpointer pObject, const col_cvt_t* table_row, GdaQuery* query )
+{
+ GValue value;
+
+ get_gvalue_int( be, obj_name, pObject, table_row, &value );
+ return gnc_gda_create_condition_from_field( query, table_row->col_name, &value );
+}
+
+static void
+create_int_col( GdaServerProvider* server, GdaConnection* cnn,
+ xmlNodePtr array_data, const col_cvt_t* table_row )
+{
+ const gchar* dbms_type;
+
+ dbms_type = gda_server_provider_get_default_dbms_type( server,
+ cnn, G_TYPE_INT );
+ add_table_column( server, cnn, array_data, table_row->col_name,
+ dbms_type, table_row->size, table_row->flags );
+}
+
+static col_type_handler_t int_handler =
+ { load_int, create_int_col,
+ get_gvalue_int_for_query, get_gvalue_int_cond };
+/* ----------------------------------------------------------------- */
+
+static void
+load_int64( GdaDataModel* pModel, gint row,
+ QofSetterFunc setter, gpointer pObject,
+ const col_cvt_t* table )
+{
+ const GValue* val;
+ gint64 i64_value;
+
+ val = gda_data_model_get_value_at_col_name( pModel, table->col_name, row );
+ if( gda_value_is_null( val ) ) {
+ (*setter)( pObject, NULL );
+ } else {
+ i64_value = g_value_get_int64( val );
+ (*setter)( pObject, (gpointer)&i64_value );
+ }
+}
+
+static void
+get_gvalue_int64( GncGdaBackend* be, QofIdTypeConst obj_name, gpointer pObject,
+ const col_cvt_t* table_row, GValue* value )
+{
+ gint64* pInt64;
+ gint64 i64_value;
+ QofAccessFunc getter;
+
+ memset( value, 0, sizeof( GValue ) );
+ getter = get_getter( obj_name, table_row );
+ pInt64 = (*getter)( pObject, NULL );
+ if( pInt64 != NULL ) {
+ gchar* s;
+
+ i64_value = *pInt64;
+ g_value_init( value, G_TYPE_INT64 );
+ g_value_set_int64( value, i64_value );
+ }
+}
+
+static void
+get_gvalue_int64_for_query( GncGdaBackend* be, QofIdTypeConst obj_name,
+ gpointer pObject, const col_cvt_t* table_row, GdaQuery* query )
+{
+ GValue value;
+
+ get_gvalue_int64( be, obj_name, pObject, table_row, &value );
+ add_field_to_query( query, table_row->col_name, &value );
+}
+
+static GdaQueryCondition*
+get_gvalue_int64_cond( GncGdaBackend* be, QofIdTypeConst obj_name,
+ gpointer pObject, const col_cvt_t* table_row, GdaQuery* query )
+{
+ GValue value;
+
+ get_gvalue_int64( be, obj_name, pObject, table_row, &value );
+ return gnc_gda_create_condition_from_field( query, table_row->col_name, &value );
+}
+
+static void
+create_int64_col( GdaServerProvider* server, GdaConnection* cnn,
+ xmlNodePtr array_data, const col_cvt_t* table_row )
+{
+ const gchar* dbms_type;
+
+ dbms_type = gda_server_provider_get_default_dbms_type( server,
+ cnn, G_TYPE_INT64 );
+ add_table_column( server, cnn, array_data, table_row->col_name,
+ dbms_type, table_row->size, table_row->flags );
+}
+
+static col_type_handler_t int64_handler =
+ { load_int64, create_int64_col,
+ get_gvalue_int64_for_query, get_gvalue_int64_cond };
+/* ----------------------------------------------------------------- */
+
+static void
+load_double( GdaDataModel* pModel, gint row,
+ QofSetterFunc setter, gpointer pObject,
+ const col_cvt_t* table )
+{
+ const GValue* val;
+ gdouble d_value;
+
+ val = gda_data_model_get_value_at_col_name( pModel, table->col_name, row );
+ if( gda_value_is_null( val ) ) {
+ (*setter)( pObject, (gpointer)NULL );
+ } else {
+ d_value = g_value_get_double( val );
+ (*setter)( pObject, (gpointer)&d_value );
+ }
+}
+
+static void
+get_gvalue_double( GncGdaBackend* be, QofIdTypeConst obj_name, gpointer pObject,
+ const col_cvt_t* table_row, GValue* value )
+{
+ QofAccessFunc getter;
+ gdouble* pDouble;
+ gdouble d_value;
+
+ memset( value, 0, sizeof( GValue ) );
+
+ getter = get_getter( obj_name, table_row );
+ pDouble = (*getter)( pObject, NULL );
+ if( pDouble != NULL ) {
+ d_value = *pDouble;
+ g_value_init( value, G_TYPE_DOUBLE );
+ g_value_set_double( value, d_value );
+ }
+}
+
+static void
+get_gvalue_double_for_query( GncGdaBackend* be, QofIdTypeConst obj_name,
+ gpointer pObject, const col_cvt_t* table_row, GdaQuery* query )
+{
+ GValue value;
+
+ get_gvalue_double( be, obj_name, pObject, table_row, &value );
+ add_field_to_query( query, table_row->col_name, &value );
+}
+
+static GdaQueryCondition*
+get_gvalue_double_cond( GncGdaBackend* be, QofIdTypeConst obj_name,
+ gpointer pObject, const col_cvt_t* table_row, GdaQuery* query )
+{
+ GValue value;
+
+ get_gvalue_double( be, obj_name, pObject, table_row, &value );
+ return gnc_gda_create_condition_from_field( query, table_row->col_name, &value );
+}
+
+static void
+create_double_col( GdaServerProvider* server, GdaConnection* cnn,
+ xmlNodePtr array_data, const col_cvt_t* table_row )
+{
+ const gchar* dbms_type;
+
+ dbms_type = gda_server_provider_get_default_dbms_type( server,
+ cnn, G_TYPE_INT64 );
+ add_table_column( server, cnn, array_data, table_row->col_name,
+ dbms_type, table_row->size, table_row->flags );
+}
+
+static col_type_handler_t double_handler =
+ { load_double, create_double_col,
+ get_gvalue_double_for_query, get_gvalue_double_cond };
+/* ----------------------------------------------------------------- */
+
+static void
+load_guid( GdaDataModel* pModel, gint row,
+ QofSetterFunc setter, gpointer pObject,
+ const col_cvt_t* table )
+{
+ const GValue* val;
+ GUID guid;
+ const GUID* pGuid;
+
+ val = gda_data_model_get_value_at_col_name( pModel, table->col_name, row );
+ if( gda_value_is_null( val ) ) {
+ pGuid = NULL;
+ } else {
+ string_to_guid( g_value_get_string( val ), &guid );
+ pGuid = &guid;
+ }
+ (*setter)( pObject, (gpointer)pGuid );
+}
+
+static void
+get_gvalue_guid( GncGdaBackend* be, QofIdTypeConst obj_name, gpointer pObject,
+ const col_cvt_t* table_row, GValue* value )
+{
+ QofAccessFunc getter;
+ const GUID* guid;
+ gchar guid_buf[GUID_ENCODING_LENGTH+1];
+
+ memset( value, 0, sizeof( GValue ) );
+
+ getter = get_getter( obj_name, table_row );
+ guid = (*getter)( pObject, NULL );
+ if( guid != NULL ) {
+ (void)guid_to_string_buff( guid, guid_buf );
+ g_value_init( value, G_TYPE_STRING );
+ g_value_set_string( value, guid_buf );
+ }
+}
+
+static void
+get_gvalue_guid_for_query( GncGdaBackend* be, QofIdTypeConst obj_name,
+ gpointer pObject, const col_cvt_t* table_row, GdaQuery* query )
+{
+ GValue value;
+
+ get_gvalue_guid( be, obj_name, pObject, table_row, &value );
+ add_field_to_query( query, table_row->col_name, &value );
+}
+
+static GdaQueryCondition*
+get_gvalue_guid_cond( GncGdaBackend* be, QofIdTypeConst obj_name,
+ gpointer pObject, const col_cvt_t* table_row, GdaQuery* query )
+{
+ GValue value;
+
+ get_gvalue_guid( be, obj_name, pObject, table_row, &value );
+ return gnc_gda_create_condition_from_field( query, table_row->col_name, &value );
+}
+
+static void
+create_guid_col( GdaServerProvider* server, GdaConnection* cnn,
+ xmlNodePtr array_data, const col_cvt_t* table_row )
+{
+ add_table_column( server, cnn, array_data, table_row->col_name,
+ "char", GUID_ENCODING_LENGTH, table_row->flags );
+}
+
+static col_type_handler_t guid_handler =
+ { load_guid, create_guid_col,
+ get_gvalue_guid_for_query, get_gvalue_guid_cond };
+/* ----------------------------------------------------------------- */
+static void
+load_timespec( GdaDataModel* pModel, gint row,
+ QofSetterFunc setter, gpointer pObject,
+ const col_cvt_t* table )
+{
+ const GValue* val;
+ GDate* date;
+ Timespec ts;
+
+ val = gda_data_model_get_value_at_col_name( pModel, table->col_name, row );
+ if( gda_value_is_null( val ) ) {
+ (*setter)( pObject, NULL );
+ } else {
+ date = (GDate*)g_value_get_boxed( val );
+ if( date != NULL ) {
+ ts = gnc_dmy2timespec( g_date_get_day( date ),
+ g_date_get_month( date ),
+ g_date_get_year( date ) );
+ (*setter)( pObject, &ts );
+ }
+ }
+}
+
+static void
+get_gvalue_timespec( GncGdaBackend* be, QofIdTypeConst obj_name,
+ gpointer pObject, const col_cvt_t* table_row, GValue* value )
+{
+ QofAccessFunc getter;
+ Timespec* pTimespec;
+
+ memset( value, 0, sizeof( GValue ) );
+
+ getter = get_getter( obj_name, table_row );
+ pTimespec = (Timespec*)(*getter)( pObject, NULL );
+ if( pTimespec != NULL ) {
+ GDate* date;
+ gchar* s;
+ gint y, m, d;
+ gchar iso8601_buf[33];
+
+ date = g_date_new();
+ (void)gnc_timespec_to_iso8601_buff( *pTimespec, iso8601_buf );
+ sscanf( iso8601_buf, "%d-%d-%d", &y, &m, &d );
+ g_date_set_dmy( date, d, m, y );
+ g_value_init( value, G_TYPE_DATE );
+ g_value_set_boxed( value, date );
+ }
+}
+
+static void
+get_gvalue_timespec_for_query( GncGdaBackend* be, QofIdTypeConst obj_name,
+ gpointer pObject, const col_cvt_t* table_row, GdaQuery* query )
+{
+ GValue value;
+
+ get_gvalue_timespec( be, obj_name, pObject, table_row, &value );
+ add_field_to_query( query, table_row->col_name, &value );
+}
+
+static GdaQueryCondition*
+get_gvalue_timespec_cond( GncGdaBackend* be, QofIdTypeConst obj_name,
+ gpointer pObject, const col_cvt_t* table_row, GdaQuery* query )
+{
+ GValue value;
+
+ get_gvalue_timespec( be, obj_name, pObject, table_row, &value );
+ return gnc_gda_create_condition_from_field( query, table_row->col_name, &value );
+}
+
+static void
+create_timespec_col( GdaServerProvider* server, GdaConnection* cnn,
+ xmlNodePtr array_data, const col_cvt_t* table_row )
+{
+ const gchar* dbms_type;
+
+ dbms_type = gda_server_provider_get_default_dbms_type( server,
+ cnn, G_TYPE_DATE );
+ add_table_column( server, cnn, array_data, table_row->col_name,
+ dbms_type, table_row->size, table_row->flags );
+}
+
+static col_type_handler_t timespec_handler =
+ { load_timespec, create_timespec_col,
+ get_gvalue_timespec_for_query, get_gvalue_timespec_cond };
+/* ----------------------------------------------------------------- */
+static void
+load_date( GdaDataModel* pModel, gint row,
+ QofSetterFunc setter, gpointer pObject,
+ const col_cvt_t* table )
+{
+ const GValue* val;
+ GDate* date;
+
+ val = gda_data_model_get_value_at_col_name( pModel, table->col_name, row );
+ if( gda_value_is_null( val ) ) {
+ (*setter)( pObject, NULL );
+ } else {
+ date = (GDate*)g_value_get_boxed( val );
+ if( date != NULL ) {
+ (*setter)( pObject, date );
+ }
+ }
+}
+
+static void
+get_gvalue_date( GncGdaBackend* be, QofIdTypeConst obj_name, gpointer pObject,
+ const col_cvt_t* table_row, GValue* value )
+{
+ GDate* date;
+ QofAccessFunc getter;
+
+ memset( value, 0, sizeof( GValue ) );
+
+ getter = get_getter( obj_name, table_row );
+ date = (GDate*)(*getter)( pObject, NULL );
+ if( date != NULL ) {
+ g_value_init( value, G_TYPE_DATE );
+ g_value_set_boxed( value, date );
+ }
+}
+
+static void
+get_gvalue_date_for_query( GncGdaBackend* be, QofIdTypeConst obj_name,
+ gpointer pObject, const col_cvt_t* table_row, GdaQuery* query )
+{
+ GValue value;
+
+ get_gvalue_date( be, obj_name, pObject, table_row, &value );
+ add_field_to_query( query, table_row->col_name, &value );
+}
+
+static GdaQueryCondition*
+get_gvalue_date_cond( GncGdaBackend* be, QofIdTypeConst obj_name,
+ gpointer pObject, const col_cvt_t* table_row, GdaQuery* query )
+{
+ GValue value;
+
+ get_gvalue_date( be, obj_name, pObject, table_row, &value );
+ return gnc_gda_create_condition_from_field( query, table_row->col_name, &value );
+}
+
+static col_type_handler_t date_handler =
+ { load_date, create_timespec_col,
+ get_gvalue_date_for_query, get_gvalue_date_cond };
+/* ----------------------------------------------------------------- */
+static void
+load_numeric( GdaDataModel* pModel, gint row,
+ QofSetterFunc setter, gpointer pObject,
+ const col_cvt_t* table )
+{
+ const GValue* val;
+ gchar* buf;
+ gint64 num, denom;
+ gnc_numeric n;
+ gboolean isNull = FALSE;
+
+ buf = g_strdup_printf( "%s_num", table->col_name );
+ val = gda_data_model_get_value_at_col_name( pModel, buf, row );
+ g_free( buf );
+ if( gda_value_is_null( val ) ) {
+ isNull = TRUE;
+ num = 0;
+ } else {
+ num = g_value_get_int64( val );
+ }
+ buf = g_strdup_printf( "%s_denom", table->col_name );
+ val = gda_data_model_get_value_at_col_name( pModel, buf, row );
+ g_free( buf );
+ if( gda_value_is_null( val ) ) {
+ isNull = TRUE;
+ denom = 1;
+ } else {
+ denom = g_value_get_int64( val );
+ }
+ n = gnc_numeric_create( num, denom );
+ if( isNull ) {
+ (*setter)( pObject, NULL );
+ } else {
+ (*setter)( pObject, &n );
+ }
+}
+
+static void
+get_gvalue_numeric( GncGdaBackend* be, QofIdTypeConst obj_name, gpointer pObject,
+ const col_cvt_t* table_row, GValue* value )
+{
+ QofAccessFunc getter;
+ gnc_numeric* n;
+
+ memset( value, 0, sizeof( GValue ) );
+
+ getter = get_getter( obj_name, table_row );
+ n = (gnc_numeric*)(*getter)( pObject, NULL );
+ if( n != NULL ) {
+ g_value_init( value, gnc_numeric_get_type() );
+ g_value_set_boxed( value, n );
+ }
+}
+
+static void
+get_gvalue_numeric_for_query( GncGdaBackend* be, QofIdTypeConst obj_name,
+ gpointer pObject, const col_cvt_t* table_row, GdaQuery* query )
+{
+ GValue value;
+ GValue num_value;
+ GValue denom_value;
+ gnc_numeric* n;
+ gchar* s;
+
+ memset( &value, 0, sizeof( GValue ) );
+ memset( &num_value, 0, sizeof( GValue ) );
+ memset( &denom_value, 0, sizeof( GValue ) );
+
+ get_gvalue_numeric( be, obj_name, pObject, table_row, &value );
+ if( G_VALUE_TYPE(&value) != 0 ) {
+ n = g_value_get_boxed( &value );
+ g_value_init( &num_value, G_TYPE_INT64 );
+ g_value_set_int64( &num_value, gnc_numeric_num( *n ) );
+ g_value_init( &denom_value, G_TYPE_INT64 );
+ g_value_set_int64( &denom_value, gnc_numeric_denom( *n ) );
+ }
+
+ s = g_strdup_printf( "%s_num", table_row->col_name );
+ add_field_to_query( query, s, &num_value );
+ g_free( s );
+ s = g_strdup_printf( "%s_denom", table_row->col_name );
+ add_field_to_query( query, s, &denom_value );
+ g_free( s );
+}
+
+static GdaQueryCondition*
+get_gvalue_numeric_cond( GncGdaBackend* be, QofIdTypeConst obj_name,
+ gpointer pObject, const col_cvt_t* table_row, GdaQuery* query )
+{
+ GValue value;
+ GValue num_value;
+ GValue denom_value;
+ gnc_numeric* n;
+ gint64 num;
+ gint64 denom;
+ gchar* s;
+ GdaQueryCondition* num_cond;
+ GdaQueryCondition* denom_cond;
+ GdaQueryCondition* cond;
+
+ memset( &value, 0, sizeof( GValue ) );
+ memset( &num_value, 0, sizeof( GValue ) );
+ memset( &denom_value, 0, sizeof( GValue ) );
+
+ get_gvalue_numeric( be, obj_name, pObject, table_row, &value );
+ if( G_VALUE_TYPE(&value) != 0 ) {
+ n = g_value_get_boxed( &value );
+ g_value_init( &num_value, G_TYPE_INT64 );
+ g_value_set_int64( &num_value, gnc_numeric_num( *n ) );
+ g_value_init( &denom_value, G_TYPE_INT64 );
+ g_value_set_int64( &denom_value, gnc_numeric_denom( *n ) );
+ }
+
+ s = g_strdup_printf( "%s_num", table_row->col_name );
+ num_cond = gnc_gda_create_condition_from_field( query, table_row->col_name, &value );
+ g_free( s );
+ s = g_strdup_printf( "%s_denom", table_row->col_name );
+ denom_cond = gnc_gda_create_condition_from_field( query, table_row->col_name, &value );
+ g_free( s );
+
+ cond = gda_query_condition_new( query, GDA_QUERY_CONDITION_NODE_AND );
+ gda_query_condition_node_add_child( cond, num_cond, NULL );
+ gda_query_condition_node_add_child( cond, denom_cond, NULL );
+
+ return cond;
+}
+
+static void
+create_numeric_col( GdaServerProvider* server, GdaConnection* cnn,
+ xmlNodePtr array_data, const col_cvt_t* table_row )
+{
+ const gchar* dbms_type;
+ gchar* buf;
+
+ dbms_type = gda_server_provider_get_default_dbms_type( server, cnn,
+ G_TYPE_INT64 );
+ buf = g_strdup_printf( "%s_num", table_row->col_name );
+ add_table_column( server, cnn, array_data, buf, dbms_type,
+ table_row->size, table_row->flags );
+ g_free( buf );
+ buf = g_strdup_printf( "%s_denom", table_row->col_name );
+ add_table_column( server, cnn, array_data, buf, dbms_type,
+ table_row->size, table_row->flags );
+ g_free( buf );
+}
+
+static col_type_handler_t numeric_handler =
+ { load_numeric, create_numeric_col,
+ get_gvalue_numeric_for_query, get_gvalue_numeric_cond };
+/* ================================================================= */
+
+static col_type_handler_t*
+get_handler( int col_type )
+{
+ col_type_handler_t* pHandler;
+
+ switch( col_type ) {
+ case CT_STRING:
+ pHandler = &string_handler;
+ break;
+
+ case CT_BOOLEAN:
+ case CT_INT:
+ pHandler = &int_handler;
+ break;
+
+ case CT_INT64:
+ pHandler = &int64_handler;
+ break;
+
+ case CT_DOUBLE:
+ pHandler = &double_handler;
+ break;
+
+ case CT_GUID:
+ pHandler = &guid_handler;
+ break;
+
+ case CT_TIMESPEC:
+ pHandler = ×pec_handler;
+ break;
+
+ case CT_GDATE:
+ pHandler = &date_handler;
+ break;
+
+ case CT_NUMERIC:
+ pHandler = &numeric_handler;
+ break;
+
+ default: /* undefined col type */
+ g_assert( FALSE );
+ }
+
+ return pHandler;
+}
+
+static void retrieve_guid( gpointer pObject, gpointer pValue );
+
+static void
+retrieve_guid( gpointer pObject, gpointer pValue )
+{
+ GUID** ppGuid = (GUID**)pObject;
+ GUID* guid = (GUID*)pValue;
+
+ *ppGuid = guid;
+}
+
+
+// Table to retrieve just the guid
+static col_cvt_t guid_table[] =
+{
+ { "guid", CT_GUID, 0, 0, NULL, NULL, retrieve_guid },
+ { NULL }
+};
+
+const GUID*
+gnc_gda_load_guid( GdaDataModel* pModel, gint row )
+{
+ const GUID* guid;
+
+ gnc_gda_load_object( pModel, row, NULL, &guid, guid_table );
+
+ return guid;
+}
+
+void
+gnc_gda_load_object( GdaDataModel* pModel, gint row,
+ QofIdTypeConst obj_name, gpointer pObject,
+ const col_cvt_t* table )
+{
+ int col;
+ QofSetterFunc setter;
+ col_type_handler_t* pHandler;
+
+ for( col = 0; table[col].col_name != NULL; col++ ) {
+ if( table[col].param_name != NULL ) {
+ setter = qof_class_get_parameter_setter( obj_name,
+ table[col].param_name );
+ } else {
+ setter = table[col].setter;
+ }
+ pHandler = get_handler( table[col].col_type );
+ pHandler->load_fn( pModel, row, setter, pObject, &table[col] );
+ }
+}
+
+/* ================================================================= */
+GdaQuery*
+gnc_gda_create_select_query( const GncGdaBackend* be, const gchar* table_name )
+{
+ GdaQuery* query;
+ GdaQueryTarget* target;
+ GdaQueryField* allFields;
+
+ /* SELECT */
+ query = gda_query_new( be->pDict );
+ gda_query_set_query_type( query, GDA_QUERY_TYPE_SELECT );
+
+ /* FROM */
+ target = gda_query_target_new( query, table_name );
+ gda_query_add_target( query, target, NULL );
+ g_object_unref( G_OBJECT(target) );
+
+ /* all fields */
+ allFields = gda_query_field_all_new( query, table_name );
+ gda_query_field_set_visible( allFields, TRUE );
+ gda_entity_add_field( GDA_ENTITY(query), GDA_ENTITY_FIELD(allFields) );
+ g_object_unref( G_OBJECT(allFields) );
+
+ return query;
+}
+
+/* ================================================================= */
+GdaObject*
+gnc_gda_execute_query( GncGdaBackend* be, GdaQuery* query )
+{
+ GError* error = NULL;
+
+ GdaObject* ret;
+
+ ret = gda_query_execute( query, NULL, FALSE, &error );
+
+ if( error != NULL ) {
+ printf( "SQL error: %s\n", error->message );
+ }
+
+ return ret;
+}
+
+GdaObject*
+gnc_gda_execute_sql( GncGdaBackend* be, const gchar* sql )
+{
+ GError* error = NULL;
+
+ GdaQuery* query;
+
+ query = gda_query_new_from_sql( be->pDict, sql, &error );
+ if( query == NULL ) {
+ printf( "SQL error: %s\n", error->message );
+ return NULL;
+ }
+ return gnc_gda_execute_query( be, query );
+}
+
+int
+gnc_gda_execute_select_get_count( GncGdaBackend* be, const gchar* sql )
+{
+ GError* error = NULL;
+ int count = 0;
+
+ GdaObject* ret;
+
+ ret = gnc_gda_execute_sql( be, sql );
+ if( GDA_IS_DATA_MODEL(ret) ) {
+ GdaDataModel* pModel = GDA_DATA_MODEL(ret);
+ count = gda_data_model_get_n_rows( pModel );
+ }
+
+ if( error != NULL ) {
+ printf( "SQL error: %s\n", error->message );
+ }
+
+ return count;
+}
+
+int
+gnc_gda_execute_query_get_count( GncGdaBackend* be, GdaQuery* query )
+{
+ int count = 0;
+
+ GdaObject* ret;
+
+ ret = gnc_gda_execute_query( be, query );
+ if( GDA_IS_DATA_MODEL(ret) ) {
+ GdaDataModel* pModel = GDA_DATA_MODEL(ret);
+ count = gda_data_model_get_n_rows( pModel );
+ }
+
+ return count;
+}
+/* ================================================================= */
+static void
+get_col_gvalue_for_query( GncGdaBackend* be, QofIdTypeConst obj_name,
+ gpointer pObject, const col_cvt_t* table_row,
+ GdaQuery* query )
+{
+ GValue value;
+ col_type_handler_t* pHandler;
+
+ pHandler = get_handler( table_row->col_type );
+ pHandler->get_gvalue_query_fn( be, obj_name, pObject, table_row, query );
+}
+
+static void
+get_col_gvalue_for_condition( GncGdaBackend* be, QofIdTypeConst obj_name,
+ gpointer pObject, const col_cvt_t* table_row,
+ GdaQuery* query )
+{
+ GValue value;
+ col_type_handler_t* pHandler;
+ GdaQueryCondition* cond;
+
+ pHandler = get_handler( table_row->col_type );
+ cond = pHandler->get_gvalue_cond_fn( be, obj_name, pObject, table_row, query );
+
+ gda_query_set_condition( query, cond );
+ g_object_unref( G_OBJECT(cond) );
+}
+
+gboolean
+gnc_gda_object_is_it_in_db( GncGdaBackend* be, const gchar* table_name,
+ QofIdTypeConst obj_name, gpointer pObject,
+ const col_cvt_t* table )
+{
+ GdaQuery* query;
+ GValue value;
+ int count;
+
+ /* SELECT * FROM */
+ query = gnc_gda_create_select_query( be, table_name );
+
+ /* WHERE */
+ get_col_gvalue_for_condition( be, obj_name, pObject, &table[0], query );
+
+ count = gnc_gda_execute_query_get_count( be, query );
+ if( count == 0 ) {
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+}
+
+gboolean
+gnc_gda_do_db_operation( GncGdaBackend* be,
+ E_DB_OPERATION op,
+ const gchar* table_name,
+ QofIdTypeConst obj_name, gpointer pObject,
+ const col_cvt_t* table )
+{
+ GdaQuery* pQuery;
+
+ if( op == OP_DB_ADD_OR_UPDATE ) {
+ if( gnc_gda_object_is_it_in_db( be, table_name, obj_name, pObject, table ) ) {
+ pQuery = gnc_gda_build_update_query( be, table_name, obj_name, pObject, table );
+ } else {
+ pQuery = gnc_gda_build_insert_query( be, table_name, obj_name, pObject, table );
+ }
+ } else if( op == OP_DB_DELETE ) {
+ pQuery = gnc_gda_build_delete_query( be, table_name, obj_name, pObject, table );
+ } else if( op == OP_DB_ADD ) {
+ pQuery = gnc_gda_build_insert_query( be, table_name, obj_name, pObject, table );
+ } else {
+ g_assert( FALSE );
+ }
+ if( pQuery != NULL ) {
+ gnc_gda_execute_query( be, pQuery );
+ g_object_unref( G_OBJECT(pQuery) );
+
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+#define INITIAL_SQL_BUF_LEN 500
+
+GdaQuery*
+gnc_gda_build_insert_query( GncGdaBackend* be,
+ const gchar* table_name,
+ QofIdTypeConst obj_name, gpointer pObject,
+ const col_cvt_t* table )
+{
+ GdaQuery* query;
+ int col;
+
+ GdaQueryTarget* target;
+
+ /* INSERT */
+ query = gda_query_new( be->pDict );
+ gda_query_set_query_type( query, GDA_QUERY_TYPE_INSERT );
+
+ /* INTO */
+ target = gda_query_target_new( query, table_name );
+ gda_query_add_target( query, target, NULL );
+
+ /* VALUES */
+ for( col = 0; table[col].col_name != NULL; col++ ) {
+ get_col_gvalue_for_query( be, obj_name, pObject, &table[col], query );
+ }
+
+ return query;
+}
+
+GdaQuery*
+gnc_gda_build_update_query( GncGdaBackend* be,
+ const gchar* table_name,
+ QofIdTypeConst obj_name, gpointer pObject,
+ const col_cvt_t* table )
+{
+ GdaQuery* query;
+ int col;
+
+ GdaQueryTarget* target;
+
+ /* UPDATE */
+ query = gda_query_new( be->pDict );
+ gda_query_set_query_type( query, GDA_QUERY_TYPE_UPDATE );
+ target = gda_query_target_new( query, table_name );
+ gda_query_add_target( query, target, NULL );
+
+ /* SET */
+ for( col = 1; table[col].col_name != NULL; col++ ) {
+ get_col_gvalue_for_query( be, obj_name, pObject, &table[col], query );
+ }
+
+ /* WHERE */
+ get_col_gvalue_for_condition( be, obj_name, pObject, &table[0], query );
+
+ return query;
+}
+
+GdaQuery*
+gnc_gda_build_delete_query( GncGdaBackend* be,
+ const gchar* table_name,
+ QofIdTypeConst obj_name, gpointer pObject,
+ const col_cvt_t* table )
+{
+ GdaQuery* query;
+ GdaQueryTarget* target;
+ GdaQueryField* key;
+ GdaQueryField* key_value;
+
+ /* DELETE */
+ query = gda_query_new( be->pDict );
+ gda_query_set_query_type( query, GDA_QUERY_TYPE_DELETE );
+
+ /* FROM */
+ target = gda_query_target_new( query, table_name );
+ gda_query_add_target( query, target, NULL );
+ g_object_unref( G_OBJECT(target) );
+
+ /* WHERE */
+ get_col_gvalue_for_condition( be, obj_name, pObject, &table[0], query );
+
+ return query;
+}
+
+/* ================================================================= */
+static void
+add_table_column( GdaServerProvider* server, GdaConnection* cnn,
+ xmlNodePtr array_data, const gchar* arg, const gchar* dbms_type,
+ gint size, gint flags )
+{
+ xmlNodePtr array_row, array_value;
+ gchar* buf;
+
+ array_row = xmlNewChild( array_data, NULL, "gda_array_row", NULL );
+ array_value = xmlNewChild( array_row, NULL, "gda_array_value", arg );
+ xmlSetProp( array_value, "colid", "COLUMN_NAME" );
+ array_value = xmlNewChild( array_row, NULL, "gda_array_value", dbms_type );
+ xmlSetProp( array_value, "colid", "COLUMN_TYPE" );
+ if( size != 0 ) {
+ buf = g_strdup_printf( "%d", size );
+ array_value = xmlNewChild( array_row, NULL, "gda_array_value", buf );
+ xmlSetProp( array_value, "colid", "COLUMN_SIZE" );
+ g_free( buf );
+ }
+ if( (flags & COL_PKEY) != 0 ) {
+ array_value = xmlNewChild( array_row, NULL, "gda_array_value", "TRUE" );
+ xmlSetProp( array_value, "colid", "COLUMN_PKEY" );
+ }
+ if( (flags & COL_NNUL) != 0 ) {
+ array_value = xmlNewChild( array_row, NULL, "gda_array_value", "TRUE" );
+ xmlSetProp( array_value, "colid", "COLUMN_NNUL" );
+ }
+ if( (flags & COL_AUTOINC) != 0 ) {
+ array_value = xmlNewChild( array_row, NULL, "gda_array_value", "TRUE" );
+ xmlSetProp( array_value, "colid", "COLUMN_AUTOINC" );
+ }
+ if( (flags & COL_UNIQUE) != 0 ) {
+ array_value = xmlNewChild( array_row, NULL, "gda_array_value", "TRUE" );
+ xmlSetProp( array_value, "colid", "COLUMN_UNIQUE" );
+ }
+}
+
+gboolean
+gnc_gda_create_table( GdaConnection* cnn, const gchar* table_name,
+ col_cvt_t* col_table, GError** error )
+{
+ GdaServerOperation *op;
+ GdaServerProvider *server;
+
+ g_return_val_if_fail( GDA_IS_CONNECTION(cnn), FALSE );
+ g_return_val_if_fail( gda_connection_is_opened(cnn), FALSE );
+
+ server = gda_connection_get_provider_obj( cnn );
+
+ op = gda_server_provider_create_operation( server, cnn,
+ GDA_SERVER_OPERATION_CREATE_TABLE, NULL, error );
+ if( GDA_IS_SERVER_OPERATION(op) ) {
+ gint col;
+ GType type;
+ xmlDocPtr parameters;
+ xmlNodePtr root;
+ xmlNodePtr table, op_data, array_data, array_row, array_value;
+
+ if( table_name == NULL ) {
+ g_message( "Table name is NULL!" );
+ g_set_error( error,
+ GDA_GENERAL_ERROR, GDA_GENERAL_OBJECT_NAME_ERROR,
+ "Couldn't create table with a NULL string" );
+ return FALSE;
+ }
+
+
+ /* Initation of the xmlDoc */
+ parameters = xmlNewDoc( "1.0" );
+
+ root = xmlNewDocNode( parameters, NULL, "serv_op_data", NULL );
+ xmlDocSetRootElement( parameters, root );
+ table = xmlNewChild( root, NULL, "op_data", table_name );
+ xmlSetProp( table, "path", "/TABLE_DEF_P/TABLE_NAME" );
+
+ op_data = xmlNewChild( root, NULL, "op_data", NULL );
+ xmlSetProp( op_data, "path", "/FIELDS_A" );
+ array_data = xmlNewChild( op_data, NULL, "gda_array_data", NULL );
+
+ type = 0;
+
+ for( col = 0; col_table[col].col_name != NULL; col++ ) {
+ gchar* buf;
+ gchar *dbms_type = NULL;
+ const gchar *arg;
+ gint size;
+ gint flags;
+ col_type_handler_t* pHandler;
+
+ pHandler = get_handler( col_table[col].col_type );
+
+ pHandler->create_col_fn( server, cnn, array_data, &col_table[col] );
+ }
+
+ if( !gda_server_operation_load_data_from_xml(op, root, error ) ) {
+ /* error */
+ g_set_error( error, GDA_GENERAL_ERROR, GDA_GENERAL_OPERATION_ERROR,
+ "The XML operation doesn't exist or could't be loaded" );
+ g_object_unref( op );
+ xmlFreeDoc( parameters );
+ return FALSE;
+ } else {
+ if( !gda_server_provider_perform_operation( server, cnn, op, error ) ) {
+ /* error */
+ g_set_error( error,
+ GDA_GENERAL_ERROR, GDA_GENERAL_OPERATION_ERROR,
+ "The Server couldn't perform the CREATE TABLE operation!" );
+ g_object_unref( op );
+ xmlFreeDoc( parameters );
+ return FALSE;
+ }
+ }
+
+ g_object_unref( op );
+ xmlFreeDoc( parameters );
+ } else {
+ g_set_error( error, GDA_GENERAL_ERROR, GDA_GENERAL_OBJECT_NAME_ERROR,
+ "The Server doesn't support the CREATE TABLE operation!" );
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void gnc_gda_create_table_if_needed( GncGdaBackend* be,
+ const gchar* table_name, col_cvt_t* col_table )
+{
+ GdaDictTable* table;
+ GError* error = NULL;
+ GdaDictDatabase* db;
+
+ db = gda_dict_get_database( be->pDict );
+ table = gda_dict_database_get_table_by_name( db, table_name );
+ if( !GDA_IS_DICT_TABLE(table) ) {
+ gnc_gda_create_table( be->pConnection, table_name, col_table, &error );
+ if( error != NULL ) {
+ printf( "Error creating table: %s\n", error->message );
+ }
+ }
+}
+/* ================================================================= */
+
+static gboolean
+create_or_drop_db( GdaConnection* cnn, GdaServerOperationType opType,
+ const gchar* db_name, GError** error )
+{
+ typedef struct {
+ GdaServerOperationType opType;
+ const gchar* op_name;
+ const gchar* op_path_name;
+ } S_ServerOpInfo;
+#define NUMOF(X) (sizeof(X)/sizeof(X[0]))
+ static S_ServerOpInfo s_op_info[] =
+ {
+ { GDA_SERVER_OPERATION_CREATE_DB, "CREATE DB", "DB_DEF_P" },
+ { GDA_SERVER_OPERATION_DROP_DB, "DROP DB", "DB_DESC_P" }
+ };
+#define NUM_OPS NUMOF(s_op_info)
+ S_ServerOpInfo* op_info;
+ GdaServerOperation *op;
+ GdaServerProvider *server;
+ gchar* buf;
+ gint i;
+
+ g_return_val_if_fail( GDA_IS_CONNECTION(cnn), FALSE );
+ g_return_val_if_fail( gda_connection_is_opened(cnn), FALSE );
+
+ if( db_name == NULL ) {
+ g_message( "Database name is NULL!" );
+ g_set_error( error,
+ GDA_GENERAL_ERROR, GDA_GENERAL_OBJECT_NAME_ERROR,
+ "Couldn't create or drop database with a NULL string" );
+ return FALSE;
+ }
+
+ for( i = 0, op_info = NULL; i < NUM_OPS; i++ ) {
+ if( s_op_info[i].opType == opType ) {
+ op_info = &s_op_info[i];
+ break;
+ }
+ }
+
+ g_return_val_if_fail( op_info != NULL, FALSE );
+
+ server = gda_connection_get_provider_obj( cnn );
+ op = gda_server_provider_create_operation( server, cnn, opType, NULL,
+ error );
+ if( GDA_IS_SERVER_OPERATION(op) ) {
+ xmlDocPtr parameters;
+ xmlNodePtr root;
+ xmlNodePtr db;
+
+ /* Initation of the xmlDoc */
+ parameters = xmlNewDoc( "1.0" );
+
+ root = xmlNewDocNode( parameters, NULL, "serv_op_data", NULL );
+ xmlDocSetRootElement( parameters, root );
+ db = xmlNewChild( root, NULL, "op_data", db_name );
+ buf = g_strdup_printf( "/%s/DB_NAME", op_info->op_path_name );
+ xmlSetProp( db, "path", buf );
+ g_free( buf );
+
+ if( !gda_server_operation_load_data_from_xml(op, root, error ) ) {
+ /* error */
+ g_set_error( error, GDA_GENERAL_ERROR, GDA_GENERAL_OPERATION_ERROR,
+ "The XML operation doesn't exist or could't be loaded" );
+ g_object_unref( op );
+ xmlFreeDoc( parameters );
+ return FALSE;
+ } else {
+ if( !gda_server_provider_perform_operation( server, cnn, op, error ) ) {
+ /* error */
+ buf = g_strdup_printf( "The server couldn't perform the %s operation",
+ op_info->op_name );
+ g_set_error( error,
+ GDA_GENERAL_ERROR, GDA_GENERAL_OPERATION_ERROR,
+ buf );
+ g_free( buf );
+ g_object_unref( op );
+ xmlFreeDoc( parameters );
+ return FALSE;
+ }
+ }
+
+ g_object_unref( op );
+ xmlFreeDoc( parameters );
+ } else {
+ buf = g_strdup_printf( "The server doesn't support the %s operation",
+ op_info->op_name );
+ g_set_error( error, GDA_GENERAL_ERROR, GDA_GENERAL_OBJECT_NAME_ERROR,
+ buf );
+ g_free( buf );
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static gboolean
+drop_db( GncGdaBackend* be, const gchar* db_name, GError** error )
+{
+ return create_or_drop_db( be->pConnection, GDA_SERVER_OPERATION_DROP_DB,
+ db_name, error );
+}
+
+static gboolean
+create_db( GncGdaBackend* be, const gchar* db_name, GError** error )
+{
+ return create_or_drop_db( be->pConnection, GDA_SERVER_OPERATION_CREATE_DB,
+ db_name, error );
+}
+
+/* ========================== END OF FILE ===================== */
Added: gnucash/branches/gda-dev/src/backend/gda/gnc-backend-util-gda.h
===================================================================
--- gnucash/branches/gda-dev/src/backend/gda/gnc-backend-util-gda.h 2007-01-09 20:32:32 UTC (rev 15333)
+++ gnucash/branches/gda-dev/src/backend/gda/gnc-backend-util-gda.h 2007-01-09 20:59:02 UTC (rev 15334)
@@ -0,0 +1,155 @@
+/********************************************************************
+ * gnc-backend-gda.h: load and save data to SQL via libgda *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License as *
+ * published by the Free Software Foundation; either version 2 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact: *
+ * *
+ * Free Software Foundation Voice: +1-617-542-5942 *
+ * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
+ * Boston, MA 02110-1301, USA gnu at gnu.org *
+\********************************************************************/
+/** @file gnc-backend-gda.h
+ * @brief load and save data to SQL via libgda
+ * @author Copyright (c) 2006 Phil Longstaff <plongstaff at rogers.com>
+ *
+ * This file implements the top-level QofBackend API for saving/
+ * restoring data to/from an SQL database via libgda
+ */
+
+#ifndef GNC_BACKEND_GDA_H_
+#define GNC_BACKEND_GDA_H_
+
+#include "qof.h"
+#include <gmodule.h>
+
+#include "qofbackend-p.h"
+struct GncGdaBackend_struct
+{
+ QofBackend be;
+
+ GdaClient* pClient;
+ GdaConnection* pConnection;
+ GdaDict* pDict;
+
+ QofBook *primary_book; /* The primary, main open book */
+ gboolean loading; /* We are performing an initial load */
+ gboolean in_query;
+};
+typedef struct GncGdaBackend_struct GncGdaBackend;
+
+/**
+ * Struct used to pass in a new data type for GDA storage. This contains
+ * the set of callbacks to read and write GDA for new data objects.. New
+ * types should register an instance of this object with the engine.
+ *
+ * commit() - commit an object to the db
+ * initial_load() - load stuff when new db opened
+ */
+#define GNC_GDA_BACKEND "gnc:gda:1"
+#define GNC_GDA_BACKEND_VERSION 1
+typedef struct
+{
+ int version; /* backend version number */
+ const gchar * type_name; /* The XML tag for this type */
+
+ void (*commit)( GncGdaBackend* pBackend, QofInstance* inst );
+ void (*initial_load)( GncGdaBackend* pBackend );
+ void (*create_tables)( GncGdaBackend* pBackend );
+ gpointer (*compile_query)( GncGdaBackend* pBackend, QofQuery* pQuery );
+ void (*run_query)( GncGdaBackend* pBackend, gpointer pQuery );
+ void (*free_query)( GncGdaBackend* pBackend, gpointer pQuery );
+} GncGdaDataType_t;
+
+// This is now a static inside the module
+//QofBackend * libgncmod_backend_gda_LTX_gnc_backend_new(void);
+
+// Type for conversion of db row to object.
+typedef enum {
+ CT_STRING,
+ CT_GUID,
+ CT_INT,
+ CT_INT64,
+ CT_TIMESPEC,
+ CT_GDATE,
+ CT_NUMERIC,
+ CT_DOUBLE,
+ CT_BOOLEAN
+} E_COL_TYPE;
+
+typedef struct {
+ const gchar* col_name;
+ E_COL_TYPE col_type;
+ gint size;
+#define COL_PKEY 0x01
+#define COL_NNUL 0x02
+#define COL_UNIQUE 0x04
+#define COL_AUTOINC 0x08
+ gint flags;
+ const char* param_name; // If non null, use qof getter/setter
+ QofAccessFunc getter;
+ QofSetterFunc setter;
+} col_cvt_t;
+
+typedef enum {
+ OP_DB_ADD,
+ OP_DB_ADD_OR_UPDATE,
+ OP_DB_DELETE
+} E_DB_OPERATION;
+
+gboolean gnc_gda_do_db_operation( GncGdaBackend* pBackend,
+ E_DB_OPERATION op,
+ const gchar* table_name,
+ QofIdTypeConst obj_name,
+ gpointer pObject,
+ const col_cvt_t* table );
+GdaQuery* gnc_gda_build_insert_query( GncGdaBackend* pBackend,
+ const gchar* table_name,
+ QofIdTypeConst obj_name,
+ gpointer pObject,
+ const col_cvt_t* table );
+GdaQuery* gnc_gda_build_update_query( GncGdaBackend* pBackend,
+ const gchar* table_name,
+ QofIdTypeConst obj_name,
+ gpointer pObject,
+ const col_cvt_t* table );
+GdaQuery* gnc_gda_build_delete_query( GncGdaBackend* pBackend,
+ const gchar* table_name,
+ QofIdTypeConst obj_name,
+ gpointer pObject,
+ const col_cvt_t* table );
+GdaObject* gnc_gda_execute_query( GncGdaBackend* pBackend, GdaQuery* pQuery );
+GdaObject* gnc_gda_execute_sql( GncGdaBackend* pBackend, const gchar* sql );
+int gnc_gda_execute_select_get_count( GncGdaBackend* pBackend, const gchar* sql );
+int gnc_gda_execute_query_get_count( GncGdaBackend* pBackend, GdaQuery* query );
+void gnc_gda_load_object( GdaDataModel* pModel, int row,
+ QofIdTypeConst obj_name, gpointer pObject,
+ const col_cvt_t* table );
+gboolean gnc_gda_object_is_it_in_db( GncGdaBackend* be,
+ const gchar* table_name,
+ QofIdTypeConst obj_name, gpointer pObject,
+ const col_cvt_t* table );
+gboolean gnc_gda_create_table( GdaConnection* pConnection,
+ const gchar* table_name, col_cvt_t* col_table,
+ GError** error );
+void gnc_gda_create_table_if_needed( GncGdaBackend* be,
+ const gchar* table_name, col_cvt_t* col_table );
+const GUID* gnc_gda_load_guid( GdaDataModel* pModel, int row );
+GdaQuery* gnc_gda_create_select_query( const GncGdaBackend* be, const gchar* table_name );
+GdaQueryCondition* gnc_gda_create_condition_from_field( GdaQuery* query,
+ const gchar* col_name,
+ const GValue* value );
+
+G_MODULE_EXPORT const gchar *
+g_module_check_init(GModule *module);
+
+#endif /* GNC_BACKEND_GDA_H_ */
More information about the gnucash-changes
mailing list