QOF  0.8.7
test-recursive.c
1 /***************************************************************************
2  * test-recursive.c
3  *
4  * Wed Feb 1 21:54:49 2006
5  * Copyright 2006 Neil Williams
6  * linux@codehelp.co.uk
7  ****************************************************************************/
8 /*
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor
22  * Boston, MA 02110-1301, USA
23  */
24 
25 #include <glib.h>
26 #include <glib/gprintf.h>
27 #include "config.h"
28 #include "qof.h"
29 #include "test-engine-stuff.h"
30 #include "test-stuff.h"
31 
32 #define GRAND_MODULE_NAME "recursive-grandparent"
33 #define PARENT_MODULE_NAME "recursive-parent"
34 #define CHILD_MODULE_NAME "recursive-child"
35 #define GRAND_MODULE_DESC "Recursive Grand Parent Test"
36 #define PARENT_MODULE_DESC "Recursive Parent Test"
37 #define CHILD_MODULE_DESC "Recursive Child Test"
38 #define OBJ_NAME "somename"
39 #define OBJ_AMOUNT "anamount"
40 #define OBJ_DATE "nottoday"
41 #define OBJ_DISCOUNT "hefty"
42 #define OBJ_VERSION "early"
43 #define OBJ_MINOR "tiny"
44 #define OBJ_ACTIVE "ofcourse"
45 #define OBJ_FLAG "tiny_flag"
46 #define OBJ_RELATIVE "family"
47 #define OBJ_LIST "descendents"
48 
49 /* set to TRUE to get QSF XML output
50  * requires QSF available (i.e. make install) */
51 static gboolean debug = FALSE;
52 
53 /* simple object structure */
54 typedef struct child_s
55 {
56  QofInstance inst;
57  gchar *Name;
58  gchar flag;
59  QofNumeric Amount;
60  QofTime *date;
61  gdouble discount; /* cheap pun, I know. */
62  gboolean active;
63  gint32 version;
64  gint64 minor;
65 } mychild;
66 
67 /* simple object structure */
68 typedef struct parent_s
69 {
70  QofInstance inst;
71  mychild *child;
72  gchar *Name;
73  gchar flag;
74  QofNumeric Amount;
75  QofTime *date;
76  gdouble discount; /* cheap pun, I know. */
77  gboolean active;
78  gint32 version;
79  gint64 minor;
80 } myparent;
81 
82  /* simple object structure */
83 typedef struct grand_s
84 {
85  QofInstance inst;
86  myparent *child;
87  GList *descend;
88  gchar *Name;
89  gchar flag;
90  QofNumeric Amount;
91  QofTime *date;
92  gdouble discount; /* cheap pun, I know. */
93  gboolean active;
94  gint32 version;
95  gint64 minor;
96 } mygrand;
97 
98 mygrand *grand_create (QofBook *);
99 myparent *parent_create (QofBook *);
100 mychild *child_create (QofBook *);
101 
102 gboolean mygrandRegister (void);
103 gboolean myparentRegister (void);
104 gboolean mychildRegister (void);
105 
106 /* obvious setter functions */
107 void grand_setName (mygrand *, gchar *);
108 void grand_setAmount (mygrand *, QofNumeric);
109 void grand_setDate (mygrand *, QofTime *h);
110 void grand_setDiscount (mygrand *, gdouble);
111 void grand_setActive (mygrand *, gboolean);
112 void grand_setVersion (mygrand *, gint32);
113 void grand_setMinor (mygrand *, gint64);
114 void grand_setFlag (mygrand *, gchar);
115 
116 /* obvious getter functions */
117 gchar *grand_getName (mygrand *);
118 QofNumeric grand_getAmount (mygrand *);
119 QofTime *grand_getDate (mygrand *);
120 gdouble grand_getDiscount (mygrand *);
121 gboolean grand_getActive (mygrand *);
122 gint32 grand_getVersion (mygrand *);
123 gint64 grand_getMinor (mygrand *);
124 gchar grand_getFlag (mygrand *);
125 
126 /* obvious setter functions */
127 void parent_setName (myparent *, gchar *);
128 void parent_setAmount (myparent *, QofNumeric);
129 void parent_setDate (myparent *, QofTime *h);
130 void parent_setDiscount (myparent *, gdouble);
131 void parent_setActive (myparent *, gboolean);
132 void parent_setVersion (myparent *, gint32);
133 void parent_setMinor (myparent *, gint64);
134 void parent_setFlag (myparent *, gchar);
135 
136 /* obvious getter functions */
137 gchar *parent_getName (myparent *);
138 QofNumeric parent_getAmount (myparent *);
139 QofTime *parent_getDate (myparent *);
140 gdouble parent_getDiscount (myparent *);
141 gboolean parent_getActive (myparent *);
142 gint32 parent_getVersion (myparent *);
143 gint64 parent_getMinor (myparent *);
144 gchar parent_getFlag (myparent *);
145 
146 /* obvious setter functions */
147 void child_setName (mychild *, gchar *);
148 void child_setAmount (mychild *, QofNumeric);
149 void child_setDate (mychild *, QofTime *h);
150 void child_setDiscount (mychild *, gdouble);
151 void child_setActive (mychild *, gboolean);
152 void child_setVersion (mychild *, gint32);
153 void child_setMinor (mychild *, gint64);
154 void child_setFlag (mychild *, gchar);
155 
156 /* obvious getter functions */
157 gchar *child_getName (mychild *);
158 QofNumeric child_getAmount (mychild *);
159 QofTime *child_getDate (mychild *);
160 gdouble child_getDiscount (mychild *);
161 gboolean child_getActive (mychild *);
162 gint32 child_getVersion (mychild *);
163 gint64 child_getMinor (mychild *);
164 gchar child_getFlag (mychild *);
165 
166 mygrand *
167 grand_create (QofBook * book)
168 {
169  mygrand *g;
170 
171  g_return_val_if_fail (book, NULL);
172  g = g_new0 (mygrand, 1);
173  qof_instance_init (&g->inst, GRAND_MODULE_NAME, book);
174  /* implement qof_time_random? */
175  g->date = qof_time_get_current ();
176  g->discount = get_random_double ();;
177  g->active = get_random_boolean ();
178  g->version = get_random_int_in_range (1, 10000);
179  g->minor = get_random_int_in_range (100001, 99999999);
180  g->flag = get_random_character ();
181  g->Name = get_random_string ();
182  g->Amount = get_random_qof_numeric ();
183  g->child = NULL;
184  g->descend = NULL;
185  qof_event_gen (&g->inst.entity, QOF_EVENT_CREATE, NULL);
186  return g;
187 }
188 
189 myparent *
190 parent_create (QofBook * book)
191 {
192  myparent *g;
193 
194  g_return_val_if_fail (book, NULL);
195  g = g_new0 (myparent, 1);
196  qof_instance_init (&g->inst, PARENT_MODULE_NAME, book);
197  g->date = qof_time_get_current ();
198  g->discount = get_random_double ();
199  g->active = get_random_boolean ();
200  g->version = get_random_int_in_range (1, 10000);
201  g->minor = get_random_int_in_range (100001, 99999999);
202  g->flag = get_random_character ();
203  g->Name = get_random_string ();
204  g->Amount = get_random_qof_numeric ();
205  g->child = NULL;
206  qof_event_gen (&g->inst.entity, QOF_EVENT_CREATE, NULL);
207  return g;
208 }
209 
210 mychild *
211 child_create (QofBook * book)
212 {
213  mychild *g;
214 
215  g_return_val_if_fail (book, NULL);
216  g = g_new0 (mychild, 1);
217  qof_instance_init (&g->inst, CHILD_MODULE_NAME, book);
218  g->date = qof_time_get_current ();
219  g->discount = get_random_double ();
220  g->active = get_random_boolean ();
221  g->version = get_random_int_in_range (1, 10000);
222  g->minor = get_random_int_in_range (100001, 99999999);
223  g->flag = get_random_character ();
224  g->Name = get_random_string ();
225  g->Amount = get_random_qof_numeric ();
226  qof_event_gen (&g->inst.entity, QOF_EVENT_CREATE, NULL);
227  return g;
228 }
229 
230 static void
231 descend_cb (QofEntity * ent, gpointer user_data)
232 {
233  mygrand *g = (mygrand *) user_data;
234 
235  g_return_if_fail (g || ent);
236  g->descend = g_list_prepend (g->descend, (mychild *) ent);
237 }
238 
239 static void
240 grand_setDescend (mygrand * g, QofCollection * coll)
241 {
242  g_return_if_fail (g || coll);
243  if (0 != safe_strcmp (qof_collection_get_type (coll), CHILD_MODULE_NAME))
244  {
245  return;
246  }
247  qof_collection_foreach (coll, descend_cb, g);
248 }
249 
250 static QofCollection *
251 grand_getDescend (mygrand * g)
252 {
253  QofCollection *col;
254  QofEntity *ent;
255  GList *list;
256 
257  g_return_val_if_fail (g, NULL);
258  col = qof_collection_new (CHILD_MODULE_NAME);
259  for (list = g_list_copy (g->descend); list; list = list->next)
260  {
261  ent = (QofEntity *) list->data;
262  if (!ent)
263  {
264  break;
265  }
266  do_test (0 == safe_strcmp (ent->e_type, CHILD_MODULE_NAME),
267  "wrong entity");
268  qof_collection_add_entity (col, ent);
269  }
270  return col;
271 }
272 
273 static void
274 grand_setChild (mygrand * g, myparent * p)
275 {
276  g_return_if_fail (g || p);
277  g->child = p;
278 }
279 
280 static myparent *
281 grand_getChild (mygrand * g)
282 {
283  g_return_val_if_fail (g, NULL);
284  return g->child;
285 }
286 
287 void
288 grand_setFlag (mygrand * g, gchar f)
289 {
290  g_return_if_fail (g);
291  g->flag = f;
292 }
293 
294 gchar
295 grand_getFlag (mygrand * g)
296 {
297  g_return_val_if_fail (g, 'n');
298  return g->flag;
299 }
300 
301 void
302 grand_setMinor (mygrand * g, gint64 h)
303 {
304  g_return_if_fail (g != NULL);
305  g->minor = h;
306 }
307 
308 gint64
309 grand_getMinor (mygrand * g)
310 {
311  g_return_val_if_fail ((g != NULL), 0);
312  return g->minor;
313 }
314 
315 void
316 grand_setVersion (mygrand * g, gint32 h)
317 {
318  g_return_if_fail (g != NULL);
319  g->version = h;
320 }
321 
322 gint32
323 grand_getVersion (mygrand * g)
324 {
325  if (!g)
326  return 0;
327  return g->version;
328 }
329 
330 void
331 grand_setActive (mygrand * g, gboolean h)
332 {
333  if (!g)
334  return;
335  g->active = h;
336 }
337 
338 gboolean
339 grand_getActive (mygrand * g)
340 {
341  if (!g)
342  return FALSE;
343  return g->active;
344 }
345 
346 void
347 grand_setDiscount (mygrand * g, double h)
348 {
349  if (!g)
350  return;
351  g->discount = h;
352 }
353 
354 double
355 grand_getDiscount (mygrand * g)
356 {
357  if (!g)
358  return 0;
359  return g->discount;
360 }
361 
362 void
363 grand_setDate (mygrand * g, QofTime *h)
364 {
365  if (!g)
366  return;
367  g->date = h;
368 }
369 
370 QofTime*
371 grand_getDate (mygrand * g)
372 {
373  if (!g)
374  return NULL;
375  return g->date;
376 }
377 
378 void
379 grand_setName (mygrand * g, gchar * h)
380 {
381  if (!g || !h)
382  return;
383  g->Name = strdup (h);
384 }
385 
386 gchar *
387 grand_getName (mygrand * g)
388 {
389  if (!g)
390  return NULL;
391  return g->Name;
392 }
393 
394 void
395 grand_setAmount (mygrand * g, QofNumeric h)
396 {
397  if (!g)
398  return;
399  g->Amount = h;
400 }
401 
403 grand_getAmount (mygrand * g)
404 {
405  if (!g)
406  return qof_numeric_zero ();
407  return g->Amount;
408 }
409 
410 static void
411 parent_setChild (myparent * p, mychild * c)
412 {
413  g_return_if_fail (p || c);
414  p->child = c;
415 }
416 
417 static mychild *
418 parent_getChild (myparent * p)
419 {
420  g_return_val_if_fail (p, NULL);
421  return p->child;
422 }
423 
424 void
425 parent_setFlag (myparent * p, gchar f)
426 {
427  g_return_if_fail (p);
428  p->flag = f;
429 }
430 
431 gchar
432 parent_getFlag (myparent * p)
433 {
434  g_return_val_if_fail (p, 'n');
435  return p->flag;
436 }
437 
438 void
439 parent_setMinor (myparent * p, gint64 h)
440 {
441  g_return_if_fail (p != NULL);
442  p->minor = h;
443 }
444 
445 gint64
446 parent_getMinor (myparent * p)
447 {
448  g_return_val_if_fail ((p != NULL), 0);
449  return p->minor;
450 }
451 
452 void
453 parent_setVersion (myparent * p, gint32 h)
454 {
455  g_return_if_fail (p != NULL);
456  p->version = h;
457 }
458 
459 gint32
460 parent_getVersion (myparent * p)
461 {
462  if (!p)
463  return 0;
464  return p->version;
465 }
466 
467 void
468 parent_setActive (myparent * p, gboolean h)
469 {
470  if (!p)
471  return;
472  p->active = h;
473 }
474 
475 gboolean
476 parent_getActive (myparent * p)
477 {
478  if (!p)
479  return FALSE;
480  return p->active;
481 }
482 
483 void
484 parent_setDiscount (myparent * p, double h)
485 {
486  if (!p)
487  return;
488  p->discount = h;
489 }
490 
491 double
492 parent_getDiscount (myparent * p)
493 {
494  if (!p)
495  return 0;
496  return p->discount;
497 }
498 
499 void
500 parent_setDate (myparent * p, QofTime *h)
501 {
502  if (!p)
503  return;
504  p->date = h;
505 }
506 
507 QofTime *
508 parent_getDate (myparent * p)
509 {
510  if (!p)
511  return NULL;
512  return p->date;
513 }
514 
515 void
516 parent_setName (myparent * p, gchar * h)
517 {
518  if (!p || !h)
519  return;
520  p->Name = strdup (h);
521 }
522 
523 gchar *
524 parent_getName (myparent * p)
525 {
526  if (!p)
527  return NULL;
528  return p->Name;
529 }
530 
531 void
532 parent_setAmount (myparent * p, QofNumeric h)
533 {
534  if (!p)
535  return;
536  p->Amount = h;
537 }
538 
540 parent_getAmount (myparent * p)
541 {
542  if (!p)
543  return qof_numeric_zero ();
544  return p->Amount;
545 }
546 
547 void
548 child_setFlag (mychild * c, gchar f)
549 {
550  g_return_if_fail (c);
551  c->flag = f;
552 }
553 
554 gchar
555 child_getFlag (mychild * c)
556 {
557  g_return_val_if_fail (c, 'n');
558  return c->flag;
559 }
560 
561 void
562 child_setMinor (mychild * c, gint64 h)
563 {
564  g_return_if_fail (c != NULL);
565  c->minor = h;
566 }
567 
568 gint64
569 child_getMinor (mychild * c)
570 {
571  g_return_val_if_fail ((c != NULL), 0);
572  return c->minor;
573 }
574 
575 void
576 child_setVersion (mychild * c, gint32 h)
577 {
578  g_return_if_fail (c != NULL);
579  c->version = h;
580 }
581 
582 gint32
583 child_getVersion (mychild * c)
584 {
585  if (!c)
586  return 0;
587  return c->version;
588 }
589 
590 void
591 child_setActive (mychild * c, gboolean h)
592 {
593  if (!c)
594  return;
595  c->active = h;
596 }
597 
598 gboolean
599 child_getActive (mychild * c)
600 {
601  if (!c)
602  return FALSE;
603  return c->active;
604 }
605 
606 void
607 child_setDiscount (mychild * c, double h)
608 {
609  if (!c)
610  return;
611  c->discount = h;
612 }
613 
614 double
615 child_getDiscount (mychild * c)
616 {
617  if (!c)
618  return 0;
619  return c->discount;
620 }
621 
622 void
623 child_setDate (mychild * c, QofTime *h)
624 {
625  if (!c)
626  return;
627  c->date = h;
628 }
629 
630 QofTime*
631 child_getDate (mychild * c)
632 {
633  if (!c)
634  return NULL;
635  return c->date;
636 }
637 
638 void
639 child_setName (mychild * c, gchar * h)
640 {
641  if (!c || !h)
642  return;
643  c->Name = strdup (h);
644 }
645 
646 gchar *
647 child_getName (mychild * c)
648 {
649  if (!c)
650  return NULL;
651  return c->Name;
652 }
653 
654 void
655 child_setAmount (mychild * c, QofNumeric h)
656 {
657  if (!c)
658  return;
659  c->Amount = h;
660 }
661 
663 child_getAmount (mychild * c)
664 {
665  if (!c)
666  return qof_numeric_zero ();
667  return c->Amount;
668 }
669 
670 static QofObject grand_object_def = {
671  .interface_version = QOF_OBJECT_VERSION,
672  .e_type = GRAND_MODULE_NAME,
673  .type_label = GRAND_MODULE_DESC,
674  .create = (gpointer) grand_create,
675  .book_begin = NULL,
676  .book_end = NULL,
677  .is_dirty = qof_collection_is_dirty,
678  .mark_clean = qof_collection_mark_clean,
679  .foreach = qof_collection_foreach,
680  .printable = NULL,
681  .version_cmp = (gint (*)(gpointer, gpointer))
683 };
684 
685 gboolean
686 mygrandRegister (void)
687 {
688  static QofParam params[] = {
689  {OBJ_NAME, QOF_TYPE_STRING, (QofAccessFunc) grand_getName,
690  (QofSetterFunc) grand_setName, NULL},
691  {OBJ_AMOUNT, QOF_TYPE_NUMERIC, (QofAccessFunc) grand_getAmount,
692  (QofSetterFunc) grand_setAmount, NULL},
693  {OBJ_DATE, QOF_TYPE_TIME, (QofAccessFunc) grand_getDate,
694  (QofSetterFunc) grand_setDate, NULL},
695  {OBJ_DISCOUNT, QOF_TYPE_DOUBLE, (QofAccessFunc) grand_getDiscount,
696  (QofSetterFunc) grand_setDiscount, NULL},
697  {OBJ_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc) grand_getActive,
698  (QofSetterFunc) grand_setActive, NULL},
699  {OBJ_VERSION, QOF_TYPE_INT32, (QofAccessFunc) grand_getVersion,
700  (QofSetterFunc) grand_setVersion, NULL},
701  {OBJ_MINOR, QOF_TYPE_INT64, (QofAccessFunc) grand_getMinor,
702  (QofSetterFunc) grand_setMinor, NULL},
703  {OBJ_FLAG, QOF_TYPE_CHAR, (QofAccessFunc) grand_getFlag,
704  (QofSetterFunc) grand_setFlag, NULL},
705  {OBJ_RELATIVE, PARENT_MODULE_NAME, (QofAccessFunc) grand_getChild,
706  (QofSetterFunc) grand_setChild, NULL},
707  {OBJ_LIST, QOF_TYPE_COLLECT, (QofAccessFunc) grand_getDescend,
708  (QofSetterFunc) grand_setDescend, NULL},
710  NULL, NULL},
711  {QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc) qof_instance_get_guid,
712  NULL, NULL},
713  {NULL, NULL, NULL, NULL, NULL},
714  };
715 
716  qof_class_register (GRAND_MODULE_NAME, NULL, params);
717 /* if(!qof_choice_create(GRAND_MODULE_NAME)) { return FALSE; }*/
718 
719  return qof_object_register (&grand_object_def);
720 }
721 
722 static QofObject parent_object_def = {
723  .interface_version = QOF_OBJECT_VERSION,
724  .e_type = PARENT_MODULE_NAME,
725  .type_label = PARENT_MODULE_DESC,
726  .create = (gpointer) parent_create,
727  .book_begin = NULL,
728  .book_end = NULL,
729  .is_dirty = qof_collection_is_dirty,
730  .mark_clean = qof_collection_mark_clean,
731  .foreach = qof_collection_foreach,
732  .printable = NULL,
733  .version_cmp = (gint (*)(gpointer, gpointer))
735 };
736 
737 gboolean
738 myparentRegister (void)
739 {
740  static QofParam params[] = {
741  {OBJ_NAME, QOF_TYPE_STRING, (QofAccessFunc) parent_getName,
742  (QofSetterFunc) parent_setName, NULL},
743  {OBJ_AMOUNT, QOF_TYPE_NUMERIC, (QofAccessFunc) parent_getAmount,
744  (QofSetterFunc) parent_setAmount, NULL},
745  {OBJ_DATE, QOF_TYPE_TIME, (QofAccessFunc) parent_getDate,
746  (QofSetterFunc) parent_setDate, NULL},
747  {OBJ_DISCOUNT, QOF_TYPE_DOUBLE, (QofAccessFunc) parent_getDiscount,
748  (QofSetterFunc) parent_setDiscount, NULL},
749  {OBJ_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc) parent_getActive,
750  (QofSetterFunc) parent_setActive, NULL},
751  {OBJ_VERSION, QOF_TYPE_INT32, (QofAccessFunc) parent_getVersion,
752  (QofSetterFunc) parent_setVersion, NULL},
753  {OBJ_MINOR, QOF_TYPE_INT64, (QofAccessFunc) parent_getMinor,
754  (QofSetterFunc) parent_setMinor, NULL},
755  {OBJ_FLAG, QOF_TYPE_CHAR, (QofAccessFunc) parent_getFlag,
756  (QofSetterFunc) parent_setFlag, NULL},
757  {OBJ_RELATIVE, CHILD_MODULE_NAME, (QofAccessFunc) parent_getChild,
758  (QofSetterFunc) parent_setChild, NULL},
760  NULL, NULL},
761  {QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc) qof_instance_get_guid,
762  NULL, NULL},
763  {NULL, NULL, NULL, NULL, NULL},
764  };
765 
766  qof_class_register (PARENT_MODULE_NAME, NULL, params);
767 
768  return qof_object_register (&parent_object_def);
769 }
770 
771 static QofObject child_object_def = {
772  .interface_version = QOF_OBJECT_VERSION,
773  .e_type = CHILD_MODULE_NAME,
774  .type_label = CHILD_MODULE_DESC,
775  .create = (gpointer) child_create,
776  .book_begin = NULL,
777  .book_end = NULL,
778  .is_dirty = qof_collection_is_dirty,
779  .mark_clean = qof_collection_mark_clean,
780  .foreach = qof_collection_foreach,
781  .printable = NULL,
782  .version_cmp = (gint (*)(gpointer, gpointer))
784 };
785 
786 gboolean
787 mychildRegister (void)
788 {
789  static QofParam params[] = {
790  {OBJ_NAME, QOF_TYPE_STRING, (QofAccessFunc) child_getName,
791  (QofSetterFunc) child_setName, NULL},
792  {OBJ_AMOUNT, QOF_TYPE_NUMERIC, (QofAccessFunc) child_getAmount,
793  (QofSetterFunc) child_setAmount, NULL},
794  {OBJ_DATE, QOF_TYPE_TIME, (QofAccessFunc) child_getDate,
795  (QofSetterFunc) child_setDate, NULL},
796  {OBJ_DISCOUNT, QOF_TYPE_DOUBLE, (QofAccessFunc) child_getDiscount,
797  (QofSetterFunc) child_setDiscount, NULL},
798  {OBJ_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc) child_getActive,
799  (QofSetterFunc) child_setActive, NULL},
800  {OBJ_VERSION, QOF_TYPE_INT32, (QofAccessFunc) child_getVersion,
801  (QofSetterFunc) child_setVersion, NULL},
802  {OBJ_MINOR, QOF_TYPE_INT64, (QofAccessFunc) child_getMinor,
803  (QofSetterFunc) child_setMinor, NULL},
804  {OBJ_FLAG, QOF_TYPE_CHAR, (QofAccessFunc) child_getFlag,
805  (QofSetterFunc) child_setFlag, NULL},
807  NULL, NULL},
808  {QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc) qof_instance_get_guid,
809  NULL, NULL},
810  {NULL, NULL, NULL, NULL, NULL},
811  };
812 
813  qof_class_register (CHILD_MODULE_NAME, NULL, params);
814 
815  return qof_object_register (&child_object_def);
816 }
817 
818 static void
819 create_data (QofSession * original, guint counter)
820 {
821  QofCollection *coll;
822  QofBook *start;
823  mygrand *grand1;
824  myparent *parent1;
825  mychild *child1;
826 
827  start = qof_session_get_book (original);
828  grand1 = (mygrand *) qof_object_new_instance (GRAND_MODULE_NAME, start);
829  do_test ((NULL != &grand1->inst), "instance init");
830  switch (counter)
831  {
832  case 0:
833  { /* NULL tree */
834  do_test ((grand1 != NULL), "empty tree check");
835  coll = qof_book_get_collection (start, GRAND_MODULE_NAME);
836  do_test ((qof_collection_count (coll) == 1),
837  "Too many grandparents found - should be 1");
838  coll = qof_book_get_collection (start, CHILD_MODULE_NAME);
839  do_test ((qof_collection_count (coll) == 0),
840  "child found, should be empty");
841  coll = qof_book_get_collection (start, PARENT_MODULE_NAME);
842  do_test ((qof_collection_count (coll) == 0),
843  "tree not empty: parent found");
844  break;
845  }
846  case 1:
847  { /* one parent, no child */
848  parent1 =
849  (myparent *) qof_object_new_instance (PARENT_MODULE_NAME,
850  start);
851  grand_setChild (grand1, parent1);
852  do_test ((parent1 != NULL), "single parent check");
853  do_test ((grand_getChild (grand1) == parent1),
854  "set child in grandparent");
855  coll = qof_book_get_collection (start, GRAND_MODULE_NAME);
856  do_test ((qof_collection_count (coll) == 1),
857  "Wrong number of grandparents, should be 1");
858  coll = qof_book_get_collection (start, CHILD_MODULE_NAME);
859  do_test ((qof_collection_count (coll) == 0),
860  "Should be no child entities this iteration.");
861  coll = qof_book_get_collection (start, PARENT_MODULE_NAME);
862  do_test ((qof_collection_count (coll) == 1),
863  "Wrong number of parents found, should be 1");
864  break;
865  }
866  case 2:
867  { /* one parent, one child */
868  parent1 =
869  (myparent *) qof_object_new_instance (PARENT_MODULE_NAME,
870  start);
871  grand_setChild (grand1, parent1);
872  child1 =
873  (mychild *) qof_object_new_instance (CHILD_MODULE_NAME,
874  start);
875  parent1 = grand_getChild (grand1);
876  parent_setChild (parent1, child1);
877  do_test ((child1 != NULL), "one parent with one related child");
878  do_test ((child1 == parent_getChild (parent1)),
879  "child of single parent");
880  coll = qof_book_get_collection (start, GRAND_MODULE_NAME);
881  do_test ((qof_collection_count (coll) == 1),
882  "Wrong number of grandparents. Should be 1");
883  coll = qof_book_get_collection (start, CHILD_MODULE_NAME);
884  do_test ((qof_collection_count (coll) == 1),
885  "Wrong number of child entities, should be 1");
886  coll = qof_book_get_collection (start, PARENT_MODULE_NAME);
887  do_test ((qof_collection_count (coll) == 1),
888  "Wrong number of parents. Should be 1");
889  break;
890  }
891  case 3:
892  { /* same grand, new parent, same child */
893  child1 =
894  (mychild *) qof_object_new_instance (CHILD_MODULE_NAME,
895  start);
896  parent1 =
897  (myparent *) qof_object_new_instance (PARENT_MODULE_NAME,
898  start);
899  grand_setChild (grand1, parent1);
900  parent_setChild (parent1, child1);
901  do_test ((parent1 == grand_getChild (grand1)),
902  "same grandparent, new parent");
903  do_test ((child1 == parent_getChild (parent1)),
904  "new parent, same child");
905  coll = qof_book_get_collection (start, GRAND_MODULE_NAME);
906  do_test ((qof_collection_count (coll) == 1),
907  "Wrong number of grandparents. Should be 1, Iteration 3.");
908  coll = qof_book_get_collection (start, CHILD_MODULE_NAME);
909  do_test ((qof_collection_count (coll) == 1),
910  "Wrong number of child entities, should be 1. Iteration 3.");
911  coll = qof_book_get_collection (start, PARENT_MODULE_NAME);
912  do_test ((qof_collection_count (coll) == 1),
913  "Wrong number of parents. Should be 1. Iteration 3.");
914  break;
915  }
916  case 4:
917  { /* new grand, unrelated parent, child unrelated to grand */
918  grand1 =
919  (mygrand *) qof_object_new_instance (GRAND_MODULE_NAME,
920  start);
921  parent1 =
922  (myparent *) qof_object_new_instance (PARENT_MODULE_NAME,
923  start);
924  child1 =
925  (mychild *) qof_object_new_instance (CHILD_MODULE_NAME,
926  start);
927  parent_setChild (parent1, child1);
928  do_test ((NULL == grand_getChild (grand1)),
929  "new grand, unrelated parent");
930  do_test ((child1 == parent_getChild (parent1)),
931  "child unrelated to grand");
932  coll = grand_getDescend (grand1);
933  do_test ((coll != NULL), "grandparent not valid");
934  if (coll)
935  {
936  QofEntity *ent;
937 
938  ent = (QofEntity *) child1;
939  qof_collection_add_entity (coll, ent);
940  grand_setDescend (grand1, coll);
941  qof_collection_destroy (coll);
942  do_test ((g_list_length (grand1->descend) > 0),
943  "entity not added");
944  do_test ((qof_collection_count (grand_getDescend (grand1)) >
945  0), "empty collection returned");
946  }
947  break;
948  }
949  }
950 }
951 
952 struct tally
953 {
954  guint nulls, total, collect;
955  QofBook *book;
956 };
957 
958 static void
959 check_cb (QofEntity * ent, gpointer data)
960 {
961  QofEntity *parent, *child;
962  QofCollection *coll;
963  struct tally *c;
964  const QofParam *param;
965  mygrand *testg;
966  myparent *testp;
967  mychild *testc;
968 
969  c = (struct tally *) data;
970  /* check the same number and type of entities
971  exist in the copied book */
972  testg = (mygrand *) ent;
973  /* we always have a grandparent */
974  do_test ((testg != NULL), "grandparent not found");
975  c->total++;
976  param = qof_class_get_parameter (GRAND_MODULE_NAME, OBJ_LIST);
977  coll = (QofCollection *) param->param_getfcn (ent, param);
978  c->collect = qof_collection_count (coll);
979  if (c->book)
980  {
981  qof_book_set_references (c->book);
982  }
983  param = qof_class_get_parameter (GRAND_MODULE_NAME, OBJ_RELATIVE);
984  parent = (QofEntity *) param->param_getfcn (ent, param);
985  testp = grand_getChild ((mygrand *) ent);
986  /* not all grandparents have family so just keep count. */
987  if (!parent)
988  {
989  c->nulls++;
990  return;
991  }
992  do_test ((0 == safe_strcmp (parent_getName (testp),
993  parent_getName ((myparent *) parent))),
994  "parent copy test");
995  param = qof_class_get_parameter (PARENT_MODULE_NAME, OBJ_RELATIVE);
996  child = param->param_getfcn (parent, param);
997  testc = parent_getChild ((myparent *) parent);
998  if (!child)
999  {
1000  c->nulls++;
1001  return;
1002  }
1003  do_test ((0 == safe_strcmp (child_getName (testc),
1004  child_getName ((mychild *) child))),
1005  "child copy test");
1006 }
1007 
1008 static void
1009 test_recursion (QofSession * original, guint counter)
1010 {
1011  QofSession *copy;
1012  QofCollection *grand_coll;
1013  struct tally c;
1014  QofBook *book;
1015  guint d, e, f;
1016 
1017  c.nulls = 0;
1018  c.total = 0;
1019  c.collect = 0;
1020  c.book = NULL;
1021  book = qof_session_get_book (original);
1022  grand_coll = qof_book_get_collection (book, GRAND_MODULE_NAME);
1023  copy = qof_session_new ();
1024  if (debug)
1025  {
1026  qof_session_begin (copy, QOF_STDOUT, TRUE, FALSE);
1027  }
1028  /* TODO: implement QOF_TYPE_CHOICE testing. */
1029  qof_entity_copy_coll_r (copy, grand_coll);
1030  /* test the original */
1031  qof_object_foreach (GRAND_MODULE_NAME, book, check_cb, &c);
1032  book = qof_session_get_book (copy);
1033  /* test the copy */
1034  d = c.nulls;
1035  e = c.total;
1036  f = c.collect;
1037  c.nulls = 0;
1038  c.total = 0;
1039  c.collect = 0;
1040  c.book = book;
1041  qof_object_foreach (GRAND_MODULE_NAME, book, check_cb, &c);
1042  do_test ((d == c.nulls), "Null parents do not match");
1043  do_test ((e == c.total), "Total parents do not match");
1044  do_test ((f == c.collect),
1045  "Number of children in descendents does not match");
1046  if (counter == 4 && debug == TRUE)
1047  {
1048  qof_session_save (copy, NULL);
1049  qof_session_save (original, NULL);
1050  }
1051  qof_session_end (copy);
1052  copy = NULL;
1053 }
1054 
1055 int
1056 main (void)
1057 {
1058  QofSession *original;
1059  guint counter;
1060 
1061  qof_init ();
1062  mygrandRegister ();
1063  myparentRegister ();
1064  mychildRegister ();
1065  for (counter = 0; counter < 35; counter++)
1066  {
1067  original = qof_session_new ();
1068  if (debug)
1069  {
1070  qof_session_begin (original, QOF_STDOUT, TRUE, FALSE);
1071  }
1072  create_data (original, (counter % 5));
1073  test_recursion (original, (counter % 5));
1074  qof_session_end (original);
1075  }
1076  print_test_results ();
1077  qof_close ();
1078  return EXIT_SUCCESS;
1079 }
gboolean qof_collection_add_entity(QofCollection *coll, QofEntity *ent)
Add an entity to a QOF_TYPE_COLLECT.
Definition: qofid.c:182
gpointer qof_object_new_instance(QofIdTypeConst type_name, QofBook *book)
Definition: qofobject.c:42
#define QOF_TYPE_COLLECT
secondary collections are used for one-to-many references between entities and are implemented using ...
Definition: qofclass.h:121
QofCollection * qof_book_get_collection(QofBook *book, QofIdType entity_type)
Definition: qofbook.c:220
gboolean qof_collection_is_dirty(QofCollection *col)
Definition: qofid.c:333
#define QOF_OBJECT_VERSION
Definition: qofobject.h:57
void qof_object_foreach(QofIdTypeConst type_name, QofBook *book, QofEntityForeachCB cb, gpointer user_data)
Definition: qofobject.c:174
void qof_class_register(QofIdTypeConst obj_name, QofSortFunc default_sort_function, const QofParam *params)
registers a new object class with the Qof subsystem.
Definition: qofclass.c:94
This file declares testing functions for the engine.
QofBook * qof_instance_get_book(QofInstance *inst)
Definition: qofinstance.c:87
#define QOF_PARAM_BOOK
Definition: qofquery.h:104
void qof_event_gen(QofEntity *entity, QofEventId event_id, gpointer event_data)
Invoke all registered event handlers using the given arguments.
Definition: qofevent.c:235
void(* QofSetterFunc)(gpointer, gpointer)
Definition: qofclass.h:151
QofTime * qof_time_get_current(void)
Get the current QofTime.
Definition: qoftime.c:362
struct QofCollection_s QofCollection
Definition: qofid.h:138
const QofParam * qof_class_get_parameter(QofIdTypeConst obj_name, const gchar *parameter)
Definition: qofclass.c:147
#define QOF_EVENT_CREATE
Definition: qofevent.h:71
const GUID * qof_instance_get_guid(QofInstance *inst)
Definition: qofinstance.c:79
gboolean qof_entity_copy_coll_r(QofSession *new_session, QofCollection *coll)
Recursively copy a collection of entities to a session.
Definition: qofsession.c:859
void qof_book_set_references(QofBook *book)
Read QofEntityReference data for this book and set values.
Definition: qofreference.c:177
void qof_session_begin(QofSession *session, const gchar *book_id, gboolean ignore_lock, gboolean create_if_nonexistent)
Definition: qofsession.c:1032
guint qof_collection_count(QofCollection *col)
Definition: qofid.c:322
void qof_collection_foreach(QofCollection *col, QofEntityForeachCB cb_func, gpointer user_data)
Definition: qofid.c:392
gpointer(* QofAccessFunc)(gpointer object, const QofParam *param)
Definition: qofclass.h:144
void qof_collection_mark_clean(QofCollection *)
Definition: qofid.c:339
QofIdType qof_collection_get_type(QofCollection *col)
Definition: qofid.c:146
gboolean qof_object_register(const QofObject *object)
Definition: qofobject.c:278
void qof_close(void)
Safely close down the Query Object Framework.
Definition: qofutil.c:840
#define QOF_STDOUT
Allow session data to be printed to stdout.
Definition: qofsession.h:385
struct QofTime64 QofTime
Use a 64-bit signed int QofTime.
Definition: qoftime.h:112
void qof_collection_destroy(QofCollection *col)
Definition: qofid.c:132
QofCollection * qof_collection_new(QofIdType type)
Definition: qofid.c:121
void qof_session_save(QofSession *session, QofPercentageFunc percentage_func)
Definition: qofsession.c:1220
void qof_session_end(QofSession *session)
Definition: qofsession.c:1374
static QofNumeric qof_numeric_zero(void)
Definition: qofnumeric.h:253
gint safe_strcmp(const gchar *da, const gchar *db)
Definition: qofutil.c:75
int qof_instance_version_cmp(QofInstance *left, QofInstance *right)
Definition: qofinstance.c:116
void qof_instance_init(QofInstance *inst, QofIdType type, QofBook *book)
Definition: qofinstance.c:53
void qof_init(void)
Initialise the Query Object Framework.
Definition: qofutil.c:829