beginings of outlien for sql work

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@2321 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Linas Vepstas 2000-05-15 01:16:47 +00:00
parent 542f67beec
commit fb82419ce2
4 changed files with 356 additions and 7 deletions

View File

@ -1,3 +1,56 @@
# Generated automatically from Makefile.in by configure.
# Makefile -- makefile for xacc/src/engine/sql
# Copyright (C) 1997 Robin Clark
# Copyright (C) 1998 Linas Vepstas
# Copyright (C) 1998 Rob Browning <rlb@cs.utexas.edu>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, contact:
#
# Free Software Foundation Voice: +1-617-542-5942
# 59 Temple Place - Suite 330 Fax: +1-617-542-2652
# Boston, MA 02111-1307, USA gnu@gnu.org
include ../../../Makefile.init
INCLPATH = -I. \
-I.. \
-I../.. \
-I../../.. \
-I../guid \
-I/usr/include
# add the -fpic flag to generate relocatable position independent code
# for the engine so that in can be used in a shared module (e.g. a perl module)
CFLAGS = -g -O2 ${INCLPATH} -fpic
LIBS = -lpq
######################################################################
# See Makefile.common for information about these variables.
INDEP_SRCS := PostgresBackend.c
######################################################################
all: default
# This inclusion must come after the first target, and after the
# definitions of *_SRCS, etc., but before the usage of *_OBJS.
include ../../../Makefile.common
default: ${OBJS}
.PHONY: all default
demo: demo.c

View File

@ -0,0 +1,261 @@
/*
* 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.
*
*/
#include <pgsql/libpq-fe.h>
#include <stdio.h>
#include <string.h>
#include "BackendP.h"
#include "Group.h"
#include "Session.h"
#include "guid.h"
#include "util.h"
#include "PostgresBackend.h"
static short module = MOD_BACKEND;
/* hack alert -- this is the query buffer, it might be too small.
we need to make it dynamic sized */
#define QBUFSIZE 16350
/* ============================================================= */
#define FLUSH(conn) { \
PGresult *result; \
/* complete/commit the transaction, check the status */ \
do { \
ExecStatusType status; \
result = PQgetResult((conn)); \
if (!result) break; \
PINFO ("got result\n"); \
status = PQresultStatus(result); \
if (PGRES_COMMAND_OK != status) { \
PERR("bad status\n"); \
PQclear(result); \
PQfinish ((conn)); \
} \
PQclear(result); \
} while (result); \
}
/* ============================================================= */
/* This routine stores the indicated group structure into the database.
* It does *not* chase pointers, traverse the tree, etc.
*/
static void
pgendStoreOneGroupOnly (PGBackend *be, AccountGroup *grp)
{
Account *parent;
const GUID *parent_guid, *grp_guid;
char buff[QBUFSIZE];
int i, nacc, rc;
ENTER ("be=%p, grp=%p\n", be, grp);
if (!be || !grp) return;
grp_guid = xaccGroupGetGUID (grp);
parent = xaccGroupGetParentAccount(grp);
parent_guid = xaccAccountGetGUID (parent);
nacc = xaccGroupGetNumAccounts(grp);
for (i=0; i<nacc; i++) {
Account *acc = xaccGroupGetAccount(grp, i);
/* hack alert -- values should be escaped so that no '' apear in them */
snprintf (buff, QBUFSIZE,
"INSERT INTO gncGroup "
"(groupGuid, parentGuid, childGuid)"
" values "
"('%s', '%s', '%s');",
guid_to_string(grp_guid),
guid_to_string(parent_guid),
guid_to_string(xaccAccountGetGUID (acc))
);
rc = PQsendQuery (be->connection, buff);
if (!rc)
{
PERR("send query failed:\n"
"\t%s", PQerrorMessage(be->connection));
PQfinish (be->connection);
return;
}
/* complete/commit the transaction, check the status */
FLUSH(be->connection);
}
LEAVE ("\n");
}
/* ============================================================= */
/* this routine stores the indicated split in the database
*/
static void
pgendStoreSplit (PGBackend *be, Split *split)
{
Timespec ts;
char buff[QBUFSIZE];
int rc;
ENTER ("be=%p, split=%p\n", be, split);
if (!be || !split) return;
/* hack alert date is not stored ... */
xaccSplitGetDateReconciledTS (split, &ts);
/* hack alert -- values should be escaped so that no '' apear in them */
snprintf (buff, QBUFSIZE,
"INSERT INTO gncEntry "
"(entryGuid, accountGuid, transGuid, memo, action,"
"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))),
xaccSplitGetMemo(split),
xaccSplitGetAction(split),
xaccSplitGetReconcile(split),
xaccSplitGetShareAmount(split),
xaccSplitGetSharePrice(split)
);
rc = PQsendQuery (be->connection, buff);
if (!rc)
{
PERR("send query failed:\n"
"\t%s", PQerrorMessage(be->connection));
PQfinish (be->connection);
return;
}
/* complete/commit the transaction, check the status */
FLUSH(be->connection);
LEAVE ("\n");
}
/* ============================================================= */
/* this routine fills in the structure pointed at by split
* with data sucked out of the database
*/
static void
pgendGetSplit (PGBackend *be, Split *split, GUID *guid)
{
int rc;
ENTER ("be=%p, split=%p\n", be, split);
if (!be || !split || !guid) return;
rc = PQsendQuery (be->connection, "SELECT * FROM gncEntry;");
if (!rc)
{
PERR("send query failed:\n"
"\t%s", PQerrorMessage(be->connection));
PQfinish (be->connection);
return;
}
LEAVE ("\n");
}
/* ============================================================= */
AccountGroup *
pgend_session_begin (Session *sess, const char * sessionid)
{
PGBackend *be;
ENTER("sessionid=%s\n", sessionid);
/* connect to a bogus database ... */
/* hack alert -- clean this up ... */
be->dbName = strdup ("gnc_bogus");
be->connection = PQsetdbLogin (NULL, NULL, NULL, NULL, be->dbName, NULL, NULL);
/* check the conmnection status */
if (CONNECTION_BAD == PQstatus(be->connection))
{
PERR("Connection to database '%s' failed:\n"
"\t%s",
be->dbName, PQerrorMessage(be->connection));
PQfinish (be->connection);
return NULL;
}
DEBUGCMD (PQtrace(be->connection, stderr));
LEAVE("\n");
return NULL;
}
/* ============================================================= */
int
pgend_trans_commit_edit (Backend * bend, Transaction * trans)
{
PGBackend *be = (PGBackend *)bend;
int i, nsplits;
int rc;
ENTER ("be=%p, trans=%p\n", be, trans);
if (!be || !trans) return 1; /* hack alert hardcode literal */
nsplits = xaccTransCountSplits (trans);
for (i=0; i<nsplits; i++) {
Split *s = xaccTransGetSplit (trans, i);
pgendStoreSplit (be, s);
}
#if 0
rc = PQsendQuery (be->connection, "SELECT * FROM gncAccount;");
if (!rc)
{
PERR("send query failed:\n"
"\t%s", PQerrorMessage(be->connection));
PQfinish (be->connection);
return 2; /* hack alert hardcode literal */
}
#endif
LEAVE ("\n");
}
/* ============================================================= */
Backend *
pgendNew (void)
{
PGBackend *be;
be = (PGBackend *) malloc (sizeof (PGBackend));
/* generic backend handlers */
be->be.session_begin = pgend_session_begin;
be->be.session_end = NULL;
be->be.account_begin_edit = NULL;
be->be.account_commit_edit = NULL;
be->be.trans_begin_edit = NULL;
be->be.trans_commit_edit = pgend_trans_commit_edit;
be->be.trans_rollback_edit= NULL;
/* postgres specific data */
be->dbName = NULL;
be->connection = NULL;
return (Backend *) be;
}
/* ======================== END OF FILE ======================== */

