[Gnucash-changes] QOF/CashUtil Sync: Engine

Neil Williams codehelp at cvs.gnucash.org
Wed Aug 17 02:53:38 EDT 2005


Log Message:
-----------
QOF/CashUtil Sync: Engine

Tags:
----
gnucash-gnome2-dev

Modified Files:
--------------
    gnucash/src/engine:
        .cvsignore
        Account.c
        FreqSpec.c
        Group.c
        Makefile.am
        SX-book.c
        SchedXaction.c
        Scrub2.c
        Transaction.c
        gnc-commodity.c
        gnc-engine-util.h
        gnc-event-p.h
        gnc-event.h
        gnc-lot-p.h
        gnc-lot.c
        gnc-numeric.c
        gnc-numeric.h
        gnc-pricedb.c
        qof-be-utils.h
        qof.h
        qof_book_merge.c
        qof_book_merge.h
        qofbackend-p.h
        qofbackend.c
        qofbackend.h
        qofbook.h
        qofclass.c
        qofclass.h
        qofgobj.c
        qofid.h
        qofinstance.c
        qofinstance.h
        qofobject.h
        qofquery.c
        qofquery.h
        qofquerycore-p.h
        qofquerycore.c
        qofquerycore.h
        qofsession-p.h
        qofsession.c
        qofsession.h
        qofsql.c
    gnucash/src/engine/test-core:
        Makefile.am
        test-engine-stuff.c

Revision Data
-------------
Index: qofquery.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofquery.h,v
retrieving revision 1.5.2.6
retrieving revision 1.5.2.7
diff -Lsrc/engine/qofquery.h -Lsrc/engine/qofquery.h -u -r1.5.2.6 -r1.5.2.7
--- src/engine/qofquery.h
+++ src/engine/qofquery.h
@@ -85,6 +85,7 @@
 #include "guid.h"
 #include "qofbook.h"
 #include "qofquerycore.h"
+#include "qofchoice.h"
 
 /** A Query */
 typedef struct _QofQuery QofQuery;
Index: Scrub2.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/Scrub2.c,v
retrieving revision 1.15.2.5
retrieving revision 1.15.2.6
diff -Lsrc/engine/Scrub2.c -Lsrc/engine/Scrub2.c -u -r1.15.2.5 -r1.15.2.6
--- src/engine/Scrub2.c
+++ src/engine/Scrub2.c
@@ -324,7 +324,7 @@
    KvpFrame *ksub;
 
    /* Find and remove the matching guid's */
-   ksub = gnc_kvp_bag_find_by_guid (sa->kvp_data, "lot-split",
+   ksub = (KvpFrame*)gnc_kvp_bag_find_by_guid (sa->kvp_data, "lot-split",
                     "peer_guid", &sb->entity.guid);
    if (ksub) 
    {
@@ -333,7 +333,7 @@
    }
 
    /* Now do it in the other direction */
-   ksub = gnc_kvp_bag_find_by_guid (sb->kvp_data, "lot-split",
+   ksub = (KvpFrame*)gnc_kvp_bag_find_by_guid (sb->kvp_data, "lot-split",
                     "peer_guid", &sa->entity.guid);
    if (ksub) 
    {
Index: qofquery.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofquery.c,v
retrieving revision 1.10.2.8
retrieving revision 1.10.2.9
diff -Lsrc/engine/qofquery.c -Lsrc/engine/qofquery.c -u -r1.10.2.8 -r1.10.2.9
--- src/engine/qofquery.c
+++ src/engine/qofquery.c
@@ -1646,7 +1646,7 @@
   gs = g_string_new ("    Pred Data:\n      ");
   g_string_append (gs, (gchar *) pd->type_name);
 
-  /* Char Predicate and GUID predicate dosn't use the 'how' field. */
+  /* Char Predicate and GUID predicate don't use the 'how' field. */
   if (safe_strcmp (pd->type_name, QOF_TYPE_CHAR) &&
       safe_strcmp (pd->type_name, QOF_TYPE_GUID))
   {
@@ -1777,6 +1777,7 @@
     g_string_sprintfa (gs, " boolean: %s", pdata->val?"TRUE":"FALSE");
     return;
   }
+  /** \todo QOF_TYPE_COLLECT */
   return;
 }                               /* qof_query_printValueForParam */
 
Index: qofid.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofid.h,v
retrieving revision 1.2.6.9
retrieving revision 1.2.6.10
diff -Lsrc/engine/qofid.h -Lsrc/engine/qofid.h -u -r1.2.6.9 -r1.2.6.10
--- src/engine/qofid.h
+++ src/engine/qofid.h
@@ -191,15 +191,24 @@
 /** Return value of 'dirty' flag on collection */
 gboolean qof_collection_is_dirty (QofCollection *col);
 
-/** \brief Add an entity to a QOF_TYPE_COLLECT.
+/** @name QOF_TYPE_COLLECT: Linking one entity to many of one type
 
 \note These are \b NOT the same as the main collections in the book.
 
 QOF_TYPE_COLLECT is a secondary collection, used to select entities
-as references of another entity. Entities can be freely added and merged
-across these secondary collections, they will not be removed from the
-original collection as they would by using ::qof_entity_insert_entity
-or ::qof_entity_remove_entity. 
+of one object type as references of another entity.
+\sa QOF_TYPE_CHOICE.
+
+@{
+*/
+/** \brief Add an entity to a QOF_TYPE_COLLECT.
+
+\note These are \b NOT the same as the main collections in the book.
+
+Entities can be
+freely added and merged across these secondary collections, they
+will not be removed from the original collection as they would
+by using ::qof_entity_insert_entity or ::qof_entity_remove_entity. 
 
 */
 gboolean
@@ -246,6 +255,7 @@
 qof_collection_from_glist (QofIdType type, GList *glist);
 
 /** @} */
+/** @} */
 
 #endif /* QOF_ID_H */
 /** @} */
Index: qofbackend.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofbackend.c,v
retrieving revision 1.2.4.2
retrieving revision 1.2.4.3
diff -Lsrc/engine/qofbackend.c -Lsrc/engine/qofbackend.c -u -r1.2.4.2 -r1.2.4.3
--- src/engine/qofbackend.c
+++ src/engine/qofbackend.c
@@ -138,4 +138,64 @@
 #endif
 }
 
+void
+qof_backend_run_begin(QofBackend *be, QofInstance *inst)
+{
+	(be->begin) (be, inst);
+}
+
+gboolean
+qof_backend_begin_exists(QofBackend *be)
+{
+	if(be->begin) { return TRUE; }
+	else { return FALSE; }
+}
+
+void
+qof_backend_run_commit(QofBackend *be, QofInstance *inst)
+{
+	(be->commit) (be, inst);
+}
+
+gboolean
+qof_backend_commit_exists(QofBackend *be)
+{
+	if(be->commit) { return TRUE; }
+	else { return FALSE; }
+}
+
+void 
+qof_begin_edit(QofInstance *inst)
+{
+  QofBackend * be;
+
+  if (!inst) { return; }
+  inst->editlevel++;
+  if (1 < inst->editlevel) return;
+  if (0 >= inst->editlevel) { inst->editlevel = 1; }
+  be = qof_book_get_backend (inst->book);
+    if (be && qof_backend_begin_exists(be)) {
+     qof_backend_run_begin(be, inst);
+  } else { inst->dirty = TRUE; }
+}
+
+void qof_commit_edit(QofInstance *inst)
+{
+  QofBackend * be;
+
+  if (!inst) return;
+  inst->editlevel--;
+  if (0 < inst->editlevel) { return; }
+  if ((-1 == inst->editlevel) && inst->dirty)
+  {
+    be = qof_book_get_backend ((inst)->book);
+    if (be && qof_backend_begin_exists(be)) {
+     qof_backend_run_begin(be, inst);
+    }
+    inst->editlevel = 0;
+  }
+  if (0 > inst->editlevel) { inst->editlevel = 0; }
+}
+
+
 /************************* END OF FILE ********************************/
Index: qofquerycore.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofquerycore.h,v
retrieving revision 1.5.2.5
retrieving revision 1.5.2.6
diff -Lsrc/engine/qofquerycore.h -Lsrc/engine/qofquerycore.h -u -r1.5.2.5 -r1.5.2.6
--- src/engine/qofquerycore.h
+++ src/engine/qofquerycore.h
@@ -160,6 +160,9 @@
 QofQueryPredData *qof_query_boolean_predicate (QofQueryCompare how, gboolean val);
 QofQueryPredData *qof_query_char_predicate (QofCharMatch options,
                                             const char *chars);
+QofQueryPredData *qof_query_collect_predicate (QofGuidMatch options,
+                                            QofCollection *coll);
+QofQueryPredData *qof_query_choice_predicate  (QofGuidMatch options, GList *guids);
 
 /** The qof_query_kvp_predicate() matches the object that has
  *  the value 'value' located at the path 'path'.  In a certain
Index: qofquerycore.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofquerycore.c,v
retrieving revision 1.8.2.7
retrieving revision 1.8.2.8
diff -Lsrc/engine/qofquerycore.c -Lsrc/engine/qofquerycore.c -u -r1.8.2.7 -r1.8.2.8
--- src/engine/qofquerycore.c
+++ src/engine/qofquerycore.c
@@ -86,6 +86,12 @@
 typedef KvpFrame * (*query_kvp_getter) (gpointer, QofParam *);
 static const char * query_kvp_type = QOF_TYPE_KVP;
 
+typedef QofCollection * (*query_collect_getter) (gpointer, QofParam*);
+static const char * query_collect_type = QOF_TYPE_COLLECT;
+
+typedef const GUID * (*query_choice_getter) (gpointer, QofParam *);
+static const char * query_choice_type = QOF_TYPE_CHOICE;
+
 /* Tables for predicate storage and lookup */
 static gboolean initialized = FALSE;
 static GHashTable *predTable = NULL;
@@ -1272,6 +1278,332 @@
   return pd;
 }
 
+
+/* QOF_TYPE_COLLECT =============================================== */
+
+static int
+collect_match_predicate (gpointer object, QofParam *getter,
+                     QofQueryPredData *pd)
+{
+	query_coll_t pdata;
+	QofCollection *coll;
+	GList *node, *node2, *o_list;
+	const GUID *guid;
+
+	pdata = (query_coll_t)pd;
+	VERIFY_PREDICATE (query_collect_type);
+	coll = ((query_collect_getter)getter->param_getfcn) (object, getter);
+	guid = NULL;
+	switch(pdata->options) {
+		case QOF_GUID_MATCH_ALL : {
+			for (node = pdata->guids; node; node = node->next)
+			{
+				for (o_list = object; o_list; o_list = o_list->next)
+				{
+				guid = ((query_guid_getter)getter->param_getfcn)
+					(o_list->data, getter);
+				if (guid_equal (node->data, guid)) {
+					break;
+					}
+				}
+				if (o_list == NULL) {
+					break;
+				}
+			}
+			break;
+		}
+		case QOF_GUID_MATCH_LIST_ANY : {
+			o_list = ((query_glist_getter)getter->param_getfcn) (object, getter);
+			for (node = o_list; node; node = node->next)
+			{
+				for (node2 = pdata->guids; node2; node2 = node2->next)
+				{
+					if (guid_equal (node->data, node2->data)) {
+						break;
+					}
+				}
+				if (node2 != NULL) {
+					break;
+				}
+			}
+			g_list_free(o_list);
+			break;
+		}
+		default : {
+			guid = ((query_guid_getter)getter->param_getfcn) (object, getter);
+			for (node = pdata->guids; node; node = node->next)
+			{
+				if (guid_equal (node->data, guid)) {
+					break;
+				}
+			}
+		}
+		switch (pdata->options) {
+			case QOF_GUID_MATCH_ANY :
+			case QOF_GUID_MATCH_LIST_ANY : {
+				return (node != NULL);
+				break;
+			}
+			case QOF_GUID_MATCH_NONE :
+			case QOF_GUID_MATCH_ALL : {
+				return (node == NULL);
+				break;
+			}
+			case QOF_GUID_MATCH_NULL : {
+				return (guid == NULL);
+				break;
+			}
+			default : {
+				PWARN ("bad match type");
+				return 0;
+			}
+		}
+	}
+	return 0;
+}
+
+static int
+collect_compare_func (gpointer a, gpointer b, gint options, QofParam *getter)
+{
+	gint result;
+	QofCollection *c1, *c2;
+
+	c1 = ((query_collect_getter)getter->param_getfcn) (a, getter);
+	c2 = ((query_collect_getter)getter->param_getfcn) (b, getter);
+	result = qof_collection_compare(c1, c2);
+	return result;
+}
+
+static void
+collect_free_pdata (QofQueryPredData *pd)
+{
+	query_coll_t pdata;
+	GList *node;
+
+	node = NULL;
+	pdata = (query_coll_t) pd;
+	VERIFY_PDATA (query_collect_type);
+	for (node = pdata->guids; node; node = node->next)
+	{
+		guid_free (node->data);
+	}
+	qof_collection_destroy(pdata->coll);
+	g_list_free (pdata->guids);
+	g_free (pdata);
+}
+
+static QofQueryPredData *
+collect_copy_predicate (QofQueryPredData *pd)
+{
+	query_coll_t pdata = (query_coll_t) pd;
+
+	VERIFY_PDATA_R (query_collect_type);
+	return qof_query_collect_predicate (pdata->options, pdata->coll);
+}
+
+static gboolean
+collect_predicate_equal (QofQueryPredData *p1, QofQueryPredData *p2)
+{
+	query_coll_t pd1;
+	query_coll_t pd2;
+	gint result;
+
+	pd1 = (query_coll_t) p1;
+	pd2 = (query_coll_t) p2;
+	result = qof_collection_compare(pd1->coll, pd2->coll);
+	if(result == 0) { return TRUE; }
+	return FALSE;
+}
+
+static void
+query_collect_cb(QofEntity* ent, gpointer user_data)
+{
+	query_coll_t pdata;
+	GUID *guid;
+
+	guid = guid_malloc();
+	guid = (GUID*)qof_entity_get_guid(ent);
+	pdata = (query_coll_t)user_data;
+	pdata->guids = g_list_append(pdata->guids, guid);
+}
+
+QofQueryPredData *
+qof_query_collect_predicate (QofGuidMatch options, QofCollection *coll)
+{
+	query_coll_t pdata;
+
+	g_return_val_if_fail (coll, NULL);
+	pdata = g_new0 (query_coll_def, 1);
+	pdata->pd.type_name = query_collect_type;
+	pdata->options = options;
+	qof_collection_foreach(coll, query_collect_cb, pdata);
+	if (NULL == pdata->guids) { return NULL; }
+	return ((QofQueryPredData*)pdata);
+}
+
+/* QOF_TYPE_CHOICE */
+
+static int
+choice_match_predicate (gpointer object, QofParam *getter,
+                      QofQueryPredData *pd)
+{
+  query_choice_t pdata = (query_choice_t)pd;
+  GList *node, *o_list;
+  const GUID *guid = NULL;
+
+  VERIFY_PREDICATE (query_choice_type);
+
+  switch (pdata->options) {
+
+  case QOF_GUID_MATCH_ALL:
+    /* object is a GList of objects; param_getfcn must be called on each one.
+     * See if every guid in the predicate is accounted-for in the
+     * object list
+     */
+
+    for (node = pdata->guids; node; node = node->next)
+    {
+      /* See if this GUID matches the object's guid */
+      for (o_list = object; o_list; o_list = o_list->next)
+      {
+        guid = ((query_choice_getter)getter->param_getfcn) (o_list->data, getter);
+        if (guid_equal (node->data, guid))
+          break;
+      }
+
+      /*
+       * If o_list is NULL, we've walked the whole list without finding
+       * a match.  Therefore break out now, the match has failed.
+       */
+      if (o_list == NULL)
+        break;
+    }
+
+    /*
+     * The match is complete.  If node == NULL then we've succesfully
+     * found a match for all the guids in the predicate.  Return
+     * appropriately below.
+     */
+
+    break;
+
+  case QOF_GUID_MATCH_LIST_ANY:
+
+    o_list = ((query_glist_getter)getter->param_getfcn) (object, getter);
+
+    for (node = o_list; node; node = node->next)
+    {
+      GList *node2;
+
+      for (node2 = pdata->guids; node2; node2 = node2->next)
+      {
+        if (guid_equal (node->data, node2->data))
+          break;
+      }
+
+      if (node2 != NULL)
+        break;
+    }
+
+    g_list_free(o_list);
+
+    break;
+
+  default:
+    /* object is a single object, getter returns a GUID*
+     *
+     * See if the guid is in the list
+     */
+
+    guid = ((query_choice_getter)getter->param_getfcn) (object, getter);
+    for (node = pdata->guids; node; node = node->next)
+    {
+      if (guid_equal (node->data, guid))
+        break;
+    }
+  }
+
+  switch (pdata->options) {
+  case QOF_GUID_MATCH_ANY:
+  case QOF_GUID_MATCH_LIST_ANY:
+    return (node != NULL);
+    break;
+  case QOF_GUID_MATCH_NONE:
+  case QOF_GUID_MATCH_ALL:
+    return (node == NULL);
+    break;
+  case QOF_GUID_MATCH_NULL:
+    return (guid == NULL);
+    break;
+  default:
+    PWARN ("bad match type");
+    return 0;
+  }
+}
+
+static void
+choice_free_pdata (QofQueryPredData *pd)
+{
+  query_choice_t pdata = (query_choice_t)pd;
+  GList *node;
+  VERIFY_PDATA (query_choice_type);
+  for (node = pdata->guids; node; node = node->next)
+  {
+    guid_free (node->data);
+  }
+  g_list_free (pdata->guids);
+  g_free (pdata);
+}
+
+static QofQueryPredData *
+choice_copy_predicate (QofQueryPredData *pd)
+{
+  query_choice_t pdata = (query_choice_t)pd;
+  VERIFY_PDATA_R (query_choice_type);
+  return qof_query_choice_predicate (pdata->options, pdata->guids);
+}
+
+static gboolean
+choice_predicate_equal (QofQueryPredData *p1, QofQueryPredData *p2)
+{
+  query_choice_t pd1 = (query_choice_t) p1;
+  query_choice_t pd2 = (query_choice_t) p2;
+  GList *l1 = pd1->guids, *l2 = pd2->guids;
+
+  if (pd1->options != pd2->options) return FALSE;
+  if (g_list_length (l1) != g_list_length (l2)) return FALSE;
+  for ( ; l1 ; l1 = l1->next, l2 = l2->next)
+  {
+    if (!guid_equal (l1->data, l2->data))
+      return FALSE;
+  }
+  return TRUE;
+}
+
+QofQueryPredData *
+qof_query_choice_predicate (QofGuidMatch options, GList *guid_list)
+{
+  query_choice_t pdata;
+  GList *node;
+
+  if (NULL == guid_list) return NULL;
+
+  pdata = g_new0 (query_choice_def, 1);
+  pdata->pd.how = QOF_COMPARE_EQUAL;
+  pdata->pd.type_name = query_choice_type;
+  pdata->options = options;
+
+  pdata->guids = g_list_copy (guid_list);
+  for (node = pdata->guids; node; node = node->next)
+  {
+    GUID *guid = guid_malloc ();
+    *guid = *((GUID *)node->data);
+    node->data = guid;
+  }
+  return ((QofQueryPredData*)pdata);
+}
+
+
 /* initialization ================================================== */
 /** This function registers a new Core Object with the QofQuery
  * subsystem.  It maps the "core_name" object to the given
@@ -1361,6 +1693,11 @@
       char_predicate_equal },
     { QOF_TYPE_KVP, kvp_match_predicate, NULL, kvp_copy_predicate,
       kvp_free_pdata, NULL, kvp_predicate_equal },
+    { QOF_TYPE_COLLECT, collect_match_predicate, collect_compare_func,
+      collect_copy_predicate, collect_free_pdata, NULL,
+      collect_predicate_equal },
+    { QOF_TYPE_CHOICE, choice_match_predicate, NULL,
+      choice_copy_predicate, choice_free_pdata, NULL, choice_predicate_equal },
   };
 
   /* Register the known data types */
