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