00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "config.h"
00026 #include <glib.h>
00027 #include <gmodule.h>
00028 #include "qof.h"
00029 #include "qofbackend-p.h"
00030
00031 #define QOF_CONFIG_DESC "desc"
00032 #define QOF_CONFIG_TIP "tip"
00033
00034 static QofLogModule log_module = QOF_MOD_BACKEND;
00035
00036 void
00037 qof_backend_init (QofBackend * be)
00038 {
00039 be->session_begin = NULL;
00040 be->session_end = NULL;
00041 be->destroy_backend = NULL;
00042 be->load = NULL;
00043 be->begin = NULL;
00044 be->commit = NULL;
00045 be->rollback = NULL;
00046 be->compile_query = NULL;
00047 be->free_query = NULL;
00048 be->run_query = NULL;
00049 be->sync = NULL;
00050 be->load_config = NULL;
00051 be->events_pending = NULL;
00052 be->process_events = NULL;
00053 be->percentage = NULL;
00054 be->backend_configuration = kvp_frame_new ();
00055 #ifndef QOF_DISABLE_DEPRECATED
00056 be->last_err = QOF_SUCCESS;
00057 if (be->error_msg)
00058 g_free (be->error_msg);
00059 be->error_msg = NULL;
00061 be->price_lookup = NULL;
00063 be->export = NULL;
00064 #endif
00065 }
00066
00067 void
00068 qof_backend_run_begin (QofBackend * be, QofInstance * inst)
00069 {
00070 if (!be || !inst)
00071 return;
00072 if (!be->begin)
00073 return;
00074 (be->begin) (be, inst);
00075 }
00076
00077 gboolean
00078 qof_backend_begin_exists (QofBackend * be)
00079 {
00080 if (be->begin)
00081 return TRUE;
00082 else
00083 return FALSE;
00084 }
00085
00086 void
00087 qof_backend_run_commit (QofBackend * be, QofInstance * inst)
00088 {
00089 if (!be || !inst)
00090 return;
00091 if (!be->commit)
00092 return;
00093 (be->commit) (be, inst);
00094 }
00095
00096
00097
00098 void
00099 qof_backend_prepare_frame (QofBackend * be)
00100 {
00101 g_return_if_fail (be);
00102 if (!kvp_frame_is_empty (be->backend_configuration))
00103 {
00104 kvp_frame_delete (be->backend_configuration);
00105 be->backend_configuration = kvp_frame_new ();
00106 }
00107 be->config_count = 0;
00108 }
00109
00110 void
00111 qof_backend_prepare_option (QofBackend * be,
00112 QofBackendOption * option)
00113 {
00114 KvpValue *value;
00115 gchar *temp;
00116 gint count;
00117
00118 g_return_if_fail (be || option);
00119 count = be->config_count;
00120 count++;
00121 value = NULL;
00122 switch (option->type)
00123 {
00124 case KVP_TYPE_GINT64:
00125 {
00126 value = kvp_value_new_gint64 (*(gint64 *) option->value);
00127 break;
00128 }
00129 case KVP_TYPE_DOUBLE:
00130 {
00131 value = kvp_value_new_double (*(gdouble *) option->value);
00132 break;
00133 }
00134 case KVP_TYPE_NUMERIC:
00135 {
00136 value = kvp_value_new_numeric (*(QofNumeric *) option->value);
00137 break;
00138 }
00139 case KVP_TYPE_STRING:
00140 {
00141 value = kvp_value_new_string ((const gchar *) option->value);
00142 break;
00143 }
00144 case KVP_TYPE_BOOLEAN:
00145 {
00146 break;
00147 }
00148 case KVP_TYPE_GUID:
00149 {
00150 break;
00151 }
00152 case KVP_TYPE_TIME :
00153 {
00154 value = kvp_value_new_time ((QofTime*) option->value);
00155 break;
00156 }
00157 #ifndef QOF_DISABLE_DEPRECATED
00158 case KVP_TYPE_TIMESPEC:
00159 {
00160 value = kvp_value_new_timespec (*(Timespec *) option->value);
00161 break;
00162 }
00163 #endif
00164 case KVP_TYPE_BINARY:
00165 {
00166 break;
00167 }
00168 case KVP_TYPE_GLIST:
00169 {
00170 break;
00171 }
00172 case KVP_TYPE_FRAME:
00173 {
00174 break;
00175 }
00176 }
00177 if (value)
00178 {
00179 temp = g_strdup_printf ("/%s", option->option_name);
00180 kvp_frame_set_value (be->backend_configuration, temp, value);
00181 g_free (temp);
00182 temp =
00183 g_strdup_printf ("/%s/%s", QOF_CONFIG_DESC,
00184 option->option_name);
00185 kvp_frame_set_string (be->backend_configuration, temp,
00186 option->description);
00187 g_free (temp);
00188 temp =
00189 g_strdup_printf ("/%s/%s", QOF_CONFIG_TIP,
00190 option->option_name);
00191 kvp_frame_set_string (be->backend_configuration, temp,
00192 option->tooltip);
00193 g_free (temp);
00194
00195 be->config_count = count;
00196 }
00197 }
00198
00199 KvpFrame *
00200 qof_backend_complete_frame (QofBackend * be)
00201 {
00202 g_return_val_if_fail (be, NULL);
00203 be->config_count = 0;
00204 return be->backend_configuration;
00205 }
00206
00207 struct config_iterate
00208 {
00209 QofBackendOptionCB fcn;
00210 gpointer data;
00211 gint count;
00212 KvpFrame *recursive;
00213 };
00214
00215
00216
00217
00218
00219 static void
00220 config_foreach_cb (const gchar * key, KvpValue * value, gpointer data)
00221 {
00222 QofBackendOption option;
00223 gint64 int64;
00224 gdouble db;
00225 QofNumeric num;
00226 gchar *parent;
00227 struct config_iterate *helper;
00228
00229 g_return_if_fail (key || value || data);
00230 helper = (struct config_iterate *) data;
00231 if (!helper->recursive)
00232 {
00233 PERR (" no parent frame");
00234 return;
00235 }
00236
00237 if (0 == safe_strcmp (key, QOF_CONFIG_DESC))
00238 {
00239 return;
00240 }
00241 if (0 == safe_strcmp (key, QOF_CONFIG_TIP))
00242 {
00243 return;
00244 }
00245 ENTER (" key=%s", key);
00246 option.option_name = key;
00247 option.type = kvp_value_get_type (value);
00248 if (!option.type)
00249 return;
00250 switch (option.type)
00251 {
00252 case KVP_TYPE_GINT64:
00253 {
00254 int64 = kvp_value_get_gint64 (value);
00255 option.value = (gpointer) & int64;
00256 break;
00257 }
00258 case KVP_TYPE_DOUBLE:
00259 {
00260 db = kvp_value_get_double (value);
00261 option.value = (gpointer) & db;
00262 break;
00263 }
00264 case KVP_TYPE_NUMERIC:
00265 {
00266 num = kvp_value_get_numeric (value);
00267 option.value = (gpointer) & num;
00268 break;
00269 }
00270 case KVP_TYPE_STRING:
00271 {
00272 option.value = (gpointer) kvp_value_get_string (value);
00273 break;
00274 }
00275 case KVP_TYPE_TIME :
00276 {
00277 option.value = (gpointer) kvp_value_get_time (value);
00278 }
00279 #ifndef QOF_DISABLE_DEPRECATED
00280 case KVP_TYPE_TIMESPEC:
00281 {
00282 Timespec ts;
00283 ts = kvp_value_get_timespec (value);
00284 option.value = (gpointer) & ts;
00285 break;
00286 }
00287 #endif
00288 case KVP_TYPE_BOOLEAN :
00289 {
00290 break;
00291 }
00292 case KVP_TYPE_GUID:
00293 {
00294 break;
00295 }
00296 case KVP_TYPE_BINARY:
00297 {
00298 break;
00299 }
00300 case KVP_TYPE_GLIST:
00301 {
00302 break;
00303 }
00304 case KVP_TYPE_FRAME:
00305 {
00306 break;
00307 }
00308 }
00309 parent = g_strdup_printf ("/%s/%s", QOF_CONFIG_DESC, key);
00310 option.description = kvp_frame_get_string (helper->recursive, parent);
00311 g_free (parent);
00312 parent = g_strdup_printf ("/%s/%s", QOF_CONFIG_TIP, key);
00313 option.tooltip = kvp_frame_get_string (helper->recursive, parent);
00314 g_free (parent);
00315 helper->count++;
00316
00317 helper->fcn (&option, helper->data);
00318 switch (option.type)
00319 {
00320 case KVP_TYPE_GINT64:
00321 {
00322 kvp_frame_set_gint64 (helper->recursive, key,
00323 (*(gint64 *) option.value));
00324 break;
00325 }
00326 case KVP_TYPE_DOUBLE:
00327 {
00328 kvp_frame_set_double (helper->recursive, key,
00329 (*(gdouble *) option.value));
00330 break;
00331 }
00332 case KVP_TYPE_NUMERIC:
00333 {
00334 kvp_frame_set_numeric (helper->recursive, key,
00335 (*(QofNumeric *) option.value));
00336 break;
00337 }
00338 case KVP_TYPE_STRING:
00339 {
00340 kvp_frame_set_string (helper->recursive, key,
00341 (gchar *) option.value);
00342 break;
00343 }
00344 case KVP_TYPE_TIME :
00345 {
00346 kvp_frame_set_time (helper->recursive, key,
00347 (QofTime*) option.value);
00348 break;
00349 }
00350 #ifndef QOF_DISABLE_DEPRECATED
00351 case KVP_TYPE_TIMESPEC:
00352 {
00353 kvp_frame_set_timespec (helper->recursive, key,
00354 (*(Timespec *) option.value));
00355 break;
00356 }
00357 #endif
00358 case KVP_TYPE_BOOLEAN :
00359 {
00360 break;
00361 }
00362 case KVP_TYPE_GUID:
00363 {
00364 break;
00365 }
00366 case KVP_TYPE_BINARY:
00367 {
00368 break;
00369 }
00370 case KVP_TYPE_GLIST:
00371 {
00372 break;
00373 }
00374 case KVP_TYPE_FRAME:
00375 {
00376 break;
00377 }
00378 }
00379 LEAVE (" ");
00380 }
00381
00382 void
00383 qof_backend_option_foreach (KvpFrame * config,
00384 QofBackendOptionCB cb, gpointer data)
00385 {
00386 struct config_iterate helper;
00387
00388 if (!config || !cb)
00389 return;
00390 ENTER (" ");
00391 helper.fcn = cb;
00392 helper.count = 1;
00393 helper.data = data;
00394 helper.recursive = config;
00395 kvp_frame_for_each_slot (config, config_foreach_cb, &helper);
00396 LEAVE (" ");
00397 }
00398
00399 void
00400 qof_backend_load_config (QofBackend * be, KvpFrame * config)
00401 {
00402 if (!be || !config)
00403 return;
00404 if (!be->load_config)
00405 return;
00406 (be->load_config) (be, config);
00407 }
00408
00409 KvpFrame *
00410 qof_backend_get_config (QofBackend * be)
00411 {
00412 if (!be)
00413 return NULL;
00414 if (!be->get_config)
00415 return NULL;
00416 return (be->get_config) (be);
00417 }
00418
00419 gboolean
00420 qof_backend_commit_exists (QofBackend * be)
00421 {
00422 if (!be)
00423 return FALSE;
00424 if (be->commit)
00425 return TRUE;
00426 else
00427 return FALSE;
00428 }
00429
00430 gboolean
00431 qof_load_backend_library (const gchar * directory,
00432 const gchar * filename, const gchar * init_fcn)
00433 {
00434 gchar *fullpath;
00435 typedef void (*backend_init) (void);
00436 GModule *backend;
00437 backend_init gmod_init;
00438 gpointer g;
00439
00440 g_return_val_if_fail (g_module_supported (), FALSE);
00441 fullpath = g_module_build_path (directory, filename);
00442 backend = g_module_open (fullpath, G_MODULE_BIND_LAZY);
00443 if (!backend)
00444 {
00445 PERR (" No backend found. %s", g_module_error ());
00446 return FALSE;
00447 }
00448 g = &gmod_init;
00449 if (!g_module_symbol (backend, init_fcn, g))
00450 {
00451 PERR (" Backend did not initialise. %s", g_module_error ());
00452 return FALSE;
00453 }
00454 g_module_make_resident (backend);
00455 gmod_init ();
00456 g_free (fullpath);
00457 return TRUE;
00458 }
00459
00460