r16700 - gnucash/branches/gda-dev2/src - 1) Add gda backend code

Phil Longstaff plongstaff at cvs.gnucash.org
Sun Dec 23 15:25:57 EST 2007


Author: plongstaff
Date: 2007-12-23 15:25:56 -0500 (Sun, 23 Dec 2007)
New Revision: 16700
Trac: http://svn.gnucash.org/trac/changeset/16700

Added:
   gnucash/branches/gda-dev2/src/backend/gda/
   gnucash/branches/gda-dev2/src/backend/gda/Makefile.am
   gnucash/branches/gda-dev2/src/backend/gda/gnc-account-gda.c
   gnucash/branches/gda-dev2/src/backend/gda/gnc-account-gda.h
   gnucash/branches/gda-dev2/src/backend/gda/gnc-backend-gda.c
   gnucash/branches/gda-dev2/src/backend/gda/gnc-backend-gda.h
   gnucash/branches/gda-dev2/src/backend/gda/gnc-backend-util-gda.c
   gnucash/branches/gda-dev2/src/backend/gda/gnc-backend-util-gda.h
   gnucash/branches/gda-dev2/src/backend/gda/gnc-book-gda.c
   gnucash/branches/gda-dev2/src/backend/gda/gnc-book-gda.h
   gnucash/branches/gda-dev2/src/backend/gda/gnc-budget-gda.c
   gnucash/branches/gda-dev2/src/backend/gda/gnc-budget-gda.h
   gnucash/branches/gda-dev2/src/backend/gda/gnc-commodity-gda.c
   gnucash/branches/gda-dev2/src/backend/gda/gnc-commodity-gda.h
   gnucash/branches/gda-dev2/src/backend/gda/gnc-lots-gda.c
   gnucash/branches/gda-dev2/src/backend/gda/gnc-lots-gda.h
   gnucash/branches/gda-dev2/src/backend/gda/gnc-price-gda.c
   gnucash/branches/gda-dev2/src/backend/gda/gnc-price-gda.h
   gnucash/branches/gda-dev2/src/backend/gda/gnc-recurrence-gda.c
   gnucash/branches/gda-dev2/src/backend/gda/gnc-recurrence-gda.h
   gnucash/branches/gda-dev2/src/backend/gda/gnc-schedxaction-gda.c
   gnucash/branches/gda-dev2/src/backend/gda/gnc-schedxaction-gda.h
   gnucash/branches/gda-dev2/src/backend/gda/gnc-slots-gda.c
   gnucash/branches/gda-dev2/src/backend/gda/gnc-slots-gda.h
   gnucash/branches/gda-dev2/src/backend/gda/gnc-transaction-gda.c
   gnucash/branches/gda-dev2/src/backend/gda/gnc-transaction-gda.h
   gnucash/branches/gda-dev2/src/backend/gda/gncmod-backend-gda.c
   gnucash/branches/gda-dev2/src/backend/gda/test/
   gnucash/branches/gda-dev2/src/backend/gda/test/Makefile.am
   gnucash/branches/gda-dev2/src/backend/gda/test/test-load-backend.c
   gnucash/branches/gda-dev2/src/backend/xml/
   gnucash/branches/gda-dev2/src/business/business-core/gda/
   gnucash/branches/gda-dev2/src/business/business-core/gda/Makefile.am
   gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-address-gda.c
   gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-address-gda.h
   gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-bill-term-gda.c
   gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-bill-term-gda.h
   gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-customer-gda.c
   gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-customer-gda.h
   gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-employee-gda.c
   gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-employee-gda.h
   gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-entry-gda.c
   gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-entry-gda.h
   gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-invoice-gda.c
   gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-invoice-gda.h
   gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-job-gda.c
   gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-job-gda.h
   gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-order-gda.c
   gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-order-gda.h
   gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-vendor-gda.c
   gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-vendor-gda.h
   gnucash/branches/gda-dev2/src/business/business-core/gda/gncmod-business-backend-gda.c
   gnucash/branches/gda-dev2/src/business/business-core/xml/
Removed:
   gnucash/branches/gda-dev2/src/backend/file/
   gnucash/branches/gda-dev2/src/business/business-core/file/
Log:
1) Add gda backend code
2) Rename file backend directories to xml



Added: gnucash/branches/gda-dev2/src/backend/gda/Makefile.am
===================================================================
--- gnucash/branches/gda-dev2/src/backend/gda/Makefile.am	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/backend/gda/Makefile.am	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,63 @@
+SUBDIRS = . test
+
+# Now a shared library AND a GModule
+lib_LTLIBRARIES = libgnc-backend-gda-utils.la
+pkglib_LTLIBRARIES = libgncmod-backend-gda.la
+
+
+AM_CFLAGS = \
+  -I.. -I../.. \
+  -DLOCALE_DIR=\""$(datadir)/locale"\" \
+  -I${top_srcdir}/src/backend \
+  -I${top_srcdir}/src/engine \
+  -I${top_srcdir}/src/core-utils\
+  -I${top_srcdir}/lib/libc\
+  ${QOF_CFLAGS} \
+  ${GLIB_CFLAGS} \
+  ${LIBGDA_CFLAGS} \
+  ${GCONF_CFLAGS} \
+  ${WARN_CFLAGS}
+
+libgnc_backend_gda_utils_la_SOURCES = \
+  gnc-backend-util-gda.c \
+  gnc-account-gda.c \
+  gnc-book-gda.c \
+  gnc-budget-gda.c \
+  gnc-commodity-gda.c \
+  gnc-lots-gda.c \
+  gnc-price-gda.c \
+  gnc-recurrence-gda.c \
+  gnc-schedxaction-gda.c \
+  gnc-slots-gda.c \
+  gnc-transaction-gda.c
+
+libgncmod_backend_gda_la_SOURCES = \
+  gnc-backend-gda.c
+
+noinst_HEADERS = \
+  gnc-account-gda.h \
+  gnc-backend-gda.h \
+  gnc-backend-util-gda.h \
+  gnc-book-gda.h \
+  gnc-budget-gda.h \
+  gnc-commodity-gda.h \
+  gnc-lots-gda.h \
+  gnc-price-gda.h \
+  gnc-recurrence-gda.h \
+  gnc-schedxaction-gda.h \
+  gnc-slots-gda.h \
+  gnc-transaction-gda.h
+
+libgnc_backend_gda_utils_la_LIBADD = \
+   ${GLIB_LIBS} ${GCONF_LIBS} \
+   ${top_builddir}/src/engine/libgncmod-engine.la \
+   ${LIBGDA_LIBS}
+
+libgncmod_backend_gda_la_LDFLAGS = -module -avoid-version
+libgncmod_backend_gda_la_LIBADD = \
+   ${GLIB_LIBS} ${GCONF_LIBS} \
+   ${top_builddir}/src/engine/libgncmod-engine.la \
+   libgnc-backend-gda-utils.la \
+   ${LIBGDA_LIBS}
+
+INCLUDES = -DG_LOG_DOMAIN=\"gnc.backend.gda\"

Added: gnucash/branches/gda-dev2/src/backend/gda/gnc-account-gda.c
===================================================================
--- gnucash/branches/gda-dev2/src/backend/gda/gnc-account-gda.c	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/backend/gda/gnc-account-gda.c	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,314 @@
+/********************************************************************
+ * gnc-account-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-account-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 "Account.h"
+#include "AccountP.h"
+#include "gnc-commodity.h"
+
+#include "gnc-backend-util-gda.h"
+
+#include "gnc-account-gda.h"
+#include "gnc-commodity-gda.h"
+#include "gnc-slots-gda.h"
+#include "gnc-transaction-gda.h"
+
+static QofLogModule log_module = GNC_MOD_BACKEND;
+
+#define TABLE_NAME "accounts"
+
+static gpointer get_parent( gpointer pObject, const QofParam* );
+static void set_parent( gpointer pObject, gpointer pValue );
+static void set_parent_guid( gpointer pObject, gpointer pValue );
+
+#define ACCOUNT_MAX_NAME_LEN 50
+#define ACCOUNT_MAX_TYPE_LEN 50
+#define ACCOUNT_MAX_CODE_LEN 100
+#define ACCOUNT_MAX_DESCRIPTION_LEN 500
+
+static col_cvt_t col_table[] =
+{
+    { "guid",           CT_GUID,         0,                           COL_NNUL, "guid" },
+    { "name",           CT_STRING,       ACCOUNT_MAX_NAME_LEN,        COL_NNUL, "name" },
+    { "account_type",   CT_STRING,       ACCOUNT_MAX_TYPE_LEN,        COL_NNUL, NULL, ACCOUNT_TYPE_ },
+    { "commodity_guid", CT_COMMODITYREF, 0,                           COL_NNUL, "commodity" },
+    { "parent_guid",    CT_GUID,         0,                           0,        NULL, NULL, get_parent, set_parent },
+    { "code",           CT_STRING,       ACCOUNT_MAX_CODE_LEN,        0,        "code" },
+    { "description",    CT_STRING,       ACCOUNT_MAX_DESCRIPTION_LEN, 0,        "description" },
+    { NULL }
+};
+static col_cvt_t parent_col_table[] =
+{
+    { "parent_guid", CT_GUID, 0, 0, NULL, NULL, NULL, set_parent_guid },
+    { NULL }
+};
+
+typedef struct {
+	Account* pAccount;
+	GUID guid;
+} account_parent_guid_struct;
+
+/* ================================================================= */
+
+static gpointer
+get_parent( gpointer pObject, const QofParam* param )
+{
+    const Account* pAccount = GNC_ACCOUNT(pObject);
+    const Account* pParent = gnc_account_get_parent( pAccount );
+    const GUID* parent_guid;
+
+    if( pParent == NULL ) {
+        parent_guid = NULL;
+    } else {
+        parent_guid = qof_instance_get_guid( QOF_INSTANCE(pParent) );
+    }
+
+    return (gpointer)parent_guid;
+}
+
+static void 
+set_parent( gpointer pObject, gpointer pValue )
+{
+    Account* pAccount = GNC_ACCOUNT(pObject);
+    QofBook* pBook = qof_instance_get_book( QOF_INSTANCE(pAccount) );
+    GUID* guid = (GUID*)pValue;
+    Account* pParent;
+    
+    if( guid != NULL ) {
+        pParent = xaccAccountLookup( guid, pBook );
+        if( pParent != NULL ) {
+            gnc_account_append_child( pParent, pAccount );
+        }
+    }
+}
+
+static void
+set_parent_guid( gpointer pObject, gpointer pValue )
+{
+	account_parent_guid_struct* s = (account_parent_guid_struct*)pObject;
+    GUID* guid = (GUID*)pValue;
+
+	s->guid = *guid;
+}
+
+static void
+load_balances( GncGdaBackend* be, Account* pAccount )
+{
+    gnc_numeric start_balance;
+	gnc_numeric cleared_balance;
+	gnc_numeric reconciled_balance;
+
+	gnc_gda_get_account_balances( be, pAccount, &start_balance, &cleared_balance, &reconciled_balance );
+
+    g_object_set( pAccount,
+				"end-balance", &start_balance,
+                "end-cleared-balance", &cleared_balance,
+                "end-reconciled-balance", &reconciled_balance,
+                NULL);
+}
+
+static Account*
+load_single_account( GncGdaBackend* be, GdaDataModel* pModel, int row,
+				GList** l_accounts_needing_parents )
+{
+    const GUID* guid;
+    GUID acc_guid;
+	Account* pAccount;
+
+    guid = gnc_gda_load_guid( be, pModel, row );
+    acc_guid = *guid;
+
+    pAccount = xaccAccountLookup( &acc_guid, be->primary_book );
+    if( pAccount == NULL ) {
+        pAccount = xaccMallocAccount( be->primary_book );
+    }
+    gnc_gda_load_object( be, pModel, row, GNC_ID_ACCOUNT, pAccount, col_table );
+    gnc_gda_slots_load( be, xaccAccountGetGUID( pAccount ),
+                        qof_instance_get_slots( QOF_INSTANCE(pAccount) ) );
+    load_balances( be, pAccount );
+
+    qof_instance_mark_clean( QOF_INSTANCE(pAccount) );
+
+	/* If we don't have a parent, it might be because the parent account hasn't
+	   been loaded yet.  Remember the account and its parent guid for later. */
+	if( gnc_account_get_parent( pAccount ) == NULL ) {
+		account_parent_guid_struct* s = g_slice_new( account_parent_guid_struct );
+		s->pAccount = pAccount;
+		gnc_gda_load_object( be, pModel, row, GNC_ID_ACCOUNT, s, parent_col_table );
+		*l_accounts_needing_parents = g_list_prepend( *l_accounts_needing_parents, s );
+	}
+
+    return pAccount;
+}
+
+static void
+load_all_accounts( GncGdaBackend* be )
+{
+    static GdaQuery* query = NULL;
+    GdaObject* ret;
+    QofBook* pBook = be->primary_book;
+    gnc_commodity_table* pTable = gnc_commodity_table_get_table( pBook );
+
+    /* First time, create the query */
+    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;
+        Account* pAccount;
+        Account* parent;
+		GList* l_accounts_needing_parents = NULL;
+
+        for( r = 0; r < numRows; r++ ) {
+            pAccount = load_single_account( be, pModel, r, &l_accounts_needing_parents );
+
+#if 0
+            if( pAccount != NULL ) {
+
+                /* Backwards compatibility.  If there's no parent, see if
+                 * this account is of type ROOT.  If not, find or create a
+                 * ROOT account and make that the parent. */
+                parent = gnc_account_get_parent( pAccount );
+                if( parent == NULL ) {
+                    int type;
+
+                    type = xaccAccountGetType( pAccount );
+                    if( type != ACCT_TYPE_ROOT ) {
+                        Account* root;
+                        root = gnc_book_get_root_account( pBook );
+                        if( root == NULL ) {
+                            root = gnc_account_create_root( pBook );
+                        }
+                        gnc_account_append_child( root, pAccount ); 
+                    }
+                }
+            }
+#endif
+        }
+
+		/* While there are items on the list of accounts needing parents,
+		   try to see if the parent has now been loaded.  Theory says that if
+		   items are removed from the front and added to the back if the
+		   parent is still not available, then eventually, the list will
+		   shrink to size 0. */
+		if( l_accounts_needing_parents != NULL ) {
+			gboolean progress_made = TRUE;
+
+			Account* pParent;
+			GList* elem;
+			
+			while( progress_made ) {
+				progress_made = FALSE;
+				for( elem = l_accounts_needing_parents; elem != NULL; elem = g_list_next( elem ) ) {
+					account_parent_guid_struct* s = (account_parent_guid_struct*)elem->data;
+					const gchar* name = xaccAccountGetName( s->pAccount );
+    				pParent = xaccAccountLookup( &s->guid, be->primary_book );
+					if( pParent != NULL ) {
+						gnc_account_append_child( pParent, s->pAccount );
+						l_accounts_needing_parents = g_list_delete_link( l_accounts_needing_parents, elem );
+						progress_made = TRUE;
+					}
+				}
+			}
+
+			/* Any accounts left over must be parented by the root account */
+			for( elem = l_accounts_needing_parents; elem != NULL; elem = g_list_next( elem ) ) {
+				account_parent_guid_struct* s = (account_parent_guid_struct*)elem->data;
+                Account* root;
+                root = gnc_book_get_root_account( pBook );
+                if( root == NULL ) {
+                    root = gnc_account_create_root( pBook );
+                }
+                gnc_account_append_child( root, pAccount ); 
+			}
+		}
+    }
+}
+
+/* ================================================================= */
+static void
+create_account_tables( GncGdaBackend* be )
+{
+    gnc_gda_create_table_if_needed( be, TABLE_NAME, col_table );
+}
+
+/* ================================================================= */
+void
+gnc_gda_save_account( GncGdaBackend* be, QofInstance* inst )
+{
+    Account* pAcc = GNC_ACCOUNT(inst);
+    const GUID* guid;
+
+    // If there is no commodity yet, this might be because a new account name has been entered directly
+    // into the register and an account window will be opened.  The account info is not complete yet,
+    // but the name has been set, triggering this commit
+    if( xaccAccountGetCommodity( pAcc ) != NULL ) {
+        // Ensure the commodity is in the db
+        gnc_gda_save_commodity( be, xaccAccountGetCommodity( pAcc ) );
+
+        (void)gnc_gda_do_db_operation( be,
+                        (qof_instance_get_destroying(inst) ? OP_DB_DELETE : OP_DB_ADD_OR_UPDATE ),
+                        TABLE_NAME,
+                        GNC_ID_ACCOUNT, pAcc,
+                        col_table );
+
+        // Now, commit or delete any slots
+        guid = qof_instance_get_guid( inst );
+        if( !qof_instance_get_destroying(inst) ) {
+            gnc_gda_slots_save( be, guid, qof_instance_get_slots( inst ) );
+        } else {
+            gnc_gda_slots_delete( be, guid );
+        }
+    }
+}
+
+/* ================================================================= */
+void
+gnc_gda_init_account_handler( void )
+{
+    static GncGdaDataType_t be_data =
+    {
+        GNC_GDA_BACKEND_VERSION,
+        GNC_ID_ACCOUNT,
+        gnc_gda_save_account,				/* commit */
+        load_all_accounts,				/* initial_load */
+        create_account_tables		/* create_tables */
+    };
+
+    qof_object_register_backend( GNC_ID_ACCOUNT, GNC_GDA_BACKEND, &be_data );
+}
+/* ========================== END OF FILE ===================== */

Added: gnucash/branches/gda-dev2/src/backend/gda/gnc-account-gda.h
===================================================================
--- gnucash/branches/gda-dev2/src/backend/gda/gnc-account-gda.h	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/backend/gda/gnc-account-gda.h	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,38 @@
+/********************************************************************
+ * gnc-account-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-account-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_ACCOUNT_GDA_H_
+#define GNC_ACCOUNT_GDA_H_
+
+#include "qof.h"
+#include <gmodule.h>
+
+void gnc_gda_init_account_handler( void );
+void gnc_gda_save_account( GncGdaBackend* be, QofInstance* inst );
+
+#endif /* GNC_ACCOUNT_GDA_H_ */

