mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
new improved prototype
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@2328 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
@@ -2,8 +2,9 @@
|
||||
* PostgressBackend.c
|
||||
*
|
||||
* Implements the callbacks for the postgress backend.
|
||||
* this is some seriously broken, poorly designed code.
|
||||
* its meant to be a quiick hack just ot check things out.
|
||||
* this is somewhat seriously broken, poorly designed code.
|
||||
* its meant to be a quick hack just ot check things out.
|
||||
* it needs extensive review and design checking
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -64,19 +65,20 @@ static void
|
||||
pgendStoreOneGroupOnly (PGBackend *be, AccountGroup *grp)
|
||||
{
|
||||
Account *parent;
|
||||
const GUID *parent_guid, *grp_guid;
|
||||
const char *parent_guid, *grp_guid;
|
||||
int i, nacc;
|
||||
|
||||
ENTER ("be=%p, grp=%p\n", be, grp);
|
||||
if (!be || !grp) return;
|
||||
|
||||
grp_guid = xaccGroupGetGUID (grp);
|
||||
grp_guid = guid_to_string(xaccGroupGetGUID (grp));
|
||||
parent = xaccGroupGetParentAccount(grp);
|
||||
parent_guid = xaccAccountGetGUID (parent);
|
||||
parent_guid = guid_to_string(xaccAccountGetGUID (parent));
|
||||
nacc = xaccGroupGetNumAccounts(grp);
|
||||
|
||||
for (i=0; i<nacc; i++) {
|
||||
Account *acc = xaccGroupGetAccount(grp, i);
|
||||
const char * acc_guid = guid_to_string(xaccAccountGetGUID (acc));
|
||||
|
||||
/* hack alert -- values should be escaped so that no '' apear in them */
|
||||
snprintf (be->buff, be->bufflen,
|
||||
@@ -84,16 +86,19 @@ pgendStoreOneGroupOnly (PGBackend *be, AccountGroup *grp)
|
||||
"(groupGuid, parentGuid, childGuid)"
|
||||
" values "
|
||||
"('%s', '%s', '%s');",
|
||||
guid_to_string(grp_guid),
|
||||
guid_to_string(parent_guid),
|
||||
guid_to_string(xaccAccountGetGUID (acc))
|
||||
grp_guid,
|
||||
parent_guid,
|
||||
acc_guid
|
||||
);
|
||||
|
||||
free ((char *) acc_guid);
|
||||
SEND_QUERY(be);
|
||||
|
||||
/* complete/commit the transaction, check the status */
|
||||
FLUSH(be->connection);
|
||||
}
|
||||
free ((char *) grp_guid);
|
||||
free ((char *) parent_guid);
|
||||
|
||||
LEAVE ("\n");
|
||||
}
|
||||
@@ -107,10 +112,14 @@ pgendStoreOneGroupOnly (PGBackend *be, AccountGroup *grp)
|
||||
static void
|
||||
pgendStoreOneAccountOnly (PGBackend *be, Account *acct)
|
||||
{
|
||||
|
||||
const char *acct_guid, *parent_guid, *child_guid;
|
||||
ENTER ("be=%p, acct=%p\n", be, acct);
|
||||
if (!be || !acct) return;
|
||||
|
||||
acct_guid = guid_to_string(xaccAccountGetGUID (acct));
|
||||
parent_guid = guid_to_string(xaccGroupGetGUID (xaccAccountGetParent(acct)));
|
||||
child_guid = guid_to_string(xaccGroupGetGUID (xaccAccountGetChildren(acct)));
|
||||
|
||||
/* hack alert -- values should be escaped so that no '' apear in them */
|
||||
snprintf (be->buff, be->bufflen,
|
||||
"INSERT INTO gncAccount "
|
||||
@@ -120,9 +129,9 @@ pgendStoreOneAccountOnly (PGBackend *be, Account *acct)
|
||||
" values "
|
||||
"('%s', '%s', '%s', '%s', '%s', '%s', '%s', "
|
||||
"%d, '%s', '%s');",
|
||||
guid_to_string(xaccAccountGetGUID (acct)),
|
||||
guid_to_string(xaccGroupGetGUID (xaccAccountGetParent(acct))),
|
||||
guid_to_string(xaccGroupGetGUID (xaccAccountGetChildren(acct))),
|
||||
acct_guid,
|
||||
parent_guid,
|
||||
child_guid,
|
||||
xaccAccountGetName (acct),
|
||||
xaccAccountGetCode (acct),
|
||||
xaccAccountGetDescription (acct),
|
||||
@@ -131,6 +140,9 @@ pgendStoreOneAccountOnly (PGBackend *be, Account *acct)
|
||||
xaccAccountGetCurrency (acct),
|
||||
xaccAccountGetSecurity (acct)
|
||||
);
|
||||
free ((char *) acct_guid);
|
||||
free ((char *) parent_guid);
|
||||
free ((char *) child_guid);
|
||||
|
||||
SEND_QUERY (be);
|
||||
|
||||
@@ -149,21 +161,25 @@ pgendStoreOneAccountOnly (PGBackend *be, Account *acct)
|
||||
static void
|
||||
pgendStoreOneTransactionOnly (PGBackend *be, Transaction *trans)
|
||||
{
|
||||
const char * trans_guid;
|
||||
|
||||
ENTER ("be=%p, trans=%p\n", be, trans);
|
||||
if (!be || !trans) return;
|
||||
|
||||
trans_guid = guid_to_string(xaccTransGetGUID (trans));
|
||||
/* hack alert -- values should be escaped so that no '' apear in them */
|
||||
snprintf (be->buff, be->bufflen,
|
||||
"INSERT INTO gncTransaction "
|
||||
"(transGuid, num, description)"
|
||||
" values "
|
||||
"('%s', '%s', '%s');",
|
||||
guid_to_string(xaccTransGetGUID (trans)),
|
||||
trans_guid,
|
||||
xaccTransGetNum (trans),
|
||||
xaccTransGetDescription (trans)
|
||||
);
|
||||
|
||||
free ((char *) trans_guid);
|
||||
|
||||
SEND_QUERY (be);
|
||||
|
||||
/* complete/commit the transaction, check the status */
|
||||
@@ -180,10 +196,15 @@ static void
|
||||
pgendStoreOneSplitOnly (PGBackend *be, Split *split)
|
||||
{
|
||||
Timespec ts;
|
||||
const char *split_guid, *acct_guid, *trans_guid;
|
||||
|
||||
ENTER ("be=%p, split=%p\n", be, split);
|
||||
if (!be || !split) return;
|
||||
|
||||
split_guid = guid_to_string(xaccSplitGetGUID (split));
|
||||
acct_guid = guid_to_string(xaccAccountGetGUID (xaccSplitGetAccount(split)));
|
||||
trans_guid = guid_to_string(xaccTransGetGUID (xaccSplitGetParent(split)));
|
||||
|
||||
/* hack alert date is not stored ... */
|
||||
xaccSplitGetDateReconciledTS (split, &ts);
|
||||
|
||||
@@ -194,15 +215,18 @@ pgendStoreOneSplitOnly (PGBackend *be, Split *split)
|
||||
"reconciled, amount, share_price)"
|
||||
" values "
|
||||
"('%s', '%s', '%s', '%s', '%s', '%c', %g, %g);",
|
||||
guid_to_string(xaccSplitGetGUID (split)),
|
||||
guid_to_string(xaccAccountGetGUID (xaccSplitGetAccount(split))),
|
||||
guid_to_string(xaccTransGetGUID (xaccSplitGetParent(split))),
|
||||
split_guid,
|
||||
acct_guid,
|
||||
trans_guid,
|
||||
xaccSplitGetMemo(split),
|
||||
xaccSplitGetAction(split),
|
||||
xaccSplitGetReconcile(split),
|
||||
xaccSplitGetShareAmount(split),
|
||||
xaccSplitGetSharePrice(split)
|
||||
);
|
||||
free ((char *) split_guid);
|
||||
free ((char *) acct_guid);
|
||||
free ((char *) trans_guid);
|
||||
|
||||
SEND_QUERY (be);
|
||||
|
||||
@@ -212,6 +236,106 @@ pgendStoreOneSplitOnly (PGBackend *be, Split *split)
|
||||
LEAVE ("\n");
|
||||
}
|
||||
|
||||
/* ============================================================= */
|
||||
/* this routine routine returns non-zero if the indicated split
|
||||
* differs fropm that in the SQL database.
|
||||
* this routine grabs no locks.
|
||||
*/
|
||||
|
||||
static int
|
||||
pgendCompareOneSplitOnly (PGBackend *be, Split *split)
|
||||
{
|
||||
const char *split_guid;
|
||||
PGresult *result;
|
||||
int i, nrows, ncols, ndiffs=0;
|
||||
|
||||
ENTER ("be=%p, split=%p\n", be, split);
|
||||
if (!be || !split) return;
|
||||
|
||||
split_guid = guid_to_string(xaccSplitGetGUID (split));
|
||||
|
||||
/* try to find this split in the database */
|
||||
/* hack alert -- values should be escaped so that no '' apear in them */
|
||||
snprintf (be->buff, be->bufflen,
|
||||
"SELECT accountGuid, transGuid, memo, action, "
|
||||
"reconciled, amount, share_price "
|
||||
"FROM gncEntry "
|
||||
"WHERE entryGuid = '%s';",
|
||||
split_guid
|
||||
);
|
||||
free ((char *) split_guid);
|
||||
|
||||
SEND_QUERY (be);
|
||||
|
||||
i=0; nrows=0;
|
||||
do {
|
||||
ExecStatusType status;
|
||||
|
||||
result = PQgetResult (be->connection);
|
||||
if (!result) break;
|
||||
|
||||
status = PQresultStatus(result);
|
||||
|
||||
if ((PGRES_COMMAND_OK != status) &&
|
||||
(PGRES_TUPLES_OK != status))
|
||||
{
|
||||
PERR ("failed to get result to query\n");
|
||||
PQclear (result);
|
||||
/* hack alert need gentler, kinder error recovery */
|
||||
PQfinish (be->connection);
|
||||
break;
|
||||
}
|
||||
|
||||
nrows += PQntuples (result);
|
||||
ncols = PQnfields (result);
|
||||
|
||||
PINFO ("query result %d has %d rows and %d cols\n",
|
||||
i, nrows, ncols);
|
||||
if (1 < nrows) {
|
||||
PERR ("unexpected duplicate records\n");
|
||||
break;
|
||||
} else if (1 == nrows) {
|
||||
|
||||
#define GETV(str) (PQgetvalue (result, 0, PQfnumber (result, str)))
|
||||
#define COMP(sqlname,fun) if (strcmp (GETV(sqlname),fun)) { \
|
||||
PINFO("%s sql='%s', split='%s'\n", sqlname, GETV(sqlname), fun); \
|
||||
ndiffs++; }
|
||||
#define GCOMP(sqlname,fun) { \
|
||||
const char *tmp = guid_to_string(fun); \
|
||||
if (strcmp (GETV(sqlname),tmp)) { \
|
||||
PINFO("%s sql='%s', split='%s'\n", sqlname, GETV(sqlname), tmp); \
|
||||
ndiffs++; } \
|
||||
free ((char *) tmp); }
|
||||
|
||||
/* compared queried values to input values */
|
||||
COMP ("memo", xaccSplitGetMemo(split));
|
||||
COMP ("action", xaccSplitGetAction(split));
|
||||
GCOMP ("accountGuid",
|
||||
xaccAccountGetGUID (xaccSplitGetAccount(split)));
|
||||
GCOMP ("transGuid",
|
||||
xaccTransGetGUID (xaccSplitGetParent(split)));
|
||||
|
||||
PINFO ("recn=%s amt=%s price=%s\n", GETV("reconciled"), GETV("amount"),
|
||||
GETV("share_price"));
|
||||
}
|
||||
|
||||
PQclear (result);
|
||||
i++;
|
||||
} while (result);
|
||||
|
||||
if (0 == nrows) ndiffs = -1;
|
||||
|
||||
/*
|
||||
xaccSplitGetReconcile(split),
|
||||
xaccSplitGetShareAmount(split),
|
||||
xaccSplitGetSharePrice(split)
|
||||
*/
|
||||
|
||||
|
||||
LEAVE ("\n");
|
||||
return ndiffs;
|
||||
}
|
||||
|
||||
/* ============================================================= */
|
||||
/* This routine traverses the group structure and stores it into
|
||||
* the database. The NoLock version doesn't lock up the tables.
|
||||
@@ -228,9 +352,11 @@ traverse_cb (Transaction *trans, void *cb_data)
|
||||
pgendStoreOneTransactionOnly (be, trans);
|
||||
|
||||
/* walk over the list of splits */
|
||||
nsplits = xaccTransGetNumSplits (trans);
|
||||
nsplits = xaccTransCountSplits (trans);
|
||||
for (i=0; i<nsplits; i++) {
|
||||
Split * s = xaccTransGetSplit (trans, i);
|
||||
int ndiffs = pgendCompareOneSplitOnly (be, s);
|
||||
PINFO ("ndiffs = %d\n", ndiffs);
|
||||
pgendStoreOneSplitOnly (be, s);
|
||||
}
|
||||
|
||||
@@ -288,11 +414,12 @@ pgendStoreGroup (PGBackend *be, AccountGroup *grp)
|
||||
|
||||
/* ============================================================= */
|
||||
/* this routine fills in the structure pointed at by split
|
||||
* with data sucked out of the database
|
||||
* with data sucked out of the database. It does only that
|
||||
* one split,
|
||||
*/
|
||||
|
||||
static void
|
||||
pgendGetSplit (PGBackend *be, Split *split, GUID *guid)
|
||||
pgendGetOneSplitOnly (PGBackend *be, Split *split, GUID *guid)
|
||||
{
|
||||
int rc;
|
||||
|
||||
@@ -325,7 +452,8 @@ pgend_session_begin (Session *sess, const char * sessionid)
|
||||
|
||||
ENTER("sessionid=%s\n", sessionid);
|
||||
/* connect to a bogus database ... */
|
||||
/* hack alert -- clean this up ... */
|
||||
/* hack alert -- we should be parsing the sessionid for the
|
||||
* hostname, port number, db name, etc... clean this up ... */
|
||||
be->dbName = strdup ("gnc_bogus");
|
||||
be->connection = PQsetdbLogin (NULL, NULL, NULL, NULL, be->dbName, NULL, NULL);
|
||||
|
||||
@@ -365,6 +493,8 @@ pgend_trans_commit_edit (Backend * bend, Transaction * trans)
|
||||
nsplits = xaccTransCountSplits (trans);
|
||||
for (i=0; i<nsplits; i++) {
|
||||
Split *s = xaccTransGetSplit (trans, i);
|
||||
int ndiffs = pgendCompareOneSplitOnly (be, s);
|
||||
PINFO ("ndiffs = %d\n", ndiffs);
|
||||
pgendStoreOneSplitOnly (be, s);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,13 +17,13 @@ CREATE TABLE gncAccount (
|
||||
accountGuid CHAR(32) PRIMARY KEY,
|
||||
parentGuid CHAR(32),
|
||||
childrenGuid CHAR(32),
|
||||
accountName VARCHAR(40) DEFAULT 'xoxo',
|
||||
accountCode VARCHAR(8),
|
||||
description VARCHAR(120),
|
||||
notes VARCHAR(120),
|
||||
accountName TEXT DEFAULT 'xoxo',
|
||||
accountCode TEXT,
|
||||
description TEXT,
|
||||
notes TEXT,
|
||||
type INT2,
|
||||
currency VARCHAR(8),
|
||||
security VARCHAR(8)
|
||||
currency TEXT,
|
||||
security TEXT
|
||||
);
|
||||
|
||||
-- hack alert -- docref ??
|
||||
@@ -33,8 +33,8 @@ CREATE TABLE gncTransaction (
|
||||
transGuid CHAR(32) PRIMARY KEY,
|
||||
date_entered DATETIME,
|
||||
date_posted DATETIME,
|
||||
num VARCHAR(8),
|
||||
description VARCHAR(32)
|
||||
num TEXT,
|
||||
description TEXT
|
||||
);
|
||||
|
||||
-- a gncEntry is what we call 'Split' elsewhere in the engine
|
||||
@@ -44,8 +44,8 @@ CREATE TABLE gncEntry (
|
||||
entryGuid CHAR(32) PRIMARY KEY,
|
||||
accountGuid CHAR(32),
|
||||
transGuid CHAR(32),
|
||||
memo VARCHAR(20),
|
||||
action VARCHAR(20),
|
||||
memo TEXT,
|
||||
action TEXT,
|
||||
reconciled CHAR,
|
||||
date_reconciled DATETIME,
|
||||
amount FLOAT8 DEFAULT '0.0',
|
||||
|
||||
Reference in New Issue
Block a user