QOF: qofsession.c Source File

QOF 0.7.5

qofsession.c
Go to the documentation of this file.
1 /********************************************************************\
2 * qofsesssion.c -- session access (connection to backend) *
3 * *
4 * This program is free software; you can redistribute it and/or *
5 * modify it under the terms of the GNU General Public License as *
6 * published by the Free Software Foundation; either version 2 of *
7 * the License, or (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License*
15 * along with this program; if not, contact: *
16 * *
17 * Free Software Foundation Voice: +1-617-542-5942 *
18 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
19 * Boston, MA 02110-1301, USA gnu@gnu.org *
20 \********************************************************************/
21
34 #include "config.h"
35
36 #include <stdlib.h>
37 #include <string.h>
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <unistd.h>
41 #include <glib.h>
42 #include <libintl.h>
43 #include "qof.h"
44 #include "qoferror-p.h"
45 #include "qofbackend-p.h"
46 #include "qofbook-p.h"
47 #include "qofsession-p.h"
48 #include "qofobject-p.h"
49
50 #define _(String) dgettext (GETTEXT_PACKAGE, String)
51
52 static GHookList *session_closed_hooks = NULL;
53 static QofLogModule log_module = QOF_MOD_SESSION;
54 static GSList *provider_list = NULL;
55
56 /* ============================================================= */
57
58 void
59 qof_backend_register_provider (QofBackendProvider * prov)
60 {
61 provider_list = g_slist_prepend (provider_list, prov);
62 }
63
64 /* =========================================================== */
65
66 /* hook routines */
67
68 void
69 qof_session_add_close_hook (GFunc fn, gpointer data)
70 {
71 GHook *hook;
72
73 if (session_closed_hooks == NULL)
74 {
75 session_closed_hooks = malloc (sizeof (GHookList)); /* LEAKED */
76 g_hook_list_init (session_closed_hooks, sizeof (GHook));
77 }
78
79 hook = g_hook_alloc (session_closed_hooks);
80 if (!hook)
81 return;
82
83 hook->func = (GHookFunc) fn;
84 hook->data = data;
85 g_hook_append (session_closed_hooks, hook);
86 }
87
88 void
89 qof_session_call_close_hooks (QofSession * session)
90 {
91 GHook *hook;
92 GFunc fn;
93
94 if (session_closed_hooks == NULL)
95 return;
96
97 hook = g_hook_first_valid (session_closed_hooks, FALSE);
98 while (hook)
99 {
100 fn = (GFunc) hook->func;
101 fn (session, hook->data);
102 hook = g_hook_next_valid (session_closed_hooks, hook, FALSE);
103 }
104 }
105
106 /* =============================================================== */
107
108 static void
109 qof_session_init (QofSession * session)
110 {
111 if (!session)
112 return;
113
114 #ifndef QOF_DISABLE_DEPRECATED
115 session->entity.e_type = QOF_ID_SESSION;
116 #endif
117 session->books = g_list_append (NULL, qof_book_new ());
118 session->book_id = NULL;
119 session->backend = NULL;
120 qof_error_init ();
121 }
122
123 QofSession *
124 qof_session_new (void)
125 {
126 QofSession *session = g_new0 (QofSession, 1);
127 qof_session_init (session);
128 return session;
129 }
130
131 QofBook *
132 qof_session_get_book (QofSession * session)
133 {
134 GList *node;
135 if (!session)
136 return NULL;
137
138 for (node = session->books; node; node = node->next)
139 {
140 QofBook *book = node->data;
141 if ('y' == book->book_open)
142 return book;
143 }
144 return NULL;
145 }
146
147 void
148 qof_session_add_book (QofSession * session, QofBook * addbook)
149 {
150 GList *node;
151 if (!session)
152 return;
153
154 ENTER (" sess=%p book=%p", session, addbook);
155
156 /* See if this book is already there ... */
157 for (node = session->books; node; node = node->next)
158 {
159 QofBook *book = node->data;
160 if (addbook == book)
161 return;
162 }
163
164 if ('y' == addbook->book_open)
165 {
166 /* hack alert -- someone should free all the books in the list,
167 * but it should probably not be us ... since the books backends
168 * should be shutdown first, etc */
169 /* XXX this should probably be an error XXX */
170 g_list_free (session->books);
171 session->books = g_list_append (NULL, addbook);
172 }
173 else
174 {
175 /* XXX Need to tell the backend to add a book as well */
176 session->books = g_list_append (session->books, addbook);
177 }
178
179 qof_book_set_backend (addbook, session->backend);
180 LEAVE (" ");
181 }
182
183 QofBackend *
184 qof_session_get_backend (QofSession * session)
185 {
186 if (!session)
187 return NULL;
188 return session->backend;
189 }
190
191 const gchar *
192 qof_session_get_file_path (QofSession * session)
193 {
194 if (!session)
195 return NULL;
196 if (!session->backend)
197 return NULL;
198 return session->backend->fullpath;
199 }
200
201 const gchar *
202 qof_session_get_url (QofSession * session)
203 {
204 if (!session)
205 return NULL;
206 return session->book_id;
207 }
208
209 /* =============================================================== */
210
211 typedef struct qof_entity_copy_data
212 {
213 QofEntity *from;
214 QofEntity *to;
215 QofParam *param;
216 GList *referenceList;
217 GSList *param_list;
218 QofSession *new_session;
219 gboolean error;
220 } QofEntityCopyData;
221
222 static void
223 qof_book_set_partial (QofBook * book)
224 {
225 gboolean partial;
226
227 partial =
228 (gboolean)
229 GPOINTER_TO_INT (qof_book_get_data (book, PARTIAL_QOFBOOK));
230 if (!partial)
231 {
232 qof_book_set_data (book, PARTIAL_QOFBOOK, GINT_TO_POINTER (TRUE));
233 }
234 }
235
236 void
237 qof_session_update_reference_list (QofSession * session,
238 QofEntityReference * reference)
239 {
240 QofBook *book;
241 GList *book_ref_list;
242
243 book = qof_session_get_book (session);
244 book_ref_list = (GList *) qof_book_get_data (book, ENTITYREFERENCE);
245 book_ref_list = g_list_append (book_ref_list, reference);
246 qof_book_set_data (book, ENTITYREFERENCE, book_ref_list);
247 qof_book_set_partial (book);
248 }
249
250 static void
251 qof_entity_param_cb (QofParam * param, gpointer data)
252 {
253 QofEntityCopyData *qecd;
254
255 g_return_if_fail (data != NULL);
256 qecd = (QofEntityCopyData *) data;
257 g_return_if_fail (param != NULL);
258 /* KVP doesn't need a set routine to be copied. */
259 if (0 == safe_strcmp (param->param_type, QOF_TYPE_KVP))
260 {
261 qecd->param_list = g_slist_prepend (qecd->param_list, param);
262 return;
263 }
264 if ((param->param_getfcn != NULL) && (param->param_setfcn != NULL))
265 {
266 qecd->param_list = g_slist_prepend (qecd->param_list, param);
267 }
268 }
269
270 static void
271 col_ref_cb (QofEntity * ref_ent, gpointer user_data)
272 {
273 QofEntityReference *ref;
274 QofEntityCopyData *qecd;
275 QofEntity *ent;
276 const GUID *cm_guid;
277 gchar cm_sa[GUID_ENCODING_LENGTH + 1];
278 gchar *cm_string;
279
280 qecd = (QofEntityCopyData *) user_data;
281 ent = qecd->from;
282 ref = g_new0 (QofEntityReference, 1);
283 ref->type = ent->e_type;
284 ref->ref_guid = g_new (GUID, 1);
285 ref->ent_guid = &ent->guid;
286 ref->param = qof_class_get_parameter (ent->e_type,
287 qecd->param->param_name);
288 cm_guid = qof_entity_get_guid (ref_ent);
289 guid_to_string_buff (cm_guid, cm_sa);
290 cm_string = g_strdup (cm_sa);
291 if (TRUE == string_to_guid (cm_string, ref->ref_guid))
292 {
293 g_free (cm_string);
294 qof_session_update_reference_list (qecd->new_session, ref);
295 }
296 }
297
298 static void
299 qof_entity_foreach_copy (gpointer data, gpointer user_data)
300 {
301 QofEntity *importEnt, *targetEnt /*, *referenceEnt */ ;
302 QofEntityCopyData *context;
303 QofEntityReference *reference;
304 gboolean registered_type;
305 /* cm_ prefix used for variables that hold the data to commit */
306 QofParam *cm_param;
307 gchar *cm_string, *cm_char;
308 const GUID *cm_guid;
309 KvpFrame *cm_kvp;
310 QofCollection *cm_col;
311 /* function pointers and variables for parameter getters that don't use pointers normally */
312 QofNumeric cm_numeric, (*numeric_getter) (QofEntity *, QofParam *);
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 *);
317 /* function pointers to the parameter setters */
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 *);
327
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;
333 cm_param = (QofParam *) data;
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)
337 {
338 cm_string = (gchar *) cm_param->param_getfcn (importEnt, cm_param);
339 if (cm_string)
340 {
341 string_setter =
342 (void (*)(QofEntity *,
343 const char *)) cm_param->param_setfcn;
344 if (string_setter != NULL)
345 {
346 qof_util_param_edit ((QofInstance *) targetEnt, cm_param);
347 string_setter (targetEnt, cm_string);
348 qof_util_param_commit ((QofInstance *) targetEnt, cm_param);
349 }
350 }
351 registered_type = TRUE;
352 }
353 if (safe_strcmp (cm_param->param_type, QOF_TYPE_TIME) == 0)
354 {
355 QofTime *qt;
356 void (*time_setter) (QofEntity *, QofTime *);
357
358 qt = cm_param->param_getfcn (importEnt, cm_param);
359 time_setter =
360 (void (*)(QofEntity *, QofTime*))cm_param->param_setfcn;
361 if (time_setter != NULL)
362 {
363 qof_util_param_edit ((QofInstance *) targetEnt, cm_param);
364 time_setter (targetEnt, qt);
365 qof_util_param_commit ((QofInstance *) targetEnt, cm_param);
366 }
367 registered_type = TRUE;
368 }
369 #ifndef QOF_DISABLE_DEPRECATED
370 if (safe_strcmp (cm_param->param_type, QOF_TYPE_DATE) == 0)
371 {
372 Timespec cm_date, (*date_getter) (QofEntity *, QofParam *);
373 void (*date_setter) (QofEntity *, Timespec);
374
375 cm_date.tv_nsec = 0;
376 cm_date.tv_sec = 0;
377 date_getter =
378 (Timespec (*)(QofEntity *, QofParam *)) cm_param->param_getfcn;
379 cm_date = date_getter (importEnt, cm_param);
380 date_setter =
381 (void (*)(QofEntity *, Timespec)) cm_param->param_setfcn;
382 if (date_setter != NULL)
383 {
384 qof_util_param_edit ((QofInstance *) targetEnt, cm_param);
385 date_setter (targetEnt, cm_date);
386 qof_util_param_commit ((QofInstance *) targetEnt, cm_param);
387 }
388 registered_type = TRUE;
389 }
390 #endif
391 if ((safe_strcmp (cm_param->param_type, QOF_TYPE_NUMERIC) == 0) ||
392 (safe_strcmp (cm_param->param_type, QOF_TYPE_DEBCRED) == 0))
393 {
394 numeric_getter =
395 (QofNumeric (*)(QofEntity *,
396 QofParam *)) cm_param->param_getfcn;
397 cm_numeric = numeric_getter (importEnt, cm_param);
398 numeric_setter =
399 (void (*)(QofEntity *, QofNumeric)) cm_param->param_setfcn;
400 if (numeric_setter != NULL)
401 {
402 qof_util_param_edit ((QofInstance *) targetEnt, cm_param);
403 numeric_setter (targetEnt, cm_numeric);
404 qof_util_param_commit ((QofInstance *) targetEnt, cm_param);
405 }
406 registered_type = TRUE;
407 }
408 if (safe_strcmp (cm_param->param_type, QOF_TYPE_GUID) == 0)
409 {
410 cm_guid =
411 (const GUID *) cm_param->param_getfcn (importEnt, cm_param);
412 guid_setter =
413 (void (*)(QofEntity *, const GUID *)) cm_param->param_setfcn;
414 if (guid_setter != NULL)
415 {
416 qof_util_param_edit ((QofInstance *) targetEnt, cm_param);
417 guid_setter (targetEnt, cm_guid);
418 qof_util_param_commit ((QofInstance *) targetEnt, cm_param);
419 }
420 registered_type = TRUE;
421 }
422 if (safe_strcmp (cm_param->param_type, QOF_TYPE_INT32) == 0)
423 {
424 int32_getter =
425 (gint32 (*)(QofEntity *, QofParam *)) cm_param->param_getfcn;
426 cm_i32 = int32_getter (importEnt, cm_param);
427 i32_setter =
428 (void (*)(QofEntity *, gint32)) cm_param->param_setfcn;
429 if (i32_setter != NULL)
430 {
431 qof_util_param_edit ((QofInstance *) targetEnt, cm_param);
432 i32_setter (targetEnt, cm_i32);
433 qof_util_param_commit ((QofInstance *) targetEnt, cm_param);
434 }
435 registered_type = TRUE;
436 }
437 if (safe_strcmp (cm_param->param_type, QOF_TYPE_INT64) == 0)
438 {
439 int64_getter =
440 (gint64 (*)(QofEntity *, QofParam *)) cm_param->param_getfcn;
441 cm_i64 = int64_getter (importEnt, cm_param);
442 i64_setter =
443 (void (*)(QofEntity *, gint64)) cm_param->param_setfcn;
444 if (i64_setter != NULL)
445 {
446 qof_util_param_edit ((QofInstance *) targetEnt, cm_param);
447 i64_setter (targetEnt, cm_i64);
448 qof_util_param_commit ((QofInstance *) targetEnt, cm_param);
449 }
450 registered_type = TRUE;
451 }
452 if (safe_strcmp (cm_param->param_type, QOF_TYPE_DOUBLE) == 0)
453 {
454 double_getter =
455 (gdouble (*)(QofEntity *, QofParam *)) cm_param->param_getfcn;
456 cm_double = double_getter (importEnt, cm_param);
457 double_setter =
458 (void (*)(QofEntity *, gdouble)) cm_param->param_setfcn;
459 if (double_setter != NULL)
460 {
461 qof_util_param_edit ((QofInstance *) targetEnt, cm_param);
462 double_setter (targetEnt, cm_double);
463 qof_util_param_commit ((QofInstance *) targetEnt, cm_param);
464 }
465 registered_type = TRUE;
466 }
467 if (safe_strcmp (cm_param->param_type, QOF_TYPE_BOOLEAN) == 0)
468 {
469 boolean_getter =
470 (gboolean (*)(QofEntity *, QofParam *)) cm_param->param_getfcn;
471 cm_boolean = boolean_getter (importEnt, cm_param);
472 boolean_setter =
473 (void (*)(QofEntity *, gboolean)) cm_param->param_setfcn;
474 if (boolean_setter != NULL)
475 {
476 qof_util_param_edit ((QofInstance *) targetEnt, cm_param);
477 boolean_setter (targetEnt, cm_boolean);
478 qof_util_param_commit ((QofInstance *) targetEnt, cm_param);
479 }
480 registered_type = TRUE;
481 }
482 if (safe_strcmp (cm_param->param_type, QOF_TYPE_KVP) == 0)
483 {
484 cm_kvp = (KvpFrame *) cm_param->param_getfcn (importEnt, cm_param);
485 kvp_frame_setter =
486 (void (*)(QofEntity *, KvpFrame *)) cm_param->param_setfcn;
487 if (kvp_frame_setter != NULL)
488 {
489 qof_util_param_edit ((QofInstance *) targetEnt, cm_param);
490 kvp_frame_setter (targetEnt, cm_kvp);
491 qof_util_param_commit ((QofInstance *) targetEnt, cm_param);
492 }
493 else
494 {
495 QofInstance *target_inst;
496
497 target_inst = (QofInstance *) targetEnt;
498 kvp_frame_delete (target_inst->kvp_data);
499 target_inst->kvp_data = kvp_frame_copy (cm_kvp);
500 }
501 registered_type = TRUE;
502 }
503 if (safe_strcmp (cm_param->param_type, QOF_TYPE_CHAR) == 0)
504 {
505 cm_char = (gchar *) cm_param->param_getfcn (importEnt, cm_param);
506 char_setter =
507 (void (*)(QofEntity *, char *)) cm_param->param_setfcn;
508 if (char_setter != NULL)
509 {
510 qof_util_param_edit ((QofInstance *) targetEnt, cm_param);
511 char_setter (targetEnt, cm_char);
512 qof_util_param_commit ((QofInstance *) targetEnt, cm_param);
513 }
514 registered_type = TRUE;
515 }
516 if (safe_strcmp (cm_param->param_type, QOF_TYPE_COLLECT) == 0)
517 {
518 cm_col =
519 (QofCollection *) cm_param->param_getfcn (importEnt, cm_param);
520 if (cm_col)
521 {
522 /* create one reference for each member of the collection. */
523 qof_collection_foreach (cm_col, col_ref_cb, context);
524 }
525 registered_type = TRUE;
526 }
527 if (registered_type == FALSE)
528 {
529 /* referenceEnt = (QofEntity*)cm_param->param_getfcn(importEnt, cm_param);
530 if(!referenceEnt) { return; }
531 if(!referenceEnt->e_type) { return; }*/
532 reference = qof_entity_get_reference_from (importEnt, cm_param);
533 if (reference)
534 {
535 qof_session_update_reference_list (context->new_session,
536 reference);
537 }
538 }
539 }
540
541 static gboolean
542 qof_entity_guid_match (QofSession * new_session, QofEntity * original)
543 {
544 QofEntity *copy;
545 const GUID *g;
546 QofIdTypeConst type;
547 QofBook *targetBook;
548 QofCollection *coll;
549
550 copy = NULL;
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);
554 g = qof_entity_get_guid (original);
555 type = g_strdup (original->e_type);
556 coll = qof_book_get_collection (targetBook, type);
557 copy = qof_collection_lookup_entity (coll, g);
558 if (copy)
559 {
560 return TRUE;
561 }
562 return FALSE;
563 }
564
565 static void
566 qof_entity_list_foreach (gpointer data, gpointer user_data)
567 {
568 QofEntityCopyData *qecd;
569 QofEntity *original;
570 QofInstance *inst;
571 QofBook *book;
572 const GUID *g;
573
574 g_return_if_fail (data != NULL);
575 original = (QofEntity *) data;
576 g_return_if_fail (user_data != NULL);
577 qecd = (QofEntityCopyData *) user_data;
578 if (qof_entity_guid_match (qecd->new_session, original))
579 {
580 return;
581 }
582 qecd->from = original;
583 if (!qof_object_compliance (original->e_type, FALSE))
584 {
585 qecd->error = TRUE;
586 return;
587 }
588 book = qof_session_get_book (qecd->new_session);
589 inst =
590 (QofInstance *) qof_object_new_instance (original->e_type, book);
591 if (!inst)
592 {
593 PERR (" failed to create new entity type=%s.", original->e_type);
594 qecd->error = TRUE;
595 return;
596 }
597 qecd->to = &inst->entity;
598 g = qof_entity_get_guid (original);
599 qof_entity_set_guid (qecd->to, g);
600 if (qecd->param_list != NULL)
601 {
602 g_slist_free (qecd->param_list);
603 qecd->param_list = NULL;
604 }
605 qof_class_param_foreach (original->e_type, qof_entity_param_cb, qecd);
606 g_slist_foreach (qecd->param_list, qof_entity_foreach_copy, qecd);
607 }
608
609 static void
610 qof_entity_coll_foreach (QofEntity * original, gpointer user_data)
611 {
612 QofEntityCopyData *qecd;
613 const GUID *g;
614 QofBook *targetBook;
615 QofCollection *coll;
616 QofEntity *copy;
617
618 g_return_if_fail (user_data != NULL);
619 copy = NULL;
620 qecd = (QofEntityCopyData *) user_data;
621 targetBook = qof_session_get_book (qecd->new_session);
622 g = qof_entity_get_guid (original);
623 coll = qof_book_get_collection (targetBook, original->e_type);
624 copy = qof_collection_lookup_entity (coll, g);
625 if (copy)
626 {
627 qecd->error = TRUE;
628 }
629 }
630
631 static void
632 qof_entity_coll_copy (QofEntity * original, gpointer user_data)
633 {
634 QofEntityCopyData *qecd;
635 QofBook *book;
636 QofInstance *inst;
637 const GUID *g;
638
639 g_return_if_fail (user_data != NULL);
640 qecd = (QofEntityCopyData *) user_data;
641 book = qof_session_get_book (qecd->new_session);
642 if (!qof_object_compliance (original->e_type, TRUE))
643 {
644 return;
645 }
646 inst =
647 (QofInstance *) qof_object_new_instance (original->e_type, book);
648 qecd->to = &inst->entity;
649 qecd->from = original;
650 g = qof_entity_get_guid (original);
651 qof_entity_set_guid (qecd->to, g);
652 g_slist_foreach (qecd->param_list, qof_entity_foreach_copy, qecd);
653 }
654
655 gboolean
656 qof_entity_copy_to_session (QofSession * new_session, QofEntity * original)
657 {
658 QofEntityCopyData qecd;
659 QofInstance *inst;
660 QofBook *book;
661
662 if (!new_session || !original)
663 return FALSE;
664 if (qof_entity_guid_match (new_session, original))
665 return FALSE;
666 if (!qof_object_compliance (original->e_type, TRUE))
667 return FALSE;
668 qof_event_suspend ();
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);
673 inst =
674 (QofInstance *) qof_object_new_instance (original->e_type, book);
675 qecd.to = &inst->entity;
676 qecd.from = original;
677 qof_entity_set_guid (qecd.to, qof_entity_get_guid (original));
678 qof_class_param_foreach (original->e_type, qof_entity_param_cb, &qecd);
679 if (g_slist_length (qecd.param_list) == 0)
680 return FALSE;
681 g_slist_foreach (qecd.param_list, qof_entity_foreach_copy, &qecd);
682 g_slist_free (qecd.param_list);
683 qof_event_resume ();
684 return TRUE;
685 }
686
687 gboolean
688 qof_entity_copy_list (QofSession * new_session, GList * entity_list)
689 {
690 QofEntityCopyData *qecd;
691
692 if (!new_session || !entity_list)
693 return FALSE;
694 ENTER (" list=%d", g_list_length (entity_list));
695 qecd = g_new0 (QofEntityCopyData, 1);
696 qof_event_suspend ();
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);
701 qof_event_resume ();
702 if (qecd->error)
703 PWARN (" some/all entities in the list could not be copied.");
704 g_free (qecd);
705 LEAVE (" ");
706 return TRUE;
707 }
708
709 gboolean
710 qof_entity_copy_coll (QofSession * new_session,
711 QofCollection * entity_coll)
712 {
713 QofEntityCopyData qecd;
714
715 g_return_val_if_fail (new_session, FALSE);
716 if (!entity_coll)
717 {
718 return FALSE;
719 }
720 qof_event_suspend ();
721 qecd.param_list = NULL;
722 qecd.new_session = new_session;
723 qof_book_set_partial (qof_session_get_book (qecd.new_session));
724 qof_collection_foreach (entity_coll, qof_entity_coll_foreach, &qecd);
725 qof_class_param_foreach (qof_collection_get_type (entity_coll),
726 qof_entity_param_cb, &qecd);
727 qof_collection_foreach (entity_coll, qof_entity_coll_copy, &qecd);
728 if (qecd.param_list != NULL)
729 {
730 g_slist_free (qecd.param_list);
731 }
732 qof_event_resume ();
733 return TRUE;
734 }
735
736 struct recurse_s
737 {
738 QofSession *session;
739 gboolean success;
740 GList *ref_list;
741 GList *ent_list;
742 };
743
744 static void
745 recurse_collection_cb (QofEntity * ent, gpointer user_data)
746 {
747 struct recurse_s *store;
748
749 if (user_data == NULL)
750 {
751 return;
752 }
753 store = (struct recurse_s *) user_data;
754 if (!ent || !store)
755 {
756 return;
757 }
758 store->success = qof_entity_copy_to_session (store->session, ent);
759 if (store->success)
760 {
761 store->ent_list = g_list_append (store->ent_list, ent);
762 }
763 }
764
765 static void
766 recurse_ent_cb (QofEntity * ent, gpointer user_data)
767 {
768 GList *ref_list, *i, *j, *ent_list, *child_list;
769 QofParam *ref_param;
770 QofEntity *ref_ent, *child_ent;
771 QofSession *session;
772 struct recurse_s *store;
773 gboolean success;
774
775 if (user_data == NULL)
776 {
777 return;
778 }
779 store = (struct recurse_s *) user_data;
780 session = store->session;
781 success = store->success;
782 ref_list = NULL;
783 child_ent = NULL;
784 ref_list = g_list_copy (store->ref_list);
785 if ((!session) || (!ent))
786 {
787 return;
788 }
789 ent_list = NULL;
790 child_list = NULL;
791 i = NULL;
792 j = NULL;
793 for (i = ref_list; i != NULL; i = i->next)
794 {
795 if (i->data == NULL)
796 {
797 continue;
798 }
799 ref_param = (QofParam *) i->data;
800 if (ref_param->param_name == NULL)
801 {
802 continue;
803 }
804 if (0 == safe_strcmp (ref_param->param_type, QOF_TYPE_COLLECT))
805 {
806 QofCollection *col;
807
808 col = ref_param->param_getfcn (ent, ref_param);
809 if (col)
810 {
811 qof_collection_foreach (col, recurse_collection_cb, store);
812 }
813 continue;
814 }
815 ref_ent = (QofEntity *) ref_param->param_getfcn (ent, ref_param);
816 if ((ref_ent) && (ref_ent->e_type))
817 {
818 store->success = qof_entity_copy_to_session (session, ref_ent);
819 if (store->success)
820 {
821 ent_list = g_list_append (ent_list, ref_ent);
822 }
823 }
824 }
825 for (i = ent_list; i != NULL; i = i->next)
826 {
827 if (i->data == NULL)
828 {
829 continue;
830 }
831 child_ent = (QofEntity *) i->data;
832 if (child_ent == NULL)
833 {
834 continue;
835 }
836 ref_list = qof_class_get_referenceList (child_ent->e_type);
837 for (j = ref_list; j != NULL; j = j->next)
838 {
839 if (j->data == NULL)
840 {
841 continue;
842 }
843 ref_param = (QofParam *) j->data;
844 ref_ent = ref_param->param_getfcn (child_ent, ref_param);
845 if (ref_ent != NULL)
846 {
847 success = qof_entity_copy_to_session (session, ref_ent);
848 if (success)
849 {
850 child_list = g_list_append (child_list, ref_ent);
851 }
852 }
853 }
854 }
855 for (i = child_list; i != NULL; i = i->next)
856 {
857 if (i->data == NULL)
858 {
859 continue;
860 }
861 ref_ent = (QofEntity *) i->data;
862 if (ref_ent == NULL)
863 {
864 continue;
865 }
866 ref_list = qof_class_get_referenceList (ref_ent->e_type);
867 for (j = ref_list; j != NULL; j = j->next)
868 {
869 if (j->data == NULL)
870 {
871 continue;
872 }
873 ref_param = (QofParam *) j->data;
874 child_ent = ref_param->param_getfcn (ref_ent, ref_param);
875 if (child_ent != NULL)
876 {
877 qof_entity_copy_to_session (session, child_ent);
878 }
879 }
880 }
881 }
882
883 gboolean
884 qof_entity_copy_coll_r (QofSession * new_session, QofCollection * coll)
885 {
886 struct recurse_s store;
887 gboolean success;
888
889 if ((!new_session) || (!coll))
890 {
891 return FALSE;
892 }
893 store.session = new_session;
894 success = TRUE;
895 store.success = success;
896 store.ent_list = NULL;
897 store.ref_list =
898 qof_class_get_referenceList (qof_collection_get_type (coll));
899 success = qof_entity_copy_coll (new_session, coll);
900 if (success)
901 {
902 qof_collection_foreach (coll, recurse_ent_cb, &store);
903 }
904 return success;
905 }
906
907 gboolean
908 qof_entity_copy_one_r (QofSession * new_session, QofEntity * ent)
909 {
910 struct recurse_s store;
911 QofCollection *coll;
912 gboolean success;
913
914 if ((!new_session) || (!ent))
915 {
916 return FALSE;
917 }
918 store.session = new_session;
919 success = TRUE;
920 store.success = success;
921 store.ref_list = qof_class_get_referenceList (ent->e_type);
922 success = qof_entity_copy_to_session (new_session, ent);
923 if (success == TRUE)
924 {
925 coll =
926 qof_book_get_collection (qof_session_get_book (new_session),
927 ent->e_type);
928 if (coll)
929 {
930 qof_collection_foreach (coll, recurse_ent_cb, &store);
931 }
932 }
933 return success;
934 }
935
936
937 /* ============================================================== */
938
942 struct backend_providers
943 {
944 const gchar *libdir;
945 const gchar *filename;
946 const gchar *init_fcn;
947 };
948
949 /* All available QOF backends need to be described here
950 and the last entry must be three NULL's.
951 Remember: Use the libdir from the current build environment
952 and use JUST the module name without .so - .so is not portable! */
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"},
956 #ifdef HAVE_GDA
957 {QOF_LIB_DIR, "libqof-backend-gda", "qof_gda_provider_init"},
958 #endif
959 #ifdef HAVE_DWI
960 {QOF_LIB_DIR, "libqof_backend_dwi", "dwiend_provider_init"},
961 #endif
962 {NULL, NULL, NULL}
963 };
964
965 static void
966 qof_session_load_backend (QofSession * session, gchar *access_method)
967 {
968 GSList *p;
969 GList *node;
970 QofBackendProvider *prov;
971 QofBook *book;
972 gint num;
973 gboolean prov_type;
974 gboolean (*type_check) (const gchar *);
975
976 ENTER (" list=%d", g_slist_length (provider_list));
977 prov_type = FALSE;
978 if (NULL == provider_list)
979 {
980 for (num = 0; backend_list[num].filename != NULL; num++)
981 {
982 if (!qof_load_backend_library (backend_list[num].libdir,
983 backend_list[num].filename,
984 backend_list[num].init_fcn))
985 {
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);
989 }
990 }
991 }
992 p = g_slist_copy (provider_list);
993 while (p != NULL)
994 {
995 prov = p->data;
996 /* Does this provider handle the desired access method? */
997 if (0 == strcasecmp (access_method, prov->access_method))
998 {
999 /* More than one backend could provide this
1000 access method, check file type compatibility. */
1001 type_check =
1002 (gboolean (*)(const gchar *)) prov->check_data_type;
1003 prov_type = (type_check) (session->book_id);
1004 if (!prov_type)
1005 {
1006 PINFO (" %s not usable", prov->provider_name);
1007 p = p->next;
1008 continue;
1009 }
1010 PINFO (" selected %s", prov->provider_name);
1011 if (NULL == prov->backend_new)
1012 {
1013 p = p->next;
1014 continue;
1015 }
1016 /* Use the providers creation callback */
1017 session->backend = (*(prov->backend_new)) ();
1018 session->backend->provider = prov;
1019 /* Tell the books about the backend that they'll be using. */
1020 for (node = session->books; node; node = node->next)
1021 {
1022 book = node->data;
1023 qof_book_set_backend (book, session->backend);
1024 }
1025 LEAVE (" ");
1026 return;
1027 }
1028 p = p->next;
1029 }
1030 LEAVE (" ");
1031 }
1032
1033 /* =============================================================== */
1034
1035 static void
1036 qof_session_destroy_backend (QofSession * session)
1037 {
1038 g_return_if_fail (session);
1039
1040 if (session->backend)
1041 {
1042 /* Then destroy the backend */
1043 if (session->backend->destroy_backend)
1044 {
1045 session->backend->destroy_backend (session->backend);
1046 }
1047 else
1048 {
1049 g_free (session->backend);
1050 }
1051 }
1052
1053 session->backend = NULL;
1054 }
1055
1056 void
1057 qof_session_begin (QofSession * session, const gchar *book_id,
1058 gboolean ignore_lock, gboolean create_if_nonexistent)
1059 {
1060 gchar *p, *access_method;
1061
1062 if (!session)
1063 return;
1064
1065 ENTER (" sess=%p ignore_lock=%d, book-id=%s",
1066 session, ignore_lock, book_id ? book_id : "(null)");
1067
1068 /* Clear the error condition of previous errors */
1069 qof_error_clear (session);
1070
1071 /* Check to see if this session is already open */
1072 if (session->book_id)
1073 {
1074 qof_error_set (session, qof_error_register
1075 (_("This book appears to be open already."), FALSE));
1076 LEAVE (" push error book is already open ");
1077 return;
1078 }
1079
1080 if (!book_id)
1081 {
1082 LEAVE (" using stdout");
1083 return;
1084 }
1085
1086 /* Store the session URL */
1087 session->book_id = g_strdup (book_id);
1088
1089 /* destroy the old backend */
1090 qof_session_destroy_backend (session);
1091
1092 /* Look for something of the form of "file:/", "http://" or
1093 * "postgres://". Everything before the colon is the access
1094 * method. Load the first backend found for that access method.
1095 */
1096 p = strchr (book_id, ':');
1097 if (p)
1098 {
1099 access_method = g_strdup (book_id);
1100 p = strchr (access_method, ':');
1101 *p = 0;
1102 qof_session_load_backend (session, access_method);
1103 g_free (access_method);
1104 }
1105 else
1106 {
1107 /* If no colon found, assume it must be a file-path */
1108 qof_session_load_backend (session, "file");
1109 }
1110
1111 /* No backend was found. That's bad. */
1112 if (NULL == session->backend)
1113 {
1114 gchar * msg;
1115
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);
1120 qof_error_set (session, qof_error_register
1121 (msg, FALSE));
1122 DEBUG (" msg=%s", msg);
1123 LEAVE (" BAD: no backend: sess=%p book-id=%s",
1124 session, book_id ? book_id : "(null)");
1125 g_free (msg);
1126 return;
1127 }
1128
1129 /* If there's a begin method, call that. */
1130 if (session->backend->session_begin)
1131 {
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");
1135 if (qof_error_check(session) != QOF_SUCCESS)
1136 {
1137 g_free (session->book_id);
1138 session->book_id = NULL;
1139 LEAVE (" backend error ");
1140 return;
1141 }
1142 }
1143 qof_error_clear (session);
1144 LEAVE (" sess=%p book-id=%s", session, book_id ? book_id : "(null)");
1145 }
1146
1147 /* ============================================================== */
1148
1149 void
1150 qof_session_load (QofSession * session, QofPercentageFunc percentage_func)
1151 {
1152 QofBook *newbook, *ob;
1153 QofBookList *oldbooks, *node;
1154 QofBackend *be;
1155
1156 if (!session)
1157 return;
1158 if ((!session->book_id) ||
1159 (0 == safe_strcasecmp(session->book_id, QOF_STDOUT)))
1160 return;
1161
1162 ENTER (" sess=%p book_id=%s", session, session->book_id
1163 ? session->book_id : "(null)");
1164
1165 /* At this point, we should are supposed to have a valid book
1166 * id and a lock on the file. */
1167
1168 oldbooks = session->books;
1169
1170 /* XXX why are we creating a book here? I think the books
1171 * need to be handled by the backend ... especially since
1172 * the backend may need to load multiple books ... XXX. FIXME.
1173 */
1174 newbook = qof_book_new ();
1175 session->books = g_list_append (NULL, newbook);
1176 PINFO (" new book=%p", newbook);
1177
1178 qof_error_clear (session);
1179
1180 /* This code should be sufficient to initialize *any* backend,
1181 * whether http, postgres, or anything else that might come along.
1182 * Basically, the idea is that by now, a backend has already been
1183 * created & set up. At this point, we only need to get the
1184 * top-level account group out of the backend, and that is a
1185 * generic, backend-independent operation.
1186 */
1187 be = session->backend;
1188 qof_book_set_backend (newbook, be);
1189
1190 /* Starting the session should result in a bunch of accounts
1191 * and currencies being downloaded, but probably no transactions;
1192 * The GUI will need to do a query for that.
1193 */
1194 if (be)
1195 {
1196 be->percentage = percentage_func;
1197
1198 if (be->load)
1199 {
1200 be->load (be, newbook);
1201 }
1202 }
1203
1204 if (qof_error_check(session) != QOF_SUCCESS)
1205 {
1206 /* Something broke, put back the old stuff */
1207 qof_book_set_backend (newbook, NULL);
1208 qof_book_destroy (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 ");
1214 return;
1215 }
1216
1217 for (node = oldbooks; node; node = node->next)
1218 {
1219 ob = node->data;
1220 qof_book_set_backend (ob, NULL);
1221 qof_book_destroy (ob);
1222 }
1223 g_list_free (oldbooks);
1224
1225 LEAVE (" sess = %p, book_id=%s", session, session->book_id
1226 ? session->book_id : "(null)");
1227 }
1228
1229 /* ============================================================= */
1230
1231 gboolean
1232 qof_session_save_may_clobber_data (QofSession * session)
1233 {
1234 if (!session)
1235 return FALSE;
1236 if (!session->backend)
1237 return FALSE;
1238 if (!session->backend->save_may_clobber_data)
1239 return FALSE;
1240
1241 return (*(session->backend->save_may_clobber_data)) (session->backend);
1242 }
1243
1244 void
1245 qof_session_save (QofSession * session,
1246 QofPercentageFunc percentage_func)
1247 {
1248 GList *node;
1249 QofBackend *be;
1250 gboolean partial, change_backend;
1251 QofBackendProvider *prov;
1252 GSList *p;
1253 QofBook *book, *abook;
1254 gint num;
1255 gchar *msg, *book_id;
1256
1257 if (!session)
1258 return;
1259 ENTER (" sess=%p book_id=%s",
1260 session, session->book_id ? session->book_id : "(null)");
1261 /* Partial book handling. */
1262 book = qof_session_get_book (session);
1263 partial =
1264 (gboolean)
1265 GPOINTER_TO_INT (qof_book_get_data (book, PARTIAL_QOFBOOK));
1266 change_backend = FALSE;
1267 msg = g_strdup_printf (" ");
1268 book_id = g_strdup (session->book_id);
1269 if (partial == TRUE)
1270 {
1271 if (session->backend && session->backend->provider)
1272 {
1273 prov = session->backend->provider;
1274 if (TRUE == prov->partial_book_supported)
1275 {
1276 /* if current backend supports partial, leave alone. */
1277 change_backend = FALSE;
1278 }
1279 else
1280 {
1281 change_backend = TRUE;
1282 }
1283 }
1284 /* If provider is undefined, assume partial not supported. */
1285 else
1286 {
1287 change_backend = TRUE;
1288 }
1289 }
1290 if (change_backend == TRUE)
1291 {
1292 qof_session_destroy_backend (session);
1293 if (NULL == provider_list)
1294 {
1295 for (num = 0; backend_list[num].filename != NULL; num++)
1296 {
1297 qof_load_backend_library (backend_list[num].libdir,
1298 backend_list[num].filename,
1299 backend_list[num].init_fcn);
1300 }
1301 }
1302 p = g_slist_copy (provider_list);
1303 while (p != NULL)
1304 {
1305 prov = p->data;
1306 if (TRUE == prov->partial_book_supported)
1307 {
1309 /* if((TRUE == prov->partial_book_supported) &&
1310 (0 == strcasecmp (access_method, prov->access_method)))
1311 { */
1312 if (NULL == prov->backend_new)
1313 continue;
1314 /* Use the providers creation callback */
1315 session->backend = (*(prov->backend_new)) ();
1316 session->backend->provider = prov;
1317 if (session->backend->session_begin)
1318 {
1319 /* Call begin - backend has been changed,
1320 so make sure a file can be written,
1321 use ignore_lock and create_if_nonexistent */
1322 g_free (session->book_id);
1323 session->book_id = NULL;
1324 (session->backend->session_begin) (session->backend,
1325 session, book_id, TRUE, TRUE);
1326 PINFO
1327 (" Done running session_begin on changed backend");
1328 if (qof_error_check (session) != QOF_SUCCESS)
1329 {
1330 g_free (session->book_id);
1331 session->book_id = NULL;
1332 LEAVE (" changed backend error");
1333 return;
1334 }
1335 }
1336 /* Tell the books about the backend that they'll be using. */
1337 for (node = session->books; node; node = node->next)
1338 {
1339 book = node->data;
1340 qof_book_set_backend (book, session->backend);
1341 }
1342 p = NULL;
1343 }
1344 if (p)
1345 {
1346 p = p->next;
1347 }
1348 }
1349 if (!session->backend)
1350 {
1351 msg = g_strdup_printf (" failed to load backend");
1352 qof_error_set (session, qof_error_register
1353 (_("Failed to load backend, no suitable handler."),
1354 FALSE));
1355 return;
1356 }
1357 }
1358 /* If there is a backend, and the backend is reachable
1359 * (i.e. we can communicate with it), then synchronize with
1360 * the backend. If we cannot contact the backend (e.g.
1361 * because we've gone offline, the network has crashed, etc.)
1362 * then give the user the option to save to the local disk.
1363 *
1364 * hack alert -- FIXME -- XXX the code below no longer
1365 * does what the words above say. This needs fixing.
1366 */
1367 be = session->backend;
1368 if (be)
1369 {
1370 for (node = session->books; node; node = node->next)
1371 {
1372 abook = node->data;
1373 /* if invoked as SaveAs(), then backend not yet set */
1374 qof_book_set_backend (abook, be);
1375 be->percentage = percentage_func;
1376 if (be->sync)
1377 (be->sync) (be, abook);
1378 }
1379 /* If we got to here, then the backend saved everything
1380 * just fine, and we are done. So return. */
1381 /* Return the book_id to previous value. */
1382 qof_error_clear (session);
1383 LEAVE (" Success");
1384 return;
1385 }
1386 else
1387 {
1388 msg = g_strdup_printf (" failed to load backend");
1389 qof_error_set (session, qof_error_register
1390 (_("Failed to load backend, no suitable handler."),
1391 FALSE));
1392 }
1393 LEAVE (" error -- No backend!");
1394 }
1395
1396 /* ============================================================= */
1397
1398 void
1399 qof_session_end (QofSession * session)
1400 {
1401 if (!session)
1402 return;
1403
1404 ENTER (" sess=%p book_id=%s", session, session->book_id
1405 ? session->book_id : "(null)");
1406
1407 /* close down the backend first */
1408 if (session->backend && session->backend->session_end)
1409 {
1410 (session->backend->session_end) (session->backend);
1411 }
1412
1413 qof_error_clear (session);
1414
1415 g_free (session->book_id);
1416 session->book_id = NULL;
1417
1418 LEAVE (" sess=%p book_id=%s", session, session->book_id
1419 ? session->book_id : "(null)");
1420 }
1421
1422 void
1423 qof_session_destroy (QofSession * session)
1424 {
1425 GList *node;
1426 if (!session)
1427 return;
1428
1429 ENTER (" sess=%p book_id=%s", session, session->book_id
1430 ? session->book_id : "(null)");
1431
1432 qof_session_end (session);
1433
1434 /* destroy the backend */
1435 qof_session_destroy_backend (session);
1436
1437 for (node = session->books; node; node = node->next)
1438 {
1439 QofBook *book = node->data;
1440 qof_book_set_backend (book, NULL);
1441 qof_book_destroy (book);
1442 }
1443
1444 session->books = NULL;
1445 #ifndef QOF_DISABLE_DEPRECATED
1446 if (session == qof_session_get_current_session())
1447 qof_session_clear_current_session();
1448 #endif
1449 g_free (session);
1450 qof_error_close ();
1451
1452 LEAVE (" sess=%p", session);
1453 }
1454
1455 /* ============================================================= */
1456
1457 void
1458 qof_session_swap_data (QofSession * session_1, QofSession * session_2)
1459 {
1460 GList *books_1, *books_2, *node;
1461
1462 if (session_1 == session_2)
1463 return;
1464 if (!session_1 || !session_2)
1465 return;
1466
1467 ENTER (" sess1=%p sess2=%p", session_1, session_2);
1468
1469 books_1 = session_1->books;
1470 books_2 = session_2->books;
1471
1472 session_1->books = books_2;
1473 session_2->books = books_1;
1474
1475 for (node = books_1; node; node = node->next)
1476 {
1477 QofBook *book_1 = node->data;
1478 qof_book_set_backend (book_1, session_2->backend);
1479 }
1480 for (node = books_2; node; node = node->next)
1481 {
1482 QofBook *book_2 = node->data;
1483 qof_book_set_backend (book_2, session_1->backend);
1484 }
1485
1486 LEAVE (" ");
1487 }
1488
1489 /* ============================================================= */
1490
1491 gboolean
1492 qof_session_events_pending (QofSession * session)
1493 {
1494 if (!session)
1495 return FALSE;
1496 if (!session->backend)
1497 return FALSE;
1498 if (!session->backend->events_pending)
1499 return FALSE;
1500
1501 return session->backend->events_pending (session->backend);
1502 }
1503
1504 gboolean
1505 qof_session_process_events (QofSession * session)
1506 {
1507 if (!session)
1508 return FALSE;
1509 if (!session->backend)
1510 return FALSE;
1511 if (!session->backend->process_events)
1512 return FALSE;
1513
1514 return session->backend->process_events (session->backend);
1515 }
1516
1517 /* ============== END OF FILE ========================== */
QOF_TYPE_DATE
#define QOF_TYPE_DATE
Definition: deprecated.h:336
recurse_ent_cb
static void recurse_ent_cb(QofEntity *ent, gpointer user_data)
Definition: qofsession.c:766
qof_session_call_close_hooks
void qof_session_call_close_hooks(QofSession *session)
Definition: qofsession.c:89
qof_error_register
QofErrorId qof_error_register(const gchar *err_message, gboolean use_file)
Generate and register a new error.
Definition: qoferror.c:91
QofBackend_s::fullpath
gchar * fullpath
Definition: qofbackend-p.h:338
QofBackend_s::save_may_clobber_data
gboolean(* save_may_clobber_data)(QofBackend *)
Definition: qofbackend-p.h:320
PERR
#define PERR(format, args...)
Definition: qoflog.h:183
qof_object_new_instance
gpointer qof_object_new_instance(QofIdTypeConst type_name, QofBook *book)
Definition: qofobject.c:42
qof_entity_reference::ent_guid
const GUID * ent_guid
Definition: qofreference.h:115
qof_entity_copy_coll
gboolean qof_entity_copy_coll(QofSession *new_session, QofCollection *entity_coll)
Copy a QofCollection of entities.
Definition: qofsession.c:710
QOF_TYPE_COLLECT
#define QOF_TYPE_COLLECT
Definition: qofclass.h:93
qof_entity_reference::type
QofIdType type
Definition: qofreference.h:109
qof_entity_foreach_copy
static void qof_entity_foreach_copy(gpointer data, gpointer user_data)
Definition: qofsession.c:299
PINFO
#define PINFO(format, args...)
Definition: qoflog.h:199
QofInstance_s
Definition: qofinstance-p.h:35
qof_book_get_collection
QofCollection * qof_book_get_collection(QofBook *book, QofIdType entity_type)
Definition: qofbook.c:220
Timespec
struct timespec64 Timespec
QofNumeric
struct _QofNumeric QofNumeric
A rational-number type.
Definition: qofnumeric.h:61
qof_class_param_foreach
void qof_class_param_foreach(QofIdTypeConst obj_name, QofParamForeachCB cb, gpointer user_data)
Definition: qofclass.c:267
qof_backend_register_provider
void qof_backend_register_provider(QofBackendProvider *prov)
Definition: qofsession.c:59
_QofParam
Definition: qofclass.h:195
_QofSession::entity
QofEntity entity
Definition: qofsession-p.h:41
qof_entity_copy_one_r
gboolean qof_entity_copy_one_r(QofSession *new_session, QofEntity *ent)
Recursively copy a single entity to a new session.
Definition: qofsession.c:908
_QofSession
Definition: qofsession-p.h:35
QofBackendProvider_s
Definition: qofbackend-p.h:238
qof_session_events_pending
gboolean qof_session_events_pending(QofSession *session)
Definition: qofsession.c:1492
qof_object_compliance
gboolean qof_object_compliance(QofIdTypeConst type_name, gboolean warn)
check an object can be created and supports iteration
Definition: qofobject.c:155
QofEntity_s
Definition: qofid.h:147
qof_session_add_book
void qof_session_add_book(QofSession *session, QofBook *addbook)
Definition: qofsession.c:148
qof_session_process_events
gboolean qof_session_process_events(QofSession *session)
Definition: qofsession.c:1505
qof_error_check
QofErrorId qof_error_check(QofSession *session)
Definition: qoferror.c:227
string_to_guid
gboolean string_to_guid(const gchar *string, GUID *guid)
qof_book_get_data
gpointer qof_book_get_data(QofBook *book, const gchar *key)
Definition: qofbook.c:212
_QofBook::book_open
gchar book_open
Definition: qofbook-p.h:70
QofBackendProvider_s::partial_book_supported
gboolean partial_book_supported
Partial QofBook handler.
Definition: qofbackend-p.h:254
kvp_frame_copy
KvpFrame * kvp_frame_copy(const KvpFrame *frame)
Definition: kvpframe.c:156
KvpFrame
struct _KvpFrame KvpFrame
Definition: kvpframe.h:74
qof_book_new
QofBook * qof_book_new(void)
Definition: qofbook.c:75
safe_strcasecmp
gint safe_strcasecmp(const gchar *da, const gchar *db)
Definition: qofutil.c:92
timespec64
Definition: qoftime.h:97
qof_load_backend_library
gboolean qof_load_backend_library(const gchar *directory, const gchar *filename, const gchar *init_fcn)
Load a QOF-compatible backend shared library.
Definition: qofbackend.c:431
qof_entity_reference::ref_guid
GUID * ref_guid
Definition: qofreference.h:112
QofInstance_s::kvp_data
KvpFrame * kvp_data
Definition: qofinstance-p.h:47
LEAVE
#define LEAVE(format, args...)
Definition: qoflog.h:227
GUID_ENCODING_LENGTH
#define GUID_ENCODING_LENGTH
Definition: guid.h:64
qof_session_get_current_session
QofSession * qof_session_get_current_session(void)
Definition: deprecated.c:1633
qofbook-p.h
Private QofBook interface.
kvp_frame_delete
void kvp_frame_delete(KvpFrame *frame)
Definition: kvpframe.c:118
qofobject-p.h
the Core Object Registration/Lookup Private Interface
qof_session_swap_data
void qof_session_swap_data(QofSession *session_1, QofSession *session_2)
Definition: qofsession.c:1458
QofPercentageFunc
void(* QofPercentageFunc)(const gchar *message, gdouble percent)
Definition: qofsession.h:168
QofCollection
struct QofCollection_s QofCollection
Definition: qofid.h:138
qof_class_get_parameter
const QofParam * qof_class_get_parameter(QofIdTypeConst obj_name, const gchar *parameter)
Definition: qofclass.c:146
qof_util_param_edit
gboolean qof_util_param_edit(QofInstance *inst, const QofParam *param)
Prepare to edit a parameter.
Definition: qofutil.c:278
qof_entity_copy_coll_r
gboolean qof_entity_copy_coll_r(QofSession *new_session, QofCollection *coll)
Recursively copy a collection of entities to a session.
Definition: qofsession.c:884
qof_session_save_may_clobber_data
gboolean qof_session_save_may_clobber_data(QofSession *session)
Definition: qofsession.c:1232
qof_error_set
void qof_error_set(QofSession *session, QofErrorId error)
Add an error to the stack for this session.
Definition: qoferror.c:133
qof_session_begin
void qof_session_begin(QofSession *session, const gchar *book_id, gboolean ignore_lock, gboolean create_if_nonexistent)
Definition: qofsession.c:1057
qof_book_set_backend
void qof_book_set_backend(QofBook *book, QofBackend *)
Set the backend used by this book.
Definition: qofbook.c:170
qof_collection_lookup_entity
QofEntity * qof_collection_lookup_entity(QofCollection *col, const GUID *guid)
Definition: qofid.c:321
qof_entity_get_reference_from
QofEntityReference * qof_entity_get_reference_from(QofEntity *ent, const QofParam *param)
Get a reference from this entity to another entity.
Definition: qofreference.c:167
qof_collection_foreach
void qof_collection_foreach(QofCollection *col, QofEntityForeachCB cb_func, gpointer user_data)
Definition: qofid.c:421
QOF_SUCCESS
#define QOF_SUCCESS
Definition: qoferror.h:124
_QofNumeric
Definition: qofnumeric.h:52
DEBUG
#define DEBUG(format, args...)
Definition: qoflog.h:208
QofBackendProvider_s::backend_new
QofBackend *(* backend_new)(void)
Definition: qofbackend-p.h:260
qof_entity_copy_list
gboolean qof_entity_copy_list(QofSession *new_session, GList *entity_list)
Copy a GList of entities to another session.
Definition: qofsession.c:688
guid_to_string_buff
gchar * guid_to_string_buff(const GUID *guid, gchar *buff)
qof_session_get_file_path
const gchar * qof_session_get_file_path(QofSession *session)
Definition: qofsession.c:192
qof_util_param_commit
gboolean qof_util_param_commit(QofInstance *inst, const QofParam *param)
Commit this parameter change, with undo support.
Definition: qofutil.c:306
qof_book_set_data
void qof_book_set_data(QofBook *book, const gchar *key, gpointer data)
Definition: qofbook.c:191
QofInstance_s::entity
QofEntity entity
Definition: qofinstance-p.h:38
qof_entity_copy_to_session
gboolean qof_entity_copy_to_session(QofSession *new_session, QofEntity *original)
Copy a single QofEntity to another session.
Definition: qofsession.c:656
qof_entity_reference::param
const QofParam * param
Definition: qofreference.h:113
qof_class_get_referenceList
GList * qof_class_get_referenceList(QofIdTypeConst type)
List of the parameters that could be references.
Definition: qofclass.c:332
QofBackendProvider_s::access_method
const gchar * access_method
Definition: qofbackend-p.h:247
ENTITYREFERENCE
#define ENTITYREFERENCE
Definition: qofreference.h:137
qof_collection_get_type
QofIdType qof_collection_get_type(QofCollection *col)
Definition: qofid.c:175
_GUID
Definition: guid.h:53
qof_session_add_close_hook
void qof_session_add_close_hook(GFunc fn, gpointer data)
Definition: qofsession.c:69
QofBackendProvider_s::check_data_type
gboolean(* check_data_type)(const gchar *)
Distinguish two providers with same access method.
Definition: qofbackend-p.h:277
QOF_STDOUT
#define QOF_STDOUT
Allow session data to be printed to stdout.
Definition: qofsession.h:385
qofbackend-p.h
private api for data storage backend
QofIdTypeConst
const gchar * QofIdTypeConst
Definition: qofid.h:83
PWARN
#define PWARN(format, args...)
Definition: qoflog.h:191
QofTime
struct QofTime64 QofTime
Use a 64-bit signed int QofTime.
Definition: qoftime.h:120
qof_event_suspend
void qof_event_suspend(void)
Suspend all engine events.
Definition: qofevent.c:189
qof_entity_get_guid
const GUID * qof_entity_get_guid(QofEntity *ent)
Definition: qofid.c:105
qof_entity_reference
External references in a partial QofBook.
Definition: qofreference.h:105
qof_event_resume
void qof_event_resume(void)
Definition: qofevent.c:200
qof_session_save
void qof_session_save(QofSession *session, QofPercentageFunc percentage_func)
Definition: qofsession.c:1245
QofBookList
GList QofBookList
Definition: qofbook.h:64
qof_session_end
void qof_session_end(QofSession *session)
Definition: qofsession.c:1399
qof_error_clear
void qof_error_clear(QofSession *session)
clear the error stack for the session.
Definition: qoferror.c:209
qof_session_clear_current_session
void qof_session_clear_current_session(void)
Definition: deprecated.c:1652
qof_entity_set_guid
void qof_entity_set_guid(QofEntity *ent, const GUID *guid)
Definition: qofid.c:92
_QofBook
Definition: qofbook-p.h:48
safe_strcmp
gint safe_strcmp(const gchar *da, const gchar *db)
Definition: qofutil.c:72
QofBackendProvider_s::provider_name
const gchar * provider_name
Definition: qofbackend-p.h:241
qof_session_update_reference_list
void qof_session_update_reference_list(QofSession *session, QofEntityReference *reference)
Adds a new reference to the partial book data hash.
Definition: qofsession.c:237
ENTER
#define ENTER(format, args...)
Definition: qoflog.h:217
QofBackend_s
Definition: qofbackend-p.h:283
QofLogModule
const gchar * QofLogModule
Definition: qofid.h:85
PARTIAL_QOFBOOK
#define PARTIAL_QOFBOOK
Flag indicating a partial QofBook.
Definition: qofreference.h:146
qof_book_destroy
void qof_book_destroy(QofBook *book)
Definition: qofbook.c:99