Added: gnucash/branches/gda-dev2/src/backend/gda/gnc-backend-gda.c
===================================================================
--- gnucash/branches/gda-dev2/src/backend/gda/gnc-backend-gda.c	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/backend/gda/gnc-backend-gda.c	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,1067 @@
+/********************************************************************
+ * gnc-backend-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-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 <glib/gi18n.h>
+#include <glib/gstdio.h>
+
+#include <libgda/libgda.h>
+
+#include "qof.h"
+#include "qofquery-p.h"
+#include "qofquerycore-p.h"
+#include "TransLog.h"
+#include "gnc-engine.h"
+#include "SX-book.h"
+#include "Recurrence.h"
+
+#include "gnc-backend-util-gda.h"
+#include "gnc-gconf-utils.h"
+
+#include "gnc-account-gda.h"
+#include "gnc-book-gda.h"
+#include "gnc-budget-gda.h"
+#include "gnc-commodity-gda.h"
+#include "gnc-lots-gda.h"
+#include "gnc-price-gda.h"
+#include "gnc-pricedb.h"
+#include "gnc-recurrence-gda.h"
+#include "gnc-schedxaction-gda.h"
+#include "gnc-slots-gda.h"
+#include "gnc-transaction-gda.h"
+
+#include "gnc-backend-gda.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;
+
+#define SQLITE_PROVIDER_NAME "SQLite"
+
+/* ================================================================= */
+
+static void
+create_tables_cb( const gchar* type, gpointer data_p, gpointer be_data_p )
+{
+    GncGdaDataType_t* pData = data_p;
+    gda_backend* be_data = be_data_p;
+
+    g_return_if_fail( type != NULL && pData != NULL && be_data != NULL );
+    g_return_if_fail( pData->version == GNC_GDA_BACKEND_VERSION );
+
+    if( pData->create_tables != NULL ) {
+        (pData->create_tables)( be_data->be );
+    }
+}
+
+static void
+gnc_gda_session_begin(QofBackend *be_start, QofSession *session, 
+                   const gchar *book_id,
+                   gboolean ignore_lock,
+				   gboolean create_if_nonexistent)
+{
+    GncGdaBackend *be = (GncGdaBackend*) be_start;
+    GError* error = NULL;
+    gda_backend be_data;
+    gchar* book_info;
+    gchar* dsn;
+    gchar* username = "";
+    gchar* password = "";
+
+    ENTER (" ");
+
+    be->pClient = gda_client_new();
+	be->pConnection = NULL;
+
+    /* Split book_id into provider and connection string.  If there's no
+	provider, use "file" */
+    book_info = g_strdup( book_id );
+    dsn = strchr( book_info, ':' );
+	if( dsn != NULL ) {
+    	*dsn = '\0';
+    	dsn += 3;						// Skip '://'
+
+		// String will be one of:
+		//
+		//    sqlite:<filename>
+		//    mysql:<dbname>
+		//    pgsql:<dbname>
+		//    @<gda_connectionname>
+
+		if( dsn[0] == '@' ) {
+	    	dsn++;
+
+	    	be->pConnection = gda_client_open_connection( be->pClient,
+													dsn,
+													username, password,
+													0,
+													&error );
+		}
+	}
+
+	if( dsn == NULL || dsn[0] != '@' ) {
+		gchar* provider;
+		GList* provider_list;
+		GList* l;
+		gboolean provider_found;
+		
+		if( dsn != NULL ) {
+			provider = dsn;
+	    	dsn = strchr( dsn, ':' );
+			*dsn = '\0';
+			dsn++;
+		} else {
+			provider = SQLITE_PROVIDER_NAME;
+			dsn = book_info;
+		}
+
+		// Get a list of all of the providers.  If the requested provider is on the list, use it.
+		// Note that we need a case insensitive comparison here
+		provider_list = gda_config_get_provider_list();
+
+		provider_found = FALSE;
+		for( l = provider_list; l != NULL; l = l->next ) {
+			GdaProviderInfo* provider_info = (GdaProviderInfo*)l->data;
+
+			if( provider_info != NULL && g_ascii_strcasecmp( provider_info->id, provider ) == 0 ) {
+				provider_found = TRUE;
+				provider = provider_info->id;
+				break;
+			}
+		}
+
+		if( provider_found ) {
+			gchar* cnc;
+
+		    // If the provider is SQLite, split the file name into DB_DIR and
+			// DB_NAME
+			if( strcmp( provider, SQLITE_PROVIDER_NAME ) == 0 ) {
+				gchar* dirname;
+				gchar* basename;
+
+				dirname = g_path_get_dirname( dsn );
+				basename = g_path_get_basename( dsn );
+				
+				// Remove .db from the base name if it exists
+				if( g_str_has_suffix( basename, ".db" ) ) {
+					gchar* bn = g_strdup( basename );
+					gchar* suffix = g_strrstr( bn, ".db" );
+					*suffix = '\0';
+
+					cnc = g_strdup_printf( "DB_DIR=%s;DB_NAME=%s", dirname, bn );
+					g_free( bn );
+				} else {
+					cnc = g_strdup_printf( "DB_DIR=%s;DB_NAME=%s",
+											dirname, basename );
+				}
+				g_free( dirname );
+				g_free( basename );
+			} else {
+			    cnc = g_strdup( dsn );
+			}
+
+			be->pConnection = gda_client_open_connection_from_string( be->pClient,
+									provider, 
+									cnc,
+									username, password,
+									0,
+									&error );
+
+		    if( be->pConnection == NULL ) {
+				GdaServerOperation* op = gda_client_prepare_create_database(
+													be->pClient,
+													dsn,
+													provider );
+				if( op != NULL ) {
+					gboolean isOK;
+					isOK = gda_client_perform_create_database(
+													be->pClient,
+													op,
+													&error );
+					if( isOK ) {
+						be->pConnection = gda_client_open_connection_from_string(
+													be->pClient,
+													provider, 
+													cnc,
+													username, password,
+													0,
+													&error );
+					}
+				}
+			}
+		g_free( cnc );
+		}
+	}
+    g_free( book_info );
+
+    if( be->pConnection == NULL ) {
+        g_critical( "SQL error: %s\n", error->message );
+        qof_backend_set_error( be_start, ERR_BACKEND_NO_SUCH_DB );
+
+        LEAVE( " " );
+        return;
+    }
+
+    // Set up the dictionary
+    be->pDict = gda_dict_new();
+    gda_dict_set_connection( be->pDict, be->pConnection );
+    gda_dict_update_dbms_meta_data( be->pDict, 0, NULL, &error );
+    if( error != NULL ) {
+        g_critical( "gda_dict_update_dbms_meta_data() error: %s\n", error->message );
+    }
+
+    // Call all object backends to create any required tables
+    be_data.ok = FALSE;
+    be_data.be = be;
+    be_data.inst = NULL;
+    qof_object_foreach_backend( GNC_GDA_BACKEND, create_tables_cb, &be_data );
+
+    // Update the dictionary because new tables may exist
+    gda_dict_update_dbms_meta_data( be->pDict, 0, NULL, &error );
+    if( error != NULL ) {
+        g_critical( "gda_dict_update_dbms_meta_data() error: %s\n", error->message );
+    }
+
+    LEAVE (" ");
+}
+
+/* ================================================================= */
+
+static void
+gnc_gda_session_end(QofBackend *be_start)
+{
+    GncGdaBackend *be = (GncGdaBackend*)be_start;
+    ENTER (" ");
+
+    if( be->pDict != NULL ) {
+        g_object_unref( G_OBJECT(be->pDict) );
+        be->pDict = NULL;
+    }
+    if( be->pConnection != NULL && gda_connection_is_opened( be->pConnection ) ) {
+        gda_connection_close( be->pConnection );
+    }
+    be->pConnection = NULL;
+    if( be->pClient != NULL ) {
+        g_object_unref( G_OBJECT(be->pClient ) );
+        be->pClient = NULL;
+    }
+
+    LEAVE (" ");
+}
+
+static void
+gnc_gda_destroy_backend(QofBackend *be)
+{
+    g_free(be);
+}
+
+/* ================================================================= */
+
+static void
+initial_load_cb( const gchar* type, gpointer data_p, gpointer be_data_p )
+{
+    GncGdaDataType_t* pData = data_p;
+    gda_backend* be_data = be_data_p;
+
+    g_return_if_fail( type != NULL && pData != NULL && be_data != NULL );
+    g_return_if_fail( pData->version == GNC_GDA_BACKEND_VERSION );
+    g_return_if_fail( g_ascii_strcasecmp( type, GNC_ID_BOOK ) != 0 );
+
+    if( pData->initial_load != NULL ) {
+        (pData->initial_load)( be_data->be );
+    }
+}
+
+static void
+gnc_gda_load(QofBackend* be_start, QofBook *book)
+{
+    GncGdaBackend *be = (GncGdaBackend*)be_start;
+    gda_backend be_data;
+    GncGdaDataType_t* pData;
+
+    ENTER( "be=%p, book=%p", be, book );
+
+    g_assert( be->primary_book == NULL );
+    be->primary_book = book;
+
+    /* Load any initial stuff */
+    be->loading = TRUE;
+    
+    /* Some of this needs to happen in a certain order */
+    pData = qof_object_lookup_backend( GNC_ID_BOOK, GNC_GDA_BACKEND );
+    if( pData->initial_load != NULL ) {
+        (pData->initial_load)( be );
+    }
+
+    be_data.ok = FALSE;
+    be_data.be = be;
+    be_data.inst = NULL;
+    qof_object_foreach_backend( GNC_GDA_BACKEND, initial_load_cb, &be_data );
+
+    be->loading = FALSE;
+
+	// Mark the book as clean
+	qof_instance_mark_clean( QOF_INSTANCE(book) );
+
+    LEAVE( "" );
+}
+
+/* ================================================================= */
+
+static gint
+compare_namespaces(gconstpointer a, gconstpointer b)
+{
+  const gchar *sa = (const gchar *) a;
+  const gchar *sb = (const gchar *) b;
+  return(safe_strcmp(sa, sb));
+}
+
+static gint
+compare_commodity_ids(gconstpointer a, gconstpointer b)
+{
+  const gnc_commodity *ca = (const gnc_commodity *) a;
+  const gnc_commodity *cb = (const gnc_commodity *) b;
+  return(safe_strcmp(gnc_commodity_get_mnemonic(ca),
+                     gnc_commodity_get_mnemonic(cb)));
+}
+
+static void
+save_commodities( GncGdaBackend* be, QofBook* book )
+{
+    gnc_commodity_table* tbl;
+    GList* namespaces;
+    GList* lp;
+
+    tbl = gnc_book_get_commodity_table( book );
+    namespaces = gnc_commodity_table_get_namespaces( tbl );
+    if( namespaces != NULL ) {
+        namespaces = g_list_sort( namespaces, compare_namespaces );
+    }
+    for( lp = namespaces; lp != NULL; lp = lp->next ) {
+        GList* comms;
+        GList* lp2;
+        
+        comms = gnc_commodity_table_get_commodities( tbl, lp->data );
+        comms = g_list_sort( comms, compare_commodity_ids );
+
+        for( lp2 = comms; lp2 != NULL; lp2 = lp2->next ) {
+	    gnc_gda_save_commodity( be, GNC_COMMODITY(lp2->data) );
+        }
+    }
+}
+
+static void
+save_account_tree( GncGdaBackend* be, Account* root )
+{
+    GList* descendants;
+    GList* node;
+
+    descendants = gnc_account_get_descendants( root );
+    for( node = descendants; node != NULL; node = g_list_next(node) ) {
+        gnc_gda_save_account( be, QOF_INSTANCE(GNC_ACCOUNT(node->data)) );
+    }
+    g_list_free( descendants );
+}
+
+static void
+save_accounts( GncGdaBackend* be, QofBook* book )
+{
+    save_account_tree( be, gnc_book_get_root_account( book ) );
+}
+
+static void
+write_budget( QofInstance* ent, gpointer data )
+{
+    GncGdaBackend* be = (GncGdaBackend*)data;
+
+    gnc_gda_save_budget( be, ent );
+}
+
+static void
+save_budgets( GncGdaBackend* be, QofBook* book )
+{
+    qof_collection_foreach( qof_book_get_collection( book, GNC_ID_BUDGET ),
+                            write_budget, be );
+}
+
+static gboolean
+save_price( GNCPrice* p, gpointer data )
+{
+    GncGdaBackend* be = (GncGdaBackend*)data;
+
+    gnc_gda_save_price( be, QOF_INSTANCE(p) );
+
+    return TRUE;
+}
+
+static void
+save_prices( GncGdaBackend* be, QofBook* book )
+{
+    GNCPriceDB* priceDB = gnc_book_get_pricedb( book );
+
+    gnc_pricedb_foreach_price( priceDB, save_price, be, TRUE );
+}
+
+static int
+save_tx( Transaction* tx, gpointer data )
+{
+    GncGdaBackend* be = (GncGdaBackend*)data;
+
+    gnc_gda_save_transaction( be, QOF_INSTANCE(tx) );
+
+    return 0;
+}
+
+static void
+save_transactions( GncGdaBackend* be, QofBook* book )
+{
+    xaccAccountTreeForEachTransaction( gnc_book_get_root_account( book ),
+                                       save_tx,
+                                       (gpointer)be );
+}
+
+static void
+save_template_transactions( GncGdaBackend* be, QofBook* book )
+{
+    Account* ra;
+
+    ra = gnc_book_get_template_root( book );
+    if( gnc_account_n_descendants( ra ) > 0 ) {
+        save_account_tree( be, ra );
+        xaccAccountTreeForEachTransaction( ra, save_tx, (gpointer)be );
+    }
+}
+
+static void
+save_schedXactions( GncGdaBackend* be, QofBook* book )
+{
+    GList* schedXactions;
+    SchedXaction* tmpSX;
+
+    schedXactions = gnc_book_get_schedxactions( book )->sx_list;
+
+    for( ; schedXactions != NULL; schedXactions = schedXactions->next ) {
+        tmpSX = schedXactions->data;
+	gnc_gda_save_schedxaction( be, QOF_INSTANCE( tmpSX ) );
+    }
+}
+
+static void
+gnc_gda_sync_all( QofBackend* be, QofBook *book )
+{
+    GncGdaBackend *fbe = (GncGdaBackend *) be;
+    GdaDataModel* tables;
+    GError* error = NULL;
+    gint row;
+    gint numTables;
+    gda_backend be_data;
+
+    ENTER ("book=%p, primary=%p", book, fbe->primary_book);
+
+    /* Destroy the current contents of the database */
+    tables = gda_connection_get_schema( fbe->pConnection,
+                                        GDA_CONNECTION_SCHEMA_TABLES,
+                                        NULL,
+                                        &error );
+    if( error != NULL ) {
+        g_critical( "SQL error: %s\n", error->message );
+    }
+    numTables = gda_data_model_get_n_rows( tables );
+    for( row = 0; row < numTables; row++ ) {
+        const GValue* row_value;
+        const gchar* table_name;
+
+        row_value = gda_data_model_get_value_at( tables, 0, row );
+        table_name = g_value_get_string( row_value );
+        error = NULL;
+        if( !gda_drop_table( fbe->pConnection, table_name, &error ) ) {
+            g_critical( "Unable to drop table %s\n", table_name );
+            if( error != NULL ) {
+                g_critical( "SQL error: %s\n", error->message );
+            }
+        }
+    }
+
+    // Update the dictionary because new tables may exist
+    gda_dict_update_dbms_meta_data( fbe->pDict, 0, NULL, &error );
+    if( error != NULL ) {
+        g_critical( "gda_dict_update_dbms_meta_data() error: %s\n", error->message );
+    }
+
+    /* Create new tables */
+    be_data.ok = FALSE;
+    be_data.be = fbe;
+    be_data.inst = NULL;
+    qof_object_foreach_backend( GNC_GDA_BACKEND, create_tables_cb, &be_data );
+
+    // Update the dictionary because new tables may exist
+    gda_dict_update_dbms_meta_data( fbe->pDict, 0, NULL, &error );
+    if( error != NULL ) {
+        g_critical( "gda_dict_update_dbms_meta_data() error: %s\n", error->message );
+    }
+
+    /* Save all contents */
+    //save_commodities( fbe, book );
+    save_accounts( fbe, book );
+    save_prices( fbe, book );
+    save_transactions( fbe, book );
+    save_template_transactions( fbe, book );
+    save_schedXactions( fbe, book );
+    save_budgets( fbe, book );
+
+    LEAVE ("book=%p", book);
+}
+
+/* ================================================================= */
+/* Routines to deal with the creation of multiple books. */
+
+
+static void
+gnc_gda_begin_edit (QofBackend *be, QofInstance *inst)
+{
+}
+
+static void
+gnc_gda_rollback_edit (QofBackend *be, QofInstance *inst)
+{
+}
+
+static void
+commit_cb( const gchar* type, gpointer data_p, gpointer be_data_p )
+{
+    GncGdaDataType_t* pData = data_p;
+    gda_backend* be_data = be_data_p;
+
+    g_return_if_fail( type != NULL && pData != NULL && be_data != NULL );
+    g_return_if_fail( pData->version == GNC_GDA_BACKEND_VERSION );
+
+    /* If this has already been handled, or is not the correct handler, return */
+    g_return_if_fail( strcmp( pData->type_name, be_data->inst->e_type ) == 0 );
+    g_return_if_fail( !be_data->ok );
+
+    if( pData->commit != NULL ) {
+        (pData->commit)( be_data->be, be_data->inst );
+        be_data->ok = TRUE;
+    }
+}
+
+/* Commit_edit handler - find the correct backend handler for this object
+ * type and call its commit handler
+ */
+static void
+gnc_gda_commit_edit (QofBackend *be_start, QofInstance *inst)
+{
+    GncGdaBackend *be = (GncGdaBackend*)be_start;
+    gda_backend be_data;
+
+    ENTER( " " );
+
+    /* During initial load where objects are being created, don't commit
+    anything */
+
+    if( be->loading ) {
+		LEAVE( "" );
+	    return;
+	}
+
+    g_debug( "gda_commit_edit(): %s dirty = %d, do_free=%d\n",
+             (inst->e_type ? inst->e_type : "(null)"),
+             qof_instance_get_dirty_flag(inst), qof_instance_get_destroying(inst) );
+
+    if( !qof_instance_get_dirty_flag(inst) && !qof_instance_get_destroying(inst) && GNC_IS_TRANS(inst) ) {
+        gnc_gda_transaction_commit_splits( be, GNC_TRANS(inst) );
+    }
+
+    if( !qof_instance_get_dirty_flag(inst) && !qof_instance_get_destroying(inst) ) return;
+
+    be_data.ok = FALSE;
+    be_data.be = be;
+    be_data.inst = inst;
+    qof_object_foreach_backend( GNC_GDA_BACKEND, commit_cb, &be_data );
+
+    if( !be_data.ok ) {
+        g_critical( "gnc_gda_commit_edit(): Unknown object type %s\n",
+                inst->e_type );
+        return;
+    }
+
+    qof_instance_mark_clean(inst);
+    qof_book_mark_saved( be->primary_book );
+
+	LEAVE( "" );
+}
+/* ---------------------------------------------------------------------- */
+
+/* Query processing */
+
+static const gchar*
+convert_search_obj( QofIdType objType )
+{
+    return (gchar*)objType;
+}
+
+static void
+handle_and_term( QofQueryTerm* pTerm, gchar* sql )
+{
+    GSList* pParamPath = qof_query_term_get_param_path( pTerm );
+    QofQueryPredData* pPredData = qof_query_term_get_pred_data( pTerm );
+    gboolean isInverted = qof_query_term_is_inverted( pTerm );
+    GSList* name;
+    gchar val[GUID_ENCODING_LENGTH+1];
+
+    strcat( sql, "(" );
+    if( isInverted ) {
+        strcat( sql, "!" );
+    }
+
+    for( name = pParamPath; name != NULL; name = name->next ) {
+        if( name != pParamPath ) strcat( sql, "." );
+        strcat( sql, name->data );
+    }
+
+    if( pPredData->how == QOF_COMPARE_LT ) {
+        strcat( sql, "<" );
+    } else if( pPredData->how == QOF_COMPARE_LTE ) {
+        strcat( sql, "<=" );
+    } else if( pPredData->how == QOF_COMPARE_EQUAL ) {
+        strcat( sql, "=" );
+    } else if( pPredData->how == QOF_COMPARE_GT ) {
+        strcat( sql, ">" );
+    } else if( pPredData->how == QOF_COMPARE_GTE ) {
+        strcat( sql, ">=" );
+    } else if( pPredData->how == QOF_COMPARE_NEQ ) {
+        strcat( sql, "~=" );
+    } else {
+        strcat( sql, "??" );
+    }
+
+    if( strcmp( pPredData->type_name, "string" ) == 0 ) {
+        query_string_t pData = (query_string_t)pPredData;
+        strcat( sql, "'" );
+        strcat( sql, pData->matchstring );
+        strcat( sql, "'" );
+    } else if( strcmp( pPredData->type_name, "date" ) == 0 ) {
+        query_date_t pData = (query_date_t)pPredData;
+
+        (void)gnc_timespec_to_iso8601_buff( pData->date, val );
+        strcat( sql, "'" );
+        strncat( sql, val, 4+1+2+1+2 );
+        strcat( sql, "'" );
+    } else if( strcmp( pPredData->type_name, "numeric" ) == 0 ) {
+        query_numeric_t pData = (query_numeric_t)pPredData;
+    
+        strcat( sql, "numeric" );
+    } else if( strcmp( pPredData->type_name, "guid" ) == 0 ) {
+        query_guid_t pData = (query_guid_t)pPredData;
+        (void)guid_to_string_buff( pData->guids->data, val );
+        strcat( sql, "'" );
+        strcat( sql, val );
+        strcat( sql, "'" );
+    } else if( strcmp( pPredData->type_name, "gint32" ) == 0 ) {
+        query_int32_t pData = (query_int32_t)pPredData;
+
+        sprintf( val, "%d", pData->val );
+        strcat( sql, val );
+    } else if( strcmp( pPredData->type_name, "gint64" ) == 0 ) {
+        query_int64_t pData = (query_int64_t)pPredData;
+    
+        sprintf( val, "%" G_GINT64_FORMAT, pData->val );
+        strcat( sql, val );
+    } else if( strcmp( pPredData->type_name, "double" ) == 0 ) {
+        query_double_t pData = (query_double_t)pPredData;
+
+        sprintf( val, "%f", pData->val );
+        strcat( sql, val );
+    } else if( strcmp( pPredData->type_name, "boolean" ) == 0 ) {
+        query_boolean_t pData = (query_boolean_t)pPredData;
+
+        sprintf( val, "%d", pData->val );
+        strcat( sql, val );
+    } else {
+        g_assert( FALSE );
+    }
+
+    strcat( sql, ")" );
+}
+
+static void
+compile_query_cb( const gchar* type, gpointer data_p, gpointer be_data_p )
+{
+    GncGdaDataType_t* pData = data_p;
+    gda_backend* be_data = be_data_p;
+
+    g_return_if_fail( type != NULL && pData != NULL && be_data != NULL );
+    g_return_if_fail( pData->version == GNC_GDA_BACKEND_VERSION );
+
+    g_return_if_fail( strcmp( type, be_data->pQueryInfo->searchObj ) == 0 );
+    g_return_if_fail( !be_data->ok );
+
+    if( pData->compile_query != NULL ) {
+        be_data->pQueryInfo->pCompiledQuery = (pData->compile_query)(
+                                                            be_data->be,
+                                                            be_data->pQuery );
+        be_data->ok = TRUE;
+    }
+}
+
+static gpointer
+gnc_gda_compile_query(QofBackend* pBEnd, QofQuery* pQuery)
+{
+    GncGdaBackend *be = (GncGdaBackend*)pBEnd;
+    GList* pBookList;
+    QofIdType searchObj;
+    gchar sql[1000];
+    gda_backend be_data;
+    gnc_gda_query_info* pQueryInfo;
+
+	ENTER( " " );
+
+    searchObj = qof_query_get_search_for( pQuery );
+
+    pQueryInfo = g_malloc( sizeof( gnc_gda_query_info ) );
+
+    // Try various objects first
+    be_data.ok = FALSE;
+    be_data.be = be;
+    be_data.pQuery = pQuery;
+    pQueryInfo->searchObj = searchObj;
+    be_data.pQueryInfo = pQueryInfo;
+
+    qof_object_foreach_backend( GNC_GDA_BACKEND, compile_query_cb, &be_data );
+    if( be_data.ok ) {
+		LEAVE( "" );
+        return be_data.pQueryInfo;
+    }
+
+    pBookList = qof_query_get_books( pQuery );
+
+    /* Convert search object type to table name */
+    sprintf( sql, "SELECT * from %s", convert_search_obj( searchObj ) );
+    if( !qof_query_has_terms( pQuery ) ) {
+        strcat( sql, ";" );
+    } else {
+        GList* pOrTerms = qof_query_get_terms( pQuery );
+        GList* orTerm;
+
+        strcat( sql, " WHERE " );
+
+        for( orTerm = pOrTerms; orTerm != NULL; orTerm = orTerm->next ) {
+            GList* pAndTerms = (GList*)orTerm->data;
+            GList* andTerm;
+
+            if( orTerm != pOrTerms ) strcat( sql, " OR " );
+            strcat( sql, "(" );
+            for( andTerm = pAndTerms; andTerm != NULL; andTerm = andTerm->next ) {
+                if( andTerm != pAndTerms ) strcat( sql, " AND " );
+                handle_and_term( (QofQueryTerm*)andTerm->data, sql );
+            }
+            strcat( sql, ")" );
+        }
+    }
+
+    g_debug( "Compiled: %s\n", sql );
+    pQueryInfo->pCompiledQuery =  g_strdup( sql );
+
+	LEAVE( "" );
+
+    return pQueryInfo;
+}
+
+static void
+free_query_cb( const gchar* type, gpointer data_p, gpointer be_data_p )
+{
+    GncGdaDataType_t* pData = data_p;
+    gda_backend* be_data = be_data_p;
+
+    g_return_if_fail( type != NULL && pData != NULL && be_data != NULL );
+    g_return_if_fail( pData->version == GNC_GDA_BACKEND_VERSION );
+    g_return_if_fail( strcmp( type, be_data->pQueryInfo->searchObj ) == 0 );
+
+    g_return_if_fail( !be_data->ok );
+
+    if( pData->free_query != NULL ) {
+        (pData->free_query)( be_data->be, be_data->pCompiledQuery );
+        be_data->ok = TRUE;
+    }
+}
+
+static void
+gnc_gda_free_query(QofBackend* pBEnd, gpointer pQuery)
+{
+    GncGdaBackend *be = (GncGdaBackend*)pBEnd;
+    gnc_gda_query_info* pQueryInfo = (gnc_gda_query_info*)pQuery;
+    gda_backend be_data;
+
+	ENTER( " " );
+
+    // Try various objects first
+    be_data.ok = FALSE;
+    be_data.be = be;
+    be_data.pCompiledQuery = pQuery;
+    be_data.pQueryInfo = pQueryInfo;
+
+    qof_object_foreach_backend( GNC_GDA_BACKEND, free_query_cb, &be_data );
+    if( be_data.ok ) {
+		LEAVE( "" );
+        return;
+    }
+
+    g_debug( "gda_free_query(): %s\n", (gchar*)pQueryInfo->pCompiledQuery );
+    g_free( pQueryInfo->pCompiledQuery );
+    g_free( pQueryInfo );
+
+	LEAVE( "" );
+}
+
+static void
+run_query_cb( const gchar* type, gpointer data_p, gpointer be_data_p )
+{
+    GncGdaDataType_t* pData = data_p;
+    gda_backend* be_data = be_data_p;
+
+    g_return_if_fail( type != NULL && pData != NULL && be_data != NULL );
+    g_return_if_fail( pData->version == GNC_GDA_BACKEND_VERSION );
+    g_return_if_fail( strcmp( type, be_data->pQueryInfo->searchObj ) == 0 );
+
+    g_return_if_fail( !be_data->ok );
+
+    if( pData->run_query != NULL ) {
+        (pData->run_query)( be_data->be, be_data->pCompiledQuery );
+        be_data->ok = TRUE;
+    }
+}
+
+static void
+gnc_gda_run_query(QofBackend* pBEnd, gpointer pQuery)
+{
+    GncGdaBackend *be = (GncGdaBackend*)pBEnd;
+    gnc_gda_query_info* pQueryInfo = (gnc_gda_query_info*)pQuery;
+    gda_backend be_data;
+
+    g_return_if_fail( !be->in_query );
+
+	ENTER( " " );
+
+    be->loading = TRUE;
+    be->in_query = TRUE;
+
+    qof_event_suspend();
+
+    // Try various objects first
+    be_data.ok = FALSE;
+    be_data.be = be;
+    be_data.pCompiledQuery = pQueryInfo->pCompiledQuery;
+    be_data.pQueryInfo = pQueryInfo;
+
+    qof_object_foreach_backend( GNC_GDA_BACKEND, run_query_cb, &be_data );
+    be->loading = FALSE;
+    be->in_query = FALSE;
+    qof_event_resume();
+//    if( be_data.ok ) {
+//		LEAVE( "" );
+//       	return;
+//    }
+
+	// Mark the book as clean
+	qof_instance_mark_clean( QOF_INSTANCE(be->primary_book) );
+
+//    g_debug( "gda_run_query(): %s\n", (gchar*)pQueryInfo->pCompiledQuery );
+
+	LEAVE( "" );
+}
+
+/* ================================================================= */
+static void
+gnc_gda_init_object_handlers( void )
+{
+    gnc_gda_init_book_handler();
+    gnc_gda_init_commodity_handler();
+    gnc_gda_init_account_handler();
+    gnc_gda_init_budget_handler();
+    gnc_gda_init_price_handler();
+    gnc_gda_init_transaction_handler();
+    gnc_gda_init_slots_handler();
+	gnc_gda_init_recurrence_handler();
+    gnc_gda_init_schedxaction_handler();
+    gnc_gda_init_lot_handler();
+}
+
+/* ================================================================= */
+
+static QofBackend*
+gnc_gda_backend_new(void)
+{
+    GncGdaBackend *gnc_be;
+    QofBackend *be;
+    static gboolean initialized = FALSE;
+
+    gnc_be = g_new0(GncGdaBackend, 1);
+    be = (QofBackend*) gnc_be;
+    qof_backend_init(be);
+
+    be->session_begin = gnc_gda_session_begin;
+    be->session_end = gnc_gda_session_end;
+    be->destroy_backend = gnc_gda_destroy_backend;
+
+    be->load = gnc_gda_load;
+    be->save_may_clobber_data = NULL;
+
+    /* The gda backend treats accounting periods transactionally. */
+    be->begin = gnc_gda_begin_edit;
+    be->commit = gnc_gda_commit_edit;
+    be->rollback = gnc_gda_rollback_edit;
+
+    /* The gda backend uses queries to load data ... */
+    be->compile_query = gnc_gda_compile_query;
+    be->free_query = gnc_gda_free_query;
+    be->run_query = gnc_gda_run_query;
+
+    be->counter = NULL;
+
+    /* The gda backend will not be multi-user (for now)... */
+    be->events_pending = NULL;
+    be->process_events = NULL;
+
+    be->sync = gnc_gda_sync_all;
+    be->load_config = NULL;
+    be->get_config = NULL;
+
+    be->export = NULL;
+
+    gnc_be->primary_book = NULL;
+
+    if( !initialized ) {
+        gda_init( "gnucash", "2.0", 0, NULL );
+        gnc_gda_init_object_handlers();
+		gnc_gda_register_standard_col_type_handlers();
+        initialized = TRUE;
+    }
+
+    return be;
+}
+
+static void
+gnc_gda_provider_free (QofBackendProvider *prov)
+{
+    prov->provider_name = NULL;
+    prov->access_method = NULL;
+    g_free (prov);
+}
+
+/*
+ * Checks to see whether the file is an sqlite file or not
+ *
+ */
+static gboolean
+gnc_gda_check_sqlite_file(const gchar *path)
+{
+	FILE* f;
+	gchar buf[50];
+
+	// BAD if the path is null
+	if( path == NULL ) {
+		return FALSE;
+	}
+
+	if( g_str_has_suffix( path, ".db" ) ) {
+		f = g_fopen( path, "r" );
+
+		// OK if the file doesn't exist - new file
+		if( f == NULL ) {
+			return TRUE;
+		}
+
+		// OK if file has the correct header
+		fread( buf, sizeof(buf), 1, f );
+		fclose( f );
+		if( g_str_has_prefix( buf, "SQLite format" ) ) {
+			return TRUE;
+		}
+	} else {
+		f = g_fopen( path, "r" );
+
+		// BAD if the file exists - not ours
+		if( f != NULL ) {
+			fclose( f );
+			return FALSE;
+		}
+
+		// OK - new file
+		return TRUE;
+	}
+
+	// Otherwise, BAD
+	return FALSE;
+}
+
+G_MODULE_EXPORT void
+qof_backend_module_init(void)
+{
+    QofBackendProvider *prov;
+
+    prov = g_new0 (QofBackendProvider, 1);
+    prov->provider_name = "GnuCash LibGDA Backend";
+    prov->access_method = "gda";
+    prov->partial_book_supported = FALSE;
+    prov->backend_new = gnc_gda_backend_new;
+    prov->provider_free = gnc_gda_provider_free;
+    prov->check_data_type = NULL;
+    qof_backend_register_provider (prov);
+
+    prov = g_new0 (QofBackendProvider, 1);
+    prov->provider_name = "GnuCash LibGDA Backend";
+    prov->access_method = "file";
+    prov->partial_book_supported = FALSE;
+    prov->backend_new = gnc_gda_backend_new;
+    prov->provider_free = gnc_gda_provider_free;
+    prov->check_data_type = gnc_gda_check_sqlite_file;
+    qof_backend_register_provider (prov);
+}
+
+/* ========================== END OF FILE ===================== */

Added: gnucash/branches/gda-dev2/src/backend/gda/gnc-backend-gda.h
===================================================================
--- gnucash/branches/gda-dev2/src/backend/gda/gnc-backend-gda.h	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/backend/gda/gnc-backend-gda.h	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,81 @@
+/********************************************************************
+ * 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>
+
+#if 0
+#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;
+#endif
+
+// This is now a static inside the module
+//QofBackend * libgncmod_backend_gda_LTX_gnc_backend_new(void);
+
+G_MODULE_EXPORT void
+qof_backend_module_init(void);
+
+#endif /* GNC_BACKEND_GDA_H_ */

