GnuCash 2.4.99
qofbackend.c
00001 /********************************************************************\
00002  * qofbackend.c -- utility routines for dealing with the data backend  *
00003  * Copyright (C) 2000 Linas Vepstas <linas@linas.org>               *
00004  * Copyright (C) 2004-5 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 <stdio.h>
00027 #include <stdlib.h>
00028 #include <stdarg.h>
00029 #include <regex.h>
00030 #include <glib.h>
00031 #include <gmodule.h>
00032 #include <errno.h>
00033 #include "qof.h"
00034 #include "qofbackend-p.h"
00035 
00036 static QofLogModule log_module = QOF_MOD_BACKEND;
00037 
00038 #define QOF_CONFIG_DESC    "desc"
00039 #define QOF_CONFIG_TIP     "tip"
00040 
00041 /* *******************************************************************\
00042  * error handling                                                   *
00043 \********************************************************************/
00044 
00045 void
00046 qof_backend_set_error (QofBackend *be, QofBackendError err)
00047 {
00048     if (!be) return;
00049 
00050     /* use stack-push semantics. Only the earliest error counts */
00051     if (ERR_BACKEND_NO_ERR != be->last_err) return;
00052     be->last_err = err;
00053 }
00054 
00055 QofBackendError
00056 qof_backend_get_error (QofBackend *be)
00057 {
00058     QofBackendError err;
00059     if (!be) return ERR_BACKEND_NO_BACKEND;
00060 
00061     /* use 'stack-pop' semantics */
00062     err = be->last_err;
00063     be->last_err = ERR_BACKEND_NO_ERR;
00064     return err;
00065 }
00066 
00067 void
00068 qof_backend_set_message (QofBackend *be, const char *format, ...)
00069 {
00070     va_list args;
00071     char * buffer;
00072 
00073     if (!be) return;
00074 
00075     /* If there's already something here, free it */
00076     if (be->error_msg) g_free(be->error_msg);
00077 
00078     if (!format)
00079     {
00080         be->error_msg = NULL;
00081         return;
00082     }
00083 
00084     va_start(args, format);
00085     buffer = (char *)g_strdup_vprintf(format, args);
00086     va_end(args);
00087 
00088     be->error_msg = buffer;
00089 }
00090 
00091 char *
00092 qof_backend_get_message (QofBackend *be)
00093 {
00094     char * msg;
00095 
00096     if (!be) return g_strdup("ERR_BACKEND_NO_BACKEND");
00097     if (!be->error_msg) return NULL;
00098 
00099     /*
00100      * Just return the contents of the error_msg and then set it to
00101      * NULL. This is necessary, because the Backends don't seem to
00102      * have a destroy_backend function to take care of freeing stuff
00103      * up. The calling function should free the copy.
00104      * Also, this is consistent with the qof_backend_get_error() popping.
00105      */
00106 
00107     msg = be->error_msg;
00108     be->error_msg = NULL;
00109     return msg;
00110 }
00111 
00112 /***********************************************************************/
00113 /* Get a clean backend */
00114 void
00115 qof_backend_init(QofBackend *be)
00116 {
00117     be->session_begin = NULL;
00118     be->session_end = NULL;
00119     be->destroy_backend = NULL;
00120 
00121     be->load = NULL;
00122 
00123     be->begin = NULL;
00124     be->commit = NULL;
00125     be->rollback = NULL;
00126 
00127     be->compile_query = NULL;
00128     be->free_query = NULL;
00129     be->run_query = NULL;
00130 
00131     be->sync = NULL;
00132     be->safe_sync = NULL;
00133     be->load_config = NULL;
00134 
00135     be->events_pending = NULL;
00136     be->process_events = NULL;
00137 
00138     be->last_err = ERR_BACKEND_NO_ERR;
00139     if (be->error_msg) g_free (be->error_msg);
00140     be->error_msg = NULL;
00141     be->percentage = NULL;
00142     be->backend_configuration = kvp_frame_new();
00143 
00144     /* to be removed */
00145     be->price_lookup = NULL;
00146     be->export_fn = NULL;
00147 }
00148 
00149 void
00150 qof_backend_destroy(QofBackend *be)
00151 {
00152     g_free(be->error_msg);
00153     be->error_msg = NULL;
00154     kvp_frame_delete(be->backend_configuration);
00155     be->backend_configuration = NULL;
00156 }
00157 
00158 void
00159 qof_backend_run_begin(QofBackend *be, QofInstance *inst)
00160 {
00161     if (!be || !inst)
00162     {
00163         return;
00164     }
00165     if (!be->begin)
00166     {
00167         return;
00168     }
00169     (be->begin) (be, inst);
00170 }
00171 
00172 gboolean
00173 qof_backend_begin_exists(const QofBackend *be)
00174 {
00175     if (be->begin)
00176     {
00177         return TRUE;
00178     }
00179     else
00180     {
00181         return FALSE;
00182     }
00183 }
00184 
00185 void
00186 qof_backend_run_commit(QofBackend *be, QofInstance *inst)
00187 {
00188     if (!be || !inst)
00189     {
00190         return;
00191     }
00192     if (!be->commit)
00193     {
00194         return;
00195     }
00196     (be->commit) (be, inst);
00197 }
00198 
00199 
00200 gboolean
00201 qof_backend_commit_exists(const QofBackend *be)
00202 {
00203     if (!be)
00204     {
00205         return FALSE;
00206     }
00207     if (be->commit)
00208     {
00209         return TRUE;
00210     }
00211     else
00212     {
00213         return FALSE;
00214     }
00215 }
00216 
00217 static GSList* backend_module_list = NULL;
00218 
00219 gboolean
00220 qof_load_backend_library (const char *directory, const char* module_name)
00221 {
00222     gchar *fullpath;
00223     GModule *backend;
00224     void (*module_init_func) (void);
00225 
00226     g_return_val_if_fail(g_module_supported(), FALSE);
00227     fullpath = g_module_build_path(directory, module_name);
00228     backend = g_module_open(fullpath, G_MODULE_BIND_LAZY);
00229     g_free(fullpath);
00230     if (!backend)
00231     {
00232         g_message ("%s: %s\n", PACKAGE, g_module_error ());
00233         return FALSE;
00234     }
00235     if (g_module_symbol(backend, "qof_backend_module_init",
00236                         (gpointer)&module_init_func))
00237         module_init_func();
00238 
00239     g_module_make_resident(backend);
00240     backend_module_list = g_slist_prepend( backend_module_list, backend );
00241     return TRUE;
00242 }
00243 
00244 void
00245 qof_finalize_backend_libraries(void)
00246 {
00247     GSList* node;
00248     GModule* backend;
00249     void (*module_finalize_func) (void);
00250 
00251     for (node = backend_module_list; node != NULL; node = node->next)
00252     {
00253         backend = (GModule*)node->data;
00254 
00255         if (g_module_symbol(backend, "qof_backend_module_finalize",
00256                             (gpointer)&module_finalize_func))
00257             module_finalize_func();
00258 
00259     }
00260 }
00261 
00262 /************************* END OF FILE ********************************/
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines