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:
Linas Vepstas
2001-06-03 23:27:10 +00:00
parent fbffc3e5d1
commit 562da87fe2
3 changed files with 94 additions and 68 deletions

View File

@@ -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;";

View File

@@ -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)

View File

@@ -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 */