QOF  0.7.5
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-2006 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
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 #ifndef QOF_DISABLE_DEPRECATED
56  be->last_err = QOF_SUCCESS;
57  if (be->error_msg)
58  g_free (be->error_msg);
59  be->error_msg = NULL;
61  be->price_lookup = NULL;
63  be->export = NULL;
64 #endif
65 }
66 
67 void
68 qof_backend_run_begin (QofBackend * be, QofInstance * inst)
69 {
70  if (!be || !inst)
71  return;
72  if (!be->begin)
73  return;
74  (be->begin) (be, inst);
75 }
76 
77 gboolean
78 qof_backend_begin_exists (QofBackend * be)
79 {
80  if (be->begin)
81  return TRUE;
82  else
83  return FALSE;
84 }
85 
86 void
87 qof_backend_run_commit (QofBackend * be, QofInstance * inst)
88 {
89  if (!be || !inst)
90  return;
91  if (!be->commit)
92  return;
93  (be->commit) (be, inst);
94 }
95 
96 /* =========== Backend Configuration ================ */
97 
98 void
100 {
101  g_return_if_fail (be);
102  if (!kvp_frame_is_empty (be->backend_configuration))
103  {
104  kvp_frame_delete (be->backend_configuration);
105  be->backend_configuration = kvp_frame_new ();
106  }
107  be->config_count = 0;
108 }
109 
110 void
112  QofBackendOption * option)
113 {
114  KvpValue *value;
115  gchar *temp;
116  gint count;
117 
118  g_return_if_fail (be || option);
119  count = be->config_count;
120  count++;
121  value = NULL;
122  switch (option->type)
123  {
124  case KVP_TYPE_GINT64:
125  {
126  value = kvp_value_new_gint64 (*(gint64 *) option->value);
127  break;
128  }
129  case KVP_TYPE_DOUBLE:
130  {
131  value = kvp_value_new_double (*(gdouble *) option->value);
132  break;
133  }
134  case KVP_TYPE_NUMERIC:
135  {
136  value = kvp_value_new_numeric (*(QofNumeric *) option->value);
137  break;
138  }
139  case KVP_TYPE_STRING:
140  {
141  value = kvp_value_new_string ((const gchar *) option->value);
142  break;
143  }
144  case KVP_TYPE_BOOLEAN:
145  {
146  break;
147  }
148  case KVP_TYPE_GUID:
149  {
150  break;
151  } /* unsupported */
152  case KVP_TYPE_TIME :
153  {
154  value = kvp_value_new_time ((QofTime*) option->value);
155  break;
156  }
157 #ifndef QOF_DISABLE_DEPRECATED
158  case KVP_TYPE_TIMESPEC:
159  {
160  value = kvp_value_new_timespec (*(Timespec *) option->value);
161  break;
162  }
163 #endif
164  case KVP_TYPE_BINARY:
165  {
166  break;
167  } /* unsupported */
168  case KVP_TYPE_GLIST:
169  {
170  break;
171  } /* unsupported */
172  case KVP_TYPE_FRAME:
173  {
174  break;
175  } /* unsupported */
176  }
177  if (value)
178  {
179  temp = g_strdup_printf ("/%s", option->option_name);
180  kvp_frame_set_value (be->backend_configuration, temp, value);
181  g_free (temp);
182  temp =
183  g_strdup_printf ("/%s/%s", QOF_CONFIG_DESC,
184  option->option_name);
185  kvp_frame_set_string (be->backend_configuration, temp,
186  option->description);
187  g_free (temp);
188  temp =
189  g_strdup_printf ("/%s/%s", QOF_CONFIG_TIP,
190  option->option_name);
191  kvp_frame_set_string (be->backend_configuration, temp,
192  option->tooltip);
193  g_free (temp);
194  /* only increment the counter if successful */
195  be->config_count = count;
196  }
197 }
198 
199 KvpFrame *
201 {
202  g_return_val_if_fail (be, NULL);
203  be->config_count = 0;
204  return be->backend_configuration;
205 }
206 
207 struct config_iterate
208 {
209  QofBackendOptionCB fcn;
210  gpointer data;
211  gint count;
212  KvpFrame *recursive;
213 };
214 
215 /* Set the option with the default KvpValue,
216 manipulate the option in the supplied callback routine
217 then set the value of the option into the KvpValue
218 in the configuration frame. */
219 static void
220 config_foreach_cb (const gchar * key, KvpValue * value, gpointer data)
221 {
222  QofBackendOption option;
223  gint64 int64;
224  gdouble db;
225  QofNumeric num;
226  gchar *parent;
227  struct config_iterate *helper;
228 
229  g_return_if_fail (key || value || data);
230  helper = (struct config_iterate *) data;
231  if (!helper->recursive)
232  {
233  PERR (" no parent frame");
234  return;
235  }
236  // skip the presets.
237  if (0 == safe_strcmp (key, QOF_CONFIG_DESC))
238  {
239  return;
240  }
241  if (0 == safe_strcmp (key, QOF_CONFIG_TIP))
242  {
243  return;
244  }
245  ENTER (" key=%s", key);
246  option.option_name = key;
247  option.type = kvp_value_get_type (value);
248  if (!option.type)
249  return;
250  switch (option.type)
251  { /* set the KvpFrame value into the option */
252  case KVP_TYPE_GINT64:
253  {
254  int64 = kvp_value_get_gint64 (value);
255  option.value = (gpointer) & int64;
256  break;
257  }
258  case KVP_TYPE_DOUBLE:
259  {
260  db = kvp_value_get_double (value);
261  option.value = (gpointer) & db;
262  break;
263  }
264  case KVP_TYPE_NUMERIC:
265  {
266  num = kvp_value_get_numeric (value);
267  option.value = (gpointer) & num;
268  break;
269  }
270  case KVP_TYPE_STRING:
271  {
272  option.value = (gpointer) kvp_value_get_string (value);
273  break;
274  }
275  case KVP_TYPE_TIME :
276  {
277  option.value = (gpointer) kvp_value_get_time (value);
278  }
279 #ifndef QOF_DISABLE_DEPRECATED
280  case KVP_TYPE_TIMESPEC:
281  {
282  Timespec ts;
283  ts = kvp_value_get_timespec (value);
284  option.value = (gpointer) & ts;
285  break;
286  }
287 #endif
288  case KVP_TYPE_BOOLEAN :
289  {
290  break;
291  }
292  case KVP_TYPE_GUID:
293  {
294  break;
295  } /* unsupported */
296  case KVP_TYPE_BINARY:
297  {
298  break;
299  } /* unsupported */
300  case KVP_TYPE_GLIST:
301  {
302  break;
303  } /* unsupported */
304  case KVP_TYPE_FRAME:
305  {
306  break;
307  } /* unsupported */
308  }
309  parent = g_strdup_printf ("/%s/%s", QOF_CONFIG_DESC, key);
310  option.description = kvp_frame_get_string (helper->recursive, parent);
311  g_free (parent);
312  parent = g_strdup_printf ("/%s/%s", QOF_CONFIG_TIP, key);
313  option.tooltip = kvp_frame_get_string (helper->recursive, parent);
314  g_free (parent);
315  helper->count++;
316  /* manipulate the option */
317  helper->fcn (&option, helper->data);
318  switch (option.type)
319  { /* set the option value into the KvpFrame */
320  case KVP_TYPE_GINT64:
321  {
322  kvp_frame_set_gint64 (helper->recursive, key,
323  (*(gint64 *) option.value));
324  break;
325  }
326  case KVP_TYPE_DOUBLE:
327  {
328  kvp_frame_set_double (helper->recursive, key,
329  (*(gdouble *) option.value));
330  break;
331  }
332  case KVP_TYPE_NUMERIC:
333  {
334  kvp_frame_set_numeric (helper->recursive, key,
335  (*(QofNumeric *) option.value));
336  break;
337  }
338  case KVP_TYPE_STRING:
339  {
340  kvp_frame_set_string (helper->recursive, key,
341  (gchar *) option.value);
342  break;
343  }
344  case KVP_TYPE_TIME :
345  {
346  kvp_frame_set_time (helper->recursive, key,
347  (QofTime*) option.value);
348  break;
349  }
350 #ifndef QOF_DISABLE_DEPRECATED
351  case KVP_TYPE_TIMESPEC:
352  {
353  kvp_frame_set_timespec (helper->recursive, key,
354  (*(Timespec *) option.value));
355  break;
356  }
357 #endif
358  case KVP_TYPE_BOOLEAN :
359  {
360  break;
361  }
362  case KVP_TYPE_GUID:
363  {
364  break;
365  } /* unsupported */
366  case KVP_TYPE_BINARY:
367  {
368  break;
369  } /* unsupported */
370  case KVP_TYPE_GLIST:
371  {
372  break;
373  } /* unsupported */
374  case KVP_TYPE_FRAME:
375  {
376  break;
377  } /* unsupported */
378  }
379  LEAVE (" ");
380 }
381 
382 void
384  QofBackendOptionCB cb, gpointer data)
385 {
386  struct config_iterate helper;
387 
388  if (!config || !cb)
389  return;
390  ENTER (" ");
391  helper.fcn = cb;
392  helper.count = 1;
393  helper.data = data;
394  helper.recursive = config;
395  kvp_frame_for_each_slot (config, config_foreach_cb, &helper);
396  LEAVE (" ");
397 }
398 
399 void
401 {
402  if (!be || !config)
403  return;
404  if (!be->load_config)
405  return;
406  (be->load_config) (be, config);
407 }
408 
409 KvpFrame *
411 {
412  if (!be)
413  return NULL;
414  if (!be->get_config)
415  return NULL;
416  return (be->get_config) (be);
417 }
418 
419 gboolean
420 qof_backend_commit_exists (QofBackend * be)
421 {
422  if (!be)
423  return FALSE;
424  if (be->commit)
425  return TRUE;
426  else
427  return FALSE;
428 }
429 
430 gboolean
431 qof_load_backend_library (const gchar * directory,
432  const gchar * filename, const gchar * init_fcn)
433 {
434  gchar *fullpath;
435  typedef void (*backend_init) (void);
436  GModule *backend;
437  backend_init gmod_init;
438  gpointer g;
439 
440  g_return_val_if_fail (g_module_supported (), FALSE);
441  fullpath = g_module_build_path (directory, filename);
442  backend = g_module_open (fullpath, G_MODULE_BIND_LAZY);
443  if (!backend)
444  {
445  PERR (" No backend found. %s", g_module_error ());
446  return FALSE;
447  }
448  g = &gmod_init;
449  if (!g_module_symbol (backend, init_fcn, g))
450  {
451  PERR (" Backend did not initialise. %s", g_module_error ());
452  return FALSE;
453  }
454  g_module_make_resident (backend);
455  gmod_init ();
456  g_free (fullpath);
457  return TRUE;
458 }
459 
460 /************************* END OF FILE ********************************/