mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
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:
parent
9e9f2764af
commit
6300299c7b
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/* ============================================================= */
|
||||
|
@ -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);
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user