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  * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
00019  * Boston, MA  02111-1307,  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 "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 /* constructor / destructor */
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,  /* key_destroy_func   */
00073       coll_destroy);                            /* value_destroy_func */
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   /* Call the list of finalizers, let them do their thing. 
00120    * Do this before tearing into the rest of the book.
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 /* XXX this should probably be calling is_equal callbacks on gncObject */
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 /* getters */
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 /* setters */
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 /* Store arbitrary pointers in the QofBook for data storage extensibility */
00208 /* XXX if data is NULL, we should remove the key from the hash table!
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   /* If we've got a backend with a counter method, call it */
00339   be = book->backend;
00340   if (be && be->counter)
00341     return ((be->counter)(be, counter_name));
00342 
00343   /* If not, then use the KVP in the book */
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     /* found it */
00354     counter = kvp_value_get_gint64 (value);
00355   } else {
00356     /* New counter */
00357     counter = 0;
00358   }
00359 
00360   /* Counter is now valid; increment it */
00361   counter++;
00362 
00363   /* Save off the new counter */
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   /* and return the value */
00369   return counter;
00370 }
00371 
00372 /* QofObject function implementation and registration */
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 /* ========================== END OF FILE =============================== */

Generated on Fri Oct 21 15:49:55 2005 for QOF by  doxygen 1.4.5