QOF 0.8.2

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-2008 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 }
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 /* =========== Backend Configuration ================ */
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         }                       /* unsupported */
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         }                       /* unsupported */
00151         case KVP_TYPE_GLIST:
00152         {
00153             break;
00154         }                       /* unsupported */
00155         case KVP_TYPE_FRAME:
00156         {
00157             break;
00158         }                       /* unsupported */
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         /* only increment the counter if successful */
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 /* Set the option with the default KvpValue,
00199 manipulate the option in the supplied callback routine
00200 then set the value of the option into the KvpValue
00201 in the configuration frame. */
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     // skip the presets.
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     {                           /* set the KvpFrame value into the option */
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         }                       /* unsupported */
00270         case KVP_TYPE_BINARY:
00271         {
00272             break;
00273         }                       /* unsupported */
00274         case KVP_TYPE_GLIST:
00275         {
00276             break;
00277         }                       /* unsupported */
00278         case KVP_TYPE_FRAME:
00279         {
00280             break;
00281         }                       /* unsupported */
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     /* manipulate the option */
00291     helper->fcn (&option, helper->data);
00292     switch (option.type)
00293     {                           /* set the option value into the KvpFrame */
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         }                       /* unsupported */
00332         case KVP_TYPE_BINARY:
00333         {
00334             break;
00335         }                       /* unsupported */
00336         case KVP_TYPE_GLIST:
00337         {
00338             break;
00339         }                       /* unsupported */
00340         case KVP_TYPE_FRAME:
00341         {
00342             break;
00343         }                       /* unsupported */
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 /************************* END OF FILE ********************************/