38 #include <sys/types.h>
44 #include "qoferror-p.h"
47 #include "qofsession-p.h"
50 #define _(String) dgettext (GETTEXT_PACKAGE, String)
52 static GHookList *session_closed_hooks = NULL;
54 static GSList *provider_list = NULL;
61 provider_list = g_slist_prepend (provider_list, prov);
73 if (session_closed_hooks == NULL)
75 session_closed_hooks = malloc (
sizeof (GHookList));
76 g_hook_list_init (session_closed_hooks,
sizeof (GHook));
79 hook = g_hook_alloc (session_closed_hooks);
83 hook->func = (GHookFunc) fn;
85 g_hook_append (session_closed_hooks, hook);
94 if (session_closed_hooks == NULL)
97 hook = g_hook_first_valid (session_closed_hooks, FALSE);
100 fn = (GFunc) hook->func;
101 fn (session, hook->data);
102 hook = g_hook_next_valid (session_closed_hooks, hook, FALSE);
114 #ifndef QOF_DISABLE_DEPRECATED
115 session->
entity.e_type = QOF_ID_SESSION;
118 session->book_id = NULL;
119 session->backend = NULL;
124 qof_session_new (
void)
127 qof_session_init (session);
138 for (node = session->books; node; node = node->next)
154 ENTER (
" sess=%p book=%p", session, addbook);
157 for (node = session->books; node; node = node->next)
170 g_list_free (session->books);
171 session->books = g_list_append (NULL, addbook);
176 session->books = g_list_append (session->books, addbook);
184 qof_session_get_backend (
QofSession * session)
188 return session->backend;
196 if (!session->backend)
206 return session->book_id;
211 typedef struct qof_entity_copy_data
216 GList *referenceList;
223 qof_book_set_partial (
QofBook * book)
241 GList *book_ref_list;
243 book = qof_session_get_book (session);
245 book_ref_list = g_list_append (book_ref_list, reference);
247 qof_book_set_partial (book);
251 qof_entity_param_cb (
QofParam * param, gpointer data)
253 QofEntityCopyData *qecd;
255 g_return_if_fail (data != NULL);
256 qecd = (QofEntityCopyData *) data;
257 g_return_if_fail (param != NULL);
259 if (0 ==
safe_strcmp (param->param_type, QOF_TYPE_KVP))
261 qecd->param_list = g_slist_prepend (qecd->param_list, param);
264 if ((param->param_getfcn != NULL) && (param->param_setfcn != NULL))
266 qecd->param_list = g_slist_prepend (qecd->param_list, param);
271 col_ref_cb (
QofEntity * ref_ent, gpointer user_data)
274 QofEntityCopyData *qecd;
280 qecd = (QofEntityCopyData *) user_data;
283 ref->
type = ent->e_type;
287 qecd->param->param_name);
290 cm_string = g_strdup (cm_sa);
302 QofEntityCopyData *context;
304 gboolean registered_type;
307 gchar *cm_string, *cm_char;
313 gdouble cm_double, (*double_getter) (QofEntity *,
QofParam *);
314 gboolean cm_boolean, (*boolean_getter) (QofEntity *,
QofParam *);
315 gint32 cm_i32, (*int32_getter) (QofEntity *,
QofParam *);
316 gint64 cm_i64, (*int64_getter) (QofEntity *,
QofParam *);
318 void (*string_setter) (QofEntity *,
const gchar *);
319 void (*numeric_setter) (QofEntity *,
QofNumeric);
320 void (*guid_setter) (QofEntity *,
const GUID *);
321 void (*double_setter) (QofEntity *, gdouble);
322 void (*boolean_setter) (QofEntity *, gboolean);
323 void (*i32_setter) (QofEntity *, gint32);
324 void (*i64_setter) (QofEntity *, gint64);
325 void (*char_setter) (QofEntity *, gchar *);
326 void (*kvp_frame_setter) (QofEntity *,
KvpFrame *);
328 g_return_if_fail (user_data != NULL);
329 context = (QofEntityCopyData *) user_data;
330 importEnt = context->from;
331 targetEnt = context->to;
332 registered_type = FALSE;
334 g_return_if_fail (cm_param != NULL);
335 context->param = cm_param;
336 if (
safe_strcmp (cm_param->param_type, QOF_TYPE_STRING) == 0)
338 cm_string = (gchar *) cm_param->param_getfcn (importEnt, cm_param);
342 (void (*)(QofEntity *,
343 const char *)) cm_param->param_setfcn;
344 if (string_setter != NULL)
347 string_setter (targetEnt, cm_string);
351 registered_type = TRUE;
353 if (
safe_strcmp (cm_param->param_type, QOF_TYPE_TIME) == 0)
356 void (*time_setter) (QofEntity *,
QofTime *);
358 qt = cm_param->param_getfcn (importEnt, cm_param);
360 (void (*)(QofEntity *,
QofTime*))cm_param->param_setfcn;
361 if (time_setter != NULL)
364 time_setter (targetEnt, qt);
367 registered_type = TRUE;
369 #ifndef QOF_DISABLE_DEPRECATED
373 void (*date_setter) (QofEntity *,
Timespec);
379 cm_date = date_getter (importEnt, cm_param);
381 (void (*)(QofEntity *,
Timespec)) cm_param->param_setfcn;
382 if (date_setter != NULL)
385 date_setter (targetEnt, cm_date);
388 registered_type = TRUE;
391 if ((
safe_strcmp (cm_param->param_type, QOF_TYPE_NUMERIC) == 0) ||
392 (
safe_strcmp (cm_param->param_type, QOF_TYPE_DEBCRED) == 0))
396 QofParam *)) cm_param->param_getfcn;
397 cm_numeric = numeric_getter (importEnt, cm_param);
399 (void (*)(QofEntity *,
QofNumeric)) cm_param->param_setfcn;
400 if (numeric_setter != NULL)
403 numeric_setter (targetEnt, cm_numeric);
406 registered_type = TRUE;
408 if (
safe_strcmp (cm_param->param_type, QOF_TYPE_GUID) == 0)
411 (
const GUID *) cm_param->param_getfcn (importEnt, cm_param);
413 (void (*)(QofEntity *,
const GUID *)) cm_param->param_setfcn;
414 if (guid_setter != NULL)
417 guid_setter (targetEnt, cm_guid);
420 registered_type = TRUE;
422 if (
safe_strcmp (cm_param->param_type, QOF_TYPE_INT32) == 0)
425 (gint32 (*)(QofEntity *,
QofParam *)) cm_param->param_getfcn;
426 cm_i32 = int32_getter (importEnt, cm_param);
428 (void (*)(QofEntity *, gint32)) cm_param->param_setfcn;
429 if (i32_setter != NULL)
432 i32_setter (targetEnt, cm_i32);
435 registered_type = TRUE;
437 if (
safe_strcmp (cm_param->param_type, QOF_TYPE_INT64) == 0)
440 (gint64 (*)(QofEntity *,
QofParam *)) cm_param->param_getfcn;
441 cm_i64 = int64_getter (importEnt, cm_param);
443 (void (*)(QofEntity *, gint64)) cm_param->param_setfcn;
444 if (i64_setter != NULL)
447 i64_setter (targetEnt, cm_i64);
450 registered_type = TRUE;
452 if (
safe_strcmp (cm_param->param_type, QOF_TYPE_DOUBLE) == 0)
455 (gdouble (*)(QofEntity *,
QofParam *)) cm_param->param_getfcn;
456 cm_double = double_getter (importEnt, cm_param);
458 (void (*)(QofEntity *, gdouble)) cm_param->param_setfcn;
459 if (double_setter != NULL)
462 double_setter (targetEnt, cm_double);
465 registered_type = TRUE;
467 if (
safe_strcmp (cm_param->param_type, QOF_TYPE_BOOLEAN) == 0)
470 (gboolean (*)(QofEntity *,
QofParam *)) cm_param->param_getfcn;
471 cm_boolean = boolean_getter (importEnt, cm_param);
473 (void (*)(QofEntity *, gboolean)) cm_param->param_setfcn;
474 if (boolean_setter != NULL)
477 boolean_setter (targetEnt, cm_boolean);
480 registered_type = TRUE;
482 if (
safe_strcmp (cm_param->param_type, QOF_TYPE_KVP) == 0)
484 cm_kvp = (
KvpFrame *) cm_param->param_getfcn (importEnt, cm_param);
486 (void (*)(QofEntity *,
KvpFrame *)) cm_param->param_setfcn;
487 if (kvp_frame_setter != NULL)
490 kvp_frame_setter (targetEnt, cm_kvp);
501 registered_type = TRUE;
503 if (
safe_strcmp (cm_param->param_type, QOF_TYPE_CHAR) == 0)
505 cm_char = (gchar *) cm_param->param_getfcn (importEnt, cm_param);
507 (void (*)(QofEntity *,
char *)) cm_param->param_setfcn;
508 if (char_setter != NULL)
511 char_setter (targetEnt, cm_char);
514 registered_type = TRUE;
519 (
QofCollection *) cm_param->param_getfcn (importEnt, cm_param);
525 registered_type = TRUE;
527 if (registered_type == FALSE)
551 g_return_val_if_fail (original != NULL, FALSE);
552 targetBook = qof_session_get_book (new_session);
553 g_return_val_if_fail (targetBook != NULL, FALSE);
555 type = g_strdup (original->e_type);
566 qof_entity_list_foreach (gpointer data, gpointer user_data)
568 QofEntityCopyData *qecd;
574 g_return_if_fail (data != NULL);
576 g_return_if_fail (user_data != NULL);
577 qecd = (QofEntityCopyData *) user_data;
578 if (qof_entity_guid_match (qecd->new_session, original))
582 qecd->from = original;
588 book = qof_session_get_book (qecd->new_session);
593 PERR (
" failed to create new entity type=%s.", original->e_type);
600 if (qecd->param_list != NULL)
602 g_slist_free (qecd->param_list);
603 qecd->param_list = NULL;
610 qof_entity_coll_foreach (
QofEntity * original, gpointer user_data)
612 QofEntityCopyData *qecd;
618 g_return_if_fail (user_data != NULL);
620 qecd = (QofEntityCopyData *) user_data;
621 targetBook = qof_session_get_book (qecd->new_session);
632 qof_entity_coll_copy (
QofEntity * original, gpointer user_data)
634 QofEntityCopyData *qecd;
639 g_return_if_fail (user_data != NULL);
640 qecd = (QofEntityCopyData *) user_data;
641 book = qof_session_get_book (qecd->new_session);
649 qecd->from = original;
658 QofEntityCopyData qecd;
662 if (!new_session || !original)
664 if (qof_entity_guid_match (new_session, original))
669 qecd.param_list = NULL;
670 book = qof_session_get_book (new_session);
671 qecd.new_session = new_session;
672 qof_book_set_partial (book);
676 qecd.from = original;
679 if (g_slist_length (qecd.param_list) == 0)
682 g_slist_free (qecd.param_list);
690 QofEntityCopyData *qecd;
692 if (!new_session || !entity_list)
694 ENTER (
" list=%d", g_list_length (entity_list));
695 qecd = g_new0 (QofEntityCopyData, 1);
697 qecd->param_list = NULL;
698 qecd->new_session = new_session;
699 qof_book_set_partial (qof_session_get_book (new_session));
700 g_list_foreach (entity_list, qof_entity_list_foreach, qecd);
703 PWARN (
" some/all entities in the list could not be copied.");
713 QofEntityCopyData qecd;
715 g_return_val_if_fail (new_session, FALSE);
721 qecd.param_list = NULL;
722 qecd.new_session = new_session;
723 qof_book_set_partial (qof_session_get_book (qecd.new_session));
726 qof_entity_param_cb, &qecd);
728 if (qecd.param_list != NULL)
730 g_slist_free (qecd.param_list);
745 recurse_collection_cb (
QofEntity * ent, gpointer user_data)
747 struct recurse_s *store;
749 if (user_data == NULL)
753 store = (
struct recurse_s *) user_data;
761 store->ent_list = g_list_append (store->ent_list, ent);
768 GList *ref_list, *i, *j, *ent_list, *child_list;
772 struct recurse_s *store;
775 if (user_data == NULL)
779 store = (
struct recurse_s *) user_data;
780 session = store->session;
781 success = store->success;
784 ref_list = g_list_copy (store->ref_list);
785 if ((!session) || (!ent))
793 for (i = ref_list; i != NULL; i = i->next)
800 if (ref_param->param_name == NULL)
808 col = ref_param->param_getfcn (ent, ref_param);
815 ref_ent = (
QofEntity *) ref_param->param_getfcn (ent, ref_param);
816 if ((ref_ent) && (ref_ent->e_type))
821 ent_list = g_list_append (ent_list, ref_ent);
825 for (i = ent_list; i != NULL; i = i->next)
832 if (child_ent == NULL)
837 for (j = ref_list; j != NULL; j = j->next)
844 ref_ent = ref_param->param_getfcn (child_ent, ref_param);
850 child_list = g_list_append (child_list, ref_ent);
855 for (i = child_list; i != NULL; i = i->next)
867 for (j = ref_list; j != NULL; j = j->next)
874 child_ent = ref_param->param_getfcn (ref_ent, ref_param);
875 if (child_ent != NULL)
886 struct recurse_s store;
889 if ((!new_session) || (!coll))
893 store.session = new_session;
895 store.success = success;
896 store.ent_list = NULL;
910 struct recurse_s store;
914 if ((!new_session) || (!ent))
918 store.session = new_session;
920 store.success = success;
942 struct backend_providers
945 const gchar *filename;
946 const gchar *init_fcn;
953 struct backend_providers backend_list[] = {
954 {QOF_LIB_DIR, QSF_BACKEND_LIB, QSF_MODULE_INIT},
955 {QOF_LIB_DIR,
"libqof-backend-sqlite",
"qof_sqlite_provider_init"},
957 {QOF_LIB_DIR,
"libqof-backend-gda",
"qof_gda_provider_init"},
960 {QOF_LIB_DIR,
"libqof_backend_dwi",
"dwiend_provider_init"},
966 qof_session_load_backend (
QofSession * session, gchar *access_method)
974 gboolean (*type_check) (
const gchar *);
976 ENTER (
" list=%d", g_slist_length (provider_list));
978 if (NULL == provider_list)
980 for (num = 0; backend_list[num].filename != NULL; num++)
983 backend_list[num].filename,
984 backend_list[num].init_fcn))
986 PWARN (
" failed to load %s from %s using %s",
987 backend_list[num].filename, backend_list[num].libdir,
988 backend_list[num].init_fcn);
992 p = g_slist_copy (provider_list);
1003 prov_type = (type_check) (session->book_id);
1018 session->backend->provider = prov;
1020 for (node = session->books; node; node = node->next)
1036 qof_session_destroy_backend (
QofSession * session)
1038 g_return_if_fail (session);
1040 if (session->backend)
1043 if (session->backend->destroy_backend)
1045 session->backend->destroy_backend (session->backend);
1049 g_free (session->backend);
1053 session->backend = NULL;
1058 gboolean ignore_lock, gboolean create_if_nonexistent)
1060 gchar *p, *access_method;
1065 ENTER (
" sess=%p ignore_lock=%d, book-id=%s",
1066 session, ignore_lock, book_id ? book_id :
"(null)");
1072 if (session->book_id)
1075 (_(
"This book appears to be open already."), FALSE));
1076 LEAVE (
" push error book is already open ");
1082 LEAVE (
" using stdout");
1087 session->book_id = g_strdup (book_id);
1090 qof_session_destroy_backend (session);
1096 p = strchr (book_id,
':');
1099 access_method = g_strdup (book_id);
1100 p = strchr (access_method,
':');
1102 qof_session_load_backend (session, access_method);
1103 g_free (access_method);
1108 qof_session_load_backend (session,
"file");
1112 if (NULL == session->backend)
1116 msg = g_strdup_printf (_(
"Unable to locate a "
1117 "suitable backend for '%s' - please check "
1118 "you have specified an access method "
1119 "like file: or sqlite:"), book_id);
1122 DEBUG (
" msg=%s", msg);
1123 LEAVE (
" BAD: no backend: sess=%p book-id=%s",
1124 session, book_id ? book_id :
"(null)");
1130 if (session->backend->session_begin)
1132 (session->backend->session_begin) (session->backend, session,
1133 session->book_id, ignore_lock, create_if_nonexistent);
1134 PINFO (
" Done running session_begin on backend");
1137 g_free (session->book_id);
1138 session->book_id = NULL;
1139 LEAVE (
" backend error ");
1144 LEAVE (
" sess=%p book-id=%s", session, book_id ? book_id :
"(null)");
1158 if ((!session->book_id) ||
1162 ENTER (
" sess=%p book_id=%s", session, session->book_id
1163 ? session->book_id :
"(null)");
1168 oldbooks = session->books;
1175 session->books = g_list_append (NULL, newbook);
1176 PINFO (
" new book=%p", newbook);
1187 be = session->backend;
1196 be->percentage = percentage_func;
1200 be->load (be, newbook);
1209 g_list_free (session->books);
1210 session->books = oldbooks;
1211 g_free (session->book_id);
1212 session->book_id = NULL;
1213 LEAVE (
" error from backend ");
1217 for (node = oldbooks; node; node = node->next)
1223 g_list_free (oldbooks);
1225 LEAVE (
" sess = %p, book_id=%s", session, session->book_id
1226 ? session->book_id :
"(null)");
1236 if (!session->backend)
1250 gboolean partial, change_backend;
1255 gchar *msg, *book_id;
1259 ENTER (
" sess=%p book_id=%s",
1260 session, session->book_id ? session->book_id :
"(null)");
1262 book = qof_session_get_book (session);
1266 change_backend = FALSE;
1267 msg = g_strdup_printf (
" ");
1268 book_id = g_strdup (session->book_id);
1269 if (partial == TRUE)
1271 if (session->backend && session->backend->provider)
1273 prov = session->backend->provider;
1277 change_backend = FALSE;
1281 change_backend = TRUE;
1287 change_backend = TRUE;
1290 if (change_backend == TRUE)
1292 qof_session_destroy_backend (session);
1293 if (NULL == provider_list)
1295 for (num = 0; backend_list[num].filename != NULL; num++)
1298 backend_list[num].filename,
1299 backend_list[num].init_fcn);
1302 p = g_slist_copy (provider_list);
1316 session->backend->provider = prov;
1317 if (session->backend->session_begin)
1322 g_free (session->book_id);
1323 session->book_id = NULL;
1324 (session->backend->session_begin) (session->backend,
1325 session, book_id, TRUE, TRUE);
1327 (
" Done running session_begin on changed backend");
1330 g_free (session->book_id);
1331 session->book_id = NULL;
1332 LEAVE (
" changed backend error");
1337 for (node = session->books; node; node = node->next)
1349 if (!session->backend)
1351 msg = g_strdup_printf (
" failed to load backend");
1353 (_(
"Failed to load backend, no suitable handler."),
1367 be = session->backend;
1370 for (node = session->books; node; node = node->next)
1375 be->percentage = percentage_func;
1377 (be->sync) (be, abook);
1388 msg = g_strdup_printf (
" failed to load backend");
1390 (_(
"Failed to load backend, no suitable handler."),
1393 LEAVE (
" error -- No backend!");
1404 ENTER (
" sess=%p book_id=%s", session, session->book_id
1405 ? session->book_id :
"(null)");
1408 if (session->backend && session->backend->session_end)
1410 (session->backend->session_end) (session->backend);
1415 g_free (session->book_id);
1416 session->book_id = NULL;
1418 LEAVE (
" sess=%p book_id=%s", session, session->book_id
1419 ? session->book_id :
"(null)");
1429 ENTER (
" sess=%p book_id=%s", session, session->book_id
1430 ? session->book_id :
"(null)");
1435 qof_session_destroy_backend (session);
1437 for (node = session->books; node; node = node->next)
1444 session->books = NULL;
1445 #ifndef QOF_DISABLE_DEPRECATED
1446 if (session == qof_session_get_current_session())
1447 qof_session_clear_current_session();
1452 LEAVE (
" sess=%p", session);
1460 GList *books_1, *books_2, *node;
1462 if (session_1 == session_2)
1464 if (!session_1 || !session_2)
1467 ENTER (
" sess1=%p sess2=%p", session_1, session_2);
1469 books_1 = session_1->books;
1470 books_2 = session_2->books;
1472 session_1->books = books_2;
1473 session_2->books = books_1;
1475 for (node = books_1; node; node = node->next)
1480 for (node = books_2; node; node = node->next)
1496 if (!session->backend)
1498 if (!session->backend->events_pending)
1501 return session->backend->events_pending (session->backend);
1509 if (!session->backend)
1511 if (!session->backend->process_events)
1514 return session->backend->process_events (session->backend);