r15192 - gnucash/branches/gda-dev/src/backend/gda - 1) Add missing files

Phil Longstaff plongstaff at cvs.gnucash.org
Fri Dec 8 13:48:35 EST 2006


Author: plongstaff
Date: 2006-12-08 13:48:34 -0500 (Fri, 08 Dec 2006)
New Revision: 15192
Trac: http://svn.gnucash.org/trac/changeset/15192

Added:
   gnucash/branches/gda-dev/src/backend/gda/gnc-lots-gda.c
   gnucash/branches/gda-dev/src/backend/gda/gnc-lots-gda.h
   gnucash/branches/gda-dev/src/backend/gda/gnc-slots-gda.c
   gnucash/branches/gda-dev/src/backend/gda/gnc-slots-gda.h
Modified:
   gnucash/branches/gda-dev/src/backend/gda/gnc-backend-gda.c
   gnucash/branches/gda-dev/src/backend/gda/gnc-schedxaction-gda.c
   gnucash/branches/gda-dev/src/backend/gda/gnc-transaction-gda.c
   gnucash/branches/gda-dev/src/backend/gda/gnc-transaction-gda.h
Log:
1) Add missing files
2) Add initial SX save/restore - will probably crash
3) When committing clean transaction, commit any dirty splits



Modified: gnucash/branches/gda-dev/src/backend/gda/gnc-backend-gda.c
===================================================================
--- gnucash/branches/gda-dev/src/backend/gda/gnc-backend-gda.c	2006-12-08 18:45:36 UTC (rev 15191)
+++ gnucash/branches/gda-dev/src/backend/gda/gnc-backend-gda.c	2006-12-08 18:48:34 UTC (rev 15192)
@@ -30,18 +30,6 @@
 
 #include <glib.h>
 #include <glib/gi18n.h>
-//#include <libintl.h>
-//#include <locale.h>
-//#include <stdio.h>
-//#include <fcntl.h>
-//#include <limits.h>
-//#include <sys/stat.h>
-//#include <sys/types.h>
-//#include <unistd.h>
-//#include <errno.h>
-//#include <string.h>
-//#include <dirent.h>
-//#include <time.h>
 #include <libgda/libgda.h>
 
 #include "qof.h"
@@ -50,8 +38,6 @@
 #include "TransLog.h"
 #include "gnc-engine.h"
 
-//#include "gnc-filepath-utils.h"
-
 #include "gnc-backend-gda.h"
 #include "gnc-gconf-utils.h"
 
@@ -64,10 +50,6 @@
 #include "gnc-slots-gda.h"
 #include "gnc-transaction-gda.h"
 
-//#ifndef HAVE_STRPTIME
-//# include "strptime.h"
-//#endif
-
 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,
@@ -821,6 +803,7 @@
 			pHandler = &string_handler;
 			break;
 
+		case CT_BOOLEAN:
 		case CT_INT:
 			pHandler = &int_handler;
 			break;
@@ -1537,6 +1520,10 @@
 
 	printf( "gda_commit_edit(): %s dirty = %d, do_free=%d\n", inst->entity.e_type, inst->dirty, inst->do_free );
 
+	if( !inst->dirty && !inst->do_free && GNC_IS_TRANS(inst) ) {
+		gnc_gda_transaction_commit_splits( be, GNC_TRANS(inst) );
+	}
+
 	if( !inst->dirty && !inst->do_free ) return;
 
 	be_data.ok = FALSE;
@@ -1549,8 +1536,6 @@
 				inst->entity.e_type );
 		return;
 	}
-
-	//qof_instance_mark_clean( inst );
 }
 /* ---------------------------------------------------------------------- */
 

