r15124 - gnucash/branches/gda-dev/src/backend/gda - Basic transaction/split query

Phil Longstaff plongstaff at cvs.gnucash.org
Fri Nov 17 21:31:41 EST 2006


Author: plongstaff
Date: 2006-11-17 21:31:40 -0500 (Fri, 17 Nov 2006)
New Revision: 15124
Trac: http://svn.gnucash.org/trac/changeset/15124

Modified:
   gnucash/branches/gda-dev/src/backend/gda/gnc-account-gda.c
   gnucash/branches/gda-dev/src/backend/gda/gnc-backend-gda.c
   gnucash/branches/gda-dev/src/backend/gda/gnc-backend-gda.h
   gnucash/branches/gda-dev/src/backend/gda/gnc-commodity-gda.c
   gnucash/branches/gda-dev/src/backend/gda/gnc-commodity-gda.h
   gnucash/branches/gda-dev/src/backend/gda/gnc-price-gda.c
   gnucash/branches/gda-dev/src/backend/gda/gnc-transaction-gda.c
Log:
Basic transaction/split query


Modified: gnucash/branches/gda-dev/src/backend/gda/gnc-account-gda.c
===================================================================
--- gnucash/branches/gda-dev/src/backend/gda/gnc-account-gda.c	2006-11-15 08:54:51 UTC (rev 15123)
+++ gnucash/branches/gda-dev/src/backend/gda/gnc-account-gda.c	2006-11-18 02:31:40 UTC (rev 15124)
@@ -38,6 +38,7 @@
 #include "gnc-backend-gda.h"
 
 #include "gnc-account-gda.h"
+#include "gnc-commodity-gda.h"
 #include "gnc-slots-gda.h"
 
 static QofLogModule log_module = GNC_MOD_BACKEND;
@@ -121,11 +122,12 @@
 }
 
 static Account*
