qofbackend.c

00001 /********************************************************************\
00002  * qofbackend.c -- utility routines for the data backend            *
00003  * Copyright (C) 2000 Linas Vepstas <linas@linas.org>               *
00004  * Copyright (C) 2004-2006 Neil Williams <linux@codehelp.co.uk>     *
00005  *                                                                  *
00006  * This program is free software; you can redistribute it and/or    *
00007  * modify it under the terms of the GNU General Public License as   *
00008  * published by the Free Software Foundation; either version 2 of   *
00009  * the License, or (at your option) any later version.              *
00010  *                                                                  *
00011  * This program is distributed in the hope that it will be useful,  *
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
00014  * GNU General Public License for more details.                     *
00015  *                                                                  *
00016  * You should have received a copy of the GNU General Public License*
00017  * along with this program; if not, contact:                        *
00018  *                                                                  *
00019  * Free Software Foundation           Voice:  +1-617-542-5942       *
00020  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
00021  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
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 /* =========== Backend Configuration ================ */
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         }                       /* unsupported */
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         }                       /* unsupported */
00168         case KVP_TYPE_GLIST:
00169         {
00170             break;
00171         }                       /* unsupported */
00172         case KVP_TYPE_FRAME:
00173         {
00174             break;
00175         }                       /* unsupported */
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         /* only increment the counter if successful */
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 /* Set the option with the default KvpValue,
00216 manipulate the option in the supplied callback routine
00217 then set the value of the option into the KvpValue
00218 in the configuration frame. */
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     // skip the presets.
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     {                           /* set the KvpFrame value into the option */
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         }                       /* unsupported */
00296         case KVP_TYPE_BINARY:
00297         {
00298             break;
00299         }                       /* unsupported */
00300         case KVP_TYPE_GLIST:
00301         {
00302             break;
00303         }                       /* unsupported */
00304         case KVP_TYPE_FRAME:
00305         {
00306             break;
00307         }                       /* unsupported */
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     /* manipulate the option */
00317     helper->fcn (&option, helper->data);
00318     switch (option.type)
00319     {                           /* set the option value into the KvpFrame */
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         }                       /* unsupported */
00366         case KVP_TYPE_BINARY:
00367         {
00368             break;
00369         }                       /* unsupported */
00370         case KVP_TYPE_GLIST:
00371         {
00372             break;
00373         }                       /* unsupported */
00374         case KVP_TYPE_FRAME:
00375         {
00376             break;
00377         }                       /* unsupported */
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 /************************* END OF FILE ********************************/

Generated on Thu Jan 31 22:50:25 2008 for QOF by  doxygen 1.5.4