Index: qofsql.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofsql.c,v
retrieving revision 1.5.2.4
retrieving revision 1.5.2.5
diff -Lsrc/engine/qofsql.c -Lsrc/engine/qofsql.c -u -r1.5.2.4 -r1.5.2.5
--- src/engine/qofsql.c
+++ src/engine/qofsql.c
@@ -26,11 +26,13 @@
     @author Copyright (C) 2004 Linas Vepstas <linas at linas.org>
 
 */
+#define _GNU_SOURCE
 
 #include <stdlib.h>   /* for working atoll */
 #include <errno.h>
-#include <glib.h>
-#include "sql_parser.h"
+#include "glib.h"
+#include <sql_parser.h>
+#include <time.h>
 #include "kvp_frame.h"
 #include "gnc-date.h"
 #include "gnc-numeric.h"
@@ -42,6 +44,7 @@
 #include "qofsql.h"
 #include "gnc-engine-util.h"
 #include "qofinstance-p.h"
+#include "qofobject.h"
 
 static short module = MOD_QUERY;
 
@@ -159,7 +162,6 @@
 	KvpValueType kvt;
 	QofQueryCompare qop;
 	time_t exact;
-	struct tm utc;
 	int rc, len;
 	Timespec ts;
 	QofType param_type;
@@ -171,7 +173,6 @@
 		PWARN("missing condition");
 		return NULL;
 	}
-			
 	/* -------------------------------- */
 	/* field to match, assumed, for now to be on the left */
 	/* XXX fix this so it can be either left or right */
@@ -281,7 +282,7 @@
 		default:
 			/* XXX for string-type queries, we should be able to
 			 * support 'IN' for substring search.  Also regex. */
-			PWARN ("Unsupported compare op (parsed as %s)", cond->op);
+			PWARN ("Unsupported compare op (parsed as %u)", cond->op);
 			return NULL;
 	}
 
@@ -293,7 +294,6 @@
 	{
 		table_name = query->single_global_tablename;
 	}
-		
 	if (NULL == table_name)
 	{
 		PWARN ("Need to specify an object class to query");
@@ -595,6 +595,7 @@
 
 	/* how to cope with multiple results? */
 	if (insert->values == NULL) { return NULL; }
+	insert_string = NULL;
 	for (walk = insert->values; walk != NULL; walk = walk->next) 
 	{
 		field = walk->data;
@@ -617,6 +618,7 @@
 	sql_field_item *item;
 
 	param = NULL;
+	param_name = NULL;
 	if (insert->fields == NULL) { return NULL; }
 	for (walk = insert->fields; walk != NULL; walk = walk->next) 
 	{
@@ -634,7 +636,7 @@
 static void
 qof_sql_insertCB( gpointer value, gpointer data)
 {
-	GList *param_list, *walk;
+	GList *param_list;
 	QofSqlQuery *q;
 	QofIdTypeConst type;
 	sql_insert_statement *sis;
@@ -653,10 +655,9 @@
 	Timespec       cm_date;
 	char           cm_char, *tail;
 	GUID           *cm_guid;
-	KvpFrame       *cm_kvp;
+/*	KvpFrame       *cm_kvp;
 	KvpValue       *cm_value;
-	KvpValueType   cm_type;
-	QofSetterFunc  cm_setter;
+	KvpValueType   cm_type;*/
 	const QofParam *cm_param;
 	void (*string_setter)    (QofEntity*, const char*);
 	void (*date_setter)      (QofEntity*, Timespec);
@@ -666,7 +667,7 @@
 	void (*i32_setter)       (QofEntity*, gint32);
 	void (*i64_setter)       (QofEntity*, gint64);
 	void (*char_setter)      (QofEntity*, char);
-	void (*kvp_frame_setter) (QofEntity*, KvpFrame*);
+/*	void (*kvp_frame_setter) (QofEntity*, KvpFrame*);*/
 
 	q = (QofSqlQuery*)data;
 	ent = q->inserted_entity;
@@ -683,7 +684,7 @@
 			registered_type = TRUE;
 		}
 		if(safe_strcmp(cm_param->param_type, QOF_TYPE_DATE) == 0) { 
-			date_setter = (void(*)(QofEntity*, Timespec))cm_setter;
+			date_setter = (void(*)(QofEntity*, Timespec))cm_param->param_setfcn;
 			strptime(insert_string, QOF_UTC_DATE_FORMAT, &query_time);
 			query_time_t = mktime(&query_time);
 			timespecFromTime_t(&cm_date, query_time_t);
@@ -691,7 +692,7 @@
 		}
 		if((safe_strcmp(cm_param->param_type, QOF_TYPE_NUMERIC) == 0)  ||
 		(safe_strcmp(cm_param->param_type, QOF_TYPE_DEBCRED) == 0)) { 
-			numeric_setter = (void(*)(QofEntity*, gnc_numeric))cm_setter;
+			numeric_setter = (void(*)(QofEntity*, gnc_numeric))cm_param->param_setfcn;
 			string_to_gnc_numeric(insert_string, &cm_numeric);
 			if(numeric_setter != NULL) { numeric_setter(ent, cm_numeric); }
 		}
@@ -718,7 +719,7 @@
 			errno = 0;
 			cm_i32 = (gint32)strtol (insert_string, &tail, 0);
 			if(errno == 0) {
-				i32_setter = (void(*)(QofEntity*, gint32))cm_setter;
+				i32_setter = (void(*)(QofEntity*, gint32))cm_param->param_setfcn;
 				if(i32_setter != NULL) { i32_setter(ent, cm_i32); }
 			}
 //			else { qof_backend_set_error(params->be, ERR_QSF_OVERFLOW); }
@@ -727,7 +728,7 @@
 			errno = 0;
 			cm_i64 = strtoll(insert_string, &tail, 0);
 			if(errno == 0) {
-				i64_setter = (void(*)(QofEntity*, gint64))cm_setter;
+				i64_setter = (void(*)(QofEntity*, gint64))cm_param->param_setfcn;
 				if(i64_setter != NULL) { i64_setter(ent, cm_i64); }
 			}
 //			else { qof_backend_set_error(params->be, ERR_QSF_OVERFLOW); }
@@ -736,7 +737,7 @@
 			errno = 0;
 			cm_double = strtod(insert_string, &tail);
 			if(errno == 0) {
-				double_setter = (void(*)(QofEntity*, double))cm_setter;
+				double_setter = (void(*)(QofEntity*, double))cm_param->param_setfcn;
 				if(double_setter != NULL) { double_setter(ent, cm_double); }
 			}
 		}
@@ -745,21 +746,15 @@
 				cm_boolean = TRUE;
 			}
 			else { cm_boolean = FALSE; }
-			boolean_setter = (void(*)(QofEntity*, gboolean))cm_setter;
+			boolean_setter = (void(*)(QofEntity*, gboolean))cm_param->param_setfcn;
 			if(boolean_setter != NULL) { boolean_setter(ent, cm_boolean); }
 		}
 			if(safe_strcmp(cm_param->param_type, QOF_TYPE_KVP) == 0) { 
-/*				cm_type = qsf_to_kvp_helper(xmlGetProp(node, QSF_OBJECT_VALUE));
-				if(!cm_type) { return; }
-				cm_value = string_to_kvp_value(xmlNodeGetContent(node), cm_type);
-				cm_kvp = kvp_frame_copy(cm_param->param_getfcn(qsf_ent, cm_param));
-				cm_kvp = kvp_frame_set_value(cm_kvp, xmlGetProp(node, QSF_OBJECT_KVP), cm_value);
-				kvp_frame_setter = (void(*)(QofEntity*, KvpFrame*))cm_setter;
-				if(kvp_frame_setter != NULL) { kvp_frame_setter(qsf_ent, cm_kvp); }*/
+				
 			}
 		if(safe_strcmp(cm_param->param_type, QOF_TYPE_CHAR) == 0) { 
 			cm_char = *insert_string;
-			char_setter = (void(*)(QofEntity*, char))cm_setter;
+			char_setter = (void(*)(QofEntity*, char))cm_param->param_setfcn;
 			if(char_setter != NULL) { char_setter(ent, cm_char); }
 		}
 		param_list = param_list->next;
@@ -772,12 +767,15 @@
 	QofIdType type;
 	QofInstance *inst;
 	sql_insert_statement *sis;
+	sql_table *sis_t;
 
 	query->param_list = NULL;
+	type = NULL;
 	sis = query->parse_result->statement;
 	switch(sis->table->type) {
 		case SQL_simple: {
-			query->single_global_tablename = g_strdup_printf("%s", sis->table->d);
+			sis_t = sis->table;
+			query->single_global_tablename = g_strdup_printf("%s", sis_t->d.simple);
 			type = g_strdup(query->single_global_tablename);
 			break;
 		}
@@ -786,7 +784,7 @@
 		}
 	}
 	inst = (QofInstance*)qof_object_new_instance(type, query->book);
-	if(inst == NULL) { return; }
+	if(inst == NULL) { return NULL; }
 	query->param_list = NULL;
 	query->inserted_entity = &inst->entity;
 	qof_class_param_foreach((QofIdTypeConst)type, qof_queryForeachParam, query);
@@ -794,6 +792,19 @@
 	return query->inserted_entity;
 }
 
+static const char*
+sql_type_as_string(sql_statement_type type)
+{
+	switch (type)
+	{
+		case SQL_select : { return "SELECT"; }
+		case SQL_insert : { return "INSERT"; }
+		case SQL_delete : { return "DELETE"; }
+		case SQL_update : { return "UPDATE"; }
+		default : { return "unknown"; }
+	}
+}
+
 void 
 qof_sql_query_parse (QofSqlQuery *query, const char *str)
 {
@@ -826,7 +837,7 @@
 	if ((SQL_select != query->parse_result->type)&&(SQL_insert != query->parse_result->type))
 	{
 		PWARN("currently, only SELECT or INSERT statements are supported, "
-		                     "got type=%d", query->parse_result);
+		         "got type=%s", sql_type_as_string(query->parse_result->type));
 		return;
 	}
 