Added: gnucash/branches/gda-dev/src/backend/gda/gnc-lots-gda.c
===================================================================
--- gnucash/branches/gda-dev/src/backend/gda/gnc-lots-gda.c	2006-12-08 18:45:36 UTC (rev 15191)
+++ gnucash/branches/gda-dev/src/backend/gda/gnc-lots-gda.c	2006-12-08 18:48:34 UTC (rev 15192)
@@ -0,0 +1,182 @@
+/********************************************************************
+ * gnc-lots-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-lots-gda.c
+ *  @brief load and save data to SQL 
+ *  @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 <libgda/libgda.h>
+
+#include "qof.h"
+#include "gnc-lot.h"
+
+#include "gnc-backend-gda.h"
+#include "gnc-slots-gda.h"
+
+#include "gnc-lots-gda.h"
+
+static QofLogModule log_module = GNC_MOD_BACKEND;
+
+#define TABLE_NAME "lots"
+
+static gpointer get_lot_account( gpointer pObject );
+static void set_lot_account( gpointer pObject, const gpointer pValue );
+static gpointer get_lot_is_closed( gpointer pObject );
+static void set_lot_is_closed( gpointer pObject, const gpointer pValue );
+
+static col_cvt_t col_table[] =
+{
+	{ "guid",			CT_GUID,	0, COL_NNUL|COL_PKEY,	NULL,
+			(GNC_GDA_FN_GETTER)qof_entity_get_guid,
+			(GNC_GDA_FN_SETTER)qof_entity_set_guid },
+	{ "account_guid",	CT_GUID,	  0, COL_NNUL,	NULL,
+			get_lot_account, set_lot_account },
+	{ "is_closed",		CT_STRING,  1, COL_NNUL, NULL,
+			get_lot_is_closed, set_lot_is_closed },
+	{ NULL }
+};
+
+/* ================================================================= */
+static gpointer
+get_lot_account( gpointer pObject )
+{
+	const GNCLot* lot = GNC_LOT(pObject);
+	const Account* pAccount = gnc_lot_get_account( lot );
+
+	return (gpointer)qof_instance_get_guid( QOF_INSTANCE(pAccount) );
+}
+
+static void 
+set_lot_account( gpointer pObject, const gpointer pValue )
+{
+	GNCLot* lot = GNC_LOT(pObject);
+	QofBook* pBook = qof_instance_get_book( QOF_INSTANCE(lot) );
+	GUID* guid = (GUID*)pValue;
+	Account* pAccount = xaccAccountLookup( guid, pBook );
+
+	xaccAccountInsertLot( pAccount, lot );
+}
+
+static gpointer
+get_lot_is_closed( gpointer pObject )
+{
+	GNCLot* lot = GNC_LOT(pObject);
+	static gboolean is_closed; 
+
+	is_closed = gnc_lot_is_closed( lot );
+	return &is_closed;
+}
+
+static void
+set_lot_is_closed( gpointer pObject, const gpointer pValue )
+{
+	GNCLot* lot = GNC_LOT(pObject);
+	const gboolean* pBoolean = (const gboolean*)pValue;
+
+	lot->is_closed = *pBoolean;
+}
+
+static GNCLot*
+load_lot( GncGdaBackend* be, GdaDataModel* pModel, int row, GNCLot* lot )
+{
+	if( lot == NULL ) {
+		lot = gnc_lot_new( be->primary_book );
+	}
+
+	gnc_gda_load_object( pModel, row, GNC_ID_LOT, lot, col_table );
+	gnc_gda_slots_load( be, qof_instance_get_guid( QOF_INSTANCE(lot) ),
+							qof_instance_get_slots( QOF_INSTANCE(lot) ) );
+
+	qof_instance_mark_clean( QOF_INSTANCE(lot) );
+
+	return lot;
+}
+
+static void
+load_lots( GncGdaBackend* be )
+{
+	static GdaQuery* query;
+	GdaObject* ret;
+
+	if( query == NULL ) {
+		query = gnc_gda_create_select_query( be, TABLE_NAME );
+	}
+	ret = gnc_gda_execute_query( be, query );
+	if( GDA_IS_DATA_MODEL( ret ) ) {
+		GdaDataModel* pModel = GDA_DATA_MODEL(ret);
+		int numRows = gda_data_model_get_n_rows( pModel );
+		int r;
+		GNCLot* lot;
+
+		for( r = 0; r < numRows; r++ ) {
+			lot = load_lot( be, pModel, r, NULL );
+		}
+	}
+}
+
+/* ================================================================= */
+static void
+create_lots_tables( GncGdaBackend* be )
+{
+	gnc_gda_create_table_if_needed( be, TABLE_NAME, col_table );
+}
+
+/* ================================================================= */
+
+static void
+commit_lot( GncGdaBackend* be, QofInstance* inst )
+{
+	GNCLot* lot = GNC_LOT(inst);
+
+	(void)gnc_gda_do_db_operation( be,
+						(inst->do_free ? OP_DB_DELETE : OP_DB_ADD_OR_UPDATE ),
+						TABLE_NAME,
+						GNC_ID_LOT, lot,
+						col_table );
+
+	// Now, commit any slots
+	gnc_gda_slots_save( be, qof_instance_get_guid( inst ),
+						qof_instance_get_slots( inst ) );
+}
+
+/* ================================================================= */
+void
+gnc_gda_init_lot_handler( void )
+{
+	static GncGdaDataType_t be_data =
+	{
+		GNC_GDA_BACKEND_VERSION,
+		GNC_ID_LOT,
+		commit_lot,			/* commit */
+		load_lots,			/* initial_load */
+		create_lots_tables	/* create tables */
+	};
+
+	qof_object_register_backend( GNC_ID_LOT, GNC_GDA_BACKEND, &be_data );
+}
+
+/* ========================== END OF FILE ===================== */

Added: gnucash/branches/gda-dev/src/backend/gda/gnc-lots-gda.h
===================================================================
--- gnucash/branches/gda-dev/src/backend/gda/gnc-lots-gda.h	2006-12-08 18:45:36 UTC (rev 15191)
+++ gnucash/branches/gda-dev/src/backend/gda/gnc-lots-gda.h	2006-12-08 18:48:34 UTC (rev 15192)
@@ -0,0 +1,37 @@
+/********************************************************************
+ * gnc-lots-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-lots-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_LOT_GDA_H_
+#define GNC_LOT_GDA_H_
+
+#include "qof.h"
+#include <gmodule.h>
+
+void gnc_gda_init_lot_handler( void );
+
+#endif /* GNC_LOT_GDA_H_ */