Added: gnucash/branches/gda-dev2/src/backend/gda/gnc-backend-util-gda.c
===================================================================
--- gnucash/branches/gda-dev2/src/backend/gda/gnc-backend-util-gda.c	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/backend/gda/gnc-backend-util-gda.c	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,1719 @@
+/********************************************************************
+ * 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 contains utility routines to support 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-commodity.h"
+
+#include "gnc-backend-util-gda.h"
+#include "gnc-gconf-utils.h"
+
+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;
+
+#if 0
+typedef void (*GNC_GDA_LOAD_FN)( GncGdaBackend* be, 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, gboolean pkey );
+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;
+#endif
+
+/* ================================================================= */
+void
+gnc_gda_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;
+}
+/* ----------------------------------------------------------------- */
+QofAccessFunc
+gnc_gda_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( const GncGdaBackend* be, 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 );
+    }
+    if( table->gobj_param_name != NULL ) {
+		g_object_set( pObject, table->gobj_param_name, s, NULL );
+    } else {
+		(*setter)( pObject, (const gpointer)s );
+    }
+}
+
+static void
+get_gvalue_string( const GncGdaBackend* be, QofIdTypeConst obj_name,
+                const gpointer pObject, const col_cvt_t* table_row, GValue* value )
+{
+    QofAccessFunc getter;
+    gchar* s;
+
+    memset( value, 0, sizeof( GValue ) );
+	if( table_row->gobj_param_name != NULL ) {
+		g_object_get( pObject, table_row->gobj_param_name, &s, NULL );
+	} else {
+    	getter = gnc_gda_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( const GncGdaBackend* be, QofIdTypeConst obj_name,
+                const gpointer pObject, const col_cvt_t* table_row, GdaQuery* query )
+{
+    GValue value;
+
+    get_gvalue_string( be, obj_name, pObject, table_row, &value );
+    gnc_gda_add_field_to_query( query, table_row->col_name, &value );
+}
+
+static GdaQueryCondition*
+get_gvalue_string_cond( const GncGdaBackend* be, QofIdTypeConst obj_name,
+                const 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, gboolean pkey )
+{
+    const gchar* dbms_type;
+
+    dbms_type = gda_server_provider_get_default_dbms_type( server,
+                                                        cnn, G_TYPE_STRING );
+    gnc_gda_add_table_column( server, cnn, array_data, table_row->col_name,
+                    dbms_type, table_row->size, table_row->flags | pkey ? COL_PKEY : 0 );
+}
+
+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( const GncGdaBackend* be, 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 );
+    }
+    if( table->gobj_param_name != NULL ) {
+		g_object_set( pObject, table->gobj_param_name, int_value, NULL );
+    } else {
+    	(*setter)( pObject, GINT_TO_POINTER(int_value) );
+    }
+}
+
+static void
+get_gvalue_int( const GncGdaBackend* be, QofIdTypeConst obj_name,
+                const gpointer pObject, const col_cvt_t* table_row, GValue* value )
+{
+    gint int_value;
+    QofAccessFunc getter;
+
+    memset( value, 0, sizeof( GValue ) );
+
+    getter = gnc_gda_get_getter( obj_name, table_row );
+    int_value = GPOINTER_TO_INT((*getter)( pObject, NULL ));
+    g_value_init( value, G_TYPE_INT );
+    g_value_set_int( value, int_value );
+}
+
+static void
+get_gvalue_int_for_query( const GncGdaBackend* be, QofIdTypeConst obj_name,
+                const gpointer pObject, const col_cvt_t* table_row, GdaQuery* query )
+{
+    GValue value;
+
+    get_gvalue_int( be, obj_name, pObject, table_row, &value );
+    gnc_gda_add_field_to_query( query, table_row->col_name, &value );
+}
+
+static GdaQueryCondition*
+get_gvalue_int_cond( const GncGdaBackend* be, QofIdTypeConst obj_name,
+                const 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, gboolean pkey )
+{
+    const gchar* dbms_type;
+
+    dbms_type = gda_server_provider_get_default_dbms_type( server,
+                                                        cnn, G_TYPE_INT );
+    gnc_gda_add_table_column( server, cnn, array_data, table_row->col_name,
+                    dbms_type, table_row->size, table_row->flags | pkey ? COL_PKEY : 0 );
+}
+
+static col_type_handler_t int_handler =
+        { load_int, create_int_col,
+            get_gvalue_int_for_query, get_gvalue_int_cond };
+/* ----------------------------------------------------------------- */
+
+static void
+load_boolean( const GncGdaBackend* be, 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 );
+    }
+    if( table->gobj_param_name != NULL ) {
+		g_object_set( pObject, table->gobj_param_name, int_value, NULL );
+    } else {
+    	(*setter)( pObject, GINT_TO_POINTER(int_value) );
+    }
+}
+
+static void
+get_gvalue_boolean( const GncGdaBackend* be, QofIdTypeConst obj_name,
+                const gpointer pObject, const col_cvt_t* table_row, GValue* value )
+{
+    gint int_value;
+    QofAccessFunc getter;
+
+    memset( value, 0, sizeof( GValue ) );
+
+    getter = gnc_gda_get_getter( obj_name, table_row );
+    int_value = GPOINTER_TO_INT((*getter)( pObject, NULL ));
+    g_value_init( value, G_TYPE_INT );
+    g_value_set_int( value, int_value );
+}
+
+static void
+get_gvalue_boolean_for_query( const GncGdaBackend* be, QofIdTypeConst obj_name,
+                const gpointer pObject, const col_cvt_t* table_row, GdaQuery* query )
+{
+    GValue value;
+
+    get_gvalue_int( be, obj_name, pObject, table_row, &value );
+    gnc_gda_add_field_to_query( query, table_row->col_name, &value );
+}
+
+static GdaQueryCondition*
+get_gvalue_boolean_cond( const GncGdaBackend* be, QofIdTypeConst obj_name,
+                const 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_boolean_col( GdaServerProvider* server, GdaConnection* cnn,
+            xmlNodePtr array_data, const col_cvt_t* table_row, gboolean pkey )
+{
+    const gchar* dbms_type;
+
+    dbms_type = gda_server_provider_get_default_dbms_type( server,
+                                                        cnn, G_TYPE_INT );
+    gnc_gda_add_table_column( server, cnn, array_data, table_row->col_name,
+                    dbms_type, table_row->size, table_row->flags | pkey ? COL_PKEY : 0 );
+}
+
+static col_type_handler_t boolean_handler =
+        { load_boolean, create_boolean_col,
+            get_gvalue_boolean_for_query, get_gvalue_boolean_cond };
+/* ----------------------------------------------------------------- */
+
+static void
+load_int64( const GncGdaBackend* be, 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( const GncGdaBackend* be, QofIdTypeConst obj_name, const gpointer pObject,
+                const col_cvt_t* table_row, GValue* value )
+{
+    gint64* pInt64;
+    gint64 i64_value;
+    QofAccessFunc getter;
+
+    memset( value, 0, sizeof( GValue ) );
+    getter = gnc_gda_get_getter( obj_name, table_row );
+    pInt64 = (*getter)( pObject, NULL );
+    if( pInt64 != NULL ) {
+        i64_value = *pInt64;
+        g_value_init( value, G_TYPE_INT64 );
+        g_value_set_int64( value, i64_value );
+    }
+}
+
+static void
+get_gvalue_int64_for_query( const GncGdaBackend* be, QofIdTypeConst obj_name,
+                const gpointer pObject, const col_cvt_t* table_row, GdaQuery* query )
+{
+    GValue value;
+
+    get_gvalue_int64( be, obj_name, pObject, table_row, &value );
+    gnc_gda_add_field_to_query( query, table_row->col_name, &value );
+}
+
+static GdaQueryCondition*
+get_gvalue_int64_cond( const GncGdaBackend* be, QofIdTypeConst obj_name,
+                const 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, gboolean pkey )
+{
+    const gchar* dbms_type;
+
+    dbms_type = gda_server_provider_get_default_dbms_type( server,
+                                                        cnn, G_TYPE_INT64 );
+    gnc_gda_add_table_column( server, cnn, array_data, table_row->col_name,
+                    dbms_type, table_row->size, table_row->flags | pkey ? COL_PKEY : 0 );
+}
+
+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( const GncGdaBackend* be, 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( const GncGdaBackend* be, QofIdTypeConst obj_name, const gpointer pObject,
+                const col_cvt_t* table_row, GValue* value )
+{
+    QofAccessFunc getter;
+    gdouble* pDouble;
+    gdouble d_value;
+
+    memset( value, 0, sizeof( GValue ) );
+
+    getter = gnc_gda_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( const GncGdaBackend* be, QofIdTypeConst obj_name,
+                const gpointer pObject, const col_cvt_t* table_row, GdaQuery* query )
+{
+    GValue value;
+
+    get_gvalue_double( be, obj_name, pObject, table_row, &value );
+    gnc_gda_add_field_to_query( query, table_row->col_name, &value );
+}
+
+static GdaQueryCondition*
+get_gvalue_double_cond( const GncGdaBackend* be, QofIdTypeConst obj_name,
+                const 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, gboolean pkey )
+{
+    const gchar* dbms_type;
+
+    dbms_type = gda_server_provider_get_default_dbms_type( server,
+                                                        cnn, G_TYPE_INT64 );
+    gnc_gda_add_table_column( server, cnn, array_data, table_row->col_name,
+                    dbms_type, table_row->size, table_row->flags | pkey ? COL_PKEY : 0 );
+}
+
+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( const GncGdaBackend* be, 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;
+    }
+    if( table->gobj_param_name != NULL ) {
+		g_object_set( pObject, table->gobj_param_name, pGuid, NULL );
+    } else {
+		(*setter)( pObject, (const gpointer)pGuid );
+    }
+}
+
+static void
+get_gvalue_guid( const GncGdaBackend* be, QofIdTypeConst obj_name, const 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 ) );
+
+	if( table_row->gobj_param_name != NULL ) {
+		g_object_get( pObject, table_row->gobj_param_name, &guid, NULL );
+	} else {
+    	getter = gnc_gda_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( const GncGdaBackend* be, QofIdTypeConst obj_name,
+                const gpointer pObject, const col_cvt_t* table_row, GdaQuery* query )
+{
+    GValue value;
+
+    get_gvalue_guid( be, obj_name, pObject, table_row, &value );
+    gnc_gda_add_field_to_query( query, table_row->col_name, &value );
+}
+
+static GdaQueryCondition*
+get_gvalue_guid_cond( const GncGdaBackend* be, QofIdTypeConst obj_name,
+                const 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, gboolean pkey )
+{
+    gnc_gda_add_table_column( server, cnn, array_data, table_row->col_name,
+                    "char", GUID_ENCODING_LENGTH, table_row->flags | pkey ? COL_PKEY : 0 );
+}
+
+static col_type_handler_t guid_handler =
+        { load_guid, create_guid_col,
+            get_gvalue_guid_for_query, get_gvalue_guid_cond };
+/* ----------------------------------------------------------------- */
+
+static void
+get_gvalue_objectref_guid( const GncGdaBackend* be, QofIdTypeConst obj_name, const gpointer pObject,
+                const col_cvt_t* table_row, GValue* value )
+{
+    QofAccessFunc getter;
+    const GUID* guid = NULL;
+    gchar guid_buf[GUID_ENCODING_LENGTH+1];
+	QofInstance* inst;
+
+    memset( value, 0, sizeof( GValue ) );
+
+	if( table_row->gobj_param_name != NULL ) {
+		g_object_get( pObject, table_row->gobj_param_name, &inst, NULL );
+	} else {
+    	getter = gnc_gda_get_getter( obj_name, table_row );
+    	inst = (*getter)( pObject, NULL );
+	}
+	if( inst != NULL ) {
+		guid = qof_instance_get_guid( inst );
+	}
+    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 );
+    }
+}
+
+void
+gnc_gda_get_gvalue_objectref_guid_for_query( const GncGdaBackend* be, QofIdTypeConst obj_name,
+                const gpointer pObject, const col_cvt_t* table_row, GdaQuery* query )
+{
+    GValue value;
+
+    get_gvalue_objectref_guid( be, obj_name, pObject, table_row, &value );
+    gnc_gda_add_field_to_query( query, table_row->col_name, &value );
+}
+
+GdaQueryCondition*
+gnc_gda_get_gvalue_objectref_guid_cond( const GncGdaBackend* be, QofIdTypeConst obj_name,
+                const gpointer pObject, const col_cvt_t* table_row, GdaQuery* query )
+{
+    GValue value;
+
+    get_gvalue_objectref_guid( be, obj_name, pObject, table_row, &value );
+    return gnc_gda_create_condition_from_field( query, table_row->col_name, &value );
+}
+
+void
+gnc_gda_create_objectref_guid_col( GdaServerProvider* server, GdaConnection* cnn,
+            xmlNodePtr array_data, const col_cvt_t* table_row, gboolean pkey )
+{
+    gnc_gda_add_table_column( server, cnn, array_data, table_row->col_name,
+                    "char", GUID_ENCODING_LENGTH, table_row->flags | pkey ? COL_PKEY : 0 );
+}
+
+static void
+load_account_guid( const GncGdaBackend* be, GdaDataModel* pModel, gint row,
+            QofSetterFunc setter, gpointer pObject,
+            const col_cvt_t* table )
+{
+    const GValue* val;
+    GUID guid;
+    const GUID* pGuid;
+	Account* account = NULL;
+
+    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;
+    }
+	if( pGuid != NULL ) {
+		account = xaccAccountLookup( pGuid, be->primary_book );
+	}
+    if( table->gobj_param_name != NULL ) {
+		g_object_set( pObject, table->gobj_param_name, account, NULL );
+    } else {
+		(*setter)( pObject, (const gpointer)account );
+    }
+}
+
+static col_type_handler_t account_guid_handler =
+        { load_account_guid, gnc_gda_create_objectref_guid_col,
+            gnc_gda_get_gvalue_objectref_guid_for_query, gnc_gda_get_gvalue_objectref_guid_cond };
+/* ----------------------------------------------------------------- */
+
+static void
+load_commodity_guid( const GncGdaBackend* be, GdaDataModel* pModel, gint row,
+            QofSetterFunc setter, gpointer pObject,
+            const col_cvt_t* table )
+{
+    const GValue* val;
+    GUID guid;
+    const GUID* pGuid;
+	gnc_commodity* commodity = NULL;
+
+    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;
+    }
+	if( pGuid != NULL ) {
+		commodity = gnc_commodity_find_commodity_by_guid( pGuid, be->primary_book );
+	}
+    if( table->gobj_param_name != NULL ) {
+		g_object_set( pObject, table->gobj_param_name, commodity, NULL );
+    } else {
+		(*setter)( pObject, (const gpointer)commodity );
+    }
+}
+
+static col_type_handler_t commodity_guid_handler =
+        { load_commodity_guid, gnc_gda_create_objectref_guid_col,
+            gnc_gda_get_gvalue_objectref_guid_for_query, gnc_gda_get_gvalue_objectref_guid_cond };
+/* ----------------------------------------------------------------- */
+
+static void
+load_tx_guid( const GncGdaBackend* be, GdaDataModel* pModel, gint row,
+            QofSetterFunc setter, gpointer pObject,
+            const col_cvt_t* table )
+{
+    const GValue* val;
+    GUID guid;
+    const GUID* pGuid;
+	Transaction* tx = NULL;
+
+    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;
+    }
+	if( pGuid != NULL ) {
+		tx = xaccTransLookup( pGuid, be->primary_book );
+	}
+    if( table->gobj_param_name != NULL ) {
+		g_object_set( pObject, table->gobj_param_name, tx, NULL );
+    } else {
+		(*setter)( pObject, (const gpointer)tx );
+    }
+}
+
+static col_type_handler_t tx_guid_handler =
+        { load_tx_guid, gnc_gda_create_objectref_guid_col,
+            gnc_gda_get_gvalue_objectref_guid_for_query, gnc_gda_get_gvalue_objectref_guid_cond };
+/* ----------------------------------------------------------------- */
+static void
+load_timespec( const GncGdaBackend* be, 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 {
+		if( G_VALUE_HOLDS_STRING( val ) ) {
+			const gchar* s = g_value_get_string( val );
+			gchar* buf;
+			buf = g_strdup_printf( "%c%c%c%c-%c%c-%c%c 00:00:00",
+									s[6], s[7], s[8], s[9],
+									s[0], s[1],
+									s[3], s[4] );
+		    ts = gnc_iso8601_to_timespec_gmt( buf );
+			(*setter)( pObject, &ts );
+			g_free( buf );
+
+		} else if( G_VALUE_HOLDS_BOXED( val ) ) {
+        	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 );
+			}
+		} else {
+			g_warning( "Unknown timespec type: %s", G_VALUE_TYPE_NAME( val ) );
+        }
+    }
+}
+
+static void
+get_gvalue_timespec( const GncGdaBackend* be, QofIdTypeConst obj_name,
+                const gpointer pObject, const col_cvt_t* table_row, GValue* value )
+{
+    QofAccessFunc getter;
+    Timespec* pTimespec;
+
+    memset( value, 0, sizeof( GValue ) );
+
+    getter = gnc_gda_get_getter( obj_name, table_row );
+    pTimespec = (Timespec*)(*getter)( pObject, NULL );
+    if( pTimespec != NULL ) {
+        GDate* date;
+        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( const GncGdaBackend* be, QofIdTypeConst obj_name,
+                const gpointer pObject, const col_cvt_t* table_row, GdaQuery* query )
+{
+    GValue value;
+
+    get_gvalue_timespec( be, obj_name, pObject, table_row, &value );
+    gnc_gda_add_field_to_query( query, table_row->col_name, &value );
+}
+
+static GdaQueryCondition*
+get_gvalue_timespec_cond( const GncGdaBackend* be, QofIdTypeConst obj_name,
+                const 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, gboolean pkey )
+{
+    const gchar* dbms_type;
+
+    dbms_type = gda_server_provider_get_default_dbms_type( server,
+                                                        cnn, G_TYPE_DATE );
+    gnc_gda_add_table_column( server, cnn, array_data, table_row->col_name,
+                    dbms_type, table_row->size, table_row->flags | pkey ? COL_PKEY : 0 );
+}
+
+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( const GncGdaBackend* be, 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 ) ) {
+		date = g_date_new_dmy( 1, 1, 1970 );
+        (*setter)( pObject, date );
+		g_date_free( date );
+    } else {
+		if( G_VALUE_HOLDS_STRING( val ) ) {
+			const gchar* s = g_value_get_string( val );
+			guint year = atoi( &s[6] );
+			guint month = atoi( &s[0] );
+			guint day = atoi( &s[3] );
+
+			date = g_date_new_dmy( day, month, year );
+			(*setter)( pObject, date );
+			g_date_free( date );
+
+		} else if( G_VALUE_HOLDS_BOXED( val ) ) {
+        	date = (GDate*)g_value_get_boxed( val );
+        	if( date != NULL ) {
+            	(*setter)( pObject, date );
+				g_date_free( date );
+			}
+		} else {
+			g_warning( "Unknown timespec type: %s", G_VALUE_TYPE_NAME( val ) );
+        }
+    }
+}
+
+static void
+get_gvalue_date( const GncGdaBackend* be, QofIdTypeConst obj_name, const gpointer pObject,
+                const col_cvt_t* table_row, GValue* value )
+{
+    GDate* date;
+    QofAccessFunc getter;
+
+    memset( value, 0, sizeof( GValue ) );
+
+    getter = gnc_gda_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( const GncGdaBackend* be, QofIdTypeConst obj_name,
+                const gpointer pObject, const col_cvt_t* table_row, GdaQuery* query )
+{
+    GValue value;
+
+    get_gvalue_date( be, obj_name, pObject, table_row, &value );
+    gnc_gda_add_field_to_query( query, table_row->col_name, &value );
+}
+
+static GdaQueryCondition*
+get_gvalue_date_cond( const GncGdaBackend* be, QofIdTypeConst obj_name,
+                const 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 gint64
+get_integer_value( const GValue* value )
+{
+	if( G_VALUE_HOLDS_INT(value) ) {
+		return g_value_get_int( value );
+	} else if( G_VALUE_HOLDS_UINT(value) ) {
+		return g_value_get_uint( value );
+	} else if( G_VALUE_HOLDS_LONG(value) ) {
+		return g_value_get_long( value );
+	} else if( G_VALUE_HOLDS_ULONG(value) ) {
+		return g_value_get_ulong( value );
+	} else if( G_VALUE_HOLDS_INT64(value) ) {
+		return g_value_get_int64( value );
+	} else if( G_VALUE_HOLDS_UINT64(value) ) {
+		return g_value_get_uint64( value );
+	} else {
+		g_warning( "Unknown type: %s", G_VALUE_TYPE_NAME( value ) );
+	}
+
+	return 0;
+}
+
+typedef void (*NumericSetterFunc)( gpointer, gnc_numeric );
+typedef gnc_numeric (*NumericGetterFunc)( const gpointer );
+
+static void
+load_numeric( const GncGdaBackend* be, 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;
+	NumericSetterFunc n_setter = (NumericSetterFunc)setter;
+
+    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 = get_integer_value( 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 = get_integer_value( val );
+    }
+    n = gnc_numeric_create( num, denom );
+    if( !isNull ) {
+        (*n_setter)( pObject, n );
+    }
+}
+
+static void
+get_gvalue_numeric( const GncGdaBackend* be, QofIdTypeConst obj_name, const gpointer pObject,
+                const col_cvt_t* table_row, GValue* value )
+{
+    NumericGetterFunc getter;
+    gnc_numeric n;
+
+    memset( value, 0, sizeof( GValue ) );
+
+    getter = (NumericGetterFunc)gnc_gda_get_getter( obj_name, table_row );
+    n = (*getter)( pObject );
+    g_value_init( value, gnc_numeric_get_type() );
+    g_value_set_boxed( value, &n );
+}
+
+static void
+get_gvalue_numeric_for_query( const GncGdaBackend* be, QofIdTypeConst obj_name,
+                const 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 );
+    gnc_gda_add_field_to_query( query, s, &num_value );
+    g_free( s );
+    s = g_strdup_printf( "%s_denom", table_row->col_name );
+    gnc_gda_add_field_to_query( query, s, &denom_value );
+    g_free( s );
+}
+
+static GdaQueryCondition*
+get_gvalue_numeric_cond( const GncGdaBackend* be, QofIdTypeConst obj_name,
+                const gpointer pObject, const col_cvt_t* table_row, GdaQuery* query )
+{
+    GValue value;
+    GValue num_value;
+    GValue denom_value;
+    gnc_numeric* n;
+    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, s, &value );
+    g_free( s );
+    s = g_strdup_printf( "%s_denom", table_row->col_name );
+    denom_cond = gnc_gda_create_condition_from_field( query, s, &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, gboolean pkey )
+{
+    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 );
+    gnc_gda_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 );
+    gnc_gda_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 GHashTable* g_columnTypeHash = NULL;
+
+void
+gnc_gda_register_col_type_handler( const gchar* colType, const col_type_handler_t* handler )
+{
+	if( g_columnTypeHash == NULL ) {
+		g_columnTypeHash = g_hash_table_new( g_str_hash, g_str_equal );
+	}
+
+	g_hash_table_insert( g_columnTypeHash, (gpointer)colType, (gpointer)handler );
+}
+
+static col_type_handler_t*
+get_handler( const gchar* col_type )
+{
+    col_type_handler_t* pHandler;
+
+	pHandler = g_hash_table_lookup( g_columnTypeHash, col_type );
+	if( pHandler == NULL ) {
+        g_assert( FALSE );
+    }
+
+    return pHandler;
+}
+
+void
+gnc_gda_register_standard_col_type_handlers( void )
+{
+	gnc_gda_register_col_type_handler( CT_STRING, &string_handler );
+    gnc_gda_register_col_type_handler( CT_BOOLEAN, &boolean_handler );
+    gnc_gda_register_col_type_handler( CT_INT, &int_handler );
+    gnc_gda_register_col_type_handler( CT_INT64, &int64_handler );
+    gnc_gda_register_col_type_handler( CT_DOUBLE, &double_handler );
+    gnc_gda_register_col_type_handler( CT_GUID, &guid_handler );
+	gnc_gda_register_col_type_handler( CT_ACCOUNTREF, &account_guid_handler );
+	gnc_gda_register_col_type_handler( CT_COMMODITYREF, &commodity_guid_handler );
+	gnc_gda_register_col_type_handler( CT_TXREF, &tx_guid_handler );
+    gnc_gda_register_col_type_handler( CT_TIMESPEC, &timespec_handler );
+    gnc_gda_register_col_type_handler( CT_GDATE, &date_handler );
+    gnc_gda_register_col_type_handler( CT_NUMERIC, &numeric_handler );
+}
+
+static void retrieve_guid( gpointer pObject, gpointer pValue );
+
+static void 
+retrieve_guid( gpointer pObject, gpointer pValue )
+{
+    GUID* pGuid = (GUID*)pObject;
+    GUID* guid = (GUID*)pValue;
+
+	memcpy( pGuid, guid, sizeof( GUID ) );
+}
+
+
+// Table to retrieve just the guid
+static col_cvt_t guid_table[] =
+{
+    { "guid", CT_GUID, 0, 0, NULL, NULL, NULL, retrieve_guid },
+    { NULL }
+};
+
+const GUID*
+gnc_gda_load_guid( const GncGdaBackend* be, GdaDataModel* pModel, gint row )
+{
+	static GUID guid;
+
+    gnc_gda_load_object( be, pModel, row, NULL, &guid, guid_table );
+
+    return &guid;
+}
+
+// Table to retrieve just the guid
+static col_cvt_t tx_guid_table[] =
+{
+    { "tx_guid", CT_GUID, 0, 0, NULL, NULL, NULL, retrieve_guid },
+    { NULL }
+};
+
+const GUID*
+gnc_gda_load_tx_guid( const GncGdaBackend* be, GdaDataModel* pModel, gint row )
+{
+    static GUID guid;
+
+    gnc_gda_load_object( be, pModel, row, NULL, &guid, tx_guid_table );
+
+    return &guid;
+}
+
+void
+gnc_gda_load_object( const GncGdaBackend* be, 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( be, 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( const GncGdaBackend* be, GdaQuery* query )
+{
+    GError* error = NULL;
+
+    GdaObject* ret;
+
+    ret = gda_query_execute( query, NULL, FALSE, &error );
+
+    if( error != NULL ) {
+        g_critical( "SQL error: %s\n", error->message );
+    }
+
+    return ret;
+}
+
+GdaQuery*
+gnc_gda_create_query_from_sql( const GncGdaBackend* be, const gchar* sql )
+{
+    GError* error = NULL;
+
+    GdaQuery* query;
+
+    query = gda_query_new_from_sql( be->pDict, sql, &error );
+    if( query == NULL ) {
+        g_critical( "SQL error: %s\n", error->message );
+    }
+
+	return query;
+}
+
+GdaObject*
+gnc_gda_execute_sql( const GncGdaBackend* be, const gchar* sql )
+{
+	GdaQuery* query;
+
+	query = gnc_gda_create_query_from_sql( be, sql );
+	if( query != NULL ) {
+	    return gnc_gda_execute_query( be, query );
+	} else {
+		return NULL;
+	}
+}
+
+int
+gnc_gda_execute_select_get_count( const 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 ) {
+        g_critical( "SQL error: %s\n", error->message );
+    }
+
+    return count;
+}
+
+int
+gnc_gda_execute_query_get_count( const 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 )
+{
+    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( const GncGdaBackend* be, QofIdTypeConst obj_name,
+                        gpointer pObject, const col_cvt_t* table_row,
+                        GdaQuery* query )
+{
+    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( const GncGdaBackend* be, const gchar* table_name,
+                    QofIdTypeConst obj_name, gpointer pObject,
+                    const col_cvt_t* table )
+{
+    GdaQuery* query;
+    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++ ) {
+		if(( table[col].flags & COL_AUTOINC ) == 0 ) {
+	        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;
+
+    /* 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;
+}
+
+/* ================================================================= */
+void
+gnc_gda_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,
+                    const 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;
+        
+        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++ ) {
+            col_type_handler_t* pHandler;
+
+            pHandler = get_handler( col_table[col].col_type );
+
+            pHandler->create_col_fn( server, cnn, array_data, &col_table[col], col == 0 );
+        }
+        
+        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( const GncGdaBackend* be,
+			                        const gchar* table_name,
+									const 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 ) {
+            g_critical( "Error creating table: %s\n", error->message );
+        }
+    }
+}
+/* ================================================================= */
+#if 0
+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 );
+}
+#endif
+/* ========================== END OF FILE ===================== */

Added: gnucash/branches/gda-dev2/src/backend/gda/gnc-backend-util-gda.h
===================================================================
--- gnucash/branches/gda-dev2/src/backend/gda/gnc-backend-util-gda.h	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/backend/gda/gnc-backend-util-gda.h	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,191 @@
+/********************************************************************
+ * 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_UTIL_H_
+#define GNC_BACKEND_GDA_UTIL_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;
+
+// Type for conversion of db row to object.
+#define CT_STRING "ct_string"
+#define CT_GUID "ct_guid"
+#define CT_INT "ct_int"
+#define CT_INT64 "ct_int64"
+#define CT_TIMESPEC "ct_timespec"
+#define CT_GDATE "ct_gdate"
+#define CT_NUMERIC "ct_numeric"
+#define CT_DOUBLE "ct_double"
+#define CT_BOOLEAN "ct_boolean"
+#define CT_ACCOUNTREF "ct_accountref"
+#define CT_COMMODITYREF "ct_commodityref"
+#define CT_TXREF "ct_txref"
+
+typedef struct {
+	const gchar* col_name;
+	const gchar* col_type;
+	gint size;
+#define COL_PKEY	0x01
+#define COL_NNUL	0x02
+#define COL_UNIQUE	0x04
+#define COL_AUTOINC	0x08
+	gint flags;
+	const gchar* gobj_param_name;	// If non-null, use g_object_get/g_object_set
+	const gchar* 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;
+
+typedef void (*GNC_GDA_LOAD_FN)( const GncGdaBackend* be, 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, gboolean pkey );
+typedef void (*GNC_GDA_GET_GVALUE_QUERY_FN)( const GncGdaBackend* be,
+                QofIdTypeConst obj_name, const gpointer pObject,
+                const col_cvt_t* table_row, GdaQuery* query );
+typedef GdaQueryCondition* (*GNC_GDA_GET_GVALUE_COND_FN)( const GncGdaBackend* be,
+                QofIdTypeConst obj_name, const 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;
+
+QofAccessFunc gnc_gda_get_getter( QofIdTypeConst obj_name, const col_cvt_t* table_row );
+void gnc_gda_add_table_column( GdaServerProvider* server, GdaConnection* cnn,
+            xmlNodePtr array_data, const gchar* arg, const gchar* dbms_type,
+            gint size, gint flags );
+
+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( const GncGdaBackend* pBackend, GdaQuery* pQuery );
+GdaObject* gnc_gda_execute_sql( const GncGdaBackend* pBackend, const gchar* sql );
+GdaQuery* gnc_gda_create_query_from_sql( const GncGdaBackend* pBackend, const gchar* sql );
+int gnc_gda_execute_select_get_count( const GncGdaBackend* pBackend, const gchar* sql );
+int gnc_gda_execute_query_get_count( const GncGdaBackend* pBackend, GdaQuery* query );
+void gnc_gda_load_object( const GncGdaBackend* be, GdaDataModel* pModel, int row,
+						QofIdTypeConst obj_name, gpointer pObject,
+						const col_cvt_t* table );
+gboolean gnc_gda_object_is_it_in_db( const GncGdaBackend* be,
+									const gchar* table_name,
+									QofIdTypeConst obj_name, const gpointer pObject,
+									const col_cvt_t* table );
+gboolean gnc_gda_create_table( GdaConnection* pConnection,
+						const gchar* table_name, const col_cvt_t* col_table,
+						GError** error );
+void gnc_gda_create_table_if_needed( const GncGdaBackend* be,
+						const gchar* table_name, const col_cvt_t* col_table );
+const GUID* gnc_gda_load_guid( const GncGdaBackend* be, GdaDataModel* pModel, int row );
+const GUID* gnc_gda_load_tx_guid( const GncGdaBackend* be, 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 );
+void gnc_gda_register_col_type_handler( const gchar* colType, const col_type_handler_t* handler );
+void gnc_gda_register_standard_col_type_handlers( void );
+void gnc_gda_add_field_to_query( GdaQuery* query, const gchar* col_name, const GValue* value );
+
+void gnc_gda_get_gvalue_objectref_guid_for_query( const GncGdaBackend* be, QofIdTypeConst obj_name,
+                const gpointer pObject, const col_cvt_t* table_row, GdaQuery* query );
+GdaQueryCondition* gnc_gda_get_gvalue_objectref_guid_cond( const GncGdaBackend* be, QofIdTypeConst obj_name,
+                const gpointer pObject, const col_cvt_t* table_row, GdaQuery* query );
+void gnc_gda_create_objectref_guid_col( GdaServerProvider* server, GdaConnection* cnn,
+	            xmlNodePtr array_data, const col_cvt_t* table_row, gboolean pkey );
+
+G_MODULE_EXPORT const gchar *
+g_module_check_init( GModule *module );
+
+#endif /* GNC_BACKEND_GDA_UTIL_H_ */

Added: gnucash/branches/gda-dev2/src/backend/gda/gnc-book-gda.c
===================================================================
--- gnucash/branches/gda-dev2/src/backend/gda/gnc-book-gda.c	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/backend/gda/gnc-book-gda.c	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,207 @@
+/********************************************************************
+ * gnc-book-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-book-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-backend-util-gda.h"
+
+#include "gnc-book-gda.h"
+#include "gnc-slots-gda.h"
+
+#include "gnc-engine.h"
+#include "gnc-book.h"
+#include "SX-book.h"
+#include "SX-book-p.h"
+
+#define BOOK_TABLE "books"
+
+static QofLogModule log_module = GNC_MOD_BACKEND;
+
+static void commit_book( GncGdaBackend* be, QofInstance* inst );
+
+static gpointer get_root_account_guid( gpointer pObject, const QofParam* );
+static void set_root_account_guid( gpointer pObject, gpointer pValue );
+static gpointer get_root_template_guid( gpointer pObject, const QofParam* );
+static void set_root_template_guid( gpointer pObject, gpointer pValue );
+
+static col_cvt_t col_table[] =
+{
+    { "guid",               CT_GUID, 0, COL_NNUL, "guid" },
+    { "root_account_guid",  CT_GUID, 0, COL_NNUL, NULL, NULL, get_root_account_guid,  set_root_account_guid },
+    { "root_template_guid", CT_GUID, 0, COL_NNUL, NULL, NULL, get_root_template_guid, set_root_template_guid },
+    { NULL }
+};
+
+/* ================================================================= */
+static gpointer
+get_root_account_guid( gpointer pObject, const QofParam* param )
+{
+    GNCBook* book = QOF_BOOK(pObject);
+    const Account* root = gnc_book_get_root_account( book );
+
+    return (gpointer)qof_instance_get_guid( QOF_INSTANCE( root ) );
+}
+
+static void 
+set_root_account_guid( gpointer pObject, gpointer pValue )
+{
+    GNCBook* book = QOF_BOOK(pObject);
+    const Account* root = gnc_book_get_root_account( book );
+    GUID* guid = (GUID*)pValue;
+
+    qof_instance_set_guid( QOF_INSTANCE( root ), guid );
+}
+
+static gpointer
+get_root_template_guid( gpointer pObject, const QofParam* param )
+{
+    const GNCBook* book = QOF_BOOK(pObject);
+    const Account* root = gnc_book_get_template_root( book );
+
+    return (gpointer)qof_instance_get_guid( QOF_INSTANCE( root ) );
+}
+
+static void 
+set_root_template_guid( gpointer pObject, gpointer pValue )
+{
+    GNCBook* book = QOF_BOOK(pObject);
+    GUID* guid = (GUID*)pValue;
+    Account* root = gnc_book_get_template_root( book );
+
+    if( root == NULL ) {
+        root = xaccMallocAccount( book );
+        xaccAccountBeginEdit( root );
+        xaccAccountSetType( root, ACCT_TYPE_ROOT );
+        xaccAccountCommitEdit( root );
+        gnc_book_set_template_root( book, root );
+    }
+    qof_instance_set_guid( QOF_INSTANCE( root ), guid );
+}
+
+/* ================================================================= */
+static GNCBook*
+load_single_book( GncGdaBackend* be, GdaDataModel* pModel, int row )
+{
+    const GUID* guid;
+    GUID book_guid;
+	GNCBook* pBook;
+
+    guid = gnc_gda_load_guid( be, pModel, row );
+    book_guid = *guid;
+
+	pBook = be->primary_book;
+	if( pBook == NULL ) {
+	    pBook = gnc_book_new();
+	}
+
+    gnc_gda_load_object( be, pModel, row, GNC_ID_BOOK, pBook, col_table );
+    gnc_gda_slots_load( be, gnc_book_get_guid( pBook ),
+                            qof_instance_get_slots( QOF_INSTANCE(pBook) ) );
+
+    qof_instance_mark_clean( QOF_INSTANCE(pBook) );
+
+    return pBook;
+}
+
+static void
+load_all_books( GncGdaBackend* be )
+{
+    static GdaQuery* query;
+    GdaObject* ret;
+    QofBook* pBook = be->primary_book;
+
+    if( query == NULL ) {
+        query = gnc_gda_create_select_query( be, BOOK_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 );
+
+		// If there are no rows, try committing the book
+		if( numRows == 0 ) {
+   	    	commit_book( be, QOF_INSTANCE( be->primary_book ) );
+		} else {
+			// Otherwise, load the 1st book.
+            (void)load_single_book( be, pModel, 0 );
+		}
+    }
+}
+
+/* ================================================================= */
+static void
+create_book_tables( GncGdaBackend* be )
+{
+    gnc_gda_create_table_if_needed( be, BOOK_TABLE, col_table );
+}
+
+/* ================================================================= */
+static void
+commit_book( GncGdaBackend* be, QofInstance* inst )
+{
+    GNCBook* pBook = QOF_BOOK(inst);
+    const GUID* guid;
+
+    (void)gnc_gda_do_db_operation( be,
+                        qof_instance_get_destroying(inst) ? OP_DB_DELETE : OP_DB_ADD_OR_UPDATE,
+                        BOOK_TABLE,
+                        GNC_ID_BOOK, pBook,
+                        col_table );
+
+    // Delete old slot info
+    guid = qof_instance_get_guid( inst );
+
+    // Now, commit any slots
+    if( !qof_instance_get_destroying(inst) ) {
+        gnc_gda_slots_save( be, guid, qof_instance_get_slots( inst ) );
+    } else {
+        gnc_gda_slots_delete( be, guid );
+    }
+}
+
+/* ================================================================= */
+void
+gnc_gda_init_book_handler( void )
+{
+    static GncGdaDataType_t be_data =
+    {
+        GNC_GDA_BACKEND_VERSION,
+        GNC_ID_BOOK,
+        commit_book,                /* commit */
+        load_all_books,                    /* initial_load */
+        create_book_tables            /* create_tables */
+    };
+
+    qof_object_register_backend( GNC_ID_BOOK, GNC_GDA_BACKEND, &be_data );
+}
+/* ========================== END OF FILE ===================== */