@@ -873,7 +884,7 @@
 GList * 
 qof_sql_query_run (QofSqlQuery *query, const char *str)
 {
-	GList *node, *results;
+	GList *results;
 
 	if (!query) return NULL;
 
@@ -895,7 +906,7 @@
 GList * 
 qof_sql_query_rerun (QofSqlQuery *query)
 {
-	GList *node, *results;
+	GList *results;
 
 	if (!query) return NULL;
 
Index: gnc-numeric.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/gnc-numeric.c,v
retrieving revision 1.26.4.7
retrieving revision 1.26.4.8
diff -Lsrc/engine/gnc-numeric.c -Lsrc/engine/gnc-numeric.c -u -r1.26.4.7 -r1.26.4.8
--- src/engine/gnc-numeric.c
+++ src/engine/gnc-numeric.c
@@ -33,7 +33,7 @@
 #include <string.h>
 
 #include "gnc-numeric.h"
-#include "qofmath128.c"
+#include "qofmath128.h"
 
 /* static short module = MOD_ENGINE; */
 
Index: gnc-lot-p.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/gnc-lot-p.h,v
retrieving revision 1.5.2.3
retrieving revision 1.5.2.4
diff -Lsrc/engine/gnc-lot-p.h -Lsrc/engine/gnc-lot-p.h -u -r1.5.2.3 -r1.5.2.4
--- src/engine/gnc-lot-p.h
+++ src/engine/gnc-lot-p.h
@@ -41,7 +41,6 @@
 #include "kvp_frame.h"
 #include "qofbook.h"
 #include "qofid.h"
-#include "qofid-p.h"
 
 struct gnc_lot_struct
 {
@@ -75,4 +74,3 @@
 void gnc_lot_register (void);
 
 #endif /* GNC_LOT_P_H */
-
Index: Account.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/Account.c,v
retrieving revision 1.222.4.15
retrieving revision 1.222.4.16
diff -Lsrc/engine/Account.c -Lsrc/engine/Account.c -u -r1.222.4.15 -r1.222.4.16
--- src/engine/Account.c
+++ src/engine/Account.c
@@ -35,21 +35,20 @@
 #include "gnc-date.h"
 #include "gnc-engine.h"
 #include "gnc-engine-util.h"
-#include "gnc-event-p.h"
+#include "gnc-event.h"
 #include "gnc-lot.h"
 #include "gnc-lot-p.h"
 #include "gnc-pricedb.h"
 #include "gnc-trace.h"
 #include "kvp_frame.h"
-#include "kvp-util-p.h"
+#include "kvp-util.h"
 #include "messages.h"
 #include "policy.h"
 
 #include "qofbackend.h"
-#include "qofbackend-p.h"
 #include "qof-be-utils.h"
 #include "qofbook.h"
-#include "qofbook-p.h"
+#include "qofquery.h"
 #include "qofclass.h"
 #include "qofid-p.h"
 #include "qofinstance-p.h"
Index: qofinstance.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofinstance.h,v
retrieving revision 1.10.2.1
retrieving revision 1.10.2.2
diff -Lsrc/engine/qofinstance.h -Lsrc/engine/qofinstance.h -u -r1.10.2.1 -r1.10.2.2
--- src/engine/qofinstance.h
+++ src/engine/qofinstance.h
@@ -84,6 +84,20 @@
 /** Return value of is_dirty flag */
 gboolean qof_instance_is_dirty (QofInstance *);
 
+/** \brief Set the dirty flag
+
+Sets this instance AND the collection as dirty.
+*/
+void qof_instance_set_dirty(QofInstance* inst);
+
+gboolean qof_instance_check_edit(QofInstance *inst);
+
+gboolean qof_instance_do_free(QofInstance *inst);
+
+void qof_instance_mark_free(QofInstance *inst);
+
+QofInstance* qof_instance_create (QofIdType type, QofBook *book);
+
 /** Pair things up.  This routine inserts a kvp value into each instance
  *  containing the guid of the other.  In this way, if one has one of the
  *  pair, one can always find the other by looking up it's guid.  Typically,
Index: gnc-numeric.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/gnc-numeric.h,v
retrieving revision 1.8.6.3
retrieving revision 1.8.6.4
diff -Lsrc/engine/gnc-numeric.h -Lsrc/engine/gnc-numeric.h -u -r1.8.6.3 -r1.8.6.4
--- src/engine/gnc-numeric.h
+++ src/engine/gnc-numeric.h
@@ -20,6 +20,7 @@
  *******************************************************************/
 
 /** @addtogroup Numeric
+
     The 'Numeric' functions provide a way of working with rational
     numbers while maintaining strict control over rounding errors
     when adding rationals with different denominators.  The Numeric
@@ -35,31 +36,22 @@
     addition and multiplication, but 64-bit rationals do not have 
     the dynamic range of floating point numbers.  
 
-@{ */
-/** @file gnc-numeric.h
-    @brief An exact-rational-number library for gnucash.
-    @author Copyright (C) 2000 Bill Gribble
-    @author Copyright (C) 2004 Linas Vepstas <linas at linas.org>
-*/
-
-/* ----------------------------------------------------------------
-
-EXAMPLE
--------
-The following program finds the best @code{gnc_numeric} approximation to
-the @file{math.h} constant @code{M_PI} given a maximum denominator. For
-large denominators, the @code{gnc_numeric} approximation is accurate to
+EXAMPLE\n
+-------\n
+The following program finds the best ::gnc_numeric approximation to
+the \a math.h constant \a M_PI given a maximum denominator. For
+large denominators, the ::gnc_numeric approximation is accurate to
 more decimal places than will generally be needed, but in some cases
 this may not be good enough. For example,
 
- at example
+ at verbatim
     M_PI                   = 3.14159265358979323846
     245850922 / 78256779   = 3.14159265358979311599  (16 sig figs)
     3126535 / 995207       = 3.14159265358865047446  (12 sig figs)
     355 / 113              = 3.14159292035398252096  (7 sig figs)
- at end example
+ at endverbatim
 
- at example
+ at verbatim
 #include <glib.h>
 #include "gnc-numeric.h"
 #include <math.h>
@@ -88,8 +80,15 @@
     }
   }
 }
+ at endverbatim
+
+@{ */
+/** @file gnc-numeric.h
+    @brief An exact-rational-number library for gnucash.
+    @author Copyright (C) 2000 Bill Gribble
+    @author Copyright (C) 2004 Linas Vepstas <linas at linas.org>
+*/
 
------------------------------------------------------------------ */
 
 #ifndef GNC_NUMERIC_H
 #define GNC_NUMERIC_H
@@ -107,8 +106,7 @@
  * This is a rational number, defined by numerator and denominator. */
 typedef struct _gnc_numeric gnc_numeric;
 
-/** @name Arguments 
-  * @brief Standard Arguments to most functions
+/** @name Arguments Standard Arguments to most functions
 
     Most of the gnc_numeric arithmetic functions take two arguments
     in addition to their numeric args: 'denom', which is the denominator
@@ -153,10 +151,11 @@
    the same denominator as each other and as the result), use
    GNC_DENOM_AUTO as 'denom' and 
    GNC_HOW_DENOM_FIXED | GNC_HOW_RND_NEVER as 'how'.
+@{
+*/
 
-  @{ */
+/** \brief bitmasks for HOW flags.
 
-/** bitmasks for HOW flags.
  * bits 8-15 of 'how' are reserved for the number of significant
  * digits to use in the output with GNC_HOW_DENOM_SIGFIG 
  */ 
@@ -164,7 +163,8 @@
 #define GNC_NUMERIC_DENOM_MASK   0x000000f0
 #define GNC_NUMERIC_SIGFIGS_MASK 0x0000ff00
 
-/** Rounding/Truncation modes for operations.
+/** \brief Rounding/Truncation modes for operations.
+
  *  Rounding instructions control how fractional parts in the specified
  *  denominator affect the result. For example, if a computed result is
  *  "3/4" but the specified denominator for the return value is 2, should
@@ -278,8 +278,9 @@
 
 /**  @} */
 
-/** @name Constructors */
-/*@{*/
+/** @name Constructors
+@{
+*/
 /** Make a gnc_numeric from numerator and denominator */
 static inline 
 gnc_numeric gnc_numeric_create(gint64 num, gint64 denom) {
@@ -310,10 +311,11 @@
  *  noted by error_code, rather than a number. 
  */
 gnc_numeric gnc_numeric_error(GNCNumericErrorCode error_code);
-/*@}*/
+/** @} */
 
-/** @name Value Accessors */
-/** @{*/
+/** @name Value Accessors
+ @{
+*/
 /** Return numerator */
 static inline 
 gint64 gnc_numeric_num(gnc_numeric a) { return a.num; }
@@ -333,8 +335,9 @@
 gchar * gnc_num_dbg_to_string(gnc_numeric n);
 /** @}*/
 
-/** @name Comparisons and Predicates */
-/** @{ */
+/** @name Comparisons and Predicates 
+ @{
+*/
 /** Check for error signal in value. Returns GNC_ERROR_OK (==0) if
  *  the number appears to be valid, otherwise it returns the
  *  type of error.  Error values always have a denominator of zero.
@@ -378,10 +381,11 @@
  */ 
 int gnc_numeric_same(gnc_numeric a, gnc_numeric b,   
                      gint64 denom, gint how);
-/** @}*/
+/** @} */
 
-/** @name Arithmetic Operations */
-/** @{*/
+/** @name Arithmetic Operations 
+ @{ 
+*/
 /** Return a+b. */
 gnc_numeric gnc_numeric_add(gnc_numeric a, gnc_numeric b, 
                             gint64 denom, gint how);
@@ -432,10 +436,11 @@
   return gnc_numeric_sub(a, b, GNC_DENOM_AUTO,
                          GNC_HOW_DENOM_FIXED | GNC_HOW_RND_NEVER);
 }
-/** @}*/
+/** @} */
 
-/** @name Arithmetic Functions with Exact Error Returns */
-/** @{*/
+/** @name Arithmetic Functions with Exact Error Returns 
+ @{
+*/
 /** The same as gnc_numeric_add, but uses 'error' for accumulating
  *  conversion roundoff error. */
 gnc_numeric gnc_numeric_add_with_error(gnc_numeric a, gnc_numeric b,
@@ -461,10 +466,11 @@
 gnc_numeric gnc_numeric_div_with_error(gnc_numeric a, gnc_numeric b,
                                        gint64 denom, gint how,
                                        gnc_numeric * error);
-/** @}*/
+/** @} */
 
-/** @name Change Denominator */
-/** @{*/
+/** @name Change Denominator 
+ @{
+*/
 /** Change the denominator of a gnc_numeric value to the 
  *  specified denominator under standard arguments 
  *  'denom' and 'how'. 
@@ -482,10 +488,11 @@
 /** Return input after reducing it by Greated Common Factor (GCF) 
  *  elimination */
 gnc_numeric gnc_numeric_reduce(gnc_numeric in);
-/** @}*/
+/** @} */
 
 /** @name Deprecated, backwards-compatible definitions 
-  @{ */
+  @{
+*/
 #define GNC_RND_FLOOR	GNC_HOW_RND_FLOOR
 #define GNC_RND_CEIL 	GNC_HOW_RND_CEIL 
 #define GNC_RND_TRUNC	GNC_HOW_RND_TRUNC
@@ -503,6 +510,6 @@
 
 #define GNC_DENOM_SIGFIGS(X)  GNC_HOW_DENOM_SIGFIGS(X)
 #define GNC_NUMERIC_GET_SIGFIGS(X) GNC_HOW_GET_SIGFIGS(X)
-/** @}*/
-/** @}*/
+/** @} */
+/** @} */
 #endif
Index: gnc-event-p.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/gnc-event-p.h,v
retrieving revision 1.6.4.2
retrieving revision 1.6.4.3
diff -Lsrc/engine/gnc-event-p.h -Lsrc/engine/gnc-event-p.h -u -r1.6.4.2 -r1.6.4.3
--- src/engine/gnc-event-p.h
+++ src/engine/gnc-event-p.h
@@ -27,23 +27,6 @@
 #include "gnc-event.h"
 #include "qofid.h"
 
-/* gnc_engine_generate_event
- *   Invoke all registered event handlers using the given arguments.
- *
- *   GNC_EVENT_CREATE events should be generated after the object
- *     has been created and registered in the engine entity table.
- *   GNC_EVENT_MODIFY events should be generated whenever any data
- *     member or submember (i.e., splits) is changed.
- *   GNC_EVENT_DESTROY events should be called before the object
- *     has been destroyed or removed from the entity table.
- *
- * entity:     the GUID of the entity generating the event
- * event_type: the type of event -- this should be one of the
- *             single-bit GNCEngineEventType values, not a combination.
- */
-void gnc_engine_gen_event (QofEntity *entity, 
-				GNCEngineEventType event_type);
-
 /* XXX deprecated, but still usedion on postgres backend */
 void gnc_engine_generate_event (const GUID *, QofIdType, GNCEngineEventType);
 
Index: gnc-pricedb.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/gnc-pricedb.c,v
retrieving revision 1.48.4.8
retrieving revision 1.48.4.9
diff -Lsrc/engine/gnc-pricedb.c -Lsrc/engine/gnc-pricedb.c -u -r1.48.4.8 -r1.48.4.9
--- src/engine/gnc-pricedb.c
+++ src/engine/gnc-pricedb.c
@@ -29,7 +29,7 @@
 
 #include "gnc-engine.h"
 #include "gnc-engine-util.h"
-#include "gnc-event-p.h"
+#include "gnc-event.h"
 #include "gnc-pricedb-p.h"
 #include "gnc-trace.h"
 #include "guid.h"
@@ -37,8 +37,11 @@
 
 #include "qofbackend-p.h"
 #include "qof-be-utils.h"
-#include "qofbook.h"
+/** \todo fix backend price_lookup using define gnucash major version
+and remove the private book header. */
+#ifdef GNUCASH_MAJOR_VERSION
 #include "qofbook-p.h"
+#endif
 #include "qofclass.h"
 #include "qofid-p.h"
 #include "qofobject.h"
@@ -656,9 +659,11 @@
 gnc_pricedb_destroy(GNCPriceDB *db)
 {
   if(!db) return;
+  if(!db->commodity_hash) {
   g_hash_table_foreach (db->commodity_hash,
                         destroy_pricedb_commodity_hash_data,
                         NULL);
+  }
   g_hash_table_destroy (db->commodity_hash);
   db->commodity_hash = NULL;
   qof_instance_release (&db->inst);
@@ -811,7 +816,7 @@
     PWARN("no currency");
     return FALSE;
   }
-  if(!db->commodity_hash) return FALSE;
+  if(!db->commodity_hash) { return FALSE; }
 
   currency_hash = g_hash_table_lookup(db->commodity_hash, commodity);
   if(!currency_hash) {
@@ -986,7 +991,7 @@
 
 /* ==================================================================== */
 /* lookup/query functions */
-
+/** \todo Fix the backend lookup that relies on a #define */
 GNCPrice *
 gnc_pricedb_lookup_latest(GNCPriceDB *db,
                           gnc_commodity *commodity,
@@ -998,7 +1003,8 @@
 
   ENTER ("db=%p commodity=%p currency=%p", db, commodity, currency);
   if(!db || !commodity || !currency) return NULL;
-
+/** \todo QOF spinout: fix book->backend price_lookup in gnucash */
+#ifdef GNUCASH_MAJOR_VERSION
   if (db->inst.book->backend && db->inst.book->backend->price_lookup)
   {
      GNCPriceLookup pl;
@@ -1008,6 +1014,7 @@
      pl.currency = currency;
      (db->inst.book->backend->price_lookup) (db->inst.book->backend, &pl);
   }
+#endif
 
   currency_hash = g_hash_table_lookup(db->commodity_hash, commodity);
   if(!currency_hash) return NULL;
@@ -1049,7 +1056,8 @@
 
   ENTER ("db=%p commodity=%p", db, commodity);
   if(!db || !commodity) return NULL;
-
+/** \todo QOF spinout: Fix the book->backend lookup */
+#ifdef GNUCASH_MAJOR_VERSION
   if (db->inst.book->backend && db->inst.book->backend->price_lookup)
   {
      GNCPriceLookup pl;
@@ -1059,7 +1067,7 @@
      pl.currency = NULL;  /* can the backend handle this??? */
      (db->inst.book->backend->price_lookup) (db->inst.book->backend, &pl);
   }
-
+#endif
   currency_hash = g_hash_table_lookup(db->commodity_hash, commodity);
   if(!currency_hash) return NULL;
 
@@ -1092,7 +1100,8 @@
 
   ENTER ("db=%p commodity=%p currency=%p", db, commodity, currency);
   if(!db || !commodity) return FALSE;
-
+/** \todo QOF spinout: Fix the book->backend lookup */
+#ifdef GNUCASH_MAJOR_VERSION
   if (db->inst.book && db->inst.book->backend && db->inst.book->backend->price_lookup)
   {
      GNCPriceLookup pl;
@@ -1102,7 +1111,7 @@
      pl.currency = currency;
      (db->inst.book->backend->price_lookup) (db->inst.book->backend, &pl);
   }
-
+#endif
   currency_hash = g_hash_table_lookup(db->commodity_hash, commodity);
   if(!currency_hash) {
     LEAVE("no, no currency_hash table");
@@ -1137,7 +1146,8 @@
 
   ENTER ("db=%p commodity=%p currency=%p", db, commodity, currency);
   if(!db || !commodity) return NULL;
-
+/** \todo QOF spinout: Fix the book->backend lookup */
+#ifdef GNUCASH_MAJOR_VERSION
   if (db->inst.book->backend && db->inst.book->backend->price_lookup)
   {
      GNCPriceLookup pl;
@@ -1147,7 +1157,7 @@
      pl.currency = currency;
      (db->inst.book->backend->price_lookup) (db->inst.book->backend, &pl);
   }
-
+#endif
   currency_hash = g_hash_table_lookup(db->commodity_hash, commodity);
   if(!currency_hash) return NULL;
 
@@ -1183,7 +1193,8 @@
 
   /* Convert to noon local time. */
   t = timespecCanonicalDayTime(t);
-
+/** \todo QOF spinout: Fix the book->backend lookup */
+#ifdef GNUCASH_MAJOR_VERSION
   if (db->inst.book->backend && db->inst.book->backend->price_lookup)
   {
      GNCPriceLookup pl;
@@ -1194,7 +1205,7 @@
      pl.date = t;
      (db->inst.book->backend->price_lookup) (db->inst.book->backend, &pl);
   }
-
+#endif
   currency_hash = g_hash_table_lookup(db->commodity_hash, c);
   if(!currency_hash) return NULL;
 
@@ -1251,7 +1262,8 @@
 
   /* Convert to noon local time. */
   t = timespecCanonicalDayTime(t);
-
+/** \todo QOF spinout: Fix the book->backend lookup */
+#ifdef GNUCASH_MAJOR_VERSION
   if (db->inst.book->backend && db->inst.book->backend->price_lookup)
   {
      GNCPriceLookup pl;
@@ -1262,7 +1274,7 @@
      pl.date = t;
      (db->inst.book->backend->price_lookup) (db->inst.book->backend, &pl);
   }
-
+#endif
   currency_hash = g_hash_table_lookup(db->commodity_hash, c);
   if(!currency_hash) return NULL;
 
@@ -1292,7 +1304,8 @@
 
   ENTER ("db=%p commodity=%p currency=%p", db, c, currency);
   if(!db || !c || !currency) return NULL;
-
+/** \todo QOF spinout: Fix the book->backend lookup */
+#ifdef GNUCASH_MAJOR_VERSION
   if (db->inst.book->backend && db->inst.book->backend->price_lookup)
   {
      GNCPriceLookup pl;
@@ -1303,7 +1316,7 @@
      pl.date = t;
      (db->inst.book->backend->price_lookup) (db->inst.book->backend, &pl);
   }
-
+#endif
   currency_hash = g_hash_table_lookup(db->commodity_hash, c);
   if(!currency_hash) return NULL;
 
@@ -1356,7 +1369,8 @@
 
   ENTER ("db=%p commodity=%p", db, c);
   if(!db || !c) return NULL;
-
+/** \todo QOF spinout: Fix the book->backend lookup */
+#ifdef GNUCASH_MAJOR_VERSION
   if (db->inst.book->backend && db->inst.book->backend->price_lookup)
   {
      GNCPriceLookup pl;
@@ -1367,7 +1381,7 @@
      pl.date = t;
      (db->inst.book->backend->price_lookup) (db->inst.book->backend, &pl);
   }
-
+#endif
   currency_hash = g_hash_table_lookup(db->commodity_hash, c);
   if(!currency_hash) return NULL;
 
@@ -1399,7 +1413,8 @@
 
   ENTER ("db=%p commodity=%p currency=%p", db, c, currency);
   if(!db || !c || !currency) return NULL;
-
+/** \todo QOF spinout: Fix the book->backend lookup */
+#ifdef GNUCASH_MAJOR_VERSION
   if (db->inst.book->backend && db->inst.book->backend->price_lookup)
   {
      GNCPriceLookup pl;
@@ -1410,7 +1425,7 @@
      pl.date = t;
      (db->inst.book->backend->price_lookup) (db->inst.book->backend, &pl);
   }
-
+#endif
   currency_hash = g_hash_table_lookup(db->commodity_hash, c);
   if(!currency_hash) return NULL;
 
@@ -1523,7 +1538,8 @@
 
   ENTER ("db=%p commodity=%p", db, c);
   if(!db || !c) return NULL;
-
+/** \todo QOF spinout: Fix the book->backend lookup */
+#ifdef GNUCASH_MAJOR_VERSION
   if (db->inst.book->backend && db->inst.book->backend->price_lookup)
   {
      GNCPriceLookup pl;
@@ -1534,7 +1550,7 @@
      pl.date = t;
      (db->inst.book->backend->price_lookup) (db->inst.book->backend, &pl);
   }
-
+#endif
   currency_hash = g_hash_table_lookup(db->commodity_hash, c);
   if(!currency_hash) return NULL;
 
@@ -1749,7 +1765,7 @@
   foreach_data.ok = TRUE;
   foreach_data.func = f;
   foreach_data.user_data = user_data;
-
+  if(db->commodity_hash == NULL) { return FALSE; }
   g_hash_table_foreach(db->commodity_hash,
                        pricedb_foreach_currencies_hash,
                        &foreach_data);
Index: FreqSpec.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/FreqSpec.c,v
retrieving revision 1.28.4.8
retrieving revision 1.28.4.9
diff -Lsrc/engine/FreqSpec.c -Lsrc/engine/FreqSpec.c -u -r1.28.4.8 -r1.28.4.9
--- src/engine/FreqSpec.c
+++ src/engine/FreqSpec.c
@@ -74,7 +74,6 @@
 \********************************************************************/
 
 #include "config.h"
-
 #include <time.h>
 
 #include <glib.h>
@@ -87,12 +86,12 @@
 #include "FreqSpecP.h"
 #include "gnc-date.h"
 #include "gnc-engine-util.h"
-#include "gnc-event-p.h"
+#include "gnc-event.h"
 #include "gnc-trace.h"
 #include "messages.h"
 #include "qofbook.h"
-#include "qofbook-p.h"
 #include "qofid-p.h"
+#include "qofinstance-p.h"
 
 static short module = MOD_SX;
 /* 
@@ -689,7 +688,7 @@
   if(dom > 31)
   {
     /* This is displayed instead of the number of the day of month. */
-    g_string_sprintf(str, _( "last day"));
+    g_string_sprintf(str, (char*)_( "last day"));
   }
   else
   {
@@ -727,7 +726,7 @@
 
    switch( xaccFreqSpecGetUIType( fs ) ) {
    case UIFREQ_NONE:
-     snprintf( freqStrBuf, MAX_FREQ_STR_SIZE, _("None") );
+     snprintf( freqStrBuf, MAX_FREQ_STR_SIZE, (char*)_("None") );
      break;
 
    case UIFREQ_ONCE:
@@ -737,7 +736,7 @@
              GNC_D_FMT,
              &fs->s.once.date );
       /* %s is the strftime-string of the one-time date. */
-      snprintf( freqStrBuf, MAX_FREQ_STR_SIZE, _("Once: %s"), tmpStr );
+      snprintf( freqStrBuf, MAX_FREQ_STR_SIZE, (char*)_("Once: %s"), tmpStr );
       g_free( tmpStr );
       break;
 
@@ -746,12 +745,12 @@
       {
          snprintf( freqStrBuf, MAX_FREQ_STR_SIZE,
               /* %u is the number of intervals */
-              _("Daily (x%u)"),
+              (char*)_("Daily (x%u)"),
               fs->s.daily.interval_days );
       }
       else 
       {
-         snprintf( freqStrBuf, MAX_FREQ_STR_SIZE, _("Daily") );
+         snprintf( freqStrBuf, MAX_FREQ_STR_SIZE, (char*)_("Daily") );
       }
       break;
 
@@ -761,7 +760,7 @@
       if ( g_list_length( fs->s.composites.subSpecs ) != 5 ) {
          PERR( "Invalid Daily[M-F] structure." );
          snprintf( freqStrBuf, MAX_FREQ_STR_SIZE,
-              "Daily[M-F]: error" );
+              (char*)"Daily[M-F]: error" );
          return;
       }
       /* We assume that all of the weekly FreqSpecs that make up
@@ -771,12 +770,12 @@
       if ( subFS->s.weekly.interval_weeks > 1 ) {
         snprintf( freqStrBuf, MAX_FREQ_STR_SIZE,
              /* %u is the number of intervals */
-             _("Weekdays: (x%u)"),
+             (char*)_("Weekdays: (x%u)"),
              subFS->s.weekly.interval_weeks );
       }
       else
       {
-        snprintf(freqStrBuf, MAX_FREQ_STR_SIZE, _("Weekdays"));
+        snprintf(freqStrBuf, MAX_FREQ_STR_SIZE, (char*)_("Weekdays"));
       }
      
    }
@@ -798,7 +797,7 @@
          tmpFS = (FreqSpec*)list->data;
          if ( xaccFreqSpecGetType(tmpFS) != WEEKLY ) {
             snprintf( freqStrBuf, MAX_FREQ_STR_SIZE,
-                 "error: UIFREQ_WEEKLY doesn't contain weekly children" );
+                 (char*)"error: UIFREQ_WEEKLY doesn't contain weekly children" );
             g_free( tmpStr );
             return;
          }
@@ -815,20 +814,20 @@
         snprintf( freqStrBuf, MAX_FREQ_STR_SIZE,
              /* %d are the number of intervals; %s is
                 the name of the weekday */
-             _( "Weekly (x%d): %s"), tmpInt, tmpStr );
+             (char*)_( "Weekly (x%d): %s"), tmpInt, tmpStr );
       }
       else
       {
         snprintf( freqStrBuf, MAX_FREQ_STR_SIZE,
              /* Translators: %s is the name of the weekday */
-             _( "Weekly: %s"), tmpStr );
+             (char*)_( "Weekly: %s"), tmpStr );
       }
       g_free( tmpStr );
       break;
 
    case UIFREQ_BI_WEEKLY:
      /* %s is the name of the weekday */
-     snprintf( freqStrBuf, MAX_FREQ_STR_SIZE, _("Bi-Weekly, %ss"), 
+     snprintf( freqStrBuf, MAX_FREQ_STR_SIZE, (char*)_("Bi-Weekly, %ss"), 
           get_wday_name(fs->s.weekly.offset_from_epoch % 7) );
      break;
 
@@ -851,7 +850,7 @@
           %s is the day of month of the starting month
           (or the string "last day"); %s is the day of
           month of the ending month  */
-            _("Semi-monthly (x%u): %s, %s"), 
+            (char*)_("Semi-monthly (x%u): %s, %s"), 
             tmpFS->s.monthly.interval_months,
             first_dom->str, 
             second_dom->str);
@@ -862,7 +861,7 @@
             /* Translators: %s is the day of month of the
           starting month (or the string "last day"); %s
           is the day of month of the ending month  */
-            _("Semi-monthly: %s, %s"), 
+            (char*)_("Semi-monthly: %s, %s"), 
             first_dom->str,
             second_dom->str);
      }
