QOF  0.8.7
qofbook.c
1 /********************************************************************\
2  * qofbook.c -- dataset access (set of books of entities) *
3  * *
4  * This program is free software; you can redistribute it and/or *
5  * modify it under the terms of the GNU General Public License as *
6  * published by the Free Software Foundation; either version 2 of *
7  * the License, or (at your option) any later version. *
8  * *
9  * This program is distributed in the hope that it will be useful, *
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12  * GNU General Public License for more details. *
13  * *
14  * You should have received a copy of the GNU General Public License*
15  * along with this program; if not, contact: *
16  * *
17  * Free Software Foundation Voice: +1-617-542-5942 *
18  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
19  * Boston, MA 02110-1301, USA gnu@gnu.org *
20 \********************************************************************/
21 
22 /*
23  * FILE:
24  * qofbook.c
25  *
26  * FUNCTION:
27  * Encapsulate all the information about a QOF dataset.
28  *
29  * HISTORY:
30  * Created by Linas Vepstas December 1998
31  * Copyright (c) 1998-2001,2003 Linas Vepstas <linas@linas.org>
32  * Copyright (c) 2000 Dave Peticolas
33  * Copyright (c) 2006 Neil Williams <linux@codehelp.co.uk>
34  */
35 
36 #include "config.h"
37 #include <stdlib.h>
38 #include <string.h>
39 #include <glib.h>
40 #include "qof.h"
41 #include "qofevent-p.h"
42 #include "qofbackend-p.h"
43 #include "qofbook-p.h"
44 #include "qofid-p.h"
45 #include "qofobject-p.h"
46 
47 static QofLogModule log_module = QOF_MOD_ENGINE;
48 
49 static void
50 coll_destroy (gpointer col)
51 {
53 }
54 
55 static void
56 qof_book_init (QofBook * book)
57 {
58  if (!book)
59  return;
60 
61  book->hash_of_collections =
62  g_hash_table_new_full (g_str_hash, g_str_equal,
63  (GDestroyNotify) qof_util_string_cache_remove, coll_destroy);
64  qof_instance_init (&book->inst, QOF_ID_BOOK, book);
65  book->data_tables = g_hash_table_new (g_str_hash, g_str_equal);
66  book->data_table_finalizers =
67  g_hash_table_new (g_str_hash, g_str_equal);
68  book->book_open = 'y';
69  book->version = 0;
70  book->idata = 0;
71  book->undo_data = g_new0 (QofUndo, 1);
72 }
73 
74 QofBook *
76 {
77  QofBook *book;
78 
79  ENTER (" ");
80  book = g_new0 (QofBook, 1);
81  qof_book_init (book);
82  qof_object_book_begin (book);
83  qof_event_gen (&book->inst.entity, QOF_EVENT_CREATE, NULL);
84  LEAVE ("book=%p", book);
85  return book;
86 }
87 
88 static void
89 book_final (gpointer key, gpointer value, gpointer booq)
90 {
91  QofBookFinalCB cb = value;
92  QofBook *book = booq;
93 
94  gpointer user_data = g_hash_table_lookup (book->data_tables, key);
95  (*cb) (book, key, user_data);
96 }
97 
98 void
100 {
101  if (!book)
102  return;
103  ENTER ("book=%p", book);
104  book->shutting_down = TRUE;
105  qof_event_force (&book->inst.entity, QOF_EVENT_DESTROY, NULL);
106  /* Call the list of finalizers, let them do their thing.
107  * Do this before tearing into the rest of the book.
108  */
109  g_hash_table_foreach (book->data_table_finalizers, book_final, book);
110  qof_object_book_end (book);
111  g_hash_table_destroy (book->data_table_finalizers);
112  book->data_table_finalizers = NULL;
113  g_hash_table_destroy (book->data_tables);
114  book->data_tables = NULL;
115  qof_instance_release (&book->inst);
116  g_hash_table_destroy (book->hash_of_collections);
117  book->hash_of_collections = NULL;
118  g_free (book);
119  LEAVE ("book=%p", book);
120 }
121 
122 /* call is_equal callbacks on QofObject ? */
123 
124 gboolean
125 qof_book_equal (QofBook * book_1, QofBook * book_2)
126 {
127  if (book_1 == book_2)
128  return TRUE;
129  if (!book_1 || !book_2)
130  return FALSE;
131  return TRUE;
132 }
133 
134 gboolean
136 {
137  if (!book)
138  return FALSE;
139 
140  return (book->inst.dirty || qof_object_is_dirty (book));
141 }
142 
143 void
145 {
146  if (!book)
147  return;
148 
149  book->inst.dirty = FALSE;
150  qof_object_mark_clean (book);
151 }
152 
153 QofBackend *
155 {
156  if (!book)
157  return NULL;
158  return book->backend;
159 }
160 
161 gboolean
163 {
164  if (!book)
165  return FALSE;
166  return book->shutting_down;
167 }
168 
169 void
171 {
172  if (!book)
173  return;
174  ENTER ("book=%p be=%p", book, be);
175  book->backend = be;
176  LEAVE (" ");
177 }
178 
179 void
181 {
182  if (!book)
183  return;
184  book->inst.dirty = TRUE;
185 }
186 
187 /* Store arbitrary pointers in the QofBook for data storage extensibility */
188 /* XXX if data is NULL, we should remove the key from the hash table!
189  */
190 void
191 qof_book_set_data (QofBook * book, const gchar * key, gpointer data)
192 {
193  if (!book || !key)
194  return;
195  g_hash_table_insert (book->data_tables, (gpointer) key, data);
196 }
197 
198 void
199 qof_book_set_data_fin (QofBook * book, const gchar * key,
200  gpointer data, QofBookFinalCB cb)
201 {
202  if (!book || !key)
203  return;
204  g_hash_table_insert (book->data_tables, (gpointer) key, data);
205 
206  if (!cb)
207  return;
208  g_hash_table_insert (book->data_table_finalizers, (gpointer) key, cb);
209 }
210 
211 gpointer
212 qof_book_get_data (QofBook * book, const gchar * key)
213 {
214  if (!book || !key)
215  return NULL;
216  return g_hash_table_lookup (book->data_tables, (gpointer) key);
217 }
218 
221 {
222  QofCollection *col;
223 
224  if (!book || !entity_type)
225  return NULL;
226  col = g_hash_table_lookup (book->hash_of_collections, entity_type);
227  if (!col)
228  {
229  col = qof_collection_new (entity_type);
230  g_hash_table_insert (book->hash_of_collections,
231  qof_util_string_cache_insert ((gpointer) entity_type), col);
232  }
233  return col;
234 }
235 
236 struct _iterate
237 {
239  gpointer data;
240 };
241 
242 static void
243 foreach_cb (gpointer key __attribute__ ((unused)), gpointer item, gpointer arg)
244 {
245  struct _iterate *qiter = arg;
246  QofCollection *col = item;
247 
248  qiter->fn (col, qiter->data);
249 }
250 
251 void
252 qof_book_foreach_collection (QofBook * book,
253  QofCollectionForeachCB cb, gpointer user_data)
254 {
255  struct _iterate qiter;
256 
257  g_return_if_fail (book);
258  g_return_if_fail (cb);
259  qiter.fn = cb;
260  qiter.data = user_data;
261  g_hash_table_foreach (book->hash_of_collections, foreach_cb, &qiter);
262 }
263 
264 void
266 {
267  if (!book)
268  {
269  return;
270  }
271  book->book_open = 'n';
272 }
273 
274 gchar
276 {
277  if (!book)
278  {
279  return 'n';
280  }
281  return book->book_open;
282 }
283 
284 gint32
286 {
287  if (!book)
288  {
289  return -1;
290  }
291  return book->version;
292 }
293 
294 guint32
296 {
297  if (!book)
298  {
299  return 0;
300  }
301  return book->idata;
302 }
303 
304 void
305 qof_book_set_version (QofBook * book, gint32 version)
306 {
307  if (!book && version < 0)
308  {
309  return;
310  }
311  book->version = version;
312 }
313 
314 void
315 qof_book_set_idata (QofBook * book, guint32 idata)
316 {
317  if (!book && idata == 0)
318  {
319  return;
320  }
321  book->idata = idata;
322 }
323 
324 gint64
325 qof_book_get_counter (QofBook * book, const gchar * counter_name)
326 {
327  QofBackend *be;
328  KvpFrame *kvp;
329  KvpValue *value;
330  gint64 counter;
331 
332  if (!book)
333  {
334  PWARN ("No book!!!");
335  return -1;
336  }
337  if (!counter_name || *counter_name == '\0')
338  {
339  PWARN ("Invalid counter name.");
340  return -1;
341  }
342  /* If we've got a backend with a counter method, call it */
343  be = book->backend;
344  if (be && be->counter)
345  return ((be->counter) (be, counter_name));
346  /* If not, then use the KVP in the book */
347  kvp = qof_book_get_slots (book);
348  if (!kvp)
349  {
350  PWARN ("Book has no KVP_Frame");
351  return -1;
352  }
353  value = kvp_frame_get_slot_path (kvp, "counters", counter_name, NULL);
354  if (value)
355  {
356  /* found it */
357  counter = kvp_value_get_gint64 (value);
358  }
359  else
360  {
361  /* New counter */
362  counter = 0;
363  }
364  /* Counter is now valid; increment it */
365  counter++;
366  /* Save off the new counter */
367  value = kvp_value_new_gint64 (counter);
368  kvp_frame_set_slot_path (kvp, value, "counters", counter_name, NULL);
369  kvp_value_delete (value);
370  /* and return the value */
371  return counter;
372 }
373 
374 /* QofObject function implementation and registration */
375 gboolean
377 {
378  static QofParam params[] = {
379  {QOF_PARAM_GUID, QOF_TYPE_GUID,
381  NULL, NULL},
382  {QOF_PARAM_KVP, QOF_TYPE_KVP,
384  NULL, NULL},
385  {NULL, NULL, NULL, NULL, NULL},
386  };
387 
388  qof_class_register (QOF_ID_BOOK, NULL, params);
389 
390  return TRUE;
391 }
392 
393 /* ========================== END OF FILE =============================== */
QofInstance inst
Definition: qofbook-p.h:51
GHashTable * hash_of_collections
Definition: qofbook-p.h:57
gint32 qof_book_get_version(QofBook *book)
Definition: qofbook.c:285
const gchar * QofIdType
Definition: qofid.h:81
QofCollection * qof_book_get_collection(QofBook *book, QofIdType entity_type)
Definition: qofbook.c:220
void qof_book_mark_saved(QofBook *book)
Definition: qofbook.c:144
void(* QofCollectionForeachCB)(QofCollection *, gpointer user_data)
Definition: qofbook.h:102
gboolean qof_book_equal(QofBook *book_1, QofBook *book_2)
Definition: qofbook.c:125
gboolean qof_book_register(void)
Definition: qofbook.c:376
void qof_object_book_begin(QofBook *book)
Definition: qofobject.c:60
#define QOF_EVENT_DESTROY
Definition: qofevent.h:81
gpointer qof_book_get_data(QofBook *book, const gchar *key)
Definition: qofbook.c:212
gchar book_open
Definition: qofbook-p.h:70
void qof_class_register(QofIdTypeConst obj_name, QofSortFunc default_sort_function, const QofParam *params)
registers a new object class with the Qof subsystem.
Definition: qofclass.c:94
struct _KvpFrame KvpFrame
Definition: kvpframe.h:74
QofBook * qof_book_new(void)
Definition: qofbook.c:75
void qof_book_mark_closed(QofBook *book)
Definition: qofbook.c:265
void kvp_frame_set_slot_path(KvpFrame *frame, const KvpValue *new_value, const gchar *first_key,...)
Definition: kvpframe.c:723
gint64 qof_book_get_counter(QofBook *book, const gchar *counter_name)
Definition: qofbook.c:325
QofUndo * undo_data
Definition: qofbook-p.h:90
#define LEAVE(format, args...)
Definition: qoflog.h:227
Private QofBook interface.
void qof_event_gen(QofEntity *entity, QofEventId event_id, gpointer event_data)
Invoke all registered event handlers using the given arguments.
Definition: qofevent.c:235
the Core Object Registration/Lookup Private Interface
gint64 kvp_value_get_gint64(const KvpValue *value)
Definition: kvpframe.c:1399
struct QofCollection_s QofCollection
Definition: qofid.h:138
#define QOF_EVENT_CREATE
Definition: qofevent.h:71
struct _KvpValue KvpValue
Definition: kvpframe.h:78
GHashTable * data_table_finalizers
Definition: qofbook-p.h:64
guint32 qof_book_get_idata(QofBook *book)
Definition: qofbook.c:295
KvpFrame * qof_instance_get_slots(QofInstance *inst)
Definition: qofinstance.c:95
gpointer qof_util_string_cache_insert(gconstpointer key)
Definition: qofutil.c:456
void qof_util_string_cache_remove(gconstpointer key)
Definition: qofutil.c:450
void qof_book_set_backend(QofBook *book, QofBackend *be)
Set the backend used by this book.
Definition: qofbook.c:170
gboolean qof_book_not_saved(QofBook *book)
Definition: qofbook.c:135
QofBackend * backend
Definition: qofbook-p.h:87
void qof_book_set_data_fin(QofBook *book, const gchar *key, gpointer data, QofBookFinalCB cb)
Definition: qofbook.c:199
gboolean qof_book_shutting_down(QofBook *book)
Definition: qofbook.c:162
void qof_book_set_data(QofBook *book, const gchar *key, gpointer data)
Definition: qofbook.c:191
gpointer(* QofAccessFunc)(gpointer object, const QofParam *param)
Definition: qofclass.h:144
KvpValue * kvp_frame_get_slot_path(KvpFrame *frame, const gchar *first_key,...)
Definition: kvpframe.c:1057
QofEntity entity
Definition: qofinstance-p.h:39
gchar qof_book_get_open_marker(QofBook *book)
Definition: qofbook.c:275
void qof_book_kvp_changed(QofBook *book)
Definition: qofbook.c:180
#define QOF_PARAM_KVP
Definition: qofquery.h:108
private api for data storage backend
#define PWARN(format, args...)
Definition: qoflog.h:191
void qof_collection_destroy(QofCollection *col)
Definition: qofid.c:132
const GUID * qof_entity_get_guid(QofEntity *ent)
Definition: qofid.c:105
QofCollection * qof_collection_new(QofIdType type)
Definition: qofid.c:121
void qof_instance_release(QofInstance *inst)
Definition: qofinstance.c:69
guint32 idata
Definition: qofbook-p.h:94
GHashTable * data_tables
Definition: qofbook-p.h:61
QofBackend * qof_book_get_backend(QofBook *book)
Retrieve the backend used by this book.
Definition: qofbook.c:154
gint32 version
Definition: qofbook-p.h:80
void qof_instance_init(QofInstance *inst, QofIdType type, QofBook *book)
Definition: qofinstance.c:53
void kvp_value_delete(KvpValue *value)
Definition: kvpframe.c:1358
#define qof_book_get_slots(book)
Definition: qofbook.h:113
#define ENTER(format, args...)
Definition: qoflog.h:217
const gchar * QofLogModule
Definition: qofid.h:85
void qof_book_destroy(QofBook *book)
Definition: qofbook.c:99
gboolean shutting_down
Definition: qofbook-p.h:77