From da601a847d875f914834231a48c4d832e6506b6e Mon Sep 17 00:00:00 2001 From: Dave Peticolas Date: Sat, 29 Dec 2001 12:14:20 +0000 Subject: [PATCH] work on tests and sql backend git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@6416 57a11ea4-9604-0410-9ed3-97b8803252fd --- src/backend/postgres/PostgresBackend.c | 16 ++- src/backend/postgres/account.c | 4 +- src/backend/postgres/checkpoint.c | 7 ++ src/backend/postgres/test/test-db.c | 26 ++-- src/backend/postgres/txn.c | 157 ++++++++++++++++++------- 5 files changed, 154 insertions(+), 56 deletions(-) diff --git a/src/backend/postgres/PostgresBackend.c b/src/backend/postgres/PostgresBackend.c index 298dba949e..0b708662d5 100644 --- a/src/backend/postgres/PostgresBackend.c +++ b/src/backend/postgres/PostgresBackend.c @@ -500,26 +500,30 @@ pgendFillOutToCheckpoint (PGBackend *be, const char *query_string) char *p; AcctEarliest * ae = (AcctEarliest *) anode->data; pgendAccountGetBalance (be, ae->acct, ae->ts); - + /* n.b. date_posted compare must be strictly greater than, since the * GetBalance goes to less-then-or-equal-to because of the BETWEEN * that appears in the gncSubTotalBalance sql function. */ p = be->buff; *p = 0; - p = stpcpy (p, "SELECT DISTINCT gncTransaction.* from gncEntry, gncTransaction WHERE " - " gncEntry.transGuid = gncTransaction.transGuid AND gncEntry.accountGuid='"); + p = stpcpy (p, + "SELECT DISTINCT gncTransaction.* " + "FROM gncEntry, gncTransaction WHERE " + "gncEntry.transGuid = gncTransaction.transGuid AND " + "gncEntry.accountGuid='"); p = guid_to_string_buff(xaccAccountGetGUID(ae->acct), p); p = stpcpy (p, "' AND gncTransaction.date_posted > '"); p = gnc_timespec_to_iso8601_buff (ae->ts, p); p = stpcpy (p, "';"); - + pgendFillOutToCheckpoint (be, be->buff); - + g_free (ae); nact ++; } g_list_free(acct_list); - REPORT_CLOCK (9, "done w/ fillout at call %d, handled %d accounts", call_count, nact); + REPORT_CLOCK (9, "done w/ fillout at call %d, handled %d accounts", + call_count, nact); LEAVE (" "); } diff --git a/src/backend/postgres/account.c b/src/backend/postgres/account.c index b8dad26778..176ac72c61 100644 --- a/src/backend/postgres/account.c +++ b/src/backend/postgres/account.c @@ -384,10 +384,10 @@ pgendCopyAccountToEngine (PGBackend *be, const GUID *acct_guid) pbuff = be->buff; pbuff[0] = 0; pbuff = stpcpy (pbuff, - "SELECT * FROM gncAccount WHERE accountGuid='"); + "SELECT * FROM gncAccount WHERE accountGuid='"); pbuff = guid_to_string_buff(acct_guid, pbuff); pbuff = stpcpy (pbuff, "';"); - + SEND_QUERY (be,be->buff, 0); pgendGetResults (be, get_account_cb, pgendGetTopGroup (be)); diff --git a/src/backend/postgres/checkpoint.c b/src/backend/postgres/checkpoint.c index f255d05a0e..00c6e843db 100644 --- a/src/backend/postgres/checkpoint.c +++ b/src/backend/postgres/checkpoint.c @@ -446,6 +446,13 @@ pgendAccountGetBalance (PGBackend *be, Account *acc, Timespec as_of_date) chk.date_end = as_of_date; com = xaccAccountGetCommodity(acc); + if (!com) + { + PERR ("account %s has no commodity", + guid_to_string (xaccAccountGetGUID (acc))); + return; + } + chk.commodity = gnc_commodity_get_unique_name(com); chk.account_guid = xaccAccountGetGUID (acc); chk.balance = 0; diff --git a/src/backend/postgres/test/test-db.c b/src/backend/postgres/test/test-db.c index 501eecb8cd..e00f891658 100644 --- a/src/backend/postgres/test/test-db.c +++ b/src/backend/postgres/test/test-db.c @@ -488,11 +488,6 @@ test_raw_query (GNCSession *session, Query *q) sq = sqlQuery_new(); sql_query_string = sqlQuery_build (sq, q, gnc_session_get_book(session)); -#if 0 - fputs (sql_query_string, stderr); - fputs ("\n", stderr); -#endif - result = PQexec (be->connection, sql_query_string); ok = (result && PQresultStatus (result) == PGRES_TUPLES_OK); @@ -852,7 +847,7 @@ test_updates_2 (GNCSession *session_base, #if 0 { Account * account = get_random_account (td.book_1); - Account * child = get_random_account (td.book_1); + Account * child = NULL; /* get_random_account (td.book_1); */ Transaction * trans = get_random_transaction (td.book_1); Query * q = xaccMallocQuery (); int count = 0; @@ -869,12 +864,12 @@ test_updates_2 (GNCSession *session_base, { Split * split = node->data; - xaccAccountInsertSplit (child, split); + xaccAccountInsertSplit (account, split); count++; } xaccTransCommitEdit (trans); - xaccQueryAddGUIDMatch (q, xaccAccountGetGUID (child), + xaccQueryAddGUIDMatch (q, xaccAccountGetGUID (account), GNC_ID_ACCOUNT, QUERY_AND); xaccQuerySetGroup (q, td.group_2); @@ -883,6 +878,21 @@ test_updates_2 (GNCSession *session_base, xaccFreeQuery (q); + if (ok) + { + Transaction * trans_2; + Account * account_2; + Account * child_2; + + trans_2 = xaccTransLookup (xaccTransGetGUID (trans), td.book_2); + account_2 = xaccAccountLookup (xaccAccountGetGUID (account), td.book_2); + child_2 = xaccAccountLookup (xaccAccountGetGUID (child), td.book_2); + + ok = ok && xaccTransEqual (trans, trans_2, TRUE, TRUE); + ok = ok && xaccAccountEqual (account, account_2, TRUE); + ok = ok && xaccAccountEqual (child, child_2, TRUE); + } + if (!do_test_args (ok, "test new account", __FILE__, __LINE__, diff --git a/src/backend/postgres/txn.c b/src/backend/postgres/txn.c index 1eff659c14..86e38a61c2 100644 --- a/src/backend/postgres/txn.c +++ b/src/backend/postgres/txn.c @@ -44,6 +44,7 @@ #include "TransactionP.h" #include "PostgresBackend.h" +#include "account.h" #include "checkpoint.h" #include "kvp-sql.h" #include "price.h" @@ -409,16 +410,23 @@ pgendStoreAllTransactions (PGBackend *be, AccountGroup *grp) * probably be fixed. */ +typedef struct +{ + Split * split; + GUID account_guid; + gint64 amount; +} SplitResolveInfo; + void pgendCopySplitsToEngine (PGBackend *be, Transaction *trans) { char *pbuff; int i, j, nrows; PGresult *result; - int save_state = 1; const GUID *trans_guid; Account *acc, *previous_acc=NULL; GList *node, *db_splits=NULL, *engine_splits, *delete_splits=NULL; + GList *unresolved_splits = NULL; gnc_commodity *currency = NULL; gint64 trans_frac = 0; @@ -430,7 +438,7 @@ pgendCopySplitsToEngine (PGBackend *be, Transaction *trans) pbuff = be->buff; pbuff[0] = 0; pbuff = stpcpy (pbuff, - "SELECT * FROM gncEntry WHERE transGuid='"); + "SELECT * FROM gncEntry WHERE transGuid='"); pbuff = guid_to_string_buff(trans_guid, pbuff); pbuff = stpcpy (pbuff, "';"); @@ -444,7 +452,7 @@ pgendCopySplitsToEngine (PGBackend *be, Transaction *trans) jrows = PQntuples (result); nrows += jrows; PINFO ("query result %d has %d rows and %d cols", - i, nrows, ncols); + i, nrows, ncols); for (j=0; jbook); + if (!acc) { - PERR ("account not found, will delete this split\n" - "\t(split with guid=%s\n" - "\twants an acct with guid=%s)\n", - DB_GET_VAL("entryGUID",j), - DB_GET_VAL("accountGUID",j) - ); - xaccSplitDestroy (s); + SplitResolveInfo *sri = g_new0 (SplitResolveInfo, 1); + + sri->split = s; + sri->account_guid = guid; + sri->amount = strtoll (DB_GET_VAL("amount", j), NULL, 0); + + unresolved_splits = g_list_prepend (unresolved_splits, sri); } - else + + xaccTransAppendSplit (trans, s); + + if (acc) { - gnc_commodity *modity; - gint64 acct_frac; + int save_state; - xaccTransAppendSplit (trans, s); + if (acc != previous_acc) + { + xaccAccountCommitEdit (previous_acc); + xaccAccountBeginEdit (acc); + previous_acc = acc; + } - if (acc != previous_acc) - { - xaccAccountCommitEdit (previous_acc); - xaccAccountBeginEdit (acc); - previous_acc = acc; - } - if (acc->parent) save_state = acc->parent->saved; - xaccAccountInsertSplit(acc, s); - if (acc->parent) acc->parent->saved = save_state; + if (acc->parent) + save_state = acc->parent->saved; + else + save_state = 1; - /* Ummm, we really need to set the amount & value after - * the split has been inserted into the account. This - * is because the amount/value setting routines require - * SCU settings from the account to work correctly. - */ - num = strtoll (DB_GET_VAL("value", j), NULL, 0); - value = gnc_numeric_create (num, trans_frac); - xaccSplitSetValue (s, value); + xaccAccountInsertSplit(acc, s); - num = strtoll (DB_GET_VAL("amount", j), NULL, 0); - modity = xaccAccountGetCommodity (acc); - acct_frac = gnc_commodity_get_fraction (modity); - amount = gnc_numeric_create (num, acct_frac); - xaccSplitSetAmount (s, amount); - - /* finally tally them up; we use this below to - * clean out deleted splits */ - db_splits = g_list_prepend (db_splits, s); + if (acc->parent) + acc->parent->saved = save_state; } + + /* It's ok to set value without an account, since + * the fraction depends on the transaction and not + * the account. */ + num = strtoll (DB_GET_VAL("value", j), NULL, 0); + value = gnc_numeric_create (num, trans_frac); + xaccSplitSetValue (s, value); + + if (acc) + { + int acct_frac; + + num = strtoll (DB_GET_VAL("amount", j), NULL, 0); + acct_frac = xaccAccountGetCommoditySCU (acc); + amount = gnc_numeric_create (num, acct_frac); + xaccSplitSetAmount (s, amount); + } + + /* finally tally them up; we use this below to + * clean out deleted splits */ + db_splits = g_list_prepend (db_splits, s); } } i++; @@ -536,6 +554,65 @@ pgendCopySplitsToEngine (PGBackend *be, Transaction *trans) /* close out dangling edit session */ xaccAccountCommitEdit (previous_acc); + /* resolve any splits that didn't have accounts */ + for (node = unresolved_splits; node; node = node->next) + { + SplitResolveInfo * sri = node->data; + Account * account; + + /* account could have been pulled in by a previous + * iteration of this loop. */ + account = xaccAccountLookup (&sri->account_guid, be->book); + + if (!account) + { + pgendCopyAccountToEngine (be, &sri->account_guid); + account = xaccAccountLookup (&sri->account_guid, be->book); + } + + if (account) + { + gnc_numeric amount; + int save_state; + int acct_frac; + + if (account->parent) + save_state = account->parent->saved; + else + save_state = 1; + + xaccAccountBeginEdit (account); + xaccAccountInsertSplit (account, sri->split); + xaccAccountCommitEdit (account); + + if (account->parent) + account->parent->saved = save_state; + + acct_frac = xaccAccountGetCommoditySCU (account); + amount = gnc_numeric_create (sri->amount, acct_frac); + xaccSplitSetAmount (sri->split, amount); + } + else + { + PERR ("account not found, will delete this split\n" + "\t(split with guid=%s\n" + "\twants an acct with guid=%s)\n", + guid_to_string(xaccSplitGetGUID (sri->split)), + guid_to_string(&sri->account_guid)); + + /* Remove the split from the list */ + db_splits = g_list_remove (db_splits, sri->split); + + xaccSplitDestroy (sri->split); + } + + g_free (sri); + node->data = NULL; + } + + g_list_free (unresolved_splits); + unresolved_splits = NULL; + /* ------------------------------------------------- */ /* destroy any splits that the engine has that the DB didn't */