Modified: gnucash/branches/gda-dev/src/backend/gda/gnc-schedxaction-gda.c
===================================================================
--- gnucash/branches/gda-dev/src/backend/gda/gnc-schedxaction-gda.c	2006-12-08 18:45:36 UTC (rev 15191)
+++ gnucash/branches/gda-dev/src/backend/gda/gnc-schedxaction-gda.c	2006-12-08 18:48:34 UTC (rev 15192)
@@ -44,89 +44,148 @@
 
 static QofLogModule log_module = GNC_MOD_BACKEND;
 
+#define SX_MAX_NAME_LEN 50
+
+static gpointer get_autocreate( gpointer pObject );
+static void set_autocreate( gpointer pObject, const gpointer pValue );
+static gpointer get_autonotify( gpointer pObject );
+static void set_autonotify( gpointer pObject, const gpointer pValue );
+
 static col_cvt_t col_table[] =
 {
 	{ "guid",			CT_GUID,	0, COL_NNUL|COL_PKEY,	NULL,
 			(GNC_GDA_FN_GETTER)qof_entity_get_guid,
 			(GNC_GDA_FN_SETTER)qof_entity_set_guid },
+	{ "name",			CT_STRING, SX_MAX_NAME_LEN, COL_NNUL, GNC_SX_NAME },
+	{ "start_date",		CT_GDATE,	0, COL_NNUL, GNC_SX_START_DATE },
+	{ "last_occur",		CT_GDATE,	0, COL_NNUL, GNC_SX_LAST_DATE },
+	{ "num_occur",		CT_INT,		0, COL_NNUL, GNC_SX_NUM_OCCUR },
+	{ "rem_occur",		CT_INT,		0, COL_NNUL, GNC_SX_REM_OCCUR },
+	{ "auto_create",	CT_BOOLEAN,	0, COL_NNUL, NULL,
+			get_autocreate, set_autocreate },
+	{ "auto_notify",	CT_BOOLEAN,	0, COL_NNUL, NULL,
+			get_autonotify, set_autonotify },
+	{ "adv_creation",	CT_INT,		0, COL_NNUL, NULL,
+			(GNC_GDA_FN_GETTER)xaccSchedXactionGetAdvanceCreation,
+			(GNC_GDA_FN_SETTER)xaccSchedXactionSetAdvanceCreation },
+	{ "adv_notify",	CT_INT,		0, COL_NNUL, NULL,
+			(GNC_GDA_FN_GETTER)xaccSchedXactionGetAdvanceReminder,
+			(GNC_GDA_FN_SETTER)xaccSchedXactionSetAdvanceReminder },
 	{ NULL }
 };
 
 /* ================================================================= */
 
