diff --git a/src/FileDialog.c b/src/FileDialog.c index ec447b98e8..9a3914d185 100644 --- a/src/FileDialog.c +++ b/src/FileDialog.c @@ -67,14 +67,48 @@ show_book_error (GNCBackendError io_error, const char *newfile) case ERR_BACKEND_NO_BACKEND: fmt = _("The URL \n %s\n" - "is not supported by this version of GnuCash."); + "is not supported by this version of GnuCash."); + buf = g_strdup_printf (fmt, newfile); + gnc_error_dialog (buf); + break; + + case ERR_BACKEND_BAD_URL: + fmt = _("Can't parse the URL\n %s\n"); + buf = g_strdup_printf (fmt, newfile); + gnc_error_dialog (buf); + break; + + case ERR_BACKEND_CANT_CONNECT: + fmt = _("Can't connect to\n %s\n" + "The host, username or password were incorrect."); + buf = g_strdup_printf (fmt, newfile); + gnc_error_dialog (buf); + break; + + case ERR_BACKEND_CONN_LOST: + fmt = _("Can't connect to\n %s\n" + "Connection was lost, unable to send data."); buf = g_strdup_printf (fmt, newfile); gnc_error_dialog (buf); break; case ERR_BACKEND_LOCKED: fmt = _("The URL \n %s\n" - "is in use by another user."); + "is in use by another user."); + buf = g_strdup_printf (fmt, newfile); + gnc_error_dialog (buf); + break; + + case ERR_BACKEND_DATA_CORRUPT: + fmt = _("The URL \n %s\n" + "does not contain GnuCash data or the data is corrupt."); + buf = g_strdup_printf (fmt, newfile); + gnc_error_dialog (buf); + break; + + case ERR_BACKEND_SERVER_ERR: + fmt = _("The server at URL \n %s\n" + "experienced an error or encountered bad or corrupt data."); buf = g_strdup_printf (fmt, newfile); gnc_error_dialog (buf); break; @@ -122,19 +156,6 @@ show_book_error (GNCBackendError io_error, const char *newfile) gnc_error_dialog(buf); break; - case ERR_SQL_BAD_LOCATION: - fmt = _("Can't parse the database URL\n %s\n"); - buf = g_strdup_printf (fmt, newfile); - gnc_error_dialog (buf); - break; - - case ERR_SQL_CANT_CONNECT: - fmt = _("Can't connect to the database\n %s\n" - "The host, username or password were incorrect."); - buf = g_strdup_printf (fmt, newfile); - gnc_error_dialog (buf); - break; - default: PERR("FIXME: Unhandled error %d", io_error); fmt = _("An unknown I/O error occurred."); diff --git a/src/engine/Backend.h b/src/engine/Backend.h index d8b8a62937..d2b704a6ed 100644 --- a/src/engine/Backend.h +++ b/src/engine/Backend.h @@ -44,13 +44,18 @@ typedef enum { ERR_BACKEND_NO_ERR = 0, ERR_BACKEND_NO_BACKEND, /* Backend * pointer was null the err routine */ /* or no backend handler (ENOSYS) */ - ERR_BACKEND_LOCKED, /* in use by another user (ETXTBSY) */ + ERR_BACKEND_BAD_URL, /* Can't parse url */ ERR_BACKEND_NO_SUCH_DB, /* the named database doesn't exist */ + ERR_BACKEND_CANT_CONNECT, /* bad dbname/login/passwd or network failure */ + ERR_BACKEND_CONN_LOST, /* Lost connection to server */ + ERR_BACKEND_LOCKED, /* in use by another user (ETXTBSY) */ + ERR_BACKEND_DATA_CORRUPT, /* data in db is corrupt */ + ERR_BACKEND_SERVER_ERR, /* error in response from server */ ERR_BACKEND_ALLOC, /* internal memory allocation failure */ ERR_BACKEND_MISC, /* undetermined error */ /* fileio errors */ - ERR_FILEIO_FILE_BAD_READ, /* read failed or file prematurely truncated */ + ERR_FILEIO_FILE_BAD_READ = 1000, /* read failed or file prematurely truncated */ ERR_FILEIO_FILE_EMPTY, /* file exists, is readable, but is empty */ ERR_FILEIO_FILE_LOCKERR, /* mangled locks (unspecified error) */ ERR_FILEIO_FILE_NOT_FOUND, /* not found / no such file */ @@ -59,30 +64,19 @@ typedef enum { ERR_FILEIO_UNKNOWN_FILE_TYPE, /* network errors */ - ERR_NETIO_NO_CONNECTION, /* network failure, can't connect to server */ - ERR_NETIO_SHORT_READ, /* not enough bytes received */ + ERR_NETIO_SHORT_READ = 2000, /* not enough bytes received */ ERR_NETIO_WRONG_CONTENT_TYPE, /* wrong kind of server, wrong data served */ ERR_NETIO_NOT_GNCXML, /* whatever it is, we can't parse it. */ /* database errors */ - ERR_SQL_BAD_LOCATION, /* can't parse url */ - ERR_SQL_CANT_CONNECT, /* bad dbname/login/passwd or network failure */ - ERR_SQL_SEND_QUERY_FAILED, /* can't send to database */ - ERR_SQL_FINISH_QUERY_FAILED, /* can't finish out sent request */ - ERR_SQL_GET_RESULT_FAILED, /* can't read response from the db. */ - ERR_SQL_CORRUPT_DB, /* data in db is corrupt */ - ERR_SQL_MISSING_DATA, /* database doesn't contain expected data */ + ERR_SQL_MISSING_DATA = 3000, /* database doesn't contain expected data */ /* RPC errors */ - ERR_RPC_BAD_URL, /* Can't parse url */ - ERR_RPC_HOST_UNK, /* Host unknown */ - ERR_RPC_CANT_CONNECT, /* bad hostname/port/dbname/etc. */ + ERR_RPC_HOST_UNK = 4000, /* Host unknown */ ERR_RPC_CANT_BIND, /* can't bind to address */ ERR_RPC_CANT_ACCEPT, /* can't accept connection */ ERR_RPC_NO_CONNECTION, /* no connection to server */ - ERR_RPC_CONNECTION_LOST, /* Lost connection to server */ ERR_RPC_BAD_VERSION, /* RPC Version Mismatch */ - ERR_RPC_SERVER_STATE, /* Invalid/bad server state */ ERR_RPC_FAILED, /* Operation failed */ ERR_RPC_NOT_ADDED, /* object not added */ diff --git a/src/engine/rpc/RpcBackend.c b/src/engine/rpc/RpcBackend.c index 6c9ba306ca..e9ba6e5969 100644 --- a/src/engine/rpc/RpcBackend.c +++ b/src/engine/rpc/RpcBackend.c @@ -809,7 +809,7 @@ static void rpcend_book_begin (GNCBook *book, const char *book_id, * rpc://host[:port]/db_name */ if (strncmp (book_id, "rpc://", 6)) { - xaccBackendSetError (&be->be, ERR_RPC_BAD_URL); + xaccBackendSetError (&be->be, ERR_BACKEND_BAD_URL); LEAVE ("Not an RPC URL?"); return; } @@ -817,7 +817,7 @@ static void rpcend_book_begin (GNCBook *book, const char *book_id, start = url + 6; rest = strchr (start, '/'); if (!rest || *rest == '\0') { - xaccBackendSetError (&be->be, ERR_RPC_BAD_URL); + xaccBackendSetError (&be->be, ERR_BACKEND_BAD_URL); g_free (url); LEAVE ("cannot find a path after host[:port]"); return; @@ -832,7 +832,7 @@ static void rpcend_book_begin (GNCBook *book, const char *book_id, be->hostname = g_strdup (start); start = rest+1; if (*start == '\0') { - xaccBackendSetError (&be->be, ERR_RPC_BAD_URL); + xaccBackendSetError (&be->be, ERR_BACKEND_BAD_URL); g_free (url); LEAVE ("tailing slash but no path after host[:port]"); return; diff --git a/src/engine/rpc/RpcSock.c b/src/engine/rpc/RpcSock.c index eb84210753..c2791027b4 100644 --- a/src/engine/rpc/RpcSock.c +++ b/src/engine/rpc/RpcSock.c @@ -13,6 +13,8 @@ #include #include #include +#include + #include "RpcBackend.h" #include "RpcSock.h" @@ -103,7 +105,7 @@ int RpcConnect (char *hostname, unsigned short port, RPCSock **sock) struct sockaddr_in sin; if (hostname == NULL || *hostname == '\0' || port == 0) - return ERR_RPC_BAD_URL; + return ERR_BACKEND_BAD_URL; if (sock == NULL) return ERR_BACKEND_MISC; @@ -118,8 +120,8 @@ int RpcConnect (char *hostname, unsigned short port, RPCSock **sock) if ((s = socket (sin.sin_family, SOCK_STREAM, 0)) < 0) return ERR_BACKEND_ALLOC; - if (connect (s, &sin, sizeof(sin)) != 0) - return ERR_RPC_CANT_CONNECT; + if (connect (s, (struct sockaddr *) &sin, sizeof(sin)) != 0) + return ERR_BACKEND_CANT_CONNECT; new = g_malloc (sizeof (*new)); if (new == NULL) { @@ -186,7 +188,7 @@ int RpcCreateListener (unsigned short port, RPCSock **sock) sin.sin_family = AF_INET; sin.sin_port = port; sin.sin_addr.s_addr = INADDR_ANY; - if (bind (s, &sin, sizeof (sin)) < 0) { + if (bind (s, (struct sockaddr *) &sin, sizeof (sin)) < 0) { close (s); return ERR_RPC_CANT_BIND; } diff --git a/src/engine/rpc/gncRpc_server.c b/src/engine/rpc/gncRpc_server.c index c74dfe8989..5d94b8a0d1 100644 --- a/src/engine/rpc/gncRpc_server.c +++ b/src/engine/rpc/gncRpc_server.c @@ -57,7 +57,7 @@ gncrpc_book_begin_1_svc(gncrpc_book_begin_args *argp, int *result, struct svc_re { bool_t retval = TRUE; GncRpcSvc *cl; - int res = ERR_RPC_SERVER_STATE; + int res = ERR_BACKEND_SERVER_ERR; ENTER ("id=\"%s\"", argp->book_id ? argp->book_id : ""); @@ -91,7 +91,7 @@ gncrpc_book_load_1_svc(char *argp, gncrpc_book_load_ret *result, struct svc_req retval = gncrpc_get_state (rqstp, NULL, &cl); if (!retval) { - result->error = ERR_RPC_SERVER_STATE; + result->error = ERR_BACKEND_SERVER_ERR; LEAVE ("bad state"); return retval; } @@ -121,7 +121,7 @@ gncrpc_book_end_1_svc(char *argp, int *result, struct svc_req *rqstp) ENTER ("ok"); retval = gncrpc_get_state (rqstp, NULL, &cl); if (!retval) { - *result = ERR_RPC_SERVER_STATE; + *result = ERR_BACKEND_SERVER_ERR; LEAVE ("bad state"); return retval; } @@ -168,7 +168,7 @@ gncrpc_account_commit_edit_1_svc(gncrpc_commit_acct_args *argp, int *result, str ENTER ("vers=%d", argp->acct.vers); retval = gncrpc_get_state (rqstp, NULL, &cl); if (!retval) { - *result = ERR_RPC_SERVER_STATE; + *result = ERR_BACKEND_SERVER_ERR; LEAVE ("bad state"); return retval; } @@ -217,7 +217,7 @@ gncrpc_account_rollback_edit_1_svc(gncrpc_backend_guid *argp, int *result, struc ENTER ("ok"); retval = gncrpc_get_state (rqstp, NULL, &cl); if (!retval) { - *result = ERR_RPC_SERVER_STATE; + *result = ERR_BACKEND_SERVER_ERR; LEAVE ("bad state"); return retval; } @@ -273,7 +273,7 @@ gncrpc_txn_commit_edit_1_svc(gncrpc_commit_txn_args *argp, int *result, struct s ENTER ("vers=%d", argp->new.vers); retval = gncrpc_get_state (rqstp, NULL, &cl); if (!retval) { - *result = ERR_RPC_SERVER_STATE; + *result = ERR_BACKEND_SERVER_ERR; LEAVE ("bad state"); return retval; } @@ -334,7 +334,7 @@ gncrpc_run_query_1_svc(gncrpc_query_args *argp, gncrpc_query_ret *result, struct /* Find state */ retval = gncrpc_get_state (rqstp, NULL, &cl); if (!retval) { - result->error = ERR_RPC_SERVER_STATE; + result->error = ERR_BACKEND_SERVER_ERR; LEAVE ("Bad state"); return retval; } @@ -386,7 +386,7 @@ gncrpc_sync1_1_svc(gncrpc_sync1_args *argp, gncrpc_sync1_ret *result, struct svc memset (result, 0, sizeof (*result)); retval = gncrpc_get_state (rqstp, NULL, &cl); if (!retval) { - result->error = ERR_RPC_SERVER_STATE; + result->error = ERR_BACKEND_SERVER_ERR; LEAVE ("bad state"); return retval; } @@ -507,7 +507,7 @@ gncrpc_sync2_1_svc(gncrpc_sync2_args *argp, int *result, struct svc_req *rqstp) *result = 0; retval = gncrpc_get_state (rqstp, NULL, &cl); if (!retval) { - *result = ERR_RPC_SERVER_STATE; + *result = ERR_BACKEND_SERVER_ERR; LEAVE ("bad state"); return retval; } @@ -543,7 +543,7 @@ gncrpc_get_txns_1_svc(gncrpc_get_txns_args *argp, gncrpc_get_txns_ret *result, s memset (result, 0, sizeof (*result)); retval = gncrpc_get_state (rqstp, NULL, &cl); if (!retval) { - result->error = ERR_RPC_SERVER_STATE; + result->error = ERR_BACKEND_SERVER_ERR; LEAVE ("Bad state"); return retval; } diff --git a/src/engine/sql/PostgresBackend.c b/src/engine/sql/PostgresBackend.c index 3c63c4b388..8f59edea10 100644 --- a/src/engine/sql/PostgresBackend.c +++ b/src/engine/sql/PostgresBackend.c @@ -404,7 +404,7 @@ pgendGetAllCommodities (PGBackend *be) char * p; if (!be) return; - ENTER ("be=%p", be); + ENTER ("be=%p, conn=%p", be, be->connection); comtab = gnc_engine_commodities(); if (!comtab) { @@ -857,7 +857,7 @@ pgendCopyTransactionToEngine (PGBackend *be, GUID *trans_guid) "too many transactions with GUID=%s\n", guid_to_string (trans_guid)); if (jrows != nrows) xaccTransCommitEdit (trans); - xaccBackendSetError (&be->be, ERR_SQL_CORRUPT_DB); + xaccBackendSetError (&be->be, ERR_BACKEND_DATA_CORRUPT); pgendEnable(be); gnc_engine_resume_events(); return 0; @@ -1693,11 +1693,22 @@ pgendSessionCanStart (PGBackend *be, int break_lock) /* ============================================================= */ -/* Determine whether a valid session could be obtained. - * Return TRUE if we have a session +/* The pgendSessionValidate() routine determines whether a valid + * session could be obtained. + * Return TRUE if we have a session. * This routine is implemented attomically as a test-n-set. */ +static gpointer +is_gnucash_cb (PGBackend *be, PGresult *result, int j, gpointer data) +{ + if (TRUE == (gboolean) data) return (gpointer) TRUE; + + if (0 == strcmp ("gncsession", (DB_GET_VAL ("tablename", j)))) + return (gpointer) TRUE; + return FALSE; +} + static gboolean pgendSessionValidate (PGBackend *be, int break_lock) { @@ -1707,6 +1718,16 @@ pgendSessionValidate (PGBackend *be, int break_lock) if (MODE_NONE == be->session_mode) return FALSE; + /* check to see if this database actually contains + * GnuCash data... */ + p = "SELECT * FROM pg_tables; "; + SEND_QUERY (be,p, FALSE); + retval = (gboolean) pgendGetResults (be, is_gnucash_cb, (gpointer) FALSE); + if (FALSE == retval) { + xaccBackendSetError (&be->be, ERR_BACKEND_DATA_CORRUPT); + return FALSE; + } + /* Lock it up so that we test-n-set atomically * i.e. we want to avoid a race condition when testing * for the single-user session. @@ -1897,7 +1918,7 @@ pgend_session_begin (GNCBook *sess, const char * sessionid, if (strncmp (sessionid, "postgres://", 11)) { - xaccBackendSetError (&be->be, ERR_SQL_BAD_LOCATION); + xaccBackendSetError (&be->be, ERR_BACKEND_BAD_URL); return; } url = g_strdup(sessionid); @@ -1924,7 +1945,7 @@ pgend_session_begin (GNCBook *sess, const char * sessionid, start = end+1; if (0x0 == *start) { - xaccBackendSetError (&be->be, ERR_SQL_BAD_LOCATION); + xaccBackendSetError (&be->be, ERR_BACKEND_BAD_URL); g_free(url); return; } @@ -2062,7 +2083,7 @@ pgend_session_begin (GNCBook *sess, const char * sessionid, } else { - xaccBackendSetError (&be->be, ERR_SQL_CANT_CONNECT); + xaccBackendSetError (&be->be, ERR_BACKEND_CANT_CONNECT); return; } } @@ -2086,7 +2107,7 @@ pgend_session_begin (GNCBook *sess, const char * sessionid, PQerrorMessage(be->connection)); PQfinish (be->connection); be->connection = NULL; - xaccBackendSetError (&be->be, ERR_SQL_CANT_CONNECT); + xaccBackendSetError (&be->be, ERR_BACKEND_CANT_CONNECT); return; } @@ -2117,7 +2138,7 @@ pgend_session_begin (GNCBook *sess, const char * sessionid, PQerrorMessage(be->connection)); PQfinish (be->connection); be->connection = NULL; - xaccBackendSetError (&be->be, ERR_SQL_CANT_CONNECT); + xaccBackendSetError (&be->be, ERR_BACKEND_CANT_CONNECT); return; } diff --git a/src/engine/sql/README b/src/engine/sql/README index 75a097057b..4272bb0962 100644 --- a/src/engine/sql/README +++ b/src/engine/sql/README @@ -12,11 +12,16 @@ Postgres Install Instructions 1) Install postgresql server, client and devel packages. 2) if installed from redhat, then running /etc/rc.d/init.d/postgresql will setup and initialize basic Postgres first-time setup & config. -3) as root, su - postgres then run 'createuser' to add your user id -4) (don't set a password on your postgres db name, yet, gnucash doesn't - have a GUI to ask for your password yet) - -5) (optional) enable TCPIP connections to remote hosts. To do this: +3) as root, 'su - postgres' then run 'createuser' to add your user id + (don't set a password on your postgres db name, yet, gnucash doesn't + have a GUI to ask for your password yet) + If you've forgotten what users are on the system, you can check + by starting the 'psql' command shell and typing the command. + 'SELECT * FROM pg_shadow;' + Note this wnly works for the posgres user, and other users that + have creatuser permissions. + +4) (optional) enable TCPIP connections to remote hosts. To do this: edit the file pg_hba.conf on the remote host to configure and allow access from other hosts. See 'man pg_hba.conf' for details. RedHat: /var/lib/pgsql/pg_hba.conf @@ -26,9 +31,17 @@ Postgres Install Instructions Note also the user must have 'createuser' permissions in order to lock tables (this is a bug in postgres 6.5 and maybe later ???) +5) Hints and Tips: + If you've forgotten what databases you've created in the past, + you can look the filesystem: 'ls -la /var/lib/postgres/data/base' + to view the existing databases. Alternately, if you connect as + user postgres, you can 'SELECT * FROM pg_database;' + + Alternatively, you can install into a brand new database without using root privileges. After step 1 above, perform the following: +1) Install postgresql server, client and devel packages. 2) initdb -D ~/gnucash This creates a directory structure and supporting files under ~/gnucash. The gnucash directory is automatically @@ -54,6 +67,7 @@ using root privileges. After step 1 above, perform the following: connections from processes on the local host. + GnuCash Build Instructions -------------------------- Same as usual, but you must specify the flag '--enable-sql' in order @@ -76,6 +90,9 @@ in the file open dialogs. Or try it on the command line: /usr/local/bin/gnucash postgres://localhost/dbname_whatever +Note: GnuCash will automatically create the database if it does +not already exist. Do *not* try to create the database by hand, +or to specify a database that wasn't created by GnuCash. Remote Access ------------- @@ -125,8 +142,6 @@ Core bugs/features that still need work: -- distinguish between 'save' and 'save-as' in gnc-book & backend. --- document the need for the 'gnucash' database & what its role is. - -- single-update mode is asking to 'save' data at end of session fix this (again, ...) @@ -141,6 +156,7 @@ Core bugs/features that still need work: GUI dialogs. This is because the backend needs to return things like usernames, etc. in the dialogs, and the backend doesn't have the interfaces for passing this kind of info. + (actually, the PERR/PINFO strings might do ??) -- fix the annoying postgres:,,localhost,asdf file syntax: needs mods to gnc-book to keep it happy about lock files & such. @@ -152,9 +168,9 @@ Core bugs/features that still need work: there will be other debilitating conditions if the backend disappears, leaving the engine in a possibly confused state. - for example, if postgres user is misconfigured, the LOCK TABLE + For example, if postgres user is misconfigured, the LOCK TABLE will fail on session validate, and FINISH_QUERY will close the - connection. subsequent sql will core dump gnucash, even though this + connection. Subsequent sql will core dump gnucash, even though this is a sysadmin error. -- during sync, detect and report conflicting edits to accounts @@ -214,7 +230,7 @@ This list only affects the multi-user and advanced/optional features. I don't currently have an opinion on the 'best' way of dealing with this situation. --- implement account rollback (i.e. of other user has modified the +-- implement account rollback (i.e. if other user has modified the account, we need to do something to merge their work into ours...) -- transaction rollback is 'incorrect'; sort of ?? since we should @@ -234,9 +250,10 @@ This list only affects the multi-user and advanced/optional features. note, however, that the file format needs to save the version number ... --- Implement logging history in the SQL server. i.e. save the old - copies of stuff in log tables. Make the username part of the - logging scheme. +-- Implement logging history/audit-trail in the SQL server. + i.e. save the old copies of stuff in log tables. Make the username + part of the logging scheme. Having 'audit trails' is considered + to be an important accounting feature. -- let all attached client receive update events via SQL LISTEN/NOTIFY events. diff --git a/src/engine/sql/design.txt b/src/engine/sql/design.txt index 11d34fe0f8..2037443641 100644 --- a/src/engine/sql/design.txt +++ b/src/engine/sql/design.txt @@ -75,9 +75,11 @@ If you want incremental deletion, then use the 'Single Update' mode. Connecting to Postgres ---------- -The postgres API requires a database to connect to. The initial -connect is made using the "template1" database. +---------------------- +The postgres API requires a database to connect to. The initial +connect is made using the "template1" database, which is the default +database that is always created when Postgres is installed. Thus, +we assume its always present. m4 macros @@ -132,3 +134,10 @@ are not closely synchronized. (e.g. which may happen if the machines are not using NTP for time synchronization; or, e.g. if one machine failed to have daylight-savings time set correctly: its transactions would be an hour newer/older than the others, leading to bad updates). + +Balances +-------- +UPDATE tx + SET (balance )= (SELECT expr from .... WHERE ) +WHERE txdate between today - 7 and today + diff --git a/src/engine/sql/putil.h b/src/engine/sql/putil.h index f3c67f3476..f7d3c8f6c8 100644 --- a/src/engine/sql/putil.h +++ b/src/engine/sql/putil.h @@ -58,6 +58,7 @@ gpointer pgendGetResults (PGBackend *be, #define SEND_QUERY(be,buff,retval) \ { \ int rc; \ + if (NULL == be->connection) return retval; \ rc = PQsendQuery (be->connection, buff); \ if (!rc) \ { \ @@ -65,7 +66,8 @@ gpointer pgendGetResults (PGBackend *be, PERR("send query failed:\n" \ "\t%s", PQerrorMessage(be->connection)); \ PQfinish (be->connection); \ - xaccBackendSetError (&be->be, ERR_SQL_SEND_QUERY_FAILED); \ + be->connection = NULL; \ + xaccBackendSetError (&be->be, ERR_BACKEND_CONN_LOST); \ return retval; \ } \ } @@ -93,7 +95,9 @@ gpointer pgendGetResults (PGBackend *be, "\t%s", PQerrorMessage((conn))); \ PQclear(result); \ PQfinish ((conn)); \ - xaccBackendSetError (&be->be, ERR_SQL_FINISH_QUERY_FAILED); \ + be->connection = NULL; \ + xaccBackendSetError (&be->be, ERR_BACKEND_CONN_LOST); \ + break; \ } \ PQclear(result); \ i++; \ @@ -118,7 +122,8 @@ gpointer pgendGetResults (PGBackend *be, "\t%s", PQerrorMessage((conn))); \ PQclear (result); \ PQfinish (conn); \ - xaccBackendSetError (&be->be, ERR_SQL_GET_RESULT_FAILED); \ + be->connection = NULL; \ + xaccBackendSetError (&be->be, ERR_BACKEND_SERVER_ERR); \ break; \ } \ } @@ -138,7 +143,7 @@ gpointer pgendGetResults (PGBackend *be, } \ if (1 < nrows) { \ PERR ("unexpected duplicate records"); \ - xaccBackendSetError (&be->be, ERR_SQL_CORRUPT_DB); \ + xaccBackendSetError (&be->be, ERR_BACKEND_DATA_CORRUPT); \ break; \ } else if (1 == nrows)