QOF  0.8.7
qofbackend.c
1 /********************************************************************\
2  * qofbackend.c -- utility routines for the data backend *
3  * Copyright (C) 2000 Linas Vepstas <linas@linas.org> *
4  * Copyright (C) 2004-2008 Neil Williams <linux@codehelp.co.uk> *
5  * *
6  * This program is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU General Public License as *
8  * published by the Free Software Foundation; either version 2 of *
9  * the License, or (at your option) any later version. *
10  * *
11  * This program is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14  * GNU General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU General Public License*
17  * along with this program; if not, contact: *
18  * *
19  * Free Software Foundation Voice: +1-617-542-5942 *
20  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
21  * Boston, MA 02110-1301, USA gnu@gnu.org *
22  * *
23 \********************************************************************/
24 
25 #include "config.h"
26 #include <glib.h>
27 #include <gmodule.h>
28 #include "qof.h"
29 #include "qofbackend-p.h"
30 
31 #define QOF_CONFIG_DESC "desc"
32 #define QOF_CONFIG_TIP "tip"
33 
34 static QofLogModule log_module = QOF_MOD_BACKEND;
35 
36 void
37 qof_backend_init (QofBackend * be)
38 {
39  be->session_begin = NULL;
40  be->session_end = NULL;
41  be->destroy_backend = NULL;
42  be->load = NULL;
43  be->begin = NULL;
44  be->commit = NULL;
45  be->rollback = NULL;
46  be->compile_query = NULL;
47  be->free_query = NULL;
48  be->run_query = NULL;
49  be->sync = NULL;
50  be->load_config = NULL;
51  be->events_pending = NULL;
52  be->process_events = NULL;
53  be->percentage = NULL;
54  be->backend_configuration = kvp_frame_new ();
55 }
56 
57 void
58 qof_backend_run_begin (QofBackend * be, QofInstance * inst)
59 {
60  if (!be || !inst)
61  return;
62  if (!be->begin)
63  return;
64  (be->begin) (be, inst);
65 }
66 
67 gboolean
68 qof_backend_begin_exists (QofBackend * be)
69 {
70  if (be->begin)
71  return TRUE;
72  else
73  return FALSE;
74 }
75 
76 void
77 qof_backend_run_commit (QofBackend * be, QofInstance * inst)
78 {
79  if (!be || !inst)
80  return;
81  if (!be->commit)
82  return;
83  (be->commit) (be, inst);
84 }
85 
86 /* =========== Backend Configuration ================ */
87 
88 void
90 {
91  g_return_if_fail (be);
92  if (!kvp_frame_is_empty (be->backend_configuration))
93  {
94  kvp_frame_delete (be->backend_configuration);
95  be->backend_configuration = kvp_frame_new ();
96  }
97  be->config_count = 0;
98 }
99 
100 void
102  QofBackendOption * option)
103 {
104  KvpValue *value;
105  gchar *temp;
106  gint count;
107 
108  g_return_if_fail (be || option);
109  count = be->config_count;
110  count++;
111  value = NULL;
112  switch (option->type)
113  {
114  case KVP_TYPE_GINT64:
115  {
116  value = kvp_value_new_gint64 (*(gint64 *) option->value);
117  break;
118  }
119  case KVP_TYPE_DOUBLE:
120  {
121  value = kvp_value_new_double (*(gdouble *) option->value);
122  break;
123  }
124  case KVP_TYPE_NUMERIC:
125  {
126  value = kvp_value_new_numeric (*(QofNumeric *) option->value);
127  break;
128  }
129  case KVP_TYPE_STRING:
130  {
131  value = kvp_value_new_string ((const gchar *) option->value);
132  break;
133  }
134  case KVP_TYPE_BOOLEAN:
135  {
136  break;
137  }
138  case KVP_TYPE_GUID:
139  {
140  break;
141  } /* unsupported */
142  case KVP_TYPE_TIME :
143  {
144  value = kvp_value_new_time ((QofTime*) option->value);
145  break;
146  }
147  case KVP_TYPE_BINARY:
148  {
149  break;
150  } /* unsupported */
151  case KVP_TYPE_GLIST:
152  {
153  break;
154  } /* unsupported */
155  case KVP_TYPE_FRAME:
156  {
157  break;
158  } /* unsupported */
159  }
160  if (value)
161  {
162  temp = g_strdup_printf ("/%s", option->option_name);
163  kvp_frame_set_value (be->backend_configuration, temp, value);
164  g_free (temp);
165  temp =
166  g_strdup_printf ("/%s/%s", QOF_CONFIG_DESC,
167  option->option_name);
168  kvp_frame_set_string (be->backend_configuration, temp,
169  option->description);
170  g_free (temp);
171  temp =
172  g_strdup_printf ("/%s/%s", QOF_CONFIG_TIP,
173  option->option_name);
174  kvp_frame_set_string (be->backend_configuration, temp,
175  option->tooltip);
176  g_free (temp);
177  /* only increment the counter if successful */
178  be->config_count = count;
179  }
180 }
181 
182 KvpFrame *
184 {
185  g_return_val_if_fail (be, NULL);
186  be->config_count = 0;
187  return be->backend_configuration;
188 }
189 
190 struct config_iterate
191 {
192  QofBackendOptionCB fcn;
193  gpointer data;
194  gint count;
195  KvpFrame *recursive;
196 };
197 
198 /* Set the option with the default KvpValue,
199 manipulate the option in the supplied callback routine
200 then set the value of the option into the KvpValue
201 in the configuration frame. */
202 static void
203 config_foreach_cb (const gchar * key, KvpValue * value, gpointer data)
204 {
205  QofBackendOption option;
206  gint64 int64;
207  gdouble db;
208  QofNumeric num;
209  gchar *parent;
210  struct config_iterate *helper;
211 
212  g_return_if_fail (key || value || data);
213  helper = (struct config_iterate *) data;
214  if (!helper->recursive)
215  {
216  PERR (" no parent frame");
217  return;
218  }
219  // skip the presets.
220  if (0 == safe_strcmp (key, QOF_CONFIG_DESC))
221  {
222  return;
223  }
224  if (0 == safe_strcmp (key, QOF_CONFIG_TIP))
225  {
226  return;
227  }
228  ENTER (" key=%s", key);
229  option.option_name = key;
230  option.type = kvp_value_get_type (value);
231  if (!option.type)
232  return;
233  switch (option.type)
234  { /* set the KvpFrame value into the option */
235  case KVP_TYPE_GINT64:
236  {
237  int64 = kvp_value_get_gint64 (value);
238  option.value = (gpointer) & int64;
239  break;
240  }
241  case KVP_TYPE_DOUBLE:
242  {
243  db = kvp_value_get_double (value);
244  option.value = (gpointer) & db;
245  break;
246  }
247  case KVP_TYPE_NUMERIC:
248  {
249  num = kvp_value_get_numeric (value);
250  option.value = (gpointer) & num;
251  break;
252  }
253  case KVP_TYPE_STRING:
254  {
255  option.value = (gpointer) kvp_value_get_string (value);
256  break;
257  }
258  case KVP_TYPE_TIME :
259  {
260  option.value = (gpointer) kvp_value_get_time (value);
261  }
262  case KVP_TYPE_BOOLEAN :
263  {
264  break;
265  }
266  case KVP_TYPE_GUID:
267  {
268  break;
269  } /* unsupported */
270  case KVP_TYPE_BINARY:
271  {
272  break;
273  } /* unsupported */
274  case KVP_TYPE_GLIST:
275  {
276  break;
277  } /* unsupported */
278  case KVP_TYPE_FRAME:
279  {
280  break;
281  } /* unsupported */
282  }
283  parent = g_strdup_printf ("/%s/%s", QOF_CONFIG_DESC, key);
284  option.description = kvp_frame_get_string (helper->recursive, parent);
285  g_free (parent);
286  parent = g_strdup_printf ("/%s/%s", QOF_CONFIG_TIP, key);
287  option.tooltip = kvp_frame_get_string (helper->recursive, parent);
288  g_free (parent);
289  helper->count++;
290  /* manipulate the option */
291  helper->fcn (&option, helper->data);
292  switch (option.type)
293  { /* set the option value into the KvpFrame */
294  case KVP_TYPE_GINT64:
295  {
296  kvp_frame_set_gint64 (helper->recursive, key,
297  (*(gint64 *) option.value));
298  break;
299  }
300  case KVP_TYPE_DOUBLE:
301  {
302  kvp_frame_set_double (helper->recursive, key,
303  (*(gdouble *) option.value));
304  break;
305  }
306  case KVP_TYPE_NUMERIC:
307  {
308  kvp_frame_set_numeric (helper->recursive, key,
309  (*(QofNumeric *) option.value));
310  break;
311  }
312  case KVP_TYPE_STRING:
313  {
314  kvp_frame_set_string (helper->recursive, key,
315  (gchar *) option.value);
316  break;
317  }
318  case KVP_TYPE_TIME :
319  {
320  kvp_frame_set_time (helper->recursive, key,
321  (QofTime*) option.value);
322  break;
323  }
324  case KVP_TYPE_BOOLEAN :
325  {
326  break;
327  }
328  case KVP_TYPE_GUID:
329  {
330  break;
331  } /* unsupported */
332  case KVP_TYPE_BINARY:
333  {
334  break;
335  } /* unsupported */
336  case KVP_TYPE_GLIST:
337  {
338  break;
339  } /* unsupported */
340  case KVP_TYPE_FRAME:
341  {
342  break;
343  } /* unsupported */
344  }
345  LEAVE (" ");
346 }
347 
348 void
350  QofBackendOptionCB cb, gpointer data)
351 {
352  struct config_iterate helper;
353 
354  if (!config || !cb)
355  return;
356  ENTER (" ");
357  helper.fcn = cb;
358  helper.count = 1;
359  helper.data = data;
360  helper.recursive = config;
361  kvp_frame_for_each_slot (config, config_foreach_cb, &helper);
362  LEAVE (" ");
363 }
364 
365 void
367 {
368  if (!be || !config)
369  return;
370  if (!be->load_config)
371  return;
372  (be->load_config) (be, config);
373 }
374 
375 KvpFrame *
377 {
378  if (!be)
379  return NULL;
380  if (!be->get_config)
381  return NULL;
382  return (be->get_config) (be);
383 }
384 
385 gboolean
386 qof_backend_commit_exists (QofBackend * be)
387 {
388  if (!be)
389  return FALSE;
390  if (be->commit)
391  return TRUE;
392  else
393  return FALSE;
394 }
395 
396 gboolean
397 qof_load_backend_library (const gchar * directory,
398  const gchar * filename, const gchar * init_fcn)
399 {
400  gchar *fullpath;
401  typedef void (*backend_init) (void);
402  GModule *backend;
403  backend_init gmod_init;
404  gpointer g;
405 
406  g_return_val_if_fail (g_module_supported (), FALSE);
407  fullpath = g_module_build_path (directory, filename);
408  backend = g_module_open (fullpath, G_MODULE_BIND_LAZY);
409  if (!backend)
410  {
411  PERR (" No backend found. %s", g_module_error ());
412  return FALSE;
413  }
414  g = &gmod_init;
415  if (!g_module_symbol (backend, init_fcn, g))
416  {
417  PERR (" Backend did not initialise. %s", g_module_error ());
418  return FALSE;
419  }
420  g_module_make_resident (backend);
421  gmod_init ();
422  g_free (fullpath);
423  return TRUE;
424 }
425 
426 /************************* END OF FILE ********************************/
#define PERR(format, args...)
Definition: qoflog.h:183
void kvp_frame_set_numeric(KvpFrame *frame, const gchar *path, QofNumeric nval)
store the value of the QofNumeric at the indicated path.
Definition: kvpframe.c:417
Unique identifier.
Definition: kvpframe.h:118
void kvp_frame_set_time(KvpFrame *frame, const gchar *path, QofTime *qt)
Store a copy of the QofTime at the indicated path.
Definition: kvpframe.c:407
const gchar * description
Definition: qofbackend.h:119
struct _KvpFrame KvpFrame
Definition: kvpframe.h:74
void kvp_frame_set_gint64(KvpFrame *frame, const gchar *path, gint64 ival)
store the value of the gint64 at the indicated path.
Definition: kvpframe.c:387
gboolean qof_load_backend_library(const gchar *directory, const gchar *filename, const gchar *init_fcn)
Load a QOF-compatible backend shared library.
Definition: qofbackend.c:397
KvpFrame * qof_backend_complete_frame(QofBackend *be)
Definition: qofbackend.c:183
gboolean kvp_frame_is_empty(KvpFrame *frame)
Definition: kvpframe.c:134
void(* QofBackendOptionCB)(QofBackendOption *, gpointer data)
Definition: qofbackend.h:134
#define LEAVE(format, args...)
Definition: qoflog.h:227
KvpFrame * kvp_frame_set_value(KvpFrame *frame, const gchar *key_path, const KvpValue *value)
Copy the KvpValue into the frame.
Definition: kvpframe.c:496
128bit denominator/numerator maths.
Definition: kvpframe.h:106
void kvp_frame_delete(KvpFrame *frame)
Definition: kvpframe.c:115
gint64 kvp_value_get_gint64(const KvpValue *value)
Definition: kvpframe.c:1399
struct _KvpValue KvpValue
Definition: kvpframe.h:78
void qof_backend_prepare_option(QofBackend *be, QofBackendOption *option)
Definition: qofbackend.c:101
64bit integer
Definition: kvpframe.h:94
void qof_backend_option_foreach(KvpFrame *config, QofBackendOptionCB cb, gpointer data)
Definition: qofbackend.c:349
const gchar * option_name
Definition: qofbackend.h:118
gchar * kvp_value_get_string(const KvpValue *value)
Definition: kvpframe.c:1444
KvpFrame * qof_backend_get_config(QofBackend *be)
Get the available configuration options.
Definition: qofbackend.c:376
void kvp_frame_for_each_slot(KvpFrame *f, KvpValueForeachCB proc, gpointer data)
Definition: kvpframe.c:1642
private api for data storage backend
struct QofTime64 QofTime
Use a 64-bit signed int QofTime.
Definition: qoftime.h:112
Simple boolean type.
Definition: kvpframe.h:136
const gchar * tooltip
Definition: qofbackend.h:120
standard C string
Definition: kvpframe.h:112
void kvp_frame_set_double(KvpFrame *frame, const gchar *path, gdouble dval)
store the value of the double at the indicated path.
Definition: kvpframe.c:397
KvpFrame * kvp_frame_new(void)
Definition: kvpframe.c:97
gint safe_strcmp(const gchar *da, const gchar *db)
Definition: qofutil.c:75
standard C double type
Definition: kvpframe.h:100
void qof_backend_load_config(QofBackend *be, KvpFrame *config)
Load configuration options specific to this backend.
Definition: qofbackend.c:366
#define ENTER(format, args...)
Definition: qoflog.h:217
KvpValueType type
Definition: qofbackend.h:116
const gchar * QofLogModule
Definition: qofid.h:85
void kvp_frame_set_string(KvpFrame *frame, const gchar *path, const gchar *str)
Store a copy of the string at the indicated path.
Definition: kvpframe.c:439
64bit time/date handling.
Definition: kvpframe.h:124
void qof_backend_prepare_frame(QofBackend *be)
Definition: qofbackend.c:89