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