diff --git a/src/engine/sql/PostgresBackend.c b/src/engine/sql/PostgresBackend.c index 1155e091dc..b17c4dda3c 100644 --- a/src/engine/sql/PostgresBackend.c +++ b/src/engine/sql/PostgresBackend.c @@ -2054,12 +2054,6 @@ pgendSync (Backend *bend, AccountGroup *grp) pgendStoreGroup (be, grp); pgendStoreAllTransactions (be, grp); - /* although the book may be open in 'single-user' mode right now, - * it might be opened in multi-user mode next time. Thus, update - * the account balance checkpoints just in case. - */ - pgendGroupRecomputeAllCheckpoints (be, grp); - /* don't send events to GUI, don't accept callbacks to backend */ gnc_engine_suspend_events(); pgendDisable(be); @@ -2440,6 +2434,29 @@ pgend_session_end (Backend *bend) ENTER("be=%p", be); + /* mode-specific shutdowns */ + switch (be->session_mode) + { + case MODE_SINGLE_FILE: + case MODE_SINGLE_UPDATE: + /* although the book may be open in 'single-user' mode right now, + * it might be opened in multi-user mode next time. Thus, update + * the account balance checkpoints just in case. + */ + pgendGroupRecomputeAllCheckpoints (be, be->topgroup); + break; + + case MODE_POLL: + break; + + case MODE_EVENT: + break; + + default: + PERR ("bad mode specified"); + break; + } + /* prevent further callbacks into backend */ pgendDisable(be); be->be.book_begin = NULL; @@ -2500,6 +2517,7 @@ pgend_book_load_poll (Backend *bend) pgendEnable(be); gnc_engine_resume_events(); + be->topgroup = grp; return grp; } @@ -2554,6 +2572,7 @@ pgend_book_load_single (Backend *bend) pgendEnable(be); gnc_engine_resume_events(); + be->topgroup = grp; return grp; } @@ -3165,6 +3184,8 @@ pgendInit (PGBackend *be) (be->path_cache)[i] = NULL; } be->ipath_max = 0; + + be->topgroup = NULL; } /* ============================================================= */ diff --git a/src/engine/sql/PostgresBackend.h b/src/engine/sql/PostgresBackend.h index 74d2385e66..57ea3be8dc 100644 --- a/src/engine/sql/PostgresBackend.h +++ b/src/engine/sql/PostgresBackend.h @@ -85,6 +85,9 @@ struct _pgend { char **path_cache; int path_cache_size; int ipath_max; + + /* enginge data caches -- not used anywhere except in session_end */ + AccountGroup *topgroup; }; /* diff --git a/src/engine/sql/checkpoint.c b/src/engine/sql/checkpoint.c index 1ae691bb8a..cdd12e5041 100644 --- a/src/engine/sql/checkpoint.c +++ b/src/engine/sql/checkpoint.c @@ -93,9 +93,9 @@ pgendAccountRecomputeAllCheckpoints (PGBackend *be, const GUID *acct_guid) /* prevent others from inserting any splits while we recompute * the checkpoints. (hack alert -verify that this is the correct * lock) */ - p = "BEGIN WORK; " - "LOCK TABLE gncCheckpoint IN ACCESS EXCLUSIVE MODE; " - "LOCK TABLE gncEntry IN SHARE MODE; "; + p = "BEGIN WORK;\n" + "LOCK TABLE gncCheckpoint IN ACCESS EXCLUSIVE MODE;\n" + "LOCK TABLE gncEntry IN SHARE MODE;\n"; SEND_QUERY (be,p, ); FINISH_QUERY(be->connection); @@ -206,13 +206,13 @@ done: * subtotal balances */ p = be->buff; *p = 0; p = stpcpy (p, "UPDATE gncCheckpoint SET " - " balance = (gncsubtotalbalance (accountGuid, date_start, date_end ))," - " cleared_balance = (gncsubtotalclearedbalance (accountGuid, date_start, date_end ))," - " reconciled_balance = (gncsubtotalreconedbalance (accountGuid, date_start, date_end )) " - "WHERE accountGuid='"); + " balance = (gncsubtotalbalance (accountGuid, date_start, date_end ))," + " cleared_balance = (gncsubtotalclearedbalance (accountGuid, date_start, date_end ))," + " reconciled_balance = (gncsubtotalreconedbalance (accountGuid, date_start, date_end )) " + " WHERE accountGuid='"); p = stpcpy (p, guid_string); - p = stpcpy (p, "'; "); - p = stpcpy (p, "COMMIT WORK;"); + p = stpcpy (p, "';\n"); + p = stpcpy (p, "COMMIT WORK;\n"); SEND_QUERY (be,be->buff, ); FINISH_QUERY(be->connection); @@ -236,6 +236,37 @@ pgendGroupRecomputeAllCheckpoints (PGBackend *be, AccountGroup *grp) g_list_free (acclist); } +/* ============================================================= */ +/* recompute *one* checkpoints for the account */ + +void +pgendAccountRecomputeOneCheckpoint (PGBackend *be, Account *acc, Timespec ts) +{ + char *p, dbuf[80]; + + gnc_timespec_to_iso8601_buff (ts, dbuf); + + p = be->buff; *p = 0; + p = stpcpy (p, "BEGIN WORK;\n" + "LOCK TABLE gncCheckpoint IN ACCESS EXCLUSIVE MODE;\n" + "LOCK TABLE gncEntry IN SHARE MODE;\n" + "UPDATE gncCheckpoint SET " + " balance = (gncsubtotalbalance (accountGuid, date_start, date_end ))," + " cleared_balance = (gncsubtotalclearedbalance (accountGuid, date_start, date_end ))," + " reconciled_balance = (gncsubtotalreconedbalance (accountGuid, date_start, date_end )) " + " WHERE accountGuid='"); + p = guid_to_string_buff (xaccAccountGetGUID(acc), p); + p = stpcpy (p, "' AND date_start <= '"); + p = stpcpy (p, dbuf); + p = stpcpy (p, "' AND date_end > '"); + p = stpcpy (p, dbuf); + p = stpcpy (p, "';\n"); + + p = stpcpy (p, "COMMIT WORK;\n"); + SEND_QUERY (be,be->buff, ); + FINISH_QUERY(be->connection); +} + /* ============================================================= */ /* get checkpoint value for the account * We find the checkpoint which matches the account and commodity, diff --git a/src/engine/sql/checkpoint.h b/src/engine/sql/checkpoint.h index e11d2b520b..fa72f314bc 100644 --- a/src/engine/sql/checkpoint.h +++ b/src/engine/sql/checkpoint.h @@ -77,6 +77,7 @@ typedef struct _checkpoint { #define CK_AFTER_LAST_DATE "2038-01-02 12:12:12.00" +void pgendAccountRecomputeOneCheckpoint (PGBackend *be, Account *acc, Timespec ts); void pgendGroupRecomputeAllCheckpoints (PGBackend *, AccountGroup *); void pgendGroupGetAllBalances (PGBackend *, AccountGroup *, Timespec as_of_date);