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