r16708 - gnucash/branches/gda-dev2/src - Implement GncOwner backend and basic tax table references in other

Phil Longstaff plongstaff at cvs.gnucash.org
Sun Dec 23 18:37:45 EST 2007


Author: plongstaff
Date: 2007-12-23 18:37:45 -0500 (Sun, 23 Dec 2007)
New Revision: 16708
Trac: http://svn.gnucash.org/trac/changeset/16708

Added:
   gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-owner-gda.c
   gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-owner-gda.h
   gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-tax-table-gda.c
   gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-tax-table-gda.h
Modified:
   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/business/business-core/gda/Makefile.am
   gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-invoice-gda.c
   gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-job-gda.c
   gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-order-gda.c
   gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-vendor-gda.c
   gnucash/branches/gda-dev2/src/business/business-core/gda/gncmod-business-backend-gda.c
Log:
Implement GncOwner backend and basic tax table references in other
tables.  Still need to implement tax table backend.


Modified: gnucash/branches/gda-dev2/src/backend/gda/gnc-backend-util-gda.c
===================================================================
--- gnucash/branches/gda-dev2/src/backend/gda/gnc-backend-util-gda.c	2007-12-23 21:49:37 UTC (rev 16707)
+++ gnucash/branches/gda-dev2/src/backend/gda/gnc-backend-util-gda.c	2007-12-23 23:37:45 UTC (rev 16708)
@@ -39,6 +39,7 @@
 #include "gnc-engine.h"
 
 #include "gnc-commodity.h"
+#include "gnc-lot.h"
 
 #include "gnc-backend-util-gda.h"
 #include "gnc-gconf-utils.h"
@@ -710,7 +711,38 @@
         { 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_lot_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;
+	GNCLot* lot = 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 ) {
+		lot = gnc_lot_lookup( pGuid, be->primary_book );
+	}
+    if( table->gobj_param_name != NULL ) {
+		g_object_set( pObject, table->gobj_param_name, lot, NULL );
+    } else {
+		(*setter)( pObject, (const gpointer)lot );
+    }
+}
+
+static col_type_handler_t lot_guid_handler =
+        { load_lot_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,
@@ -1123,12 +1155,14 @@
     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_TIMESPEC, &timespec_handler );
+    gnc_gda_register_col_type_handler( CT_GDATE, &date_handler );
+    gnc_gda_register_col_type_handler( CT_NUMERIC, &numeric_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_LOTREF, &lot_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 );
@@ -1555,7 +1589,6 @@
             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 );
         }
         

Modified: gnucash/branches/gda-dev2/src/backend/gda/gnc-backend-util-gda.h
===================================================================
--- gnucash/branches/gda-dev2/src/backend/gda/gnc-backend-util-gda.h	2007-12-23 21:49:37 UTC (rev 16707)
+++ gnucash/branches/gda-dev2/src/backend/gda/gnc-backend-util-gda.h	2007-12-23 23:37:45 UTC (rev 16708)
@@ -83,6 +83,7 @@
 #define CT_ACCOUNTREF "ct_accountref"
 #define CT_COMMODITYREF "ct_commodityref"
 #define CT_TXREF "ct_txref"
