diff --git a/src/engine/sql/PostgresBackend.c b/src/engine/sql/PostgresBackend.c index cd516649c8..082197694f 100644 --- a/src/engine/sql/PostgresBackend.c +++ b/src/engine/sql/PostgresBackend.c @@ -878,7 +878,7 @@ pgendStoreAllTransactions (PGBackend *be, AccountGroup *grp) * If this routine finds a pre-existing transaction in the engine, * and the version of last modification of this transaction is * equal to or *newer* then what the DB holds, then this routine - * returns 0 if equal, and +1 if newr, and does *not* perform any + * returns 0 if equal, and +1 if newer, and does *not* perform any * update. (Note that 0 is returned for various error conditions. * Thus, testing for 0 is a bad idea. This is a hack, and should * probably be fixed. @@ -1322,6 +1322,7 @@ query_cb (PGBackend *be, PGresult *result, int j, gpointer data) { if (guid_equal ((GUID *)node->data, trans_guid)) { + xaccGUIDFree (trans_guid); return xaction_list; } } @@ -1366,13 +1367,13 @@ pgendFillOutToCheckpoint (PGBackend *be, const char *query_string) GList *split_list, *snode; Timespec ts; Transaction *trans; - int found = 0; trans = xaccTransLookup (trans_guid); ts = xaccTransRetDatePostedTS (trans); split_list = xaccTransGetSplitList (trans); for (snode=split_list; snode; snode=snode->next) { + int found = 0; Split *s = (Split *) snode->data; Account *acc = xaccSplitGetAccount (s); diff --git a/src/engine/sql/README b/src/engine/sql/README index a2496bdc87..49d45f1618 100644 --- a/src/engine/sql/README +++ b/src/engine/sql/README @@ -238,6 +238,9 @@ access). this is a waste of time. This occurs primarily for transaction memos, I think. +-- minor optimization: keeping an iguid cache will avoid sql queries. + also caching the count for single-user mode would be good + To Be Done, Part II ------------------- This list only affects the multi-user and advanced/optional features. @@ -245,8 +248,8 @@ This list only affects the multi-user and advanced/optional features. Most of the items on this list are 'critical' in the sense that multi-user mode is fundamentally broken unless they are fixed. --- bug: if user modifies entry, account starting balances are - set incorrectly. +-- multi-user mode says 'not saved, save?' we keep clearing this flag, + when is it getting set ??? -- modify checkpoint computation to always occur on fixed dates. Failure to do so causes the fill-out algorithm to pull in all @@ -318,6 +321,13 @@ multi-user mode is fundamentally broken unless they are fixed. -- review & match up against docs at http://www.lupercalia.net/gnc-db/ +-- nice-to-have performance improvement: + many queries are needlessly duplicated, even in multi-user mode. + They are duplicated just in case some other user has modified + the data. But if we last checked just a few seconds ago, + we don't really need to update, not yet. We can wait a few + seconds ... doing this uniformly can cut down on sql traffic. + -- use version numbers for commodities. Right now, multi-user updates of commodities are not detected (this seem OK for now, since this is a rare occurrence, right ???) diff --git a/src/engine/sql/checkpoint.c b/src/engine/sql/checkpoint.c index e70d2eed52..2ee7bdc7a5 100644 --- a/src/engine/sql/checkpoint.c +++ b/src/engine/sql/checkpoint.c @@ -302,11 +302,19 @@ pgendTransactionRecomputeCheckpoints (PGBackend *be, Transaction *trans) * Then we fill in the balance fields for the returned query. */ +static gpointer +get_checkpoint_cb (PGBackend *be, PGresult *result, int j, gpointer data) +{ + Checkpoint *chk = (Checkpoint *) data; + chk->balance = atoll(DB_GET_VAL("baln", j)); + chk->cleared_balance = atoll(DB_GET_VAL("cleared_baln", j)); + chk->reconciled_balance = atoll(DB_GET_VAL("reconed_baln", j)); + return data; +} + static void pgendAccountGetCheckpoint (PGBackend *be, Checkpoint *chk) { - PGresult *result; - int i, nrows; char * p; if (!be || !chk) return; @@ -327,34 +335,7 @@ pgendAccountGetCheckpoint (PGBackend *be, Checkpoint *chk) p = stpcpy (p, "';"); SEND_QUERY (be,be->buff, ); - i=0; nrows=0; - do { - GET_RESULTS (be->connection, result); - { - int j=0, jrows; - int ncols = PQnfields (result); - jrows = PQntuples (result); - nrows += jrows; - PINFO ("query result %d has %d rows and %d cols", - i, nrows, ncols); - - if (1 < nrows) - { - PERR ("excess data"); - PQclear (result); - return; - } - if (0 < nrows ) - { - chk->balance = atoll(DB_GET_VAL("baln", j)); - chk->cleared_balance = atoll(DB_GET_VAL("cleared_baln", j)); - chk->reconciled_balance = atoll(DB_GET_VAL("reconed_baln", j)); - } - } - - PQclear (result); - i++; - } while (result); + pgendGetResults (be, get_checkpoint_cb, chk); LEAVE("be=%p", be); } @@ -388,6 +369,10 @@ pgendAccountGetBalance (PGBackend *be, Account *acc, Timespec as_of_date) /* get the checkpoint */ pgendAccountGetCheckpoint (be, &chk); +/* hack alert --- xxxxxxxxxx I think we need to tot up all entries +since the end of the checkpoint too */ + + /* set the account balances */ deno = gnc_commodity_get_fraction (com); baln = gnc_numeric_create (chk.balance, deno); @@ -396,8 +381,13 @@ pgendAccountGetBalance (PGBackend *be, Account *acc, Timespec as_of_date) xaccAccountSetStartingBalance (acc, baln, cleared_baln, reconciled_baln); - LEAVE("be=%p baln=%lld/%lld clr=%lld/%lld rcn=%lld/%lld", be, + { + char buf[80]; + gnc_timespec_to_iso8601_buff (as_of_date, buf); + LEAVE("be=%p %s %s baln=%lld/%lld clr=%lld/%lld rcn=%lld/%lld", be, + xaccAccountGetDescription (acc), buf, chk.balance, deno, chk.cleared_balance, deno, chk.reconciled_balance, deno); + } return chk.date_start; } diff --git a/src/engine/sql/kvp-sql.c b/src/engine/sql/kvp-sql.c index 904bbeb97f..a89f8b1f5c 100644 --- a/src/engine/sql/kvp-sql.c +++ b/src/engine/sql/kvp-sql.c @@ -348,7 +348,6 @@ pgendKVPStore (PGBackend *be, const GUID *guid, kvp_frame *kf) * and poke them into our local cache. */ - static gpointer path_loader (PGBackend *be, PGresult *result, int j, gpointer data) { @@ -363,6 +362,16 @@ pgendKVPInit (PGBackend *be) { char *p; + /* don't re-init multiple times in single-user mode. + * Once is enough. But in multi-user mode, we need to + * check constantly, since other users may have added + * more paths. + */ + if (((MODE_SINGLE_UPDATE == be->session_mode) || + (MODE_SINGLE_FILE == be->session_mode)) && + (0 < be->ipath_max)) return; + + /* get new paths out of the database */ p = be->buff; *p=0; p = stpcpy (p, "SELECT * FROM gncPathCache WHERE ipath > "); p += sprintf (p, "%d", be->ipath_max);