GnuCash  5.6-150-g038405b370+
qofinstance.cpp
1 /********************************************************************\
2  * qofinstance.c -- handler for fields common to all objects *
3  * *
4  * This program is free software; you can redistribute it and/or *
5  * modify it under the terms of the GNU General Public License as *
6  * published by the Free Software Foundation; either version 2 of *
7  * the License, or (at your option) any later version. *
8  * *
9  * This program is distributed in the hope that it will be useful, *
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12  * GNU General Public License for more details. *
13  * *
14  * You should have received a copy of the GNU General Public License*
15  * along with this program; if not, contact: *
16  * *
17  * Free Software Foundation Voice: +1-617-542-5942 *
18  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
19  * Boston, MA 02110-1301, USA gnu@gnu.org *
20  * *
21 \********************************************************************/
22 
23 /*
24  * Object instance holds many common fields that most
25  * gnucash objects use.
26  *
27  * Copyright (C) 2003 Linas Vepstas <linas@linas.org>
28  * Copyright (c) 2007 David Hampton <hampton@employees.org>
29  * Copyright 2017 Aaron Laws <dartme18@gmail.com>
30  */
31 
32 #include "guid.hpp"
33 #include <config.h>
34 #include <glib.h>
35 
36 #include <cstdint>
37 #include <utility>
38 #include "qof.h"
39 #include "qofbook-p.h"
40 #include "qofid-p.h"
41 #include "kvp-frame.hpp"
42 #include "qofinstance-p.h"
43 #include "qof-backend.hpp"
44 
45 static QofLogModule log_module = QOF_MOD_ENGINE;
46 
47 /* ========================================================== */
48 
49 enum
50 {
51  LAST_SIGNAL
52 };
53 
54 enum
55 {
56  PROP_0,
57  PROP_TYPE,
58  PROP_GUID,
59  PROP_COLLECTION,
60  PROP_BOOK,
61  PROP_LAST_UPDATE,
62  PROP_EDITLEVEL,
63  PROP_DESTROYING,
64  PROP_DIRTY,
65  PROP_INFANT,
66 
67  PROP_VERSION,
68  PROP_VERSION_CHECK,
69  PROP_IDATA,
70 };
71 
72 typedef struct QofInstancePrivate
73 {
74 // QofIdType e_type; /**< Entity type */
76  QofCollection *collection;
78  /* The entity_table in which this instance is stored */
79  QofBook * book;
80 
81  /* Timestamp used to track the last modification to this
82  * instance. Typically used to compare two versions of the
83  * same object, to see which is newer. When used with the
84  * SQL backend, this field is reserved for SQL use, to compare
85  * the version in local memory to the remote, server version.
86  */
87  time64 last_update;
88 
89  /* Keep track of nesting level of begin/end edit calls */
90  int editlevel;
91 
92  /* In process of being destroyed */
93  gboolean do_free;
94 
95  /* dirty/clean flag. If dirty, then this instance has been modified,
96  * but has not yet been written out to storage (file/database)
97  */
98  gboolean dirty;
99 
100  /* True iff this instance has never been committed. */
101  gboolean infant;
102 
103  /* version number, used for tracking multiuser updates */
104  gint32 version;
105  guint32 version_check; /* data aging timestamp */
106 
107  /* -------------------------------------------------------------- */
108  /* Backend private expansion data */
109  guint32 idata; /* used by the sql backend for kvp management */
111 
112 #define GET_PRIVATE(o) \
113  ((QofInstancePrivate*)qof_instance_get_instance_private((QofInstance*)o))
114 
115 G_DEFINE_TYPE_WITH_PRIVATE(QofInstance, qof_instance, G_TYPE_OBJECT)
116 QOF_GOBJECT_FINALIZE(qof_instance);
117 #undef G_PARAM_READWRITE
118 #define G_PARAM_READWRITE static_cast<GParamFlags>(G_PARAM_READABLE | G_PARAM_WRITABLE)
119 
120 static void qof_instance_get_property (GObject *object,
121  guint prop_id,
122  GValue *value,
123  GParamSpec *pspec);
124 static void qof_instance_set_property (GObject *object,
125  guint prop_id,
126  const GValue *value,
127  GParamSpec *pspec);
128 static void qof_instance_dispose(GObject*);
129 static void qof_instance_class_init(QofInstanceClass *klass)
130 {
131  GObjectClass *object_class = G_OBJECT_CLASS(klass);
132  object_class->finalize = qof_instance_finalize;
133  object_class->dispose = qof_instance_dispose;
134  object_class->set_property = qof_instance_set_property;
135  object_class->get_property = qof_instance_get_property;
136 
137  klass->get_display_name = nullptr;
138  klass->refers_to_object = nullptr;
139  klass->get_typed_referring_object_list = nullptr;
140 
141  g_object_class_install_property
142  (object_class,
143  PROP_GUID,
144  g_param_spec_boxed ("guid",
145  "Object GncGUID",
146  "The object Globally Unique ID.",
147  GNC_TYPE_GUID,
148  G_PARAM_READWRITE));
149 
150  g_object_class_install_property
151  (object_class,
152  PROP_COLLECTION,
153  g_param_spec_pointer ("collection",
154  "Object Collection",
155  "A collection of like objects of which this "
156  "particular object is amember. E.g.. A "
157  "collection of accounts, or a collection of "
158  "splits.",
159  G_PARAM_READWRITE));
160 
161  g_object_class_install_property
162  (object_class,
163  PROP_BOOK,
164  g_param_spec_object ("book",
165  "Object Book",
166  "The book that contains this object.",
167  QOF_TYPE_BOOK,
168  G_PARAM_READWRITE));
169 
170  g_object_class_install_property
171  (object_class,
172  PROP_LAST_UPDATE,
173  g_param_spec_pointer ("last-update",
174  "Object Last Update",
175  "A pointer to the last time this object was "
176  "updated. This value is present for use by "
177  "backends and shouldn't be written by other "
178  "code.",
179  G_PARAM_READWRITE));
180 
181  g_object_class_install_property
182  (object_class,
183  PROP_EDITLEVEL,
184  g_param_spec_int ("editlevel",
185  "Object Edit Level",
186  "The object edit level.",
187  0, G_MAXINT32, 0,
188  G_PARAM_READABLE));
189 
190  g_object_class_install_property
191  (object_class,
192  PROP_DESTROYING,
193  g_param_spec_boolean ("destroying",
194  "Object Destroying",
195  "This flag is set to TRUE if the object is "
196  "about to be destroyed.",
197  FALSE,
198  G_PARAM_READWRITE));
199 
200  g_object_class_install_property
201  (object_class,
202  PROP_DIRTY,
203  g_param_spec_boolean ("dirty",
204  "Object Dirty",
205  "This flag is set to TRUE if the object has "
206  "unsaved changes.",
207  FALSE,
208  G_PARAM_READWRITE));
209 
210  g_object_class_install_property
211  (object_class,
212  PROP_INFANT,
213  g_param_spec_boolean ("infant",
214  "Object Infant",
215  "This flag is set to TRUE if the object has "
216  "never been added to a book. This implies "
217  "that its destruction does not affect the "
218  "state of the book, and therefore the saved "
219  "state of the data file.",
220  FALSE,
221  G_PARAM_READABLE));
222 
223  g_object_class_install_property
224  (object_class,
225  PROP_VERSION,
226  g_param_spec_int ("version",
227  "Version",
228  "The version number of the current instance state.",
229  0,
230  G_MAXINT32,
231  0,
232  G_PARAM_READWRITE));
233 
234  g_object_class_install_property
235  (object_class,
236  PROP_VERSION_CHECK,
237  g_param_spec_uint ("version-check",
238  "Version Check",
239  "The version check number of the current instance state.",
240  0,
241  G_MAXUINT32,
242  0,
243  G_PARAM_READWRITE));
244 
245  g_object_class_install_property
246  (object_class,
247  PROP_EDITLEVEL,
248  g_param_spec_uint ("idata",
249  "Object IData",
250  "Per instance backend private data.",
251  0, G_MAXUINT32, 0,
252  G_PARAM_READWRITE));
253 }
254 
255 static void
256 qof_instance_init (QofInstance *inst)
257 {
258  QofInstancePrivate *priv;
259 
260  priv = GET_PRIVATE(inst);
261  priv->book = nullptr;
262  inst->kvp_data = new KvpFrame;
263  priv->last_update = 0;
264  priv->editlevel = 0;
265  priv->do_free = FALSE;
266  priv->dirty = FALSE;
267  priv->infant = TRUE;
268 }
269 
270 void
271 qof_instance_init_data (QofInstance *inst, QofIdType type, QofBook *book)
272 {
273  QofInstancePrivate *priv;
274  QofCollection *col;
275  QofIdType col_type;
276 
277  g_return_if_fail(QOF_IS_INSTANCE(inst));
278  priv = GET_PRIVATE(inst);
279  g_return_if_fail(!priv->book);
280 
281  priv->book = book;
282  col = qof_book_get_collection (book, type);
283  g_return_if_fail(col != nullptr);
284 
285  /* XXX We passed redundant info to this routine ... but I think that's
286  * OK, it might eliminate programming errors. */
287 
288  col_type = qof_collection_get_type(col);
289  if (g_strcmp0(col_type, type))
290  {
291  PERR ("attempt to insert \"%s\" into \"%s\"", type, col_type);
292  return;
293  }
294  priv = GET_PRIVATE(inst);
295  inst->e_type = static_cast<QofIdType>(CACHE_INSERT (type));
296 
297  do
298  {
299  guid_replace(&priv->guid);
300 
301  if (nullptr == qof_collection_lookup_entity (col, &priv->guid))
302  break;
303 
304  PWARN("duplicate id created, trying again");
305  }
306  while (1);
307 
308  priv->collection = col;
309 
310  qof_collection_insert_entity (col, inst);
311 }
312 
313 static void
314 qof_instance_dispose (GObject *instp)
315 {
316  QofInstancePrivate *priv;
317  QofInstance* inst = QOF_INSTANCE(instp);
318 
319  priv = GET_PRIVATE(instp);
320  if (priv->collection)
321  qof_collection_remove_entity(inst);
322 
323  CACHE_REMOVE(inst->e_type);
324  inst->e_type = nullptr;
325 
326  G_OBJECT_CLASS(qof_instance_parent_class)->dispose(instp);
327 }
328 
329 static void
330 qof_instance_finalize_real (GObject *instp)
331 {
332  QofInstancePrivate *priv;
333  QofInstance* inst = QOF_INSTANCE(instp);
334 
335  delete inst->kvp_data;
336  inst->kvp_data = nullptr;
337 
338  priv = GET_PRIVATE(inst);
339  priv->editlevel = 0;
340  priv->do_free = FALSE;
341  priv->dirty = FALSE;
342 }
343 
344 /* Note that g_value_set_object() refs the object, as does
345  * g_object_get(). But g_object_get() only unrefs once when it disgorges
346  * the object, leaving an unbalanced ref, which leaks. So instead of
347  * using g_value_set_object(), use g_value_take_object() which doesn't
348  * ref the object when used in get_property().
349  */
350 static void
351 qof_instance_get_property (GObject *object,
352  guint prop_id,
353  GValue *value,
354  GParamSpec *pspec)
355 {
356  QofInstance *inst;
357  QofInstancePrivate *priv;
358 
359  g_return_if_fail(QOF_IS_INSTANCE(object));
360 
361  inst = QOF_INSTANCE(object);
362  priv = GET_PRIVATE(inst);
363 
364  switch (prop_id)
365  {
366  case PROP_GUID:
367  g_value_set_boxed(value, &priv->guid);
368  break;
369  case PROP_COLLECTION:
370  g_value_set_pointer(value, priv->collection);
371  break;
372  case PROP_BOOK:
373  g_value_take_object(value, priv->book);
374  break;
375  case PROP_LAST_UPDATE:
376  g_value_set_pointer(value, &priv->last_update);
377  break;
378  case PROP_EDITLEVEL:
379  g_value_set_int(value, priv->editlevel);
380  break;
381  case PROP_DESTROYING:
382  g_value_set_boolean(value, priv->do_free);
383  break;
384  case PROP_DIRTY:
385  g_value_set_boolean(value, qof_instance_get_dirty(inst));
386  break;
387  case PROP_INFANT:
388  g_value_set_boolean(value, priv->infant);
389  break;
390  case PROP_VERSION:
391  g_value_set_int(value, priv->version);
392  break;
393  case PROP_VERSION_CHECK:
394  g_value_set_uint(value, priv->version_check);
395  break;
396  case PROP_IDATA:
397  g_value_set_uint(value, priv->idata);
398  break;
399  default:
400  G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
401  break;
402  }
403 }
404 
405 static void
406 qof_instance_set_property (GObject *object,
407  guint prop_id,
408  const GValue *value,
409  GParamSpec *pspec)
410 {
411  QofInstance *inst;
412  Time64 t;
413 
414  g_return_if_fail(QOF_IS_INSTANCE(object));
415 
416  inst = QOF_INSTANCE(object);
417 
418  switch (prop_id)
419  {
420  case PROP_GUID:
421  qof_instance_set_guid(inst,
422  static_cast<GncGUID*>(g_value_get_boxed(value)));
423  break;
424  case PROP_COLLECTION:
425  qof_instance_set_collection(inst, static_cast<QofCollection*>(g_value_get_pointer(value)));
426  break;
427  case PROP_BOOK:
429  static_cast<QofBook*>(g_value_get_object(value)));
430  break;
431  case PROP_LAST_UPDATE:
432  t = *(static_cast<Time64*>(g_value_get_pointer(value)));
433  qof_instance_set_last_update(inst, t.t);
434  break;
435  case PROP_DESTROYING:
436  qof_instance_set_destroying(inst, g_value_get_boolean(value));
437  break;
438  case PROP_DIRTY:
439  qof_instance_set_dirty(inst);
440  break;
441  case PROP_VERSION:
442  qof_instance_set_version(inst, g_value_get_int(value));
443  break;
444  case PROP_VERSION_CHECK:
445  qof_instance_set_version_check(inst, g_value_get_uint(value));
446  break;
447  case PROP_IDATA:
448  qof_instance_set_idata(inst, g_value_get_uint(value));
449  break;
450  default:
451  G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
452  break;
453  }
454 }
455 
456 const GncGUID *
457 qof_instance_get_guid (gconstpointer inst)
458 {
459  QofInstancePrivate *priv;
460 
461  if (!inst) return nullptr;
462  g_return_val_if_fail(QOF_IS_INSTANCE(inst), guid_null());
463  priv = GET_PRIVATE(inst);
464  return &(priv->guid);
465 }
466 
467 const GncGUID *
468 qof_entity_get_guid (gconstpointer ent)
469 {
470  return ent ? qof_instance_get_guid(ent) : guid_null();
471 }
472 
473 void
474 qof_instance_set_guid (gpointer ptr, const GncGUID *guid)
475 {
476  QofInstancePrivate *priv;
477  QofInstance *inst;
478  QofCollection *col;
479 
480  g_return_if_fail(QOF_IS_INSTANCE(ptr));
481 
482  inst = QOF_INSTANCE(ptr);
483  priv = GET_PRIVATE(inst);
484  if (guid_equal (guid, &priv->guid))
485  return;
486 
487  col = priv->collection;
488  qof_collection_remove_entity(inst);
489  priv->guid = *guid;
490  qof_collection_insert_entity(col, inst);
491 }
492 
493 void
494 qof_instance_copy_guid (gpointer to, gconstpointer from)
495 {
496  g_return_if_fail(QOF_IS_INSTANCE(to));
497  g_return_if_fail(QOF_IS_INSTANCE(from));
498 
499  GET_PRIVATE(to)->guid = GET_PRIVATE(from)->guid;
500 }
501 
502 gint
503 qof_instance_guid_compare(gconstpointer ptr1, gconstpointer ptr2)
504 {
505  const QofInstancePrivate *priv1, *priv2;
506 
507  g_return_val_if_fail(QOF_IS_INSTANCE(ptr1), -1);
508  g_return_val_if_fail(QOF_IS_INSTANCE(ptr2), 1);
509 
510  priv1 = GET_PRIVATE(ptr1);
511  priv2 = GET_PRIVATE(ptr2);
512 
513  return guid_compare(&priv1->guid, &priv2->guid);
514 }
515 
516 QofCollection *
517 qof_instance_get_collection (gconstpointer ptr)
518 {
519 
520  g_return_val_if_fail(QOF_IS_INSTANCE(ptr), nullptr);
521  return GET_PRIVATE(ptr)->collection;
522 }
523 
524 void
525 qof_instance_set_collection (gconstpointer ptr, QofCollection *col)
526 {
527  g_return_if_fail(QOF_IS_INSTANCE(ptr));
528  GET_PRIVATE(ptr)->collection = col;
529 }
530 
531 QofBook *
532 qof_instance_get_book (gconstpointer inst)
533 {
534  if (!inst) return nullptr;
535  g_return_val_if_fail(QOF_IS_INSTANCE(inst), nullptr);
536  return GET_PRIVATE(inst)->book;
537 }
538 
539 void
540 qof_instance_set_book (gconstpointer inst, QofBook *book)
541 {
542  g_return_if_fail(QOF_IS_INSTANCE(inst));
543  GET_PRIVATE(inst)->book = book;
544 }
545 
546 void
547 qof_instance_copy_book (gpointer ptr1, gconstpointer ptr2)
548 {
549  g_return_if_fail(QOF_IS_INSTANCE(ptr1));
550  g_return_if_fail(QOF_IS_INSTANCE(ptr2));
551 
552  GET_PRIVATE(ptr1)->book = GET_PRIVATE(ptr2)->book;
553 }
554 
555 gboolean
556 qof_instance_books_equal (gconstpointer ptr1, gconstpointer ptr2)
557 {
558  const QofInstancePrivate *priv1, *priv2;
559 
560  g_return_val_if_fail(QOF_IS_INSTANCE(ptr1), FALSE);
561  g_return_val_if_fail(QOF_IS_INSTANCE(ptr2), FALSE);
562 
563  priv1 = GET_PRIVATE(ptr1);
564  priv2 = GET_PRIVATE(ptr2);
565 
566  return (priv1->book == priv2->book);
567 }
568 
569 /* Watch out: This function is still used (as a "friend") in src/import-export/aqb/gnc-ab-kvp.c */
570 KvpFrame*
571 qof_instance_get_slots (const QofInstance *inst)
572 {
573  if (!inst) return nullptr;
574  return inst->kvp_data;
575 }
576 
577 void
578 qof_instance_set_slots (QofInstance *inst, KvpFrame *frm)
579 {
580  QofInstancePrivate *priv;
581 
582  if (!inst) return;
583 
584  priv = GET_PRIVATE(inst);
585  if (inst->kvp_data && (inst->kvp_data != frm))
586  {
587  delete inst->kvp_data;
588  }
589 
590  priv->dirty = TRUE;
591  inst->kvp_data = frm;
592 }
593 
594 void
595 qof_instance_set_last_update (QofInstance *inst, time64 t)
596 {
597  if (!inst) return;
598  GET_PRIVATE(inst)->last_update = t;
599 }
600 
601 gint
602 qof_instance_get_editlevel (gconstpointer ptr)
603 {
604  g_return_val_if_fail(QOF_IS_INSTANCE(ptr), 0);
605  return GET_PRIVATE(ptr)->editlevel;
606 }
607 
608 void qof_instance_increase_editlevel (gpointer ptr)
609 {
610  g_return_if_fail(QOF_IS_INSTANCE(ptr));
611  GET_PRIVATE(ptr)->editlevel++;
612 }
613 
614 void qof_instance_decrease_editlevel (gpointer ptr)
615 {
616  g_return_if_fail(QOF_IS_INSTANCE(ptr));
617  GET_PRIVATE(ptr)->editlevel--;
618 }
619 
620 void qof_instance_reset_editlevel (gpointer ptr)
621 {
622  g_return_if_fail(QOF_IS_INSTANCE(ptr));
623  GET_PRIVATE(ptr)->editlevel = 0;
624 }
625 
626 int
628 {
629  QofInstancePrivate *lpriv, *rpriv;
630 
631  if (!left && !right) return 0;
632  if (!left) return -1;
633  if (!right) return +1;
634 
635  lpriv = GET_PRIVATE(left);
636  rpriv = GET_PRIVATE(right);
637  return lpriv->last_update < rpriv->last_update ? -1 :
638  lpriv->last_update > rpriv->last_update ? 1 : 0;
639 }
640 
641 gboolean
642 qof_instance_get_destroying (gconstpointer ptr)
643 {
644  g_return_val_if_fail(QOF_IS_INSTANCE(ptr), FALSE);
645  return GET_PRIVATE(ptr)->do_free;
646 }
647 
648 void
649 qof_instance_set_destroying (gpointer ptr, gboolean value)
650 {
651  g_return_if_fail(QOF_IS_INSTANCE(ptr));
652  GET_PRIVATE(ptr)->do_free = value;
653 }
654 
655 gboolean
656 qof_instance_get_dirty_flag (gconstpointer ptr)
657 {
658  g_return_val_if_fail(QOF_IS_INSTANCE(ptr), FALSE);
659  return GET_PRIVATE(ptr)->dirty;
660 }
661 
662 void
663 qof_instance_set_dirty_flag (gconstpointer inst, gboolean flag)
664 {
665  g_return_if_fail(QOF_IS_INSTANCE(inst));
666  GET_PRIVATE(inst)->dirty = flag;
667 }
668 
669 void
670 qof_instance_mark_clean (QofInstance *inst)
671 {
672  if (!inst) return;
673  GET_PRIVATE(inst)->dirty = FALSE;
674 }
675 
676 void
677 qof_instance_print_dirty (const QofInstance *inst, gpointer dummy)
678 {
679  QofInstancePrivate *priv;
680 
681  priv = GET_PRIVATE(inst);
682  if (priv->dirty)
683  {
684  gchar guidstr[GUID_ENCODING_LENGTH+1];
685  guid_to_string_buff(&priv->guid, guidstr);
686  printf("%s instance %s is dirty.\n", inst->e_type, guidstr);
687  }
688 }
689 
690 gboolean
691 qof_instance_get_dirty (QofInstance *inst)
692 {
693  QofInstancePrivate *priv;
694 
695  if (!inst)
696  {
697  return FALSE;
698  }
699 
700  priv = GET_PRIVATE(inst);
701  return priv->dirty;
702 }
703 
704 void
705 qof_instance_set_dirty(QofInstance* inst)
706 {
707  QofInstancePrivate *priv;
708 
709  priv = GET_PRIVATE(inst);
710  priv->dirty = TRUE;
711 }
712 
713 gboolean
714 qof_instance_get_infant(const QofInstance *inst)
715 {
716  g_return_val_if_fail(QOF_IS_INSTANCE(inst), FALSE);
717  return GET_PRIVATE(inst)->infant;
718 }
719 
720 gint32
721 qof_instance_get_version (gconstpointer inst)
722 {
723  g_return_val_if_fail(QOF_IS_INSTANCE(inst), 0);
724  return GET_PRIVATE(inst)->version;
725 }
726 
727 void
728 qof_instance_set_version (gpointer inst, gint32 vers)
729 {
730  g_return_if_fail(QOF_IS_INSTANCE(inst));
731  GET_PRIVATE(inst)->version = vers;
732 }
733 
734 void
735 qof_instance_copy_version (gpointer to, gconstpointer from)
736 {
737  g_return_if_fail(QOF_IS_INSTANCE(to));
738  g_return_if_fail(QOF_IS_INSTANCE(from));
739  GET_PRIVATE(to)->version = GET_PRIVATE(from)->version;
740 }
741 
742 guint32
743 qof_instance_get_version_check (gconstpointer inst)
744 {
745  g_return_val_if_fail(QOF_IS_INSTANCE(inst), 0);
746  return GET_PRIVATE(inst)->version_check;
747 }
748 
749 void
750 qof_instance_set_version_check (gpointer inst, guint32 value)
751 {
752  g_return_if_fail(QOF_IS_INSTANCE(inst));
753  GET_PRIVATE(inst)->version_check = value;
754 }
755 
756 void
757 qof_instance_copy_version_check (gpointer to, gconstpointer from)
758 {
759  g_return_if_fail(QOF_IS_INSTANCE(to));
760  g_return_if_fail(QOF_IS_INSTANCE(from));
761  GET_PRIVATE(to)->version_check = GET_PRIVATE(from)->version_check;
762 }
763 
764 guint32 qof_instance_get_idata (gconstpointer inst)
765 {
766  if (!inst)
767  {
768  return 0;
769  }
770  g_return_val_if_fail(QOF_IS_INSTANCE(inst), 0);
771  return GET_PRIVATE(inst)->idata;
772 }
773 
774 void qof_instance_set_idata(gpointer inst, guint32 idata)
775 {
776  if (!inst)
777  {
778  return;
779  }
780  g_return_if_fail(QOF_IS_INSTANCE(inst));
781  GET_PRIVATE(inst)->idata = idata;
782 }
783 
784 /* ========================================================== */
785 
786 /* Returns a displayable name to represent this object */
788 {
789  g_return_val_if_fail( inst != nullptr, nullptr );
790 
791  if ( QOF_INSTANCE_GET_CLASS(inst)->get_display_name != nullptr )
792  {
793  return QOF_INSTANCE_GET_CLASS(inst)->get_display_name(inst);
794  }
795  else
796  {
797  /* Not implemented - return default string */
798  return g_strdup_printf("Object %s %p",
800  inst);
801  }
802 }
803 
804 typedef struct
805 {
806  const QofInstance* inst;
807  GList* list;
809 
810 static void
811 get_referring_object_instance_helper(QofInstance* inst, gpointer user_data)
812 {
813  QofInstance** pInst = (QofInstance**)user_data;
814 
815  if (*pInst == nullptr)
816  {
817  *pInst = inst;
818  }
819 }
820 
821 static void
822 get_referring_object_helper(QofCollection* coll, gpointer user_data)
823 {
824  QofInstance* first_instance = nullptr;
826 
827  qof_collection_foreach(coll, get_referring_object_instance_helper, &first_instance);
828 
829  if (first_instance != nullptr)
830  {
831  GList* new_list = qof_instance_get_typed_referring_object_list(first_instance, data->inst);
832  data->list = g_list_concat(data->list, new_list);
833  }
834 }
835 
836 /* Returns a list of objects referring to this object */
838 {
840 
841  g_return_val_if_fail( inst != nullptr, nullptr );
842 
843  /* scan all collections */
844  data.inst = inst;
845  data.list = nullptr;
846 
847  qof_book_foreach_collection(qof_instance_get_book(inst),
848  get_referring_object_helper,
849  &data);
850  return data.list;
851 }
852 
853 static void
854 get_typed_referring_object_instance_helper(QofInstance* inst, gpointer user_data)
855 {
857 
858  if (qof_instance_refers_to_object(inst, data->inst))
859  {
860  data->list = g_list_prepend(data->list, inst);
861  }
862 }
863 
864 GList*
866 {
868 
869  g_return_val_if_fail( coll != nullptr, nullptr );
870  g_return_val_if_fail( ref != nullptr, nullptr );
871 
872  data.inst = ref;
873  data.list = nullptr;
874 
875  qof_collection_foreach(coll, get_typed_referring_object_instance_helper, &data);
876  return data.list;
877 }
878 
879 GList*
881 {
882  g_return_val_if_fail( inst != nullptr, nullptr );
883  g_return_val_if_fail( ref != nullptr, nullptr );
884 
885  if ( QOF_INSTANCE_GET_CLASS(inst)->get_typed_referring_object_list != nullptr )
886  {
887  return QOF_INSTANCE_GET_CLASS(inst)->get_typed_referring_object_list(inst, ref);
888  }
889  else
890  {
891  /* Not implemented - by default, loop through all objects of this object's type and check
892  them individually. */
893  QofCollection* coll;
894 
895  coll = qof_instance_get_collection(inst);
897  }
898 }
899 
900 /* Check if this object refers to a specific object */
901 gboolean qof_instance_refers_to_object(const QofInstance* inst, const QofInstance* ref)
902 {
903  g_return_val_if_fail( inst != nullptr, FALSE );
904  g_return_val_if_fail( ref != nullptr, FALSE );
905 
906  if ( QOF_INSTANCE_GET_CLASS(inst)->refers_to_object != nullptr )
907  {
908  return QOF_INSTANCE_GET_CLASS(inst)->refers_to_object(inst, ref);
909  }
910  else
911  {
912  /* Not implemented - default = NO */
913  return FALSE;
914  }
915 }
916 
917 /* g_object_set/get wrappers */
918 void
919 qof_instance_get (const QofInstance *inst, const gchar *first_prop, ...)
920 {
921  va_list ap;
922  g_return_if_fail (QOF_IS_INSTANCE (inst));
923 
924  va_start (ap, first_prop);
925  g_object_get_valist (G_OBJECT (inst), first_prop, ap);
926  va_end (ap);
927 }
928 
929 void
930 qof_instance_set (QofInstance *inst, const gchar *first_prop, ...)
931 {
932  va_list ap;
933  g_return_if_fail (QOF_IS_INSTANCE (inst));
934 
935  qof_instance_set_dirty (inst);
936  va_start (ap, first_prop);
937  g_object_set_valist (G_OBJECT (inst), first_prop, ap);
938  va_end (ap);
939 }
940 
941 
942 /* =================================================================== */
943 /* Entity edit and commit utilities */
944 /* =================================================================== */
945 
946 gboolean
948 {
949  QofInstancePrivate *priv;
950 
951  if (!inst) return FALSE;
952 
953  priv = GET_PRIVATE(inst);
954  priv->editlevel++;
955  if (1 < priv->editlevel) return FALSE;
956  if (0 >= priv->editlevel)
957  priv->editlevel = 1;
958 
959  auto be = qof_book_get_backend(priv->book);
960  if (be)
961  be->begin(inst);
962  else
963  priv->dirty = TRUE;
964 
965  return TRUE;
966 }
967 
968 gboolean qof_commit_edit (QofInstance *inst)
969 {
970  QofInstancePrivate *priv;
971 
972  if (!inst) return FALSE;
973 
974  priv = GET_PRIVATE(inst);
975  priv->editlevel--;
976  if (0 < priv->editlevel) return FALSE;
977 
978  if (0 > priv->editlevel)
979  {
980  PERR ("unbalanced call - resetting (was %d)", priv->editlevel);
981  priv->editlevel = 0;
982  }
983  return TRUE;
984 }
985 
986 gboolean
988  void (*on_error)(QofInstance *, QofBackendError),
989  void (*on_done)(QofInstance *),
990  void (*on_free)(QofInstance *))
991 {
992  QofInstancePrivate *priv;
993 
994  priv = GET_PRIVATE(inst);
995 
996  if (priv->dirty &&
997  !(priv->infant && priv->do_free)) {
998  qof_collection_mark_dirty(priv->collection);
999  qof_book_mark_session_dirty(priv->book);
1000  }
1001 
1002  /* See if there's a backend. If there is, invoke it. */
1003  auto be = qof_book_get_backend(priv->book);
1004  if (be)
1005  {
1006  QofBackendError errcode;
1007 
1008  /* clear errors */
1009  do
1010  {
1011  errcode = be->get_error();
1012  }
1013  while (errcode != ERR_BACKEND_NO_ERR);
1014 
1015  be->commit(inst);
1016  errcode = be->get_error();
1017  if (errcode != ERR_BACKEND_NO_ERR)
1018  {
1019  /* XXX Should perform a rollback here */
1020  priv->do_free = FALSE;
1021 
1022  /* Push error back onto the stack */
1023  be->set_error (errcode);
1024  if (on_error)
1025  on_error(inst, errcode);
1026  return FALSE;
1027  }
1028  if (!priv->dirty) //Cleared if the save was successful
1029  priv->infant = FALSE;
1030  }
1031 
1032  if (priv->do_free)
1033  {
1034  if (on_free)
1035  on_free(inst);
1036  return TRUE;
1037  }
1038 
1039  if (on_done)
1040  on_done(inst);
1041  return TRUE;
1042 }
1043 
1044 gboolean
1046 {
1047  return (inst->kvp_data != nullptr && !inst->kvp_data->empty());
1048 }
1049 
1050 void qof_instance_set_path_kvp (QofInstance * inst, GValue const * value, std::vector<std::string> const & path)
1051 {
1052  delete inst->kvp_data->set_path (path, kvp_value_from_gvalue (value));
1053 }
1054 
1055 void
1056 qof_instance_set_kvp (QofInstance * inst, GValue const * value, unsigned count, ...)
1057 {
1058  std::vector<std::string> path;
1059  va_list args;
1060  va_start (args, count);
1061  for (unsigned i{0}; i < count; ++i)
1062  path.push_back (va_arg (args, char const *));
1063  va_end (args);
1064  delete inst->kvp_data->set_path (path, kvp_value_from_gvalue (value));
1065 }
1066 
1067 template <typename T> std::optional<T>
1068 qof_instance_get_path_kvp (QofInstance* inst, const Path& path)
1069 {
1070  g_return_val_if_fail (QOF_IS_INSTANCE(inst), std::nullopt);
1071  auto kvp_value{inst->kvp_data->get_slot(path)};
1072  return kvp_value ? std::make_optional<T>(kvp_value->get<T>()) : std::nullopt;
1073 }
1074 
1075 template <typename T> void
1076 qof_instance_set_path_kvp (QofInstance* inst, std::optional<T> value, const Path& path)
1077 {
1078  g_return_if_fail (QOF_IS_INSTANCE(inst));
1079  delete inst->kvp_data->set_path(path, value ? new KvpValue(*value) : nullptr);
1080  qof_instance_set_dirty (inst);
1081 }
1082 
1083 template std::optional<const char*> qof_instance_get_path_kvp <const char*> (QofInstance*, const Path&);
1084 template std::optional<gnc_numeric> qof_instance_get_path_kvp <gnc_numeric> (QofInstance*, const Path&);
1085 template std::optional<GncGUID*> qof_instance_get_path_kvp <GncGUID*> (QofInstance*, const Path&);
1086 template std::optional<int64_t> qof_instance_get_path_kvp <int64_t> (QofInstance*, const Path&);
1087 
1088 template void qof_instance_set_path_kvp <const char*> (QofInstance*, std::optional<const char*>, const Path& path);
1089 template void qof_instance_set_path_kvp <gnc_numeric> (QofInstance*, std::optional<gnc_numeric>, const Path& path);
1090 template void qof_instance_set_path_kvp <GncGUID*> (QofInstance*, std::optional<GncGUID*>, const Path& path);
1091 template void qof_instance_set_path_kvp <int64_t> (QofInstance*, std::optional<int64_t>, const Path& path);
1092 
1093 void qof_instance_get_path_kvp (QofInstance * inst, GValue * value, std::vector<std::string> const & path)
1094 {
1095  gvalue_from_kvp_value (inst->kvp_data->get_slot (path), value);
1096 }
1097 
1098 void
1099 qof_instance_get_kvp (QofInstance * inst, GValue * value, unsigned count, ...)
1100 {
1101  std::vector<std::string> path;
1102  va_list args;
1103  va_start (args, count);
1104  for (unsigned i{0}; i < count; ++i)
1105  path.push_back (va_arg (args, char const *));
1106  va_end (args);
1107  gvalue_from_kvp_value (inst->kvp_data->get_slot (path), value);
1108 }
1109 
1110 void
1111 qof_instance_copy_kvp (QofInstance *to, const QofInstance *from)
1112 {
1113  delete to->kvp_data;
1114  to->kvp_data = new KvpFrame(*from->kvp_data);
1115 }
1116 
1117 void
1118 qof_instance_swap_kvp (QofInstance *a, QofInstance *b)
1119 {
1120  std::swap(a->kvp_data, b->kvp_data);
1121 }
1122 
1123 int
1124 qof_instance_compare_kvp (const QofInstance *a, const QofInstance *b)
1125 {
1126  return compare(a->kvp_data, b->kvp_data);
1127 }
1128 
1129 char*
1130 qof_instance_kvp_as_string (const QofInstance *inst)
1131 {
1132  auto str{inst->kvp_data->to_string()};
1133  return g_strdup(str.c_str());
1134 }
1135 
1136 void
1137 qof_instance_kvp_add_guid (const QofInstance *inst, const char* path,
1138  time64 time, const char *key,
1139  const GncGUID *guid)
1140 {
1141  g_return_if_fail (inst->kvp_data != nullptr);
1142 
1143  auto container = new KvpFrame;
1144  Time64 t{time};
1145  container->set({key}, new KvpValue(const_cast<GncGUID*>(guid)));
1146  container->set({"date"}, new KvpValue(t));
1147  delete inst->kvp_data->set_path({path}, new KvpValue(container));
1148 }
1149 
1150 inline static gboolean
1151 kvp_match_guid (KvpValue *v, std::vector<std::string> const & path, const GncGUID *guid)
1152 {
1153  if (v->get_type() != KvpValue::Type::FRAME)
1154  return FALSE;
1155  auto frame = v->get<KvpFrame*>();
1156  auto val = frame->get_slot(path);
1157  if (val == nullptr || val->get_type() != KvpValue::Type::GUID)
1158  return FALSE;
1159  auto this_guid = val->get<GncGUID*>();
1160 
1161  return guid_equal (this_guid, guid);
1162 }
1163 
1164 gboolean
1165 qof_instance_kvp_has_guid (const QofInstance *inst, const char *path,
1166  const char* key, const GncGUID *guid)
1167 {
1168  g_return_val_if_fail (inst->kvp_data != nullptr, FALSE);
1169  g_return_val_if_fail (guid != nullptr, FALSE);
1170 
1171  auto v = inst->kvp_data->get_slot({path});
1172  if (v == nullptr) return FALSE;
1173 
1174  switch (v->get_type())
1175  {
1176  case KvpValue::Type::FRAME:
1177  return kvp_match_guid (v, {key}, guid);
1178  break;
1179  case KvpValue::Type::GLIST:
1180  {
1181  auto list = v->get<GList*>();
1182  for (auto node = list; node != nullptr; node = node->next)
1183  {
1184  auto val = static_cast<KvpValue*>(node->data);
1185  if (kvp_match_guid (val, {key}, guid))
1186  {
1187  return TRUE;
1188  }
1189  }
1190  break;
1191  }
1192  default:
1193  PWARN ("Instance KVP on path %s contains the wrong type.", path);
1194  break;
1195  }
1196  return FALSE;
1197 }
1198 
1199 void
1200 qof_instance_kvp_remove_guid (const QofInstance *inst, const char *path,
1201  const char *key, const GncGUID *guid)
1202 {
1203  g_return_if_fail (inst->kvp_data != nullptr);
1204  g_return_if_fail (guid != nullptr);
1205 
1206  auto v = inst->kvp_data->get_slot({path});
1207  if (v == nullptr) return;
1208 
1209  switch (v->get_type())
1210  {
1211  case KvpValue::Type::FRAME:
1212  if (kvp_match_guid (v, {key}, guid))
1213  {
1214  delete inst->kvp_data->set_path({path}, nullptr);
1215  delete v;
1216  }
1217  break;
1218  case KvpValue::Type::GLIST:
1219  {
1220  auto list = v->get<GList*>();
1221  for (auto node = list; node != nullptr; node = node->next)
1222  {
1223  auto val = static_cast<KvpValue*>(node->data);
1224  if (kvp_match_guid (val, {key}, guid))
1225  {
1226  list = g_list_delete_link (list, node);
1227  v->set(list);
1228  delete val;
1229  break;
1230  }
1231  }
1232  break;
1233  }
1234  default:
1235  PWARN ("Instance KVP on path %s contains the wrong type.", path);
1236  break;
1237  }
1238  return;
1239 }
1240 
1241 void
1242 qof_instance_kvp_merge_guids (const QofInstance *target,
1243  const QofInstance *donor, const char *path)
1244 {
1245  g_return_if_fail (target != nullptr);
1246  g_return_if_fail (donor != nullptr);
1247 
1248  if (! qof_instance_has_slot (donor, path)) return;
1249  auto v = donor->kvp_data->get_slot({path});
1250  if (v == nullptr) return;
1251 
1252  auto target_val = target->kvp_data->get_slot({path});
1253  switch (v->get_type())
1254  {
1255  case KvpValue::Type::FRAME:
1256  if (target_val)
1257  target_val->add(v);
1258  else
1259  target->kvp_data->set_path({path}, v);
1260  donor->kvp_data->set({path}, nullptr); //Contents moved, Don't delete!
1261  break;
1262  case KvpValue::Type::GLIST:
1263  if (target_val)
1264  {
1265  auto list = target_val->get<GList*>();
1266  list = g_list_concat(list, v->get<GList*>());
1267  target_val->set(list);
1268  }
1269  else
1270  target->kvp_data->set({path}, v);
1271  donor->kvp_data->set({path}, nullptr); //Contents moved, Don't delete!
1272  break;
1273  default:
1274  PWARN ("Instance KVP on path %s contains the wrong type.", path);
1275  break;
1276  }
1277 }
1278 
1279 bool qof_instance_has_path_slot (QofInstance const * inst, std::vector<std::string> const & path)
1280 {
1281  return inst->kvp_data->get_slot (path) != nullptr;
1282 }
1283 
1284 gboolean
1285 qof_instance_has_slot (const QofInstance *inst, const char *path)
1286 {
1287  return inst->kvp_data->get_slot({path}) != nullptr;
1288 }
1289 
1290 void qof_instance_slot_path_delete (QofInstance const * inst, std::vector<std::string> const & path)
1291 {
1292  delete inst->kvp_data->set (path, nullptr);
1293 }
1294 
1295 void
1296 qof_instance_slot_delete (QofInstance const *inst, char const * path)
1297 {
1298  delete inst->kvp_data->set ({path}, nullptr);
1299 }
1300 
1301 void qof_instance_slot_path_delete_if_empty (QofInstance const * inst, std::vector<std::string> const & path)
1302 {
1303  auto slot = inst->kvp_data->get_slot (path);
1304  if (slot)
1305  {
1306  auto frame = slot->get <KvpFrame*> ();
1307  if (frame && frame->empty())
1308  delete inst->kvp_data->set (path, nullptr);
1309  }
1310 }
1311 
1312 void
1313 qof_instance_slot_delete_if_empty (QofInstance const *inst, char const * path)
1314 {
1315  auto slot = inst->kvp_data->get_slot ({path});
1316  if (slot)
1317  {
1318  auto frame = slot->get <KvpFrame*> ();
1319  if (frame && frame->empty ())
1320  delete inst->kvp_data->set ({path}, nullptr);
1321  }
1322 }
1323 
1324 std::vector <std::pair <std::string, KvpValue*>>
1325 qof_instance_get_slots_prefix (QofInstance const * inst, std::string const & prefix)
1326 {
1327  std::vector <std::pair <std::string, KvpValue*>> ret;
1328  inst->kvp_data->for_each_slot_temp ([&prefix, &ret] (std::string const & key, KvpValue * val) {
1329  if (key.find (prefix) == 0)
1330  ret.emplace_back (key, val);
1331  });
1332  return ret;
1333 }
1334 
1335 namespace {
1336 struct wrap_param
1337 {
1338  void (*proc)(const char*, const GValue*, void*);
1339  void *user_data;
1340 };
1341 }
1342 
1343 static void
1344 wrap_gvalue_function (const char* key, KvpValue *val, wrap_param & param)
1345 {
1346  GValue gv;
1347  if (val->get_type() != KvpValue::Type::FRAME)
1348  gvalue_from_kvp_value(val, &gv);
1349  else
1350  {
1351  g_value_init (&gv, G_TYPE_STRING);
1352  g_value_set_string (&gv, nullptr);
1353  }
1354  param.proc(key, &gv, param.user_data);
1355  g_value_unset (&gv);
1356 }
1357 
1358 void
1359 qof_instance_foreach_slot (const QofInstance *inst, const char* head, const char* category,
1360  void (*proc)(const char*, const GValue*, void*), void* data)
1361 {
1362  std::vector<std::string> path {head};
1363  if (category)
1364  path.emplace_back (category);
1365 
1366  auto slot = inst->kvp_data->get_slot(path);
1367  if (slot == nullptr || slot->get_type() != KvpValue::Type::FRAME)
1368  return;
1369  auto frame = slot->get<KvpFrame*>();
1370  wrap_param new_data {proc, data};
1371  frame->for_each_slot_temp(&wrap_gvalue_function, new_data);
1372 }
1373 
1374 /* ========================== END OF FILE ======================= */
1375 
int qof_instance_version_cmp(const QofInstance *left, const QofInstance *right)
Compare two instances, based on their last update times.
void guid_replace(GncGUID *guid)
Generate a new guid.
Definition: guid.cpp:143
const GncGUID * qof_instance_get_guid(gconstpointer inst)
Return the GncGUID of this instance.
void qof_instance_get(const QofInstance *inst, const gchar *first_prop,...)
Wrapper for g_object_get.
void qof_instance_set_kvp(QofInstance *, GValue const *value, unsigned count,...)
Sets a KVP slot to a value from a GValue.
QofBook * qof_instance_get_book(gconstpointer inst)
Return the book pointer.
QofInstance * qof_collection_lookup_entity(const QofCollection *col, const GncGUID *guid)
Find the entity going only from its guid.
Definition: qofid.cpp:212
QofBackendError
The errors that can be reported to the GUI & other front-end users.
Definition: qofbackend.h:57
GncGUID guid
GncGUID for the entity.
Definition: qofinstance.cpp:75
GList * qof_instance_get_referring_object_list_from_collection(const QofCollection *coll, const QofInstance *ref)
Returns a list of objects from the collection which refer to the specific object. ...
void gvalue_from_kvp_value(const KvpValue *kval, GValue *val)
Convert a kvp_value into a GValue.
Definition: kvp-frame.cpp:237
gboolean qof_instance_get_destroying(gconstpointer ptr)
Retrieve the flag that indicates whether or not this object is about to be destroyed.
void qof_instance_set(QofInstance *inst, const gchar *first_prop,...)
Wrapper for g_object_set Group setting multiple parameters in a single begin/commit/rollback.
STL namespace.
KvpValue * kvp_value_from_gvalue(const GValue *gval)
Convert a gvalue into a kvpvalue.
Definition: kvp-frame.cpp:280
QofCollection * qof_instance_get_collection(gconstpointer ptr)
Return the collection this instance belongs to.
gchar * guid_to_string_buff(const GncGUID *guid, gchar *str)
The guid_to_string_buff() routine puts a null-terminated string encoding of the id into the memory po...
Definition: guid.cpp:173
gboolean qof_commit_edit(QofInstance *inst)
commit_edit helpers
#define PERR(format, args...)
Log a serious error.
Definition: qoflog.h:244
void qof_instance_get_kvp(QofInstance *, GValue *value, unsigned count,...)
Retrieves the contents of a KVP slot into a provided GValue.
#define PWARN(format, args...)
Log a warning.
Definition: qoflog.h:250
const gchar * QofIdType
QofIdType declaration.
Definition: qofid.h:80
void qof_instance_init_data(QofInstance *inst, QofIdType type, QofBook *book)
Initialise the settings associated with an instance.
gboolean qof_begin_edit(QofInstance *inst)
begin_edit
guint32 qof_instance_get_idata(gconstpointer inst)
get the instance tag number used for kvp management in sql backends.
gboolean guid_equal(const GncGUID *guid_1, const GncGUID *guid_2)
Given two GUIDs, return TRUE if they are non-NULL and equal.
Definition: guid.cpp:204
#define GUID_ENCODING_LENGTH
Number of characters needed to encode a guid as a string not including the null terminator.
Definition: guid.h:84
gboolean qof_instance_get_dirty_flag(gconstpointer ptr)
Retrieve the flag that indicates whether or not this object has been modified.
void qof_instance_copy_book(gpointer ptr1, gconstpointer ptr2)
Copy the book from one QofInstances to another.
GList * qof_instance_get_typed_referring_object_list(const QofInstance *inst, const QofInstance *ref)
Returns a list of my type of object which refers to an object.
gboolean qof_commit_edit_part2(QofInstance *inst, void(*on_error)(QofInstance *, QofBackendError), void(*on_done)(QofInstance *), void(*on_free)(QofInstance *))
part2 – deal with the backend
void qof_collection_insert_entity(QofCollection *, QofInstance *)
Take entity, remove it from whatever collection its currently in, and place it in a new collection...
Definition: qofid.cpp:95
const GncGUID * qof_entity_get_guid(gconstpointer ent)
gboolean qof_instance_books_equal(gconstpointer ptr1, gconstpointer ptr2)
See if two QofInstances share the same book.
void qof_book_mark_session_dirty(QofBook *book)
The qof_book_mark_dirty() routine marks the book as having been modified.
Definition: qofbook.cpp:397
GList * qof_instance_get_referring_object_list(const QofInstance *inst)
Returns a list of objects which refer to a specific object.
QofIdType qof_collection_get_type(const QofCollection *col)
return the type that the collection stores
Definition: qofid.cpp:73
QofIdType e_type
Entity type.
Definition: qofinstance.h:75
const GncGUID * guid_null(void)
Returns a GncGUID which is guaranteed to never reference any entity.
Definition: guid.cpp:130
void qof_instance_set_book(gconstpointer inst, QofBook *book)
Set the book pointer.
gint qof_instance_guid_compare(gconstpointer ptr1, gconstpointer ptr2)
Compare the GncGUID values of two instances.
QofCollection * qof_book_get_collection(const QofBook *book, QofIdType entity_type)
Return The table of entities of the given type.
Definition: qofbook.cpp:521
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
Definition: gnc-date.h:87
gboolean qof_instance_refers_to_object(const QofInstance *inst, const QofInstance *ref)
Does this object refer to a specific object.
gboolean qof_instance_has_kvp(QofInstance *inst)
Report whether a QofInstance has anything stored in KVP.
QofBackend * qof_book_get_backend(const QofBook *book)
Retrieve the backend used by this book.
Definition: qofbook.cpp:440
The type used to store guids in C.
Definition: guid.h:75
QofCollection * collection
Entity collection.
Definition: qofinstance.cpp:76
gchar * qof_instance_get_display_name(const QofInstance *inst)
Returns a displayable name for this object.