Added: gnucash/branches/gda-dev2/src/backend/gda/gnc-book-gda.h
===================================================================
--- gnucash/branches/gda-dev2/src/backend/gda/gnc-book-gda.h	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/backend/gda/gnc-book-gda.h	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,37 @@
+/********************************************************************
+ * gnc-book-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-book-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_BOOK_GDA_H_
+#define GNC_BOOK_GDA_H_
+
+#include "qof.h"
+#include <gmodule.h>
+
+void gnc_gda_init_book_handler( void );
+
+#endif /* GNC_BOOK_GDA_H_ */

Added: gnucash/branches/gda-dev2/src/backend/gda/gnc-budget-gda.c
===================================================================
--- gnucash/branches/gda-dev2/src/backend/gda/gnc-budget-gda.c	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/backend/gda/gnc-budget-gda.c	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,158 @@
+/********************************************************************
+ * gnc-budget-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-budget-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-backend-util-gda.h"
+
+#include "Recurrence.h"
+
+#include "gnc-budget-gda.h"
+#include "gnc-slots-gda.h"
+#include "gnc-recurrence-gda.h"
+
+#include "gnc-budget.h"
+
+#define BUDGET_TABLE "budgets"
+
+static QofLogModule log_module = GNC_MOD_BACKEND;
+
+#define BUDGET_MAX_NAME_LEN 50
+#define BUDGET_MAX_DESCRIPTION_LEN 500
+
+static col_cvt_t col_table[] =
+{
+    { "guid",        CT_GUID,   0,                          COL_NNUL, "guid" },
+    { "name",        CT_STRING, BUDGET_MAX_NAME_LEN,        COL_NNUL, NULL, "name" },
+    { "description", CT_STRING, BUDGET_MAX_DESCRIPTION_LEN, 0,        NULL, "description" },
+    { "num_periods", CT_INT,    0,                          COL_NNUL, NULL, "num_periods" },
+    { NULL }
+};
+
+/* ================================================================= */
+static GncBudget*
+load_single_budget( GncGdaBackend* be, GdaDataModel* pModel, int row )
+{
+    const GUID* guid;
+    GUID budget_guid;
+	GncBudget* pBudget;
+	Recurrence* r;
+
+    guid = gnc_gda_load_guid( be, pModel, row );
+    budget_guid = *guid;
+
+    pBudget = gnc_budget_lookup( &budget_guid, be->primary_book );
+    if( pBudget == NULL ) {
+        pBudget = gnc_budget_new( be->primary_book );
+    }
+
+    gnc_gda_load_object( be, pModel, row, GNC_ID_BUDGET, pBudget, col_table );
+	r = g_new0( Recurrence, 1 );
+	gnc_gda_recurrence_load( be, gnc_budget_get_guid( pBudget ), r );
+    gnc_gda_slots_load( be, gnc_budget_get_guid( pBudget ),
+                            qof_instance_get_slots( QOF_INSTANCE(pBudget) ) );
+
+    qof_instance_mark_clean( QOF_INSTANCE(pBudget) );
+
+    return pBudget;
+}
+
+static void
+load_all_budgets( GncGdaBackend* be )
+{
+    static GdaQuery* query;
+    GdaObject* ret;
+    QofBook* pBook = be->primary_book;
+
+    if( query == NULL ) {
+        query = gnc_gda_create_select_query( be, BUDGET_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_single_budget( be, pModel, r );
+        }
+    }
+}
+
+/* ================================================================= */
+static void
+create_budget_tables( GncGdaBackend* be )
+{
+    gnc_gda_create_table_if_needed( be, BUDGET_TABLE, col_table );
+}
+
+/* ================================================================= */
+void
+gnc_gda_save_budget( GncGdaBackend* be, QofInstance* inst )
+{
+    GncBudget* pBudget = GNC_BUDGET(inst);
+    const GUID* guid;
+
+    (void)gnc_gda_do_db_operation( be,
+                        qof_instance_get_destroying(inst) ? OP_DB_DELETE : OP_DB_ADD_OR_UPDATE,
+                        BUDGET_TABLE,
+                        GNC_ID_BUDGET, pBudget,
+                        col_table );
+
+    // Now, commit any slots and recurrence
+    guid = qof_instance_get_guid( inst );
+    if( !qof_instance_get_destroying(inst) ) {
+		gnc_gda_recurrence_save( be, guid, gnc_budget_get_recurrence( pBudget ) );
+        gnc_gda_slots_save( be, guid, qof_instance_get_slots( inst ) );
+    } else {
+        gnc_gda_recurrence_delete( be, guid );
+        gnc_gda_slots_delete( be, guid );
+    }
+}
+
+/* ================================================================= */
+void
+gnc_gda_init_budget_handler( void )
+{
+    static GncGdaDataType_t be_data =
+    {
+        GNC_GDA_BACKEND_VERSION,
+        GNC_ID_BUDGET,
+        gnc_gda_save_budget,                /* commit */
+        load_all_budgets,                /* initial_load */
+        create_budget_tables        /* create_tables */
+    };
+
+    qof_object_register_backend( GNC_ID_BUDGET, GNC_GDA_BACKEND, &be_data );
+}
+/* ========================== END OF FILE ===================== */

Added: gnucash/branches/gda-dev2/src/backend/gda/gnc-budget-gda.h
===================================================================
--- gnucash/branches/gda-dev2/src/backend/gda/gnc-budget-gda.h	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/backend/gda/gnc-budget-gda.h	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,38 @@
+/********************************************************************
+ * gnc-budget-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-budget-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_BUDGET_GDA_H_
+#define GNC_BUDGET_GDA_H_
+
+#include "qof.h"
+#include <gmodule.h>
+
+void gnc_gda_init_budget_handler( void );
+void gnc_gda_save_budget( GncGdaBackend* be, QofInstance* inst );
+
+#endif /* GNC_BUDGET_GDA_H_ */

Added: gnucash/branches/gda-dev2/src/backend/gda/gnc-commodity-gda.c
===================================================================
--- gnucash/branches/gda-dev2/src/backend/gda/gnc-commodity-gda.c	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/backend/gda/gnc-commodity-gda.c	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,220 @@
+/********************************************************************
+ * gnc-commodity-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-commodity-gda.c
+ *  @brief load and save data to SQL 
+ *  @author Copyright (c) 2000 Gnumatic Inc.
+ *  @author Copyright (c) 2002 Derek Atkins <warlord at MIT.EDU>
+ *  @author Copyright (c) 2003 Linas Vepstas <linas at linas.org>
+ *  @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-backend-util-gda.h"
+#include "gnc-commodity.h"
+
+#include "gnc-commodity-gda.h"
+#include "gnc-slots-gda.h"
+
+static QofLogModule log_module = GNC_MOD_BACKEND;
+
+static gpointer get_quote_source_name( gpointer pObject, const QofParam* );
+static void set_quote_source_name( gpointer pObject, gpointer pValue );
+
+#define COMMODITIES_TABLE "commodities"
+
+#define COMMODITY_MAX_NAMESPACE_LEN 40
+#define COMMODITY_MAX_MNEMONIC_LEN 40
+#define COMMODITY_MAX_FULLNAME_LEN 100
+#define COMMODITY_MAX_CUSIP_LEN 50
+#define COMMODITY_MAX_QUOTESOURCE_LEN 50
+#define COMMODITY_MAX_QUOTE_TZ_LEN 50
+
+static col_cvt_t col_table[] = {
+    { "guid",         CT_GUID,   0,                             COL_NNUL, "guid" },
+    { "namespace",    CT_STRING, COMMODITY_MAX_NAMESPACE_LEN,   COL_NNUL, NULL, NULL,
+            (QofAccessFunc)gnc_commodity_get_namespace,
+            (QofSetterFunc)gnc_commodity_set_namespace },
+    { "mnemonic",     CT_STRING, COMMODITY_MAX_MNEMONIC_LEN,    COL_NNUL, NULL, NULL,
+            (QofAccessFunc)gnc_commodity_get_mnemonic,
+            (QofSetterFunc)gnc_commodity_set_mnemonic },
+    { "fullname",     CT_STRING, COMMODITY_MAX_FULLNAME_LEN,    COL_NNUL, NULL, NULL,
+            (QofAccessFunc)gnc_commodity_get_fullname,
+            (QofSetterFunc)gnc_commodity_set_fullname },
+    { "cusip",        CT_STRING, COMMODITY_MAX_CUSIP_LEN,       0,        NULL, NULL,
+            (QofAccessFunc)gnc_commodity_get_cusip,
+            (QofSetterFunc)gnc_commodity_set_cusip },
+    { "fraction",     CT_INT,    0,                             COL_NNUL, NULL, NULL,
+            (QofAccessFunc)gnc_commodity_get_fraction,
+            (QofSetterFunc)gnc_commodity_set_fraction },
+    { "quote_flag",   CT_INT,    0,                             COL_NNUL, NULL, NULL,
+            (QofAccessFunc)gnc_commodity_get_quote_flag,
+            (QofSetterFunc)gnc_commodity_set_quote_flag },
+    { "quote_source", CT_STRING, COMMODITY_MAX_QUOTESOURCE_LEN, 0,        NULL, NULL,
+            get_quote_source_name, set_quote_source_name },
+    { "quote_tz",     CT_STRING, COMMODITY_MAX_QUOTE_TZ_LEN,    0,        NULL, NULL,
+            (QofAccessFunc)gnc_commodity_get_quote_tz,
+            (QofSetterFunc)gnc_commodity_set_quote_tz },
+    { NULL }
+};
+
+/* ================================================================= */
+
+static gpointer
+get_quote_source_name( gpointer pObject, const QofParam* param )
+{
+    const gnc_commodity* pCommodity = GNC_COMMODITY(pObject);
+
+    return (gpointer)gnc_quote_source_get_internal_name(
+                            gnc_commodity_get_quote_source(pCommodity));
+}
+
+static void 
+set_quote_source_name( gpointer pObject, gpointer pValue )
+{
+    gnc_commodity* pCommodity = GNC_COMMODITY(pObject);
+    const gchar* quote_source_name = (const gchar*)pValue;
+    gnc_quote_source* quote_source;
+
+    quote_source = gnc_quote_source_lookup_by_internal( quote_source_name );
+    gnc_commodity_set_quote_source( pCommodity, quote_source );
+}
+
+static gnc_commodity*
+load_single_commodity( GncGdaBackend* be, GdaDataModel* pModel, int row )
+{
+    QofBook* pBook = be->primary_book;
+    int col;
+    const GValue* val;
+    gnc_commodity* pCommodity;
+
+    pCommodity = gnc_commodity_new( pBook, NULL, NULL, NULL, NULL, 100 );
+
+    gnc_gda_load_object( be, pModel, row, GNC_ID_COMMODITY, pCommodity, col_table );
+    gnc_gda_slots_load( be, qof_instance_get_guid( QOF_INSTANCE(pCommodity) ),
+                            qof_instance_get_slots( QOF_INSTANCE(pCommodity) ) );
+
+    qof_instance_mark_clean( QOF_INSTANCE(pCommodity) );
+
+    return pCommodity;
+}
+
+static void
+load_all_commodities( GncGdaBackend* be )
+{
+    static GdaQuery* query;
+    GdaObject* ret;
+    gnc_commodity_table* pTable = gnc_commodity_table_get_table( be->primary_book );
+
+    if( query == NULL ) {
+        query = gnc_gda_create_select_query( be, COMMODITIES_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;
+        gnc_commodity* pCommodity;
+
+        for( r = 0; r < numRows; r++ ) {
+            gnc_commodity* c;
+
+            pCommodity = load_single_commodity( be, pModel, r );
+
+            if( pCommodity != NULL ) {
+                GUID guid;
+
+                guid = *qof_instance_get_guid( QOF_INSTANCE(pCommodity) );
+                pCommodity = gnc_commodity_table_insert( pTable, pCommodity );
+                qof_instance_set_guid( QOF_INSTANCE(pCommodity), &guid );
+            }
+        }
+    }
+}
+/* ================================================================= */
+static void
+create_commodities_tables( GncGdaBackend* be )
+{
+    gnc_gda_create_table_if_needed( be, COMMODITIES_TABLE, col_table );
+}
+
+/* ================================================================= */
+static void
+commit_commodity( GncGdaBackend* be, QofInstance* inst )
+{
+    const GUID* guid;
+
+    (void)gnc_gda_do_db_operation( be,
+                        (qof_instance_get_destroying(inst) ? OP_DB_DELETE : OP_DB_ADD_OR_UPDATE ),
+                        COMMODITIES_TABLE,
+                        GNC_ID_COMMODITY, (gnc_commodity*)inst,
+                        col_table );
+
+    // Delete old slot info
+    guid = qof_instance_get_guid( inst );
+
+    // Now, commit or delete any slots
+    if( !qof_instance_get_destroying(inst) ) {
+        gnc_gda_slots_save( be, guid, qof_instance_get_slots( inst ) );
+    } else {
+        gnc_gda_slots_delete( be, guid );
+    }
+}
+
+static gboolean
+is_commodity_in_db( GncGdaBackend* be, gnc_commodity* pCommodity )
+{
+    return gnc_gda_object_is_it_in_db( be, COMMODITIES_TABLE, GNC_ID_COMMODITY,
+                                pCommodity, col_table );
+}
+
+void
+gnc_gda_save_commodity( GncGdaBackend* be, gnc_commodity* pCommodity )
+{
+    if( !is_commodity_in_db( be, pCommodity ) ) {
+        commit_commodity( be, QOF_INSTANCE(pCommodity) );
+    }
+}
+
+/* ================================================================= */
+void
+gnc_gda_init_commodity_handler( void )
+{
+    static GncGdaDataType_t be_data =
+    {
+        GNC_GDA_BACKEND_VERSION,
+        GNC_ID_COMMODITY,
+        commit_commodity,            /* commit */
+        load_all_commodities,            /* initial_load */
+        create_commodities_tables    /* create_tables */
+    };
+
+    qof_object_register_backend( GNC_ID_COMMODITY, GNC_GDA_BACKEND, &be_data );
+}
+/* ========================== END OF FILE ===================== */

Added: gnucash/branches/gda-dev2/src/backend/gda/gnc-commodity-gda.h
===================================================================
--- gnucash/branches/gda-dev2/src/backend/gda/gnc-commodity-gda.h	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/backend/gda/gnc-commodity-gda.h	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,38 @@
+/********************************************************************
+ * gnc-commodity-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-commodity-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_COMMODITY_GDA_H_
+#define GNC_COMMODITY_GDA_H_
+
+#include "qof.h"
+#include <gmodule.h>
+
+void gnc_gda_init_commodity_handler( void );
+void gnc_gda_save_commodity( GncGdaBackend* be, gnc_commodity* pCommodity );
+
+#endif /* GNC_COMMODITY_GDA_H_ */

Added: gnucash/branches/gda-dev2/src/backend/gda/gnc-lots-gda.c
===================================================================
--- gnucash/branches/gda-dev2/src/backend/gda/gnc-lots-gda.c	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/backend/gda/gnc-lots-gda.c	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,178 @@
+/********************************************************************
+ * 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-util-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, const QofParam* param );
+static void set_lot_account( gpointer pObject, gpointer pValue );
+static gpointer get_lot_is_closed( gpointer pObject, const QofParam* param );
+static void set_lot_is_closed( gpointer pObject, gpointer pValue );
+
+static col_cvt_t col_table[] =
+{
+    { "guid",         CT_GUID,   0, COL_NNUL, "guid" },
+    { "account_guid", CT_GUID,   0, COL_NNUL, NULL, NULL, get_lot_account,   set_lot_account },
+    { "is_closed",    CT_STRING, 1, COL_NNUL, NULL, NULL, get_lot_is_closed, set_lot_is_closed },
+    { NULL }
+};
+
+/* ================================================================= */
+static gpointer
+get_lot_account( gpointer pObject, const QofParam* param )
+{
+    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, 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, const QofParam* param )
+{
+    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, gpointer pValue )
+{
+    GNCLot* lot = GNC_LOT(pObject);
+    const gboolean* pBoolean = (const gboolean*)pValue;
+
+    lot->is_closed = *pBoolean;
+}
+
+static GNCLot*
+load_single_lot( GncGdaBackend* be, GdaDataModel* pModel, int row )
+{
+	GNCLot* lot;
+
+    lot = gnc_lot_new( be->primary_book );
+
+    gnc_gda_load_object( be, 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_all_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_single_lot( be, pModel, r );
+        }
+    }
+}
+
+/* ================================================================= */
+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,
+                        (qof_instance_get_destroying(inst) ? 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_all_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-dev2/src/backend/gda/gnc-lots-gda.h
===================================================================
--- gnucash/branches/gda-dev2/src/backend/gda/gnc-lots-gda.h	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/backend/gda/gnc-lots-gda.h	2007-12-23 20:25:56 UTC (rev 16700)
@@ -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_ */

Added: gnucash/branches/gda-dev2/src/backend/gda/gnc-price-gda.c
===================================================================
--- gnucash/branches/gda-dev2/src/backend/gda/gnc-price-gda.c	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/backend/gda/gnc-price-gda.c	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,168 @@
+/********************************************************************
+ * gnc-price-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-price-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-pricedb.h"
+
+#include "gnc-backend-util-gda.h"
+
+#include "gnc-commodity-gda.h"
+#include "gnc-price-gda.h"
+
+static QofLogModule log_module = GNC_MOD_BACKEND;
+
+#define TABLE_NAME "prices"
+
+static gpointer get_date( gpointer pObject, const QofParam* param );
+static void set_date( gpointer pObject, gpointer pValue );
+
+#define PRICE_MAX_SOURCE_LEN 50
+#define PRICE_MAX_TYPE_LEN 50
+
+static col_cvt_t col_table[] =
+{
+    { "guid",           CT_GUID,           0,                    COL_NNUL, "guid" },
+    { "commodity_guid", CT_COMMODITYREF,   0,                    COL_NNUL, NULL, PRICE_COMMODITY },
+    { "currency_guid",  CT_COMMODITYREF,   0,                    COL_NNUL, NULL, PRICE_CURRENCY },
+    { "date",           CT_TIMESPEC,       0,                    COL_NNUL, NULL, NULL,       get_date, set_date },
+    { "source",         CT_STRING,         PRICE_MAX_SOURCE_LEN, 0,        NULL, PRICE_SOURCE },
+    { "type",           CT_STRING,         PRICE_MAX_TYPE_LEN,   0,        NULL, PRICE_TYPE },
+    { "value",          CT_NUMERIC,        0,                    COL_NNUL, NULL, PRICE_VALUE },
+    { NULL }
+};
+
+/* ================================================================= */
+
+static gpointer
+get_date( gpointer pObject, const QofParam* param )
+{
+    const GNCPrice* pPrice = GNC_PRICE(pObject);
+    static Timespec t;
+
+    t = gnc_price_get_time( pPrice );
+    return &t;
+}
+
+static void
+set_date( gpointer pObject, gpointer pValue )
+{
+    GNCPrice* pPrice = GNC_PRICE(pObject);
+    const Timespec* pTimespec = (const Timespec*)pValue;
+
+    gnc_price_set_time( pPrice, *pTimespec );
+}
+
+static GNCPrice*
+load_single_price( GncGdaBackend* be, GdaDataModel* pModel, int row )
+{
+	GNCPrice* pPrice;
+
+    pPrice = gnc_price_create( be->primary_book );
+
+    gnc_gda_load_object( be, pModel, row, GNC_ID_PRICE, pPrice, col_table );
+
+    qof_instance_mark_clean( QOF_INSTANCE(pPrice) );
+
+    return pPrice;
+}
+
+static void
+load_all_prices( GncGdaBackend* be )
+{
+    static GdaQuery* query;
+    GdaObject* ret;
+    QofBook* pBook = be->primary_book;
+    GNCPriceDB* pPriceDB = gnc_book_get_pricedb( pBook );
+
+    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;
+        GNCPrice* pPrice;
+
+        for( r = 0; r < numRows; r++ ) {
+            pPrice = load_single_price( be, pModel, r );
+
+            if( pPrice != NULL ) {
+                gnc_pricedb_add_price( pPriceDB, pPrice );
+            }
+        }
+    }
+}
+
+/* ================================================================= */
+static void
+create_prices_tables( GncGdaBackend* be )
+{
+    gnc_gda_create_table_if_needed( be, TABLE_NAME, col_table );
+}
+
+/* ================================================================= */
+
+void
+gnc_gda_save_price( GncGdaBackend* be, QofInstance* inst )
+{
+    GNCPrice* pPrice = GNC_PRICE(inst);
+
+    /* Ensure commodity and currency are in the db */
+    gnc_gda_save_commodity( be, gnc_price_get_commodity( pPrice ) );
+    gnc_gda_save_commodity( be, gnc_price_get_currency( pPrice ) );
+
+    (void)gnc_gda_do_db_operation( be,
+                        (qof_instance_get_destroying(inst) ? OP_DB_DELETE : OP_DB_ADD_OR_UPDATE ),
+                        TABLE_NAME,
+                        GNC_ID_PRICE, pPrice,
+                        col_table );
+}
+
+/* ================================================================= */
+void
+gnc_gda_init_price_handler( void )
+{
+    static GncGdaDataType_t be_data =
+    {
+        GNC_GDA_BACKEND_VERSION,
+        GNC_ID_PRICE,
+        gnc_gda_save_price,            /* commit */
+        load_all_prices,            /* initial_load */
+        create_prices_tables    /* create tables */
+    };
+
+    qof_object_register_backend( GNC_ID_PRICE, GNC_GDA_BACKEND, &be_data );
+}
+
+/* ========================== END OF FILE ===================== */

Added: gnucash/branches/gda-dev2/src/backend/gda/gnc-price-gda.h
===================================================================
--- gnucash/branches/gda-dev2/src/backend/gda/gnc-price-gda.h	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/backend/gda/gnc-price-gda.h	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,38 @@
+/********************************************************************
+ * gnc-price-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-price-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_PRICE_GDA_H_
+#define GNC_PRICE_GDA_H_
+
+#include "qof.h"
+#include <gmodule.h>
+
+void gnc_gda_init_price_handler( void );
+void gnc_gda_save_price( GncGdaBackend* be, QofInstance* inst );
+
+#endif /* GNC_PRICE_GDA_H_ */

Added: gnucash/branches/gda-dev2/src/backend/gda/gnc-recurrence-gda.c
===================================================================
--- gnucash/branches/gda-dev2/src/backend/gda/gnc-recurrence-gda.c	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/backend/gda/gnc-recurrence-gda.c	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,349 @@
+/********************************************************************
+ * gnc-recurrence-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-recurrence-gda.c
+ *  @brief load and save data to SQL 
+ *  @author Copyright (c) 2006, 2007 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 "Recurrence.h"
+
+#include "gnc-backend-util-gda.h"
+
+#include "gnc-recurrence-gda.h"
+
+static QofLogModule log_module = GNC_MOD_BACKEND;
+
+#define TABLE_NAME "recurrences"
+
+#define BUDGET_MAX_RECURRENCE_PERIOD_TYPE_LEN 50
+
+typedef struct {
+    GncGdaBackend* be;
+    const GUID* guid;
+	Recurrence* pRecurrence;
+} recurrence_info_t;
+
+static gpointer get_recurrence_id( gpointer pObject, const QofParam* param );
+static void set_recurrence_id( gpointer pObject, gpointer pValue );
+static gpointer get_obj_guid( gpointer pObject, const QofParam* param );
+static void set_obj_guid( gpointer pObject, gpointer pValue );
+static gpointer get_recurrence_mult( gpointer pObject, const QofParam* );
+static void set_recurrence_mult( gpointer pObject, gpointer pValue );
+static gpointer get_recurrence_period_type( gpointer pObject, const QofParam* );
+static void set_recurrence_period_type( gpointer pObject, gpointer pValue );
+static gpointer get_recurrence_period_start( gpointer pObject, const QofParam* );
+static void set_recurrence_period_start( gpointer pObject, gpointer pValue );
+
+static col_cvt_t col_table[] =
+{
+    { "recurrence_id",           CT_INT,    0,                                     COL_NNUL|COL_AUTOINC, NULL, NULL,
+            get_recurrence_id, set_recurrence_id },
+    { "obj_guid",                CT_GUID,   0,                                     COL_NNUL,             NULL, NULL,
+            get_obj_guid, set_obj_guid },
+    { "recurrence_mult",         CT_INT,    0,                                     COL_NNUL,             NULL, NULL,
+            get_recurrence_mult, set_recurrence_mult },
+    { "recurrence_period_type",  CT_STRING, BUDGET_MAX_RECURRENCE_PERIOD_TYPE_LEN, COL_NNUL,             NULL, NULL,
+			get_recurrence_period_type, set_recurrence_period_type },
+    { "recurrence_period_start", CT_GDATE,  0,                                     COL_NNUL,             NULL, NULL,
+            get_recurrence_period_start, set_recurrence_period_start },
+    { 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, 0, NULL, NULL, get_obj_guid, set_obj_guid },
+    { NULL }
+};
+
+/* ================================================================= */
+
+static gpointer
+get_recurrence_id( gpointer pObject, const QofParam* param )
+{
+    // Just need a 0 to force a new recurrence id
+    return (gpointer)0;
+}
+
+static void
+set_recurrence_id( gpointer pObject, gpointer pValue )
+{
+    // Nowhere to put the ID
+}
+
+static gpointer
+get_obj_guid( gpointer pObject, const QofParam* param )
+{
+    recurrence_info_t* pInfo = (recurrence_info_t*)pObject;
+
+    return (gpointer)pInfo->guid;
+}
+
+static void
+set_obj_guid( gpointer pObject, gpointer pValue )
+{
+    // Nowhere to put the GUID
+}
+
+static gpointer
+get_recurrence_mult( gpointer pObject, const QofParam* param )
+{
+    recurrence_info_t* pInfo = (recurrence_info_t*)pObject;
+    static guint m;
+	
+	m = pInfo->pRecurrence->mult;
+
+    return GUINT_TO_POINTER(m);
+}
+
+static void
+set_recurrence_mult( gpointer pObject, gpointer pValue )
+{
+    recurrence_info_t* pInfo = (recurrence_info_t*)pObject;
+    guint m = GPOINTER_TO_UINT(pValue);
+
+    pInfo->pRecurrence->mult = m;
+}
+
+static gpointer
+get_recurrence_period_type( gpointer pObject, const QofParam* param )
+{
+    recurrence_info_t* pInfo = (recurrence_info_t*)pObject;
+
+    return (gpointer)recurrencePeriodTypeToString(
+                            recurrenceGetPeriodType( pInfo->pRecurrence ) );
+}
+
+static void
+set_recurrence_period_type( gpointer pObject, gpointer pValue )
+{
+    recurrence_info_t* pInfo = (recurrence_info_t*)pObject;
+
+    pInfo->pRecurrence->ptype = recurrencePeriodTypeFromString( (gchar*)pValue );
+}
+
+static gpointer
+get_recurrence_period_start( gpointer pObject, const QofParam* param )
+{
+    recurrence_info_t* pInfo = (recurrence_info_t*)pObject;
+    static GDate date;
+
+    date = recurrenceGetDate( pInfo->pRecurrence );
+    return (gpointer)&date;
+}
+
+static void
+set_recurrence_period_start( gpointer pObject, gpointer pValue )
+{
+    recurrence_info_t* pInfo = (recurrence_info_t*)pObject;
+    GDate* date = (GDate*)pValue;
+
+    pInfo->pRecurrence->start = *date;
+}
+
+/* ================================================================= */
+
+void
+gnc_gda_recurrence_save( GncGdaBackend* be, const GUID* guid, const Recurrence* r )
+{
+    recurrence_info_t recurrence_info;
+
+	gnc_gda_recurrence_delete( be, guid );
+
+    recurrence_info.be = be;
+    recurrence_info.guid = guid;
+	recurrence_info.pRecurrence = (Recurrence*)r;
+    (void)gnc_gda_do_db_operation( be, OP_DB_ADD, TABLE_NAME,
+                                TABLE_NAME, &recurrence_info, col_table );
+}
+
+void
+gnc_gda_recurrence_save_list( GncGdaBackend* be, const GUID* guid, GList* schedule )
+{
+    recurrence_info_t recurrence_info;
+	GList* l;
+
+	gnc_gda_recurrence_delete( be, guid );
+
+    recurrence_info.be = be;
+    recurrence_info.guid = guid;
+	for( l = schedule; l != NULL; l = g_list_next( l ) ) {
+		recurrence_info.pRecurrence = (Recurrence*)l->data;
+    	(void)gnc_gda_do_db_operation( be, OP_DB_ADD, TABLE_NAME,
+                                TABLE_NAME, &recurrence_info, col_table );
+	}
+}
+
+void
+gnc_gda_recurrence_delete( GncGdaBackend* be, const GUID* guid )
+{
+    recurrence_info_t recurrence_info;
+
+    recurrence_info.be = be;
+    recurrence_info.guid = guid;
+    (void)gnc_gda_do_db_operation( be, OP_DB_DELETE, TABLE_NAME,
+                                TABLE_NAME, &recurrence_info, guid_col_table );
+}
+
+static void
+load_recurrence( GncGdaBackend* be, GdaDataModel* pModel, gint row, Recurrence* r )
+{
+    recurrence_info_t recurrence_info;
+
+    recurrence_info.be = be;
+	recurrence_info.pRecurrence = r;
+
+    gnc_gda_load_object( be, pModel, row, TABLE_NAME, &recurrence_info, col_table );
+}
+
+static GdaObject*
+gnc_gda_set_recurrences_from_db( GncGdaBackend* be, const GUID* guid )
+{
+    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 );
+
+	return ret;
+}
+
+void
+gnc_gda_recurrence_load( GncGdaBackend* be, const GUID* guid, Recurrence* pRecurrence )
+{
+	GdaObject* ret;
+
+	ret = gnc_gda_set_recurrences_from_db( be, guid );
+    if( GDA_IS_DATA_MODEL( ret ) ) {
+        GdaDataModel* pModel = GDA_DATA_MODEL(ret);
+        int numRows = gda_data_model_get_n_rows( pModel );
+
+		if( numRows > 0 ) {
+			if( numRows > 1 ) {
+				g_warning( "More than 1 recurrence found: first one used" );
+			}
+			load_recurrence( be, pModel, 0, pRecurrence );
+		} else {
+			g_warning( "No recurrences found" );
+		}
+    }
+}
+
+void
+gnc_gda_recurrence_load_list( GncGdaBackend* be, const GUID* guid, GList** pSchedule )
+{
+	GdaObject* ret;
+
+	ret = gnc_gda_set_recurrences_from_db( be, guid );
+    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++ ) {
+			Recurrence* pRecurrence = g_new0( Recurrence, 1 );
+			load_recurrence( be, pModel, 0, pRecurrence );
+			*pSchedule = g_list_append( *pSchedule, pRecurrence );
+		}
+    }
+}
+
+/* ================================================================= */
+static void
+create_recurrence_tables( GncGdaBackend* be )
+{
+    gnc_gda_create_table_if_needed( be, TABLE_NAME, col_table );
+}
+
+/* ================================================================= */
+void
+gnc_gda_init_recurrence_handler( void )
+{
+    static GncGdaDataType_t be_data =
+    {
+        GNC_GDA_BACKEND_VERSION,
+        GNC_ID_ACCOUNT,
+        NULL,                    /* commit - cannot occur */
+        NULL,                    /* initial_load - cannot occur */
+        create_recurrence_tables        /* create_tables */
+    };
+
+    qof_object_register_backend( TABLE_NAME, GNC_GDA_BACKEND, &be_data );
+}
+/* ========================== END OF FILE ===================== */

