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