+static gpointer
+get_autocreate( gpointer pObject )
+{
+	const SchedXaction* pSx = GNC_SX(pObject);
+	gboolean autoCreate;
+	gboolean autoNotify;
+
+	xaccSchedXactionGetAutoCreate( pSx, &autoCreate, &autoNotify );
+	return (gpointer)autoCreate;
+}
+
+static void 
+set_autocreate( gpointer pObject, const gpointer pValue )
+{
+	SchedXaction* pSx = GNC_SX(pObject);
+	gboolean autoCreate;
+	gboolean autoNotify;
+
+	xaccSchedXactionGetAutoCreate( pSx, &autoCreate, &autoNotify );
+	autoCreate = (gboolean)pValue;
+	xaccSchedXactionSetAutoCreate( pSx, autoCreate, autoNotify );
+}
+
+static gpointer
+get_autonotify( gpointer pObject )
+{
+	const SchedXaction* pSx = GNC_SX(pObject);
+	gboolean autoCreate;
+	gboolean autoNotify;
+
+	xaccSchedXactionGetAutoCreate( pSx, &autoCreate, &autoNotify );
+	return (gpointer)autoNotify;
+}
+
+static void 
+set_autonotify( gpointer pObject, const gpointer pValue )
+{
+	SchedXaction* pSx = GNC_SX(pObject);
+	gboolean autoCreate;
+	gboolean autoNotify;
+
+	xaccSchedXactionGetAutoCreate( pSx, &autoCreate, &autoNotify );
+	autoNotify = (gboolean)pValue;
+	xaccSchedXactionSetAutoCreate( pSx, autoCreate, autoNotify );
+}
+
 /* ================================================================= */
 static SchedXaction*
 load_sx( GncGdaBackend* be, GdaDataModel* pModel, int row,
 			SchedXaction* pSx )
 {
-#if 0
 	const GUID* guid;
-	GUID budget_guid;
+	GUID sx_guid;
 
-	gnc_gda_load_object( pModel, row, GNC_ID_BUDGET, &guid, guid_table );
-	budget_guid = *guid;
+	guid = gnc_gda_load_guid( pModel, row );
+	sx_guid = *guid;
 
-	if( pBudget == NULL ) {
-		pBudget = gnc_budget_lookup( &budget_guid, be->primary_book );
-		if( pBudget == NULL ) {
-			pBudget = gnc_budget_new( be->primary_book );
-		}
+	if( pSx == NULL ) {
+		pSx = xaccSchedXactionMalloc( be->primary_book );
 	}
 
-	gnc_gda_load_object( pModel, row, GNC_ID_BUDGET, pBudget, col_table );
-	gnc_gda_slots_load( be, gnc_budget_get_guid( pBudget ),
-							qof_instance_get_slots( QOF_INSTANCE(pBudget) ) );
+	gnc_gda_load_object( pModel, row, GNC_ID_SCHEDXACTION, pSx, col_table );
+	gnc_gda_slots_load( be, qof_entity_get_guid( QOF_ENTITY(pSx) ),
+							qof_instance_get_slots( QOF_INSTANCE(pSx) ) );
 
-	qof_instance_mark_clean( QOF_INSTANCE(pBudget) );
+	qof_instance_mark_clean( QOF_INSTANCE(pSx) );
 
-#endif
 	return pSx;
 }
 
 static void
 load_sxes( GncGdaBackend* be )
 {
-#if 0
-	gchar* buf;
+	static GdaQuery* query;
 	GdaObject* ret;
 	QofBook* pBook = be->primary_book;
 
-	buf = g_strdup_printf( "SELECT * FROM %s", BUDGET_TABLE );
-	ret = gnc_gda_execute_sql( be, buf );
-	g_free( buf );
+	if( query == NULL ) {
+		query = gnc_gda_create_select_query( be, SCHEDXACTION_TABLE );
+	}
+	ret = gnc_gda_execute_query( be, query );
 	if( GDA_IS_DATA_MODEL( ret ) ) {
 		GdaDataModel* pModel = GDA_DATA_MODEL(ret);
 		int numRows = gda_data_model_get_n_rows( pModel );
 		int r;
 
 		for( r = 0; r < numRows; r++ ) {
-			(void)load_budget( be, pModel, r, NULL );
+			(void)load_sx( be, pModel, r, NULL );
 		}
 	}
-#endif
 }
 
 /* ================================================================= */
 static void
 create_sx_tables( GncGdaBackend* be )
 {
-#if 0
-	gnc_gda_create_table_if_needed( be, BUDGET_TABLE, col_table );
-#endif
+	gnc_gda_create_table_if_needed( be, SCHEDXACTION_TABLE, col_table );
 }
 
 /* ================================================================= */
 static void
 commit_sx( GncGdaBackend* be, QofInstance* inst )
 {
-#if 0
-	GncBudget* pBudget = (GncBudget*)inst;
+	SchedXaction* pSx = GNC_SX(inst);
 	const GUID* guid;
 
 	(void)gnc_gda_do_db_operation( be,
 						(inst->do_free ? OP_DB_DELETE : OP_DB_ADD_OR_UPDATE ),
-						BUDGET_TABLE,
-						GNC_ID_BUDGET, pBudget,
+						SCHEDXACTION_TABLE,
+						GNC_ID_SCHEDXACTION, pSx,
 						col_table );
 
 	// Delete old slot info
@@ -138,24 +197,21 @@
 	} else {
 		gnc_gda_slots_delete( be, guid );
 	}
-#endif
 }
 
 /* ================================================================= */
 void
 gnc_gda_init_schedxaction_handler( void )
 {
-#if 0
 	static GncGdaDataType_t be_data =
 	{
 		GNC_GDA_BACKEND_VERSION,
-		GNC_ID_BUDGET,
-		commit_budget,				/* commit */
-		load_budgets,				/* initial_load */
-		create_budget_tables		/* create_tables */
+		GNC_ID_SCHEDXACTION,
+		commit_sx,				/* commit */
+		load_sxes,				/* initial_load */
+		create_sx_tables		/* create_tables */
 	};
 
-	qof_object_register_backend( GNC_ID_BUDGET, GNC_GDA_BACKEND, &be_data );
-#endif
+	qof_object_register_backend( GNC_ID_SCHEDXACTION, GNC_GDA_BACKEND, &be_data );
 }
 /* ========================== END OF FILE ===================== */