@@ -878,7 +877,7 @@
         snprintf( freqStrBuf, MAX_FREQ_STR_SIZE,
              /* %u is the number of intervals; %u is
                 the day of month  */
-             _("Monthly (x%u): %u"),
+             (char*)_("Monthly (x%u): %u"),
              fs->s.monthly.interval_months,
              fs->s.monthly.day_of_month);
       }
@@ -886,7 +885,7 @@
       {
         snprintf( freqStrBuf, MAX_FREQ_STR_SIZE,
              /* %u is the day of month  */
-             _("Monthly: %u"),
+             (char*)_("Monthly: %u"),
              fs->s.monthly.day_of_month );
       }
       break;
@@ -896,7 +895,7 @@
         snprintf( freqStrBuf, MAX_FREQ_STR_SIZE,
              /* %u is the number of intervals; %u is
                 the day of month  */
-             _("Quarterly (x%u): %u"),
+             (char*)_("Quarterly (x%u): %u"),
              fs->s.monthly.interval_months/3,
              fs->s.monthly.day_of_month);
       }
@@ -904,7 +903,7 @@
       {
         snprintf( freqStrBuf, MAX_FREQ_STR_SIZE,
              /* %u is the day of month  */
-             _("Quarterly: %u"),
+             (char*)_("Quarterly: %u"),
              fs->s.monthly.day_of_month );
       }
       break;
@@ -915,7 +914,7 @@
         snprintf( freqStrBuf, MAX_FREQ_STR_SIZE,
              /* %u is the number of intervals; %u is
                 the day of month  */
-             _("Tri-Yearly (x%u): %u"),
+             (char*)_("Tri-Yearly (x%u): %u"),
              fs->s.monthly.interval_months/4,
              fs->s.monthly.day_of_month);
       }
@@ -923,7 +922,7 @@
       {
         snprintf( freqStrBuf, MAX_FREQ_STR_SIZE,
              /* %u is the day of month  */
-             _("Tri-Yearly: %u"),
+             (char*)_("Tri-Yearly: %u"),
              fs->s.monthly.day_of_month );
       }
       break;
@@ -938,7 +937,7 @@
          snprintf( freqStrBuf, MAX_FREQ_STR_SIZE,
               /* %u is the number of intervals; %u
                  is the day of month  */
-              _("Semi-Yearly (x%u): %u"),
+              (char*)_("Semi-Yearly (x%u): %u"),
               fs->s.monthly.interval_months/6,
               fs->s.monthly.day_of_month);
       }
@@ -946,7 +945,7 @@
       {
         snprintf( freqStrBuf, MAX_FREQ_STR_SIZE,
              /* %u is the day of month  */
-             _("Semi-Yearly: %u"),
+             (char*)_("Semi-Yearly: %u"),
              fs->s.monthly.day_of_month );
       }
       break;
@@ -969,7 +968,7 @@
                  %u is the number of intervals; %s is the
                  abbreviated name of the month; %u is the
                  day of month. */
-              _("Yearly (x%u): %s/%u"),
+              (char*)_("Yearly (x%u): %s/%u"),
               fs->s.monthly.interval_months/12,
               get_abbrev_month_name(fs->s.monthly.offset_from_epoch),
               fs->s.monthly.day_of_month);
@@ -979,14 +978,14 @@
         snprintf( freqStrBuf, MAX_FREQ_STR_SIZE,
              /* %s is the abbreviated name of the
                 month; %u is the day of month  */
-             _("Yearly: %s/%u"),
+             (char*)_("Yearly: %s/%u"),
              get_abbrev_month_name(fs->s.monthly.offset_from_epoch),
              fs->s.monthly.day_of_month );
       }
       break;
 
    default:
