qofbook.c

00001 /********************************************************************\
00002  * qofbook.c -- dataset access (set of books of entities)           *
00003  *                                                                  *
00004  * This program is free software; you can redistribute it and/or    *
00005  * modify it under the terms of the GNU General Public License as   *
00006  * published by the Free Software Foundation; either version 2 of   *
00007  * the License, or (at your option) any later version.              *
00008  *                                                                  *
00009  * This program is distributed in the hope that it will be useful,  *
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
00012  * GNU General Public License for more details.                     *
00013  *                                                                  *
00014  * You should have received a copy of the GNU General Public License*
00015  * along with this program; if not, contact:                        *
00016  *                                                                  *
00017  * Free Software Foundation           Voice:  +1-617-542-5942       *
00018  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
00019  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
00020 \********************************************************************/
00021 
00022 /*
00023  * FILE:
00024  * qofbook.c
00025  *
00026  * FUNCTION:
00027  * Encapsulate all the information about a QOF dataset.
00028  *
00029  * HISTORY:
00030  * Created by Linas Vepstas December 1998
00031  * Copyright (c) 1998-2001,2003 Linas Vepstas <linas@linas.org>
00032  * Copyright (c) 2000 Dave Peticolas
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 /* constructor / destructor */
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,  /* key_destroy_func   */
00067       coll_destroy);                            /* value_destroy_func */
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   /* Call the list of finalizers, let them do their thing. 
00114    * Do this before tearing into the rest of the book.
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 /* XXX this should probably be calling is_equal callbacks on gncObject */
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 /* getters */
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 /* setters */
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 /* Store arbitrary pointers in the QofBook for data storage extensibility */
00202 /* XXX if data is NULL, we should remove the key from the hash table!
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   /* If we've got a backend with a counter method, call it */
00333   be = book->backend;
00334   if (be && be->counter)
00335     return ((be->counter)(be, counter_name));
00336 
00337   /* If not, then use the KVP in the book */
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     /* found it */
00348     counter = kvp_value_get_gint64 (value);
00349   } else {
00350     /* New counter */
00351     counter = 0;
00352   }
00353 
00354   /* Counter is now valid; increment it */
00355   counter++;
00356 
00357   /* Save off the new counter */
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   /* and return the value */
00363   return counter;
00364 }
00365 
00366 /* QofObject function implementation and registration */
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 /* ========================== END OF FILE =============================== */

Generated on Fri May 12 18:00:32 2006 for QOF by  doxygen 1.4.4