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 }
00056
00057 void
00058 qof_backend_run_begin (QofBackend * be, QofInstance * inst)
00059 {
00060 if (!be || !inst)
00061 return;
00062 if (!be->begin)
00063 return;
00064 (be->begin) (be, inst);
00065 }
00066
00067 gboolean
00068 qof_backend_begin_exists (QofBackend * be)
00069 {
00070 if (be->begin)
00071 return TRUE;
00072 else
00073 return FALSE;
00074 }
00075
00076 void
00077 qof_backend_run_commit (QofBackend * be, QofInstance * inst)
00078 {
00079 if (!be || !inst)
00080 return;
00081 if (!be->commit)
00082 return;
00083 (be->commit) (be, inst);
00084 }
00085
00086
00087
00088 void
00089 qof_backend_prepare_frame (QofBackend * be)
00090 {
00091 g_return_if_fail (be);
00092 if (!kvp_frame_is_empty (be->backend_configuration))
00093 {
00094 kvp_frame_delete (be->backend_configuration);
00095 be->backend_configuration = kvp_frame_new ();
00096 }
00097 be->config_count = 0;
00098 }
00099
00100 void
00101 qof_backend_prepare_option (QofBackend * be,
00102 QofBackendOption * option)
00103 {
00104 KvpValue *value;
00105 gchar *temp;
00106 gint count;
00107
00108 g_return_if_fail (be || option);
00109 count = be->config_count;
00110 count++;
00111 value = NULL;
00112 switch (option->type)
00113 {
00114 case KVP_TYPE_GINT64:
00115 {
00116 value = kvp_value_new_gint64 (*(gint64 *) option->value);
00117 break;
00118 }
00119 case KVP_TYPE_DOUBLE:
00120 {
00121 value = kvp_value_new_double (*(gdouble *) option->value);
00122 break;
00123 }
00124 case KVP_TYPE_NUMERIC:
00125 {
00126 value = kvp_value_new_numeric (*(QofNumeric *) option->value);
00127 break;
00128 }
00129 case KVP_TYPE_STRING:
00130 {
00131 value = kvp_value_new_string ((const gchar *) option->value);
00132 break;
00133 }
00134 case KVP_TYPE_BOOLEAN:
00135 {
00136 break;
00137 }
00138 case KVP_TYPE_GUID:
00139 {
00140 break;
00141 }
00142 case KVP_TYPE_TIME :
00143 {
00144 value = kvp_value_new_time ((QofTime*) option->value);
00145 break;
00146 }
00147 case KVP_TYPE_BINARY:
00148 {
00149 break;
00150 }
00151 case KVP_TYPE_GLIST:
00152 {
00153 break;
00154 }
00155 case KVP_TYPE_FRAME:
00156 {
00157 break;
00158 }
00159 }
00160 if (value)
00161 {
00162 temp = g_strdup_printf ("/%s", option->option_name);
00163 kvp_frame_set_value (be->backend_configuration, temp, value);
00164 g_free (temp);
00165 temp =
00166 g_strdup_printf ("/%s/%s", QOF_CONFIG_DESC,
00167 option->option_name);
00168 kvp_frame_set_string (be->backend_configuration, temp,
00169 option->description);
00170 g_free (temp);
00171 temp =
00172 g_strdup_printf ("/%s/%s", QOF_CONFIG_TIP,
00173 option->option_name);
00174 kvp_frame_set_string (be->backend_configuration, temp,
00175 option->tooltip);
00176 g_free (temp);
00177
00178 be->config_count = count;
00179 }
00180 }
00181
00182 KvpFrame *
00183 qof_backend_complete_frame (QofBackend * be)
00184 {
00185 g_return_val_if_fail (be, NULL);
00186 be->config_count = 0;
00187 return be->backend_configuration;
00188 }
00189
00190 struct config_iterate
00191 {
00192 QofBackendOptionCB fcn;
00193 gpointer data;
00194 gint count;
00195 KvpFrame *recursive;
00196 };
00197
00198
00199
00200
00201
00202 static void
00203 config_foreach_cb (const gchar * key, KvpValue * value, gpointer data)
00204 {
00205 QofBackendOption option;
00206 gint64 int64;
00207 gdouble db;
00208 QofNumeric num;
00209 gchar *parent;
00210 struct config_iterate *helper;
00211
00212 g_return_if_fail (key || value || data);
00213 helper = (struct config_iterate *) data;
00214 if (!helper->recursive)
00215 {
00216 PERR (" no parent frame");
00217 return;
00218 }
00219
00220 if (0 == safe_strcmp (key, QOF_CONFIG_DESC))
00221 {
00222 return;
00223 }
00224 if (0 == safe_strcmp (key, QOF_CONFIG_TIP))
00225 {
00226 return;
00227 }
00228 ENTER (" key=%s", key);
00229 option.option_name = key;
00230 option.type = kvp_value_get_type (value);
00231 if (!option.type)
00232 return;
00233 switch (option.type)
00234 {
00235 case KVP_TYPE_GINT64:
00236 {
00237 int64 = kvp_value_get_gint64 (value);
00238 option.value = (gpointer) & int64;
00239 break;
00240 }
00241 case KVP_TYPE_DOUBLE:
00242 {
00243 db = kvp_value_get_double (value);
00244 option.value = (gpointer) & db;
00245 break;
00246 }
00247 case KVP_TYPE_NUMERIC:
00248 {
00249 num = kvp_value_get_numeric (value);
00250 option.value = (gpointer) & num;
00251 break;
00252 }
00253 case KVP_TYPE_STRING:
00254 {
00255 option.value = (gpointer) kvp_value_get_string (value);
00256 break;
00257 }
00258 case KVP_TYPE_TIME :
00259 {
00260 option.value = (gpointer) kvp_value_get_time (value);
00261 }
00262 case KVP_TYPE_BOOLEAN :
00263 {
00264 break;
00265 }
00266 case KVP_TYPE_GUID:
00267 {
00268 break;
00269 }
00270 case KVP_TYPE_BINARY:
00271 {
00272 break;
00273 }
00274 case KVP_TYPE_GLIST:
00275 {
00276 break;
00277 }
00278 case KVP_TYPE_FRAME:
00279 {
00280 break;
00281 }
00282 }
00283 parent = g_strdup_printf ("/%s/%s", QOF_CONFIG_DESC, key);
00284 option.description = kvp_frame_get_string (helper->recursive, parent);
00285 g_free (parent);
00286 parent = g_strdup_printf ("/%s/%s", QOF_CONFIG_TIP, key);
00287 option.tooltip = kvp_frame_get_string (helper->recursive, parent);
00288 g_free (parent);
00289 helper->count++;
00290
00291 helper->fcn (&option, helper->data);
00292 switch (option.type)
00293 {
00294 case KVP_TYPE_GINT64:
00295 {
00296 kvp_frame_set_gint64 (helper->recursive, key,
00297 (*(gint64 *) option.value));
00298 break;
00299 }
00300 case KVP_TYPE_DOUBLE:
00301 {
00302 kvp_frame_set_double (helper->recursive, key,
00303 (*(gdouble *) option.value));
00304 break;
00305 }
00306 case KVP_TYPE_NUMERIC:
00307 {
00308 kvp_frame_set_numeric (helper->recursive, key,
00309 (*(QofNumeric *) option.value));
00310 break;
00311 }
00312 case KVP_TYPE_STRING:
00313 {
00314 kvp_frame_set_string (helper->recursive, key,
00315 (gchar *) option.value);
00316 break;
00317 }
00318 case KVP_TYPE_TIME :
00319 {
00320 kvp_frame_set_time (helper->recursive, key,
00321 (QofTime*) option.value);
00322 break;
00323 }
00324 case KVP_TYPE_BOOLEAN :
00325 {
00326 break;
00327 }
00328 case KVP_TYPE_GUID:
00329 {
00330 break;
00331 }
00332 case KVP_TYPE_BINARY:
00333 {
00334 break;
00335 }
00336 case KVP_TYPE_GLIST:
00337 {
00338 break;
00339 }
00340 case KVP_TYPE_FRAME:
00341 {
00342 break;
00343 }
00344 }
00345 LEAVE (" ");
00346 }
00347
00348 void
00349 qof_backend_option_foreach (KvpFrame * config,
00350 QofBackendOptionCB cb, gpointer data)
00351 {
00352 struct config_iterate helper;
00353
00354 if (!config || !cb)
00355 return;
00356 ENTER (" ");
00357 helper.fcn = cb;
00358 helper.count = 1;
00359 helper.data = data;
00360 helper.recursive = config;
00361 kvp_frame_for_each_slot (config, config_foreach_cb, &helper);
00362 LEAVE (" ");
00363 }
00364
00365 void
00366 qof_backend_load_config (QofBackend * be, KvpFrame * config)
00367 {
00368 if (!be || !config)
00369 return;
00370 if (!be->load_config)
00371 return;
00372 (be->load_config) (be, config);
00373 }
00374
00375 KvpFrame *
00376 qof_backend_get_config (QofBackend * be)
00377 {
00378 if (!be)
00379 return NULL;
00380 if (!be->get_config)
00381 return NULL;
00382 return (be->get_config) (be);
00383 }
00384
00385 gboolean
00386 qof_backend_commit_exists (QofBackend * be)
00387 {
00388 if (!be)
00389 return FALSE;
00390 if (be->commit)
00391 return TRUE;
00392 else
00393 return FALSE;
00394 }
00395
00396 gboolean
00397 qof_load_backend_library (const gchar * directory,
00398 const gchar * filename, const gchar * init_fcn)
00399 {
00400 gchar *fullpath;
00401 typedef void (*backend_init) (void);
00402 GModule *backend;
00403 backend_init gmod_init;
00404 gpointer g;
00405
00406 g_return_val_if_fail (g_module_supported (), FALSE);
00407 fullpath = g_module_build_path (directory, filename);
00408 backend = g_module_open (fullpath, G_MODULE_BIND_LAZY);
00409 if (!backend)
00410 {
00411 PERR (" No backend found. %s", g_module_error ());
00412 return FALSE;
00413 }
00414 g = &gmod_init;
00415 if (!g_module_symbol (backend, init_fcn, g))
00416 {
00417 PERR (" Backend did not initialise. %s", g_module_error ());
00418 return FALSE;
00419 }
00420 g_module_make_resident (backend);
00421 gmod_init ();
00422 g_free (fullpath);
00423 return TRUE;
00424 }
00425
00426