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