+#define CT_LOTREF "ct_lotref"
 
 typedef struct {
 	const gchar* col_name;

Modified: gnucash/branches/gda-dev2/src/business/business-core/gda/Makefile.am
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/gda/Makefile.am	2007-12-23 21:49:37 UTC (rev 16707)
+++ gnucash/branches/gda-dev2/src/business/business-core/gda/Makefile.am	2007-12-23 23:37:45 UTC (rev 16708)
@@ -23,12 +23,10 @@
   gnc-invoice-gda.c \
   gnc-job-gda.c \
   gnc-order-gda.c \
+  gnc-owner-gda.c \
+  gnc-tax-table-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 \

Modified: 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	2007-12-23 21:49:37 UTC (rev 16707)
+++ gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-invoice-gda.c	2007-12-23 23:37:45 UTC (rev 16708)
@@ -44,67 +44,32 @@
 
 #define MAX_ID_LEN 50
 #define MAX_NOTES_LEN 100
+#define MAX_BILLING_ID_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,
+	{ "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 },
+	{ "owner",        CT_OWNERREF,     0,                  0,        NULL, NULL,
+			(QofAccessFunc)gncInvoiceGetOwner, (QofSetterFunc)gncInvoiceSetOwner },
+	{ "terms",        CT_BILLTERMREF,  0,                  0,        NULL, INVOICE_TERMS },
+	{ "billing_id",   CT_STRING,       MAX_BILLING_ID_LEN, 0,        NULL, INVOICE_BILLINGID },
+	{ "post_txn",     CT_TXREF,        0,                  0,        NULL, INVOICE_POST_TXN },
+	{ "post_lot",     CT_LOTREF,       0,                  0,        NULL, NULL,
+			(QofAccessFunc)gncInvoiceGetPostedLot, (QofSetterFunc)gncInvoiceSetPostedLot },
+	{ "post_acc",     CT_ACCOUNTREF,   0,                  0,        NULL, INVOICE_ACC },
+	{ "billto",       CT_OWNERREF,     0,                  0,        NULL, INVOICE_BILLTO },
+	{ "charge_amt",   CT_NUMERIC,      0,                  0,        NULL, NULL,
+			(QofAccessFunc)gncInvoiceGetToChargeAmount, (QofSetterFunc)gncInvoiceSetToChargeAmount },
 	{ 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 )
 {

Modified: 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	2007-12-23 21:49:37 UTC (rev 16707)
+++ gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-job-gda.c	2007-12-23 23:37:45 UTC (rev 16708)
@@ -44,21 +44,14 @@
 #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 },
+	{ "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 },
+	{ "owner",     CT_OWNERREF, 0,                 COL_NNUL, NULL, JOB_OWNER },
 	{ NULL }
 };
 

Modified: 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	2007-12-23 21:49:37 UTC (rev 16707)
+++ gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-order-gda.c	2007-12-23 23:37:45 UTC (rev 16708)
@@ -54,17 +54,10 @@
 	{ "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 },
+	{ "owner",       CT_OWNERREF, 0,                 COL_NNUL, NULL, ORDER_OWNER },
 	{ 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 )
 {

Added: gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-owner-gda.c
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-owner-gda.c	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-owner-gda.c	2007-12-23 23:37:45 UTC (rev 16708)
@@ -0,0 +1,299 @@
+/********************************************************************\
+ * gnc-owner-xml-v2.c -- owner 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 "gnc-owner-gda.h"
+#include "gncCustomerP.h"
+#include "gncJobP.h"
+#include "gncEmployeeP.h"
+#include "gncVendorP.h"
+
+static QofLogModule log_module = GNC_MOD_BACKEND;
+
+typedef void (*OwnerSetterFunc)( gpointer, GncOwner* );
+typedef GncOwner* (*OwnerGetterFunc)( const gpointer );
+
+static void
+load_owner( const GncGdaBackend* be, GdaDataModel* pModel, gint row,
+            QofSetterFunc setter, gpointer pObject,
+            const col_cvt_t* table )
+{
+    const GValue* val;
+    gchar* buf;
+	GncOwnerType type;
+    GUID guid;
+	QofBook* book = be->primary_book;
+	GncOwner owner;
+
+    buf = g_strdup_printf( "%s_type", table->col_name );
+    val = gda_data_model_get_value_at_col_name( pModel, buf, row );
+	type = (GncOwnerType)g_value_get_int( val );
+    g_free( buf );
+    buf = g_strdup_printf( "%s_guid", table->col_name );
+    val = gda_data_model_get_value_at_col_name( pModel, buf, row );
+    g_free( buf );
+
+    val = gda_data_model_get_value_at_col_name( pModel, table->col_name, row );
+    if( !gda_value_is_null( val ) ) {
+        string_to_guid( g_value_get_string( val ), &guid );
+    }
+
+    switch( type ) {
+  	case GNC_OWNER_CUSTOMER:
+  		{
+    		GncCustomer *cust = gncCustomerLookup( book, &guid );
+    		if( cust == NULL ) {
+      			cust = gncCustomerCreate( book );
+      			gncCustomerSetGUID( cust, &guid );
+    		}
+    		gncOwnerInitCustomer( &owner, cust );
+    		break; 
+  		}
+
+  	case GNC_OWNER_JOB:
+  		{
+    		GncJob *job = gncJobLookup( book, &guid );
+    		if( job == NULL ) {
+      			job = gncJobCreate( book );
+      			gncJobSetGUID( job, &guid );
+    		}
+    		gncOwnerInitJob( &owner, job );
+    		break; 
+  		}
+
+  	case GNC_OWNER_VENDOR:
+  		{
+    		GncVendor *vendor = gncVendorLookup( book, &guid );
+    		if( vendor == NULL ) {
+      			vendor = gncVendorCreate( book );
+    		  	gncVendorSetGUID( vendor, &guid );
+    		}
+    		gncOwnerInitVendor( &owner, vendor );
+    		break; 
+  		}
+
+  	case GNC_OWNER_EMPLOYEE:
+  		{
+    		GncEmployee *employee = gncEmployeeLookup( book, &guid );
+    		if( employee == NULL ) {
+      			employee = gncEmployeeCreate( book );
+      			gncEmployeeSetGUID( employee, &guid );
+    		}
+    		gncOwnerInitEmployee( &owner, employee );
+    		break; 
+  		}
+
+  	default:
+    	PWARN("Invalid owner type: %d\n", type );
+	}
+
+	if( table->gobj_param_name != NULL ) {
+		g_object_set( pObject, table->gobj_param_name, &owner, NULL );
+	} else {
+    	(*setter)( pObject, &owner );
+	}
+}
+
+static void
+get_gvalue_owner( const GncGdaBackend* be, QofIdTypeConst obj_name, const gpointer pObject,
+                	const col_cvt_t* table_row, GValue* value )
+{
+    OwnerGetterFunc getter;
+    GncOwner* owner;
+
+    memset( value, 0, sizeof( GValue ) );
+
+	getter = (OwnerGetterFunc)gnc_gda_get_getter( obj_name, table_row );
+    owner = (*getter)( pObject );
+    g_value_init( value, G_TYPE_POINTER );
+    g_value_set_object( value, owner );
+}
+
+static void
+get_gvalue_owner_for_query( const GncGdaBackend* be, QofIdTypeConst obj_name,
+                			const gpointer pObject, const col_cvt_t* table_row, GdaQuery* query )
+{
+    GValue value;
+    GValue subfield_value;
+    GncOwner* owner;
+	gchar* buf;
+    const GUID* guid;
+    gchar guid_buf[GUID_ENCODING_LENGTH+1];
+	GncOwnerType type;
+	QofInstance* inst = NULL;
+
+    memset( &value, 0, sizeof( GValue ) );
+    get_gvalue_owner( be, obj_name, pObject, table_row, &value );
+
+    if( G_VALUE_TYPE(&value) != 0 ) {
+        owner = g_value_get_object( &value );
+    	buf = g_strdup_printf( "%s_type", table_row->col_name );
+    	memset( &subfield_value, 0, sizeof( GValue ) );
+        g_value_init( &subfield_value, G_TYPE_INT );
+        type = gncOwnerGetType( owner );
+        g_value_set_int( &subfield_value, type );
+    	gnc_gda_add_field_to_query( query, buf, &subfield_value );
+		g_free( buf );
+
+    	buf = g_strdup_printf( "%s_guid", table_row->col_name );
+    	memset( &subfield_value, 0, sizeof( GValue ) );
+    	switch( type ) {
+  		case GNC_OWNER_CUSTOMER:
+    		inst = QOF_INSTANCE(gncOwnerGetCustomer( owner ));
+    		break; 
+
+  		case GNC_OWNER_JOB:
+    		inst = QOF_INSTANCE(gncOwnerGetJob( owner ));
+    		break; 
+
+  		case GNC_OWNER_VENDOR:
+    		inst = QOF_INSTANCE(gncOwnerGetVendor( owner ));
+    		break; 
+
+  		case GNC_OWNER_EMPLOYEE:
+    		inst = QOF_INSTANCE(gncOwnerGetEmployee( owner ));
+    		break; 
+
+  		default:
+    		PWARN("Invalid owner type: %d\n", type );
+		}
+		if( inst != NULL ) {
+			guid = qof_instance_get_guid( inst );
+    		if( guid != NULL ) {
+        		(void)guid_to_string_buff( guid, guid_buf );
+        		g_value_init( &subfield_value, G_TYPE_STRING );
+        		g_value_set_string( &subfield_value, guid_buf );
+    			gnc_gda_add_field_to_query( query, buf, &subfield_value );
+    		}
+		}
+		g_free( buf );
+    }
+}
+
+static GdaQueryCondition*
+get_gvalue_owner_cond( const GncGdaBackend* be, QofIdTypeConst obj_name,
+                const gpointer pObject, const col_cvt_t* table_row, GdaQuery* query )
+{
+    GValue value;
+    GValue subfield_value;
+    GncOwner* owner;
+	gchar* buf;
+    const GUID* guid;
+    gchar guid_buf[GUID_ENCODING_LENGTH+1];
+	GncOwnerType type;
+	QofInstance* inst = NULL;
+    GdaQueryCondition* sub_cond;
+    GdaQueryCondition* cond;
+
+    memset( &value, 0, sizeof( GValue ) );
+    get_gvalue_owner( be, obj_name, pObject, table_row, &value );
+    cond = gda_query_condition_new( query, GDA_QUERY_CONDITION_NODE_AND );
+
+    if( G_VALUE_TYPE(&value) != 0 ) {
+        owner = g_value_get_object( &value );
+    	buf = g_strdup_printf( "%s_type", table_row->col_name );
+    	memset( &subfield_value, 0, sizeof( GValue ) );
+        g_value_init( &subfield_value, G_TYPE_INT );
+        type = gncOwnerGetType( owner );
+        g_value_set_int( &subfield_value, type );
+    	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 );
+
+    	buf = g_strdup_printf( "%s_guid", table_row->col_name );
+    	memset( &subfield_value, 0, sizeof( GValue ) );
+    	switch( type ) {
+  		case GNC_OWNER_CUSTOMER:
+    		inst = QOF_INSTANCE(gncOwnerGetCustomer( owner ));
+    		break; 
+
+  		case GNC_OWNER_JOB:
+    		inst = QOF_INSTANCE(gncOwnerGetJob( owner ));
+    		break; 
+
+  		case GNC_OWNER_VENDOR:
+    		inst = QOF_INSTANCE(gncOwnerGetVendor( owner ));
+    		break; 
+
+  		case GNC_OWNER_EMPLOYEE:
+    		inst = QOF_INSTANCE(gncOwnerGetEmployee( owner ));
+    		break; 
+
+  		default:
+    		PWARN("Invalid owner type: %d\n", type );
+		}
+		if( inst != NULL ) {
+			guid = qof_instance_get_guid( inst );
+    		if( guid != NULL ) {
+        		(void)guid_to_string_buff( guid, guid_buf );
+        		g_value_init( &subfield_value, G_TYPE_STRING );
+        		g_value_set_string( &subfield_value, guid_buf );
+    			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_owner_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_INT );
+    buf = g_strdup_printf( "%s_type", 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 );
+    dbms_type = gda_server_provider_get_default_dbms_type( server, cnn,
+                                                            G_TYPE_STRING );
+    buf = g_strdup_printf( "%s_guid", table_row->col_name );
+   	gnc_gda_add_table_column( server, cnn, array_data, buf, dbms_type, GUID_ENCODING_LENGTH, table_row->flags );
+   	g_free( buf );
+}
+
+static col_type_handler_t owner_handler =
+        { load_owner, create_owner_col,
+            get_gvalue_owner_for_query, get_gvalue_owner_cond };
+
+/* ================================================================= */
+void
+gnc_owner_gda_initialize( void )
+{
+	gnc_gda_register_col_type_handler( CT_OWNERREF, &owner_handler );
+}
+/* ========================== END OF FILE ===================== */

Added: gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-owner-gda.h
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-owner-gda.h	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-owner-gda.h	2007-12-23 23:37:45 UTC (rev 16708)
@@ -0,0 +1,39 @@
+/* gnc-owner-gda.h -- Owner 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-owner-gda.h
+ *  @brief load and save owner 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_OWNER_GDA_H
+#define GNC_OWNER_GDA_H
+
+#include "gncOwner.h"
+#include "qof.h"
+
+#define CT_OWNERREF "owner"
+
+void gnc_owner_gda_initialize( void );
+
+#endif /* GNC_OWNER_GDA_H */

Added: gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-tax-table-gda.c
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-tax-table-gda.c	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-tax-table-gda.c	2007-12-23 23:37:45 UTC (rev 16708)
@@ -0,0 +1,728 @@
+/********************************************************************\
+ * gnc-tax-table-xml-v2.c -- tax table 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 "gncEntry.h"
+#include "gncTaxTableP.h"
+
+#include "gnc-tax-table-gda.h"
+
+#if 0
+#include "gnc-xml-helper.h"
+
+#include "sixtp.h"
+#include "sixtp-utils.h"
+#include "sixtp-parsers.h"
+#include "sixtp-utils.h"
+#include "sixtp-dom-parsers.h"
+#include "sixtp-dom-generators.h"
+
+#include "gnc-xml.h"
+#include "io-gncxml-gen.h"
+#include "io-gncxml-v2.h"
+
+
+#define _GNC_MOD_NAME	GNC_ID_TAXTABLE
+
+static QofLogModule log_module = GNC_MOD_IO;
+
+const gchar *taxtable_version_string = "2.0.0";
+
+/* ids */
+#define gnc_taxtable_string "gnc:GncTaxTable"
+#define taxtable_guid_string "taxtable:guid"
+#define taxtable_name_string "taxtable:name"
+#define taxtable_refcount_string "taxtable:refcount"
+#define taxtable_invisible_string "taxtable:invisible"
+#define taxtable_parent_string "taxtable:parent"
+#define taxtable_child_string "taxtable:child"
+#define taxtable_entries_string "taxtable:entries"
+#define taxtable_slots_string "taxtable:slots"
+
+#define gnc_taxtableentry_string "gnc:GncTaxTableEntry"
+#define ttentry_account_string "tte:acct"
+#define ttentry_type_string "tte:type"
+#define ttentry_amount_string "tte:amount"
+
+static void
+maybe_add_guid (xmlNodePtr ptr, const char *tag, GncTaxTable *table)
+{
+  if (table)
+    xmlAddChild (ptr, guid_to_dom_tree (tag, 
+            qof_instance_get_guid(QOF_INSTANCE(table))));
+}
+
+static xmlNodePtr
+ttentry_dom_tree_create (GncTaxTableEntry *entry)
+{
+  xmlNodePtr ret;
+  Account *account;
+  gnc_numeric amount;
+
+  ret = xmlNewNode(NULL, BAD_CAST gnc_taxtableentry_string);
+
+  account = gncTaxTableEntryGetAccount (entry);
+  if (account)
+    xmlAddChild(ret, guid_to_dom_tree (ttentry_account_string,
+				       qof_instance_get_guid (QOF_INSTANCE(account))));
+
+  amount = gncTaxTableEntryGetAmount (entry);
+  xmlAddChild (ret, gnc_numeric_to_dom_tree (ttentry_amount_string, &amount));
+
+  xmlAddChild(ret, text_to_dom_tree (ttentry_type_string,
+				     gncAmountTypeToString (
+				    gncTaxTableEntryGetType (entry))));
+
+  return ret;
+}
+
+static xmlNodePtr
+taxtable_dom_tree_create (GncTaxTable *table)
+{
+    xmlNodePtr ret, entries;
+    GList *list;
+
+    ret = xmlNewNode(NULL, BAD_CAST gnc_taxtable_string);
+    xmlSetProp(ret, BAD_CAST "version", BAD_CAST taxtable_version_string);
+
+    maybe_add_guid(ret, taxtable_guid_string, table);
+    xmlAddChild(ret, text_to_dom_tree (taxtable_name_string,
+				       gncTaxTableGetName (table)));
+
+    xmlAddChild(ret, int_to_dom_tree (taxtable_refcount_string,
+				      gncTaxTableGetRefcount (table)));
+    xmlAddChild(ret, int_to_dom_tree (taxtable_invisible_string,
+				      gncTaxTableGetInvisible (table)));
+
+    /* We should not be our own child */
+    if (gncTaxTableGetChild(table) != table)
+      maybe_add_guid(ret, taxtable_child_string, gncTaxTableGetChild (table));
+
+    maybe_add_guid(ret, taxtable_parent_string, gncTaxTableGetParent (table));
+
+    entries = xmlNewChild (ret, NULL, BAD_CAST taxtable_entries_string, NULL);
+    for (list = gncTaxTableGetEntries (table); list; list = list->next) {
+      GncTaxTableEntry *entry = list->data;
+      xmlAddChild(entries, ttentry_dom_tree_create (entry));
+    }
+
+    return ret;
+}
+
+/***********************************************************************/
+
+struct ttentry_pdata
+{
+  GncTaxTableEntry *ttentry;
+  QofBook *book;
+};
+
+static gboolean
+ttentry_acct_handler (xmlNodePtr node, gpointer ttentry_pdata)
+{
+  struct ttentry_pdata *pdata = ttentry_pdata;
+  GUID *guid;
+  Account * acc;
+
+  guid = dom_tree_to_guid (node);
+  g_return_val_if_fail (guid, FALSE);
+  acc = xaccAccountLookup (guid, pdata->book);
+  g_free (guid);
+  g_return_val_if_fail (acc, FALSE);
+
+  gncTaxTableEntrySetAccount (pdata->ttentry, acc);
+  return TRUE;
+}
+
+static gboolean
+ttentry_type_handler (xmlNodePtr node, gpointer taxtable_pdata)
+{
+  struct ttentry_pdata *pdata = taxtable_pdata;
+  GncAmountType type;
+  char *str;
+  gboolean ret;
+
+  str = dom_tree_to_text (node);
+  g_return_val_if_fail (str, FALSE);
+
+  ret = gncAmountStringToType (str, &type);
+  g_free (str);
+
+  if (ret)
+    gncTaxTableEntrySetType (pdata->ttentry, type);
+
+  return ret;
+}
+
+static gboolean
+ttentry_amount_handler (xmlNodePtr node, gpointer ttentry_pdata)
+{
+  struct ttentry_pdata *pdata = ttentry_pdata;
+  gnc_numeric* num = dom_tree_to_gnc_numeric(node);
+  g_return_val_if_fail(num, FALSE);
+    
+  gncTaxTableEntrySetAmount (pdata->ttentry, *num);
+  g_free(num);
+  return TRUE;
+}
+
+static struct dom_tree_handler ttentry_handlers_v2[] = {
+  { ttentry_account_string, ttentry_acct_handler, 0, 0 },
+  { ttentry_type_string, ttentry_type_handler, 1, 0 },
+  { ttentry_amount_string, ttentry_amount_handler, 1, 0 },
+  { NULL, 0, 0, 0 }
+};
+
+static GncTaxTableEntry*
+dom_tree_to_ttentry (xmlNodePtr node, QofBook *book)
+{
+  struct ttentry_pdata ttentry_pdata;
+  gboolean successful;
+  
+  ttentry_pdata.ttentry = gncTaxTableEntryCreate ();
+  ttentry_pdata.book = book;
+
+  successful = dom_tree_generic_parse (node, ttentry_handlers_v2,
+				       &ttentry_pdata);
+
+  if (!successful) {
+    PERR ("failed to parse tax table entry tree");
+    gncTaxTableEntryDestroy (ttentry_pdata.ttentry);
+    ttentry_pdata.ttentry = NULL;
+  }
+
+  return ttentry_pdata.ttentry;
+}
+
+/***********************************************************************/
+
+struct taxtable_pdata
+{
+  GncTaxTable *table;
+  QofBook *book;
+};
+
+static gboolean
+set_parent_child (xmlNodePtr node, struct taxtable_pdata *pdata,
+		  void (*func)(GncTaxTable *, GncTaxTable *))
+{
+  GUID *guid;
+  GncTaxTable *table;
+
+  guid = dom_tree_to_guid(node);
+  g_return_val_if_fail (guid, FALSE);
+  table = gncTaxTableLookup (pdata->book, guid);
+
+  /* Ignore pointers to self */
+  if (table == pdata->table) {
+    PINFO ("found a self-referential parent/child; ignoring.\n");
+    return TRUE;
+  }
+
+  if (!table) {
+    table = gncTaxTableCreate (pdata->book);
+    gncTaxTableBeginEdit (table);
+    gncTaxTableSetGUID (table, guid);
+    gncTaxTableCommitEdit (table);
+  }
+  g_free (guid);
+  g_return_val_if_fail (table, FALSE);
+  func (pdata->table, table);
+
+  return TRUE;
+}
+
+static gboolean
+taxtable_guid_handler (xmlNodePtr node, gpointer taxtable_pdata)
+{
+    struct taxtable_pdata *pdata = taxtable_pdata;
+    GUID *guid;
+    GncTaxTable *table;
+
+    guid = dom_tree_to_guid(node);
+    g_return_val_if_fail (guid, FALSE);
+    table = gncTaxTableLookup (pdata->book, guid);
+    if (table) {
+      gncTaxTableDestroy (pdata->table);
+      pdata->table = table;
+      gncTaxTableBeginEdit (table);
+    } else {
+      gncTaxTableSetGUID(pdata->table, guid);
+    }
+
+    g_free(guid);
+    
+    return TRUE;
+}
+
+static gboolean
+taxtable_name_handler (xmlNodePtr node, gpointer taxtable_pdata)
+{
+  struct taxtable_pdata *pdata = taxtable_pdata;
+  char* txt = dom_tree_to_text(node);
+  g_return_val_if_fail(txt, FALSE);
+    
+  gncTaxTableSetName (pdata->table, txt);
+  g_free(txt);
+  return TRUE;
+}
+
+static gboolean
+taxtable_refcount_handler (xmlNodePtr node, gpointer taxtable_pdata)
+{
+  struct taxtable_pdata *pdata = taxtable_pdata;
+  gint64 val;
+
+  dom_tree_to_integer(node, &val);
+  gncTaxTableSetRefcount (pdata->table, val);
+  return TRUE;
+}
+
+static gboolean
+taxtable_invisible_handler (xmlNodePtr node, gpointer taxtable_pdata)
+{
+  struct taxtable_pdata *pdata = taxtable_pdata;
+  gint64 val;
+
+  dom_tree_to_integer(node, &val);
+  if (val)
+    gncTaxTableMakeInvisible (pdata->table);
+  return TRUE;
+}
+
+static gboolean
+taxtable_parent_handler (xmlNodePtr node, gpointer taxtable_pdata)
+{
+  struct taxtable_pdata *pdata = taxtable_pdata;
+  return set_parent_child (node, pdata, gncTaxTableSetParent);
+}
+
+static gboolean
+taxtable_child_handler (xmlNodePtr node, gpointer taxtable_pdata)
+{
+  struct taxtable_pdata *pdata = taxtable_pdata;
+  return set_parent_child (node, pdata, gncTaxTableSetChild);
+}
+
+static gboolean
+taxtable_entries_handler (xmlNodePtr node, gpointer taxtable_pdata)
+{
+  struct taxtable_pdata *pdata = taxtable_pdata;
+  xmlNodePtr mark;
+
+  g_return_val_if_fail (node, FALSE);
+  g_return_val_if_fail (node->xmlChildrenNode, FALSE);
+
+  for (mark = node->xmlChildrenNode; mark; mark = mark->next) {
+    GncTaxTableEntry *entry;
+        
+    if (safe_strcmp ("text", (char*)mark->name) == 0)
+      continue;
+
+    if (safe_strcmp (gnc_taxtableentry_string, (char*)mark->name))
+      return FALSE;
+
+    entry = dom_tree_to_ttentry (mark, pdata->book);
+
+    if (entry)
+      gncTaxTableAddEntry (pdata->table, entry);
+    else
+      return FALSE;
+
+  }
+  return TRUE;
+}
+
+static gboolean
+taxtable_slots_handler (xmlNodePtr node, gpointer taxtable_pdata)
+{
+  return TRUE;
+}
+
+static struct dom_tree_handler taxtable_handlers_v2[] = {
+    { taxtable_guid_string, taxtable_guid_handler, 1, 0 },
+    { taxtable_name_string, taxtable_name_handler, 1, 0 },
+    { taxtable_refcount_string, taxtable_refcount_handler, 1, 0 },
+    { taxtable_invisible_string, taxtable_invisible_handler, 1, 0 },
+    { taxtable_parent_string, taxtable_parent_handler, 0, 0 },
+    { taxtable_child_string, taxtable_child_handler, 0, 0 },
+    { taxtable_entries_string, taxtable_entries_handler, 1, 0 },
+    { taxtable_slots_string, taxtable_slots_handler, 0, 0 },
+    { NULL, 0, 0, 0 }
+};
+
+static GncTaxTable*
+dom_tree_to_taxtable (xmlNodePtr node, QofBook *book)
+{
+  struct taxtable_pdata taxtable_pdata;
+  gboolean successful;
+  
+  taxtable_pdata.table = gncTaxTableCreate (book);
+  taxtable_pdata.book = book;
+  gncTaxTableBeginEdit (taxtable_pdata.table);
+
+  successful = dom_tree_generic_parse (node, taxtable_handlers_v2,
+				       &taxtable_pdata);
+
+  if (successful)
+    gncTaxTableCommitEdit (taxtable_pdata.table);
+  else
+  {
+    PERR ("failed to parse tax table tree");
+    gncTaxTableDestroy (taxtable_pdata.table);
+    taxtable_pdata.table = NULL;
+  }
+
+  return taxtable_pdata.table;
+}
+
+static gboolean
+gnc_taxtable_end_handler(gpointer data_for_children,
+			 GSList* data_from_children, GSList* sibling_data,
+			 gpointer parent_data, gpointer global_data,
+			 gpointer *result, const gchar *tag)
+{
+    int successful;
+    GncTaxTable *table;
+    xmlNodePtr tree = (xmlNodePtr)data_for_children;
+    gxpf_data *gdata = (gxpf_data*)global_data;
+    QofBook *book = gdata->bookdata;
+
+    successful = TRUE;
+
+    if(parent_data)
+    {
+        return TRUE;
+    }
+
+    /* OK.  For some messed up reason this is getting called again with a
+       NULL tag.  So we ignore those cases */
+    if(!tag)
+    {
+        return TRUE;
+    }
+
+    g_return_val_if_fail(tree, FALSE);
+
+    table = dom_tree_to_taxtable (tree, book);
+    if(table != NULL)
+    {
+        gdata->cb(tag, gdata->parsedata, table);
+    }
+
+    xmlFreeNode(tree);
+
+    return table != NULL;
+}
+
+static sixtp *
+taxtable_sixtp_parser_create(void)
+{
+  return sixtp_dom_parser_new(gnc_taxtable_end_handler, NULL, NULL);
+}
+
+static void
+do_count (QofInstance * table_p, gpointer count_p)
+{
+  int *count = count_p;
+  (*count)++;
+}
+
+static int
+taxtable_get_count (QofBook *book)
+{
+  int count = 0;
+  qof_object_foreach (_GNC_MOD_NAME, book, do_count, (gpointer) &count);
+  return count;
+}
+
+static void
+xml_add_taxtable (QofInstance * table_p, gpointer out_p)
+{
+  xmlNodePtr node;
+  GncTaxTable *table = (GncTaxTable *) table_p;
+  FILE *out = out_p;
+
+  node = taxtable_dom_tree_create (table);
+  xmlElemDump(out, NULL, node);
+  fprintf(out, "\n");
+  xmlFreeNode (node);
+}
+
+static void
+taxtable_write (FILE *out, QofBook *book)
+{
+  qof_object_foreach (_GNC_MOD_NAME, book, xml_add_taxtable, (gpointer) out);
+}
+
+
+static gboolean
+taxtable_is_grandchild (GncTaxTable *table)
+{
+  return (gncTaxTableGetParent(gncTaxTableGetParent(table)) != NULL);
+}
+
+static GncTaxTable *
+taxtable_find_senior (GncTaxTable *table)
+{
+  GncTaxTable *temp, *parent, *gp = NULL;
+
+  temp = table;
+  do {
+    /* See if "temp" is a grandchild */
+    parent = gncTaxTableGetParent(temp);
+    if (!parent)
+      break;
+    gp = gncTaxTableGetParent(parent);
+    if (!gp)
+      break;
+
+    /* Yep, this is a grandchild.  Move up one generation and try again */
+    temp = parent;
+  } while (TRUE);
+
+  /* Ok, at this point temp points to the most senior child and parent
+   * should point to the top taxtable (and gp should be NULL).  If
+   * parent is NULL then we are the most senior child (and have no
+   * children), so do nothing.  If temp == table then there is no
+   * grandparent, so do nothing.
+   *
+   * Do something if parent != NULL && temp != table
+   */
+  g_assert (gp == NULL);
+
+  /* return the most senior table */
+  return temp;
+}
+
+/* build a list of tax tables that are grandchildren or bogus (empty entry list). */
+static void
+taxtable_scrub_cb (QofInstance * table_p, gpointer list_p)
+{
+  GncTaxTable *table = GNC_TAXTABLE(table_p);
+  GList **list = list_p;
+
+  if (taxtable_is_grandchild(table) || gncTaxTableGetEntries(table) == NULL)
+    *list = g_list_prepend(*list, table);
+}
+
+/* for each entry, check the tax tables.  If the tax tables are
+ * grandchildren, then fix them to point to the most senior child
+ */
+static void
+taxtable_scrub_entries (QofInstance * entry_p, gpointer ht_p)
+{
+  GHashTable *ht = ht_p;
+  GncEntry *entry = GNC_ENTRY(entry_p);
+  GncTaxTable *table, *new_tt;
+  gint32 count;
+
+  table = gncEntryGetInvTaxTable(entry);
+  if (table) {
+    if (taxtable_is_grandchild(table)) {
+      PINFO("Fixing i-taxtable on entry %s\n",
+	     guid_to_string(qof_instance_get_guid(QOF_INSTANCE(entry))));
+      new_tt = taxtable_find_senior(table);
+      gncEntryBeginEdit(entry);
+      gncEntrySetInvTaxTable(entry, new_tt);
+      gncEntryCommitEdit(entry);
+      table = new_tt;
+    }
+    if (table) {
+      count = GPOINTER_TO_INT(g_hash_table_lookup(ht, table));
+      count++;
+      g_hash_table_insert(ht, table, GINT_TO_POINTER(count));
+    }
+  }
+
+  table = gncEntryGetBillTaxTable(entry);
+  if (table) {
+    if (taxtable_is_grandchild(table)) {
+      PINFO("Fixing b-taxtable on entry %s\n",
+	     guid_to_string(qof_instance_get_guid(QOF_INSTANCE(entry))));
+      new_tt = taxtable_find_senior(table);
+      gncEntryBeginEdit(entry);
+      gncEntrySetBillTaxTable(entry, new_tt);
+      gncEntryCommitEdit(entry);
+      table = new_tt;
+    }
+    if (table) {
+      count = GPOINTER_TO_INT(g_hash_table_lookup(ht, table));
+      count++;
+      g_hash_table_insert(ht, table, GINT_TO_POINTER(count));
+    }
+  }
+}
+
+static void
+taxtable_scrub_cust (QofInstance * cust_p, gpointer ht_p)
+{
+  GHashTable *ht = ht_p;
+  GncCustomer *cust = GNC_CUSTOMER(cust_p);
+  GncTaxTable *table;
+  gint32 count;
+  
+  table = gncCustomerGetTaxTable(cust);
+  if (table) {
+    count = GPOINTER_TO_INT(g_hash_table_lookup(ht, table));
+    count++;
+    g_hash_table_insert(ht, table, GINT_TO_POINTER(count));
+  }
+}
+
+static void
+taxtable_scrub_vendor (QofInstance * vendor_p, gpointer ht_p)
+{
+  GHashTable *ht = ht_p;
+  GncVendor *vendor = GNC_VENDOR(vendor_p);
+  GncTaxTable *table;
+  gint32 count;
+
+  table = gncVendorGetTaxTable(vendor);
+  if (table) {
+    count = GPOINTER_TO_INT(g_hash_table_lookup(ht, table));
+    count++;
+    g_hash_table_insert(ht, table, GINT_TO_POINTER(count));
+  }
+}
+
+static void
+taxtable_reset_refcount (gpointer key, gpointer value, gpointer notused)
+{
+  GncTaxTable *table = key;
+  gint32 count = GPOINTER_TO_INT(value);
+
+  if (count != gncTaxTableGetRefcount(table) && !gncTaxTableGetInvisible(table)) {
+    PWARN("Fixing refcount on taxtable %s (%" G_GINT64_FORMAT " -> %d)\n",
+	  guid_to_string(qof_instance_get_guid(QOF_INSTANCE(table))),
+	  gncTaxTableGetRefcount(table), count);
+      gncTaxTableSetRefcount(table, count);
+  }
+}
+
+static void
+taxtable_scrub (QofBook *book)
+{
+  GList *list = NULL;
+  GList *node;
+  GncTaxTable *parent, *table;
+  GHashTable *ht = g_hash_table_new(g_direct_hash, g_direct_equal);
+
+  qof_object_foreach (GNC_ID_ENTRY, book, taxtable_scrub_entries, ht);
+  qof_object_foreach (GNC_ID_CUSTOMER, book, taxtable_scrub_cust, ht);
+  qof_object_foreach (GNC_ID_VENDOR, book, taxtable_scrub_vendor, ht);
+  qof_object_foreach (GNC_ID_TAXTABLE, book, taxtable_scrub_cb, &list);
+
+  /* destroy the list of "grandchildren" tax tables */
+  for (node = list; node; node = node->next) {
+    table = node->data;
+
+    PINFO ("deleting grandchild taxtable: %s\n",
+	   guid_to_string(qof_instance_get_guid(QOF_INSTANCE(table))));
+
+    /* Make sure the parent has no children */
+    parent = gncTaxTableGetParent(table);
+    gncTaxTableSetChild(parent, NULL);
+
+    /* Destroy this tax table */
+    gncTaxTableBeginEdit(table);
+    gncTaxTableDestroy(table);
+  }
+
+  /* reset the refcounts as necessary */
+  g_hash_table_foreach(ht, taxtable_reset_refcount, NULL);
+
+  g_list_free(list);
+  g_hash_table_destroy(ht);
+}
+
+static void
+taxtable_ns(FILE *out)
+{
+  g_return_if_fail(out);
+  gnc_xml2_write_namespace_decl(out, "taxtable");
+  gnc_xml2_write_namespace_decl(out, "tte");
+}
+#endif
+
+/* ================================================================= */
+static void
+load_taxtable_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;
+	GncTaxTable* taxtable = 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 ) {
+		taxtable = gncTaxTableLookup( be->primary_book, pGuid );
+	}
+    if( table->gobj_param_name != NULL ) {
+		g_object_set( pObject, table->gobj_param_name, taxtable, NULL );
+    } else {
+		(*setter)( pObject, (const gpointer)taxtable );
+    }
+}
+
+static col_type_handler_t taxtable_guid_handler =
+        { load_taxtable_guid, gnc_gda_create_objectref_guid_col,
+            gnc_gda_get_gvalue_objectref_guid_for_query, gnc_gda_get_gvalue_objectref_guid_cond };
+/* ================================================================= */
+void
+gnc_taxtable_gda_initialize( void )
+{
+#if 0
+    static GncGdaDataType_t be_data =
+    {
+        GNC_GDA_BACKEND_VERSION,
+        GNC_ID_ORDER,
+        gnc_gda_save_taxtable,				/* commit */
+        load_all_taxtables,					/* initial_load */
+        create_taxtable_tables				/* create_tables */
+    };
+
+    qof_object_register_backend( GNC_ID_ORDER, GNC_GDA_BACKEND, &be_data );
+#endif
+
+	gnc_gda_register_col_type_handler( CT_TAXTABLEREF, &taxtable_guid_handler );
+}
+/* ========================== END OF FILE ===================== */

Added: gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-tax-table-gda.h
===================================================================
--- gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-tax-table-gda.h	                        (rev 0)
+++ gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-tax-table-gda.h	2007-12-23 23:37:45 UTC (rev 16708)
@@ -0,0 +1,37 @@
+/*
+ * gnc-tax-table-gda.h -- tax table 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-tax-table-gda.h
+ *  @brief load and save tax table 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_TAXTABLE_GDA_H
+#define GNC_TAXTABLE_GDA_H
+
+#define CT_TAXTABLEREF "tax-table"
+
+void gnc_taxtable_gda_initialize( void );
+
+#endif /* GNC_TAXTABLE_GDA_H */

Modified: 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	2007-12-23 21:49:37 UTC (rev 16707)
+++ gnucash/branches/gda-dev2/src/business/business-core/gda/gnc-vendor-gda.c	2007-12-23 23:37:45 UTC (rev 16708)
@@ -39,6 +39,7 @@
 #include "gnc-vendor-gda.h"
 #include "gnc-address-gda.h"
 #include "gnc-bill-term-gda.h"
+#include "gnc-tax-table-gda.h"
 
 #define _GNC_MOD_NAME	GNC_ID_VENDOR
 
@@ -47,47 +48,28 @@
 #define MAX_NAME_LEN 50
 #define MAX_ID_LEN 50
 #define MAX_NOTES_LEN 100
+#define MAX_TAX_INC_LEN 50
 
 #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,
+	{ "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,
+	{ "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 },
+	{ "tax_override", CT_BOOLEAN,       0,               COL_NNUL, NULL, VENDOR_TAX_OVERRIDE },
+	{ "addr",         CT_ADDRESS,       0,               0,        NULL, VENDOR_ADDR },
+	{ "terms",        CT_BILLTERMREF,   0,               0,        NULL, VENDOR_TERMS },
+	{ "tax_inc",      CT_STRING,        MAX_TAX_INC_LEN, 0,        NULL, VENDOR_TAX_INC },
+	{ "tax_table",    CT_TAXTABLEREF,   0,               0,        NULL, VENDOR_TAX_TABLE },
 	{ 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 )
 {

Modified: 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	2007-12-23 21:49:37 UTC (rev 16707)
+++ gnucash/branches/gda-dev2/src/business/business-core/gda/gncmod-business-backend-gda.c	2007-12-23 23:37:45 UTC (rev 16708)
@@ -81,12 +81,12 @@
         gnc_billterm_gda_initialize();
         gnc_customer_gda_initialize();
         gnc_employee_gda_initialize();
-//        gnc_entry_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_owner_gda_initialize();
+	    gnc_taxtable_gda_initialize();
         gnc_vendor_gda_initialize();
     }
 



More information about the gnucash-changes mailing list