View File

@ -0,0 +1,26 @@
/*
* PostgressBackend.h
*
* Implements the callbacks for the postgress backend.
*
*/
#include <pgsql/libpq-fe.h>
#include "BackendP.h"
typedef struct _pgend PGBackend;
struct _pgend {
Backend be;
/* postgres-specific conection data */
char * dbName;
PGconn * connection;
};
/*
* pgendNew creates a new postgress backend
*/
Backend * pgendNew (void);

View File

@ -1,10 +1,18 @@
-- these tables roughly mirror the c structs in TransactionP.h and
-- AccountP.h
-- these tables roughly mirror the c structs in
-- TransactionP.h, AccountP.h and GroupP.h
-- each child of a group will have its own record.
DROP TABLE gncGroup;
CREATE TABLE gncGroup (
groupGuid CHAR(32),
parentGuid CHAR(32),
childGuid CHAR(32)
);
DROP TABLE gncAccount;
CREATE TABLE gncAccount (
accountGuid CHAR(16) PRIMARY KEY,
accountGuid CHAR(32) PRIMARY KEY,
accountName VARCHAR(40) DEFAULT 'xoxo',
accountCode VARCHAR(8),
description VARCHAR(120),
@ -25,11 +33,12 @@ INSERT INTO gncaccount (accountguid,accountName,description) values
DROP TABLE gncEntry;
CREATE TABLE gncEntry (
entryGuid CHAR(16) PRIMARY KEY,
accountGuid CHAR(16),
transGuid CHAR(16),
entryGuid CHAR(32) PRIMARY KEY,
accountGuid CHAR(32),
transGuid CHAR(32),
memo VARCHAR(20),
action VARCHAR(20),
reconciled CHAR,
date_reconciled DATETIME,
amount FLOAT8 DEFAULT '0.0',
share_price FLOAT8 DEFAULT '0.0'
@ -37,7 +46,7 @@ CREATE TABLE gncEntry (
DROP TABLE gncTransaction;
CREATE TABLE gncTransaction (
transGuid CHAR(16) PRIMARY KEY,
transGuid CHAR(32) PRIMARY KEY,
date_entered DATETIME,
date_posted DATETIME,
num VARCHAR(8),