Added: gnucash/branches/gda-dev/src/backend/gda/gnc-slots-gda.c
===================================================================
--- gnucash/branches/gda-dev/src/backend/gda/gnc-slots-gda.c	2006-12-08 18:45:36 UTC (rev 15191)
+++ gnucash/branches/gda-dev/src/backend/gda/gnc-slots-gda.c	2006-12-08 18:48:34 UTC (rev 15192)
@@ -0,0 +1,467 @@
+/********************************************************************
+ * gnc-slots-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-slots-gda.c
+ *  @brief load and save data to SQL 
+ *  @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 <libgda/libgda.h>
+
+#include "qof.h"
+#include "gnc-engine.h"
+
+#include "gnc-backend-gda.h"
+
+#include "gnc-slots-gda.h"
+
+static QofLogModule log_module = GNC_MOD_BACKEND;
+
+#define TABLE_NAME "slots"
+
+typedef struct {
+	GncGdaBackend* be;
+	const GUID* guid;
+	KvpFrame* pKvpFrame;
+	KvpValueType value_type;
+	KvpValue* pKvpValue;
+	GString* path;
+} slot_info_t;
+
+static gpointer get_slot_id( gpointer pObject );
+static void set_slot_id( gpointer pObject, const gpointer pValue );
+static gpointer get_obj_guid( gpointer pObject );
+static void set_obj_guid( gpointer pObject, const gpointer pValue );
+static gpointer get_path( gpointer pObject );
+static void set_path( gpointer pObject, const gpointer pValue );
+static gpointer get_slot_type( gpointer pObject );
+static void set_slot_type( gpointer pObject, const gpointer pValue );
+static gpointer get_int64_val( gpointer pObject );
+static void set_int64_val( gpointer pObject, const gpointer pValue );
+static gpointer get_string_val( gpointer pObject );
+static void set_string_val( gpointer pObject, const gpointer pValue );
+static gpointer get_double_val( gpointer pObject );
+static void set_double_val( gpointer pObject, const gpointer pValue );
+static gpointer get_timespec_val( gpointer pObject );
+static void set_timespec_val( gpointer pObject, const gpointer pValue );
+static gpointer get_guid_val( gpointer pObject );
+static void set_guid_val( gpointer pObject, const gpointer pValue );
+static gpointer get_numeric_val( gpointer pObject );
+static void set_numeric_val( gpointer pObject, const gpointer pValue );
+
+#define SLOT_MAX_PATHNAME_LEN 500
+#define SLOT_MAX_STRINGVAL_LEN 1000
+
+static col_cvt_t col_table[] =
+{
+	{ "slot_id",		CT_INT,		0, COL_NNUL|COL_PKEY|COL_AUTOINC, NULL,
+			get_slot_id, set_slot_id },
+	{ "obj_guid",		CT_GUID,	0, COL_NNUL,	NULL,
+			get_obj_guid, set_obj_guid },
+	{ "name",			CT_STRING,	SLOT_MAX_PATHNAME_LEN, COL_NNUL,	NULL,
+			get_path, set_path },
+	{ "slot_type",		CT_INT,		0, COL_NNUL,	NULL,
+			get_slot_type, set_slot_type, },
+	{ "int64_val",		CT_INT64,	0, 0,			NULL,
+			get_int64_val, set_int64_val },
+	{ "string_val",		CT_STRING,	SLOT_MAX_PATHNAME_LEN, 0,			NULL,
+			get_string_val, set_string_val },
+	{ "double_val",		CT_DOUBLE,	0, 0,			NULL,
+			get_double_val, set_double_val },
+	{ "timespec_val",	CT_TIMESPEC, 0, 0,			NULL,
+			get_timespec_val, set_timespec_val },
+	{ "guid_val",		CT_GUID,	0, 0,			NULL,
+			get_guid_val, set_guid_val },
+	{ "numeric_val",	CT_NUMERIC,	0, 0,			NULL,
+			get_numeric_val, set_numeric_val },
+	{ NULL }
+};
+
+/* Special column table because we need to be able to access the table by
+a column other than the primary key */
+static col_cvt_t guid_col_table[] =
+{
+	{ "obj_guid",		CT_GUID,	  0, COL_NNUL,	NULL,
+			get_obj_guid, set_obj_guid },
+	{ NULL }
+};
+
+/* ================================================================= */
+
+static gpointer
+get_slot_id( gpointer pObject )
+{
+	// Just need a 0 to force a new slot id
+	return (gpointer)0;
+}
+
+static void
+set_slot_id( gpointer pObject, gpointer pValue )
+{
+	// Nowhere to put the ID
+}
+
+static gpointer
+get_obj_guid( gpointer pObject )
+{
+	slot_info_t* pInfo = (slot_info_t*)pObject;
+
+	return (gpointer)pInfo->guid;
+}
+
+static void
+set_obj_guid( gpointer pObject, gpointer pValue )
+{
+	// Nowhere to put the GUID
+}
+
+static gpointer
+get_path( gpointer pObject )
+{
+	slot_info_t* pInfo = (slot_info_t*)pObject;
+
+	return (gpointer)pInfo->path->str;
+}
+
+static void
+set_path( gpointer pObject, gpointer pValue )
+{
+	slot_info_t* pInfo = (slot_info_t*)pObject;
+
+	pInfo->path = g_string_new( (gchar*)pValue );
+}
+
+static gpointer
+get_slot_type( gpointer pObject )
+{
+	slot_info_t* pInfo = (slot_info_t*)pObject;
+
+	return (gpointer)kvp_value_get_type( pInfo->pKvpValue );
+}
+
+static void
+set_slot_type( gpointer pObject, gpointer pValue )
+{
+	slot_info_t* pInfo = (slot_info_t*)pObject;
+
+	pInfo->value_type = (KvpValueType)pValue;
+}
+
+static gpointer
+get_int64_val( gpointer pObject )
+{
+	slot_info_t* pInfo = (slot_info_t*)pObject;
+	static gint64 i64_val;
+
+	if( kvp_value_get_type( pInfo->pKvpValue ) == KVP_TYPE_GINT64 ) {
+		i64_val = kvp_value_get_gint64( pInfo->pKvpValue );
+		return &i64_val;
+	} else {
+		return NULL;
+	}
+}
+
+static void
+set_int64_val( gpointer pObject, const gpointer pValue )
+{
+	slot_info_t* pInfo = (slot_info_t*)pObject;
+
+	if( pInfo->value_type == KVP_TYPE_GINT64 ) {
+		kvp_frame_add_gint64( pInfo->pKvpFrame, pInfo->path->str, *(gint64*)pValue );
+	}
+}
+
+static gpointer
+get_string_val( gpointer pObject )
+{
+	slot_info_t* pInfo = (slot_info_t*)pObject;
+
+	if( kvp_value_get_type( pInfo->pKvpValue ) == KVP_TYPE_STRING ) {
+		return (gpointer)kvp_value_get_string( pInfo->pKvpValue );
+	} else {
+		return NULL;
+	}
+}
+
+static void
+set_string_val( gpointer pObject, const gpointer pValue )
+{
+	slot_info_t* pInfo = (slot_info_t*)pObject;
+
+	if( pInfo->value_type == KVP_TYPE_STRING ) {
+		kvp_frame_add_string( pInfo->pKvpFrame, pInfo->path->str, (const gchar*)pValue );
+	}
+}
+
+static gpointer
+get_double_val( gpointer pObject )
+{
+	slot_info_t* pInfo = (slot_info_t*)pObject;
+	static double d_val;
+
+	if( kvp_value_get_type( pInfo->pKvpValue ) == KVP_TYPE_DOUBLE ) {
+		d_val = kvp_value_get_double( pInfo->pKvpValue );
+		return (gpointer)&d_val;
+	} else {
+		return NULL;
+	}
+}
+
+static void
+set_double_val( gpointer pObject, const gpointer pValue )
+{
+	slot_info_t* pInfo = (slot_info_t*)pObject;
+
+	if( pInfo->value_type == KVP_TYPE_DOUBLE ) {
+		kvp_frame_add_double( pInfo->pKvpFrame, pInfo->path->str, *(double*)pValue );
+	}
+}
+
+static gpointer
+get_timespec_val( gpointer pObject )
+{
+	slot_info_t* pInfo = (slot_info_t*)pObject;
+	static Timespec ts;
+
+	if( kvp_value_get_type( pInfo->pKvpValue ) == KVP_TYPE_TIMESPEC ) {
+		ts = kvp_value_get_timespec( pInfo->pKvpValue );
+		return (gpointer)&ts;
+	} else {
+		return NULL;
+	}
+}
+
+static void
+set_timespec_val( gpointer pObject, const gpointer pValue )
+{
+	slot_info_t* pInfo = (slot_info_t*)pObject;
+
+	if( pInfo->value_type == KVP_TYPE_TIMESPEC ) {
+		kvp_frame_add_timespec( pInfo->pKvpFrame, pInfo->path->str, *(Timespec*)pValue );
+	}
+}
+
+static gpointer
+get_guid_val( gpointer pObject )
+{
+	slot_info_t* pInfo = (slot_info_t*)pObject;
+
+	if( kvp_value_get_type( pInfo->pKvpValue ) == KVP_TYPE_GUID ) {
+		return (gpointer)kvp_value_get_guid( pInfo->pKvpValue );
+	} else {
+		return NULL;
+	}
+}
+
+static void
+set_guid_val( gpointer pObject, const gpointer pValue )
+{
+	slot_info_t* pInfo = (slot_info_t*)pObject;
+
+	if( pInfo->value_type == KVP_TYPE_GUID ) {
+		kvp_frame_add_guid( pInfo->pKvpFrame, pInfo->path->str, (GUID*)pValue );
+	}
+}
+
+static gpointer
+get_numeric_val( gpointer pObject )
+{
+	slot_info_t* pInfo = (slot_info_t*)pObject;
+	static gnc_numeric n_val;
+
+	if( kvp_value_get_type( pInfo->pKvpValue ) == KVP_TYPE_NUMERIC ) {
+		n_val = kvp_value_get_numeric( pInfo->pKvpValue );
+		return (gpointer)&n_val;
+	} else {
+		return NULL;
+	}
+}
+
+static void
+set_numeric_val( gpointer pObject, const gpointer pValue )
+{
+	slot_info_t* pInfo = (slot_info_t*)pObject;
+
+	if( pInfo->value_type == KVP_TYPE_NUMERIC ) {
+		kvp_frame_add_numeric( pInfo->pKvpFrame, pInfo->path->str, *(gnc_numeric*)pValue );
+	}
+}
+
+static void
+save_slot( const gchar* key, KvpValue* value, gpointer data )
+{
+	slot_info_t* pSlot_info = (slot_info_t*)data;
+	gint curlen = pSlot_info->path->len;
+
+	pSlot_info->pKvpValue = value;
+	if( curlen != 0 ) {
+		g_string_append( pSlot_info->path, "/" );
+	}
+	g_string_append( pSlot_info->path, key );
+
+	if( kvp_value_get_type( value ) == KVP_TYPE_FRAME ) {
+		KvpFrame* pKvpFrame = kvp_value_get_frame( value );
+		kvp_frame_for_each_slot( pKvpFrame, save_slot, pSlot_info );
+	} else {
+		(void)gnc_gda_do_db_operation( pSlot_info->be, OP_DB_ADD, TABLE_NAME,
+										TABLE_NAME, pSlot_info, col_table );
+	}
+
+	g_string_truncate( pSlot_info->path, curlen );
+}
+
+void
+gnc_gda_slots_save( GncGdaBackend* be, const GUID* guid, KvpFrame* pFrame )
+{
+	slot_info_t slot_info;
+
+	/* First, delete the old slots for this object */
+	gnc_gda_slots_delete( be, guid );
+
+	slot_info.be = be;
+	slot_info.guid = guid;
+	slot_info.path = g_string_new( "" );
+	kvp_frame_for_each_slot( pFrame, save_slot, &slot_info );
+	g_string_free( slot_info.path, FALSE );
+}
+
+void
+gnc_gda_slots_delete( GncGdaBackend* be, const GUID* guid )
+{
+	slot_info_t slot_info;
+
+	slot_info.be = be;
+	slot_info.guid = guid;
+	(void)gnc_gda_do_db_operation( be, OP_DB_DELETE, TABLE_NAME,
+								TABLE_NAME, &slot_info, guid_col_table );
+}
+
+static void
+load_slot( GncGdaBackend* be, GdaDataModel* pModel, gint row, KvpFrame* pFrame )
+{
+	slot_info_t slot_info;
+
+	slot_info.be = be;
+	slot_info.pKvpFrame = pFrame;
+	slot_info.path = NULL;
+
+	gnc_gda_load_object( pModel, row, TABLE_NAME, &slot_info, col_table );
+
+	if( slot_info.path != NULL ) {
+		g_string_free( slot_info.path, TRUE );
+	}
+}
+
+void
+gnc_gda_slots_load( GncGdaBackend* be, const GUID* guid, KvpFrame* pFrame )
+{
+	gchar* buf;
+	GdaObject* ret;
+	gchar guid_buf[GUID_ENCODING_LENGTH+1];
+	gchar* field_name;
+
+	static GdaQuery* query = NULL;
+	GdaQueryCondition* cond;
+	GdaQueryField* key_value;
+	GValue value;
+
+	guid_to_string_buff( guid, guid_buf );
+
+	/* First time, create the query */
+	if( query == NULL ) {
+		GdaQueryTarget* target;
+		GdaQueryField* key;
+
+		/* SELECT */
+		query = gnc_gda_create_select_query( be, TABLE_NAME );
+		target = gda_query_get_target_by_alias( query, TABLE_NAME );
+
+		/* WHERE */
+		cond = gda_query_condition_new( query, GDA_QUERY_CONDITION_LEAF_EQUAL );
+		gda_query_set_condition( query, cond );
+
+		field_name = g_strdup_printf( "%s.%s",
+						gda_query_target_get_alias( target ), "obj_guid" );
+		key = gda_query_field_field_new( query, field_name );
+		g_free( field_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_TYPE_STRING );
+		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) );
+	}
+
+	/* Fill in the guid value */
+	cond = gda_query_get_condition( query );
+	key_value = gda_query_condition_leaf_get_operator( cond, 
+												GDA_QUERY_CONDITION_OP_RIGHT );
+	memset( &value, 0, sizeof( value ) );
+	g_value_init( &value, G_TYPE_STRING );
+	g_value_set_string( &value, guid_buf );
+	gda_query_field_value_set_value( GDA_QUERY_FIELD_VALUE(key_value), &value );
+
+	ret = gnc_gda_execute_query( be, query );
+	if( GDA_IS_DATA_MODEL( ret ) ) {
+		GdaDataModel* pModel = GDA_DATA_MODEL(ret);
+		int numRows = gda_data_model_get_n_rows( pModel );
+		int r;
+		KvpValue* pValue;
+
+		for( r = 0; r < numRows; r++ ) {
+			load_slot( be, pModel, r, pFrame );
+		}
+	}
+}
+
+/* ================================================================= */
+static void
+create_slots_tables( GncGdaBackend* be )
+{
+	gnc_gda_create_table_if_needed( be, TABLE_NAME, col_table );
+}
+
+/* ================================================================= */
+void
+gnc_gda_init_slots_handler( void )
+{
+	static GncGdaDataType_t be_data =
+	{
+		GNC_GDA_BACKEND_VERSION,
+		GNC_ID_ACCOUNT,
+		NULL,					/* commit - cannot occur */
+		NULL,					/* initial_load - cannot occur */
+		create_slots_tables		/* create_tables */
+	};
+
+	qof_object_register_backend( TABLE_NAME, GNC_GDA_BACKEND, &be_data );
+}
+/* ========================== END OF FILE ===================== */