Added: gnucash/branches/gda-dev2/src/backend/gda/gnc-recurrence-gda.h
===================================================================
--- gnucash/branches/gda-dev2/src/backend/gda/gnc-recurrence-gda.h	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/backend/gda/gnc-recurrence-gda.h	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,43 @@
+/********************************************************************
+ * gnc-recurrence-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-recurrence-gda.h
+ *  @brief load and save accounts data to SQL via libgda
+ *  @author Copyright (c) 2006-2007 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_RECURRENCE_GDA_H_
+#define GNC_RECURRENCE_GDA_H_
+
+#include "qof.h"
+#include <gmodule.h>
+
+void gnc_gda_recurrence_save( GncGdaBackend* be, const GUID* guid, const Recurrence* pRecurrence );
+void gnc_gda_recurrence_save_list( GncGdaBackend* be, const GUID* guid, GList* schedule );
+void gnc_gda_recurrence_delete( GncGdaBackend* be, const GUID* guid );
+void gnc_gda_recurrence_load( GncGdaBackend* be, const GUID* guid, Recurrence* pRecurrence );
+void gnc_gda_recurrence_load_list( GncGdaBackend* be, const GUID* guid, GList** pSchedule );
+
+void gnc_gda_init_recurrence_handler( void );
+
+#endif /* GNC_RECURRENCE_GDA_H_ */

Added: gnucash/branches/gda-dev2/src/backend/gda/gnc-schedxaction-gda.c
===================================================================
--- gnucash/branches/gda-dev2/src/backend/gda/gnc-schedxaction-gda.c	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/backend/gda/gnc-schedxaction-gda.c	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,245 @@
+/********************************************************************
+ * gnc-schedxaction-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-schedxaction-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-backend-util-gda.h"
+
+#include "gnc-schedxaction-gda.h"
+#include "gnc-slots-gda.h"
+
+#include "SchedXaction.h"
+#include "SX-book.h"
+#include "Recurrence.h"
+
+#include "gnc-recurrence-gda.h"
+
+#define SCHEDXACTION_TABLE "schedxactions"
+
+static QofLogModule log_module = GNC_MOD_BACKEND;
+
+#define SX_MAX_NAME_LEN 50
+
+static gpointer get_autocreate( gpointer pObject, const QofParam* param );
+static void set_autocreate( gpointer pObject, gpointer pValue );
+static gpointer get_autonotify( gpointer pObject, const QofParam* param );
+static void set_autonotify( gpointer pObject, gpointer pValue );
+static gpointer get_template_act_guid( gpointer pObject, const QofParam* param );
+static void set_template_act_guid( gpointer pObject, gpointer pValue );
+
+static col_cvt_t col_table[] =
+{
+    { "guid",              CT_GUID,    0,               COL_NNUL, "guid" },
+    { "name",              CT_STRING,  SX_MAX_NAME_LEN, 0,        NULL, GNC_SX_NAME },
+    { "start_date",        CT_GDATE,   0,               COL_NNUL, NULL, GNC_SX_START_DATE },
+    { "last_occur",        CT_GDATE,   0,               0,        NULL, GNC_SX_LAST_DATE },
+    { "num_occur",         CT_INT,     0,               COL_NNUL, NULL, GNC_SX_NUM_OCCUR },
+    { "rem_occur",         CT_INT,     0,               COL_NNUL, NULL, GNC_SX_REM_OCCUR },
+    { "auto_create",       CT_BOOLEAN, 0,               COL_NNUL, NULL, NULL,        get_autocreate,        set_autocreate },
+    { "auto_notify",       CT_BOOLEAN, 0,               COL_NNUL, NULL, NULL,        get_autonotify,        set_autonotify },
+    { "adv_creation",      CT_INT,     0,               COL_NNUL, NULL, NULL,
+            (QofAccessFunc)xaccSchedXactionGetAdvanceCreation,
+            (QofSetterFunc)xaccSchedXactionSetAdvanceCreation },
+    { "adv_notify",        CT_INT,     0,               COL_NNUL, NULL, NULL,
+            (QofAccessFunc)xaccSchedXactionGetAdvanceReminder,
+            (QofSetterFunc)xaccSchedXactionSetAdvanceReminder },
+    { "template_act_guid", CT_GUID,    0,               COL_NNUL, NULL, NULL,        get_template_act_guid, set_template_act_guid },
+    { NULL }
+};
+
+/* ================================================================= */
+
+static gpointer
+get_autocreate( gpointer pObject, const QofParam* param )
+{
+    const SchedXaction* pSx = GNC_SX(pObject);
+    gboolean autoCreate;
+    gboolean autoNotify;
+
+    xaccSchedXactionGetAutoCreate( pSx, &autoCreate, &autoNotify );
+    return GINT_TO_POINTER(autoCreate);
+}
+
+static void 
+set_autocreate( gpointer pObject, gpointer pValue )
+{
+    SchedXaction* pSx = GNC_SX(pObject);
+    gboolean autoCreate;
+    gboolean autoNotify;
+
+    xaccSchedXactionGetAutoCreate( pSx, &autoCreate, &autoNotify );
+    autoCreate = GPOINTER_TO_INT(pValue);
+    xaccSchedXactionSetAutoCreate( pSx, autoCreate, autoNotify );
+}
+
+static gpointer
+get_autonotify( gpointer pObject, const QofParam* param )
+{
+    const SchedXaction* pSx = GNC_SX(pObject);
+    gboolean autoCreate;
+    gboolean autoNotify;
+
+    xaccSchedXactionGetAutoCreate( pSx, &autoCreate, &autoNotify );
+    return GINT_TO_POINTER(autoNotify);
+}
+
+static void 
+set_autonotify( gpointer pObject, gpointer pValue )
+{
+    SchedXaction* pSx = GNC_SX(pObject);
+    gboolean autoCreate;
+    gboolean autoNotify;
+
+    xaccSchedXactionGetAutoCreate( pSx, &autoCreate, &autoNotify );
+    autoNotify = GPOINTER_TO_INT(pValue);
+    xaccSchedXactionSetAutoCreate( pSx, autoCreate, autoNotify );
+}
+
+static gpointer
+get_template_act_guid( gpointer pObject, const QofParam* param )
+{
+    const SchedXaction* pSx = GNC_SX(pObject);
+
+    return (gpointer)xaccAccountGetGUID( pSx->template_acct );
+}
+
+static void 
+set_template_act_guid( gpointer pObject, gpointer pValue )
+{
+    SchedXaction* pSx = GNC_SX(pObject);
+    QofBook* pBook = qof_instance_get_book( QOF_INSTANCE(pSx) );
+    GUID* guid = (GUID*)pValue;
+	Account* pAcct;
+
+	pAcct = xaccAccountLookup( guid, pBook );
+	sx_set_template_account( pSx, pAcct );
+}
+
+/* ================================================================= */
+static SchedXaction*
+load_single_sx( GncGdaBackend* be, GdaDataModel* pModel, int row )
+{
+    const GUID* guid;
+    GUID sx_guid;
+	SchedXaction* pSx;
+	GList* schedule = NULL;
+
+    guid = gnc_gda_load_guid( be, pModel, row );
+    sx_guid = *guid;
+
+    pSx = xaccSchedXactionMalloc( be->primary_book );
+
+    gnc_gda_load_object( be, pModel, row, /*GNC_ID_SCHEDXACTION*/GNC_SX_ID, pSx, col_table );
+	gnc_gda_recurrence_load_list( be, guid, &schedule );
+	gnc_sx_set_schedule( pSx, schedule );
+    gnc_gda_slots_load( be, qof_instance_get_guid( QOF_INSTANCE(pSx) ),
+                            qof_instance_get_slots( QOF_INSTANCE(pSx) ) );
+
+    qof_instance_mark_clean( QOF_INSTANCE(pSx) );
+
+    return pSx;
+}
+
+static void
+load_all_sxes( GncGdaBackend* be )
+{
+    static GdaQuery* query;
+    GdaObject* ret;
+    QofBook* pBook = be->primary_book;
+
+    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;
+     	SchedXactions *sxes;
+     	sxes = gnc_book_get_schedxactions( be->primary_book );
+
+        for( r = 0; r < numRows; r++ ) {
+            SchedXaction* sx;
+			
+			sx = load_single_sx( be, pModel, r );
+		    gnc_sxes_add_sx(sxes, sx);
+        }
+    }
+}
+
+/* ================================================================= */
+static void
+create_sx_tables( GncGdaBackend* be )
+{
+    gnc_gda_create_table_if_needed( be, SCHEDXACTION_TABLE, col_table );
+}
+
+/* ================================================================= */
+void
+gnc_gda_save_schedxaction( GncGdaBackend* be, QofInstance* inst )
+{
+    SchedXaction* pSx = GNC_SX(inst);
+    const GUID* guid;
+
+    (void)gnc_gda_do_db_operation( be,
+                        (qof_instance_get_destroying(inst) ? OP_DB_DELETE : OP_DB_ADD_OR_UPDATE ),
+                        SCHEDXACTION_TABLE,
+                        /*GNC_ID_SCHEDXACTION*/GNC_SX_ID, pSx,
+                        col_table );
+	gnc_gda_recurrence_save_list( be, guid, gnc_sx_get_schedule( pSx ) );
+
+    // Now, commit any slots
+    guid = qof_instance_get_guid( inst );
+    if( !qof_instance_get_destroying(inst) ) {
+        gnc_gda_slots_save( be, guid, qof_instance_get_slots( inst ) );
+    } else {
+        gnc_gda_slots_delete( be, guid );
+    }
+}
+
+/* ================================================================= */
+void
+gnc_gda_init_schedxaction_handler( void )
+{
+    static GncGdaDataType_t be_data =
+    {
+        GNC_GDA_BACKEND_VERSION,
+        GNC_ID_SCHEDXACTION,
+        gnc_gda_save_schedxaction,                /* commit */
+        load_all_sxes,                /* initial_load */
+        create_sx_tables        /* create_tables */
+    };
+
+    qof_object_register_backend( GNC_ID_SCHEDXACTION, GNC_GDA_BACKEND, &be_data );
+}
+/* ========================== END OF FILE ===================== */

Added: gnucash/branches/gda-dev2/src/backend/gda/gnc-schedxaction-gda.h
===================================================================
--- gnucash/branches/gda-dev2/src/backend/gda/gnc-schedxaction-gda.h	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/backend/gda/gnc-schedxaction-gda.h	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,38 @@
+/********************************************************************
+ * gnc-schedxaction-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_SCHEDXACTION_GDA_H_
+#define GNC_SCHEDXACTION_GDA_H_
+
+#include "qof.h"
+#include <gmodule.h>
+
+void gnc_gda_init_schedxaction_handler( void );
+void gnc_gda_save_schedxaction( GncGdaBackend* be, QofInstance* inst );
+
+#endif /* GNC_SCHEDXACTION_GDA_H_ */

Added: gnucash/branches/gda-dev2/src/backend/gda/gnc-slots-gda.c
===================================================================
--- gnucash/branches/gda-dev2/src/backend/gda/gnc-slots-gda.c	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/backend/gda/gnc-slots-gda.c	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,455 @@
+/********************************************************************
+ * 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-util-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, const QofParam* param );
+static void set_slot_id( gpointer pObject, gpointer pValue );
+static gpointer get_obj_guid( gpointer pObject, const QofParam* param );
+static void set_obj_guid( gpointer pObject, gpointer pValue );
+static gpointer get_path( gpointer pObject, const QofParam* param );
+static void set_path( gpointer pObject, gpointer pValue );
+static gpointer get_slot_type( gpointer pObject, const QofParam* param );
+static void set_slot_type( gpointer pObject, gpointer pValue );
+static gpointer get_int64_val( gpointer pObject, const QofParam* param );
+static void set_int64_val( gpointer pObject, gpointer pValue );
+static gpointer get_string_val( gpointer pObject, const QofParam* param );
+static void set_string_val( gpointer pObject, gpointer pValue );
+static gpointer get_double_val( gpointer pObject, const QofParam* param );
+static void set_double_val( gpointer pObject, gpointer pValue );
+static gpointer get_timespec_val( gpointer pObject, const QofParam* param );
+static void set_timespec_val( gpointer pObject, gpointer pValue );
+static gpointer get_guid_val( gpointer pObject, const QofParam* param );
+static void set_guid_val( gpointer pObject, gpointer pValue );
+static gnc_numeric get_numeric_val( gpointer pObject, const QofParam* param );
+static void set_numeric_val( gpointer pObject, gnc_numeric value );
+
+#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_AUTOINC, NULL, NULL, get_slot_id,      set_slot_id },
+    { "obj_guid",     CT_GUID,     0,                     COL_NNUL,             NULL, NULL, get_obj_guid,     set_obj_guid },
+    { "name",         CT_STRING,   SLOT_MAX_PATHNAME_LEN, COL_NNUL,             NULL, NULL, get_path,         set_path },
+    { "slot_type",    CT_INT,      0,                     COL_NNUL,             NULL, NULL, get_slot_type,    set_slot_type, },
+    { "int64_val",    CT_INT64,    0,                     0,                    NULL, NULL, get_int64_val,    set_int64_val },
+    { "string_val",   CT_STRING,   SLOT_MAX_PATHNAME_LEN, 0,                    NULL, NULL, get_string_val,   set_string_val },
+    { "double_val",   CT_DOUBLE,   0,                     0,                    NULL, NULL, get_double_val,   set_double_val },
+    { "timespec_val", CT_TIMESPEC, 0,                     0,                    NULL, NULL, get_timespec_val, set_timespec_val },
+    { "guid_val",     CT_GUID,     0,                     0,                    NULL, NULL, get_guid_val,     set_guid_val },
+    { "numeric_val",  CT_NUMERIC,  0,                     0,                    NULL, NULL,
+			(QofAccessFunc)get_numeric_val, (QofSetterFunc)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, 0, NULL, NULL, get_obj_guid, set_obj_guid },
+    { NULL }
+};
+
+/* ================================================================= */
+
+static gpointer
+get_slot_id( gpointer pObject, const QofParam* param )
+{
+    // 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, const QofParam* param )
+{
+    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, const QofParam* param )
+{
+    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, const QofParam* param )
+{
+    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, const QofParam* param )
+{
+    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, gpointer pValue )
+{
+    slot_info_t* pInfo = (slot_info_t*)pObject;
+
+    if( pInfo->value_type == KVP_TYPE_GINT64 ) {
+        kvp_frame_set_gint64( pInfo->pKvpFrame, pInfo->path->str, *(gint64*)pValue );
+    }
+}
+
+static gpointer
+get_string_val( gpointer pObject, const QofParam* param )
+{
+    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, gpointer pValue )
+{
+    slot_info_t* pInfo = (slot_info_t*)pObject;
+
+    if( pInfo->value_type == KVP_TYPE_STRING ) {
+        kvp_frame_set_string( pInfo->pKvpFrame, pInfo->path->str, (const gchar*)pValue );
+    }
+}
+
+static gpointer
+get_double_val( gpointer pObject, const QofParam* param )
+{
+    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, gpointer pValue )
+{
+    slot_info_t* pInfo = (slot_info_t*)pObject;
+
+    if( pInfo->value_type == KVP_TYPE_DOUBLE ) {
+        kvp_frame_set_double( pInfo->pKvpFrame, pInfo->path->str, *(double*)pValue );
+    }
+}
+
+static gpointer
+get_timespec_val( gpointer pObject, const QofParam* param )
+{
+    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, gpointer pValue )
+{
+    slot_info_t* pInfo = (slot_info_t*)pObject;
+
+    if( pInfo->value_type == KVP_TYPE_TIMESPEC ) {
+        kvp_frame_set_timespec( pInfo->pKvpFrame, pInfo->path->str, *(Timespec*)pValue );
+    }
+}
+
+static gpointer
+get_guid_val( gpointer pObject, const QofParam* param )
+{
+    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, gpointer pValue )
+{
+    slot_info_t* pInfo = (slot_info_t*)pObject;
+
+    if( pInfo->value_type == KVP_TYPE_GUID ) {
+        kvp_frame_set_guid( pInfo->pKvpFrame, pInfo->path->str, (GUID*)pValue );
+    }
+}
+
+static gnc_numeric
+get_numeric_val( gpointer pObject, const QofParam* param )
+{
+    slot_info_t* pInfo = (slot_info_t*)pObject;
+
+    if( kvp_value_get_type( pInfo->pKvpValue ) == KVP_TYPE_NUMERIC ) {
+        return kvp_value_get_numeric( pInfo->pKvpValue );
+    } else {
+        return gnc_numeric_zero();
+    }
+}
+
+static void
+set_numeric_val( gpointer pObject, gnc_numeric value )
+{
+    slot_info_t* pInfo = (slot_info_t*)pObject;
+
+    if( pInfo->value_type == KVP_TYPE_NUMERIC ) {
+        kvp_frame_set_numeric( pInfo->pKvpFrame, pInfo->path->str, value );
+    }
+}
+
+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( be, 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-dev2/src/backend/gda/gnc-slots-gda.h
===================================================================
--- gnucash/branches/gda-dev2/src/backend/gda/gnc-slots-gda.h	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/backend/gda/gnc-slots-gda.h	2007-12-23 20:25:56 UTC (rev 16700)
@@ -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_ */

Added: gnucash/branches/gda-dev2/src/backend/gda/gnc-transaction-gda.c
===================================================================
--- gnucash/branches/gda-dev2/src/backend/gda/gnc-transaction-gda.c	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/backend/gda/gnc-transaction-gda.c	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,741 @@
+/********************************************************************
+ * gnc-transaction-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-transaction-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 "qofquery-p.h"
+#include "qofquerycore-p.h"
+
+#include "Account.h"
+#include "Transaction.h"
+
+#include "gnc-backend-util-gda.h"
+#include "gnc-transaction-gda.h"
+#include "gnc-commodity.h"
+#include "gnc-commodity-gda.h"
+#include "gnc-slots-gda.h"
+
+#include "gnc-engine.h"
+
+static QofLogModule log_module = GNC_MOD_BACKEND;
+
+#define TRANSACTION_TABLE "transactions"
+#define SPLIT_TABLE "splits"
+
+typedef struct {
+    GncGdaBackend* be;
+    const GUID* guid;
+} split_info_t;
+
+static gpointer get_tx_post_date( gpointer pObject, const QofParam* param );
+static void set_tx_post_date( gpointer pObject, gpointer pValue );
+static gpointer get_tx_enter_date( gpointer pObject, const QofParam* param );
+static void set_tx_enter_date( gpointer pObject, gpointer pValue );
+
+#define TX_MAX_NUM_LEN 50
+#define TX_MAX_DESCRIPTION_LEN 500
+
+static col_cvt_t tx_col_table[] =
+{
+    { "guid",          CT_GUID,           0,                      COL_NNUL, "guid" },
+    { "currency_guid", CT_COMMODITYREF,   0,                      COL_NNUL, NULL, NULL,
+			(QofAccessFunc)xaccTransGetCurrency, (QofSetterFunc)xaccTransSetCurrency },
+    { "num",           CT_STRING,         TX_MAX_NUM_LEN,         COL_NNUL, NULL, TRANS_NUM },
+    { "post_date",     CT_TIMESPEC,       0,                      COL_NNUL, NULL, NULL, get_tx_post_date,  set_tx_post_date },
+    { "enter_date",    CT_TIMESPEC,       0,                      COL_NNUL, NULL, NULL, get_tx_enter_date, set_tx_enter_date },
+    { "description",   CT_STRING,         TX_MAX_DESCRIPTION_LEN, 0,        NULL, NULL,
+            (QofAccessFunc)xaccTransGetDescription, (QofSetterFunc)xaccTransSetDescription },
+    { NULL }
+};
+
+static gpointer get_split_reconcile_state( gpointer pObject, const QofParam* param );
+static void set_split_reconcile_state( gpointer pObject, gpointer pValue );
+static gpointer get_split_reconcile_date( gpointer pObject, const QofParam* param );
+static void set_split_reconcile_date( gpointer pObject, gpointer pValue );
+
+#define SPLIT_MAX_MEMO_LEN 50
+#define SPLIT_MAX_ACTION_LEN 50
+
+static col_cvt_t split_col_table[] =
+{
+    { "guid",            CT_GUID,         0,                    COL_NNUL, "guid" },
+    { "tx_guid",         CT_TXREF,        0,                    COL_NNUL, NULL, SPLIT_TRANS },
+    { "account_guid",    CT_ACCOUNTREF,   0,                    COL_NNUL, NULL, SPLIT_ACCOUNT },
+    { "memo",            CT_STRING,       SPLIT_MAX_MEMO_LEN,   COL_NNUL, NULL, SPLIT_MEMO },
+    { "action",          CT_STRING,       SPLIT_MAX_ACTION_LEN, COL_NNUL, NULL, SPLIT_ACTION },
+    { "reconcile_state", CT_STRING,       1,                    COL_NNUL, NULL, NULL,    get_split_reconcile_state, set_split_reconcile_state },
+    { "reconcile_date",  CT_TIMESPEC,     0,                    COL_NNUL, NULL, NULL,    get_split_reconcile_date,  set_split_reconcile_date },
+    { "value",           CT_NUMERIC,      0,                    COL_NNUL, NULL, SPLIT_VALUE },
+    { "quantity",        CT_NUMERIC,      0,                    COL_NNUL, NULL, SPLIT_AMOUNT },
+    { NULL }
+};
+
+static col_cvt_t guid_col_table[] =
+{
+    { "tx_guid", CT_GUID, 0, 0, "guid" },
+    { NULL }
+};
+
+static void retrieve_numeric_value( gpointer pObject, gnc_numeric value );
+
+/* ================================================================= */
+
+static gpointer
+get_tx_post_date( gpointer pObject, const QofParam* param )
+{
+    const Transaction* pTx = GNC_TRANS(pObject);
+    static Timespec ts;
+
+    ts = xaccTransRetDatePostedTS( pTx );
+    return (gpointer)&ts;
+}
+
+static void 
+set_tx_post_date( gpointer pObject, gpointer pValue )
+{
+    Transaction* pTx = GNC_TRANS(pObject);
+    Timespec* pTS = (Timespec*)pValue;
+
+    xaccTransSetDatePostedTS( pTx, pTS );
+}
+
+static gpointer
+get_tx_enter_date( gpointer pObject, const QofParam* param )
+{
+    const Transaction* pTx = GNC_TRANS(pObject);
+    static Timespec ts;
+
+    ts = xaccTransRetDateEnteredTS( pTx );
+    return (gpointer)&ts;
+}
+
+static void 
+set_tx_enter_date( gpointer pObject, gpointer pValue )
+{
+    Transaction* pTx = GNC_TRANS(pObject);
+    Timespec* pTS = (Timespec*)pValue;
+
+    xaccTransSetDateEnteredTS( pTx, pTS );
+}
+
+static gpointer
+get_split_reconcile_state( gpointer pObject, const QofParam* param )
+{
+    const Split* pSplit = GNC_SPLIT(pObject);
+    static gchar c[2];
+
+    c[0] = xaccSplitGetReconcile( pSplit );
+    c[1] = '\0';
+    return (gpointer)c;
+}
+
+static void 
+set_split_reconcile_state( gpointer pObject, gpointer pValue )
+{
+    Split* pSplit = GNC_SPLIT(pObject);
+    const gchar* s = (const gchar*)pValue;
+
+    xaccSplitSetReconcile( pSplit, s[0] );
+}
+
+static gpointer
+get_split_reconcile_date( gpointer pObject, const QofParam* param )
+{
+    const Split* pSplit = GNC_SPLIT(pObject);
+    static Timespec ts;
+
+    ts = xaccSplitRetDateReconciledTS( pSplit );
+    return (gpointer)&ts;
+}
+
+static void 
+set_split_reconcile_date( gpointer pObject, gpointer pValue )
+{
+    Split* pSplit = GNC_SPLIT(pObject);
+    Timespec* pTS = (Timespec*)pValue;
+
+    xaccSplitSetDateReconciledTS( pSplit, pTS );
+}
+
+static void 
+retrieve_numeric_value( gpointer pObject, gnc_numeric value )
+{
+    gnc_numeric* pResult = (gnc_numeric*)pObject;
+    *pResult = value;
+}
+
+
+// Table to retrieve just the quantity
+static col_cvt_t quantity_table[] =
+{
+    { "quantity", CT_NUMERIC, 0, COL_NNUL, NULL, NULL, NULL, (QofSetterFunc)retrieve_numeric_value },
+    { NULL }
+};
+
+static gnc_numeric
+get_gnc_numeric_from_row( GncGdaBackend* be, GdaDataModel* model, int row )
+{
+	gnc_numeric val;
+
+    gnc_gda_load_object( be, model, row, NULL, &val, quantity_table );
+
+    return val;
+}
+
+/*
+ * get_account_balance_from_query
+ *
+ * Given a GDA query which should return a number of rows of gnc_numeric num/denom pairs,
+ * return the sum.
+ */
+static gnc_numeric
+get_account_balance_from_query( GncGdaBackend* be, GdaQuery* query )
+{
+	gnc_numeric bal = gnc_numeric_zero();
+    GdaObject* ret;
+
+	/* Execute the query */
+    ret = gnc_gda_execute_query( be, query );
+
+	/* Loop for all rows, convert each to a gnc_numeric and sum them */
+    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++ ) {
+		    gnc_numeric val = get_gnc_numeric_from_row( be, pModel, r );
+			bal = gnc_numeric_add( bal, val, GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD );
+		}
+	}
+
+    return bal;
+}
+
+void
+gnc_gda_get_account_balances( GncGdaBackend* be, Account* pAccount, 
+								    gnc_numeric* start_balance,
+								    gnc_numeric* cleared_balance,
+									gnc_numeric* reconciled_balance )
+{
+	GdaQuery* query;
+    gchar guid_buf[GUID_ENCODING_LENGTH+1];
+	gchar* sql;
+
+    guid_to_string_buff( qof_instance_get_guid( pAccount ), guid_buf );
+
+	/*
+	 * For start balance,
+	 *    SELECT SUM(QUANTITY_NUM),QUANTITY_DENOM FROM SPLITS
+	 *        WHERE ACCOUNT_GUID=<guid> GROUP BY QUANTITY_DENOM
+	 *
+	 * This will return one entry per denom.  These can then be made into
+	 * gnc_numerics and then added.  With luck, there will only be one entry.
+	 */
+
+	//sql = g_strdup_printf( "SELECT SUM(QUANTITY_NUM),QUANTITY_DENOM FROM %s WHERE ACCOUNT_GUID='%s' GROUP BY QUANTITY_DENOM", SPLIT_TABLE, guid_buf );
+	sql = g_strdup_printf( "SELECT QUANTITY_NUM,QUANTITY_DENOM FROM %s WHERE ACCOUNT_GUID='%s' GROUP BY QUANTITY_DENOM", SPLIT_TABLE, guid_buf );
+
+	/* Create the query */
+	query = gnc_gda_create_query_from_sql( be, sql );
+	*start_balance = get_account_balance_from_query( be, query );
+
+	g_free( sql );
+
+	/*
+	 * For cleared balance,
+	 *    SELECT SUM(QUANTITY_NUM),QUANTITY_DENOM FROM SPLITS
+	 *        WHERE ACCOUNT_GUID=<guid> AND RECONCILE_STATE='c'
+	 *        GROUP BY QUANTITY_DENOM
+	 *
+	 * This just requires a modification to the query
+	 */
+
+	//sql = g_strdup_printf( "SELECT SUM(QUANTITY_NUM),QUANTITY_DENOM FROM %s WHERE ACCOUNT_GUID='%s' AND RECONCILE_STATE='%c' GROUP BY QUANTITY_DENOM", SPLIT_TABLE, guid_buf, CREC );
+	sql = g_strdup_printf( "SELECT QUANTITY_NUM,QUANTITY_DENOM FROM %s WHERE ACCOUNT_GUID='%s' AND RECONCILE_STATE='%c' GROUP BY QUANTITY_DENOM", SPLIT_TABLE, guid_buf, CREC );
+
+	query = gnc_gda_create_query_from_sql( be, sql );
+    *cleared_balance = get_account_balance_from_query( be, query );
+
+	g_free( sql );
+
+	/*
+	 * For reconciled balance,
+	 *    SELECT SUM(QUANTITY_NUM),QUANTITY_DENOM FROM SPLITS
+	 *        WHERE ACCOUNT_GUID=<guid> AND RECONCILE_STATE='c'
+	 *        GROUP BY QUANTITY_DENOM
+	 *
+	 * This just requires a small modification to the cleared balance query
+	 */
+
+	//sql = g_strdup_printf( "SELECT SUM(QUANTITY_NUM),QUANTITY_DENOM FROM %s WHERE ACCOUNT_GUID='%s' AND RECONCILE_STATE='%c' GROUP BY QUANTITY_DENOM", SPLIT_TABLE, guid_buf, YREC );
+	sql = g_strdup_printf( "SELECT QUANTITY_NUM,QUANTITY_DENOM FROM %s WHERE ACCOUNT_GUID='%s' AND RECONCILE_STATE='%c' GROUP BY QUANTITY_DENOM", SPLIT_TABLE, guid_buf, YREC );
+
+	query = gnc_gda_create_query_from_sql( be, sql );
+	*reconciled_balance = get_account_balance_from_query( be, query );
+
+	g_free( sql );
+}
+
+static Split*
+load_single_split( GncGdaBackend* be, GdaDataModel* pModel, int row )
+{
+    const GUID* guid;
+    GUID split_guid;
+	Split* pSplit;
+
+    guid = gnc_gda_load_guid( be, pModel, row );
+    split_guid = *guid;
+
+    pSplit = xaccSplitLookup( &split_guid, be->primary_book );
+    if( pSplit == NULL ) {
+        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( be, 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) ) );
+
+    g_assert( pSplit == xaccSplitLookup( &split_guid, be->primary_book ) );
+
+    //qof_instance_mark_clean( QOF_INSTANCE(pSplit) );
+
+    return pSplit;
+}
+
+static void
+load_all_splits( GncGdaBackend* be, const GUID* tx_guid )
+{
+    GdaObject* ret;
+    gchar guid_buf[GUID_ENCODING_LENGTH+1];
+    GdaQuery* query;
+    GdaQueryCondition* cond;
+    GValue value;
+
+    guid_to_string_buff( tx_guid, guid_buf );
+    memset( &value, 0, sizeof( GValue ) );
+    g_value_init( &value, G_TYPE_STRING );
+    g_value_set_string( &value, guid_buf );
+    query = gnc_gda_create_select_query( be, SPLIT_TABLE );
+    cond = gnc_gda_create_condition_from_field( query, "tx_guid", &value );
+    gda_query_set_condition( query, cond );
+    g_object_unref( G_OBJECT(cond) );
+
+    ret = gnc_gda_execute_query( be, query );
+    g_object_unref( G_OBJECT(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++ ) {
+            load_single_split( be, pModel, r );
+        }
+    }
+}
+
+static Transaction*
+load_single_tx( GncGdaBackend* be, GdaDataModel* pModel, int row )
+{
+    const GUID* guid;
+    GUID tx_guid;
+	Transaction* pTx;
+
+    guid = gnc_gda_load_guid( be, pModel, row );
+    tx_guid = *guid;
+
+    pTx = xaccTransLookup( &tx_guid, be->primary_book );
+    if( pTx == NULL ) {
+        pTx = xaccMallocTransaction( be->primary_book );
+    }
+    xaccTransBeginEdit( pTx );
+    gnc_gda_load_object( be, pModel, row, GNC_ID_TRANS, pTx, tx_col_table );
+    gnc_gda_slots_load( be, qof_instance_get_guid( QOF_INSTANCE(pTx) ),
+                            qof_instance_get_slots( QOF_INSTANCE(pTx) ) );
+    load_all_splits( be, qof_instance_get_guid( QOF_INSTANCE(pTx) ) );
+
+    qof_instance_mark_clean( QOF_INSTANCE(pTx) );
+    xaccTransCommitEdit( pTx );
+
+    g_assert( pTx == xaccTransLookup( &tx_guid, be->primary_book ) );
+
+    return pTx;
+}
+
+static void
+query_transactions( GncGdaBackend* be, GdaQuery* query )
+{
+    GdaObject* ret;
+
+    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++ ) {
+            load_single_tx( be, pModel, r );
+        }
+    }
+}
+
+/* ================================================================= */
+static void
+create_transaction_tables( GncGdaBackend* be )
+{
+    gnc_gda_create_table_if_needed( be, TRANSACTION_TABLE, tx_col_table );
+    gnc_gda_create_table_if_needed( be, SPLIT_TABLE, split_col_table );
+}
+/* ================================================================= */
+static void
+delete_split_slots_cb( gpointer data, gpointer user_data )
+{
+    split_info_t* split_info = (split_info_t*)user_data;
+    Split* pSplit = GNC_SPLIT(data);
+
+    gnc_gda_slots_delete( split_info->be,
+                    qof_instance_get_guid( QOF_INSTANCE(pSplit) ) );
+}
+
+static void
+delete_splits( GncGdaBackend* be, Transaction* pTx )
+{
+    split_info_t split_info;
+
+    (void)gnc_gda_do_db_operation( be, OP_DB_DELETE, SPLIT_TABLE,
+                                SPLIT_TABLE, pTx, guid_col_table );
+    split_info.be = be;
+
+    g_list_foreach( xaccTransGetSplitList( pTx ), delete_split_slots_cb, &split_info );
+}
+
+static void
+commit_split( GncGdaBackend* be, QofInstance* inst )
+{
+    Split* pSplit = GNC_SPLIT(inst);
+
+    (void)gnc_gda_do_db_operation( be,
+                        (qof_instance_get_destroying(inst) ? 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);
+
+    commit_split( split_info->be, QOF_INSTANCE(pSplit) );
+}
+
+static void
+save_splits( GncGdaBackend* be, const GUID* tx_guid, SplitList* pSplitList )
+{
+    split_info_t split_info;
+
+    split_info.be = be;
+    split_info.guid = tx_guid;
+    g_list_foreach( pSplitList, save_split_cb, &split_info );
+}
+
+void
+gnc_gda_save_transaction( GncGdaBackend* be, QofInstance* inst )
+{
+    Transaction* pTx = GNC_TRANS(inst);
+    const GUID* guid;
+
+    // Ensure the commodity is in the db
+    gnc_gda_save_commodity( be, xaccTransGetCurrency( pTx ) );
+
+    (void)gnc_gda_do_db_operation( be,
+                        (qof_instance_get_destroying(inst) ? OP_DB_DELETE : OP_DB_ADD_OR_UPDATE ),
+                        TRANSACTION_TABLE,
+                        GNC_ID_TRANS, pTx,
+                        tx_col_table );
+
+    guid = qof_instance_get_guid( inst );
+
+    // Delete any old slots and splits for this transaction
+    delete_splits( be, pTx );
+
+    if( !qof_instance_get_destroying(inst) ) {
+        SplitList* splits;
+
+        // Now, commit any slots and splits
+        gnc_gda_slots_save( be, guid, qof_instance_get_slots( inst ) );
+        splits = xaccTransGetSplitList( pTx );
+        save_splits( be, guid, splits );
+
+        /* Mark the splits as clean */
+        splits = xaccTransGetSplitList( pTx );
+        for( ; splits != NULL; splits = splits->next ) {
+            QofInstance* inst = QOF_INSTANCE(splits->data);
+
+            qof_instance_mark_clean(inst);
+        }
+    } else {
+        gnc_gda_slots_delete( be, guid );
+    }
+}
+
+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 )
+{
+    GList* pOrTerms = qof_query_get_terms( pQuery );
+    GList* pAndTerms;
+    GList* andTerm;
+    QofQueryTerm* pTerm;
+    QofQueryPredData* pPredData;
+    GSList* pParamPath;
+
+    pAndTerms = (GList*)pOrTerms->data;
+    andTerm = pAndTerms->next;
+    pTerm = (QofQueryTerm*)andTerm->data;
+
+    pPredData = qof_query_term_get_pred_data( pTerm );
+    pParamPath = qof_query_term_get_param_path( pTerm );
+
+    if( strcmp( pPredData->type_name, "guid" ) == 0 ) {
+        query_guid_t pData = (query_guid_t)pPredData;
+        return pData->guids->data;
+    } else {
+        return NULL;
+    }
+}
+
+static gpointer
+compile_split_query( GncGdaBackend* be, QofQuery* pQuery )
+{
+    gchar* buf;
+    const GUID* acct_guid;
+    gchar guid_buf[GUID_ENCODING_LENGTH+1];
+	gchar* s;
+
+#if 1
+	GdaQuery* query;
+	GdaObject* results;
+
+    acct_guid = get_guid_from_query( pQuery );
+    guid_to_string_buff( acct_guid, guid_buf );
+	buf = g_strdup_printf( "SELECT DISTINCT tx_guid FROM %s WHERE account_guid='%s'", SPLIT_TABLE, guid_buf );
+	results = gnc_gda_execute_sql( be, buf );
+	g_free( buf );
+    if( GDA_IS_DATA_MODEL( results ) ) {
+        GdaDataModel* pModel = GDA_DATA_MODEL(results);
+        int numRows = gda_data_model_get_n_rows( pModel );
+        int r;
+
+		if( numRows != 1 ) {
+			buf = g_strdup_printf( "SELECT * FROM %s WHERE guid IN (", TRANSACTION_TABLE );
+		} else {
+			buf = g_strdup_printf( "SELECT * FROM %s WHERE guid =", TRANSACTION_TABLE );
+		}
+
+        for( r = 0; r < numRows; r++ ) {
+			const GUID* guid;
+
+			guid = gnc_gda_load_tx_guid( be, pModel, r );
+    		guid_to_string_buff( guid, guid_buf );
+			if( r == 0 ) {
+				s = g_strconcat( buf, "'", guid_buf, "'", NULL );
+			} else {
+				s = g_strconcat( buf, ",'", guid_buf, "'", NULL );
+			}
+			g_free( buf );
+			buf = s;
+        }
+
+		if( numRows != 1 ) {
+			s = g_strconcat( buf, ")", NULL );
+			g_free( buf );
+			buf = s;
+		}
+    }
+
+	return buf;
+#else
+#if 1
+    acct_guid = get_guid_from_query( pQuery );
+    guid_to_string_buff( acct_guid, guid_buf );
+    buf = g_strdup_printf( "SELECT * FROM %s WHERE guid IN (SELECT DISTINCT tx_guid FROM %s WHERE account_guid = '%s')",
+                            TRANSACTION_TABLE, SPLIT_TABLE, guid_buf );
+    return buf;
+#else
+    GdaQuery* query;
+    GdaQuery* subQuery;
+    GdaQueryTarget* target;
+    GdaQueryField* allFields;
+    GdaQueryField* field;
+    GValue value;
+    GdaQueryCondition* cond;
+    GdaQueryField* key;
+    GdaQueryField* key_value;
+
+    acct_guid = get_guid_from_query( pQuery );
+    guid_to_string_buff( acct_guid, guid_buf );
+
+    /* Subquery */
+
+    /* SELECT */
+    subQuery = gda_query_new( be->pDict );
+    gda_query_set_query_type( subQuery, GDA_QUERY_TYPE_SELECT );
+
+    /* FROM splits */
+    target = gda_query_target_new( subQuery, SPLIT_TABLE );
+    gda_query_add_target( subQuery, target, NULL );
+    g_object_unref( G_OBJECT(target) );
+
+    /* tx_guid */
+    field = gda_query_field_field_new( subQuery, "tx_guid" );
+    gda_query_field_set_visible( field, TRUE );
+    gda_entity_add_field( GDA_ENTITY(subQuery), GDA_ENTITY_FIELD(field) );
+    g_object_unref( G_OBJECT(field) );
+
+    /* WHERE */
+    memset( &value, 0, sizeof( GValue ) );
+    g_value_init( &value, G_TYPE_STRING );
+    g_value_set_string( &value, guid_buf );
+    cond = gnc_gda_create_condition_from_field( subQuery, "account_guid", &value );
+    gda_query_set_condition( subQuery, cond );
+    g_object_unref( G_OBJECT(cond) );
+
+    /* Main query */
+
+    /* SELECT * FROM transactions */
+    query = gnc_gda_create_select_query( be, TRANSACTION_TABLE );
+    gda_query_add_sub_query( query, subQuery );
+    g_object_unref( G_OBJECT(subQuery) );
+
+    /* WHERE */
+    cond = gda_query_condition_new( query, GDA_QUERY_CONDITION_LEAF_IN );
+    gda_query_set_condition( query, cond );
+    g_object_unref( G_OBJECT(cond) );
+
+    key = gda_query_field_field_new( query, "account_guid" );
+    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_field_value_set_is_parameter( GDA_QUERY_FIELD_VALUE(key_value), TRUE );
+
+    g_object_set( key_value, "value-provider", subQuery, NULL );
+    gda_query_condition_leaf_set_operator( cond, GDA_QUERY_CONDITION_OP_RIGHT,
+                                                GDA_QUERY_FIELD(key_value) );
+
+    return query;
+#endif
+#endif
+}
+
+static void
+run_split_query( GncGdaBackend* be, gpointer pQuery )
+{
+    GdaQuery* query;
+#if 1
+    const gchar* sql = (const gchar*)pQuery;
+
+	query = gnc_gda_create_query_from_sql( be, sql );
+#else
+    query = GDA_QUERY(pQuery);
+#endif
+    query_transactions( be, query );
+}
+
+static void
+free_split_query( GncGdaBackend* pBackend, gpointer pQuery )
+{
+#if 1
+    g_free( pQuery );
+#else
+    g_object_unref( G_OBJECT(pQuery) );
+#endif
+}
+
+/* ================================================================= */
+void
+gnc_gda_init_transaction_handler( void )
+{
+    static GncGdaDataType_t be_data_tx =
+    {
+        GNC_GDA_BACKEND_VERSION,
+        GNC_ID_TRANS,
+        gnc_gda_save_transaction,            /* commit */
+        NULL,                        /* initial_load */
+        create_transaction_tables    /* create tables */
+    };
+    static GncGdaDataType_t be_data_split =
+    {
+        GNC_GDA_BACKEND_VERSION,
+        GNC_ID_SPLIT,
+        commit_split,                /* commit */
+        NULL,                        /* initial_load */
+        NULL,                        /* create tables */
+        compile_split_query,
+        run_split_query,
+        free_split_query
+    };
+
+    qof_object_register_backend( GNC_ID_TRANS, GNC_GDA_BACKEND, &be_data_tx );
+    qof_object_register_backend( GNC_ID_SPLIT, GNC_GDA_BACKEND, &be_data_split );
+}
+
+/* ========================== END OF FILE ===================== */

