00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "config.h"
00032 #include <glib.h>
00033 #include "qof.h"
00034 #include "kvp-util-p.h"
00035 #include "qofbook-p.h"
00036 #include "qofid-p.h"
00037 #include "qofinstance-p.h"
00038
00039 static QofLogModule log_module = QOF_MOD_ENGINE;
00040
00041
00042
00043 enum {
00044 LAST_SIGNAL
00045 };
00046
00047 enum {
00048 PROP_0,
00049 PROP_TYPE,
00050 PROP_GUID,
00051 PROP_COLLECTION,
00052 PROP_BOOK,
00053 PROP_KVP_DATA,
00054 PROP_LAST_UPDATE,
00055 PROP_EDITLEVEL,
00056 PROP_DESTROYING,
00057 PROP_DIRTY,
00058 PROP_INFANT,
00059
00060 PROP_VERSION,
00061 PROP_VERSION_CHECK,
00062 PROP_IDATA,
00063 };
00064
00065 typedef struct QofInstancePrivate
00066 {
00067
00068 GUID guid;
00069 QofCollection *collection;
00071
00072 QofBook * book;
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 Timespec last_update;
00087
00088
00089 int editlevel;
00090
00091
00092 gboolean do_free;
00093
00094
00095
00096
00097 gboolean dirty;
00098
00099
00100 gboolean infant;
00101
00102
00103 gint32 version;
00104 guint32 version_check;
00105
00106
00107
00108 guint32 idata;
00109 } QofInstancePrivate;
00110
00111 #define GET_PRIVATE(o) \
00112 (G_TYPE_INSTANCE_GET_PRIVATE ((o), QOF_TYPE_INSTANCE, QofInstancePrivate))
00113
00114 QOF_GOBJECT_GET_TYPE(QofInstance, qof_instance, G_TYPE_OBJECT, {});
00115 QOF_GOBJECT_FINALIZE(qof_instance);
00116
00117 static void qof_instance_get_property (GObject *object,
00118 guint prop_id,
00119 GValue *value,
00120 GParamSpec *pspec);
00121 static void qof_instance_set_property (GObject *object,
00122 guint prop_id,
00123 const GValue *value,
00124 GParamSpec *pspec);
00125 static void qof_instance_dispose(GObject*);
00126 static void qof_instance_class_init(QofInstanceClass *klass)
00127 {
00128 GObjectClass *object_class = G_OBJECT_CLASS(klass);
00129 object_class->finalize = qof_instance_finalize;
00130 object_class->dispose = qof_instance_dispose;
00131 object_class->set_property = qof_instance_set_property;
00132 object_class->get_property = qof_instance_get_property;
00133
00134 g_type_class_add_private(klass, sizeof(QofInstancePrivate));
00135
00136 g_object_class_install_property
00137 (object_class,
00138 PROP_GUID,
00139 g_param_spec_boxed ("guid",
00140 "Object GUID",
00141 "The object Globally Unique ID.",
00142 GNC_TYPE_GUID,
00143 G_PARAM_READWRITE));
00144
00145 g_object_class_install_property
00146 (object_class,
00147 PROP_COLLECTION,
00148 g_param_spec_pointer ("collection",
00149 "Object Collection",
00150 "A collection of like objects of which this "
00151 "particular object is amember. E.g.. A "
00152 "collection of accounts, or a collection of "
00153 "splits.",
00154 G_PARAM_READWRITE));
00155
00156 g_object_class_install_property
00157 (object_class,
00158 PROP_BOOK,
00159 g_param_spec_object ("book",
00160 "Object Book",
00161 "The book that contains this object.",
00162 QOF_TYPE_BOOK,
00163 G_PARAM_READWRITE));
00164
00165 g_object_class_install_property
00166 (object_class,
00167 PROP_KVP_DATA,
00168 g_param_spec_pointer ("kvp-data",
00169 "Object KVP Data",
00170 "A pointer to the key-value data associated "
00171 "with this object.",
00172 G_PARAM_READWRITE));
00173
00174 g_object_class_install_property
00175 (object_class,
00176 PROP_LAST_UPDATE,
00177 g_param_spec_pointer ("last-update",
00178 "Object Last Update",
00179 "A pointer to the last time this object was "
00180 "updated. This value is present for use by "
00181 "backends and shouldnot be written by other "
00182 "code.",
00183 G_PARAM_READWRITE));
00184
00185 g_object_class_install_property
00186 (object_class,
00187 PROP_EDITLEVEL,
00188 g_param_spec_int ("editlevel",
00189 "Object Edit Level",
00190 "The object edit level.",
00191 0, G_MAXINT32, 0,
00192 G_PARAM_READABLE));
00193
00194 g_object_class_install_property
00195 (object_class,
00196 PROP_DESTROYING,
00197 g_param_spec_boolean ("destroying",
00198 "Object Destroying",
00199 "This flag is set to TRUE if the object is "
00200 "about to be destroyed.",
00201 FALSE,
00202 G_PARAM_READWRITE));
00203
00204 g_object_class_install_property
00205 (object_class,
00206 PROP_DIRTY,
00207 g_param_spec_boolean ("dirty",
00208 "Object Dirty",
00209 "This flag is set to TRUE if the object has "
00210 "unsaved changes.",
00211 FALSE,
00212 G_PARAM_READWRITE));
00213
00214 g_object_class_install_property
00215 (object_class,
00216 PROP_INFANT,
00217 g_param_spec_boolean ("infant",
00218 "Object Infant",
00219 "This flag is set to TRUE if the object has "
00220 "never been added to a book. This implies "
00221 "that its destruction does not affect the "
00222 "state of the book, and therefore the saved "
00223 "state of the data file.",
00224 FALSE,
00225 G_PARAM_READABLE));
00226
00227 g_object_class_install_property
00228 (object_class,
00229 PROP_VERSION,
00230 g_param_spec_int ("version",
00231 "Version",
00232 "The version number of the current instance state.",
00233 0,
00234 G_MAXINT32,
00235 0,
00236 G_PARAM_READWRITE));
00237
00238 g_object_class_install_property
00239 (object_class,
00240 PROP_VERSION_CHECK,
00241 g_param_spec_uint ("version-check",
00242 "Version Check",
00243 "The version check number of the current instance state.",
00244 0,
00245 G_MAXUINT32,
00246 0,
00247 G_PARAM_READWRITE));
00248
00249 g_object_class_install_property
00250 (object_class,
00251 PROP_EDITLEVEL,
00252 g_param_spec_uint ("idata",
00253 "Object IData",
00254 "Per instance backend private data.",
00255 0, G_MAXUINT32, 0,
00256 G_PARAM_READWRITE));
00257 }
00258
00259 static void
00260 qof_instance_init (QofInstance *inst)
00261 {
00262 QofInstancePrivate *priv;
00263
00264 priv = GET_PRIVATE(inst);
00265 priv->book = NULL;
00266 inst->kvp_data = kvp_frame_new();
00267 priv->last_update.tv_sec = 0;
00268 priv->last_update.tv_nsec = -1;
00269 priv->editlevel = 0;
00270 priv->do_free = FALSE;
00271 priv->dirty = FALSE;
00272 priv->infant = TRUE;
00273 }
00274
00275 void
00276 qof_instance_init_data (QofInstance *inst, QofIdType type, QofBook *book)
00277 {
00278 QofInstancePrivate *priv;
00279 QofCollection *col;
00280 QofIdType col_type;
00281
00282 g_return_if_fail(QOF_IS_INSTANCE(inst));
00283 priv = GET_PRIVATE(inst);
00284 g_return_if_fail(!priv->book);
00285
00286 priv->book = book;
00287 col = qof_book_get_collection (book, type);
00288 g_return_if_fail(col != NULL);
00289
00290
00291
00292
00293 col_type = qof_collection_get_type(col);
00294 if (safe_strcmp(col_type, type)) {
00295 PERR ("attempt to insert \"%s\" into \"%s\"", type, col_type);
00296 return;
00297 }
00298 priv = GET_PRIVATE(inst);
00299 inst->e_type = CACHE_INSERT (type);
00300
00301 do {
00302 guid_new(&priv->guid);
00303
00304 if (NULL == qof_collection_lookup_entity (col, &priv->guid))
00305 break;
00306
00307 PWARN("duplicate id created, trying again");
00308 } while(1);
00309
00310 priv->collection = col;
00311
00312 qof_collection_insert_entity (col, inst);
00313 }
00314
00315 static void
00316 qof_instance_dispose (GObject *instp)
00317 {
00318 QofInstancePrivate *priv;
00319 QofInstance* inst = QOF_INSTANCE(instp);
00320
00321 priv = GET_PRIVATE(instp);
00322 if (!priv->collection)
00323 return;
00324 qof_collection_remove_entity(inst);
00325
00326 CACHE_REMOVE(inst->e_type);
00327 inst->e_type = NULL;
00328
00329 G_OBJECT_CLASS(qof_instance_parent_class)->dispose(instp);
00330 }
00331
00332 static void
00333 qof_instance_finalize_real (GObject *instp)
00334 {
00335 QofInstancePrivate *priv;
00336 QofInstance* inst = QOF_INSTANCE(instp);
00337
00338 kvp_frame_delete (inst->kvp_data);
00339 inst->kvp_data = NULL;
00340
00341 priv = GET_PRIVATE(inst);
00342 priv->editlevel = 0;
00343 priv->do_free = FALSE;
00344 priv->dirty = FALSE;
00345 }
00346
00347 static void
00348 qof_instance_get_property (GObject *object,
00349 guint prop_id,
00350 GValue *value,
00351 GParamSpec *pspec)
00352 {
00353 QofInstance *inst;
00354 QofInstancePrivate *priv;
00355
00356 g_return_if_fail(QOF_IS_INSTANCE(object));
00357
00358 inst = QOF_INSTANCE(object);
00359 priv = GET_PRIVATE(inst);
00360
00361 switch (prop_id) {
00362 case PROP_GUID:
00363 g_value_set_boxed(value, &priv->guid);
00364 break;
00365 case PROP_COLLECTION:
00366 g_value_set_pointer(value, priv->collection);
00367 break;
00368 case PROP_BOOK:
00369 g_value_set_object(value, priv->book);
00370 break;
00371 case PROP_KVP_DATA:
00372 g_value_set_pointer(value, inst->kvp_data);
00373 break;
00374 case PROP_LAST_UPDATE:
00375 g_value_set_pointer(value, &priv->last_update);
00376 break;
00377 case PROP_EDITLEVEL:
00378 g_value_set_int(value, priv->editlevel);
00379 break;
00380 case PROP_DESTROYING:
00381 g_value_set_boolean(value, priv->do_free);
00382 break;
00383 case PROP_DIRTY:
00384 g_value_set_boolean(value, qof_instance_get_dirty(inst));
00385 break;
00386 case PROP_INFANT:
00387 g_value_set_boolean(value, priv->infant);
00388 break;
00389 case PROP_VERSION:
00390 g_value_set_int(value, priv->version);
00391 break;
00392 case PROP_VERSION_CHECK:
00393 g_value_set_uint(value, priv->version_check);
00394 break;
00395 case PROP_IDATA:
00396 g_value_set_uint(value, priv->idata);
00397 break;
00398 default:
00399 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
00400 break;
00401 }
00402 }
00403
00404 static void
00405 qof_instance_set_property (GObject *object,
00406 guint prop_id,
00407 const GValue *value,
00408 GParamSpec *pspec)
00409 {
00410 QofInstance *inst;
00411 QofInstancePrivate *priv;
00412 Timespec *ts;
00413
00414 g_return_if_fail(QOF_IS_INSTANCE(object));
00415
00416 inst = QOF_INSTANCE(object);
00417 priv = GET_PRIVATE(inst);
00418
00419 switch (prop_id) {
00420 case PROP_GUID:
00421 qof_instance_set_guid(inst, g_value_get_boxed(value));
00422 break;
00423 case PROP_COLLECTION:
00424 qof_instance_set_collection(inst, g_value_get_pointer(value));
00425 break;
00426 case PROP_BOOK:
00427 qof_instance_set_book(inst, g_value_get_object(value));
00428 break;
00429 case PROP_KVP_DATA:
00430 qof_instance_set_slots(inst, g_value_get_pointer(value));
00431 break;
00432 case PROP_LAST_UPDATE:
00433 ts = g_value_get_pointer(value);
00434 qof_instance_set_last_update(inst, *ts);
00435 break;
00436 case PROP_DESTROYING:
00437 qof_instance_set_destroying(inst, g_value_get_boolean(value));
00438 break;
00439 case PROP_DIRTY:
00440 qof_instance_set_dirty(inst);
00441 break;
00442 case PROP_VERSION:
00443 qof_instance_set_version(inst, g_value_get_int(value));
00444 break;
00445 case PROP_VERSION_CHECK:
00446 qof_instance_set_version_check(inst, g_value_get_uint(value));
00447 break;
00448 case PROP_IDATA:
00449 qof_instance_set_idata(inst, g_value_get_uint(value));
00450 break;
00451 default:
00452 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
00453 break;
00454 }
00455 }
00456
00457 const GUID *
00458 qof_instance_get_guid (gconstpointer inst)
00459 {
00460 QofInstancePrivate *priv;
00461
00462 if (!inst) return NULL;
00463 g_return_val_if_fail(QOF_IS_INSTANCE(inst), guid_null());
00464 priv = GET_PRIVATE(inst);
00465 return &(priv->guid);
00466 }
00467
00468 const GUID *
00469 qof_entity_get_guid (gconstpointer ent)
00470 {
00471 return ent ? qof_instance_get_guid(ent) : guid_null();
00472 }
00473
00474 void
00475 qof_instance_set_guid (gpointer ptr, const GUID *guid)
00476 {
00477 QofInstancePrivate *priv;
00478 QofInstance *inst;
00479 QofCollection *col;
00480
00481 g_return_if_fail(QOF_IS_INSTANCE(ptr));
00482
00483 inst = QOF_INSTANCE(ptr);
00484 priv = GET_PRIVATE(inst);
00485 if (guid_equal (guid, &priv->guid))
00486 return;
00487
00488 col = priv->collection;
00489 qof_collection_remove_entity(inst);
00490 priv->guid = *guid;
00491 qof_collection_insert_entity(col, inst);
00492 }
00493
00494 void
00495 qof_instance_copy_guid (gpointer to, gconstpointer from)
00496 {
00497 g_return_if_fail(QOF_IS_INSTANCE(to));
00498 g_return_if_fail(QOF_IS_INSTANCE(from));
00499
00500 GET_PRIVATE(to)->guid = GET_PRIVATE(from)->guid;
00501 }
00502
00503 gint
00504 qof_instance_guid_compare(gconstpointer ptr1, gconstpointer ptr2)
00505 {
00506 const QofInstancePrivate *priv1, *priv2;
00507
00508 g_return_val_if_fail(QOF_IS_INSTANCE(ptr1), -1);
00509 g_return_val_if_fail(QOF_IS_INSTANCE(ptr2), 1);
00510
00511 priv1 = GET_PRIVATE(ptr1);
00512 priv2 = GET_PRIVATE(ptr2);
00513
00514 return guid_compare(&priv1->guid, &priv2->guid);
00515 }
00516
00517 QofCollection *
00518 qof_instance_get_collection (gconstpointer ptr)
00519 {
00520
00521 g_return_val_if_fail(QOF_IS_INSTANCE(ptr), NULL);
00522 return GET_PRIVATE(ptr)->collection;
00523 }
00524
00525 void
00526 qof_instance_set_collection (gconstpointer ptr, QofCollection *col)
00527 {
00528 g_return_if_fail(QOF_IS_INSTANCE(ptr));
00529 GET_PRIVATE(ptr)->collection = col;
00530 }
00531
00532 QofBook *
00533 qof_instance_get_book (gconstpointer inst)
00534 {
00535 if (!inst) return NULL;
00536 g_return_val_if_fail(QOF_IS_INSTANCE(inst), NULL);
00537 return GET_PRIVATE(inst)->book;
00538 }
00539
00540 void
00541 qof_instance_set_book (gconstpointer inst, QofBook *book)
00542 {
00543 g_return_if_fail(QOF_IS_INSTANCE(inst));
00544 GET_PRIVATE(inst)->book = book;
00545 }
00546
00547 void
00548 qof_instance_copy_book (gpointer ptr1, gconstpointer ptr2)
00549 {
00550 g_return_if_fail(QOF_IS_INSTANCE(ptr1));
00551 g_return_if_fail(QOF_IS_INSTANCE(ptr2));
00552
00553 GET_PRIVATE(ptr1)->book = GET_PRIVATE(ptr2)->book;
00554 }
00555
00556 gboolean
00557 qof_instance_books_equal (gconstpointer ptr1, gconstpointer ptr2)
00558 {
00559 const QofInstancePrivate *priv1, *priv2;
00560
00561 g_return_val_if_fail(QOF_IS_INSTANCE(ptr1), FALSE);
00562 g_return_val_if_fail(QOF_IS_INSTANCE(ptr2), FALSE);
00563
00564 priv1 = GET_PRIVATE(ptr1);
00565 priv2 = GET_PRIVATE(ptr2);
00566
00567 return (priv1->book == priv2->book);
00568 }
00569
00570 KvpFrame*
00571 qof_instance_get_slots (const QofInstance *inst)
00572 {
00573 if (!inst) return NULL;
00574 return inst->kvp_data;
00575 }
00576
00577 void
00578 qof_instance_set_slots (QofInstance *inst, KvpFrame *frm)
00579 {
00580 QofInstancePrivate *priv;
00581
00582 if (!inst) return;
00583
00584 priv = GET_PRIVATE(inst);
00585 if (inst->kvp_data && (inst->kvp_data != frm)) {
00586 kvp_frame_delete(inst->kvp_data);
00587 }
00588
00589 priv->dirty = TRUE;
00590 inst->kvp_data = frm;
00591 }
00592
00593 Timespec
00594 qof_instance_get_last_update (const QofInstance *inst)
00595 {
00596 if (!inst) {
00597 Timespec ts = {0,-1};
00598 return ts;
00599 }
00600 return GET_PRIVATE(inst)->last_update;
00601 }
00602
00603 void
00604 qof_instance_set_last_update (QofInstance *inst, Timespec ts)
00605 {
00606 if (!inst) return;
00607 GET_PRIVATE(inst)->last_update = ts;
00608 }
00609
00610 gint
00611 qof_instance_get_editlevel (gconstpointer ptr)
00612 {
00613 g_return_val_if_fail(QOF_IS_INSTANCE(ptr), 0);
00614 return GET_PRIVATE(ptr)->editlevel;
00615 }
00616
00617 void qof_instance_increase_editlevel (gpointer ptr)
00618 {
00619 g_return_if_fail(QOF_IS_INSTANCE(ptr));
00620 GET_PRIVATE(ptr)->editlevel++;
00621 }
00622
00623 void qof_instance_decrease_editlevel (gpointer ptr)
00624 {
00625 g_return_if_fail(QOF_IS_INSTANCE(ptr));
00626 GET_PRIVATE(ptr)->editlevel--;
00627 }
00628
00629 void qof_instance_reset_editlevel (gpointer ptr)
00630 {
00631 g_return_if_fail(QOF_IS_INSTANCE(ptr));
00632 GET_PRIVATE(ptr)->editlevel = 0;
00633 }
00634
00635 gboolean
00636 qof_instance_check_edit(const QofInstance *inst)
00637 {
00638 g_return_val_if_fail(QOF_IS_INSTANCE(inst), FALSE);
00639 return (GET_PRIVATE(inst)->editlevel > 0);
00640 }
00641
00642 int
00643 qof_instance_version_cmp (const QofInstance *left, const QofInstance *right)
00644 {
00645 QofInstancePrivate *lpriv, *rpriv;
00646
00647 if (!left && !right) return 0;
00648 if (!left) return -1;
00649 if (!right) return +1;
00650
00651 lpriv = GET_PRIVATE(left);
00652 rpriv = GET_PRIVATE(right);
00653 if (lpriv->last_update.tv_sec < rpriv->last_update.tv_sec) return -1;
00654 if (lpriv->last_update.tv_sec > rpriv->last_update.tv_sec) return +1;
00655 if (lpriv->last_update.tv_nsec < rpriv->last_update.tv_nsec) return -1;
00656 if (lpriv->last_update.tv_nsec > rpriv->last_update.tv_nsec) return +1;
00657 return 0;
00658 }
00659
00660 gboolean
00661 qof_instance_get_destroying (gconstpointer ptr)
00662 {
00663 g_return_val_if_fail(QOF_IS_INSTANCE(ptr), FALSE);
00664 return GET_PRIVATE(ptr)->do_free;
00665 }
00666
00667 void
00668 qof_instance_set_destroying (gpointer ptr, gboolean value)
00669 {
00670 g_return_if_fail(QOF_IS_INSTANCE(ptr));
00671 GET_PRIVATE(ptr)->do_free = value;
00672 }
00673
00674 gboolean
00675 qof_instance_get_dirty_flag (gconstpointer ptr)
00676 {
00677 g_return_val_if_fail(QOF_IS_INSTANCE(ptr), FALSE);
00678 return GET_PRIVATE(ptr)->dirty;
00679 }
00680
00681 void
00682 qof_instance_set_dirty_flag (gconstpointer inst, gboolean flag)
00683 {
00684 g_return_if_fail(QOF_IS_INSTANCE(inst));
00685 GET_PRIVATE(inst)->dirty = flag;
00686 }
00687
00688 void
00689 qof_instance_mark_clean (QofInstance *inst)
00690 {
00691 if(!inst) return;
00692 GET_PRIVATE(inst)->dirty = FALSE;
00693 }
00694
00695 void
00696 qof_instance_print_dirty (const QofInstance *inst, gpointer dummy)
00697 {
00698 QofInstancePrivate *priv;
00699
00700 priv = GET_PRIVATE(inst);
00701 if (priv->dirty) {
00702 printf("%s instance %s is dirty.\n", inst->e_type,
00703 guid_to_string(&priv->guid));
00704 }
00705 }
00706
00707 gboolean
00708 qof_instance_get_dirty (QofInstance *inst)
00709 {
00710 QofInstancePrivate *priv;
00711 QofCollection *coll;
00712
00713 if (!inst) { return FALSE; }
00714
00715 priv = GET_PRIVATE(inst);
00716 if (qof_get_alt_dirty_mode())
00717 return priv->dirty;
00718 coll = priv->collection;
00719 if(qof_collection_is_dirty(coll)) { return priv->dirty; }
00720 priv->dirty = FALSE;
00721 return FALSE;
00722 }
00723
00724 void
00725 qof_instance_set_dirty(QofInstance* inst)
00726 {
00727 QofInstancePrivate *priv;
00728 QofCollection *coll;
00729
00730 priv = GET_PRIVATE(inst);
00731 priv->dirty = TRUE;
00732 if (!qof_get_alt_dirty_mode()) {
00733 coll = priv->collection;
00734 qof_collection_mark_dirty(coll);
00735 }
00736 }
00737
00738 gboolean
00739 qof_instance_get_infant(const QofInstance *inst)
00740 {
00741 g_return_val_if_fail(QOF_IS_INSTANCE(inst), FALSE);
00742 return GET_PRIVATE(inst)->infant;
00743 }
00744
00745 gint32
00746 qof_instance_get_version (gconstpointer inst)
00747 {
00748 g_return_val_if_fail(QOF_IS_INSTANCE(inst), 0);
00749 return GET_PRIVATE(inst)->version;
00750 }
00751
00752 gint
00753 qof_instance_compare_version (gconstpointer inst1, gconstpointer inst2)
00754 {
00755 g_return_val_if_fail(QOF_IS_INSTANCE(inst1), 1);
00756 g_return_val_if_fail(QOF_IS_INSTANCE(inst2), -1);
00757 return GET_PRIVATE(inst2)->version - GET_PRIVATE(inst1)->version;
00758 }
00759
00760 void
00761 qof_instance_set_version (gpointer inst, gint32 vers)
00762 {
00763 g_return_if_fail(QOF_IS_INSTANCE(inst));
00764 GET_PRIVATE(inst)->version = vers;
00765 }
00766
00767 void
00768 qof_instance_copy_version (gpointer to, gconstpointer from)
00769 {
00770 g_return_if_fail(QOF_IS_INSTANCE(to));
00771 g_return_if_fail(QOF_IS_INSTANCE(from));
00772 GET_PRIVATE(to)->version = GET_PRIVATE(from)->version;
00773 }
00774
00775 void
00776 qof_instance_increment_version (gpointer inst, guint32 new_check)
00777 {
00778 QofInstancePrivate *priv;
00779
00780 g_return_if_fail(QOF_IS_INSTANCE(inst));
00781
00782 priv = GET_PRIVATE(inst);
00783 priv->version++;
00784 priv->version_check = new_check;
00785 }
00786
00787 guint32
00788 qof_instance_get_version_check (gconstpointer inst)
00789 {
00790 g_return_val_if_fail(QOF_IS_INSTANCE(inst), 0);
00791 return GET_PRIVATE(inst)->version_check;
00792 }
00793
00794 void
00795 qof_instance_set_version_check (gpointer inst, guint32 value)
00796 {
00797 g_return_if_fail(QOF_IS_INSTANCE(inst));
00798 GET_PRIVATE(inst)->version_check = value;
00799 }
00800
00801 void
00802 qof_instance_copy_version_check (gpointer to, gconstpointer from)
00803 {
00804 g_return_if_fail(QOF_IS_INSTANCE(to));
00805 g_return_if_fail(QOF_IS_INSTANCE(from));
00806 GET_PRIVATE(to)->version_check = GET_PRIVATE(from)->version_check;
00807 }
00808
00809 guint32 qof_instance_get_idata (gconstpointer inst)
00810 {
00811 if(!inst) { return 0; }
00812 g_return_val_if_fail(QOF_IS_INSTANCE(inst), 0);
00813 return GET_PRIVATE(inst)->idata;
00814 }
00815
00816 void qof_instance_set_idata(gpointer inst, guint32 idata)
00817 {
00818 if(!inst) { return; }
00819 if(idata < 0) { return; }
00820 g_return_if_fail(QOF_IS_INSTANCE(inst));
00821 GET_PRIVATE(inst)->idata = idata;
00822 }
00823
00824
00825
00826 void
00827 qof_instance_gemini (QofInstance *to, const QofInstance *from)
00828 {
00829 QofInstancePrivate *from_priv, *to_priv, *fb_priv, *tb_priv;
00830 time_t now;
00831
00832 g_return_if_fail(QOF_IS_INSTANCE(to));
00833 g_return_if_fail(QOF_IS_INSTANCE(from));
00834
00835 from_priv = GET_PRIVATE(from);
00836 to_priv = GET_PRIVATE(to);
00837 fb_priv = GET_PRIVATE(from_priv->book);
00838 tb_priv = GET_PRIVATE(to_priv->book);
00839
00840
00841 if (from_priv->book == to_priv->book)
00842 return;
00843
00844 now = time(0);
00845
00846
00847 gnc_kvp_bag_add (to->kvp_data, "gemini", now,
00848 "inst_guid", &from_priv->guid,
00849 "book_guid", &fb_priv->guid,
00850 NULL);
00851 gnc_kvp_bag_add (from->kvp_data, "gemini", now,
00852 "inst_guid", &to_priv->guid,
00853 "book_guid", &tb_priv->guid,
00854 NULL);
00855
00856 to_priv->dirty = TRUE;
00857 }
00858
00859 QofInstance *
00860 qof_instance_lookup_twin (const QofInstance *src, QofBook *target_book)
00861 {
00862 QofCollection *col;
00863 KvpFrame *fr;
00864 GUID * twin_guid;
00865 QofInstance * twin;
00866 QofInstancePrivate *bpriv;
00867
00868 if (!src || !target_book) return NULL;
00869 ENTER (" ");
00870
00871 bpriv = GET_PRIVATE(QOF_INSTANCE(target_book));
00872 fr = gnc_kvp_bag_find_by_guid (src->kvp_data, "gemini",
00873 "book_guid", &bpriv->guid);
00874
00875 twin_guid = kvp_frame_get_guid (fr, "inst_guid");
00876
00877 col = qof_book_get_collection (target_book, src->e_type);
00878 twin = (QofInstance *) qof_collection_lookup_entity (col, twin_guid);
00879
00880 LEAVE (" found twin=%p", twin);
00881 return twin;
00882 }
00883
00884
00885
00886
00887
00888 gboolean
00889 qof_begin_edit (QofInstance *inst)
00890 {
00891 QofInstancePrivate *priv;
00892 QofBackend * be;
00893
00894 if (!inst) return FALSE;
00895
00896 priv = GET_PRIVATE(inst);
00897 priv->editlevel++;
00898 if (1 < priv->editlevel) return FALSE;
00899 if (0 >= priv->editlevel)
00900 priv->editlevel = 1;
00901
00902 be = qof_book_get_backend(priv->book);
00903 if (be && qof_backend_begin_exists(be))
00904 qof_backend_run_begin(be, inst);
00905 else
00906 priv->dirty = TRUE;
00907
00908 return TRUE;
00909 }
00910
00911 gboolean qof_commit_edit (QofInstance *inst)
00912 {
00913 QofInstancePrivate *priv;
00914 QofBackend * be;
00915
00916 if (!inst) return FALSE;
00917
00918 priv = GET_PRIVATE(inst);
00919 priv->editlevel--;
00920 if (0 < priv->editlevel) return FALSE;
00921
00922 if ((0 == priv->editlevel) && priv->dirty) {
00923 be = qof_book_get_backend(priv->book);
00924 if (be && qof_backend_commit_exists(be)) {
00925 qof_backend_run_commit(be, inst);
00926 }
00927 }
00928 if (0 > priv->editlevel) {
00929 PERR ("unbalanced call - resetting (was %d)", priv->editlevel);
00930 priv->editlevel = 0;
00931 }
00932 return TRUE;
00933 }
00934
00935 gboolean
00936 qof_commit_edit_part2(QofInstance *inst,
00937 void (*on_error)(QofInstance *, QofBackendError),
00938 void (*on_done)(QofInstance *),
00939 void (*on_free)(QofInstance *))
00940 {
00941 QofInstancePrivate *priv;
00942 QofBackend * be;
00943 gboolean dirty;
00944
00945 priv = GET_PRIVATE(inst);
00946 dirty = priv->dirty;
00947
00948
00949 be = qof_book_get_backend(priv->book);
00950 if (be && qof_backend_commit_exists(be)) {
00951 QofBackendError errcode;
00952
00953
00954 do {
00955 errcode = qof_backend_get_error(be);
00956 } while (ERR_BACKEND_NO_ERR != errcode);
00957
00958 qof_backend_run_commit(be, inst);
00959 errcode = qof_backend_get_error(be);
00960 if (ERR_BACKEND_NO_ERR != errcode) {
00961
00962 priv->do_free = FALSE;
00963
00964
00965 qof_backend_set_error (be, errcode);
00966 if (on_error)
00967 on_error(inst, errcode);
00968 return FALSE;
00969 }
00970
00971 priv->dirty = FALSE;
00972 }
00973
00974
00975
00976
00977
00978 priv->infant = FALSE;
00979
00980 if (priv->do_free) {
00981 if (on_free)
00982 on_free(inst);
00983 return TRUE;
00984 }
00985
00986 if (on_done)
00987 on_done(inst);
00988 return TRUE;
00989 }
00990
00991
00992
00993
00994
00995
00996
00997
00998