-      snprintf( freqStrBuf, MAX_FREQ_STR_SIZE, _("Unknown") );
+      snprintf( freqStrBuf, MAX_FREQ_STR_SIZE, (char*)_("Unknown") );
       break;
    }
    g_string_sprintf( str, "%s", freqStrBuf );
Index: qofbackend-p.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofbackend-p.h,v
retrieving revision 1.2.4.3
retrieving revision 1.2.4.4
diff -Lsrc/engine/qofbackend-p.h -Lsrc/engine/qofbackend-p.h -u -r1.2.4.3 -r1.2.4.4
--- src/engine/qofbackend-p.h
+++ src/engine/qofbackend-p.h
@@ -42,10 +42,10 @@
 #define QOF_BACKEND_P_H
 
 #include "config.h"
-
+#include "qof-be-utils.h"
 #include "qofbackend.h"
 #include "qofbook.h"
-#include "qofinstance.h"
+#include "qofinstance-p.h"
 #include "qofquery.h"
 #include "qofsession.h"
 
Index: qof_book_merge.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qof_book_merge.c,v
retrieving revision 1.2.2.10
retrieving revision 1.2.2.11
diff -Lsrc/engine/qof_book_merge.c -Lsrc/engine/qof_book_merge.c -u -r1.2.2.10 -r1.2.2.11
--- src/engine/qof_book_merge.c
+++ src/engine/qof_book_merge.c
@@ -22,6 +22,8 @@
  ********************************************************************/
 
 #include "qof_book_merge.h"
+#include "qofinstance-p.h"
+#include "qofchoice.h"
 #include "qofid-p.h"
 static short module = MOD_ENGINE;
 
@@ -44,48 +46,6 @@
 #define QOF_STRING_WEIGHT       3
 #define QOF_DATE_STRING_LENGTH  MAX_DATE_LENGTH
 
-/** \brief Makes the decisions about how matches and conflicts are tagged.
-
-Paramater Type Weighting is used via the gint argument. This is used to give
-priority to string matches over boolean or numerical matches. Higher values
-of weight decrease the likelihood of that entity being the best match.
-
-New rules start at:
-	- ::MERGE_ABSOLUTE\n 
-		(GUID's match; first parameter matches) OR
-	- ::MERGE_DUPLICATE\n
-		(GUID's do NOT match; first parameter DOES match) OR
-	- ::MERGE_NEW\n
-	(GUID's do NOT match; first parameters does NOT match).
-	
-If subsequent parameters in the same object FAIL a match:
-	- \a MERGE_ABSOLUTE fallsback to ::MERGE_UPDATE \n
-		(GUID matches but some parameters differ)\n
-		(guidTarget will be updated with mergeEnt)
-	- \a MERGE_DUPLICATE fallsback to ::MERGE_REPORT\n
-		(GUID does not match and some parameters do NOT match)
-	- \a MERGE_NEW fallsback to \a MERGE_REPORT
-		(GUID does not match and some parameters now DO match)
-
-<b>Comparisons without a GUID match.</b>
-	Only sets a failed match if ALL parameters fail to match.
-	When absolute is FALSE, all suitable target objects are compared.
-
-	Identifies the closest match using a difference rank. This avoids 
-	using non-generic tests for object similarities. The
-	value closest to zero is used.
-	
-	qof_book_merge use sa high value of weight to make a good match
-	more important and make it more likely that the chosen target will
-	have matching values for the types with the highest weight.
-
- at param	currentRule - the ::qof_book_mergeRule to update.
- at param	mergeMatch	- whether the two entities match or not
- at param	weight		- Parameter Type Weighting.
-
- at return 	returns the qof_book_mergeRule.
-
-*/
 static qof_book_mergeRule*
 qof_book_mergeUpdateRule(qof_book_mergeRule *currentRule, gboolean match, gint weight)
 {
@@ -263,6 +223,12 @@
 			currentRule = qof_book_mergeUpdateRule(currentRule, mergeMatch, DEFAULT_MERGE_WEIGHT);
 			knowntype = TRUE;
 		}
+		if(safe_strcmp(mergeType, QOF_TYPE_CHOICE) ==0) {
+			referenceEnt = qtparam->param_getfcn(mergeEnt, qtparam);
+			currentRule->linkedEntList = g_slist_prepend(currentRule->linkedEntList, referenceEnt);
+			if(referenceEnt == qtparam->param_getfcn(targetEnt, qtparam)) { mergeMatch = TRUE; }
+			knowntype = TRUE;
+		}
 		if(knowntype == FALSE) {
 			referenceEnt = qtparam->param_getfcn(mergeEnt, qtparam);
 			if((referenceEnt != NULL)
@@ -324,7 +290,7 @@
 	g_list_foreach (subList, qof_book_mergeCommitForeachCB, &iter);
 }
 
-/** \brief build the table of target comparisons
+/* build the table of target comparisons
 
 This can get confusing, so bear with me. (!)
 
@@ -596,43 +562,6 @@
 	iter->remainder--;
 }
 
-static QofEntity*
-qof_book_mergeLocateReference( QofEntity *ent, qof_book_mergeData *mergeData)
-{
-	GList *all_rules;
-	qof_book_mergeRule *rule;
-	QofEntity *referenceEnt;
-
-	/* locates the rule referring to this import entity */
-	if(!ent) { return NULL; }
-	g_return_val_if_fail((mergeData != NULL), NULL);
-	all_rules = NULL;
-	referenceEnt = NULL;
-	all_rules = g_list_copy(mergeData->mergeList);
-	while(all_rules != NULL) {
-		rule = all_rules->data;
-		if(rule->importEnt == ent) { referenceEnt = rule->targetEnt; }
-		all_rules = g_list_next(all_rules);
-	}
-	return referenceEnt;
-}
-
-/** \brief Commit the data from the import to the target QofBook.
-
-	Called by ::qof_book_mergeCommit to commit data from each rule in turn.
-	Uses QofParam->param_getfcn - ::QofAccessFunc to query the import book
-	and param_setfcn - ::QofSetterFunc to update the target book.
-\n	
-	Note: Not all param_getfcn can have a matching param_setfcn.
-	Getting the balance of an account is obviously necessary to other routines
-	but is pointless in a comparison for a merge - the balance is calculated from
-	transactions, it cannot be set by the account. A discrepancy in the calculated
-	figures for an account object should not cause a MERGE_REPORT.
-\n
- 	Limits the comparison routines to only calling param_getfcn if 
-	param_setfcn is not NULL. 
-	
-*/
 static void 
 qof_book_mergeCommitRuleLoop(
 						qof_book_mergeData *mergeData,
@@ -642,7 +571,6 @@
 	QofInstance *inst;
 	gboolean    registered_type;
 	QofEntity   *referenceEnt;
-	GSList      *linkage;
 	/* cm_ prefix used for variables that hold the data to commit */
 	QofCollection *cm_coll;
 	QofParam    *cm_param;
@@ -767,23 +695,23 @@
 			if(collection_setter != NULL) { collection_setter(rule->targetEnt, cm_coll); }
 			registered_type = TRUE;
 		}
