more dinkering with multi-book support

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@6510 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Linas Vepstas 2002-01-05 03:28:51 +00:00
parent 9e9f2764af
commit 6300299c7b
4 changed files with 145 additions and 109 deletions

View File

@ -219,6 +219,22 @@ pgendGUIDType (PGBackend *be, const GUID *guid)
return GNC_ID_NONE;
}
/* ============================================================= */
static void
pgend_set_book (PGBackend *be, GNCBook *book)
{
GList *node;
be->book = book;
for (node=be->blist; node; node=node->next)
{
if (book == node->data) return;
}
be->blist = g_list_prepend (be->blist, book);
}
/* ============================================================= */
/* This routine finds the commodity by parsing a string
* of the form NAMESPACE::MNEMONIC
@ -386,7 +402,7 @@ query_cb (PGBackend *be, PGresult *result, int j, gpointer data)
/* use markers to avoid redundant traversals of transactions we've
* already checked recently. */
trans = xaccTransLookup (&trans_guid, be->book);
trans = pgendTransLookup (be, &trans_guid);
if (NULL != trans)
{
if (0 != trans->marker)
@ -703,7 +719,7 @@ pgendGetAllTransactions (PGBackend *be, AccountGroup *grp)
xaccAccountGroupBeginEdit (grp);
for (node=xaction_list; node; node=node->next)
{
pgendCopyTransactionToEngine (be, (GUID *)node->data);
xxxpgendCopyTransactionToEngine (be, (GUID *)node->data);
xaccGUIDFree (node->data);
}
g_list_free(xaction_list);
@ -771,7 +787,7 @@ pgendSync (Backend *bend, GNCBook *book)
ENTER ("be=%p, grp=%p", be, grp);
be->book = book;
pgend_set_book (be, book);
be->version_check = (guint32) time(0);
/* For the multi-user modes, we allow a save only once,
@ -858,7 +874,7 @@ pgendSyncSingleFile (Backend *bend, GNCBook *book)
ENTER ("be=%p, grp=%p", be, grp);
be->book = book;
pgend_set_book (be, book);
/* hack alert -- we shouldn't be doing a global delete,
* we should only be deleting the stuff that's in this particular
@ -944,15 +960,11 @@ pgendSyncSingleFile (Backend *bend, GNCBook *book)
static void
pgendSyncPriceDB (Backend *bend, GNCBook *book)
{
GNCPriceDB *prdb;
PGBackend *be = (PGBackend *)bend;
ENTER ("be=%p", be);
if (!be) return;
be->book = book;
prdb = gnc_book_get_pricedb (book);
if (!prdb) return;
pgend_set_book (be, book);
be->version_check = (guint32) time(0);
/* for the multi-user modes, we allow a save only once,
@ -966,13 +978,13 @@ pgendSyncPriceDB (Backend *bend, GNCBook *book)
}
be->freshly_created_prdb = FALSE;
pgendStorePriceDB (be, prdb);
pgendStorePriceDB (be, book);
/* don't send events to GUI, don't accept callbacks to backend */
gnc_engine_suspend_events();
pgendDisable(be);
pgendGetAllPrices (be, prdb);
pgendGetAllPricesInBook (be, book);
/* re-enable events */
pgendEnable(be);
@ -1001,23 +1013,23 @@ pgendSyncPriceDB (Backend *bend, GNCBook *book)
static void
pgendSyncPriceDBSingleFile (Backend *bend, GNCBook *book)
{
GNCPriceDB *prdb;
char *p;
char buff[400], *p;
PGBackend *be = (PGBackend *)bend;
ENTER ("be=%p", be);
be->book = book;
prdb = gnc_book_get_pricedb (book);
if (!prdb) return;
pgend_set_book (be, book);
p = "BEGIN;\n"
"LOCK TABLE gncPrice IN EXCLUSIVE MODE;\n"
"DELETE FROM gncPrice;\n";
SEND_QUERY (be,p, );
p = buff;
p = stpcpy (p, "BEGIN;\n"
"LOCK TABLE gncPrice IN EXCLUSIVE MODE;\n"
"DELETE FROM gncPrice WHERE bookGuid='\n");
p = guid_to_string_buff (gnc_book_get_guid(book), p);
p = stpcpy (p, "';");
SEND_QUERY (be,buff, );
FINISH_QUERY(be->connection);
/* Store accounts and commodities */
pgendStorePriceDBNoLock (be, prdb);
pgendStorePriceDBNoLock (be, book);
p = "COMMIT;";
SEND_QUERY (be,p, );
@ -1392,18 +1404,16 @@ pgend_book_load_poll (Backend *bend, GNCBook *book)
pgendKVPInit(be);
be->book = book;
if (be->blist)
{
/* XXX not clear what this means ... should we free old books ?? */
PWARN ("old book list not empty ");
g_list_free (be->blist);
be->blist = NULL;
}
pgend_set_book (be, book);
pgendGetBook (be, book);
be->blist = g_list_append (NULL, book);
pgendGetAllAccountsInBook (be, book);
grp = gnc_book_get_group (book);
@ -1438,7 +1448,7 @@ pgend_book_load_single (Backend *bend, GNCBook *book)
pgendDisable(be);
be->version_check = (guint32) time(0);
be->book = book;
pgend_set_book (be, book);
pgendKVPInit(be);
@ -1471,20 +1481,17 @@ static void
pgend_price_load_single (Backend *bend, GNCBook *book)
{
PGBackend *be = (PGBackend *)bend;
GNCPriceDB *db;
if (!be || !book) return;
be->book = book;
pgend_set_book (be, book);
/* don't send events to GUI, don't accept callbacks to backend */
gnc_engine_suspend_events();
pgendDisable(be);
be->version_check = (guint32) time(0);
db = gnc_book_get_pricedb (book);
pgendGetAllPrices (be, db);
pgendGetAllPricesInBook (be, book);
/* re-enable events */
pgendEnable(be);
@ -1555,11 +1562,15 @@ pgend_session_begin (Backend *backend,
pgendInit (be);
be->session = session;
be->book = gnc_session_get_book(session);
if (be->blist)
g_list_free (be->blist);
be->blist = g_list_append (NULL, be->book);
{
/* XXX not clear what this means ... should we free old books ?? */
PWARN ("old book list not empty ");
g_list_free (be->blist);
be->blist = NULL;
}
pgend_set_book (be, gnc_session_get_book(session));
/* Parse the sessionid for the hostname, port number and db name.
* The expected URL format is

View File

@ -249,26 +249,31 @@ pgendGetAllAccountKVP (PGBackend *be, AccountGroup *grp)
static gpointer
get_account_cb (PGBackend *be, PGresult *result, int j, gpointer data)
{
GList *node;
GNCBook *book;
GNCBook *book = data;
Account *parent;
Account *acc;
GUID acct_guid, book_guid;
GUID acct_guid;
PINFO ("account GUID=%s", DB_GET_VAL("accountGUID",j));
/* First, find the book that pertains to this account */
book_guid = nullguid; /* just in case the read fails ... */
string_to_guid (DB_GET_VAL("bookGUID",j), &book_guid);
book = NULL;
for (node=be->blist; node; node=node->next)
if (NULL == book)
{
book = node->data;
if (guid_equal (&book->guid, &book_guid)) break;
GList *node;
GUID book_guid;
/* First, find the book that pertains to this account */
book_guid = nullguid; /* just in case the read fails ... */
string_to_guid (DB_GET_VAL("bookGUID",j), &book_guid);
book = NULL;
for (node=be->blist; node; node=node->next)
{
book = node->data;
if (guid_equal (&book->guid, &book_guid)) break;
book = NULL;
}
if (!book) return data;
}
if (!book) return NULL;
/* Next, lets see if we've already got this account */
acct_guid = nullguid; /* just in case the read fails ... */
@ -326,7 +331,7 @@ get_account_cb (PGBackend *be, PGresult *result, int j, gpointer data)
}
xaccAccountCommitEdit(acc);
return acc;
return data;
}
void
@ -383,7 +388,7 @@ pgendGetAllAccountsInBook (PGBackend *be, GNCBook *book)
p = guid_to_string_buff (gnc_book_get_guid(book), p);
p = stpcpy (p, "';");
SEND_QUERY (be, buff, );
pgendGetResults (be, get_account_cb, NULL);
pgendGetResults (be, get_account_cb, book);
topgrp = gnc_book_get_group (book);
pgendGetAllAccountKVP (be, topgrp);
@ -446,7 +451,8 @@ pgendCopyAccountToEngine (PGBackend *be, const GUID *acct_guid)
pbuff = stpcpy (pbuff, "';");
SEND_QUERY (be,be->buff, 0);
acc = pgendGetResults (be, get_account_cb, NULL);
pgendGetResults (be, get_account_cb, NULL);
acc = pgendAccountLookup (be, acct_guid);
/* restore any kvp data associated with the transaction and splits */
if (acc)

View File

@ -30,6 +30,8 @@
#include <string.h>
#include <libpq-fe.h>
#include "gnc-book.h"
#include "gnc-book-p.h"
#include "gnc-commodity.h"
#include "gnc-engine.h"
#include "gnc-engine-util.h"
@ -58,46 +60,48 @@ static short module = MOD_BACKEND;
static gpointer
get_commodities_cb (PGBackend *be, PGresult *result, int j, gpointer data)
{
gnc_commodity_table *comtab = data;
gnc_commodity *com;
GList *node;
/* first, lets see if we've already got this one */
com = gnc_commodity_table_lookup(comtab,
DB_GET_VAL("namespace",j),
DB_GET_VAL("mnemonic",j));
/* stick the commodity in every book ... */
for (node=be->blist; node; node=node->next)
{
gnc_commodity *com;
GNCBook *book = node->data;
gnc_commodity_table *comtab = gnc_book_get_commodity_table (book);
if (!comtab) continue;
if (com) return comtab;
/* no we don't ... restore it */
com = gnc_commodity_new (DB_GET_VAL("fullname",j),
DB_GET_VAL("namespace",j),
DB_GET_VAL("mnemonic",j),
DB_GET_VAL("code",j),
atoi(DB_GET_VAL("fraction",j)));
gnc_commodity_table_insert (comtab, com);
return comtab;
/* first, lets see if we've already got this one */
com = gnc_commodity_table_lookup(comtab,
DB_GET_VAL("namespace",j),
DB_GET_VAL("mnemonic",j));
if (com) continue;
/* no we don't ... restore it */
com = gnc_commodity_new (DB_GET_VAL("fullname",j),
DB_GET_VAL("namespace",j),
DB_GET_VAL("mnemonic",j),
DB_GET_VAL("code",j),
atoi(DB_GET_VAL("fraction",j)));
gnc_commodity_table_insert (comtab, com);
}
return NULL;
}
void
pgendGetAllCommodities (PGBackend *be)
{
gnc_commodity_table *comtab;
char * p;
if (!be) return;
ENTER ("be=%p, conn=%p", be, be->connection);
comtab = gnc_book_get_commodity_table (be->book);
if (!comtab) {
PERR ("can't get commodity table");
return;
}
/* Get them ALL */
p = "SELECT * FROM gncCommodity;";
SEND_QUERY (be, p, );
pgendGetResults (be, get_commodities_cb, comtab);
pgendGetResults (be, get_commodities_cb, NULL);
LEAVE (" ");
}
@ -105,7 +109,6 @@ pgendGetAllCommodities (PGBackend *be)
void
pgendGetCommodity (PGBackend *be, const char * unique_name)
{
gnc_commodity_table *comtab;
sqlEscape *escape;
char *p;
@ -113,12 +116,6 @@ pgendGetCommodity (PGBackend *be, const char * unique_name)
ENTER ("be=%p, conn=%p", be, be->connection);
comtab = gnc_book_get_commodity_table (be->book);
if (!comtab) {
PERR ("can't get commodity table");
return;
}
escape = sqlEscape_new ();
/* Get them ALL */
@ -128,7 +125,7 @@ pgendGetCommodity (PGBackend *be, const char * unique_name)
p = stpcpy (p, "';");
SEND_QUERY (be, be->buff, );
pgendGetResults (be, get_commodities_cb, comtab);
pgendGetResults (be, get_commodities_cb, NULL);
sqlEscape_destroy (escape);
@ -210,11 +207,13 @@ commodity_mark_cb (gnc_commodity *cm, gpointer user_data)
void
pgendStorePriceDBNoLock (PGBackend *be, GNCPriceDB *prdb)
pgendStorePriceDBNoLock (PGBackend *be, GNCBook *book)
{
GNCPriceDB *prdb;
gnc_commodity_table *comtab;
comtab = gnc_book_get_commodity_table (be->book);
prdb = gnc_book_get_pricedb(book);
comtab = gnc_book_get_commodity_table (book);
/* Clear the marks on commodities -- we use this to mark
* the thing as 'already stored', avoiding redundant stores */
@ -227,11 +226,11 @@ pgendStorePriceDBNoLock (PGBackend *be, GNCPriceDB *prdb)
}
void
pgendStorePriceDB (PGBackend *be, GNCPriceDB *prdb)
pgendStorePriceDB (PGBackend *be, GNCBook *book)
{
char *p;
ENTER ("be=%p, prdb=%p", be, prdb);
if (!be || !prdb) return;
ENTER ("be=%p, book=%p", be, book);
if (!be || !book) return;
/* Lock it up so that we store atomically */
p = "BEGIN;\n"
@ -239,7 +238,7 @@ pgendStorePriceDB (PGBackend *be, GNCPriceDB *prdb)
SEND_QUERY (be,p, );
FINISH_QUERY(be->connection);
pgendStorePriceDBNoLock (be, prdb);
pgendStorePriceDBNoLock (be, book);
p = "COMMIT;\n"
"NOTIFY gncPrice;";
@ -258,7 +257,8 @@ pgendStorePriceDB (PGBackend *be, GNCPriceDB *prdb)
static gpointer
get_price_cb (PGBackend *be, PGresult *result, int j, gpointer data)
{
GNCPriceDB *prdb = (GNCPriceDB *) data;
GNCBook *book = data;
GNCPriceDB *prdb;
GNCPrice *pr;
gint32 sql_vers, local_vers;
Timespec ts;
@ -269,13 +269,34 @@ get_price_cb (PGBackend *be, PGresult *result, int j, gpointer data)
gnc_commodity * modity;
if (NULL == book)
{
GList *node;
GUID book_guid;
/* First, find the book that pertains to this price */
book_guid = nullguid; /* just in case the read fails ... */
string_to_guid (DB_GET_VAL("bookGUID",j), &book_guid);
book = NULL;
for (node=be->blist; node; node=node->next)
{
book = node->data;
if (guid_equal (&book->guid, &book_guid)) break;
book = NULL;
}
if (!book) return data;
}
prdb = gnc_book_get_pricedb(book);
/* First, lets see if we've already got this one */
string_to_guid (DB_GET_VAL ("priceGuid", j), &guid);
pr = pgendPriceLookup (be, &guid);
if (!pr)
{
pr = gnc_price_create(be->book);
pr = gnc_price_create(book);
gnc_price_begin_edit (pr);
gnc_price_set_guid (pr, &guid);
not_found = 1;
@ -295,14 +316,14 @@ get_price_cb (PGBackend *be, PGresult *result, int j, gpointer data)
local_vers, sql_vers);
gnc_price_commit_edit (pr);
gnc_price_unref (pr);
return prdb;
return data;
}
gnc_price_set_version (pr, sql_vers);
modity = gnc_string_to_commodity (DB_GET_VAL("commodity",j), be->book);
modity = gnc_string_to_commodity (DB_GET_VAL("commodity",j), book);
gnc_price_set_commodity (pr, modity);
modity = gnc_string_to_commodity (DB_GET_VAL("currency",j), be->book);
modity = gnc_string_to_commodity (DB_GET_VAL("currency",j), book);
gnc_price_set_currency (pr, modity);
ts = gnc_iso8601_to_timespec_local (DB_GET_VAL("time",j));
@ -320,32 +341,30 @@ get_price_cb (PGBackend *be, PGresult *result, int j, gpointer data)
gnc_price_commit_edit (pr);
gnc_price_unref (pr);
return prdb;
return data;
}
GNCPriceDB *
pgendGetAllPrices (PGBackend *be, GNCPriceDB *prdb)
void
pgendGetAllPricesInBook (PGBackend *be, GNCBook *book)
{
char * p;
char buff[400], *p;
if (!be) return NULL;
if (!be) return;
ENTER ("be=%p, conn=%p", be, be->connection);
if (!prdb) {
prdb = gnc_pricedb_create(be->book);
}
/* first, make sure commodities table is up to date */
pgendGetAllCommodities (be);
/* Get them ALL */
p = "SELECT * FROM gncPrice;";
SEND_QUERY (be, p, prdb);
pgendGetResults (be, get_price_cb, prdb);
p = buff;
p = stpcpy (p, "SELECT * FROM gncPrice WHERE bookGuid='");
p = guid_to_string_buff (gnc_book_get_guid(book), p);
p = stpcpy (p, "';");
SEND_QUERY (be, buff, );
pgendGetResults (be, get_price_cb, book);
LEAVE (" ");
return prdb;
}
/* ============================================================= */

View File

@ -28,9 +28,9 @@
void pgendGetAllCommodities (PGBackend *be);
void pgendGetCommodity (PGBackend *be, const char * unique_name);
void pgendStorePriceDB (PGBackend *be, GNCPriceDB *prdb);
void pgendStorePriceDBNoLock (PGBackend *be, GNCPriceDB *prdb);
GNCPriceDB * pgendGetAllPrices (PGBackend *be, GNCPriceDB *prdb);
void pgendStorePriceDB (PGBackend *be, GNCBook *book);
void pgendStorePriceDBNoLock (PGBackend *be, GNCBook *book);
void pgendGetAllPricesInBook (PGBackend *be, GNCBook *);
void pgendPriceFind (Backend *bend, GNCPriceLookup *look);