Added: gnucash/branches/gda-dev/src/backend/gda/gnc-slots-gda.h
===================================================================
--- gnucash/branches/gda-dev/src/backend/gda/gnc-slots-gda.h	2006-12-08 18:45:36 UTC (rev 15191)
+++ gnucash/branches/gda-dev/src/backend/gda/gnc-slots-gda.h	2006-12-08 18:48:34 UTC (rev 15192)
@@ -0,0 +1,41 @@
+/********************************************************************
+ * gnc-slots-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-slots-gda.h
+ *  @brief load and save accounts 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_SLOTS_GDA_H_
+#define GNC_SLOTS_GDA_H_
+
+#include "qof.h"
+#include <gmodule.h>
+
+void gnc_gda_slots_save( GncGdaBackend* be, const GUID* guid, KvpFrame* pFrame );
+void gnc_gda_slots_delete( GncGdaBackend* be, const GUID* guid );
+void gnc_gda_slots_load( GncGdaBackend* be, const GUID* guid, KvpFrame* pFrame );
+
+void gnc_gda_init_slots_handler( void );
+
+#endif /* GNC_SLOTS_GDA_H_ */

Modified: gnucash/branches/gda-dev/src/backend/gda/gnc-transaction-gda.c
===================================================================
--- gnucash/branches/gda-dev/src/backend/gda/gnc-transaction-gda.c	2006-12-08 18:45:36 UTC (rev 15191)
+++ gnucash/branches/gda-dev/src/backend/gda/gnc-transaction-gda.c	2006-12-08 18:48:34 UTC (rev 15192)
@@ -35,6 +35,9 @@
 #include "qofquery-p.h"
 #include "qofquerycore-p.h"
 