Added: gnucash/branches/gda-dev2/src/backend/gda/gnc-transaction-gda.h
===================================================================
--- gnucash/branches/gda-dev2/src/backend/gda/gnc-transaction-gda.h	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/backend/gda/gnc-transaction-gda.h	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,43 @@
+/********************************************************************
+ * gnc-transaction-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-transaction-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_TRANSACTION_GDA_H_
+#define GNC_TRANSACTION_GDA_H_
+
+#include "qof.h"
+#include <gmodule.h>
+
+void gnc_gda_init_transaction_handler( void );
+void gnc_gda_transaction_commit_splits( GncGdaBackend* be, Transaction* pTx );
+void gnc_gda_save_transaction( GncGdaBackend* be, QofInstance* inst );
+void gnc_gda_get_account_balances( GncGdaBackend* be, Account* pAccount, 
+								    gnc_numeric* start_balance,
+								    gnc_numeric* cleared_balance,
+									gnc_numeric* reconciled_balance );
+
+#endif /* GNC_TRANSACTION_GDA_H_ */

Added: gnucash/branches/gda-dev2/src/backend/gda/gncmod-backend-gda.c
===================================================================
--- gnucash/branches/gda-dev2/src/backend/gda/gncmod-backend-gda.c	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/backend/gda/gncmod-backend-gda.c	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,63 @@
+/*********************************************************************
+ * gncmod-backend-gda.c
+ * module definition/initialization for the gda backend module
+ *
+ * Copyright (c) 2001 Linux Developers Group, Inc.
+ *********************************************************************/
+
+#include <stdio.h>
+#include <gmodule.h>
+/* #include <glib-gobject.h> */
+
+#include "gnc-module.h"
+#include "gnc-module-api.h"
+
+/* version of the gnc module system interface we require */
+int gnc_module_system_interface = 0;
+
+/* module versioning uses libtool semantics. */
+int gnc_module_current  = 0;
+int gnc_module_revision = 0;
+int gnc_module_age      = 0;
+
+static GNCModule engine;
+
+gchar *
+gnc_module_path(void)
+{
+  return g_strdup("gnucash/backend/gda");
+}
+
+gchar *
+gnc_module_description(void)
+{
+  return g_strdup("The GDA/SQL backend for GnuCash");
+}
+
+int
+gnc_module_init(int refcount)
+{
+  engine = gnc_module_load("gnucash/engine", 0);
+  if(!engine) return FALSE;
+
+  /* Need to initialize g-type engine for gconf */
+  if (refcount == 0) {
+    g_type_init();
+  }
+
+  return TRUE;
+}
+
+int
+gnc_module_end(int refcount)
+{
+  int unload = TRUE;
+
+  if (engine)
+    unload = gnc_module_unload(engine);
+
+  if (refcount == 0)
+    engine = NULL;
+
+  return unload;
+}

Added: gnucash/branches/gda-dev2/src/backend/gda/test/Makefile.am
===================================================================
--- gnucash/branches/gda-dev2/src/backend/gda/test/Makefile.am	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/backend/gda/test/Makefile.am	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,48 @@
+SUBDIRS = .
+
+TESTS = \
+  test-load-backend
+
+GNC_TEST_DEPS := \
+  --gnc-module-dir ${top_builddir}/src/engine \
+  --guile-load-dir ${top_builddir}/src/engine \
+  --library-dir    ${top_builddir}/lib/libqof/qof \
+  --library-dir    ${top_builddir}/src/core-utils \
+  --library-dir    ${top_builddir}/src/gnc-module \
+  --library-dir    ${top_builddir}/src/engine \
+  --library-dir    ${top_builddir}/src/backend/gda
+
+TESTS_ENVIRONMENT := \
+  GNC_ACCOUNT_PATH=${top_srcdir}/accounts/C \
+  SRCDIR=${srcdir} \
+  $(shell ${top_srcdir}/src/gnc-test-env --no-exports ${GNC_TEST_DEPS})
+
+check_PROGRAMS = \
+  test-load-backend
+
+#noinst_HEADERS = test-file-stuff.h
+
+LDADD = ${top_builddir}/src/test-core/libgncmod-test.la \
+        ${top_builddir}/src/gnc-module/libgnc-module.la \
+        ${top_builddir}/src/engine/libgncmod-engine.la \
+        ${top_builddir}/src/engine/test-core/libgncmod-test-engine.la \
+        ${top_builddir}/src/core-utils/libgnc-core-utils.la \
+        ${QOF_LIBS} \
+        ${top_builddir}/lib/libc/libc-missing.la
+
+AM_CFLAGS = \
+  -I${top_srcdir}/lib/libc \
+  -I${top_srcdir}/src \
+  -I${top_srcdir}/src/core-utils \
+  -I${top_srcdir}/src/gnc-module \
+  -I${top_srcdir}/src/test-core \
+  -I${top_srcdir}/src/engine \
+  -I${top_srcdir}/src/engine/test-core \
+  -I${top_srcdir}/src/backend/gda \
+  -I${top_srcdir}/src/backend/qsf \
+  ${GLIB_CFLAGS} \
+  ${QOF_CFLAGS} \
+  ${GUILE_INCS} \
+  ${GCONF_CFLAGS}
+
+INCLUDES = -DG_LOG_DOMAIN=\"gnc.backend.gda\"

Added: gnucash/branches/gda-dev2/src/backend/gda/test/test-load-backend.c
===================================================================
--- gnucash/branches/gda-dev2/src/backend/gda/test/test-load-backend.c	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/backend/gda/test/test-load-backend.c	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,45 @@
+/***************************************************************************
+ *            test-load-backend.c
+ *
+ *  Replaces the guile version to test the GModule file backend loading.
+ *
+ *  Sun Oct  9 18:58:47 2005
+ *  Copyright  2005  Neil Williams
+ *  linux at codehelp.co.uk
+ ****************************************************************************/
+
+/*
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ *  02110-1301, USA.
+ */
+ 
+#include "config.h"
+#include "qof.h"
+#include "cashobjects.h"
+#include "test-stuff.h"
+
+#define GNC_LIB_NAME "gncmod-backend-gda"
+
+int main (int argc, char ** argv)
+{
+    qof_init();
+    cashobjects_register();
+    do_test(
+        qof_load_backend_library ("../.libs/", GNC_LIB_NAME),
+        " loading gnc-backend-gda GModule failed");
+    print_test_results();
+    qof_close();
+    exit(get_rv());
+}

Copied: gnucash/branches/gda-dev2/src/backend/xml (from rev 16699, gnucash/branches/gda-dev2/src/backend/file)

Added: gnucash/branches/gda-dev2/src/business/business-core/gda/Makefile.am
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/gda/Makefile.am	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/business/business-core/gda/Makefile.am	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,54 @@
+SUBDIRS = .
+
+pkglib_LTLIBRARIES = libgncmod-business-backend-gda.la
+
+AM_CFLAGS = \
+  -I${top_srcdir}/src \
+  -I${top_srcdir}/src/backend \
+  -I${top_srcdir}/src/backend/gda \
+  -I${top_srcdir}/src/engine \
+  -I${top_srcdir}/src/gnc-module \
+  -I${top_srcdir}/src/business/business-core \
+  ${QOF_CFLAGS} \
+  ${GLIB_CFLAGS} \
+  ${LIBGDA_CFLAGS}
+
+libgncmod_business_backend_gda_la_SOURCES = \
+  gncmod-business-backend-gda.c \
+  gnc-address-gda.c \
+  gnc-bill-term-gda.c \
+  gnc-customer-gda.c \
+  gnc-employee-gda.c \
+  gnc-entry-gda.c \
+  gnc-invoice-gda.c \
+  gnc-job-gda.c \
+  gnc-order-gda.c \
+  gnc-vendor-gda.c
+
+#libgncmod_business_backend_gda_la_SOURCES = \
+#  gnc-owner-gda.c \
+#  gnc-tax-table-gda.c
+
+noinst_HEADERS = \
+  gnc-address-gda.h \
+  gnc-bill-term-gda.h \
+  gnc-customer-gda.h \
+  gnc-employee-gda.h \
+  gnc-entry-gda.h \
+  gnc-invoice-gda.h \
+  gnc-job-gda.h \
+  gnc-order-gda.h \
+  gnc-owner-gda.h \
+  gnc-tax-table-gda.h \
+  gnc-vendor-gda.h
+
+libgncmod_business_backend_gda_la_LDFLAGS = -module -avoid-version
+
+libgncmod_business_backend_gda_la_LIBADD = \
+  ${top_builddir}/src/business/business-core/libgncmod-business-core.la \
+  ${top_builddir}/src/backend/gda/libgnc-backend-gda-utils.la \
+  ${top_builddir}/src/engine/libgncmod-engine.la \
+  ${top_builddir}/src/gnc-module/libgnc-module.la \
+  ${QOF_LIBS} \
+  ${GLIB_LIBS} \
+  ${LIBGDA_LIBS}

Added: gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-address-gda.c
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-address-gda.c	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-address-gda.c	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,226 @@
+/********************************************************************\
+ * gnc-address-gda.c -- address gda backend implementation          *
+ *                                                                  *
+ * 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-address-gda.c
+ *  @brief load and save address data to SQL via libgda
+ *  @author Copyright (c) 2007 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
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libgda/libgda.h>
+
+#include "gnc-engine.h"
+#include "gnc-address-gda.h"
+
+#include "gnc-backend-util-gda.h"
+
+static QofLogModule log_module = GNC_MOD_BACKEND;
+
+#define ADDRESS_MAX_NAME_LEN 50
+#define ADDRESS_MAX_ADDRESS_LINE_LEN 50
+#define ADDRESS_MAX_PHONE_LEN 40
+#define ADDRESS_MAX_FAX_LEN 40
+#define ADDRESS_MAX_EMAIL_LEN 40
+
+static col_cvt_t col_table[] =
+{
+	{ "name",  CT_STRING, ADDRESS_MAX_NAME_LEN,         COL_NNUL, NULL, ADDRESS_NAME },
+	{ "addr1", CT_STRING, ADDRESS_MAX_ADDRESS_LINE_LEN, COL_NNUL, NULL, ADDRESS_ONE },
+	{ "addr2", CT_STRING, ADDRESS_MAX_ADDRESS_LINE_LEN, COL_NNUL, NULL, ADDRESS_TWO },
+	{ "addr3", CT_STRING, ADDRESS_MAX_ADDRESS_LINE_LEN, COL_NNUL, NULL, ADDRESS_THREE },
+	{ "addr4", CT_STRING, ADDRESS_MAX_ADDRESS_LINE_LEN, COL_NNUL, NULL, ADDRESS_FOUR },
+	{ "phone", CT_STRING, ADDRESS_MAX_PHONE_LEN,        COL_NNUL, NULL, ADDRESS_PHONE },
+	{ "fax",   CT_STRING, ADDRESS_MAX_FAX_LEN,          COL_NNUL, NULL, ADDRESS_FAX },
+	{ "email", CT_STRING, ADDRESS_MAX_EMAIL_LEN,        COL_NNUL, NULL, ADDRESS_EMAIL },
+	{ NULL }
+};
+
+typedef void (*AddressSetterFunc)( gpointer, GncAddress* );
+typedef GncAddress* (*AddressGetterFunc)( const gpointer );
+
+static void
+load_address( const GncGdaBackend* be, GdaDataModel* pModel, gint row,
+            QofSetterFunc setter, gpointer pObject,
+            const col_cvt_t* table )
+{
+    const GValue* val;
+    gchar* buf;
+    GncAddress* addr;
+	AddressSetterFunc a_setter = (AddressSetterFunc)setter;
+	const col_cvt_t* subtable;
+	const gchar* s;
+
+    addr = gncAddressCreate( be->primary_book, NULL );
+	for( subtable = col_table; subtable->col_name != NULL; subtable++ ) {
+    	buf = g_strdup_printf( "%s_%s", table->col_name, subtable->col_name );
+    	val = gda_data_model_get_value_at_col_name( pModel, buf, row );
+    	g_free( buf );
+    	if( gda_value_is_null( val ) ) {
+        	s = NULL;
+    	} else {
+        	s = g_value_get_string( val );
+    	}
+    	if( subtable->gobj_param_name != NULL ) {
+			g_object_set( addr, subtable->gobj_param_name, s, NULL );
+    	} else {
+	        if( subtable->param_name != NULL ) {
+            	setter = qof_class_get_parameter_setter( GNC_ID_ADDRESS, subtable->param_name );
+        	} else {
+            	setter = subtable->setter;
+        	}
+			(*setter)( addr, (const gpointer)s );
+    	}
+    }
+    (*a_setter)( pObject, addr );
+}
+
+static void
+get_gvalue_address( const GncGdaBackend* be, QofIdTypeConst obj_name, const gpointer pObject,
+                	const col_cvt_t* table_row, GValue* value )
+{
+    AddressGetterFunc getter;
+    GncAddress* addr;
+
+    memset( value, 0, sizeof( GValue ) );
+
+	getter = (AddressGetterFunc)gnc_gda_get_getter( obj_name, table_row );
+    addr = (*getter)( pObject );
+    g_value_init( value, gnc_address_get_type() );
+    g_value_set_object( value, addr );
+}
+
+static void
+get_gvalue_address_for_query( const GncGdaBackend* be, QofIdTypeConst obj_name,
+                			const gpointer pObject, const col_cvt_t* table_row, GdaQuery* query )
+{
+    GValue value;
+    GValue subfield_value;
+    GncAddress* addr;
+    gchar* s;
+    QofAccessFunc getter;
+	const col_cvt_t* subtable_row;
+	gchar* buf;
+
+    memset( &value, 0, sizeof( GValue ) );
+    get_gvalue_address( be, obj_name, pObject, table_row, &value );
+
+    if( G_VALUE_TYPE(&value) != 0 ) {
+        addr = g_value_get_object( &value );
+		for( subtable_row = col_table; subtable_row->col_name != NULL; subtable_row++ ) {
+    		buf = g_strdup_printf( "%s_%s", table_row->col_name, subtable_row->col_name );
+			
+    		memset( &subfield_value, 0, sizeof( GValue ) );
+			if( subtable_row->gobj_param_name != NULL ) {
+				g_object_get( addr, subtable_row->gobj_param_name, &s, NULL );
+			} else {
+    			getter = gnc_gda_get_getter( GNC_ID_ADDRESS, subtable_row );
+    			s = (gchar*)(*getter)( addr, NULL );
+			}
+    		if( s ) {
+        		g_value_init( &subfield_value, G_TYPE_STRING );
+        		g_value_set_string( &subfield_value, s );
+			}
+    		gnc_gda_add_field_to_query( query, buf, &subfield_value );
+			g_free( buf );
+		}
+    }
+}
+
+static GdaQueryCondition*
+get_gvalue_address_cond( const GncGdaBackend* be, QofIdTypeConst obj_name,
+                const gpointer pObject, const col_cvt_t* table_row, GdaQuery* query )
+{
+    GValue value;
+	GValue subfield_value;
+    GncAddress* addr;
+    gchar* buf;
+    GdaQueryCondition* sub_cond;
+    GdaQueryCondition* cond;
+	const col_cvt_t* subtable_row;
+	gchar* s;
+	QofAccessFunc getter;
+
+    memset( &value, 0, sizeof( GValue ) );
+    get_gvalue_address( be, obj_name, pObject, table_row, &value );
+
+    cond = gda_query_condition_new( query, GDA_QUERY_CONDITION_NODE_AND );
+    if( G_VALUE_TYPE(&value) != 0 ) {
+        addr = g_value_get_object( &value );
+		for( subtable_row = col_table; subtable_row->col_name != NULL; subtable_row++ ) {
+    		buf = g_strdup_printf( "%s_%s", table_row->col_name, subtable_row->col_name );
+			
+    		memset( &subfield_value, 0, sizeof( GValue ) );
+			if( subtable_row->gobj_param_name != NULL ) {
+				g_object_get( addr, subtable_row->gobj_param_name, &s, NULL );
+			} else {
+    			getter = gnc_gda_get_getter( GNC_ID_ADDRESS, subtable_row );
+    			s = (gchar*)(*getter)( addr, NULL );
+			}
+    		if( s ) {
+        		g_value_init( &subfield_value, G_TYPE_STRING );
+        		g_value_set_string( &subfield_value, s );
+			}
+    		sub_cond = gnc_gda_create_condition_from_field( query, buf, &subfield_value );
+    		gda_query_condition_node_add_child( cond, sub_cond, NULL );
+			g_free( buf );
+		}
+    }
+
+    return cond;
+}
+
+static void
+create_address_col( GdaServerProvider* server, GdaConnection* cnn,
+            xmlNodePtr array_data, const col_cvt_t* table_row, gboolean pkey )
+{
+    const gchar* dbms_type;
+    gchar* buf;
+	const col_cvt_t* subtable_row;
+
+    dbms_type = gda_server_provider_get_default_dbms_type( server, cnn,
+                                                            G_TYPE_STRING );
+	for( subtable_row = col_table; subtable_row->col_name != NULL; subtable_row++ ) {
+    	buf = g_strdup_printf( "%s_%s", table_row->col_name, subtable_row->col_name );
+    	gnc_gda_add_table_column( server, cnn, array_data, buf, dbms_type, subtable_row->size, subtable_row->flags );
+    	g_free( buf );
+    }
+}
+
+static col_type_handler_t address_handler =
+        { load_address, create_address_col,
+            get_gvalue_address_for_query, get_gvalue_address_cond };
+
+/* ================================================================= */
+void
+gnc_address_gda_initialize( void )
+{
+	gnc_gda_register_col_type_handler( CT_ADDRESS, &address_handler );
+}
+/* ========================== END OF FILE ===================== */

