[Gnucash-changes] r13111 - gnucash/trunk/src/engine/test - New test
for recursive copying of entities between sessions
Neil Williams
codehelp at cvs.gnucash.org
Sun Feb 5 05:13:38 EST 2006
Author: codehelp
Date: 2006-02-05 05:13:37 -0500 (Sun, 05 Feb 2006)
New Revision: 13111
Trac: http://svn.gnucash.org/trac/changeset/13111
Added:
gnucash/trunk/src/engine/test/test-recursive.c
Modified:
gnucash/trunk/src/engine/test/
gnucash/trunk/src/engine/test/Makefile.am
Log:
New test for recursive copying of entities between sessions
Property changes on: gnucash/trunk/src/engine/test
___________________________________________________________________
Name: svn:ignore
- *.log
Makefile
Makefile.in
.deps
.libs
test-load-engine
test-book-merge
test-commodities
test-date
test-freq-spec
test-guid
test-group-vs-book
test-link
test-lots
test-numeric
test-object
test-period
test-print-queries
test-query
test-querynew
test-recurrence
test-resolve-file-path
test-scm-query
test-split-vs-account
test-transaction-reversal
test-transaction-voiding
test-book-merge
semantic.cache
TAGS
+ *.log
Makefile
Makefile.in
.deps
.libs
test-load-engine
test-book-merge
test-commodities
test-date
test-freq-spec
test-guid
test-group-vs-book
test-link
test-lots
test-numeric
test-object
test-period
test-print-queries
test-query
test-querynew
test-recurrence
test-recursive
test-resolve-file-path
test-scm-query
test-split-vs-account
test-transaction-reversal
test-transaction-voiding
test-book-merge
semantic.cache
TAGS
Modified: gnucash/trunk/src/engine/test/Makefile.am
===================================================================
--- gnucash/trunk/src/engine/test/Makefile.am 2006-02-05 10:12:21 UTC (rev 13110)
+++ gnucash/trunk/src/engine/test/Makefile.am 2006-02-05 10:13:37 UTC (rev 13111)
@@ -39,6 +39,7 @@
test-period \
test-querynew \
test-query \
+ test-recursive \
test-resolve-file-path \
test-split-vs-account \
test-transaction-reversal \
@@ -78,6 +79,7 @@
test-period \
test-query \
test-querynew \
+ test-recursive \
test-resolve-file-path \
test-scm-query \
test-split-vs-account \
Added: gnucash/trunk/src/engine/test/test-recursive.c
===================================================================
--- gnucash/trunk/src/engine/test/test-recursive.c 2006-02-05 10:12:21 UTC (rev 13110)
+++ gnucash/trunk/src/engine/test/test-recursive.c 2006-02-05 10:13:37 UTC (rev 13111)
@@ -0,0 +1,1005 @@
+/***************************************************************************
+ * test-recursive.c
+ *
+ * Wed Feb 1 21:54:49 2006
+ * Copyright 2006 Neil Williams
+ * linux at codehelp.co.uk
+ ****************************************************************************/
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <glib.h>
+#include <glib/gprintf.h>
+#define _GNU_SOURCE
+
+#include "qofinstance-p.h"
+#include "gnc-event-p.h"
+#include "qof.h"
+#include "test-engine-stuff.h"
+#include "test-stuff.h"
+
+#define GRAND_MODULE_NAME "recursive-grandparent"
+#define PARENT_MODULE_NAME "recursive-parent"
+#define CHILD_MODULE_NAME "recursive-child"
+#define GRAND_MODULE_DESC "Recursive Grand Parent Test"
+#define PARENT_MODULE_DESC "Recursive Parent Test"
+#define CHILD_MODULE_DESC "Recursive Child Test"
+#define OBJ_NAME "somename"
+#define OBJ_AMOUNT "anamount"
+#define OBJ_DATE "nottoday"
+#define OBJ_GUID "unique"
+#define OBJ_DISCOUNT "hefty"
+#define OBJ_VERSION "early"
+#define OBJ_MINOR "tiny"
+#define OBJ_ACTIVE "ofcourse"
+#define OBJ_FLAG "tiny_flag"
+#define OBJ_RELATIVE "family"
+
+/* simple object structure */
+typedef struct child_s
+{
+ QofInstance inst;
+ gchar *Name;
+ gchar flag;
+ gnc_numeric Amount;
+ const GUID *child_guid;
+ Timespec date;
+ double discount; /* cheap pun, I know. */
+ gboolean active;
+ gint32 version;
+ gint64 minor;
+}mychild;
+
+/* simple object structure */
+typedef struct parent_s
+{
+ QofInstance inst;
+ mychild *child;
+ gchar *Name;
+ gchar flag;
+ gnc_numeric Amount;
+ const GUID *parent_guid;
+ Timespec date;
+ double discount; /* cheap pun, I know. */
+ gboolean active;
+ gint32 version;
+ gint64 minor;
+}myparent;
+
+ /* simple object structure */
+typedef struct grand_s
+{
+ QofInstance inst;
+ myparent *child;
+ gchar *Name;
+ gchar flag;
+ gnc_numeric Amount;
+ const GUID *grand_guid;
+ Timespec date;
+ double discount; /* cheap pun, I know. */
+ gboolean active;
+ gint32 version;
+ gint64 minor;
+}mygrand;
+
+mygrand* grand_create(QofBook*);
+myparent* parent_create(QofBook*);
+mychild* child_create(QofBook*);
+
+gboolean mygrandRegister (void);
+gboolean myparentRegister (void);
+gboolean mychildRegister (void);
+
+/* obvious setter functions */
+void grand_setName(mygrand*, gchar*);
+void grand_setGUID(mygrand*, const GUID*);
+void grand_setAmount(mygrand*, gnc_numeric);
+void grand_setDate(mygrand*, Timespec h);
+void grand_setDiscount(mygrand*, double);
+void grand_setActive(mygrand*, gboolean);
+void grand_setVersion(mygrand*, gint32);
+void grand_setMinor(mygrand*, gint64);
+void grand_setFlag(mygrand*, gchar);
+
+/* obvious getter functions */
+gchar* grand_getName(mygrand*);
+const GUID* grand_getGUID(mygrand*);
+gnc_numeric grand_getAmount(mygrand*);
+Timespec grand_getDate(mygrand*);
+double grand_getDiscount(mygrand*);
+gboolean grand_getActive(mygrand*);
+gint32 grand_getVersion(mygrand*);
+gint64 grand_getMinor(mygrand*);
+gchar grand_getFlag(mygrand*);
+
+/* obvious setter functions */
+void parent_setName(myparent*, gchar*);
+void parent_setGUID(myparent*, const GUID*);
+void parent_setAmount(myparent*, gnc_numeric);
+void parent_setDate(myparent*, Timespec h);
+void parent_setDiscount(myparent*, double);
+void parent_setActive(myparent*, gboolean);
+void parent_setVersion(myparent*, gint32);
+void parent_setMinor(myparent*, gint64);
+void parent_setFlag(myparent*, gchar);
+
+/* obvious getter functions */
+gchar* parent_getName(myparent*);
+const GUID* parent_getGUID(myparent*);
+gnc_numeric parent_getAmount(myparent*);
+Timespec parent_getDate(myparent*);
+double parent_getDiscount(myparent*);
+gboolean parent_getActive(myparent*);
+gint32 parent_getVersion(myparent*);
+gint64 parent_getMinor(myparent*);
+gchar parent_getFlag(myparent*);
+
+/* obvious setter functions */
+void child_setName(mychild*, gchar*);
+void child_setGUID(mychild*, const GUID*);
+void child_setAmount(mychild*, gnc_numeric);
+void child_setDate(mychild*, Timespec h);
+void child_setDiscount(mychild*, double);
+void child_setActive(mychild*, gboolean);
+void child_setVersion(mychild*, gint32);
+void child_setMinor(mychild*, gint64);
+void child_setFlag(mychild*, gchar);
+
+/* obvious getter functions */
+gchar* child_getName(mychild*);
+const GUID* child_getGUID(mychild*);
+gnc_numeric child_getAmount(mychild*);
+Timespec child_getDate(mychild*);
+double child_getDiscount(mychild*);
+gboolean child_getActive(mychild*);
+gint32 child_getVersion(mychild*);
+gint64 child_getMinor(mychild*);
+gchar child_getFlag(mychild*);
+
+mygrand*
+grand_create(QofBook *book)
+{
+ mygrand *g;
+
+ g_return_val_if_fail(book, NULL);
+ g = g_new0(mygrand, 1);
+ qof_instance_init (&g->inst, GRAND_MODULE_NAME, book);
+ g->grand_guid = get_random_guid();
+ g->date = *get_random_timespec();
+ g->discount = get_random_double();
+ g->active = get_random_boolean();
+ g->version = get_random_int_in_range(1,10000);
+ g->minor = get_random_int_in_range(100000,99999999);
+ g->flag = get_random_character();
+ g->Name = get_random_string();
+ g->Amount = get_random_gnc_numeric();
+ g->child = NULL;
+ gnc_engine_gen_event(&g->inst.entity, GNC_EVENT_CREATE);
+ return g;
+}
+
+myparent*
+parent_create(QofBook *book)
+{
+ myparent *g;
+
+ g_return_val_if_fail(book, NULL);
+ g = g_new0(myparent, 1);
+ qof_instance_init (&g->inst, PARENT_MODULE_NAME, book);
+ g->parent_guid = get_random_guid();
+ g->date = *get_random_timespec();
+ g->discount = get_random_double();
+ g->active = get_random_boolean();
+ g->version = get_random_int_in_range(1,10000);
+ g->minor = get_random_int_in_range(100000,99999999);
+ g->flag = get_random_character();
+ g->Name = get_random_string();
+ g->Amount = get_random_gnc_numeric();
+ g->child = NULL;
+ gnc_engine_gen_event(&g->inst.entity, GNC_EVENT_CREATE);
+ return g;
+}
+
+mychild*
+child_create(QofBook *book)
+{
+ mychild *g;
+
+ g_return_val_if_fail(book, NULL);
+ g = g_new0(mychild, 1);
+ qof_instance_init (&g->inst, CHILD_MODULE_NAME, book);
+ g->child_guid = get_random_guid();
+ g->date = *get_random_timespec();
+ g->discount = get_random_double();
+ g->active = get_random_boolean();
+ g->version = get_random_int_in_range(1,10000);
+ g->minor = get_random_int_in_range(100000,99999999);
+ g->flag = get_random_character();
+ g->Name = get_random_string();
+ g->Amount = get_random_gnc_numeric();
+ gnc_engine_gen_event(&g->inst.entity, GNC_EVENT_CREATE);
+ return g;
+}
+
+static void
+grand_setChild(mygrand *g, myparent *p)
+{
+ g_return_if_fail(g || p);
+ g->child = p;
+}
+
+static myparent*
+grand_getChild(mygrand *g)
+{
+ g_return_val_if_fail(g, NULL);
+ return g->child;
+}
+
+void
+grand_setFlag(mygrand *g, gchar f)
+{
+ g_return_if_fail(g);
+ g->flag = f;
+}
+
+gchar
+grand_getFlag(mygrand *g)
+{
+ g_return_val_if_fail(g, 'n');
+ return g->flag;
+}
+
+void
+grand_setMinor(mygrand *g, gint64 h)
+{
+ g_return_if_fail(g != NULL);
+ g->minor = h;
+}
+
+gint64
+grand_getMinor(mygrand *g)
+{
+ g_return_val_if_fail((g != NULL),0);
+ return g->minor;
+}
+
+void
+grand_setVersion(mygrand *g, gint32 h)
+{
+ g_return_if_fail(g != NULL);
+ g->version = h;
+}
+
+gint32
+grand_getVersion(mygrand *g)
+{
+ if(!g) return 0;
+ return g->version;
+}
+
+void
+grand_setActive(mygrand *g, gboolean h)
+{
+ if(!g) return;
+ g->active = h;
+}
+
+gboolean
+grand_getActive(mygrand *g)
+{
+ if(!g) return FALSE;
+ return g->active;
+}
+
+void
+grand_setDiscount(mygrand *g, double h)
+{
+ if(!g) return;
+ g->discount = h;
+}
+
+double
+grand_getDiscount(mygrand *g)
+{
+ if(!g) return 0;
+ return g->discount;
+}
+
+void
+grand_setDate(mygrand *g, Timespec h)
+{
+ if(!g) return;
+ g->date = h;
+}
+
+Timespec
+grand_getDate(mygrand *g)
+{
+ Timespec ts;
+ ts.tv_sec = 0;
+ ts.tv_nsec = 0;
+ if(!g) return ts;
+ ts = g->date;
+ return ts;
+}
+
+void
+grand_setGUID(mygrand* g, const GUID* h)
+{
+ if(!g) return;
+ g->grand_guid = h;
+}
+
+const GUID*
+grand_getGUID(mygrand *g)
+{
+ if(!g) return NULL;
+ return g->grand_guid;
+}
+
+void
+grand_setName(mygrand* g, gchar* h)
+{
+ if(!g || !h) return;
+ g->Name = strdup(h);
+}
+
+gchar*
+grand_getName(mygrand *g)
+{
+ if(!g) return NULL;
+ return g->Name;
+}
+
+void
+grand_setAmount(mygrand *g, gnc_numeric h)
+{
+ if(!g) return;
+ g->Amount = h;
+}
+
+gnc_numeric
+grand_getAmount(mygrand *g)
+{
+ if(!g) return gnc_numeric_zero();
+ return g->Amount;
+}
+
+static void
+parent_setChild(myparent *p, mychild *c)
+{
+ g_return_if_fail(p || c);
+ p->child = c;
+}
+
+static mychild*
+parent_getChild(myparent* p)
+{
+ g_return_val_if_fail(p, NULL);
+ return p->child;
+}
+
+void
+parent_setFlag(myparent *p, gchar f)
+{
+ g_return_if_fail(p);
+ p->flag = f;
+}
+
+gchar
+parent_getFlag(myparent *p)
+{
+ g_return_val_if_fail(p, 'n');
+ return p->flag;
+}
+
+void
+parent_setMinor(myparent *p, gint64 h)
+{
+ g_return_if_fail(p != NULL);
+ p->minor = h;
+}
+
+gint64
+parent_getMinor(myparent *p)
+{
+ g_return_val_if_fail((p != NULL),0);
+ return p->minor;
+}
+
+void
+parent_setVersion(myparent *p, gint32 h)
+{
+ g_return_if_fail(p != NULL);
+ p->version = h;
+}
+
+gint32
+parent_getVersion(myparent *p)
+{
+ if(!p) return 0;
+ return p->version;
+}
+
+void
+parent_setActive(myparent *p, gboolean h)
+{
+ if(!p) return;
+ p->active = h;
+}
+
+gboolean
+parent_getActive(myparent *p)
+{
+ if(!p) return FALSE;
+ return p->active;
+}
+
+void
+parent_setDiscount(myparent *p, double h)
+{
+ if(!p) return;
+ p->discount = h;
+}
+
+double
+parent_getDiscount(myparent *p)
+{
+ if(!p) return 0;
+ return p->discount;
+}
+
+void
+parent_setDate(myparent *p, Timespec h)
+{
+ if(!p) return;
+ p->date = h;
+}
+
+Timespec
+parent_getDate(myparent *p)
+{
+ Timespec ts;
+ ts.tv_sec = 0;
+ ts.tv_nsec = 0;
+ if(!p) return ts;
+ ts = p->date;
+ return ts;
+}
+
+void
+parent_setGUID(myparent* p, const GUID* h)
+{
+ if(!p) return;
+ p->parent_guid = h;
+}
+
+const GUID*
+parent_getGUID(myparent *p)
+{
+ if(!p) return NULL;
+ return p->parent_guid;
+}
+
+void
+parent_setName(myparent* p, gchar* h)
+{
+ if(!p || !h) return;
+ p->Name = strdup(h);
+}
+
+gchar*
+parent_getName(myparent *p)
+{
+ if(!p) return NULL;
+ return p->Name;
+}
+
+void
+parent_setAmount(myparent *p, gnc_numeric h)
+{
+ if(!p) return;
+ p->Amount = h;
+}
+
+gnc_numeric
+parent_getAmount(myparent *p)
+{
+ if(!p) return gnc_numeric_zero();
+ return p->Amount;
+}
+
+void
+child_setFlag(mychild *c, gchar f)
+{
+ g_return_if_fail(c);
+ c->flag = f;
+}
+
+gchar
+child_getFlag(mychild *c)
+{
+ g_return_val_if_fail(c, 'n');
+ return c->flag;
+}
+
+void
+child_setMinor(mychild *c, gint64 h)
+{
+ g_return_if_fail(c != NULL);
+ c->minor = h;
+}
+
+gint64
+child_getMinor(mychild *c)
+{
+ g_return_val_if_fail((c != NULL),0);
+ return c->minor;
+}
+
+void
+child_setVersion(mychild *c, gint32 h)
+{
+ g_return_if_fail(c != NULL);
+ c->version = h;
+}
+
+gint32
+child_getVersion(mychild *c)
+{
+ if(!c) return 0;
+ return c->version;
+}
+
+void
+child_setActive(mychild *c, gboolean h)
+{
+ if(!c) return;
+ c->active = h;
+}
+
+gboolean
+child_getActive(mychild *c)
+{
+ if(!c) return FALSE;
+ return c->active;
+}
+
+void
+child_setDiscount(mychild *c, double h)
+{
+ if(!c) return;
+ c->discount = h;
+}
+
+double
+child_getDiscount(mychild *c)
+{
+ if(!c) return 0;
+ return c->discount;
+}
+
+void
+child_setDate(mychild *c, Timespec h)
+{
+ if(!c) return;
+ c->date = h;
+}
+
+Timespec
+child_getDate(mychild *c)
+{
+ Timespec ts;
+ ts.tv_sec = 0;
+ ts.tv_nsec = 0;
+ if(!c) return ts;
+ ts = c->date;
+ return ts;
+}
+
+void
+child_setGUID(mychild* c, const GUID* h)
+{
+ if(!c) return;
+ c->child_guid = h;
+}
+
+const GUID*
+child_getGUID(mychild *c)
+{
+ if(!c) return NULL;
+ return c->child_guid;
+}
+
+void
+child_setName(mychild* c, gchar* h)
+{
+ if(!c || !h) return;
+ c->Name = strdup(h);
+}
+
+gchar*
+child_getName(mychild *c)
+{
+ if(!c) return NULL;
+ return c->Name;
+}
+
+void
+child_setAmount(mychild *c, gnc_numeric h)
+{
+ if(!c) return;
+ c->Amount = h;
+}
+
+gnc_numeric
+child_getAmount(mychild *c)
+{
+ if(!c) return gnc_numeric_zero();
+ return c->Amount;
+}
+
+static QofObject grand_object_def = {
+ interface_version: QOF_OBJECT_VERSION,
+ e_type: GRAND_MODULE_NAME,
+ type_label: GRAND_MODULE_DESC,
+ create: (gpointer)grand_create,
+ book_begin: NULL,
+ book_end: NULL,
+ is_dirty: NULL,
+ mark_clean: NULL,
+ foreach: qof_collection_foreach,
+ printable: NULL,
+ version_cmp: (int (*)(gpointer,gpointer)) qof_instance_version_cmp,
+};
+
+gboolean mygrandRegister (void)
+{
+ static QofParam params[] = {
+ { OBJ_NAME, QOF_TYPE_STRING, (QofAccessFunc)grand_getName,
+ (QofSetterFunc)grand_setName },
+ { OBJ_AMOUNT, QOF_TYPE_NUMERIC, (QofAccessFunc)grand_getAmount,
+ (QofSetterFunc)grand_setAmount },
+/* { OBJ_GUID, QOF_TYPE_GUID, (QofAccessFunc)grand_getGUID,
+ (QofSetterFunc)grand_setGUID },*/
+ { OBJ_DATE, QOF_TYPE_DATE, (QofAccessFunc)grand_getDate,
+ (QofSetterFunc)grand_setDate },
+ { OBJ_DISCOUNT, QOF_TYPE_DOUBLE, (QofAccessFunc)grand_getDiscount,
+ (QofSetterFunc)grand_setDiscount },
+ { OBJ_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)grand_getActive,
+ (QofSetterFunc)grand_setActive },
+ { OBJ_VERSION, QOF_TYPE_INT32, (QofAccessFunc)grand_getVersion,
+ (QofSetterFunc)grand_setVersion },
+ { OBJ_MINOR, QOF_TYPE_INT64, (QofAccessFunc)grand_getMinor,
+ (QofSetterFunc)grand_setMinor },
+ { OBJ_FLAG, QOF_TYPE_CHAR, (QofAccessFunc)grand_getFlag,
+ (QofSetterFunc)grand_setFlag },
+ { OBJ_RELATIVE, PARENT_MODULE_NAME, (QofAccessFunc)grand_getChild,
+ (QofSetterFunc)grand_setChild },
+ { QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
+ { QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
+ { NULL },
+ };
+
+ qof_class_register (GRAND_MODULE_NAME, NULL, params);
+
+ return qof_object_register (&grand_object_def);
+}
+
+static QofObject parent_object_def = {
+ interface_version: QOF_OBJECT_VERSION,
+ e_type: PARENT_MODULE_NAME,
+ type_label: PARENT_MODULE_DESC,
+ create: (gpointer)parent_create,
+ book_begin: NULL,
+ book_end: NULL,
+ is_dirty: NULL,
+ mark_clean: NULL,
+ foreach: qof_collection_foreach,
+ printable: NULL,
+ version_cmp: (int (*)(gpointer,gpointer)) qof_instance_version_cmp,
+};
+
+gboolean myparentRegister (void)
+{
+ static QofParam params[] = {
+ { OBJ_NAME, QOF_TYPE_STRING, (QofAccessFunc)parent_getName,
+ (QofSetterFunc)parent_setName },
+ { OBJ_AMOUNT, QOF_TYPE_NUMERIC, (QofAccessFunc)parent_getAmount,
+ (QofSetterFunc)parent_setAmount },
+/* { OBJ_GUID, QOF_TYPE_GUID, (QofAccessFunc)parent_getGUID,
+ (QofSetterFunc)parent_setGUID },*/
+ { OBJ_DATE, QOF_TYPE_DATE, (QofAccessFunc)parent_getDate,
+ (QofSetterFunc)parent_setDate },
+ { OBJ_DISCOUNT, QOF_TYPE_DOUBLE, (QofAccessFunc)parent_getDiscount,
+ (QofSetterFunc)parent_setDiscount },
+ { OBJ_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)parent_getActive,
+ (QofSetterFunc)parent_setActive },
+ { OBJ_VERSION, QOF_TYPE_INT32, (QofAccessFunc)parent_getVersion,
+ (QofSetterFunc)parent_setVersion },
+ { OBJ_MINOR, QOF_TYPE_INT64, (QofAccessFunc)parent_getMinor,
+ (QofSetterFunc)parent_setMinor },
+ { OBJ_FLAG, QOF_TYPE_CHAR, (QofAccessFunc)parent_getFlag,
+ (QofSetterFunc)parent_setFlag },
+ { OBJ_RELATIVE, CHILD_MODULE_NAME, (QofAccessFunc)parent_getChild,
+ (QofSetterFunc)parent_setChild },
+ { QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
+ { QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
+ { NULL },
+ };
+
+ qof_class_register (PARENT_MODULE_NAME, NULL, params);
+
+ return qof_object_register (&parent_object_def);
+}
+
+static QofObject child_object_def = {
+ interface_version: QOF_OBJECT_VERSION,
+ e_type: CHILD_MODULE_NAME,
+ type_label: CHILD_MODULE_DESC,
+ create: (gpointer)child_create,
+ book_begin: NULL,
+ book_end: NULL,
+ is_dirty: NULL,
+ mark_clean: NULL,
+ foreach: qof_collection_foreach,
+ printable: NULL,
+ version_cmp: (int (*)(gpointer,gpointer)) qof_instance_version_cmp,
+};
+
+gboolean mychildRegister (void)
+{
+ static QofParam params[] = {
+ { OBJ_NAME, QOF_TYPE_STRING, (QofAccessFunc)child_getName,
+ (QofSetterFunc)child_setName },
+ { OBJ_AMOUNT, QOF_TYPE_NUMERIC, (QofAccessFunc)child_getAmount,
+ (QofSetterFunc)child_setAmount },
+/* { OBJ_GUID, QOF_TYPE_GUID, (QofAccessFunc)child_getGUID,
+ (QofSetterFunc)child_setGUID },*/
+ { OBJ_DATE, QOF_TYPE_DATE, (QofAccessFunc)child_getDate,
+ (QofSetterFunc)child_setDate },
+ { OBJ_DISCOUNT, QOF_TYPE_DOUBLE, (QofAccessFunc)child_getDiscount,
+ (QofSetterFunc)child_setDiscount },
+ { OBJ_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)child_getActive,
+ (QofSetterFunc)child_setActive },
+ { OBJ_VERSION, QOF_TYPE_INT32, (QofAccessFunc)child_getVersion,
+ (QofSetterFunc)child_setVersion },
+ { OBJ_MINOR, QOF_TYPE_INT64, (QofAccessFunc)child_getMinor,
+ (QofSetterFunc)child_setMinor },
+ { OBJ_FLAG, QOF_TYPE_CHAR, (QofAccessFunc)child_getFlag,
+ (QofSetterFunc)child_setFlag },
+ { QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
+ { QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
+ { NULL },
+ };
+
+ qof_class_register (CHILD_MODULE_NAME, NULL, params);
+
+ return qof_object_register (&child_object_def);
+}
+
+static void
+create_data (QofSession *original, guint counter)
+{
+ QofBook *start;
+ mygrand *grand1;
+ myparent *parent1;
+ mychild *child1;
+
+ start = qof_session_get_book(original);
+ grand1 = (mygrand*)qof_object_new_instance(GRAND_MODULE_NAME, start);
+ do_test ((NULL != &grand1->inst), "#2 instance init");
+ switch (counter)
+ {
+ case 0 : { /* NULL tree */
+ do_test((grand1 != NULL), "empty tree check");
+ break;
+ }
+ case 1 : { /* one parent, no child */
+ parent1 = (myparent*)qof_object_new_instance(PARENT_MODULE_NAME, start);
+ grand_setChild(grand1, parent1);
+ do_test((parent1 != NULL), "single parent check");
+ do_test((grand_getChild(grand1) == parent1), "set child in grandparent");
+ break;
+ }
+ case 2 : { /* one parent, one child */
+ parent1 = (myparent*)qof_object_new_instance(PARENT_MODULE_NAME, start);
+ grand_setChild(grand1, parent1);
+ child1 = (mychild*)qof_object_new_instance(CHILD_MODULE_NAME, start);
+ parent1 = grand_getChild(grand1);
+ parent_setChild(parent1, child1);
+ do_test((child1 != NULL), "one parent with one related child");
+ do_test((child1 == parent_getChild(parent1)), "child of single parent");
+ break;
+ }
+ case 3 : { /* same grand, new parent, same child */
+ child1 = (mychild*)qof_object_new_instance(CHILD_MODULE_NAME, start);
+ parent1 = (myparent*)qof_object_new_instance(PARENT_MODULE_NAME, start);
+ grand_setChild(grand1, parent1);
+ parent_setChild(parent1, child1);
+ do_test((parent1 == grand_getChild(grand1)), "same grandparent, new parent");
+ do_test((child1 == parent_getChild(parent1)), "new parent, same child");
+ break;
+ }
+ case 4 : { /* new grand, unrelated parent, child unrelated to grand */
+ grand1 = (mygrand*)qof_object_new_instance(GRAND_MODULE_NAME, start);
+ parent1 = (myparent*)qof_object_new_instance(PARENT_MODULE_NAME, start);
+ child1 = (mychild*)qof_object_new_instance(CHILD_MODULE_NAME, start);
+ parent_setChild(parent1, child1);
+ do_test((NULL == grand_getChild(grand1)), "new grand, unrelated parent");
+ do_test((child1 == parent_getChild(parent1)), "child unrelated to grand");
+ break;
+ }
+ }
+}
+
+/** \brief Read QofEntityReference data for this entity and set values.
+
+ at param partial_book The partial book containing the referenceList
+ at param ent The parent entity to hold the converted reference.
+
+The referenceList is a GList of QofEntityReference structures that contain
+the GUID of each end of a reference. e.g. where one entity refers to another.
+
+The referenceList is used in partial books to store relationships between
+entities when the entities themselves might not exist in the partial book.
+
+If the book is not marked as a partial book, an assertion error is generated.
+
+This routine tries to lookup the given entity in the referenceList for the
+book and then tries to lookup the reference - to find the child entity that
+was originally linked to this parent. The child entity is then set in the
+parent so that it can be located as normal.
+
+If the child entity does not exist in this partial book, the parent entity
+is not updated. The referenceList is unchanged (in case the child is added
+later).
+
+*/
+void
+qof_entity_set_reference_data(QofBook *partial_book, QofEntity *ent);
+
+void
+qof_entity_set_reference_data(QofBook *partial_book, QofEntity *ent)
+{
+ void (*reference_setter) (QofEntity*, QofEntity*);
+ QofEntityReference *ref;
+ GList *book_ref_list;
+ QofCollection *coll;
+ QofEntity *reference;
+ gboolean partial;
+
+ g_return_if_fail(partial_book || ent);
+ partial =
+ (gboolean)GPOINTER_TO_INT(qof_book_get_data(partial_book, PARTIAL_QOFBOOK));
+ g_return_if_fail(partial);
+ book_ref_list = qof_book_get_data(partial_book, ENTITYREFERENCE);
+ while(book_ref_list)
+ {
+ ref = (QofEntityReference*)book_ref_list->data;
+ if(0 != guid_compare(ref->ref_guid, qof_entity_get_guid(ent)))
+ {
+ book_ref_list = g_list_next(book_ref_list);
+ continue;
+ }
+ coll = qof_book_get_collection(partial_book, ref->type);
+ reference = qof_collection_lookup_entity(coll, ref->ref_guid);
+ do_test((reference == NULL), "reference is null");
+ reference_setter = (void(*)(QofEntity*, QofEntity*))ref->param->param_setfcn;
+ if(reference_setter != NULL)
+ {
+ qof_begin_edit((QofInstance*)ent);
+ qof_begin_edit((QofInstance*)reference);
+ reference_setter(ent, reference);
+ qof_commit_edit((QofInstance*)ent);
+ qof_commit_edit((QofInstance*)reference);
+ }
+ book_ref_list = g_list_next(book_ref_list);
+ }
+}
+
+struct tally
+{
+ guint nulls, total;
+ QofBook *book;
+};
+
+static void
+check_cb (QofEntity *ent, gpointer data)
+{
+ QofEntity *parent, *child;
+ struct tally *c;
+ const QofParam *param;
+ mygrand *testg;
+ myparent *testp;
+ mychild *testc;
+
+ c = (struct tally*)data;
+ /* find the child entity in the copied book */
+ testg = (mygrand*)ent;
+ do_test((testg != NULL), "grandparent not found");
+ c->total++;
+ if(c->book) { qof_entity_set_reference_data(c->book, ent); }
+ testp = grand_getChild(testg);
+ param = qof_class_get_parameter(GRAND_MODULE_NAME, OBJ_RELATIVE);
+ parent = param->param_getfcn(ent, param);
+ if(!parent || !testp) { c->nulls++; return; }
+ do_test((0 == safe_strcmp(parent_getName(testp),
+ parent_getName((myparent*)parent))), "parent copy test");
+ param = qof_class_get_parameter(PARENT_MODULE_NAME, OBJ_RELATIVE);
+ testc = parent_getChild(testp);
+ child = param->param_getfcn(parent, param);
+ do_test((0 == safe_strcmp(child_getName(testc),
+ child_getName((mychild*)child))), "child copy test");
+}
+
+static void
+test_recursion (QofSession *original, guint counter)
+{
+ QofSession *copy;
+ QofCollection *grand_coll;
+ struct tally c;
+ QofBook *book;
+ gboolean debug;
+ guint d, e;
+
+ c.nulls = 0;
+ c.total = 0;
+ c.book = NULL;
+ debug = FALSE; /* switch to TRUE to see the XML output.*/
+ book = qof_session_get_book(original);
+ grand_coll = qof_book_get_collection(book, GRAND_MODULE_NAME);
+ copy = qof_session_new();
+ qof_session_begin(copy, QOF_STDOUT, TRUE, FALSE);
+ qof_entity_copy_coll_r(copy, grand_coll);
+ /* test the original */
+ qof_object_foreach(GRAND_MODULE_NAME, book, check_cb, &c);
+ book = qof_session_get_book(copy);
+ /* test the copy */
+ d = c.nulls;
+ e = c.total;
+ c.nulls = 0;
+ c.total = 0;
+ c.book = book;
+ qof_object_foreach(GRAND_MODULE_NAME, book, check_cb, &c);
+// do_test((d == c.nulls), "Null parents do not match");
+ do_test((e == c.total), "Total parents do not match");
+ if(debug) { qof_session_save(copy, NULL); }
+ qof_session_end(copy);
+ copy = NULL;
+}
+
+int
+main (int argc, const char *argv[])
+{
+ QofSession *original;
+ guint counter;
+
+ qof_init ();
+ mygrandRegister();
+ myparentRegister();
+ mychildRegister();
+ original = qof_session_new();
+ qof_session_begin(original, QOF_STDOUT, TRUE, FALSE);
+ for(counter = 0; counter < 25; counter++)
+ {
+ create_data(original, (counter % 5));
+ test_recursion(original, (counter % 5));
+ }
+ print_test_results();
+ qof_close();
+ return EXIT_SUCCESS;
+}
More information about the gnucash-changes
mailing list