QOF
0.7.5
|
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 ********************************/