00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00034 #include "config.h"
00035
00036 #include <stdlib.h>
00037 #include <string.h>
00038 #include <sys/types.h>
00039 #include <sys/stat.h>
00040 #include <unistd.h>
00041
00042 #include <glib.h>
00043 #include "qof.h"
00044 #include "qofbackend-p.h"
00045 #include "qofbook-p.h"
00046 #include "qofsession-p.h"
00047 #include "qofobject-p.h"
00048 #include "qofla-dir.h"
00049
00051 static QofSession * current_session = NULL;
00052
00053 static GHookList * session_closed_hooks = NULL;
00054 static QofLogModule log_module = QOF_MOD_SESSION;
00055 static GSList *provider_list = NULL;
00056 static gboolean qof_providers_initialized = FALSE;
00057
00058
00059
00060 void
00061 qof_backend_register_provider (QofBackendProvider *prov)
00062 {
00063 provider_list = g_slist_append (provider_list, prov);
00064 }
00065
00066 GList*
00067 qof_backend_get_registered_access_method_list(void)
00068 {
00069 GList* list = NULL;
00070 GSList* node;
00071
00072 for( node = provider_list; node != NULL; node = node->next ) {
00073 QofBackendProvider *prov = node->data;
00074 list = g_list_append( list, (gchar*)prov->access_method );
00075 }
00076
00077 return list;
00078 }
00079
00080
00081
00082
00083
00084 void
00085 qof_session_add_close_hook (GFunc fn, gpointer data)
00086 {
00087 GHook *hook;
00088
00089 if (session_closed_hooks == NULL) {
00090 session_closed_hooks = malloc(sizeof(GHookList));
00091 g_hook_list_init (session_closed_hooks, sizeof(GHook));
00092 }
00093
00094 hook = g_hook_alloc(session_closed_hooks);
00095 if (!hook)
00096 return;
00097
00098 hook->func = (GHookFunc)fn;
00099 hook->data = data;
00100 g_hook_append(session_closed_hooks, hook);
00101 }
00102
00103 void
00104 qof_session_call_close_hooks (QofSession *session)
00105 {
00106 GHook *hook;
00107 GFunc fn;
00108
00109 if (session_closed_hooks == NULL)
00110 return;
00111
00112 hook = g_hook_first_valid (session_closed_hooks, FALSE);
00113 while (hook) {
00114 fn = (GFunc)hook->func;
00115 fn(session, hook->data);
00116 hook = g_hook_next_valid (session_closed_hooks, hook, FALSE);
00117 }
00118 }
00119
00120
00121
00122
00123 static void
00124 qof_session_clear_error (QofSession *session)
00125 {
00126 QofBackendError err;
00127
00128 session->last_err = ERR_BACKEND_NO_ERR;
00129 g_free(session->error_message);
00130 session->error_message = NULL;
00131
00132
00133 if (session->backend)
00134 {
00135 do
00136 {
00137 err = qof_backend_get_error (session->backend);
00138 } while (ERR_BACKEND_NO_ERR != err);
00139 }
00140 }
00141
00142 void
00143 qof_session_push_error (QofSession *session, QofBackendError err,
00144 const char *message)
00145 {
00146 if (!session) return;
00147
00148 g_free (session->error_message);
00149
00150 session->last_err = err;
00151 session->error_message = g_strdup (message);
00152 }
00153
00154 QofBackendError
00155 qof_session_get_error (QofSession * session)
00156 {
00157 QofBackendError err;
00158
00159 if (!session) return ERR_BACKEND_NO_BACKEND;
00160
00161
00162 if (ERR_BACKEND_NO_ERR != session->last_err)
00163 {
00164 return session->last_err;
00165 }
00166
00167
00168 if (! session->backend) return ERR_BACKEND_NO_ERR;
00169
00170 err = qof_backend_get_error (session->backend);
00171 session->last_err = err;
00172 return err;
00173 }
00174
00175 static const char *
00176 get_default_error_message(QofBackendError err)
00177 {
00178 return "";
00179 }
00180
00181 const char *
00182 qof_session_get_error_message(const QofSession *session)
00183 {
00184 if(!session) return "";
00185 if(!session->error_message)
00186 return get_default_error_message(session->last_err);
00187 return session->error_message;
00188 }
00189
00190 QofBackendError
00191 qof_session_pop_error (QofSession * session)
00192 {
00193 QofBackendError err;
00194
00195 if (!session) return ERR_BACKEND_NO_BACKEND;
00196
00197 err = qof_session_get_error(session);
00198 qof_session_clear_error(session);
00199
00200 return err;
00201 }
00202
00203
00204
00205 static void
00206 qof_session_init (QofSession *session)
00207 {
00208 if (!session) return;
00209
00210 session->entity.e_type = QOF_ID_SESSION;
00211 session->books = g_list_append (NULL, qof_book_new ());
00212 session->book_id = NULL;
00213 session->backend = NULL;
00214 session->lock = 1;
00215
00216 qof_session_clear_error (session);
00217 }
00218
00219 QofSession *
00220 qof_session_new (void)
00221 {
00222 QofSession *session = g_new0(QofSession, 1);
00223 qof_session_init(session);
00224 return session;
00225 }
00226
00229 QofSession *
00230 qof_session_get_current_session (void)
00231 {
00232 if (!current_session)
00233 {
00234 qof_event_suspend ();
00235 current_session = qof_session_new ();
00236 qof_event_resume ();
00237 }
00238
00239 return current_session;
00240 }
00241
00244 void
00245 qof_session_set_current_session (QofSession *session)
00246 {
00247 current_session = session;
00248 }
00249
00250 QofBook *
00251 qof_session_get_book (const QofSession *session)
00252 {
00253 GList *node;
00254 if (!session) return NULL;
00255
00256 for (node=session->books; node; node=node->next)
00257 {
00258 QofBook *book = node->data;
00259 if ('y' == book->book_open) return book;
00260 }
00261 return NULL;
00262 }
00263
00264 void
00265 qof_session_add_book (QofSession *session, QofBook *addbook)
00266 {
00267 GList *node;
00268 if (!session) return;
00269
00270 ENTER (" sess=%p book=%p", session, addbook);
00271
00272
00273 for (node=session->books; node; node=node->next)
00274 {
00275 QofBook *book = node->data;
00276 if (addbook == book) return;
00277 }
00278
00279 if ('y' == addbook->book_open)
00280 {
00281
00282
00283
00284
00285 g_list_free (session->books);
00286 session->books = g_list_append (NULL, addbook);
00287 }
00288 else
00289 {
00290
00291 session->books = g_list_append (session->books, addbook);
00292 }
00293
00294 qof_book_set_backend (addbook, session->backend);
00295 LEAVE (" ");
00296 }
00297
00298 QofBackend *
00299 qof_session_get_backend (const QofSession *session)
00300 {
00301 if (!session) return NULL;
00302 return session->backend;
00303 }
00304
00305 const char *
00306 qof_session_get_file_path (const QofSession *session)
00307 {
00308 if (!session) return NULL;
00309 if (!session->backend) return NULL;
00310 return session->backend->fullpath;
00311 }
00312
00313 const char *
00314 qof_session_get_url (const QofSession *session)
00315 {
00316 if (!session) return NULL;
00317 return session->book_id;
00318 }
00319
00320
00321
00322 typedef struct qof_instance_copy_data {
00323 QofInstance *from;
00324 QofInstance *to;
00325 QofParam *param;
00326 GList *referenceList;
00327 GSList *param_list;
00328 QofSession *new_session;
00329 gboolean error;
00330 }QofInstanceCopyData;
00331
00332 static void
00333 qof_book_set_partial(QofBook *book)
00334 {
00335 gboolean partial;
00336
00337 partial =
00338 (gboolean)GPOINTER_TO_INT(qof_book_get_data(book, PARTIAL_QOFBOOK));
00339 if(!partial) {
00340 qof_book_set_data(book, PARTIAL_QOFBOOK, GINT_TO_POINTER(TRUE));
00341 }
00342 }
00343
00344 void
00345 qof_session_update_reference_list(QofSession *session, QofInstanceReference *reference)
00346 {
00347 QofBook *book;
00348 GList *book_ref_list;
00349
00350 book = qof_session_get_book(session);
00351 book_ref_list = (GList*)qof_book_get_data(book, ENTITYREFERENCE);
00352 book_ref_list = g_list_append(book_ref_list, reference);
00353 qof_book_set_data(book, ENTITYREFERENCE, book_ref_list);
00354 qof_book_set_partial(book);
00355 }
00356
00357 static void
00358 qof_instance_param_cb(QofParam *param, gpointer data)
00359 {
00360 QofInstanceCopyData *qecd;
00361
00362 g_return_if_fail(data != NULL);
00363 qecd = (QofInstanceCopyData*)data;
00364 g_return_if_fail(param != NULL);
00365
00366 if(0 == safe_strcmp(param->param_type, QOF_TYPE_KVP)) {
00367 qecd->param_list = g_slist_prepend(qecd->param_list, param);
00368 return;
00369 }
00370 if((param->param_getfcn != NULL)&&(param->param_setfcn != NULL)) {
00371 qecd->param_list = g_slist_prepend(qecd->param_list, param);
00372 }
00373 }
00374
00375 static void
00376 col_ref_cb (QofInstance* ref_ent, gpointer user_data)
00377 {
00378 QofInstanceReference *ref;
00379 QofInstanceCopyData *qecd;
00380 QofInstance *ent;
00381 const GUID *cm_guid;
00382 char cm_sa[GUID_ENCODING_LENGTH + 1];
00383 gchar *cm_string;
00384
00385 g_return_if_fail(user_data);
00386 qecd = (QofInstanceCopyData*)user_data;
00387 ent = qecd->from;
00388 g_return_if_fail(ent);
00389 ref = g_new0(QofInstanceReference, 1);
00390 ref->type = ent->e_type;
00391 ref->ref_guid = g_new(GUID, 1);
00392 ref->ent_guid = qof_instance_get_guid(ent);
00393 ref->param = qof_class_get_parameter(ent->e_type,
00394 qecd->param->param_name);
00395 cm_guid = qof_entity_get_guid(ref_ent);
00396 guid_to_string_buff(cm_guid, cm_sa);
00397 cm_string = g_strdup(cm_sa);
00398 if(TRUE == string_to_guid(cm_string, ref->ref_guid)) {
00399 g_free(cm_string);
00400 qof_session_update_reference_list(qecd->new_session, ref);
00401 }
00402 }
00403
00404 static void
00405 qof_instance_foreach_copy(gpointer data, gpointer user_data)
00406 {
00407 QofInstance *importEnt, *targetEnt;
00408 QofInstanceCopyData *context;
00409 QofInstanceReference *reference;
00410 gboolean registered_type;
00411
00412 QofParam *cm_param;
00413 gchar *cm_string, *cm_char;
00414 const GUID *cm_guid;
00415 KvpFrame *cm_kvp;
00416 QofCollection *cm_col;
00417
00418 gnc_numeric cm_numeric, (*numeric_getter) (QofInstance*, QofParam*);
00419 double cm_double, (*double_getter) (QofInstance*, QofParam*);
00420 gboolean cm_boolean, (*boolean_getter) (QofInstance*, QofParam*);
00421 gint32 cm_i32, (*int32_getter) (QofInstance*, QofParam*);
00422 gint64 cm_i64, (*int64_getter) (QofInstance*, QofParam*);
00423 Timespec cm_date, (*date_getter) (QofInstance*, QofParam*);
00424
00425 void (*string_setter) (QofInstance*, const char*);
00426 void (*date_setter) (QofInstance*, Timespec);
00427 void (*numeric_setter) (QofInstance*, gnc_numeric);
00428 void (*guid_setter) (QofInstance*, const GUID*);
00429 void (*double_setter) (QofInstance*, double);
00430 void (*boolean_setter) (QofInstance*, gboolean);
00431 void (*i32_setter) (QofInstance*, gint32);
00432 void (*i64_setter) (QofInstance*, gint64);
00433 void (*char_setter) (QofInstance*, char*);
00434 void (*kvp_frame_setter) (QofInstance*, KvpFrame*);
00435
00436 g_return_if_fail(user_data != NULL);
00437 context = (QofInstanceCopyData*) user_data;
00438 cm_date.tv_nsec = 0;
00439 cm_date.tv_sec = 0;
00440 importEnt = context->from;
00441 targetEnt = context->to;
00442 registered_type = FALSE;
00443 cm_param = (QofParam*) data;
00444 g_return_if_fail(cm_param != NULL);
00445 context->param = cm_param;
00446 if(safe_strcmp(cm_param->param_type, QOF_TYPE_STRING) == 0) {
00447 cm_string = (gchar*)cm_param->param_getfcn(importEnt, cm_param);
00448 if(cm_string) {
00449 string_setter = (void(*)(QofInstance*, const char*))cm_param->param_setfcn;
00450 if(string_setter != NULL) { string_setter(targetEnt, cm_string); }
00451 }
00452 registered_type = TRUE;
00453 }
00454 if(safe_strcmp(cm_param->param_type, QOF_TYPE_DATE) == 0) {
00455 date_getter = (Timespec (*)(QofInstance*, QofParam*))cm_param->param_getfcn;
00456 cm_date = date_getter(importEnt, cm_param);
00457 date_setter = (void(*)(QofInstance*, Timespec))cm_param->param_setfcn;
00458 if(date_setter != NULL) { date_setter(targetEnt, cm_date); }
00459 registered_type = TRUE;
00460 }
00461 if((safe_strcmp(cm_param->param_type, QOF_TYPE_NUMERIC) == 0) ||
00462 (safe_strcmp(cm_param->param_type, QOF_TYPE_DEBCRED) == 0)) {
00463 numeric_getter = (gnc_numeric (*)(QofInstance*, QofParam*))cm_param->param_getfcn;
00464 cm_numeric = numeric_getter(importEnt, cm_param);
00465 numeric_setter = (void(*)(QofInstance*, gnc_numeric))cm_param->param_setfcn;
00466 if(numeric_setter != NULL) { numeric_setter(targetEnt, cm_numeric); }
00467 registered_type = TRUE;
00468 }
00469 if(safe_strcmp(cm_param->param_type, QOF_TYPE_GUID) == 0) {
00470 cm_guid = (const GUID*)cm_param->param_getfcn(importEnt, cm_param);
00471 guid_setter = (void(*)(QofInstance*, const GUID*))cm_param->param_setfcn;
00472 if(guid_setter != NULL) { guid_setter(targetEnt, cm_guid); }
00473 registered_type = TRUE;
00474 }
00475 if(safe_strcmp(cm_param->param_type, QOF_TYPE_INT32) == 0) {
00476 int32_getter = (gint32 (*)(QofInstance*, QofParam*)) cm_param->param_getfcn;
00477 cm_i32 = int32_getter(importEnt, cm_param);
00478 i32_setter = (void(*)(QofInstance*, gint32))cm_param->param_setfcn;
00479 if(i32_setter != NULL) { i32_setter(targetEnt, cm_i32); }
00480 registered_type = TRUE;
00481 }
00482 if(safe_strcmp(cm_param->param_type, QOF_TYPE_INT64) == 0) {
00483 int64_getter = (gint64 (*)(QofInstance*, QofParam*)) cm_param->param_getfcn;
00484 cm_i64 = int64_getter(importEnt, cm_param);
00485 i64_setter = (void(*)(QofInstance*, gint64))cm_param->param_setfcn;
00486 if(i64_setter != NULL) { i64_setter(targetEnt, cm_i64); }
00487 registered_type = TRUE;
00488 }
00489 if(safe_strcmp(cm_param->param_type, QOF_TYPE_DOUBLE) == 0) {
00490 double_getter = (double (*)(QofInstance*, QofParam*)) cm_param->param_getfcn;
00491 cm_double = double_getter(importEnt, cm_param);
00492 double_setter = (void(*)(QofInstance*, double))cm_param->param_setfcn;
00493 if(double_setter != NULL) { double_setter(targetEnt, cm_double); }
00494 registered_type = TRUE;
00495 }
00496 if(safe_strcmp(cm_param->param_type, QOF_TYPE_BOOLEAN) == 0){
00497 boolean_getter = (gboolean (*)(QofInstance*, QofParam*)) cm_param->param_getfcn;
00498 cm_boolean = boolean_getter(importEnt, cm_param);
00499 boolean_setter = (void(*)(QofInstance*, gboolean))cm_param->param_setfcn;
00500 if(boolean_setter != NULL) { boolean_setter(targetEnt, cm_boolean); }
00501 registered_type = TRUE;
00502 }
00503 if(safe_strcmp(cm_param->param_type, QOF_TYPE_KVP) == 0) {
00504 cm_kvp = (KvpFrame*)cm_param->param_getfcn(importEnt,cm_param);
00505 kvp_frame_setter = (void(*)(QofInstance*, KvpFrame*))cm_param->param_setfcn;
00506 if(kvp_frame_setter != NULL) { kvp_frame_setter(targetEnt, cm_kvp); }
00507 else
00508 {
00509 QofInstance *target_inst;
00510
00511 target_inst = (QofInstance*)targetEnt;
00512 kvp_frame_delete(target_inst->kvp_data);
00513 target_inst->kvp_data = kvp_frame_copy(cm_kvp);
00514 }
00515 registered_type = TRUE;
00516 }
00517 if(safe_strcmp(cm_param->param_type, QOF_TYPE_CHAR) == 0) {
00518 cm_char = (gchar*)cm_param->param_getfcn(importEnt,cm_param);
00519 char_setter = (void(*)(QofInstance*, char*))cm_param->param_setfcn;
00520 if(char_setter != NULL) { char_setter(targetEnt, cm_char); }
00521 registered_type = TRUE;
00522 }
00523 if(safe_strcmp(cm_param->param_type, QOF_TYPE_COLLECT) == 0) {
00524 cm_col = (QofCollection*)cm_param->param_getfcn(importEnt, cm_param);
00525 if(cm_col)
00526 {
00527
00528 qof_collection_foreach(cm_col, col_ref_cb, context);
00529 }
00530 registered_type = TRUE;
00531 }
00532 if(registered_type == FALSE) {
00533
00534
00535
00536 reference = qof_instance_get_reference_from(importEnt, cm_param);
00537 if(reference) {
00538 qof_session_update_reference_list(context->new_session, reference);
00539 }
00540 }
00541 }
00542
00543 static gboolean
00544 qof_instance_guid_match(QofSession *new_session, QofInstance *original)
00545 {
00546 QofInstance *copy;
00547 const GUID *g;
00548 QofIdTypeConst type;
00549 QofBook *targetBook;
00550 QofCollection *coll;
00551
00552 copy = NULL;
00553 g_return_val_if_fail(original != NULL, FALSE);
00554 targetBook = qof_session_get_book(new_session);
00555 g_return_val_if_fail(targetBook != NULL, FALSE);
00556 g = qof_instance_get_guid(original);
00557 type = g_strdup(original->e_type);
00558 coll = qof_book_get_collection(targetBook, type);
00559 copy = qof_collection_lookup_entity(coll, g);
00560 if(copy) { return TRUE; }
00561 return FALSE;
00562 }
00563
00564 static void
00565 qof_instance_list_foreach(gpointer data, gpointer user_data)
00566 {
00567 QofInstanceCopyData *qecd;
00568 QofInstance *original;
00569 QofInstance *inst;
00570 QofBook *book;
00571 const GUID *g;
00572
00573 g_return_if_fail(data != NULL);
00574 original = QOF_INSTANCE(data);
00575 g_return_if_fail(user_data != NULL);
00576 qecd = (QofInstanceCopyData*)user_data;
00577 if(qof_instance_guid_match(qecd->new_session, original)) { return; }
00578 qecd->from = original;
00579 if(!qof_object_compliance(original->e_type, FALSE))
00580 {
00581 qecd->error = TRUE;
00582 return;
00583 }
00584 book = qof_session_get_book(qecd->new_session);
00585 inst = (QofInstance*)qof_object_new_instance(original->e_type, book);
00586 if(!inst)
00587 {
00588 PERR (" failed to create new entity type=%s.", original->e_type);
00589 qecd->error = TRUE;
00590 return;
00591 }
00592 qecd->to = inst;
00593 g = qof_instance_get_guid(original);
00594 qof_instance_set_guid(qecd->to, g);
00595 if(qecd->param_list != NULL) {
00596 g_slist_free(qecd->param_list);
00597 qecd->param_list = NULL;
00598 }
00599 qof_class_param_foreach(original->e_type, qof_instance_param_cb, qecd);
00600 qof_begin_edit(inst);
00601 g_slist_foreach(qecd->param_list, qof_instance_foreach_copy, qecd);
00602 qof_commit_edit(inst);
00603 }
00604
00605 static void
00606 qof_instance_coll_foreach(QofInstance *original, gpointer user_data)
00607 {
00608 QofInstanceCopyData *qecd;
00609 const GUID *g;
00610 QofBook *targetBook;
00611 QofCollection *coll;
00612 QofInstance *copy;
00613
00614 g_return_if_fail(original != NULL);
00615 g_return_if_fail(user_data != NULL);
00616 copy = NULL;
00617 qecd = (QofInstanceCopyData*)user_data;
00618 targetBook = qof_session_get_book(qecd->new_session);
00619 g = qof_instance_get_guid(original);
00620 coll = qof_book_get_collection(targetBook, original->e_type);
00621 copy = qof_collection_lookup_entity(coll, g);
00622 if(copy) { qecd->error = TRUE; }
00623 }
00624
00625 static void
00626 qof_instance_coll_copy(QofInstance *original, gpointer user_data)
00627 {
00628 QofInstanceCopyData *qecd;
00629 QofBook *book;
00630 QofInstance *inst;
00631 const GUID *g;
00632
00633 g_return_if_fail(original != NULL);
00634 g_return_if_fail(user_data != NULL);
00635 qecd = (QofInstanceCopyData*)user_data;
00636 book = qof_session_get_book(qecd->new_session);
00637 if(!qof_object_compliance(original->e_type, TRUE)) { return; }
00638 inst = (QofInstance*)qof_object_new_instance(original->e_type, book);
00639 qecd->to = inst;
00640 qecd->from = original;
00641 g = qof_instance_get_guid(original);
00642 qof_instance_set_guid(qecd->to, g);
00643 qof_begin_edit(inst);
00644 g_slist_foreach(qecd->param_list, qof_instance_foreach_copy, qecd);
00645 qof_commit_edit(inst);
00646 }
00647
00648 gboolean
00649 qof_instance_copy_to_session(QofSession* new_session, QofInstance* original)
00650 {
00651 QofInstanceCopyData qecd;
00652 QofInstance *inst;
00653 QofBook *book;
00654
00655 if(!new_session || !original) { return FALSE; }
00656 if(qof_instance_guid_match(new_session, original)) { return FALSE; }
00657 if(!qof_object_compliance(original->e_type, TRUE)) { return FALSE; }
00658 qof_event_suspend();
00659 qecd.param_list = NULL;
00660 book = qof_session_get_book(new_session);
00661 qecd.new_session = new_session;
00662 qof_book_set_partial(book);
00663 inst = (QofInstance*)qof_object_new_instance(original->e_type, book);
00664 qecd.to = inst;
00665 qecd.from = original;
00666 qof_instance_set_guid(qecd.to, qof_instance_get_guid(original));
00667 qof_begin_edit(inst);
00668 qof_class_param_foreach(original->e_type, qof_instance_param_cb, &qecd);
00669 qof_commit_edit(inst);
00670 if(g_slist_length(qecd.param_list) == 0) { return FALSE; }
00671 g_slist_foreach(qecd.param_list, qof_instance_foreach_copy, &qecd);
00672 g_slist_free(qecd.param_list);
00673 qof_event_resume();
00674 return TRUE;
00675 }
00676
00677 gboolean qof_instance_copy_list(QofSession *new_session, GList *entity_list)
00678 {
00679 QofInstanceCopyData *qecd;
00680
00681 if(!new_session || !entity_list) { return FALSE; }
00682 ENTER (" list=%d", g_list_length(entity_list));
00683 qecd = g_new0(QofInstanceCopyData, 1);
00684 qof_event_suspend();
00685 qecd->param_list = NULL;
00686 qecd->new_session = new_session;
00687 qof_book_set_partial(qof_session_get_book(new_session));
00688 g_list_foreach(entity_list, qof_instance_list_foreach, qecd);
00689 qof_event_resume();
00690 if(qecd->error)
00691 {
00692 PWARN (" some/all entities in the list could not be copied.");
00693 }
00694 g_free(qecd);
00695 LEAVE (" ");
00696 return TRUE;
00697 }
00698
00699 gboolean
00700 qof_instance_copy_coll(QofSession *new_session, QofCollection *entity_coll)
00701 {
00702 QofInstanceCopyData qecd;
00703
00704 g_return_val_if_fail(new_session, FALSE);
00705 if(!entity_coll) { return FALSE; }
00706 qof_event_suspend();
00707 qecd.param_list = NULL;
00708 qecd.new_session = new_session;
00709 qof_book_set_partial(qof_session_get_book(qecd.new_session));
00710 qof_collection_foreach(entity_coll, qof_instance_coll_foreach, &qecd);
00711 qof_class_param_foreach(qof_collection_get_type(entity_coll),
00712 qof_instance_param_cb, &qecd);
00713 qof_collection_foreach(entity_coll, qof_instance_coll_copy, &qecd);
00714 if(qecd.param_list != NULL) { g_slist_free(qecd.param_list); }
00715 qof_event_resume();
00716 return TRUE;
00717 }
00718
00719 struct recurse_s
00720 {
00721 QofSession *session;
00722 gboolean success;
00723 GList *ref_list;
00724 GList *ent_list;
00725 };
00726
00727 static void
00728 recurse_collection_cb (QofInstance *ent, gpointer user_data)
00729 {
00730 struct recurse_s *store;
00731
00732 if(user_data == NULL) { return; }
00733 store = (struct recurse_s*)user_data;
00734 if(!ent || !store) { return; }
00735 store->success = qof_instance_copy_to_session(store->session, ent);
00736 if(store->success) {
00737 store->ent_list = g_list_append(store->ent_list, ent);
00738 }
00739 }
00740
00741 static void
00742 recurse_ent_cb(QofInstance *ent, gpointer user_data)
00743 {
00744 GList *ref_list, *i, *j, *ent_list, *child_list;
00745 QofParam *ref_param;
00746 QofInstance *ref_ent, *child_ent;
00747 QofSession *session;
00748 struct recurse_s *store;
00749 gboolean success;
00750
00751 if(user_data == NULL) { return; }
00752 store = (struct recurse_s*)user_data;
00753 session = store->session;
00754 success = store->success;
00755 ref_list = NULL;
00756 child_ent = NULL;
00757 ref_list = g_list_copy(store->ref_list);
00758 if((!session)||(!ent)) { return; }
00759 ent_list = NULL;
00760 child_list = NULL;
00761 i = NULL;
00762 j = NULL;
00763 for(i = ref_list; i != NULL; i=i->next)
00764 {
00765 if(i->data == NULL) { continue; }
00766 ref_param = (QofParam*)i->data;
00767 if(ref_param->param_name == NULL) { continue; }
00768 if(0 == safe_strcmp(ref_param->param_type, QOF_TYPE_COLLECT)) {
00769 QofCollection *col;
00770
00771 col = ref_param->param_getfcn(ent, ref_param);
00772 if(col) {
00773 qof_collection_foreach(col, recurse_collection_cb, store);
00774 }
00775 continue;
00776 }
00777 ref_ent = QOF_INSTANCE(ref_param->param_getfcn(ent, ref_param));
00778 if((ref_ent)&&(ref_ent->e_type))
00779 {
00780 store->success = qof_instance_copy_to_session(session, ref_ent);
00781 if(store->success) { ent_list = g_list_append(ent_list, ref_ent); }
00782 }
00783 }
00784 for(i = ent_list; i != NULL; i = i->next)
00785 {
00786 if(i->data == NULL) { continue; }
00787 child_ent = QOF_INSTANCE(i->data);
00788 if(child_ent == NULL) { continue; }
00789 ref_list = qof_class_get_referenceList(child_ent->e_type);
00790 for(j = ref_list; j != NULL; j = j->next)
00791 {
00792 if(j->data == NULL) { continue; }
00793 ref_param = (QofParam*)j->data;
00794 ref_ent = ref_param->param_getfcn(child_ent, ref_param);
00795 if(ref_ent != NULL)
00796 {
00797 success = qof_instance_copy_to_session(session, ref_ent);
00798 if(success) { child_list = g_list_append(child_list, ref_ent); }
00799 }
00800 }
00801 }
00802 for(i = child_list; i != NULL; i = i->next)
00803 {
00804 if(i->data == NULL) { continue; }
00805 ref_ent = QOF_INSTANCE(i->data);
00806 if(ref_ent == NULL) { continue; }
00807 ref_list = qof_class_get_referenceList(ref_ent->e_type);
00808 for(j = ref_list; j != NULL; j = j->next)
00809 {
00810 if(j->data == NULL) { continue; }
00811 ref_param = (QofParam*)j->data;
00812 child_ent = ref_param->param_getfcn(ref_ent, ref_param);
00813 if(child_ent != NULL)
00814 {
00815 qof_instance_copy_to_session(session, child_ent);
00816 }
00817 }
00818 }
00819 }
00820
00821 gboolean
00822 qof_instance_copy_coll_r(QofSession *new_session, QofCollection *coll)
00823 {
00824 struct recurse_s store;
00825 gboolean success;
00826
00827 if((!new_session)||(!coll)) { return FALSE; }
00828 store.session = new_session;
00829 success = TRUE;
00830 store.success = success;
00831 store.ent_list = NULL;
00832 store.ref_list = qof_class_get_referenceList(qof_collection_get_type(coll));
00833 success = qof_instance_copy_coll(new_session, coll);
00834 if(success){ qof_collection_foreach(coll, recurse_ent_cb, &store); }
00835 return success;
00836 }
00837
00838 gboolean qof_instance_copy_one_r(QofSession *new_session, QofInstance *ent)
00839 {
00840 struct recurse_s store;
00841 QofCollection *coll;
00842 gboolean success;
00843
00844 if((!new_session)||(!ent)) { return FALSE; }
00845 store.session = new_session;
00846 success = TRUE;
00847 store.success = success;
00848 store.ref_list = qof_class_get_referenceList(ent->e_type);
00849 success = qof_instance_copy_to_session(new_session, ent);
00850 if(success == TRUE) {
00851 coll = qof_book_get_collection(qof_session_get_book(new_session), ent->e_type);
00852 if(coll) { qof_collection_foreach(coll, recurse_ent_cb, &store); }
00853 }
00854 return success;
00855 }
00856
00857
00858
00859
00863 struct backend_providers
00864 {
00865 const char *libdir;
00866 const char *filename;
00867 };
00868
00869
00870
00871
00872
00873 struct backend_providers backend_list[] = {
00874 { QOF_LIB_DIR, QSF_BACKEND_LIB },
00875 #ifdef HAVE_DWI
00876 { QOF_LIB_DIR, "libqof_backend_dwi"},
00877 #endif
00878 { NULL, NULL }
00879 };
00880
00881 static void
00882 qof_session_load_backend(QofSession * session, const char * access_method)
00883 {
00884 GSList *p;
00885 GList *node;
00886 QofBackendProvider *prov;
00887 QofBook *book;
00888 char *msg;
00889 gint num;
00890 gboolean prov_type;
00891 gboolean (*type_check) (const char*);
00892 gchar *libdir_from_env = NULL;
00893
00894 ENTER (" list=%d, initted=%s", g_slist_length(provider_list),
00895 qof_providers_initialized ? "true" : "false");
00896 prov_type = FALSE;
00897 if (!qof_providers_initialized)
00898 {
00899 libdir_from_env = g_strdup(g_getenv("QOF_LIB_DIR"));
00900 for (num = 0; backend_list[num].filename != NULL; num++) {
00901 if (libdir_from_env) {
00902 if (!(qof_load_backend_library(libdir_from_env,
00903 backend_list[num].filename)
00904 || qof_load_backend_library(backend_list[num].libdir,
00905 backend_list[num].filename)))
00906 {
00907 PWARN (" failed to load %s from %s or %s",
00908 backend_list[num].filename, libdir_from_env,
00909 backend_list[num].libdir);
00910 }
00911 } else {
00912 if (!qof_load_backend_library(backend_list[num].libdir,
00913 backend_list[num].filename)) {
00914 PWARN (" failed to load %s from %s",
00915 backend_list[num].filename, backend_list[num].libdir);
00916 }
00917 }
00918 }
00919 g_free(libdir_from_env);
00920 qof_providers_initialized = TRUE;
00921 }
00922 p = provider_list;
00923 while(p != NULL)
00924 {
00925 prov = p->data;
00926
00927 if (0 == strcasecmp (access_method, prov->access_method))
00928 {
00929
00930
00931 type_check = (gboolean (*)(const char*)) prov->check_data_type;
00932 if (type_check) {
00933 prov_type = (type_check)(session->book_id);
00934 if (!prov_type) {
00935 PINFO(" %s not usable", prov->provider_name);
00936 p = p->next;
00937 continue;
00938 }
00939 }
00940 PINFO (" selected %s", prov->provider_name);
00941 if (NULL == prov->backend_new)
00942 {
00943 p = p->next;
00944 continue;
00945 }
00946
00947 session->backend = (*(prov->backend_new))();
00948 session->backend->provider = prov;
00949
00950 for (node=session->books; node; node=node->next)
00951 {
00952 book = node->data;
00953 qof_book_set_backend (book, session->backend);
00954 }
00955 LEAVE (" ");
00956 return;
00957 }
00958 p = p->next;
00959 }
00960 msg = g_strdup_printf("failed to load '%s' using access_method", access_method);
00961 qof_session_push_error (session, ERR_BACKEND_NO_HANDLER, msg);
00962 LEAVE (" ");
00963 }
00964
00965
00966
00967 static void
00968 qof_session_destroy_backend (QofSession *session)
00969 {
00970 g_return_if_fail (session);
00971
00972 if (session->backend)
00973 {
00974
00975 char * msg = qof_backend_get_message (session->backend);
00976 g_free (msg);
00977
00978
00979 if (session->backend->destroy_backend)
00980 {
00981 session->backend->destroy_backend(session->backend);
00982 }
00983 else
00984 {
00985 g_free(session->backend);
00986 }
00987 }
00988
00989 session->backend = NULL;
00990 }
00991
00992 void
00993 qof_session_begin (QofSession *session, const char * book_id,
00994 gboolean ignore_lock, gboolean create_if_nonexistent)
00995 {
00996 char *p, *access_method, *msg;
00997 int err;
00998
00999 if (!session) return;
01000
01001 ENTER (" sess=%p ignore_lock=%d, book-id=%s",
01002 session, ignore_lock,
01003 book_id ? book_id : "(null)");
01004
01005
01006 qof_session_clear_error (session);
01007
01008
01009 if (session->book_id)
01010 {
01011 qof_session_push_error (session, ERR_BACKEND_LOCKED, NULL);
01012 LEAVE("push error book is already open ");
01013 return;
01014 }
01015
01016
01017 if (!book_id)
01018 {
01019 qof_session_push_error (session, ERR_BACKEND_BAD_URL, NULL);
01020 LEAVE("push error missing book_id");
01021 return;
01022 }
01023
01024
01025 qof_session_destroy_backend(session);
01026
01027
01028 session->book_id = g_strdup (book_id);
01029
01030
01031
01032
01033
01034 p = strchr (book_id, ':');
01035 if (p)
01036 {
01037 access_method = g_strdup (book_id);
01038 p = strchr (access_method, ':');
01039 *p = '\0';
01040 qof_session_load_backend(session, access_method);
01041 g_free (access_method);
01042 #ifdef G_OS_WIN32
01043 if (NULL == session->backend)
01044 {
01045
01046 qof_session_clear_error (session);
01047
01048
01049
01050
01051 qof_session_load_backend(session, "file");
01052 }
01053 #endif
01054 }
01055 else
01056 {
01057
01058 qof_session_load_backend(session, "file");
01059 }
01060
01061
01062 if (NULL == session->backend)
01063 {
01064 g_free(session->book_id);
01065 session->book_id = NULL;
01066 qof_session_push_error (session, ERR_BACKEND_BAD_URL, NULL);
01067 LEAVE (" BAD: no backend: sess=%p book-id=%s",
01068 session, book_id ? book_id : "(null)");
01069 return;
01070 }
01071
01072
01073 if (session->backend->session_begin)
01074 {
01075
01076 (session->backend->session_begin)(session->backend, session,
01077 session->book_id, ignore_lock,
01078 create_if_nonexistent);
01079