-load_account( GncGdaBackend* be, GdaDataModel* pModel, int row )
+load_account( GncGdaBackend* be, GdaDataModel* pModel, int row,
+			Account* pAccount )
 {
-	Account* pAccount;
-
-	pAccount = xaccMallocAccount( be->primary_book );
+	if( pAccount == NULL ) {
+		pAccount = xaccMallocAccount( be->primary_book );
+	}
 	gnc_gda_load_object( pModel, row, GNC_ID_ACCOUNT, pAccount, col_table );
 	gnc_gda_slots_load( be, xaccAccountGetGUID( pAccount ),
 							qof_instance_get_slots( (QofInstance*)pAccount ) );
@@ -164,7 +166,7 @@
 
 		for( r = 0; r < numRows; r++ ) {
 
-			pAccount = load_account( be, pModel, r );
+			pAccount = load_account( be, pModel, r, NULL );
 
 			if( pAccount != NULL ) {
 				if( xaccAccountGetParent( pAccount ) == NULL ) {
@@ -190,6 +192,9 @@
 {
 	Account* pAcc = (Account*)inst;
 
+	// Ensure the commodity is in the db
+	gnc_gda_save_commodity( be, xaccAccountGetCommodity( pAcc ) );
+
 	(void)gnc_gda_do_db_operation( be,
 							(inst->do_free ? OP_DB_DELETE : OP_DB_ADD_OR_UPDATE ),
 							TABLE_NAME,

Modified: gnucash/branches/gda-dev/src/backend/gda/gnc-backend-gda.c
===================================================================
--- gnucash/branches/gda-dev/src/backend/gda/gnc-backend-gda.c	2006-11-15 08:54:51 UTC (rev 15123)
+++ gnucash/branches/gda-dev/src/backend/gda/gnc-backend-gda.c	2006-11-18 02:31:40 UTC (rev 15124)
@@ -72,11 +72,19 @@
 			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;
@@ -678,8 +686,8 @@
 	return buf;
 }
 
-static gboolean
-object_exists_in_db( GncGdaBackend* be, const gchar* table_name,
+gboolean
+gnc_gda_object_is_it_in_db( GncGdaBackend* be, const gchar* table_name,
 					QofIdTypeConst obj_name, gpointer pObject,
 					const col_cvt_t* table )
 {
@@ -712,7 +720,7 @@
 	GdaQuery* pQuery;
 
 	if( op == OP_DB_ADD_OR_UPDATE ) {
-		if( object_exists_in_db( be, table_name, obj_name, pObject, table ) ) {
+		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 );
@@ -1295,6 +1303,26 @@
 	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)
 {
@@ -1302,10 +1330,27 @@
 	GList* pBookList;
 	QofIdType searchObj;
 	gchar sql[1000];
+	gda_backend be_data;
+	gnc_gda_query_info* pQueryInfo;
 
-	pBookList = qof_query_get_books( pQuery );
 	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 ) {
+		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 ) ) {
@@ -1331,22 +1376,92 @@
 	}
 
 	printf( "Compiled: %s\n", sql );
-	return g_strdup( sql );
+	pQueryInfo->pCompiledQuery =  g_strdup( sql );
+
+	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;
 
-	printf( "gda_free_query(): %s\n", (gchar*)pQuery );
+	// 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 ) {
+		return;
+	}
+
+	printf( "gda_free_query(): %s\n", (gchar*)pQueryInfo->pCompiledQuery );
+	g_free( pQueryInfo->pCompiledQuery );
+	g_free( pQueryInfo );
 }
 
 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;
-	printf( "gda_run_query(): %s\n", (gchar*)pQuery );
+	gnc_gda_query_info* pQueryInfo = (gnc_gda_query_info*)pQuery;
+	gda_backend be_data;
+
+	be->loading = TRUE;
+
+	// 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;
+	if( be_data.ok ) {
+		return;
+	}
+
+	printf( "gda_run_query(): %s\n", (gchar*)pQueryInfo->pCompiledQuery );
 }
 
 /* ================================================================= */
@@ -1404,6 +1519,26 @@
 
 	gnc_be->primary_book = NULL;
 
+#if 0
+	{
+		QofCollection* col;
+		QofEntity e;
+		const GUID* g;
+		QofEntity* pEntity;
+		GUID g2;
+
+		col = qof_collection_new( "Test" );
+		qof_entity_init( &e, "Test", col );
+		g = qof_entity_get_guid( &e );
+		pEntity = qof_collection_lookup_entity( col, g );
+		g_assert( pEntity == &e );
+		guid_new( &g2 );
+		qof_entity_set_guid( &e, &g2 );
+		pEntity = qof_collection_lookup_entity( col, &g2 );
+		g_assert( pEntity == &e );
+	}
+#endif
+
 	return be;
 }
 

Modified: gnucash/branches/gda-dev/src/backend/gda/gnc-backend-gda.h
===================================================================
--- gnucash/branches/gda-dev/src/backend/gda/gnc-backend-gda.h	2006-11-15 08:54:51 UTC (rev 15123)
+++ gnucash/branches/gda-dev/src/backend/gda/gnc-backend-gda.h	2006-11-18 02:31:40 UTC (rev 15124)
@@ -64,6 +64,9 @@
   void		(*commit)( GncGdaBackend* pBackend, QofInstance* inst );
   void		(*initial_load)( GncGdaBackend* pBackend );
   void		(*create_tables)( GncGdaBackend* pBackend );
+  gpointer	(*compile_query)( GncGdaBackend* pBackend, QofQuery* pQuery );
+  void		(*run_query)( GncGdaBackend* pBackend, gpointer pQuery );
+  void		(*free_query)( GncGdaBackend* pBackend, gpointer pQuery );
 } GncGdaDataType_t;
 
 // This is now a static inside the module
@@ -130,6 +133,10 @@
 void gnc_gda_load_object( GdaDataModel* pModel, int row,
 						QofIdTypeConst obj_name, gpointer pObject,
 						const col_cvt_t* table );
+gboolean gnc_gda_object_is_it_in_db( GncGdaBackend* be,
+									const gchar* table_name,
+									QofIdTypeConst obj_name, gpointer pObject,
+									const col_cvt_t* table );
 gboolean gnc_gda_create_table( GdaConnection* pConnection,
 						const gchar* table_name, col_cvt_t* col_table,
 						GError** error );

Modified: gnucash/branches/gda-dev/src/backend/gda/gnc-commodity-gda.c
===================================================================
--- gnucash/branches/gda-dev/src/backend/gda/gnc-commodity-gda.c	2006-11-15 08:54:51 UTC (rev 15123)
+++ gnucash/branches/gda-dev/src/backend/gda/gnc-commodity-gda.c	2006-11-18 02:31:40 UTC (rev 15124)
@@ -46,7 +46,7 @@
 static gpointer get_quote_source_name( gpointer pObject );
 static void set_quote_source_name( gpointer pObject, const gpointer pValue );
 
-#define TABLE_NAME "commodities"
+#define COMMODITIES_TABLE "commodities"
 
 static col_cvt_t col_table[] = {
 	{ "guid",			CT_GUID,	  0, COL_NNUL|COL_PKEY,	NULL,
@@ -101,14 +101,16 @@
 }
 
 static gnc_commodity*
-load_commodity( GncGdaBackend* be, GdaDataModel* pModel, int row )
+load_commodity( GncGdaBackend* be, GdaDataModel* pModel, int row,
+				gnc_commodity* pCommodity )
 {
 	QofBook* pBook = be->primary_book;
 	int col;
 	const GValue* val;
-	gnc_commodity* pCommodity;
 
-	pCommodity = gnc_commodity_new( pBook, NULL, NULL, NULL, NULL, 100 );
+	if( pCommodity == NULL ) {
+		pCommodity = gnc_commodity_new( pBook, NULL, NULL, NULL, NULL, 100 );
+	}
 
 	gnc_gda_load_object( pModel, row, GNC_ID_COMMODITY, pCommodity, col_table );
 
@@ -125,7 +127,7 @@
 	QofBook* pBook = be->primary_book;
 	gnc_commodity_table* pTable = gnc_commodity_table_get_table( pBook );
 
-	buf = g_strdup_printf( "SELECT * FROM %s", TABLE_NAME );
+	buf = g_strdup_printf( "SELECT * FROM %s", COMMODITIES_TABLE );
 	query = gda_query_new_from_sql( be->pDict, buf, &error );
 	g_free( buf );
 	if( query == NULL ) {
@@ -147,7 +149,7 @@
 		for( r = 0; r < numRows; r++ ) {
 			gnc_commodity* c;
 
-			pCommodity = load_commodity( be, pModel, r );
+			pCommodity = load_commodity( be, pModel, r, NULL );
 
 			if( pCommodity != NULL ) {
 				GUID guid;
@@ -163,22 +165,34 @@
 static void
 create_commodities_tables( GncGdaBackend* be )
 {
-	gnc_gda_create_table_if_needed( be, TABLE_NAME, col_table );
+	gnc_gda_create_table_if_needed( be, COMMODITIES_TABLE, col_table );
 }
 
 /* ================================================================= */
 static void
 commit_commodity( GncGdaBackend* be, QofInstance* inst )
 {
-	gnc_commodity* pCommodity = (gnc_commodity*)inst;
-
 	(void)gnc_gda_do_db_operation( be,
 						(inst->do_free ? OP_DB_DELETE : OP_DB_ADD_OR_UPDATE ),
-						TABLE_NAME,
-						GNC_ID_COMMODITY, pCommodity,
+						COMMODITIES_TABLE,
+						GNC_ID_COMMODITY, (gnc_commodity*)inst,
 						col_table );
 }
 
+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, (QofInstance*)pCommodity );
+	}
+}
+
 /* ================================================================= */
 void
 gnc_gda_init_commodity_handler( void )

Modified: gnucash/branches/gda-dev/src/backend/gda/gnc-commodity-gda.h
===================================================================
--- gnucash/branches/gda-dev/src/backend/gda/gnc-commodity-gda.h	2006-11-15 08:54:51 UTC (rev 15123)
+++ gnucash/branches/gda-dev/src/backend/gda/gnc-commodity-gda.h	2006-11-18 02:31:40 UTC (rev 15124)
@@ -33,5 +33,6 @@
 #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_ */

Modified: gnucash/branches/gda-dev/src/backend/gda/gnc-price-gda.c
===================================================================
--- gnucash/branches/gda-dev/src/backend/gda/gnc-price-gda.c	2006-11-15 08:54:51 UTC (rev 15123)
+++ gnucash/branches/gda-dev/src/backend/gda/gnc-price-gda.c	2006-11-18 02:31:40 UTC (rev 15124)
@@ -36,6 +36,7 @@
 
 #include "gnc-backend-gda.h"
 
+#include "gnc-commodity-gda.h"
 #include "gnc-price-gda.h"
 
 static QofLogModule log_module = GNC_MOD_BACKEND;
@@ -150,12 +151,12 @@
 }
 
 static GNCPrice*
-load_price( GncGdaBackend* be, GdaDataModel* pModel, int row )
+load_price( GncGdaBackend* be, GdaDataModel* pModel, int row, GNCPrice* pPrice )
 {
-	GNCPrice* pPrice;
+	if( pPrice == NULL ) {
+		pPrice = gnc_price_create( be->primary_book );
+	}
 
-	pPrice = gnc_price_create( be->primary_book );
-
 	gnc_gda_load_object( pModel, row, GNC_ID_PRICE, pPrice, col_table );
 
 	return pPrice;
@@ -192,7 +193,7 @@
 
 		for( r = 0; r < numRows; r++ ) {
 
-			pPrice = load_price( be, pModel, r );
+			pPrice = load_price( be, pModel, r, NULL );
 
 			if( pPrice != NULL ) {
 				gnc_pricedb_add_price( pPriceDB, pPrice );
@@ -215,6 +216,10 @@
 {
 	GNCPrice* pPrice = (GNCPrice*)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,
 							(inst->do_free ? OP_DB_DELETE : OP_DB_ADD_OR_UPDATE ),
 							TABLE_NAME,

Modified: gnucash/branches/gda-dev/src/backend/gda/gnc-transaction-gda.c
===================================================================
--- gnucash/branches/gda-dev/src/backend/gda/gnc-transaction-gda.c	2006-11-15 08:54:51 UTC (rev 15123)
+++ gnucash/branches/gda-dev/src/backend/gda/gnc-transaction-gda.c	2006-11-18 02:31:40 UTC (rev 15124)
@@ -32,9 +32,14 @@
 #include <libgda/libgda.h>
 
 #include "qof.h"
+#include "qofquery-p.h"
+#include "qofquerycore-p.h"
 
 #include "gnc-backend-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"
 
@@ -53,6 +58,7 @@
 
 static gpointer get_guid( gpointer pObject );
 static void set_guid( gpointer pObject, const gpointer pValue );
+static void retrieve_guid( gpointer pObject, const gpointer pValue );
 static gpointer get_tx_currency( gpointer pObject );
 static void set_tx_currency( gpointer pObject, const gpointer pValue );
 static gpointer get_tx_post_date( gpointer pObject );
@@ -71,10 +77,19 @@
 			get_tx_post_date, set_tx_post_date },
 	{ "enter_date",		CT_TIMESPEC,  0, COL_NNUL, NULL,
 			get_tx_enter_date, set_tx_enter_date },
-	{ "description",	CT_STRING,	500, 0,	TRANS_DESCRIPTION },
+	{ "description",	CT_STRING,	500, 0,	NULL,
+			(GNC_GDA_FN_GETTER)xaccTransGetDescription,
+			(GNC_GDA_FN_SETTER)xaccTransSetDescription },
 	{ NULL }
 };
 
+// Table to retrieve just the guid
+static col_cvt_t guid_table[] =
+{
+	{ "guid", CT_GUID, 0, 0, NULL, NULL, retrieve_guid },
+	{ NULL }
+};
+
 static gpointer get_split_tx_guid( gpointer pObject );
 static void set_split_tx_guid( gpointer pObject, const gpointer pValue );
 static gpointer get_split_reconcile_state( gpointer pObject );
@@ -131,6 +146,15 @@
 	qof_entity_set_guid( pEntity, guid );
 }
 
+static void 
+retrieve_guid( gpointer pObject, const gpointer pValue )
+{
+	GUID** ppGuid = (GUID**)pObject;
+	GUID* guid = (GUID*)pValue;
+
+	*ppGuid = guid;
+}
+
 static gpointer
 get_tx_currency( gpointer pObject )
 {
@@ -307,6 +331,156 @@
 	xaccSplitSetAccount( pSplit, pAccount );
 }
 
+static Split*
+load_split( GncGdaBackend* be, GdaDataModel* pModel, int row, Split* pSplit )
+{
+	const GUID* guid;
+	GUID split_guid;
+
+	gnc_gda_load_object( pModel, row, GNC_ID_SPLIT, &guid, guid_table );
+	split_guid = *guid;
+
+	if( pSplit == NULL ) {
+		pSplit = xaccSplitLookup( &split_guid, be->primary_book );
+		if( pSplit == NULL ) {
+			pSplit = xaccMallocSplit( be->primary_book );
+		}
+	}
+	gnc_gda_load_object( pModel, row, GNC_ID_SPLIT, pSplit, split_col_table );
+	gnc_gda_slots_load( be, qof_instance_get_guid( (QofInstance*)pSplit ),
+							qof_instance_get_slots( (QofInstance*)pSplit ) );
+
+	g_assert( pSplit == xaccSplitLookup( &split_guid, be->primary_book ) );
+
+	return pSplit;
+}
+
+static void
+load_splits( GncGdaBackend* be, const GUID* guid )
+{
+	GError* error = NULL;
+	gchar* buf;
+	GdaQuery* query;
+	GdaObject* ret;
+	gchar guid_buf[GUID_ENCODING_LENGTH+1];
+
+	guid_to_string_buff( guid, guid_buf );
+	buf = g_strdup_printf( "SELECT * FROM %s where tx_guid='%s'",
+						SPLIT_TABLE, guid_buf );
+	query = gda_query_new_from_sql( be->pDict, buf, &error );
+	g_free( buf );
+	if( query == NULL ) {
+		printf( "SQL error: %s\n", error->message );
+		return;
+	}
+	error = NULL;
+	ret = gda_query_execute( query, NULL, FALSE, &error );
+
+	if( error != NULL ) {
+		printf( "SQL error: %s\n", error->message );
+	}
+	if( GDA_IS_DATA_MODEL( ret ) ) {
+		GdaDataModel* pModel = (GdaDataModel*)ret;
+		int numRows = gda_data_model_get_n_rows( pModel );
+		int r;
+
+		for( r = 0; r < numRows; r++ ) {
+			load_split( be, pModel, r, NULL );
+		}
+	}
+}
+
+static Transaction*
+load_tx( GncGdaBackend* be, GdaDataModel* pModel, int row, Transaction* pTx )
+{
+	const GUID* guid;
+	GUID tx_guid;
+
+	gnc_gda_load_object( pModel, row, GNC_ID_TRANS, &guid, guid_table );
+	tx_guid = *guid;
+
+	if( pTx == NULL ) {
+		pTx = xaccTransLookup( &tx_guid, be->primary_book );
+		if( pTx == NULL ) {
+			pTx = xaccMallocTransaction( be->primary_book );
+		}
+	}
+	xaccTransBeginEdit( pTx );
+	gnc_gda_load_object( pModel, row, GNC_ID_TRANS, pTx, tx_col_table );
+	gnc_gda_slots_load( be, qof_instance_get_guid( (QofInstance*)pTx ),
+							qof_instance_get_slots( (QofInstance*)pTx ) );
+	load_splits( be, qof_instance_get_guid( (QofInstance*)pTx ) );
+	xaccTransCommitEdit( pTx );
+
+	g_assert( pTx == xaccTransLookup( &tx_guid, be->primary_book ) );
+
+	return pTx;
+}
+
+static void
+load_transactions( GncGdaBackend* be, const GUID* guid )
+{
+	GError* error = NULL;
+	gchar* buf;
+	GdaQuery* query;
+	GdaObject* ret;
+	gchar guid_buf[GUID_ENCODING_LENGTH+1];
+
+	guid_to_string_buff( guid, guid_buf );
+	buf = g_strdup_printf( "SELECT * FROM %s where guid='%s'",
+						TRANSACTION_TABLE, guid_buf );
+	query = gda_query_new_from_sql( be->pDict, buf, &error );
+	g_free( buf );
+	if( query == NULL ) {
+		printf( "SQL error: %s\n", error->message );
+		return;
+	}
+	error = NULL;
+	ret = gda_query_execute( query, NULL, FALSE, &error );
+
+	if( error != NULL ) {
+		printf( "SQL error: %s\n", error->message );
+	}
+	if( GDA_IS_DATA_MODEL( ret ) ) {
+		GdaDataModel* pModel = (GdaDataModel*)ret;
+		int numRows = gda_data_model_get_n_rows( pModel );
+		int r;
+
+		for( r = 0; r < numRows; r++ ) {
+			load_tx( be, pModel, r, NULL );
+		}
+	}
+}
+
+static void
+query_transactions( GncGdaBackend* be, const gchar* sql )
+{
+	GError* error = NULL;
+	GdaQuery* query;
+	GdaObject* ret;
+
+	query = gda_query_new_from_sql( be->pDict, sql, &error );
+	if( query == NULL ) {
+		printf( "SQL error: %s\n", error->message );
+		return;
+	}
+	error = NULL;
+	ret = gda_query_execute( query, NULL, FALSE, &error );
+
+	if( error != NULL ) {
+		printf( "SQL error: %s\n", error->message );
+	}
+	if( GDA_IS_DATA_MODEL( ret ) ) {
+		GdaDataModel* pModel = (GdaDataModel*)ret;
+		int numRows = gda_data_model_get_n_rows( pModel );
+		int r;
+
+		for( r = 0; r < numRows; r++ ) {
+			load_tx( be, pModel, r, NULL );
+		}
+	}
+}
+
 /* ================================================================= */
 static void
 create_transaction_tables( GncGdaBackend* be )
@@ -347,6 +521,9 @@
 {
 	Transaction* pTx = (Transaction*)inst;
 
+	// Ensure the commodity is in the db
+	gnc_gda_save_commodity( be, xaccTransGetCurrency( pTx ) );
+
 	(void)gnc_gda_do_db_operation( be,
 							(inst->do_free ? OP_DB_DELETE : OP_DB_ADD_OR_UPDATE ),
 							TRANSACTION_TABLE,
@@ -362,10 +539,64 @@
 }
 
 /* ================================================================= */
+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* pBackend, QofQuery* pQuery )
+{
+	gchar* buf;
+	const GUID* acct_guid;
+	gchar guid_buf[GUID_ENCODING_LENGTH+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;
+}
+
+static void
+run_split_query( GncGdaBackend* pBackend, gpointer pQuery )
+{
+	const gchar* sql = (const gchar*)pQuery;
+
+	query_transactions( pBackend, sql );
+}
+
+static void
+free_split_query( GncGdaBackend* pBackend, gpointer pQuery )
+{
+	g_free( pQuery );
+}
+
+/* ================================================================= */
 void
 gnc_gda_init_transaction_handler( void )
 {
-	static GncGdaDataType_t be_data =
+	static GncGdaDataType_t be_data_tx =
 	{
 		GNC_GDA_BACKEND_VERSION,
 		GNC_ID_TRANS,
@@ -373,8 +604,20 @@
 		NULL,						/* initial_load */
 		create_transaction_tables	/* create tables */
 	};
+	static GncGdaDataType_t be_data_split =
+	{
+		GNC_GDA_BACKEND_VERSION,
+		GNC_ID_SPLIT,
+		NULL,						/* 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 );
+	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 ===================== */



More information about the gnucash-changes mailing list