+#include "Account.h"
+#include "Transaction.h"
+
 #include "gnc-backend-gda.h"
 #include "gnc-transaction-gda.h"
 #include "gnc-commodity.h"
@@ -43,9 +46,6 @@
 
 #include "gnc-engine.h"
 
-#include "Account.h"
-#include "Transaction.h"
-
 static QofLogModule log_module = GNC_MOD_BACKEND;
 
 #define TRANSACTION_TABLE "transactions"
@@ -357,6 +357,12 @@
 			pSplit = xaccMallocSplit( be->primary_book );
 		}
 	}
+
+	/* If the split is dirty, don't overwrite it */
+	if( qof_instance_is_dirty( QOF_INSTANCE(pSplit) ) ) {
+		return pSplit;
+	}
+
 	gnc_gda_load_object( pModel, row, GNC_ID_SPLIT, pSplit, split_col_table );
 	gnc_gda_slots_load( be, qof_instance_get_guid( QOF_INSTANCE(pSplit) ),
 							qof_instance_get_slots( QOF_INSTANCE(pSplit) ) );
@@ -508,16 +514,27 @@
 }
 
 static void
+commit_split( GncGdaBackend* be, QofInstance* inst )
+{
+	Split* pSplit = GNC_SPLIT(inst);
+
+	(void)gnc_gda_do_db_operation( be,
+						(inst->do_free ? OP_DB_DELETE : OP_DB_ADD_OR_UPDATE ),
+						SPLIT_TABLE,
+						GNC_ID_SPLIT, pSplit,
+						split_col_table );
+	gnc_gda_slots_save( be,
+						qof_instance_get_guid( QOF_INSTANCE(pSplit) ),
+						qof_instance_get_slots( QOF_INSTANCE(pSplit) ) );
+}
+
+static void
 save_split_cb( gpointer data, gpointer user_data )
 {
 	split_info_t* split_info = (split_info_t*)user_data;
 	Split* pSplit = GNC_SPLIT(data);
 
-	(void)gnc_gda_do_db_operation( split_info->be, OP_DB_ADD, SPLIT_TABLE,
-									GNC_ID_SPLIT, pSplit, split_col_table );
-	gnc_gda_slots_save( split_info->be,
-							qof_instance_get_guid( QOF_INSTANCE(pSplit) ),
-							qof_instance_get_slots( QOF_INSTANCE(pSplit) ) );
+	commit_split( split_info->be, QOF_INSTANCE(pSplit) );
 }
 
 static void