Added: gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-address-gda.h
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-address-gda.h	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-address-gda.h	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,38 @@
+/* gnc-address-gda.h -- Address GDA header
+ *
+ * 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-address-gda.h
+ *  @brief load and save address data to SQL via libgda
+ *  @author Copyright (c) 2007 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_ADDRESS_GDA_H
+#define GNC_ADDRESS_GDA_H
+
+#include "gncAddress.h"
+
+#define CT_ADDRESS "address"
+
+void gnc_address_gda_initialize( void );
+
+#endif /* GNC_ADDRESS_GDA_H */

Added: gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-bill-term-gda.c
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-bill-term-gda.c	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-bill-term-gda.c	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,205 @@
+/********************************************************************\
+ * gnc-bill-term-gda.c -- billing term gda backend                  *
+ *                                                                  *
+ * 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                   *
+ *                                                                  *
+\********************************************************************/
+
+#include "config.h"
+
+#include <glib.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libgda/libgda.h>
+
+#include "gnc-backend-util-gda.h"
+
+#include "gncBillTermP.h"
+#include "gncInvoice.h"
+#include "gnc-bill-term-gda.h"
+#include "qof.h"
+
+#define _GNC_MOD_NAME	GNC_ID_BILLTERM
+
+static QofLogModule log_module = GNC_MOD_BACKEND;
+
+#define MAX_NAME_LEN 50
+#define MAX_DESCRIPTION_LEN 50
+#define MAX_TYPE_LEN 50
+
+static void set_invisible( gpointer data, gpointer value );
+
+#define TABLE_NAME "billterms"
+
+static col_cvt_t col_table[] =
+{
+	{ "guid",         CT_GUID,        0,                   COL_NNUL, "guid" },
+	{ "name",         CT_STRING,      MAX_NAME_LEN,        COL_NNUL, NULL, GNC_BILLTERM_NAME },
+	{ "description",  CT_STRING,      MAX_DESCRIPTION_LEN, COL_NNUL, NULL, GNC_BILLTERM_DESC },
+	{ "refcount",     CT_INT,         0,                   COL_NNUL, NULL, GNC_BILLTERM_REFCOUNT },
+	{ "invisible",    CT_BOOLEAN,     0,                   COL_NNUL, NULL, NULL,
+			(QofAccessFunc)gncBillTermGetInvisible, (QofSetterFunc)set_invisible },
+	{ "parent",       CT_BILLTERMREF, 0,                   0,        NULL, NULL,
+			(QofAccessFunc)gncBillTermGetParent,    (QofSetterFunc)gncBillTermSetParent },
+	{ "child",        CT_BILLTERMREF, 0,                   0,        NULL, NULL,
+			(QofAccessFunc)gncBillTermReturnChild,  (QofSetterFunc)gncBillTermSetChild },
+	{ "type",         CT_STRING,      MAX_TYPE_LEN,        COL_NNUL, NULL, GNC_BILLTERM_TYPE },
+	{ "duedays",      CT_INT,         0,                   0,        0,    GNC_BILLTERM_DUEDAYS },
+	{ "discountdays", CT_INT,         0,                   0,        0,    GNC_BILLTERM_DISCDAYS },
+	{ "discount",     CT_NUMERIC,     0,                   0,        0,    GNC_BILLTERM_DISCOUNT },
+	{ "cutoff",       CT_INT,         0,                   0,        0,    GNC_BILLTERM_CUTOFF },
+	{ NULL }
+};
+
+static void
+set_invisible( gpointer data, gpointer value )
+{
+	GncBillTerm* term = GNC_BILLTERM(data);
+	gboolean b = GPOINTER_TO_INT(value);
+
+	if( b ) {
+		gncBillTermMakeInvisible( term );
+	}
+}
+
+static GncBillTerm*
+load_single_billterm( GncGdaBackend* be, GdaDataModel* pModel, int row )
+{
+    const GUID* guid;
+    GUID v_guid;
+	GncBillTerm* pBillTerm;
+
+    guid = gnc_gda_load_guid( be, pModel, row );
+    v_guid = *guid;
+
+    pBillTerm = gncBillTermLookup( be->primary_book, &v_guid );
+    if( pBillTerm == NULL ) {
+        pBillTerm = gncBillTermCreate( be->primary_book );
+    }
+    gnc_gda_load_object( be, pModel, row, GNC_ID_BILLTERM, pBillTerm, col_table );
+    gnc_gda_slots_load( be, qof_instance_get_guid( QOF_INSTANCE( pBillTerm )),
+                        qof_instance_get_slots( QOF_INSTANCE(pBillTerm) ) );
+
+    qof_instance_mark_clean( QOF_INSTANCE(pBillTerm) );
+
+    return pBillTerm;
+}
+
+static void
+load_all_billterms( GncGdaBackend* be )
+{
+    static GdaQuery* query = NULL;
+    GdaObject* ret;
+    QofBook* pBook = be->primary_book;
+
+    /* First time, create the query */
+    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;
+
+        for( r = 0; r < numRows; r++ ) {
+            (void)load_single_billterm( be, pModel, r );
+		}
+    }
+}
+
+/* ================================================================= */
+static void
+create_billterm_tables( GncGdaBackend* be )
+{
+    gnc_gda_create_table_if_needed( be, TABLE_NAME, col_table );
+}
+
+/* ================================================================= */
+void
+gnc_gda_save_billterm( GncGdaBackend* be, QofInstance* inst )
+{
+    GncBillTerm* v = GNC_BILLTERM(inst);
+    const GUID* guid;
+
+    (void)gnc_gda_do_db_operation( be,
+                        (qof_instance_get_destroying(inst) ? OP_DB_DELETE : OP_DB_ADD_OR_UPDATE ),
+                        TABLE_NAME,
+                        GNC_ID_BILLTERM, v,
+                        col_table );
+
+    // Now, commit or delete any slots
+    guid = qof_instance_get_guid( inst );
+    if( !qof_instance_get_destroying(inst) ) {
+        gnc_gda_slots_save( be, guid, qof_instance_get_slots( inst ) );
+    } else {
+        gnc_gda_slots_delete( be, guid );
+    }
+}
+
+/* ================================================================= */
+static void
+load_billterm_guid( const GncGdaBackend* be, GdaDataModel* pModel, gint row,
+            QofSetterFunc setter, gpointer pObject,
+            const col_cvt_t* table )
+{
+    const GValue* val;
+    GUID guid;
+    const GUID* pGuid;
+	GncBillTerm* term = NULL;
+
+    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;
+    }
+	if( pGuid != NULL ) {
+		term = gncBillTermLookup( be->primary_book, pGuid );
+	}
+    if( table->gobj_param_name != NULL ) {
+		g_object_set( pObject, table->gobj_param_name, term, NULL );
+    } else {
+		(*setter)( pObject, (const gpointer)term );
+    }
+}
+
+static col_type_handler_t billterm_guid_handler =
+        { load_billterm_guid, gnc_gda_create_objectref_guid_col,
+            gnc_gda_get_gvalue_objectref_guid_for_query, gnc_gda_get_gvalue_objectref_guid_cond };
+/* ================================================================= */
+void
+gnc_billterm_gda_initialize( void )
+{
+    static GncGdaDataType_t be_data =
+    {
+        GNC_GDA_BACKEND_VERSION,
+        GNC_ID_BILLTERM,
+        gnc_gda_save_billterm,				/* commit */
+        load_all_billterms,					/* initial_load */
+        create_billterm_tables				/* create_tables */
+    };
+
+    qof_object_register_backend( GNC_ID_BILLTERM, GNC_GDA_BACKEND, &be_data );
+
+	gnc_gda_register_col_type_handler( CT_BILLTERMREF, &billterm_guid_handler );
+}
+/* ========================== END OF FILE ===================== */

Added: gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-bill-term-gda.h
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-bill-term-gda.h	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-bill-term-gda.h	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,39 @@
+/*
+ * gnc-bill-term-gda.h -- billing term gda backend
+ *
+ * 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-bill-term-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_BILLTERM_GDA_H
+#define GNC_BILLTERM_GDA_H
+
+#include "gncBillTerm.h"
+
+#define CT_BILLTERMREF "billterm"
+
+void gnc_billterm_gda_initialize( void );
+
+#endif /* GNC_BILLTERM_GDA_H */

Added: gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-customer-gda.c
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-customer-gda.c	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-customer-gda.c	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,163 @@
+/********************************************************************\
+ * gnc-customer-gda.c -- customer gda backend                       *
+ *                                                                  *
+ * 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                   *
+ *                                                                  *
+\********************************************************************/
+
+#include "config.h"
+
+#include <glib.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libgda/libgda.h>
+
+#include "gnc-backend-util-gda.h"
+
+#include "gncBillTermP.h"
+#include "gncCustomerP.h"
+#include "gncTaxTableP.h"
+#include "gnc-customer-gda.h"
+#include "gnc-address-gda.h"
+#include "gnc-bill-term-gda.h"
+
+#define _GNC_MOD_NAME	GNC_ID_CUSTOMER
+
+static QofLogModule log_module = GNC_MOD_BACKEND;
+
+#define TABLE_NAME "customers"
+
+#define MAX_NAME_LEN 50
+#define MAX_ID_LEN 50
+#define MAX_NOTES_LEN 50
+
+static col_cvt_t col_table[] =
+{
+	{ "guid",         CT_GUID,          0,             COL_NNUL, "guid" },
+	{ "name",         CT_STRING,        MAX_NAME_LEN,  COL_NNUL, NULL, CUSTOMER_NAME },
+	{ "id",           CT_STRING,        MAX_ID_LEN,    COL_NNUL, NULL, CUSTOMER_ID },
+	{ "notes",        CT_STRING,        MAX_NOTES_LEN, COL_NNUL, NULL, CUSTOMER_NOTES },
+	{ "active",       CT_BOOLEAN,       0,             COL_NNUL, NULL, QOF_PARAM_ACTIVE },
+	{ "discount",     CT_NUMERIC,       0,             COL_NNUL, NULL, CUSTOMER_DISCOUNT },
+	{ "credit",       CT_NUMERIC,       0,             COL_NNUL, NULL, CUSTOMER_CREDIT },
+	{ "currency",     CT_COMMODITYREF,  0,             COL_NNUL, NULL, NULL,
+			(QofAccessFunc)gncCustomerGetCurrency, (QofSetterFunc)gncCustomerSetCurrency },
+	{ "tax_override", CT_BOOLEAN,       0,             COL_NNUL, NULL, CUSTOMER_TT_OVER },
+	{ "addr",         CT_ADDRESS,       0,             0,        NULL, CUSTOMER_ADDR },
+	{ "shipaddr",     CT_ADDRESS,       0,             0,        NULL, CUSTOMER_SHIPADDR },
+	{ "terms",        CT_BILLTERMREF,   0,             0,        NULL, CUSTOMER_TERMS },
+	{ "tax_included", CT_INT,           0,             0,        NULL, NULL,
+			(QofAccessFunc)gncCustomerGetTaxIncluded, (QofSetterFunc)gncCustomerSetTaxIncluded },
+	{ "taxtable",     CT_TAXTABLEREF,   0,             0,        NULL, NULL,
+			(QofAccessFunc)gncCustomerGetTaxTable, (QofSetterFunc)gncCustomerSetTaxTable },
+	{ NULL }
+};
+
+static GncCustomer*
+load_single_customer( GncGdaBackend* be, GdaDataModel* pModel, int row )
+{
+    const GUID* guid;
+    GUID customer_guid;
+	GncCustomer* pCustomer;
+
+    guid = gnc_gda_load_guid( be, pModel, row );
+    customer_guid = *guid;
+
+    pCustomer = gncCustomerLookup( be->primary_book, &customer_guid );
+    if( pCustomer == NULL ) {
+        pCustomer = gncCustomerCreate( be->primary_book );
+    }
+    gnc_gda_load_object( be, pModel, row, GNC_ID_CUSTOMER, pCustomer, col_table );
+    gnc_gda_slots_load( be, qof_instance_get_guid( QOF_INSTANCE( pCustomer )),
+                        qof_instance_get_slots( QOF_INSTANCE(pCustomer) ) );
+
+    qof_instance_mark_clean( QOF_INSTANCE(pCustomer) );
+
+    return pCustomer;
+}
+
+static void
+load_all_customers( GncGdaBackend* be )
+{
+    static GdaQuery* query = NULL;
+    GdaObject* ret;
+    QofBook* pBook = be->primary_book;
+
+    /* First time, create the query */
+    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;
+
+        for( r = 0; r < numRows; r++ ) {
+            (void)load_single_customer( be, pModel, r );
+		}
+    }
+}
+
+/* ================================================================= */
+static void
+create_customer_tables( GncGdaBackend* be )
+{
+    gnc_gda_create_table_if_needed( be, TABLE_NAME, col_table );
+}
+
+/* ================================================================= */
+void
+gnc_gda_save_customer( GncGdaBackend* be, QofInstance* inst )
+{
+    GncCustomer* customer = GNC_CUSTOMER(inst);
+    const GUID* guid;
+
+    (void)gnc_gda_do_db_operation( be,
+                        (qof_instance_get_destroying(inst) ? OP_DB_DELETE : OP_DB_ADD_OR_UPDATE ),
+                        TABLE_NAME,
+                        GNC_ID_CUSTOMER, customer,
+                        col_table );
+
+    // Now, commit or delete any slots
+    guid = qof_instance_get_guid( inst );
+    if( !qof_instance_get_destroying(inst) ) {
+        gnc_gda_slots_save( be, guid, qof_instance_get_slots( inst ) );
+    } else {
+        gnc_gda_slots_delete( be, guid );
+    }
+}
+
+/* ================================================================= */
+void
+gnc_customer_gda_initialize( void )
+{
+    static GncGdaDataType_t be_data =
+    {
+        GNC_GDA_BACKEND_VERSION,
+        GNC_ID_CUSTOMER,
+        gnc_gda_save_customer,				/* commit */
+        load_all_customers,					/* initial_load */
+        create_customer_tables				/* create_tables */
+    };
+
+    qof_object_register_backend( GNC_ID_CUSTOMER, GNC_GDA_BACKEND, &be_data );
+}
+/* ========================== END OF FILE ===================== */

Added: gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-customer-gda.h
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-customer-gda.h	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-customer-gda.h	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,35 @@
+/*
+ * gnc-customer-gda.h -- customer gda backend
+ *
+ * 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-customer-gda.h
+ *  @brief load and save customer data to SQL via libgda
+ *  @author Copyright (c) 2007 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_CUSTOMER_GDA_H
+#define GNC_CUSTOMER_GDA_H
+
+void gnc_customer_gda_initialize( void );
+
+#endif /* GNC_CUSTOMER_GDA_H */

Added: gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-employee-gda.c
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-employee-gda.c	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-employee-gda.c	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,163 @@
+/********************************************************************\
+ * gnc-employee-xml-v2.c -- employee xml i/o implementation         *
+ *                                                                  *
+ * Copyright (C) 2002 Derek Atkins <warlord at MIT.EDU>                *
+ *                                                                  *
+ * 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                   *
+ *                                                                  *
+\********************************************************************/
+
+#include "config.h"
+
+#include <glib.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libgda/libgda.h>
+
+#include "gncEmployeeP.h"
+#include "gnc-employee-gda.h"
+#include "gnc-address-gda.h"
+#include "gnc-commodity.h"
+
+#include "gnc-backend-util-gda.h"
+
+#define _GNC_MOD_NAME	GNC_ID_EMPLOYEE
+
+static QofLogModule log_module = GNC_MOD_BACKEND;
+
+#define MAX_USERNAME_LEN 50
+#define MAX_ID_LEN 50
+#define MAX_LANGUAGE_LEN 50
+#define MAX_ACL_LEN 50
+
+#define TABLE_NAME "employees"
+
+static col_cvt_t col_table[] =
+{
+	{ "guid",       CT_GUID,          0,                COL_NNUL, "guid" },
+	{ "username",   CT_STRING,        MAX_USERNAME_LEN, COL_NNUL, NULL, EMPLOYEE_USERNAME },
+	{ "id",         CT_STRING,        MAX_ID_LEN,       COL_NNUL, NULL, EMPLOYEE_ID },
+	{ "language",   CT_STRING,        MAX_LANGUAGE_LEN, COL_NNUL, NULL, EMPLOYEE_LANGUAGE },
+	{ "acl",        CT_STRING,        MAX_ACL_LEN,      COL_NNUL, NULL, EMPLOYEE_ACL },
+	{ "active",     CT_BOOLEAN,       0,                COL_NNUL, NULL, QOF_PARAM_ACTIVE },
+	{ "currency",   CT_COMMODITYREF,  0,                COL_NNUL, NULL, NULL,
+			(QofAccessFunc)gncEmployeeGetCurrency, (QofSetterFunc)gncEmployeeSetCurrency },
+	{ "ccard_guid", CT_ACCOUNTREF,    0,                COL_NNUL, NULL, EMPLOYEE_CC },
+	{ "workday",    CT_NUMERIC,       0,                COL_NNUL, NULL, EMPLOYEE_WORKDAY },
+	{ "rate",       CT_NUMERIC,       0,                COL_NNUL, NULL, EMPLOYEE_RATE },
+	{ "addr",       CT_ADDRESS,       0,                0,        NULL, EMPLOYEE_ADDR },
+    { NULL }
+};
+
+static GncEmployee*
+load_single_employee( GncGdaBackend* be, GdaDataModel* pModel, int row )
+{
+    const GUID* guid;
+    GUID emp_guid;
+	GncEmployee* pEmployee;
+
+    guid = gnc_gda_load_guid( be, pModel, row );
+    emp_guid = *guid;
+
+    pEmployee = gncEmployeeLookup( be->primary_book, &emp_guid );
+    if( pEmployee == NULL ) {
+        pEmployee = gncEmployeeCreate( be->primary_book );
+    }
+    gnc_gda_load_object( be, pModel, row, GNC_ID_EMPLOYEE, pEmployee, col_table );
+    gnc_gda_slots_load( be, qof_instance_get_guid( QOF_INSTANCE( pEmployee )),
+                        qof_instance_get_slots( QOF_INSTANCE(pEmployee) ) );
+
+    qof_instance_mark_clean( QOF_INSTANCE(pEmployee) );
+
+    return pEmployee;
+}
+
+static void
+load_all_employees( GncGdaBackend* be )
+{
+    static GdaQuery* query = NULL;
+    GdaObject* ret;
+    QofBook* pBook = be->primary_book;
+    gnc_commodity_table* pTable = gnc_commodity_table_get_table( pBook );
+
+    /* First time, create the query */
+    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;
+
+        for( r = 0; r < numRows; r++ ) {
+            (void)load_single_employee( be, pModel, r );
+		}
+    }
+}
+
+/* ================================================================= */
+static void
+create_employee_tables( GncGdaBackend* be )
+{
+    gnc_gda_create_table_if_needed( be, TABLE_NAME, col_table );
+}
+
+/* ================================================================= */
+void
+gnc_gda_save_employee( GncGdaBackend* be, QofInstance* inst )
+{
+    GncEmployee* emp = GNC_EMPLOYEE(inst);
+    const GUID* guid;
+
+    // Ensure the commodity is in the db
+    gnc_gda_save_commodity( be, gncEmployeeGetCurrency( emp ) );
+
+    (void)gnc_gda_do_db_operation( be,
+                        (qof_instance_get_destroying(inst) ? OP_DB_DELETE : OP_DB_ADD_OR_UPDATE ),
+                        TABLE_NAME,
+                        GNC_ID_EMPLOYEE, emp,
+                        col_table );
+
+    // Now, commit or delete any slots
+    guid = qof_instance_get_guid( inst );
+    if( !qof_instance_get_destroying(inst) ) {
+        gnc_gda_slots_save( be, guid, qof_instance_get_slots( inst ) );
+    } else {
+        gnc_gda_slots_delete( be, guid );
+    }
+}
+
+/* ================================================================= */
+void
+gnc_employee_gda_initialize( void )
+{
+    static GncGdaDataType_t be_data =
+    {
+        GNC_GDA_BACKEND_VERSION,
+        GNC_ID_EMPLOYEE,
+        gnc_gda_save_employee,				/* commit */
+        load_all_employees,					/* initial_load */
+        create_employee_tables				/* create_tables */
+    };
+
+    qof_object_register_backend( GNC_ID_EMPLOYEE, GNC_GDA_BACKEND, &be_data );
+}
+/* ========================== END OF FILE ===================== */

Added: gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-employee-gda.h
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-employee-gda.h	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-employee-gda.h	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,35 @@
+/*
+ * gnc-employee-gda.h -- employee gda backend
+ *
+ * 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-employee-gda.h
+ *  @brief load and save employee data to SQL via libgda
+ *  @author Copyright (c) 2007 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_EMPLOYEE_GDA_H
+#define GNC_EMPLOYEE_GDA_H
+
+void gnc_employee_gda_initialize( void );
+
+#endif /* GNC_EMPLOYEE_GDA_H */

Added: gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-entry-gda.c
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-entry-gda.c	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-entry-gda.c	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,220 @@
+/********************************************************************\
+ * gnc-entry-xml-v2.c -- entry xml i/o implementation         *
+ *                                                                  *
+ * Copyright (C) 2002 Derek Atkins <warlord at MIT.EDU>                *
+ *                                                                  *
+ * 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                   *
+ *                                                                  *
+\********************************************************************/
+
+#include "config.h"
+
+#include <glib.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libgda/libgda.h>
+
+#include "gnc-backend-util-gda.h"
+
+#include "gncEntryP.h"
+#include "gncOrderP.h"
+#include "gncInvoiceP.h"
+#include "gncTaxTableP.h"
+#include "gnc-entry-gda.h"
+#include "gnc-invoice-gda.h"
+#include "gnc-order-gda.h"
+#include "gnc-owner-gda.h"
+#include "gnc-tax-table-gda.h"
+
+#define _GNC_MOD_NAME	GNC_ID_ENTRY
+
+static QofLogModule log_module = GNC_MOD_BACKEND;
+
+static gpointer get_date( gpointer pObject, const QofParam* param );
+static void set_date( gpointer pObject, gpointer pValue );
+static gpointer get_date_entered( gpointer pObject, const QofParam* param );
+static void set_date_entered( gpointer pObject, gpointer pValue );
+
+#define TABLE_NAME "entries"
+#define MAX_DESCRIPTION_LEN 50
+#define MAX_ACTION_LEN 50
+#define MAX_NOTES_LEN 50
+#define MAX_DISCTYPE_LEN 50
+#define MAX_DISCHOW_LEN 50
+
+static col_cvt_t col_table[] =
+{
+	{ "guid",          CT_GUID,        0,                   COL_NNUL, "guid" },
+	{ "date",          CT_TIMESPEC,    0,                   COL_NNUL, NULL, NULL, get_date, set_date },
+	{ "entered",       CT_TIMESPEC,    0,                   COL_NNUL, NULL, NULL, get_date_entered, set_date_entered },
+	{ "description",   CT_STRING,      MAX_DESCRIPTION_LEN, 0,        NULL, ENTRY_DESC },
+	{ "action",        CT_STRING,      MAX_ACTION_LEN,      0,        NULL, ENTRY_ACTION },
+	{ "notes",         CT_STRING,      MAX_NOTES_LEN,       0,        NULL, ENTRY_NOTES },
+	{ "quantity",      CT_NUMERIC,     0,                   0,        NULL, ENTRY_QTY },
+	{ "i_acct",        CT_ACCOUNTREF,  0,                   0,        NULL, ENTRY_IACCT },
+	{ "i_price",       CT_NUMERIC,     0,                   0,        NULL, ENTRY_IPRICE },
+	{ "i_discount",    CT_NUMERIC,     0,                   0,        NULL, NULL, (QofAccessFunc)gncEntryGetInvDiscount, (QofSetterFunc)gncEntrySetInvDiscount },
+	{ "invoice",       CT_INVOICEREF,  0,                   0,        NULL, ENTRY_INVOICE },
+	{ "i_disc_type",   CT_STRING,      MAX_DISCTYPE_LEN,    0,        NULL, ENTRY_INV_DISC_TYPE },
+	{ "i_disc_how",    CT_STRING,      MAX_DISCHOW_LEN,     0,        NULL, ENTRY_INV_DISC_HOW },
+	{ "i_taxable",     CT_BOOLEAN,     0,                   0,        NULL, ENTRY_INV_TAXABLE },
+	{ "i_taxincluded", CT_BOOLEAN,     0,                   0,        NULL, ENTRY_INV_TAX_INC },
+	{ "i_taxtable",    CT_TAXTABLEREF, 0,                   0,        NULL, NULL, (QofAccessFunc)gncEntryGetInvTaxTable, (QofSetterFunc)gncEntrySetInvTaxTable },
+	{ "b_acct",        CT_ACCOUNTREF,  0,                   0,        NULL, ENTRY_BACCT },
+	{ "b_price",       CT_NUMERIC,     0,                   0,        NULL, ENTRY_BPRICE },
+	{ "bill",          CT_INVOICEREF,  0,                   0,        NULL, NULL, (QofAccessFunc)gncEntryGetBill, (QofSetterFunc)gncEntrySetBill },
+	{ "b_taxable",     CT_BOOLEAN,     0,                   0,        NULL, ENTRY_BILL_TAXABLE },
+	{ "b_taxincluded", CT_BOOLEAN,     0,                   0,        NULL, ENTRY_BILL_TAX_INC },
+	{ "b_taxtable",    CT_TAXTABLEREF, 0,                   0,        NULL, NULL, (QofAccessFunc)gncEntryGetBillTaxTable, (QofSetterFunc)gncEntrySetBillTaxTable },
+	{ "b_paytype",     CT_INT,         0,                   0,        NULL, NULL, (QofAccessFunc)gncEntryGetBillPayment, (QofSetterFunc)gncEntrySetBillPayment },
+	{ "billable",      CT_BOOLEAN,     0,                   0,        NULL, ENTRY_BILLABLE },
+	{ "billto",        CT_OWNERREF,    0,                   0,        NULL, ENTRY_BILLTO },
+	{ "order",         CT_ORDERREF,    0,                   0,        NULL, NULL, (QofAccessFunc)gncEntryGetOrder, (QofSetterFunc)gncEntrySetOrder },
+	{ NULL }
+};
+
+static gpointer
+get_date( gpointer pObject, const QofParam* param )
+{
+    const GncEntry* pEntry = GNC_ENTRY(pObject);
+    static Timespec ts;
+
+    ts = gncEntryGetDate( pEntry );
+    return (gpointer)&ts;
+}
+
+static void 
+set_date( gpointer pObject, gpointer pValue )
+{
+    GncEntry* pEntry = GNC_ENTRY(pObject);
+    Timespec* pTS = (Timespec*)pValue;
+
+    gncEntrySetDate( pEntry, *pTS );
+}
+
+static gpointer
+get_date_entered( gpointer pObject, const QofParam* param )
+{
+    const GncEntry* pEntry = GNC_ENTRY(pObject);
+    static Timespec ts;
+
+    ts = gncEntryGetDateEntered( pEntry );
+    return (gpointer)&ts;
+}
+
+static void 
+set_date_entered( gpointer pObject, gpointer pValue )
+{
+    GncEntry* pEntry = GNC_ENTRY(pObject);
+    Timespec* pTS = (Timespec*)pValue;
+
+    gncEntrySetDateEntered( pEntry, *pTS );
+}
+
+static GncEntry*
+load_single_entry( GncGdaBackend* be, GdaDataModel* pModel, int row )
+{
+    const GUID* guid;
+    GUID v_guid;
+	GncEntry* pEntry;
+
+    guid = gnc_gda_load_guid( be, pModel, row );
+    v_guid = *guid;
+
+    pEntry = gncEntryLookup( be->primary_book, &v_guid );
+    if( pEntry == NULL ) {
+        pEntry = gncEntryCreate( be->primary_book );
+    }
+    gnc_gda_load_object( be, pModel, row, GNC_ID_ENTRY, pEntry, col_table );
+    gnc_gda_slots_load( be, qof_instance_get_guid( QOF_INSTANCE( pEntry )),
+                        qof_instance_get_slots( QOF_INSTANCE(pEntry) ) );
+
+    qof_instance_mark_clean( QOF_INSTANCE(pEntry) );
+
+    return pEntry;
+}
+
+static void
+load_all_entries( GncGdaBackend* be )
+{
+    static GdaQuery* query = NULL;
+    GdaObject* ret;
+    QofBook* pBook = be->primary_book;
+
+    /* First time, create the query */
+    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;
+
+        for( r = 0; r < numRows; r++ ) {
+            (void)load_single_entry( be, pModel, r );
+		}
+    }
+}
+
+/* ================================================================= */
+static void
+create_entry_tables( GncGdaBackend* be )
+{
+    gnc_gda_create_table_if_needed( be, TABLE_NAME, col_table );
+}
+
+/* ================================================================= */
+void
+gnc_gda_save_entry( GncGdaBackend* be, QofInstance* inst )
+{
+    GncEntry* v = GNC_ENTRY(inst);
+    const GUID* guid;
+
+    (void)gnc_gda_do_db_operation( be,
+                        (qof_instance_get_destroying(inst) ? OP_DB_DELETE : OP_DB_ADD_OR_UPDATE ),
+                        TABLE_NAME,
+                        GNC_ID_ENTRY, v,
+                        col_table );
+
+    // Now, commit or delete any slots
+    guid = qof_instance_get_guid( inst );
+    if( !qof_instance_get_destroying(inst) ) {
+        gnc_gda_slots_save( be, guid, qof_instance_get_slots( inst ) );
+    } else {
+        gnc_gda_slots_delete( be, guid );
+    }
+}
+
+/* ================================================================= */
+void
+gnc_entry_gda_initialize( void )
+{
+    static GncGdaDataType_t be_data =
+    {
+        GNC_GDA_BACKEND_VERSION,
+        GNC_ID_ENTRY,
+        gnc_gda_save_entry,					/* commit */
+        load_all_entries,					/* initial_load */
+        create_entry_tables					/* create_tables */
+    };
+
+    qof_object_register_backend( GNC_ID_ENTRY, GNC_GDA_BACKEND, &be_data );
+}
+/* ========================== END OF FILE ===================== */

