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  * Copyright (c) 2006 Neil Williams <linux@codehelp.co.uk>
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     /* Call the list of finalizers, let them do their thing. 
00107      * Do this before tearing into the rest of the book.
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 /* call is_equal callbacks on QofObject ? */
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 /* Store arbitrary pointers in the QofBook for data storage extensibility */
00188 /* XXX if data is NULL, we should remove the key from the hash table!
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     /* If we've got a backend with a counter method, call it */
00343     be = book->backend;
00344     if (be && be->counter)
00345         return ((be->counter) (be, counter_name));
00346     /* If not, then use the KVP in the book */
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         /* found it */
00357         counter = kvp_value_get_gint64 (value);
00358     }
00359     else
00360     {
00361         /* New counter */
00362         counter = 0;
00363     }
00364     /* Counter is now valid; increment it */
00365     counter++;
00366     /* Save off the new counter */
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     /* and return the value */
00371     return counter;
00372 }
00373 
00374 /* QofObject function implementation and registration */
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 /* ========================== END OF FILE =============================== */

Generated on Thu Jan 31 22:50:25 2008 for QOF by  doxygen 1.5.4