@@ -559,6 +576,20 @@
 	}
 }
 
+void gnc_gda_transaction_commit_splits( GncGdaBackend* be, Transaction* pTx )
+{
+	SplitList* splits;
+	Split* s;
+	QofBackend* qbe = (QofBackend*)be;
+	
+	splits = xaccTransGetSplitList( pTx );
+	for( ; splits != NULL; splits = splits->next ) {
+		s = GNC_SPLIT(splits->data);
+
+		qbe->commit( qbe, QOF_INSTANCE(s) );
+	}
+}
+
 /* ================================================================= */
 static const GUID*
 get_guid_from_query( QofQuery* pQuery )
@@ -714,7 +745,7 @@
 	{
 		GNC_GDA_BACKEND_VERSION,
 		GNC_ID_SPLIT,
-		NULL,						/* commit */
+		commit_split,				/* commit */
 		NULL,						/* initial_load */
 		NULL,						/* create tables */
 		compile_split_query,

Modified: gnucash/branches/gda-dev/src/backend/gda/gnc-transaction-gda.h
===================================================================
--- gnucash/branches/gda-dev/src/backend/gda/gnc-transaction-gda.h	2006-12-08 18:45:36 UTC (rev 15191)
+++ gnucash/branches/gda-dev/src/backend/gda/gnc-transaction-gda.h	2006-12-08 18:48:34 UTC (rev 15192)
@@ -33,5 +33,6 @@
 #include <gmodule.h>
 
 void gnc_gda_init_transaction_handler( void );
+void gnc_gda_transaction_commit_splits( GncGdaBackend* be, Transaction* pTx );
 
 #endif /* GNC_TRANSACTION_GDA_H_ */



More information about the gnucash-changes mailing list