Added: gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-entry-gda.h
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-entry-gda.h	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-entry-gda.h	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,35 @@
+/*
+ * gnc-entry-gda.h -- entry gda backend
+ *
+ * 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-entry-gda.h
+ *  @brief load and save entry data to SQL via libgda
+ *  @author Copyright (c) 2007 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_ENTRY_GDA_H
+#define GNC_ENTRY_GDA_H
+
+void gnc_entry_gda_initialize( void );
+
+#endif /* GNC_ENTRY_GDA_H */

Added: gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-invoice-gda.c
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-invoice-gda.c	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-invoice-gda.c	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,235 @@
+/********************************************************************\
+ * gnc-invoice-gda.c - invoice gda backend                          *
+ *                                                                  *
+ * 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                   *
+ *                                                                  *
+\********************************************************************/
+
+#include "config.h"
+
+#include <glib.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libgda/libgda.h>
+
+#include "gnc-backend-util-gda.h"
+
+#include "gncBillTermP.h"
+#include "gncInvoiceP.h"
+#include "gnc-invoice-gda.h"
+#include "gnc-owner-gda.h"
+#include "gnc-bill-term-gda.h"
+
+#define _GNC_MOD_NAME	GNC_ID_INVOICE
+
+static QofLogModule log_module = GNC_MOD_BACKEND;
+
+#define TABLE_NAME "invoices"
+
+#define MAX_ID_LEN 50
+#define MAX_NOTES_LEN 100
+
+static col_cvt_t col_table[] =
+{
+	{ "guid",         CT_GUID,           0,             COL_NNUL, "guid" },
+	{ "id",           CT_STRING,         MAX_ID_LEN,    COL_NNUL, NULL, INVOICE_ID },
+	{ "date_opened",  CT_TIMESPEC,       0,             COL_NNUL, NULL, INVOICE_OPENED },
+	{ "date_posted",  CT_TIMESPEC,       0,             0,        NULL, INVOICE_POSTED },
+	{ "notes",        CT_STRING,         MAX_NOTES_LEN, COL_NNUL, NULL, INVOICE_NOTES },
+	{ "active",       CT_BOOLEAN,        0,             COL_NNUL, NULL, QOF_PARAM_ACTIVE },
+	{ "currency",     CT_COMMODITYREF,   0,             COL_NNUL, NULL, NULL,
+			(QofAccessFunc)gncInvoiceGetCurrency, (QofSetterFunc)gncInvoiceSetCurrency },
+	{ NULL }
+};
+
+#if 0
+/* ids */
+
+#define invoice_owner_string "invoice:owner"
+#define invoice_terms_string "invoice:terms"
+#define invoice_billing_id_string "invoice:billing_id"
+#define invoice_posttxn_string "invoice:posttxn"
+#define invoice_postlot_string "invoice:postlot"
+#define invoice_postacc_string "invoice:postacc"
+#define invoice_billto_string "invoice:billto"
+#define invoice_tochargeamt_string "invoice:charge-amt"
+
+    xmlAddChild(ret, gnc_owner_to_dom_tree (invoice_owner_string,
+					    gncInvoiceGetOwner (invoice)));
+
+    term = gncInvoiceGetTerms (invoice);
+    if (term)
+      xmlAddChild(ret, guid_to_dom_tree(invoice_terms_string,
+					qof_instance_get_guid (QOF_INSTANCE(term))));
+      
+    maybe_add_string (ret, invoice_billing_id_string,
+		      gncInvoiceGetBillingID (invoice));
+
+    txn = gncInvoiceGetPostedTxn (invoice);
+    if (txn)
+      xmlAddChild (ret, guid_to_dom_tree (invoice_posttxn_string,
+					  xaccTransGetGUID (txn)));
+
+    lot = gncInvoiceGetPostedLot (invoice);
+    if (lot)
+      xmlAddChild (ret, guid_to_dom_tree (invoice_postlot_string,
+					  gnc_lot_get_guid (lot)));
+
+    acc = gncInvoiceGetPostedAcc (invoice);
+    if (acc)
+      xmlAddChild (ret, guid_to_dom_tree (invoice_postacc_string,
+					  qof_instance_get_guid(QOF_INSTANCE(acc))));
+
+    billto = gncInvoiceGetBillTo (invoice);
+    if (billto && billto->owner.undefined != NULL)
+      xmlAddChild (ret, gnc_owner_to_dom_tree (invoice_billto_string, billto));
+
+    amt = gncInvoiceGetToChargeAmount (invoice);
+    if (! gnc_numeric_zero_p (amt))
+      xmlAddChild (ret, gnc_numeric_to_dom_tree (invoice_tochargeamt_string, &amt));
+#endif
+
+static GncInvoice*
+load_single_invoice( GncGdaBackend* be, GdaDataModel* pModel, int row )
+{
+    const GUID* guid;
+    GUID v_guid;
+	GncInvoice* pInvoice;
+
+    guid = gnc_gda_load_guid( be, pModel, row );
+    v_guid = *guid;
+
+    pInvoice = gncInvoiceLookup( be->primary_book, &v_guid );
+    if( pInvoice == NULL ) {
+        pInvoice = gncInvoiceCreate( be->primary_book );
+    }
+    gnc_gda_load_object( be, pModel, row, GNC_ID_INVOICE, pInvoice, col_table );
+    gnc_gda_slots_load( be, qof_instance_get_guid( QOF_INSTANCE( pInvoice )),
+                        qof_instance_get_slots( QOF_INSTANCE(pInvoice) ) );
+
+    qof_instance_mark_clean( QOF_INSTANCE(pInvoice) );
+
+    return pInvoice;
+}
+
+static void
+load_all_invoices( GncGdaBackend* be )
+{
+    static GdaQuery* query = NULL;
+    GdaObject* ret;
+    QofBook* pBook = be->primary_book;
+
+    /* First time, create the query */
+    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;
+
+        for( r = 0; r < numRows; r++ ) {
+            (void)load_single_invoice( be, pModel, r );
+		}
+    }
+}
+
+/* ================================================================= */
+static void
+create_invoice_tables( GncGdaBackend* be )
+{
+    gnc_gda_create_table_if_needed( be, TABLE_NAME, col_table );
+}
+
+/* ================================================================= */
+void
+gnc_gda_save_invoice( GncGdaBackend* be, QofInstance* inst )
+{
+    GncInvoice* v = GNC_INVOICE(inst);
+    const GUID* guid;
+
+    // Ensure the commodity is in the db
+    gnc_gda_save_commodity( be, gncInvoiceGetCurrency( v ) );
+
+    (void)gnc_gda_do_db_operation( be,
+                        (qof_instance_get_destroying(inst) ? OP_DB_DELETE : OP_DB_ADD_OR_UPDATE ),
+                        TABLE_NAME,
+                        GNC_ID_INVOICE, v,
+                        col_table );
+
+    // Now, commit or delete any slots
+    guid = qof_instance_get_guid( inst );
+    if( !qof_instance_get_destroying(inst) ) {
+        gnc_gda_slots_save( be, guid, qof_instance_get_slots( inst ) );
+    } else {
+        gnc_gda_slots_delete( be, guid );
+    }
+}
+
+/* ================================================================= */
+static void
+load_invoice_guid( const GncGdaBackend* be, GdaDataModel* pModel, gint row,
+            QofSetterFunc setter, gpointer pObject,
+            const col_cvt_t* table )
+{
+    const GValue* val;
+    GUID guid;
+    const GUID* pGuid;
+	GncInvoice* invoice = NULL;
+
+    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;
+    }
+	if( pGuid != NULL ) {
+		invoice = gncInvoiceLookup( be->primary_book, pGuid );
+	}
+    if( table->gobj_param_name != NULL ) {
+		g_object_set( pObject, table->gobj_param_name, invoice, NULL );
+    } else {
+		(*setter)( pObject, (const gpointer)invoice );
+    }
+}
+
+static col_type_handler_t invoice_guid_handler =
+        { load_invoice_guid, gnc_gda_create_objectref_guid_col,
+            gnc_gda_get_gvalue_objectref_guid_for_query, gnc_gda_get_gvalue_objectref_guid_cond };
+/* ================================================================= */
+void
+gnc_invoice_gda_initialize( void )
+{
+    static GncGdaDataType_t be_data =
+    {
+        GNC_GDA_BACKEND_VERSION,
+        GNC_ID_INVOICE,
+        gnc_gda_save_invoice,				/* commit */
+        load_all_invoices,					/* initial_load */
+        create_invoice_tables				/* create_tables */
+    };
+
+    qof_object_register_backend( GNC_ID_INVOICE, GNC_GDA_BACKEND, &be_data );
+
+	gnc_gda_register_col_type_handler( CT_INVOICEREF, &invoice_guid_handler );
+}
+/* ========================== END OF FILE ===================== */

Added: gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-invoice-gda.h
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-invoice-gda.h	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-invoice-gda.h	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,37 @@
+/*
+ * gnc-invoice-gda.h -- invoice gda backend
+ *
+ * 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-invoice-gda.h
+ *  @brief load and save invoice data to SQL via libgda
+ *  @author Copyright (c) 2007 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_INVOICE_GDA_H
+#define GNC_INVOICE_GDA_H
+
+#define CT_INVOICEREF "invoice"
+
+void gnc_invoice_gda_initialize( void );
+
+#endif /* GNC_INVOICE_GDA_H */

Added: gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-job-gda.c
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-job-gda.c	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-job-gda.c	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,156 @@
+/********************************************************************\
+ * gnc-job-gda.c -- job gda backend                                 *
+ *                                                                  *
+ * 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                   *
+ *                                                                  *
+\********************************************************************/
+
+#include "config.h"
+
+#include <glib.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libgda/libgda.h>
+
+#include "gnc-backend-util-gda.h"
+
+#include "gncJobP.h"
+#include "gnc-job-gda.h"
+#include "gnc-owner-gda.h"
+
+#define _GNC_MOD_NAME	GNC_ID_JOB
+
+static QofLogModule log_module = GNC_MOD_BACKEND;
+
+#define TABLE_NAME "jobs"
+
+#define MAX_ID_LEN 50
+#define MAX_NAME_LEN 50
+#define MAX_REFERENCE_LEN 50
+
+#if 0
+/* ids */
+#define job_owner_string "job:owner"
+
+    xmlAddChild(ret, gnc_owner_to_dom_tree (job_owner_string,
+					    gncJobGetOwner (job)));
+#endif
+
+static col_cvt_t col_table[] =
+{
+	{ "guid",         CT_GUID,    0,                 COL_NNUL, "guid" },
+	{ "id",           CT_STRING,  MAX_ID_LEN,        COL_NNUL, NULL, JOB_ID },
+	{ "name",         CT_STRING,  MAX_NAME_LEN,      COL_NNUL, NULL, JOB_NAME },
+	{ "reference",    CT_STRING,  MAX_REFERENCE_LEN, COL_NNUL, NULL, JOB_REFERENCE },
+	{ "active",       CT_BOOLEAN, 0,                 COL_NNUL, NULL, JOB_ACTIVE },
+	{ NULL }
+};
+
+static GncJob*
+load_single_job( GncGdaBackend* be, GdaDataModel* pModel, int row )
+{
+    const GUID* guid;
+    GUID job_guid;
+	GncJob* pJob;
+
+    guid = gnc_gda_load_guid( be, pModel, row );
+    job_guid = *guid;
+
+    pJob = gncJobLookup( be->primary_book, &job_guid );
+    if( pJob == NULL ) {
+        pJob = gncJobCreate( be->primary_book );
+    }
+    gnc_gda_load_object( be, pModel, row, GNC_ID_JOB, pJob, col_table );
+    gnc_gda_slots_load( be, qof_instance_get_guid( QOF_INSTANCE( pJob )),
+                        qof_instance_get_slots( QOF_INSTANCE(pJob) ) );
+
+    qof_instance_mark_clean( QOF_INSTANCE(pJob) );
+
+    return pJob;
+}
+
+static void
+load_all_jobs( GncGdaBackend* be )
+{
+    static GdaQuery* query = NULL;
+    GdaObject* ret;
+    QofBook* pBook = be->primary_book;
+
+    /* First time, create the query */
+    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;
+
+        for( r = 0; r < numRows; r++ ) {
+            (void)load_single_job( be, pModel, r );
+		}
+    }
+}
+
+/* ================================================================= */
+static void
+create_job_tables( GncGdaBackend* be )
+{
+    gnc_gda_create_table_if_needed( be, TABLE_NAME, col_table );
+}
+
+/* ================================================================= */
+void
+gnc_gda_save_job( GncGdaBackend* be, QofInstance* inst )
+{
+    GncJob* job = GNC_JOB(inst);
+    const GUID* guid;
+
+    (void)gnc_gda_do_db_operation( be,
+                        (qof_instance_get_destroying(inst) ? OP_DB_DELETE : OP_DB_ADD_OR_UPDATE ),
+                        TABLE_NAME,
+                        GNC_ID_JOB, job,
+                        col_table );
+
+    // Now, commit or delete any slots
+    guid = qof_instance_get_guid( inst );
+    if( !qof_instance_get_destroying(inst) ) {
+        gnc_gda_slots_save( be, guid, qof_instance_get_slots( inst ) );
+    } else {
+        gnc_gda_slots_delete( be, guid );
+    }
+}
+
+/* ================================================================= */
+void
+gnc_job_gda_initialize( void )
+{
+    static GncGdaDataType_t be_data =
+    {
+        GNC_GDA_BACKEND_VERSION,
+        GNC_ID_JOB,
+        gnc_gda_save_job,				/* commit */
+        load_all_jobs,					/* initial_load */
+        create_job_tables				/* create_tables */
+    };
+
+    qof_object_register_backend( GNC_ID_JOB, GNC_GDA_BACKEND, &be_data );
+}
+/* ========================== END OF FILE ===================== */

Added: gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-job-gda.h
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-job-gda.h	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-job-gda.h	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,35 @@
+/*
+ * gnc-job-gda.h -- job gda backend
+ *
+ * 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-job-gda.h
+ *  @brief load and save job data to SQL via libgda
+ *  @author Copyright (c) 2007 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_JOB_GDA_H
+#define GNC_JOB_GDA_H
+
+void gnc_job_gda_initialize( void );
+
+#endif /* GNC_JOB_GDA_H */

Added: gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-order-gda.c
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-order-gda.c	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-order-gda.c	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,192 @@
+/********************************************************************\
+ * gnc-order-gda.c -- order gda backend                             *
+ *                                                                  *
+ * 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                   *
+ *                                                                  *
+\********************************************************************/
+
+#include "config.h"
+
+#include <glib.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libgda/libgda.h>
+
+#include "gnc-backend-util-gda.h"
+
+#include "gncOrderP.h"
+
+#include "gnc-order-gda.h"
+#include "gnc-owner-gda.h"
+
+#define _GNC_MOD_NAME	GNC_ID_ORDER
+
+static QofLogModule log_module = GNC_MOD_BACKEND;
+
+#define TABLE_NAME "orders"
+
+#define MAX_ID_LEN 50
+#define MAX_NOTES_LEN 50
+#define MAX_REFERENCE_LEN 50
+
+static col_cvt_t col_table[] =
+{
+	{ "guid",        CT_GUID,     0,                 COL_NNUL, "guid" },
+	{ "id",          CT_STRING,   MAX_ID_LEN,        COL_NNUL, NULL, ORDER_ID },
+	{ "notes",       CT_STRING,   MAX_NOTES_LEN,     COL_NNUL, NULL, ORDER_NOTES },
+	{ "reference",   CT_STRING,   MAX_REFERENCE_LEN, COL_NNUL, NULL, ORDER_REFERENCE },
+	{ "active",      CT_BOOLEAN,  0,                 COL_NNUL, NULL, QOF_PARAM_ACTIVE },
+	{ "date_opened", CT_TIMESPEC, 0,                 COL_NNUL, NULL, ORDER_OPENED },
+	{ "date_closed", CT_TIMESPEC, 0,                 COL_NNUL, NULL, ORDER_CLOSED },
+	{ NULL },
+};
+
+#if 0
+/* ids */
+#define order_owner_string "order:owner"
+
+    xmlAddChild(ret, gnc_owner_to_dom_tree (order_owner_string,
+					    gncOrderGetOwner (order)));
+#endif
+
+static GncOrder*
+load_single_order( GncGdaBackend* be, GdaDataModel* pModel, int row )
+{
+    const GUID* guid;
+    GUID v_guid;
+	GncOrder* pOrder;
+
+    guid = gnc_gda_load_guid( be, pModel, row );
+    v_guid = *guid;
+
+    pOrder = gncOrderLookup( be->primary_book, &v_guid );
+    if( pOrder == NULL ) {
+        pOrder = gncOrderCreate( be->primary_book );
+    }
+    gnc_gda_load_object( be, pModel, row, GNC_ID_ORDER, pOrder, col_table );
+    gnc_gda_slots_load( be, qof_instance_get_guid( QOF_INSTANCE( pOrder )),
+                        qof_instance_get_slots( QOF_INSTANCE(pOrder) ) );
+
+    qof_instance_mark_clean( QOF_INSTANCE(pOrder) );
+
+    return pOrder;
+}
+
+static void
+load_all_orders( GncGdaBackend* be )
+{
+    static GdaQuery* query = NULL;
+    GdaObject* ret;
+    QofBook* pBook = be->primary_book;
+
+    /* First time, create the query */
+    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;
+
+        for( r = 0; r < numRows; r++ ) {
+            (void)load_single_order( be, pModel, r );
+		}
+    }
+}
+
+/* ================================================================= */
+static void
+create_order_tables( GncGdaBackend* be )
+{
+    gnc_gda_create_table_if_needed( be, TABLE_NAME, col_table );
+}
+
+/* ================================================================= */
+void
+gnc_gda_save_order( GncGdaBackend* be, QofInstance* inst )
+{
+    GncOrder* v = GNC_ORDER(inst);
+    const GUID* guid;
+
+    (void)gnc_gda_do_db_operation( be,
+                        (qof_instance_get_destroying(inst) ? OP_DB_DELETE : OP_DB_ADD_OR_UPDATE ),
+                        TABLE_NAME,
+                        GNC_ID_ORDER, v,
+                        col_table );
+
+    // Now, commit or delete any slots
+    guid = qof_instance_get_guid( inst );
+    if( !qof_instance_get_destroying(inst) ) {
+        gnc_gda_slots_save( be, guid, qof_instance_get_slots( inst ) );
+    } else {
+        gnc_gda_slots_delete( be, guid );
+    }
+}
+
+/* ================================================================= */
+static void
+load_order_guid( const GncGdaBackend* be, GdaDataModel* pModel, gint row,
+            QofSetterFunc setter, gpointer pObject,
+            const col_cvt_t* table )
+{
+    const GValue* val;
+    GUID guid;
+    const GUID* pGuid;
+	GncOrder* order = NULL;
+
+    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;
+    }
+	if( pGuid != NULL ) {
+		order = gncOrderLookup( be->primary_book, pGuid );
+	}
+    if( table->gobj_param_name != NULL ) {
+		g_object_set( pObject, table->gobj_param_name, order, NULL );
+    } else {
+		(*setter)( pObject, (const gpointer)order );
+    }
+}
+
+static col_type_handler_t order_guid_handler =
+        { load_order_guid, gnc_gda_create_objectref_guid_col,
+            gnc_gda_get_gvalue_objectref_guid_for_query, gnc_gda_get_gvalue_objectref_guid_cond };
+/* ================================================================= */
+void
+gnc_order_gda_initialize( void )
+{
+    static GncGdaDataType_t be_data =
+    {
+        GNC_GDA_BACKEND_VERSION,
+        GNC_ID_ORDER,
+        gnc_gda_save_order,				/* commit */
+        load_all_orders,				/* initial_load */
+        create_order_tables				/* create_tables */
+    };
+
+    qof_object_register_backend( GNC_ID_ORDER, GNC_GDA_BACKEND, &be_data );
+
+	gnc_gda_register_col_type_handler( CT_ORDERREF, &order_guid_handler );
+}
+/* ========================== END OF FILE ===================== */

Added: gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-order-gda.h
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-order-gda.h	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-order-gda.h	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,37 @@
+/*
+ * gnc-order-gda.h -- order gda backend
+ *
+ * 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-order-gda.h
+ *  @brief load and save order data to SQL via libgda
+ *  @author Copyright (c) 2007 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_ORDER_GDA_H
+#define GNC_ORDER_GDA_H
+
+#define CT_ORDERREF "order"
+
+void gnc_order_gda_initialize( void );
+
+#endif /* GNC_ORDER_GDA_H */

Added: gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-vendor-gda.c
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-vendor-gda.c	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-vendor-gda.c	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,185 @@
+/********************************************************************\
+ * gnc-vendor-gda.c -- vendor gda backend                           *
+ *                                                                  *
+ * Copyright (C) 2002 Derek Atkins <warlord at MIT.EDU>                *
+ *                                                                  *
+ * 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                   *
+ *                                                                  *
+\********************************************************************/
+
+#include "config.h"
+
+#include <glib.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libgda/libgda.h>
+
+#include "gnc-backend-util-gda.h"
+
+#include "gnc-commodity.h"
+#include "gncBillTermP.h"
+#include "gncVendorP.h"
+#include "gncTaxTableP.h"
+#include "gnc-vendor-gda.h"
+#include "gnc-address-gda.h"
+#include "gnc-bill-term-gda.h"
+
+#define _GNC_MOD_NAME	GNC_ID_VENDOR
+
+static QofLogModule log_module = GNC_MOD_BACKEND;
+
+#define MAX_NAME_LEN 50
+#define MAX_ID_LEN 50
+#define MAX_NOTES_LEN 100
+
+#define TABLE_NAME "vendors"
+
+static col_cvt_t col_table[] =
+{
+	{ "guid",         CT_GUID,          0,             COL_NNUL, "guid" },
+	{ "name",         CT_STRING,        MAX_NAME_LEN,  COL_NNUL, NULL, VENDOR_NAME },
+	{ "id",           CT_STRING,        MAX_ID_LEN,    COL_NNUL, NULL, VENDOR_ID },
+	{ "notes",        CT_STRING,        MAX_NOTES_LEN, COL_NNUL, NULL, VENDOR_NOTES },
+	{ "currency",     CT_COMMODITYREF,  0,             COL_NNUL, NULL, NULL,
+			(QofAccessFunc)gncVendorGetCurrency, (QofSetterFunc)gncVendorSetCurrency },
+	{ "active",       CT_BOOLEAN,       0,             COL_NNUL, NULL, NULL,
+			(QofAccessFunc)gncVendorGetActive, (QofSetterFunc)gncVendorSetActive },
+	{ "tax_override", CT_BOOLEAN,       0,             COL_NNUL, NULL, VENDOR_TAX_OVERRIDE },
+	{ "addr",         CT_ADDRESS,       0,             0,        NULL, VENDOR_ADDR },
+	{ NULL }
+};
+
+#if 0
+#define vendor_terms_string "vendor:terms"
+#define vendor_taxtable_string "vendor:taxtable"
+#define vendor_taxtableoverride_string "vendor:use-tt"
+
+    term = gncVendorGetTerms (vendor);
+    if (term)
+      xmlAddChild(ret, guid_to_dom_tree(vendor_terms_string,
+					qof_instance_get_guid(QOF_INSTANCE(term))));
+
+    xmlAddChild(ret, text_to_dom_tree(vendor_taxincluded_string,
+				      gncTaxIncludedTypeToString (
+				     gncVendorGetTaxIncluded (vendor))));
+
+    taxtable = gncVendorGetTaxTable (vendor);
+    if (taxtable)
+      xmlAddChild (ret, guid_to_dom_tree (vendor_taxtable_string,
+					  qof_instance_get_guid(QOF_INSTANCE(taxtable))));
+
+    return ret;
+}
+#endif
+
+static GncVendor*
+load_single_vendor( GncGdaBackend* be, GdaDataModel* pModel, int row )
+{
+    const GUID* guid;
+    GUID v_guid;
+	GncVendor* pVendor;
+
+    guid = gnc_gda_load_guid( be, pModel, row );
+    v_guid = *guid;
+
+    pVendor = gncVendorLookup( be->primary_book, &v_guid );
+    if( pVendor == NULL ) {
+        pVendor = gncVendorCreate( be->primary_book );
+    }
+    gnc_gda_load_object( be, pModel, row, GNC_ID_VENDOR, pVendor, col_table );
+    gnc_gda_slots_load( be, qof_instance_get_guid( QOF_INSTANCE( pVendor )),
+                        qof_instance_get_slots( QOF_INSTANCE(pVendor) ) );
+
+    qof_instance_mark_clean( QOF_INSTANCE(pVendor) );
+
+    return pVendor;
+}
+
+static void
+load_all_vendors( GncGdaBackend* be )
+{
+    static GdaQuery* query = NULL;
+    GdaObject* ret;
+    QofBook* pBook = be->primary_book;
+
+    /* First time, create the query */
+    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;
+
+        for( r = 0; r < numRows; r++ ) {
+            (void)load_single_vendor( be, pModel, r );
+		}
+    }
+}
+
+/* ================================================================= */
+static void
+create_vendor_tables( GncGdaBackend* be )
+{
+    gnc_gda_create_table_if_needed( be, TABLE_NAME, col_table );
+}
+
+/* ================================================================= */
+void
+gnc_gda_save_vendor( GncGdaBackend* be, QofInstance* inst )
+{
+    GncVendor* v = GNC_VENDOR(inst);
+    const GUID* guid;
+
+    // Ensure the commodity is in the db
+    gnc_gda_save_commodity( be, gncVendorGetCurrency( v ) );
+
+    (void)gnc_gda_do_db_operation( be,
+                        (qof_instance_get_destroying(inst) ? OP_DB_DELETE : OP_DB_ADD_OR_UPDATE ),
+                        TABLE_NAME,
+                        GNC_ID_VENDOR, v,
+                        col_table );
+
+    // Now, commit or delete any slots
+    guid = qof_instance_get_guid( inst );
+    if( !qof_instance_get_destroying(inst) ) {
+        gnc_gda_slots_save( be, guid, qof_instance_get_slots( inst ) );
+    } else {
+        gnc_gda_slots_delete( be, guid );
+    }
+}
+
+/* ================================================================= */
+void
+gnc_vendor_gda_initialize( void )
+{
+    static GncGdaDataType_t be_data =
+    {
+        GNC_GDA_BACKEND_VERSION,
+        GNC_ID_VENDOR,
+        gnc_gda_save_vendor,				/* commit */
+        load_all_vendors,					/* initial_load */
+        create_vendor_tables				/* create_tables */
+    };
+
+    qof_object_register_backend( GNC_ID_VENDOR, GNC_GDA_BACKEND, &be_data );
+}
+/* ========================== END OF FILE ===================== */

Added: gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-vendor-gda.h
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-vendor-gda.h	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-vendor-gda.h	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,35 @@
+/*
+ * gnc-vendor-gda.h -- vendor gda backend
+ *
+ * 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-vendor-gda.h
+ *  @brief load and save vendor data to SQL via libgda
+ *  @author Copyright (c) 2007 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_VENDOR_GDA_H
+#define GNC_VENDOR_GDA_H
+
+void gnc_vendor_gda_initialize( void );
+
+#endif /* GNC_VENDOR_GDA_H */

Added: gnucash/branches/gda-dev2/src/business/business-core/gda/gncmod-business-backend-gda.c
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/gda/gncmod-business-backend-gda.c	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/business/business-core/gda/gncmod-business-backend-gda.c	2007-12-23 20:25:56 UTC (rev 16700)
@@ -0,0 +1,110 @@
+/*********************************************************************
+ * gncmod-business-backend-gda.c
+ * module definition/initialization for the gda backend module
+ *
+ * Copyright (c) 2002 Derek Atkins <warlord at MIT.EDU>
+ *
+ * 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
+ *
+ *********************************************************************/
+
+#include "config.h"
+#include <gmodule.h>
+
+#include "gnc-module.h"
+#include "gnc-module-api.h"
+#include "gnc-engine.h"
+
+#include "gnc-address-gda.h"
+#include "gnc-bill-term-gda.h"
+#include "gnc-customer-gda.h"
+#include "gnc-employee-gda.h"
+#include "gnc-entry-gda.h"
+#include "gnc-invoice-gda.h"
+#include "gnc-job-gda.h"
+#include "gnc-order-gda.h"
+#include "gnc-owner-gda.h"
+#include "gnc-tax-table-gda.h"
+#include "gnc-vendor-gda.h"
+
+GNC_MODULE_API_DECL(libgncmod_business_backend_gda)
+
+/* version of the gnc module system interface we require */
+int libgncmod_business_backend_gda_gnc_module_system_interface = 0;
+
+/* module versioning uses libtool semantics. */
+int libgncmod_business_backend_gda_gnc_module_current  = 0;
+int libgncmod_business_backend_gda_gnc_module_revision = 0;
+int libgncmod_business_backend_gda_gnc_module_age      = 0;
+
+static GNCModule bus_core;
+
+
+gchar *
+libgncmod_business_backend_gda_gnc_module_path(void)
+{
+    return g_strdup( "gnucash/business-core-gda" );
+}
+
+gchar *
+libgncmod_business_backend_gda_gnc_module_description(void)
+{
+    return g_strdup( "The GDA backend for GnuCash business objects" );
+}
+
+int
+libgncmod_business_backend_gda_gnc_module_init(int refcount)
+{
+    if(!gnc_engine_is_initialized()) { return FALSE; }
+
+    bus_core = gnc_module_load( "gnucash/business-core", 0 );
+    if( !bus_core ) return FALSE;
+
+    if( refcount == 0 ) {
+        /* Initialize our pointers into the backend subsystem */
+        gnc_address_gda_initialize();
+        gnc_billterm_gda_initialize();
+        gnc_customer_gda_initialize();
+        gnc_employee_gda_initialize();
+//        gnc_entry_gda_initialize();
+        gnc_invoice_gda_initialize();
+        gnc_job_gda_initialize();
+        gnc_order_gda_initialize();
+//    gnc_owner_gda_initialize();
+//    gnc_taxtable_gda_initialize();
+        gnc_vendor_gda_initialize();
+    }
+
+    return TRUE;
+}
+
+int
+libgncmod_business_backend_gda_gnc_module_end(int refcount)
+{
+    int unload = TRUE;
+
+    if( bus_core ) {
+        unload = gnc_module_unload( bus_core );
+	}
+
+    if( refcount == 0 ) {
+        bus_core = NULL;
+    }
+
+    return unload;
+}

Copied: gnucash/branches/gda-dev2/src/business/business-core/xml (from rev 16699, gnucash/branches/gda-dev2/src/business/business-core/file)



More information about the gnucash-changes mailing list