mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
add price versioning
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@4401 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
@@ -200,6 +200,15 @@ pgendGetResults (PGBackend *be,
|
||||
return data;
|
||||
}
|
||||
|
||||
/* ============================================================= */
|
||||
/* version number callback for pgendGetResults */
|
||||
|
||||
static gpointer
|
||||
get_version_cb (PGBackend *be, PGresult *result, int j, gpointer data)
|
||||
{
|
||||
if (-1 != (int) data || 0 != j) return (gpointer) -1;
|
||||
return ((gpointer) atoi(DB_GET_VAL ("version", 0)));
|
||||
}
|
||||
|
||||
/* ============================================================= */
|
||||
/* include the auto-generated code */
|
||||
@@ -232,30 +241,6 @@ static const char *table_drop_str =
|
||||
* two are equal.
|
||||
*/
|
||||
|
||||
static gpointer
|
||||
acc_version_cb (PGBackend *be, PGresult *result, int j, gpointer data)
|
||||
{
|
||||
if (-1 != (int) data || 0 != j) return (gpointer) -1;
|
||||
return ((gpointer) atoi(DB_GET_VAL ("version", 0)));
|
||||
}
|
||||
|
||||
static int
|
||||
pgendAccountCompareVersion (PGBackend *be, Account *acct)
|
||||
{
|
||||
char *p;
|
||||
int sql_version = 0;
|
||||
|
||||
p = be->buff; *p = 0;
|
||||
p = stpcpy (p, "SELECT version FROM gncAccount WHERE accountGuid ='");
|
||||
p = guid_to_string_buff (&(acct->guid), p);
|
||||
p = stpcpy (p, "';");
|
||||
SEND_QUERY (be,be->buff, -1);
|
||||
sql_version = (int) pgendGetResults (be, acc_version_cb, (gpointer) -1);
|
||||
|
||||
if (-1 == sql_version) return -1;
|
||||
return (sql_version - xaccAccountGetVersion (acct));
|
||||
}
|
||||
|
||||
/* ============================================================= */
|
||||
/* the pgendStoreAccount() routine stores an account to the
|
||||
* database. That is, the engine data is written out to the
|
||||
@@ -599,39 +584,6 @@ is_trans_empty (Transaction *trans)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* ============================================================= */
|
||||
/* The pgendTransCompareVersion() routine compares the version
|
||||
* number of the transaction in the engine and the sql database. It
|
||||
* returns a negative number if the sql version is older (or the
|
||||
* acount is not present in the sql db). It returns a positive
|
||||
* number if the sql version is newer. It returns zero if the
|
||||
* two are equal.
|
||||
*/
|
||||
|
||||
static gpointer
|
||||
trans_version_cb (PGBackend *be, PGresult *result, int j, gpointer data)
|
||||
{
|
||||
if (-1 != (int) data || 0 != j) return (gpointer) -1;
|
||||
return ((gpointer) atoi(DB_GET_VAL ("version", 0)));
|
||||
}
|
||||
|
||||
static int
|
||||
pgendTransCompareVersion (PGBackend *be, Transaction *trans)
|
||||
{
|
||||
char *p;
|
||||
int sql_version = 0;
|
||||
|
||||
p = be->buff; *p = 0;
|
||||
p = stpcpy (p, "SELECT version FROM gncTransaction WHERE transGuid ='");
|
||||
p = guid_to_string_buff (&(trans->guid), p);
|
||||
p = stpcpy (p, "';");
|
||||
SEND_QUERY (be,be->buff, -1);
|
||||
sql_version = (int) pgendGetResults (be, trans_version_cb, (gpointer) -1);
|
||||
|
||||
if (-1 == sql_version) return -1;
|
||||
return (sql_version - xaccTransGetVersion (trans));
|
||||
}
|
||||
|
||||
/* ============================================================= */
|
||||
/* The pgendStoreTransactionNoLock() routine traverses the transaction
|
||||
* structure and stores/updates it in the database. If checks the
|
||||
@@ -677,7 +629,7 @@ pgendStoreTransactionNoLock (PGBackend *be, Transaction *trans,
|
||||
/* don't update the database if the database is newer ... */
|
||||
if (do_check_version)
|
||||
{
|
||||
if (0 < pgendTransCompareVersion (be, trans)) return;
|
||||
if (0 < pgendTransactionCompareVersion (be, trans)) return;
|
||||
}
|
||||
trans->version ++; /* be sure to update the version !! */
|
||||
|
||||
@@ -1364,10 +1316,17 @@ pgendGetAllTransactions (PGBackend *be, AccountGroup *grp)
|
||||
/* store just one price */
|
||||
|
||||
static void
|
||||
pgendStorePriceNoLock (PGBackend *be, GNCPrice *pr)
|
||||
pgendStorePriceNoLock (PGBackend *be, GNCPrice *pr,
|
||||
gboolean do_check_version)
|
||||
{
|
||||
gnc_commodity *modity;
|
||||
|
||||
if (do_check_version)
|
||||
{
|
||||
if (0 < pgendPriceCompareVersion (be, pr)) return;
|
||||
}
|
||||
pr->version ++; /* be sure to update the version !! */
|
||||
|
||||
/* make sure that we've stored the commodity
|
||||
* and currency before we store the price.
|
||||
*/
|
||||
@@ -1777,7 +1736,7 @@ pgend_trans_commit_edit (Backend * bend,
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (0 < pgendTransCompareVersion (be, oldtrans)) rollback ++;
|
||||
if (0 < pgendTransactionCompareVersion (be, oldtrans)) rollback ++;
|
||||
#endif
|
||||
|
||||
if (rollback) {
|
||||
@@ -1841,8 +1800,26 @@ pgend_price_commit_edit (Backend * bend, GNCPrice *pr)
|
||||
SEND_QUERY (be,bufp, 555);
|
||||
FINISH_QUERY(be->connection);
|
||||
|
||||
/* hack alert -- we should check a version number, to make
|
||||
* sure we aren't clobbering something newer in the database */
|
||||
/* check to see that the engine version is equal or newer than
|
||||
* whats in the database. It its not, then some other user has
|
||||
* made changes, and we must roll back. */
|
||||
if (0 < pgendPriceCompareVersion (be, pr))
|
||||
{
|
||||
pr->do_free = FALSE;
|
||||
bufp = "ROLLBACK;";
|
||||
SEND_QUERY (be,bufp,444);
|
||||
FINISH_QUERY(be->connection);
|
||||
|
||||
/* hack alert -- we should restore the price data from the
|
||||
* sql back end at this point ! !!! */
|
||||
PWARN(" price data in engine is newer\n"
|
||||
" price must be rolled back. This function\n"
|
||||
" is not completely implemented !! \n");
|
||||
LEAVE ("rolled back");
|
||||
return 445;
|
||||
}
|
||||
pr->version ++; /* be sure to update the version !! */
|
||||
|
||||
if (pr->do_free)
|
||||
{
|
||||
bufp = be->buff;
|
||||
@@ -1855,7 +1832,7 @@ pgend_price_commit_edit (Backend * bend, GNCPrice *pr)
|
||||
}
|
||||
else
|
||||
{
|
||||
pgendStorePriceNoLock (be, pr);
|
||||
pgendStorePriceNoLock (be, pr, FALSE);
|
||||
}
|
||||
|
||||
bufp = "COMMIT;";
|
||||
|
||||
@@ -24,3 +24,7 @@ put_one_only(modity)
|
||||
put_one_only(split)
|
||||
put_one_only(transaction)
|
||||
put_one_only(price)
|
||||
|
||||
compare_version(account)
|
||||
compare_version(transaction)
|
||||
compare_version(price)
|
||||
|
||||
@@ -192,6 +192,23 @@ cmp_fields_r(nextrec($@))')')')
|
||||
|
||||
define(`cmp_fields', `cmp_fields_r(firstrec($@))')
|
||||
|
||||
/* -------- */
|
||||
/* return the name of the sql field associcate with the primary key */
|
||||
|
||||
define(`key_fieldname_r', `ifelse($#, 1, ,
|
||||
`ifelse($2, `KEY', $1,
|
||||
`key_fieldname_r(nextrec($@))')')')
|
||||
|
||||
define(`key_fieldname', `key_fieldname_r(firstrec($@))')
|
||||
|
||||
/* -------- */
|
||||
/* return the getter function that deals with the version number */
|
||||
define(`version_function_r', `ifelse($#, 1, ,
|
||||
`ifelse($1, `version', $4,
|
||||
`version_function_r(nextrec($@))')')')
|
||||
|
||||
define(`version_function', `version_function_r(firstrec($@))')
|
||||
|
||||
/* -------- */
|
||||
|
||||
define(`store_one_only',
|
||||
@@ -235,8 +252,7 @@ define(`compare_one_only',
|
||||
*/
|
||||
|
||||
static int
|
||||
pgendCompareOne`'func_name($@)`'Only (PGBackend *be,
|
||||
xacc_type($@) *ptr)
|
||||
pgendCompareOne`'func_name($@)`'Only (PGBackend *be, xacc_type($@) *ptr)
|
||||
{
|
||||
const char *buf;
|
||||
PGresult *result;
|
||||
@@ -281,8 +297,7 @@ define(`put_one_only',
|
||||
*/
|
||||
|
||||
static void
|
||||
pgendPutOne`'func_name($@)`'Only (PGBackend *be,
|
||||
xacc_type($@) *ptr)
|
||||
pgendPutOne`'func_name($@)`'Only (PGBackend *be, xacc_type($@) *ptr)
|
||||
{
|
||||
int ndiffs;
|
||||
ndiffs = pgendCompareOne`'func_name($@)`'Only (be, ptr);
|
||||
@@ -295,5 +310,35 @@ pgendPutOne`'func_name($@)`'Only (PGBackend *be,
|
||||
|
||||
')
|
||||
|
||||
/* ------------------------------------------------------- */
|
||||
define(`compare_version',
|
||||
`
|
||||
/* ------------------------------------------------------ */
|
||||
/* This routine compares the version number of the account in
|
||||
* the engine and the sql database. It returns a negative
|
||||
* number if the sql version is older (or the item is not
|
||||
* present in the sql db). It returns a positive number
|
||||
* if the sql version is newer. It returns zero if the
|
||||
* two are equal.
|
||||
*/
|
||||
|
||||
static int
|
||||
pgend`'func_name($@)`'CompareVersion (PGBackend *be, xacc_type($@) *ptr)
|
||||
{
|
||||
char *p;
|
||||
int sql_version = 0;
|
||||
|
||||
p = be->buff; *p = 0;
|
||||
p = stpcpy (p, "SELECT version FROM tablename($@) WHERE key_fieldname($@) = ''`");
|
||||
p = guid_to_string_buff (&(ptr->guid), p);
|
||||
p = stpcpy (p, "''`;");
|
||||
SEND_QUERY (be,be->buff, -1);
|
||||
sql_version = (int) pgendGetResults (be, get_version_cb, (gpointer) -1);
|
||||
|
||||
if (-1 == sql_version) return -1;
|
||||
return (sql_version - version_function($@));
|
||||
}
|
||||
|
||||
')
|
||||
|
||||
divert
|
||||
/* DO NOT EDIT THIS FILE -- it is autogenerated -- edit table.m4 instead */
|
||||
|
||||
Reference in New Issue
Block a user