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
00032
00033
00034
00035 #include "config.h"
00036
00037 #include <stdlib.h>
00038 #include <string.h>
00039
00040 #include <glib.h>
00041
00042 #include "gnc-event.h"
00043 #include "gnc-event-p.h"
00044 #include "gnc-trace.h"
00045 #include "qofbackend-p.h"
00046 #include "qofbook.h"
00047 #include "qofbook-p.h"
00048 #include "qofclass.h"
00049 #include "qofid-p.h"
00050 #include "qofobject-p.h"
00051 #include "gnc-engine-util.h"
00052
00053 #include "guid.h"
00054
00055 static QofLogModule log_module = QOF_MOD_ENGINE;
00056
00057
00058
00059
00060 static void coll_destroy(gpointer col)
00061 {
00062 qof_collection_destroy((QofCollection *) col);
00063 }
00064
00065 static void
00066 qof_book_init (QofBook *book)
00067 {
00068 if (!book) return;
00069
00070 book->hash_of_collections = g_hash_table_new_full(
00071 g_str_hash, g_str_equal,
00072 (GDestroyNotify)gnc_string_cache_remove,
00073 coll_destroy);
00074
00075 qof_instance_init (&book->inst, QOF_ID_BOOK, book);
00076
00077 book->data_tables = g_hash_table_new (g_str_hash, g_str_equal);
00078 book->data_table_finalizers = g_hash_table_new (g_str_hash, g_str_equal);
00079
00080 book->book_open = 'y';
00081 book->version = 0;
00082 book->idata = 0;
00083 }
00084
00085 QofBook *
00086 qof_book_new (void)
00087 {
00088 QofBook *book;
00089
00090 ENTER (" ");
00091 book = g_new0(QofBook, 1);
00092 qof_book_init(book);
00093 qof_object_book_begin (book);
00094
00095 gnc_engine_gen_event (&book->inst.entity, GNC_EVENT_CREATE);
00096 LEAVE ("book=%p", book);
00097 return book;
00098 }
00099
00100 static void
00101 book_final (gpointer key, gpointer value, gpointer booq)
00102 {
00103 QofBookFinalCB cb = value;
00104 QofBook *book = booq;
00105
00106 gpointer user_data = g_hash_table_lookup (book->data_tables, key);
00107 (*cb) (book, key, user_data);
00108 }
00109
00110 void
00111 qof_book_destroy (QofBook *book)
00112 {
00113 if (!book) return;
00114 ENTER ("book=%p", book);
00115
00116 book->shutting_down = TRUE;
00117 gnc_engine_force_event (&book->inst.entity, GNC_EVENT_DESTROY);
00118
00119
00120
00121
00122 g_hash_table_foreach (book->data_table_finalizers, book_final, book);
00123
00124 qof_object_book_end (book);
00125
00126 g_hash_table_destroy (book->data_table_finalizers);
00127 book->data_table_finalizers = NULL;
00128 g_hash_table_destroy (book->data_tables);
00129 book->data_tables = NULL;
00130
00131 qof_instance_release (&book->inst);
00132
00133 g_hash_table_destroy (book->hash_of_collections);
00134 book->hash_of_collections = NULL;
00135
00136 g_free (book);
00137 LEAVE ("book=%p", book);
00138 }
00139
00140
00141
00142
00143 gboolean
00144 qof_book_equal (QofBook *book_1, QofBook *book_2)
00145 {
00146 if (book_1 == book_2) return TRUE;
00147 if (!book_1 || !book_2) return FALSE;
00148 return TRUE;
00149 }
00150
00151
00152
00153 gboolean
00154 qof_book_not_saved(QofBook *book)
00155 {
00156 if (!book) return FALSE;
00157
00158 return(book->inst.dirty || qof_object_is_dirty (book));
00159 }
00160
00161 void
00162 qof_book_mark_saved(QofBook *book)
00163 {
00164 if (!book) return;
00165
00166 book->inst.dirty = FALSE;
00167 qof_object_mark_clean (book);
00168 }
00169
00170
00171
00172
00173 QofBackend *
00174 qof_book_get_backend (QofBook *book)
00175 {
00176 if (!book) return NULL;
00177 return book->backend;
00178 }
00179
00180 gboolean
00181 qof_book_shutting_down (QofBook *book)
00182 {
00183 if (!book) return FALSE;
00184 return book->shutting_down;
00185 }
00186
00187
00188
00189
00190 void
00191 qof_book_set_backend (QofBook *book, QofBackend *be)
00192 {
00193 if (!book) return;
00194 ENTER ("book=%p be=%p", book, be);
00195 book->backend = be;
00196 LEAVE (" ");
00197 }
00198
00199 void qof_book_kvp_changed (QofBook *book)
00200 {
00201 if (!book) return;
00202 book->inst.dirty = TRUE;
00203 }
00204
00205
00206
00207
00208
00209
00210 void
00211 qof_book_set_data (QofBook *book, const char *key, gpointer data)
00212 {
00213 if (!book || !key) return;
00214 g_hash_table_insert (book->data_tables, (gpointer)key, data);
00215 }
00216
00217 void
00218 qof_book_set_data_fin (QofBook *book, const char *key, gpointer data, QofBookFinalCB cb)
00219 {
00220 if (!book || !key) return;
00221 g_hash_table_insert (book->data_tables, (gpointer)key, data);
00222
00223 if (!cb) return;
00224 g_hash_table_insert (book->data_table_finalizers, (gpointer)key, cb);
00225 }
00226
00227 gpointer
00228 qof_book_get_data (QofBook *book, const char *key)
00229 {
00230 if (!book || !key) return NULL;
00231 return g_hash_table_lookup (book->data_tables, (gpointer)key);
00232 }
00233
00234
00235
00236 QofCollection *
00237 qof_book_get_collection (QofBook *book, QofIdType entity_type)
00238 {
00239 QofCollection *col;
00240
00241 if (!book || !entity_type) return NULL;
00242
00243 col = g_hash_table_lookup (book->hash_of_collections, entity_type);
00244 if (!col) {
00245 col = qof_collection_new (entity_type);
00246 g_hash_table_insert(
00247 book->hash_of_collections,
00248 gnc_string_cache_insert((gpointer) entity_type), col);
00249 }
00250 return col;
00251 }
00252
00253 struct _iterate {
00254 QofCollectionForeachCB fn;
00255 gpointer data;
00256 };
00257
00258 static void
00259 foreach_cb (gpointer key, gpointer item, gpointer arg)
00260 {
00261 struct _iterate *iter = arg;
00262 QofCollection *col = item;
00263
00264 iter->fn (col, iter->data);
00265 }
00266
00267 void
00268 qof_book_foreach_collection (QofBook *book,
00269 QofCollectionForeachCB cb, gpointer user_data)
00270 {
00271 struct _iterate iter;
00272
00273 g_return_if_fail (book);
00274 g_return_if_fail (cb);
00275
00276 iter.fn = cb;
00277 iter.data = user_data;
00278
00279 g_hash_table_foreach (book->hash_of_collections, foreach_cb, &iter);
00280 }
00281
00282
00283
00284 void qof_book_mark_closed (QofBook *book)
00285 {
00286 if(!book) { return; }
00287 book->book_open = 'n';
00288 }
00289
00290 gchar qof_book_get_open_marker(QofBook *book)
00291 {
00292 if(!book) { return 'n'; }
00293 return book->book_open;
00294 }
00295
00296 gint32 qof_book_get_version (QofBook *book)
00297 {
00298 if(!book) { return -1; }
00299 return book->version;
00300 }
00301
00302 guint32 qof_book_get_idata (QofBook *book)
00303 {
00304 if(!book) { return 0; }
00305 return book->idata;
00306 }
00307
00308 void qof_book_set_version (QofBook *book, gint32 version)
00309 {
00310 if(!book && version < 0) { return; }
00311 book->version = version;
00312 }
00313
00314 void qof_book_set_idata(QofBook *book, guint32 idata)
00315 {
00316 if(!book && idata < 0) { return; }
00317 book->idata = idata;
00318 }
00319
00320 gint64
00321 qof_book_get_counter (QofBook *book, const char *counter_name)
00322 {
00323 QofBackend *be;
00324 KvpFrame *kvp;
00325 KvpValue *value;
00326 gint64 counter;
00327
00328 if (!book) {
00329 PWARN ("No book!!!");
00330 return -1;
00331 }
00332
00333 if (!counter_name || *counter_name == '\0') {
00334 PWARN ("Invalid counter name.");
00335 return -1;
00336 }
00337
00338
00339 be = book->backend;
00340 if (be && be->counter)
00341 return ((be->counter)(be, counter_name));
00342
00343
00344 kvp = qof_book_get_slots (book);
00345
00346 if (!kvp) {
00347 PWARN ("Book has no KVP_Frame");
00348 return -1;
00349 }
00350
00351 value = kvp_frame_get_slot_path (kvp, "counters", counter_name, NULL);
00352 if (value) {
00353
00354 counter = kvp_value_get_gint64 (value);
00355 } else {
00356
00357 counter = 0;
00358 }
00359
00360
00361 counter++;
00362
00363
00364 value = kvp_value_new_gint64 (counter);
00365 kvp_frame_set_slot_path (kvp, value, "counters", counter_name, NULL);
00366 kvp_value_delete (value);
00367
00368
00369 return counter;
00370 }
00371
00372
00373 gboolean qof_book_register (void)
00374 {
00375 static QofParam params[] = {
00376 { QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_entity_get_guid, NULL },
00377 { QOF_PARAM_KVP, QOF_TYPE_KVP, (QofAccessFunc)qof_instance_get_slots, NULL },
00378 { NULL },
00379 };
00380
00381 qof_class_register (QOF_ID_BOOK, NULL, params);
00382
00383 return TRUE;
00384 }
00385
00386