-		if(registered_type == FALSE) {
-			linkage = g_slist_copy(rule->linkedEntList);
-			referenceEnt = NULL;
-			reference_setter = (void(*)(QofEntity*, QofEntity*))cm_param->param_setfcn;
-			if((linkage == NULL)&&(rule->mergeResult == MERGE_NEW)) {
+		if(safe_strcmp(rule->mergeType, QOF_TYPE_CHOICE) == 0) {
 				referenceEnt = cm_param->param_getfcn(rule->importEnt, cm_param);
-				reference_setter(rule->targetEnt, qof_book_mergeLocateReference(referenceEnt, mergeData));
+			reference_setter = (void(*)(QofEntity*, QofEntity*))cm_param->param_setfcn;
+			if(reference_setter != NULL) 
+			{ 
+				reference_setter(rule->targetEnt, referenceEnt); 
 			}
-			while(linkage != NULL) {
-				referenceEnt = linkage->data;
-				if((referenceEnt)
-					&&(referenceEnt->e_type)
-					&&(safe_strcmp(referenceEnt->e_type, rule->mergeType) == 0)) {
-					/* The function behind reference_setter must create objects for any non-QOF references */
-					reference_setter(rule->targetEnt, qof_book_mergeLocateReference(referenceEnt, mergeData));
+			registered_type = TRUE;
+		}
+		if(registered_type == FALSE) {
+			referenceEnt = cm_param->param_getfcn(rule->importEnt, cm_param);
+			if(referenceEnt) {
+				reference_setter = (void(*)(QofEntity*, QofEntity*))cm_param->param_setfcn;
+				if(reference_setter != NULL) 
+				{ 
+					reference_setter(rule->targetEnt, referenceEnt); 
 				}
-				linkage = g_slist_next(linkage);
 			}
 		}
 		rule->mergeParam = g_slist_next(rule->mergeParam);
Index: SchedXaction.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/SchedXaction.c,v
retrieving revision 1.41.4.5
retrieving revision 1.41.4.6
diff -Lsrc/engine/SchedXaction.c -Lsrc/engine/SchedXaction.c -u -r1.41.4.5 -r1.41.4.6
--- src/engine/SchedXaction.c
+++ src/engine/SchedXaction.c
@@ -36,12 +36,11 @@
 #include "gnc-date.h"
 #include "gnc-engine.h"
 #include "gnc-engine-util.h"
-#include "gnc-event-p.h"
+#include "gnc-event.h"
 #include "gnc-trace.h"
 #include "guid.h"
 #include "messages.h"
 #include "qofbook.h"
-#include "qofbook-p.h"
 #include "qofid-p.h"
 
 static short module = MOD_SX;
Index: gnc-lot.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/gnc-lot.c,v
retrieving revision 1.14.4.7
retrieving revision 1.14.4.8
diff -Lsrc/engine/gnc-lot.c -Lsrc/engine/gnc-lot.c -u -r1.14.4.7 -r1.14.4.8
--- src/engine/gnc-lot.c
+++ src/engine/gnc-lot.c
@@ -41,16 +41,14 @@
 #include "Account.h"
 #include "gnc-engine-util.h"
 #include "gnc-event.h"
-#include "gnc-event-p.h"
 #include "gnc-lot.h"
 #include "gnc-lot-p.h"
 #include "gnc-trace.h"
 #include "Transaction.h"
 #include "TransactionP.h"
 #include "qofbook.h"
-#include "qofbook-p.h"
 #include "qofclass.h"
-#include "qofid-p.h"
+#include "qofid.h"
 #include "qofquery.h"
 
 /* This static indicates the debugging module that this .o belongs to.  */
Index: SX-book.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/SX-book.c,v
retrieving revision 1.7.4.2
retrieving revision 1.7.4.3
diff -Lsrc/engine/SX-book.c -Lsrc/engine/SX-book.c -u -r1.7.4.2 -r1.7.4.3
--- src/engine/SX-book.c
+++ src/engine/SX-book.c
@@ -47,7 +47,6 @@
 #include "SX-book-p.h"
 
 #include "qofbook.h"
-#include "qofbook-p.h"
 #include "qofinstance.h"
 #include "qofinstance-p.h"
 #include "qofobject.h"
Index: qof-be-utils.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qof-be-utils.h,v
retrieving revision 1.3.2.4
retrieving revision 1.3.2.5
diff -Lsrc/engine/qof-be-utils.h -Lsrc/engine/qof-be-utils.h -u -r1.3.2.4 -r1.3.2.5
--- src/engine/qof-be-utils.h
+++ src/engine/qof-be-utils.h
@@ -25,6 +25,7 @@
 /**  @file qof-be-utils.h 
    @brief QOF Backend Utilities
    @author Derek Atkins <derek at ihtfp.com>
+   @author Neil Williams <linux at codehelp.co.uk>
 
   Common code used by objects to define begin_edit() and
   commit_edit() functions.
@@ -37,6 +38,7 @@
 #include "gnc-engine-util.h"
 #include "qofbackend-p.h"
 #include "qofbook.h"
+#include "qofinstance.h"
 
 /** begin_edit helper
  *
@@ -44,6 +46,9 @@
  *        inst: an instance of QofInstance
  *
  * The caller should use this macro first and then perform any other operations.
+
+ Uses newly created functions to allow the macro to be used
+ when QOF is linked as a library. qofbackend-p.h is a private header.
  */
 
 #define QOF_BEGIN_EDIT(inst)                                        \
@@ -62,14 +67,19 @@
                                                                     \
   /* See if there's a backend.  If there is, invoke it. */          \
   be = qof_book_get_backend ((inst)->book);                         \
-  if (be && be->begin) {                                            \
-     (be->begin) (be, (inst));                                      \
+    if (be && qof_backend_begin_exists((be))) {                     \
+     qof_backend_run_begin((be), (inst));                           \
   } else {                                                          \
      /* We tried and failed to start transaction! */                \
      (inst)->dirty = TRUE;                                          \
-  }                                                                 \
-  LEAVE ("(inst=%p)", (inst));
+  }
 
+/** \brief function version of QOF_BEGIN_EDIT
+
+The macro cannot be used in a function that returns a value,
+this function can be used instead.
+*/
+void qof_begin_edit(QofInstance *inst);
 
 /**
  * commit_edit helpers
@@ -99,8 +109,8 @@
   {                                                              \
     QofBackend * be;                                             \
     be = qof_book_get_backend ((inst)->book);                    \
-    if (be && be->begin) {                                       \
-     (be->begin) (be, (inst));                                   \
+    if (be && qof_backend_begin_exists((be))) {                  \
+     qof_backend_run_begin((be), (inst));                        \
     }                                                            \
     (inst)->editlevel = 0;                                       \
   }                                                              \
@@ -113,6 +123,13 @@
             (inst), (inst)->dirty, (inst)->do_free);             \
 }
 
+/** \brief function version of QOF_COMMIT_EDIT_PART1
+
+The macro cannot be used in a function that returns a value,
+this function can be used instead. Only Part1 is implemented.
+*/
+void qof_commit_edit(QofInstance *inst);
+
 /**
  * part2 -- deal with the backend
  * 
@@ -132,7 +149,7 @@
                                                                  \
   /* See if there's a backend.  If there is, invoke it. */       \
   be = qof_book_get_backend ((inst)->book);                      \
-  if (be && be->commit)                                          \
+  if (be && qof_backend_commit_exists((be)))                     \
   {                                                              \
     QofBackendError errcode;                                     \
                                                                  \
@@ -141,7 +158,7 @@
       errcode = qof_backend_get_error (be);                      \
     } while (ERR_BACKEND_NO_ERR != errcode);                     \
                                                                  \
-    (be->commit) (be, (inst));                                   \
+    qof_backend_run_commit((be), (inst));                        \
     errcode = qof_backend_get_error (be);                        \
     if (ERR_BACKEND_NO_ERR != errcode)                           \
     {                                                            \
Index: qofobject.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofobject.h,v
retrieving revision 1.7.2.2
retrieving revision 1.7.2.3
diff -Lsrc/engine/qofobject.h -Lsrc/engine/qofobject.h -u -r1.7.2.2 -r1.7.2.3
--- src/engine/qofobject.h
+++ src/engine/qofobject.h
@@ -30,6 +30,11 @@
 
     QOF Objects are also used by the query system .... 
     
+    To work with your own QOF Objects, you can use the QOF
+    Generator to create sample objects and a mini-application
+    with the SQL-type query interface.
+    http://qof-gen.sourceforge.net/
+
     XXX todo, we should split out the storage aspects of this 
     thing from the 'foreach' that query depends on.  These are
     kinda unrelated concepts.
@@ -45,6 +50,7 @@
 
 #include "qofbook.h"
 #include "qofid.h"
+#include "qofchoice.h"
 
 /** Defines the version of the core object object registration
  * interface.  Only object modules compiled against this version
Index: Group.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/Group.c,v
retrieving revision 1.112.4.8
retrieving revision 1.112.4.9
diff -Lsrc/engine/Group.c -Lsrc/engine/Group.c -u -r1.112.4.8 -r1.112.4.9
--- src/engine/Group.c
+++ src/engine/Group.c
@@ -33,12 +33,11 @@
 #include "GroupP.h"
 #include "TransactionP.h"
 #include "gnc-engine-util.h"
-#include "gnc-event-p.h"
+#include "gnc-event.h"
 #include "gnc-numeric.h"
 #include "gnc-trace.h"
 #include "qofbackend.h"
 #include "qofbook.h"
-#include "qofbook-p.h"
 #include "qofid-p.h"
 #include "qofobject.h"
 
@@ -1234,7 +1233,7 @@
 {
   grp = xaccGroupGetRoot (grp);
   if (!grp || !grp->book) return NULL;
-  return grp->book->backend;
+  return qof_book_get_backend(grp->book);
 }
 
 /* ============================================================== */
Index: qofinstance.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofinstance.c,v
retrieving revision 1.10.2.3
retrieving revision 1.10.2.4
diff -Lsrc/engine/qofinstance.c -Lsrc/engine/qofinstance.c -u -r1.10.2.3 -r1.10.2.4
--- src/engine/qofinstance.c
+++ src/engine/qofinstance.c
@@ -41,6 +41,16 @@
 
 /* ========================================================== */
 
+QofInstance*
+qof_instance_create (QofIdType type, QofBook *book)
+{
+	QofInstance *inst;
+
+	inst = g_new0(QofInstance, 1);
+	qof_instance_init(inst, type, book);
+	return inst;
+}
+
 void 
 qof_instance_init (QofInstance *inst, QofIdType type, QofBook *book)
 {
@@ -116,8 +126,42 @@
 gboolean
 qof_instance_is_dirty (QofInstance *inst)
 {
-	if (!inst) return FALSE;
-	return inst->dirty;
+	QofCollection *coll;
+
+	if (!inst) { return FALSE; }
+	coll = inst->entity.collection;
+	if(qof_collection_is_dirty(coll)) { return inst->dirty; }
+	inst->dirty = FALSE;
+	return FALSE;
+}
+
+void
+qof_instance_set_dirty(QofInstance* inst)
+{
+	QofCollection *coll;
+
+	inst->dirty = TRUE;
+	coll = inst->entity.collection;
+	qof_collection_mark_dirty(coll);
+}
+
+gboolean
+qof_instance_check_edit(QofInstance *inst)
+{
+	if(inst->editlevel > 0) { return TRUE; }
+	return FALSE;
+}
+
+gboolean
+qof_instance_do_free(QofInstance *inst)
+{
+	return inst->do_free;
+}
+
+void
+qof_instance_mark_free(QofInstance *inst)
+{
+	inst->do_free = TRUE;
 }
 
 /* ========================================================== */
Index: gnc-event.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/gnc-event.h,v
retrieving revision 1.8.6.2
retrieving revision 1.8.6.3
diff -Lsrc/engine/gnc-event.h -Lsrc/engine/gnc-event.h -u -r1.8.6.2 -r1.8.6.3
--- src/engine/gnc-event.h
+++ src/engine/gnc-event.h
@@ -71,6 +71,22 @@
  */
 void gnc_engine_unregister_event_handler (gint handler_id);
 
+/* gnc_engine_generate_event
+ *   Invoke all registered event handlers using the given arguments.
+ *
+ *   GNC_EVENT_CREATE events should be generated after the object
+ *     has been created and registered in the engine entity table.
+ *   GNC_EVENT_MODIFY events should be generated whenever any data
+ *     member or submember (i.e., splits) is changed.
+ *   GNC_EVENT_DESTROY events should be called before the object
+ *     has been destroyed or removed from the entity table.
+ *
+ * entity:     the GUID of the entity generating the event
+ * event_type: the type of event -- this should be one of the
+ *             single-bit GNCEngineEventType values, not a combination.
+ */
+void gnc_engine_gen_event (QofEntity *entity,
+                                GNCEngineEventType event_type);
 /* gnc_engine_suspend_events
  *   Suspend all engine events. This function may be
  *   called multiple times. To resume event generation,
Index: qofbackend.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofbackend.h,v
retrieving revision 1.3.4.6
retrieving revision 1.3.4.7
diff -Lsrc/engine/qofbackend.h -Lsrc/engine/qofbackend.h -u -r1.3.4.6 -r1.3.4.7
--- src/engine/qofbackend.h
+++ src/engine/qofbackend.h
@@ -21,6 +21,7 @@
 /** @addtogroup Object
     @{ */
 /** @addtogroup Backend
+
     The QOF Backend is a pseudo-object providing an interface between the
     engine and a persistant data store (e.g. a server, a database, or
     a file).   Backends are not meant to be used directly by an
@@ -40,6 +41,8 @@
 #ifndef QOF_BACKEND_H
 #define QOF_BACKEND_H
 
+#include "qofinstance.h"
+
 /** \brief The errors that can be reported to the GUI & other front-end users
  *  \warning (GnuCash) If you modify QofBackendError, please update 
  *   src/engine/gw-engine-spec.scm 
@@ -149,6 +152,29 @@
 /** \brief DOCUMENT ME! */
 typedef void (*QofBePercentageFunc) (const char *message, double percent);
 
+/** \name Allow access to the begin routine for this backend.
+
+QOF_BEGIN_EDIT and QOF_COMMIT_EDIT_PART1 and part2 rely on 
+calling QofBackend *be->begin and be->commit. This means the
+QofBackend struct becomes part of the public API.
+These function replaces those calls to allow the macros to be
+used when QOF is built as a library.
+@{
+*/
+void qof_backend_run_begin(QofBackend *be, QofInstance *inst);
+
+gboolean qof_backend_begin_exists(QofBackend *be);
+
+void qof_backend_run_commit(QofBackend *be, QofInstance *inst);
+
+gboolean qof_backend_commit_exists(QofBackend *be);
+
+/** @} */
+/** \brief Retrieve the backend used by this book */
+QofBackend* qof_book_get_backend (QofBook *book);
+
+void qof_book_set_backend (QofBook *book, QofBackend *);
+
 #endif /* QOF_BACKEND_H */
 /**@}*/
 /**@}*/
Index: qofsession-p.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofsession-p.h,v
retrieving revision 1.2.4.5
retrieving revision 1.2.4.6
diff -Lsrc/engine/qofsession-p.h -Lsrc/engine/qofsession-p.h -u -r1.2.4.5 -r1.2.4.6
--- src/engine/qofsession-p.h
+++ src/engine/qofsession-p.h
@@ -31,7 +31,6 @@
 
 #include "qofbook.h"
 #include "qofsession.h"
-#include "qofid.h"
 
 struct _QofSession
 {
@@ -41,8 +40,8 @@
    */
   QofEntity entity;
 
-  /* A book holds pointers to the various types of datasets used
-   * by GnuCash.  A session may have open multiple books.  */
+  /* A book holds pointers to the various types of datasets.
+   * A session may have multiple books. */
   GList *books;
 
   /* The requested book id, in the form or a URI, such as
@@ -75,4 +74,3 @@
 QofBackend* gncBackendInit_file(const char *book_id, void *data);
 
 #endif
-
Index: qofquerycore-p.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofquerycore-p.h,v
retrieving revision 1.4.2.1
retrieving revision 1.4.2.2
diff -Lsrc/engine/qofquerycore-p.h -Lsrc/engine/qofquerycore-p.h -u -r1.4.2.1 -r1.4.2.2
--- src/engine/qofquerycore-p.h
+++ src/engine/qofquerycore-p.h
@@ -129,4 +129,18 @@
   KvpValue *	value;
 } query_kvp_def, *query_kvp_t;
 
+typedef struct {
+	QofQueryPredData pd;
+	QofGuidMatch  options;
+	QofCollection *coll;
+	GList *guids;
+} query_coll_def, *query_coll_t;
+
+typedef struct {
+	QofQueryPredData pd;
+	QofGuidMatch options;
+	const GUID *guid;
+	GList * guids;
+} query_choice_def, *query_choice_t;
+
 #endif /* QOF_QUERYCOREP_H */
Index: qof.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qof.h,v
retrieving revision 1.2.4.4
retrieving revision 1.2.4.5
diff -Lsrc/engine/qof.h -Lsrc/engine/qof.h -u -r1.2.4.4 -r1.2.4.5
--- src/engine/qof.h
+++ src/engine/qof.h
@@ -49,6 +49,9 @@
     @addtogroup Object Object: Dynamic Object Class Framework
     @ingroup QOF
 */
+/** @addtogroup Choice Choice and collect : One to many links.
+	@ingroup QOF
+*/
 /**
     @addtogroup Query Query: Querying for Objects
     @ingroup QOF
@@ -79,5 +82,6 @@
 #include "qofquerycore.h"
 #include "qofsession.h"
 #include "qofsql.h"
+#include "qofchoice.h"
 
 #endif /* QOF_H_ */
Index: gnc-engine-util.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/gnc-engine-util.h,v
retrieving revision 1.32.4.7
retrieving revision 1.32.4.8
diff -Lsrc/engine/gnc-engine-util.h -Lsrc/engine/gnc-engine-util.h -u -r1.32.4.7 -r1.32.4.8
--- src/engine/gnc-engine-util.h
+++ src/engine/gnc-engine-util.h
@@ -33,7 +33,7 @@
 
 #include <glib.h>
 #include <stddef.h>
-
+#include "config.h"
 #include "gnc-trace.h"  // XXX eliminate me eventually
 
 /** Macros *****************************************************/
@@ -63,34 +63,81 @@
 #define SAFE_STRCMP(da,db) SAFE_STRCMP_REAL(strcmp,(da),(db))
 #define SAFE_STRCASECMP(da,db) SAFE_STRCMP_REAL(strcasecmp,(da),(db))
 
+/** \name typedef enum as string macros
+@{
+*/
 #define ENUM_BODY(name, value)           \
     name value,
+
 #define AS_STRING_CASE(name, value)      \
-    case name: return #name;
+    case name: { return #name; }
+
 #define FROM_STRING_CASE(name, value)    \
     if (strcmp(str, #name) == 0) {       \
-        return name;                     \
-    }
+        return name;  }
+
 #define DEFINE_ENUM(name, list)          \
     typedef enum {                       \
         list(ENUM_BODY)                  \
     }name;
+
 #define AS_STRING_DEC(name, list)        \
     const char* name##asString(name n);
+
 #define AS_STRING_FUNC(name, list)       \
     const char* name##asString(name n) {       \
         switch (n) {                     \
             list(AS_STRING_CASE)         \
-            default: return "";          \
-        }                                \
-    }
+            default: return "";  } }
+
 #define FROM_STRING_DEC(name, list)      \
-    name name##fromString(const char* str);
+    name name##fromString                \
+    (const char* str);
+
 #define FROM_STRING_FUNC(name, list)     \
-    name name##fromString(const char* str) {   \
+    name name##fromString                \
+    (const char* str) {                  \
+    if(str == NULL) { return 0; }        \
         list(FROM_STRING_CASE)           \
-        return 0;                        \
-    }
+        return 0;  }
+
+/** @} */
+
+/** \name enum as string with no typedef
+@{
+
+  Similar but used when the enum is NOT a typedef
+ note the LACK of a define_enum macro - don't use one!
+
+ ENUM_BODY is used in both types.
+ */
+
+#define FROM_STRING_DEC_NON_TYPEDEF(name, list)   \
+   void name##fromString                          \
+   (const char* str, enum name *type);
+
+#define FROM_STRING_CASE_NON_TYPEDEF(name, value) \
+   if (strcmp(str, #name) == 0) { *type = name; }
+
+#define FROM_STRING_FUNC_NON_TYPEDEF(name, list)  \
+   void name##fromString                          \
+   (const char* str, enum name *type) {           \
+   if(str == NULL) { return; }                    \
+    list(FROM_STRING_CASE_NON_TYPEDEF) }
+
+#define AS_STRING_DEC_NON_TYPEDEF(name, list)     \
+   const char* name##asString(enum name n);
+
+#define AS_STRING_FUNC_NON_TYPEDEF(name, list)    \
+   const char* name##asString(enum name n) {     \
+       switch (n) {                              \
+           list(AS_STRING_CASE_NON_TYPEDEF)      \
+           default: return ""; } }
+
+#define AS_STRING_CASE_NON_TYPEDEF(name, value)   \
+   case name: { return #name; }
+
+/** @} */
 
 /* Define the long long int conversion for scanf */
 #if HAVE_SCANF_LLD
@@ -180,6 +227,5 @@
    (or value), as long as you use the destroy notifier above. */
 gpointer gnc_string_cache_insert(gpointer key);
 
-
 #endif /* QOF_UTIL_H */
 /** @} */
Index: qofbook.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofbook.h,v
retrieving revision 1.5.2.7
retrieving revision 1.5.2.8
diff -Lsrc/engine/qofbook.h -Lsrc/engine/qofbook.h -u -r1.5.2.7 -r1.5.2.8
--- src/engine/qofbook.h
+++ src/engine/qofbook.h
@@ -43,7 +43,7 @@
 #include <glib.h>
 
 #include "qofid.h"
-#include "qofbackend.h"
+//#include "qofbackend.h"
 #include "kvp_frame.h"
 
 /** @brief Encapsulates all the information about a dataset
@@ -130,11 +130,6 @@
 /** Retrieves arbitrary pointers to structs stored by qof_book_set_data. */
 gpointer qof_book_get_data (QofBook *book, const char *key);
 
-/** DOCUMENT ME! */
-QofBackend *qof_book_get_backend (QofBook *book);
-
-void qof_book_set_backend (QofBook *book, QofBackend *);
-
 /** Is the book shutting down? */
 gboolean qof_book_shutting_down (QofBook *book);
 
Index: qofclass.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofclass.c,v
retrieving revision 1.1.6.5
retrieving revision 1.1.6.6
diff -Lsrc/engine/qofclass.c -Lsrc/engine/qofclass.c -u -r1.1.6.5 -r1.1.6.6
--- src/engine/qofclass.c
+++ src/engine/qofclass.c
@@ -126,7 +126,7 @@
   ht = g_hash_table_lookup (classTable, obj_name);
   if (!ht)
   {
-    PERR ("no object of type %s", obj_name);
+    PWARN ("no object of type %s", obj_name);
     return NULL;
   }
 
Index: qofgobj.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofgobj.c,v
retrieving revision 1.2.2.3
retrieving revision 1.2.2.4
diff -Lsrc/engine/qofgobj.c -Lsrc/engine/qofgobj.c -u -r1.2.2.3 -r1.2.2.4
--- src/engine/qofgobj.c
+++ src/engine/qofgobj.c
@@ -221,7 +221,7 @@
   QofParam *qof_param_list, *qpar;
   QofObject *class_def;
   GParamSpec **prop_list, *gparam;
-  int n_props;
+  guint n_props;
 
   /* Get the GObject properties, convert to QOF properties */
   prop_list = g_object_class_list_properties (obclass, &n_props);
@@ -240,7 +240,7 @@
           i, gparam->name, G_PARAM_SPEC_TYPE_NAME(gparam));
 
     qpar->param_name = g_param_spec_get_name (gparam);
-    qpar->param_getfcn = qof_gobject_getter;
+    qpar->param_getfcn = (QofAccessFunc)qof_gobject_getter;
     qpar->param_setfcn = NULL;
     qpar->param_userdata = gparam;
     if ((G_IS_PARAM_SPEC_INT(gparam))  ||
Index: qofsession.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofsession.h,v
retrieving revision 1.2.4.7
retrieving revision 1.2.4.8
diff -Lsrc/engine/qofsession.h -Lsrc/engine/qofsession.h -u -r1.2.4.7 -r1.2.4.8
--- src/engine/qofsession.h
+++ src/engine/qofsession.h
@@ -412,9 +412,10 @@
 repeated references for a single entity.
 */
 typedef struct qof_entity_reference {
+	QofIdType       choice_type;/**< When the reference is a different type.*/
 	QofIdType        type;       /**< The type of entity */
 	GUID             *ref_guid;  /**< The GUID of the REFERENCE entity */
-	const QofParam  *param;      /**< The parameter used to get/set this reference. */
+	const QofParam  *param;      /**< The parameter name and type. */
 	const GUID      *ent_guid;   /**< The GUID of the original entity. */
 }QofEntityReference;
 
Index: Transaction.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/Transaction.c,v
retrieving revision 1.261.4.12
retrieving revision 1.261.4.13
diff -Lsrc/engine/Transaction.c -Lsrc/engine/Transaction.c -u -r1.261.4.12 -r1.261.4.13
--- src/engine/Transaction.c
+++ src/engine/Transaction.c
@@ -42,7 +42,7 @@
 #include "gnc-date.h"
 #include "gnc-engine-util.h"
 #include "gnc-engine.h"
-#include "gnc-event-p.h"
+#include "gnc-event.h"
 #include "gnc-lot-p.h"
 #include "gnc-lot.h"
 #include "gnc-trace.h"
@@ -51,7 +51,7 @@
 #include "qofbackend-p.h"
 #include "qof-be-utils.h"
 #include "qofbook.h"
-#include "qofbook-p.h"
+#include "qofquery.h"
 #include "qofclass.h"
 #include "qofid-p.h"
 #include "qofobject.h"
@@ -661,6 +661,7 @@
   }
 
   s->kvp_data = frm;
+  qof_commit_edit(&s->parent->inst);
 }
 
 /********************************************************************\
@@ -1620,7 +1621,7 @@
         errcode = qof_backend_get_error (be);
       } while (ERR_BACKEND_NO_ERR != errcode);
 
-      (be->commit) (be, &(trans->inst));
+      qof_backend_run_commit(be, &(trans->inst));
 
       errcode = qof_backend_get_error (be);
       if (ERR_BACKEND_NO_ERR != errcode)
@@ -1850,6 +1851,8 @@
    /* Now that the engine copy is back to its original version,
     * get the backend to fix it in the database */
    be = qof_book_get_backend (trans->inst.book);
+   /** \todo Fix transrollbackedit in QOF so that rollback
+   is exposed via the API. */
    if (be && be->rollback) 
    {
       QofBackendError errcode;
@@ -2392,8 +2395,10 @@
 {
 	if (!trans) { return; }
 	if((ts.tv_nsec == 0)&&(ts.tv_sec == 0)) { return; }
+	qof_begin_edit(&trans->inst);
 	xaccTransSetDateInternal(trans, &trans->date_posted, ts);
 	set_gains_date_dirty(trans);
+	qof_commit_edit(&trans->inst);
 }
 
 void
@@ -2409,7 +2414,9 @@
 {
 	if (!trans) { return; }
 	if((ts.tv_nsec == 0)&&(ts.tv_sec == 0)) { return; }
+	qof_begin_edit(&trans->inst);
 	xaccTransSetDateInternal(trans, &trans->date_entered, ts);
+	qof_commit_edit(&trans->inst);
 }
 
 void
@@ -2436,6 +2443,14 @@
    kvp_frame_set_timespec (trans->inst.kvp_data, TRANS_DATE_DUE_KVP, *ts);
 }
 
+static void
+qofTransSetTxnType (Transaction *trans, char type)
+{
+	qof_begin_edit(&trans->inst);
+	xaccTransSetTxnType(trans, type);
+	qof_commit_edit(&trans->inst);
+}
+
 void
 xaccTransSetTxnType (Transaction *trans, char type)
 {
@@ -2460,6 +2475,14 @@
 /********************************************************************\
 \********************************************************************/
 
+static void
+qofTransSetNum (Transaction *trans, const char *xnum)
+{
+	qof_begin_edit(&trans->inst);
+	xaccTransSetNum(trans, xnum);
+	qof_commit_edit(&trans->inst);
+}
+
 void
 xaccTransSetNum (Transaction *trans, const char *xnum)
 {
@@ -2472,6 +2495,14 @@
    trans->num = tmp;
 }
 
+static void
+qofTransSetDescription (Transaction *trans, const char *desc)
+{
+	qof_begin_edit(&trans->inst);
+	xaccTransSetDescription(trans, desc);
+	qof_commit_edit(&trans->inst);
+}
+
 void
 xaccTransSetDescription (Transaction *trans, const char *desc)
 {
@@ -2484,6 +2515,14 @@
    trans->description = tmp;
 }
 
+static void
+qofTransSetNotes (Transaction *trans, const char *notes)
+{
+	qof_begin_edit(&trans->inst);
+	xaccTransSetNotes(trans, notes);
+	qof_commit_edit(&trans->inst);
+}
+
 void
 xaccTransSetNotes (Transaction *trans, const char *notes)
 {
@@ -3366,15 +3405,15 @@
 gboolean xaccTransRegister (void)
 {
   static QofParam params[] = {
-    { TRANS_NUM, QOF_TYPE_STRING, (QofAccessFunc)xaccTransGetNum, (QofSetterFunc)xaccTransSetNum },
-    { TRANS_DESCRIPTION, QOF_TYPE_STRING, (QofAccessFunc)xaccTransGetDescription, (QofSetterFunc)xaccTransSetDescription },
+    { TRANS_NUM, QOF_TYPE_STRING, (QofAccessFunc)xaccTransGetNum, (QofSetterFunc)qofTransSetNum },
+    { TRANS_DESCRIPTION, QOF_TYPE_STRING, (QofAccessFunc)xaccTransGetDescription, (QofSetterFunc)qofTransSetDescription },
     { TRANS_DATE_ENTERED, QOF_TYPE_DATE, (QofAccessFunc)xaccTransRetDateEnteredTS, (QofSetterFunc)qofTransSetDateEntered },
     { TRANS_DATE_POSTED, QOF_TYPE_DATE, (QofAccessFunc)xaccTransRetDatePostedTS, (QofSetterFunc)qofTransSetDatePosted },
     { TRANS_DATE_DUE, QOF_TYPE_DATE, (QofAccessFunc)xaccTransRetDateDueTS, NULL },
     { TRANS_IMBALANCE, QOF_TYPE_NUMERIC, (QofAccessFunc)xaccTransGetImbalance,NULL },
-    { TRANS_NOTES, QOF_TYPE_STRING, (QofAccessFunc)xaccTransGetNotes, (QofSetterFunc)xaccTransSetNotes },
+    { TRANS_NOTES, QOF_TYPE_STRING, (QofAccessFunc)xaccTransGetNotes, (QofSetterFunc)qofTransSetNotes },
     { TRANS_IS_BALANCED, QOF_TYPE_BOOLEAN, (QofAccessFunc)trans_is_balanced_p, NULL },
-    { TRANS_TYPE, QOF_TYPE_CHAR, (QofAccessFunc)xaccTransGetTxnType, (QofSetterFunc)xaccTransSetTxnType },
+    { TRANS_TYPE, QOF_TYPE_CHAR, (QofAccessFunc)xaccTransGetTxnType, (QofSetterFunc)qofTransSetTxnType },
     { TRANS_VOID_STATUS, QOF_TYPE_BOOLEAN, (QofAccessFunc)xaccTransGetVoidStatus,NULL },
     { TRANS_VOID_REASON, QOF_TYPE_STRING, (QofAccessFunc)xaccTransGetVoidReason,NULL },
     { TRANS_VOID_TIME, QOF_TYPE_DATE,    (QofAccessFunc)xaccTransGetVoidTime,   NULL },
Index: qofsession.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofsession.c,v
retrieving revision 1.2.4.20
retrieving revision 1.2.4.21
diff -Lsrc/engine/qofsession.c -Lsrc/engine/qofsession.c -u -r1.2.4.20 -r1.2.4.21
--- src/engine/qofsession.c
+++ src/engine/qofsession.c
@@ -56,6 +56,7 @@
 #include "gnc-trace.h"
 #include "qofsession.h"
 #include "qofbackend-p.h"
+#include "qof-be-utils.h"
 #include "qofbook.h"
 #include "qofbook-p.h"
 #include "qofobject.h"
@@ -325,17 +326,6 @@
 	gboolean error;
 }QofEntityCopyData;
 
-static gboolean
-qsf_check_error(QofEntityCopyData *qecd)
-{
-	if(qecd->error == TRUE) {
-		qof_entity_release(qecd->to);
-		g_free(qecd->to);
-		return TRUE;
-	}
-	return FALSE;
-}
-
 static void
 qof_book_set_partial(QofBook *book)
 {
@@ -343,6 +333,7 @@
 
 	partial =
 	  (gboolean)GPOINTER_TO_INT(qof_book_get_data(book, PARTIAL_QOFBOOK));
+
 	if(!partial) {
 		qof_book_set_data(book, PARTIAL_QOFBOOK, (gboolean*)TRUE);
 	}
@@ -368,7 +359,7 @@
 
 	g_return_if_fail(data != NULL);
 	qecd = (QofEntityCopyData*)data;
-	g_return_if_fail(qecd != NULL);
+	g_return_if_fail(param != NULL);
 	if((param->param_getfcn != NULL)&&(param->param_setfcn != NULL)) {
 			qecd->param_list = g_slist_prepend(qecd->param_list, param);
 	}
@@ -379,21 +370,18 @@
 {
 	QofEntityReference *reference;
 	QofEntity    *ref_ent;
-	QofParam     *copy_param;
 	const GUID   *cm_guid;
 	char         cm_sa[GUID_ENCODING_LENGTH + 1];
 	gchar        *cm_string;
 
-	ref_ent = param->param_getfcn(ent, param);
+	g_return_val_if_fail(param, NULL);
+	ref_ent = (QofEntity*)param->param_getfcn(ent, param);
 	if(ref_ent != NULL) {
 		reference = g_new0(QofEntityReference, 1);
-		reference->type = g_strdup(ent->e_type);
+		reference->type = ent->e_type;
 		reference->ref_guid = g_new(GUID, 1);
 		reference->ent_guid = &ent->guid;
-		copy_param = g_new0(QofParam, 1);
-		copy_param->param_name = g_strdup(param->param_name);
-		copy_param->param_type = g_strdup(param->param_type);
-		reference->param = copy_param;
+		reference->param = qof_class_get_parameter(ent->e_type, param->param_name);
 		cm_guid = qof_entity_get_guid(ref_ent);
 		guid_to_string_buff(cm_guid, cm_sa);
 		cm_string = g_strdup(cm_sa);
@@ -448,11 +436,10 @@
 	cm_param = (QofParam*) data;
 	g_return_if_fail(cm_param != NULL);
 	if(safe_strcmp(cm_param->param_type, QOF_TYPE_STRING) == 0)  { 
-		cm_string = g_strdup(cm_param->param_getfcn(importEnt, cm_param));
+		cm_string = g_strdup((gchar*)cm_param->param_getfcn(importEnt, cm_param));
 		string_setter = (void(*)(QofEntity*, const char*))cm_param->param_setfcn;
 		if(string_setter != NULL) { string_setter(targetEnt, cm_string); }
 		registered_type = TRUE;
-		context->error = FALSE;
 	}
 	if(safe_strcmp(cm_param->param_type, QOF_TYPE_DATE) == 0) { 
 		date_getter = (Timespec (*)(QofEntity*, QofParam*))cm_param->param_getfcn;
@@ -460,7 +447,6 @@
 		date_setter = (void(*)(QofEntity*, Timespec))cm_param->param_setfcn;
 		if(date_setter != NULL) { date_setter(targetEnt, cm_date); }
 		registered_type = TRUE;
-		context->error = FALSE;
 	}
 	if((safe_strcmp(cm_param->param_type, QOF_TYPE_NUMERIC) == 0)  ||
 	(safe_strcmp(cm_param->param_type, QOF_TYPE_DEBCRED) == 0)) { 
@@ -469,14 +455,12 @@
 		numeric_setter = (void(*)(QofEntity*, gnc_numeric))cm_param->param_setfcn;
 		if(numeric_setter != NULL) { numeric_setter(targetEnt, cm_numeric); }
 		registered_type = TRUE;
-		context->error = FALSE;
 	}
 	if(safe_strcmp(cm_param->param_type, QOF_TYPE_GUID) == 0) { 
-		cm_guid = cm_param->param_getfcn(importEnt, cm_param);
+		cm_guid = (const GUID*)cm_param->param_getfcn(importEnt, cm_param);
 		guid_setter = (void(*)(QofEntity*, const GUID*))cm_param->param_setfcn;
 		if(guid_setter != NULL) { guid_setter(targetEnt, cm_guid); }
 		registered_type = TRUE;
-		context->error = FALSE;
 	}
 	if(safe_strcmp(cm_param->param_type, QOF_TYPE_INT32) == 0) { 
 		int32_getter = (gint32 (*)(QofEntity*, QofParam*)) cm_param->param_getfcn;
@@ -484,7 +468,6 @@
 		i32_setter = (void(*)(QofEntity*, gint32))cm_param->param_setfcn;
 		if(i32_setter != NULL) { i32_setter(targetEnt, cm_i32); }
 		registered_type = TRUE;
-		context->error = FALSE;
 	}
 	if(safe_strcmp(cm_param->param_type, QOF_TYPE_INT64) == 0) { 
 		int64_getter = (gint64 (*)(QofEntity*, QofParam*)) cm_param->param_getfcn;
@@ -492,7 +475,6 @@
 		i64_setter = (void(*)(QofEntity*, gint64))cm_param->param_setfcn;
 		if(i64_setter != NULL) { i64_setter(targetEnt, cm_i64); }
 		registered_type = TRUE;
-		context->error = FALSE;
 	}
 	if(safe_strcmp(cm_param->param_type, QOF_TYPE_DOUBLE) == 0) { 
 		double_getter = (double (*)(QofEntity*, QofParam*)) cm_param->param_getfcn;
@@ -500,7 +482,6 @@
 		double_setter = (void(*)(QofEntity*, double))cm_param->param_setfcn;
 		if(double_setter != NULL) { double_setter(targetEnt, cm_double); }
 		registered_type = TRUE;
-		context->error = FALSE;
 	}
 	if(safe_strcmp(cm_param->param_type, QOF_TYPE_BOOLEAN) == 0){ 
 		boolean_getter = (gboolean (*)(QofEntity*, QofParam*)) cm_param->param_getfcn;
@@ -508,29 +489,26 @@
 		boolean_setter = (void(*)(QofEntity*, gboolean))cm_param->param_setfcn;
 		if(boolean_setter != NULL) { boolean_setter(targetEnt, cm_boolean); }
 		registered_type = TRUE;
-		context->error = FALSE;
 	}
 	if(safe_strcmp(cm_param->param_type, QOF_TYPE_KVP) == 0) { 
-		cm_kvp = kvp_frame_copy(cm_param->param_getfcn(importEnt,cm_param));
+		cm_kvp = kvp_frame_copy((KvpFrame*)cm_param->param_getfcn(importEnt,cm_param));
 		kvp_frame_setter = (void(*)(QofEntity*, KvpFrame*))cm_param->param_setfcn;
 		if(kvp_frame_setter != NULL) { kvp_frame_setter(targetEnt, cm_kvp); }
 		registered_type = TRUE;
-		context->error = FALSE;
 	}
 	if(safe_strcmp(cm_param->param_type, QOF_TYPE_CHAR) == 0) { 
-		cm_char = cm_param->param_getfcn(importEnt,cm_param);
+		cm_char = (gchar*)cm_param->param_getfcn(importEnt,cm_param);
 		char_setter = (void(*)(QofEntity*, char*))cm_param->param_setfcn;
 		if(char_setter != NULL) { char_setter(targetEnt, cm_char); }
 		registered_type = TRUE;
-		context->error = FALSE;
 	}
 	if(registered_type == FALSE) {
-		referenceEnt = cm_param->param_getfcn(importEnt, cm_param);
+		referenceEnt = (QofEntity*)cm_param->param_getfcn(importEnt, cm_param);
+		if(!referenceEnt || !referenceEnt->e_type) { return; }
 		reference = qof_entity_get_reference_from(importEnt, cm_param);
 		if(reference) {
 			qof_session_update_reference_list(context->new_session, reference);
 		}
-		context->error = FALSE;
 	}
 }
 
@@ -568,17 +546,21 @@
 	original = (QofEntity*)data;
 	g_return_if_fail(user_data != NULL);
 	qecd = (QofEntityCopyData*)user_data;
+	if(qof_entity_guid_match(qecd->new_session, original)) { return; }
 	qecd->from = original;
 	book = qof_session_get_book(qecd->new_session);
 	inst = (QofInstance*)qof_object_new_instance(original->e_type, book);
 	qecd->to = &inst->entity;
 	g = qof_entity_get_guid(original);
 	qof_entity_set_guid(qecd->to, g);
-//	if(qecd->param_list != NULL) { g_slist_free(qecd->param_list); }
+	if(qecd->param_list != NULL) { 
+		g_slist_free(qecd->param_list);
+		qecd->param_list = NULL;
+	}
+	qof_begin_edit(inst);
 	qof_class_param_foreach(original->e_type, qof_entity_param_cb, qecd);
-	if(qsf_check_error(qecd)) { return; }
+	qof_commit_edit(inst);
 	g_slist_foreach(qecd->param_list, qof_entity_foreach_copy, qecd);
-	qsf_check_error(qecd);
 }
 
 static void
@@ -616,8 +598,9 @@
 	qecd->from = original;
 	g = qof_entity_get_guid(original);
 	qof_entity_set_guid(qecd->to, g);
+	qof_begin_edit(inst);
 	g_slist_foreach(qecd->param_list, qof_entity_foreach_copy, qecd);
-	qsf_check_error(qecd);
+	qof_commit_edit(inst);
 }
 
 gboolean qof_entity_copy_to_session(QofSession* new_session, QofEntity* original)
@@ -625,24 +608,23 @@
 	QofEntityCopyData qecd;
 	QofInstance *inst;
 	QofBook *book;
-	const GUID *g;
 
+	if(!new_session || !original) { return FALSE; }
 	if(qof_entity_guid_match(new_session, original)) { return FALSE; }
 	gnc_engine_suspend_events();
 	qecd.param_list = NULL;
 	book = qof_session_get_book(new_session);
 	qecd.new_session = new_session;
 	qof_book_set_partial(book);
-	qecd.error = FALSE;
 	inst = (QofInstance*)qof_object_new_instance(original->e_type, book);
 	qecd.to = &inst->entity;
 	qecd.from = original;
-	g = qof_entity_get_guid(original);
-	qof_entity_set_guid(qecd.to, g);
+	qof_entity_set_guid(qecd.to, qof_entity_get_guid(original));
+	qof_begin_edit(inst);
 	qof_class_param_foreach(original->e_type, qof_entity_param_cb, &qecd);
+	qof_commit_edit(inst);
 	if(g_slist_length(qecd.param_list) == 0) { return FALSE; }
 	g_slist_foreach(qecd.param_list, qof_entity_foreach_copy, &qecd);
-	if(qsf_check_error(&qecd)) { return FALSE; }
 	g_slist_free(qecd.param_list);
 	gnc_engine_resume_events();
 	return TRUE;
@@ -650,25 +632,16 @@
 
 gboolean qof_entity_copy_list(QofSession *new_session, GList *entity_list)
 {
-	GList *e;
-	QofEntity *original;
-	QofEntityCopyData qecd;
+	QofEntityCopyData *qecd;
 
+	qecd = g_new0(QofEntityCopyData, 1);
 	gnc_engine_suspend_events();
-	qecd.param_list = NULL;
-	qecd.new_session = new_session;
-	qof_book_set_partial(qof_session_get_book(qecd.new_session));
-	qecd.error = FALSE;
-	for(e=entity_list; e; e=e->next)
-	{
-		original = (QofEntity*) e->data;
-		/* The GList can contain mixed entity types, it may */
-		/* appear slow, but we do need to check the type every time */
-		/* because we can't re-use the QofCollection or QofIdType. */
-		if(qof_entity_guid_match(new_session, original)) return FALSE;
-	}
-	g_list_foreach(entity_list, qof_entity_list_foreach, &qecd);
+	qecd->param_list = NULL;
+	qecd->new_session = new_session;
+	qof_book_set_partial(qof_session_get_book(new_session));
+	g_list_foreach(entity_list, qof_entity_list_foreach, qecd);
 	gnc_engine_resume_events();
+	g_free(qecd);
 	return TRUE;
 }
 
@@ -680,9 +653,7 @@
 	qecd.param_list = NULL;
 	qecd.new_session = new_session;
 	qof_book_set_partial(qof_session_get_book(qecd.new_session));
-	qecd.error = FALSE;
 	qof_collection_foreach(entity_coll, qof_entity_coll_foreach, &qecd);
-	if(qecd.error == TRUE) return FALSE;
 	qof_class_param_foreach(qof_collection_get_type(entity_coll), qof_entity_param_cb, &qecd);
 	qof_collection_foreach(entity_coll, qof_entity_coll_copy, &qecd);
 	if(qecd.param_list != NULL) { g_slist_free(qecd.param_list); }
@@ -706,7 +677,10 @@
 	if(user_data == NULL) { return; }
 	store = (struct recurse_s*)user_data;
 	if(!ent || !store) { return; }
+	store->success = qof_entity_copy_to_session(store->session, ent);
+	if(store->success) {
 	store->ent_list = g_list_append(store->ent_list, ent);
+	}
 }
 
 static void
@@ -828,6 +802,9 @@
 
 /* Specify a library, and a function name. Load the library, 
  * call the function name in the library.  */
+/* Use duplicate calls to cover 
+ * the name of the shared library that is .so on
+ * GNU/Linux but .dylib on Mac OSX etc. */
 static void
 load_backend_library (const char * libso, const char * loadfn)
 {
@@ -956,10 +933,14 @@
 	if (NULL == provider_list)
 	{
 		/* hack alert: If you change this, change qof_session_save as well. */
-#ifdef BUILD_DWI
+#ifdef HAVE_DWI
 		load_backend_library ("libqof_backend_dwi.so", "dwiend_provider_init");
 #endif
+#ifdef DARWIN 
+		load_backend_library ("libqof-backend-qsf.dylib", "qsf_provider_init" );
+#else
 		load_backend_library ("libqof-backend-qsf.so", "qsf_provider_init" );
+#endif 
 	}
 	p = g_slist_copy(provider_list);
 	while(p != NULL)
@@ -1264,7 +1245,11 @@
 		qof_session_destroy_backend(session);
 		if (NULL == provider_list)
 		{
+#ifdef DARWIN
+			load_backend_library ("libqsf-backend-file.dylib", "qsf_provider_init" );
+#else
 			load_backend_library ("libqof-backend-qsf.so", "qsf_provider_init" );
+#endif
 		}
 		p = g_slist_copy(provider_list);
 		while(p != NULL)
Index: .cvsignore
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/.cvsignore,v
retrieving revision 1.10.4.1
retrieving revision 1.10.4.2
diff -Lsrc/engine/.cvsignore -Lsrc/engine/.cvsignore -u -r1.10.4.1 -r1.10.4.2
--- src/engine/.cvsignore
+++ src/engine/.cvsignore
@@ -19,3 +19,5 @@
 gw-kvp.html
 iso-4217-currencies.c
 test-link
+.DS_Store
+
Index: qof_book_merge.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qof_book_merge.h,v
retrieving revision 1.2.2.4
retrieving revision 1.2.2.5
diff -Lsrc/engine/qof_book_merge.h -Lsrc/engine/qof_book_merge.h -u -r1.2.2.4 -r1.2.2.5
--- src/engine/qof_book_merge.h
+++ src/engine/qof_book_merge.h
@@ -77,7 +77,7 @@
 #include "qofbook.h"
 #include "qofclass.h"
 #include "qofobject.h"
-#include "qofinstance-p.h"
+#include "qofinstance.h"
 #include "gnc-trace.h"
 
 /** \brief Results of collisions and user resolution.
@@ -459,4 +459,3 @@
 /** @} */
 /** @} */
 #endif // QOFBOOKMERGE_H
-
Index: qofclass.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofclass.h,v
retrieving revision 1.1.6.7
retrieving revision 1.1.6.8
diff -Lsrc/engine/qofclass.h -Lsrc/engine/qofclass.h -u -r1.1.6.7 -r1.1.6.8
--- src/engine/qofclass.h
+++ src/engine/qofclass.h
@@ -52,6 +52,11 @@
   The QOF Query subsystem depends on QOF classes having been
   declared; the Query uses the getters to get values associated
   with particular instances.
+  
+  A QofAccessFunc or QofSetterFunc do not need to be public 
+  functions, if you need to add functions to an object with an
+  established API, define the additional QOF routines as static.
+  Only the register routine needs to be public.
 @{ */
 
 /** @file qofclass.h
Index: gnc-commodity.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/gnc-commodity.c,v
retrieving revision 1.39.4.13
retrieving revision 1.39.4.14
diff -Lsrc/engine/gnc-commodity.c -Lsrc/engine/gnc-commodity.c -u -r1.39.4.13 -r1.39.4.14
--- src/engine/gnc-commodity.c
+++ src/engine/gnc-commodity.c
@@ -36,7 +36,7 @@
 
 #include "gnc-commodity.h"
 #include "gnc-engine-util.h"
-#include "gnc-event-p.h"
+#include "gnc-event.h"
 #include "gnc-trace.h"
 #include "guid.h"
 #include "messages.h"
Index: Makefile.am
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/Makefile.am,v
retrieving revision 1.94.2.12
retrieving revision 1.94.2.13
diff -Lsrc/engine/Makefile.am -Lsrc/engine/Makefile.am -u -r1.94.2.12 -r1.94.2.13
--- src/engine/Makefile.am
+++ src/engine/Makefile.am
@@ -56,6 +56,7 @@
   qofclass.c \
   qofid.c \
   qofinstance.c \
+  qofmath128.c \
   qofobject.c \
   qofquery.c \
   qofquerycore.c \
@@ -157,6 +158,7 @@
   qofclass-p.h \
   qofid-p.h \
   qofinstance-p.h \
+  qofmath128.h \
   qofobject-p.h \
   qofquery-p.h \
   qofquerycore-p.h \
Index: test-engine-stuff.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/test-core/test-engine-stuff.c,v
retrieving revision 1.52.4.12
retrieving revision 1.52.4.13
diff -Lsrc/engine/test-core/test-engine-stuff.c -Lsrc/engine/test-core/test-engine-stuff.c -u -r1.52.4.12 -r1.52.4.13
--- src/engine/test-core/test-engine-stuff.c
+++ src/engine/test-core/test-engine-stuff.c
@@ -671,8 +671,20 @@
   GNCPrice *p;
 
   p = gnc_price_create (book);
+  if(!p)
+  {
+      failure_args("engine-stuff", __FILE__, __LINE__,
+                   "get_random_price failed");
+      return NULL;
+  }
 
   make_random_changes_to_price (book, p);
+  if(!p)
+  {
+      failure_args("engine-stuff", __FILE__, __LINE__,
+                   "make_random_changes_to_price failed");
+      return NULL;
+  }
 
   return p;
 }
@@ -683,12 +695,24 @@
   int num_prices;
 
   num_prices = get_random_int_in_range (0, 40);
+  if(num_prices < 1)
+  {
+      failure_args("engine-stuff", __FILE__, __LINE__,
+                   "get_random_int_in_range failed");
+      return;
+  }
 
   while (num_prices-- > 0)
   {
     GNCPrice *p;
 
     p = get_random_price (book);
+    if(!p)
+    {
+        failure_args("engine-stuff", __FILE__, __LINE__,
+                     "get_random_price failed");
+        return;
+    }
 
     gnc_pricedb_add_price (db, p);
 
@@ -701,8 +725,14 @@
 {
   GNCPriceDB *db;
 
-  // db = gnc_pricedb_create (book);
+  //db = gnc_pricedb_create (book);
   db = gnc_pricedb_get_db (book);
+  if(!db)
+  {
+      failure_args("engine-stuff", __FILE__, __LINE__,
+                   "gnc_pricedb_get_db failed");
+      return NULL;
+  }
   make_random_pricedb (book, db);
 
   return db;
@@ -1334,6 +1364,7 @@
     ret = xaccMallocTransaction(book);
 
     xaccTransBeginEdit(ret);
+
     xaccTransSetCurrency (ret,
                           currency ? currency :
                           get_random_commodity (book));
@@ -1356,13 +1387,30 @@
     }
 
     xaccTransCommitEdit(ret);
+    if(!ret)
+    {
+        failure_args("engine-stuff", __FILE__, __LINE__,
+                     "get_random_transaction_with_currency failed");
+        return NULL;
+    }
+
     return ret;
 }
 
 Transaction*
 get_random_transaction (QofBook *book)
 {
-  return get_random_transaction_with_currency (book, NULL, NULL);
+	Transaction *ret;
+
+	g_return_val_if_fail(book, NULL);
+	ret = get_random_transaction_with_currency (book, NULL, NULL);
+    if(!ret)
+    {
+        failure_args("engine-stuff", __FILE__, __LINE__,
+                     "get_random_transaction failed");
+        return NULL;
+    }
+	return ret;
 }
 
 void
Index: Makefile.am
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/test-core/Makefile.am,v
retrieving revision 1.6.4.1
retrieving revision 1.6.4.2
diff -Lsrc/engine/test-core/Makefile.am -Lsrc/engine/test-core/Makefile.am -u -r1.6.4.1 -r1.6.4.2
--- src/engine/test-core/Makefile.am
+++ src/engine/test-core/Makefile.am
@@ -24,4 +24,6 @@
   -I${top_srcdir}/src/gnc-module \
   -I${top_srcdir}/src/test-core \
   -I${top_srcdir}/src/engine \
-  ${GLIB_CFLAGS}
+  ${GLIB_CFLAGS} \
+  ${GUILE_INCS}
+


More information about the gnucash-changes mailing list