r21829 - gnucash/trunk/src/libqof/qof - [GSOC][Testing] Modifications to qofsession for testability
John Ralls
jralls at code.gnucash.org
Mon Jan 9 18:09:47 EST 2012
Author: jralls
Date: 2012-01-09 18:09:47 -0500 (Mon, 09 Jan 2012)
New Revision: 21829
Trac: http://svn.gnucash.org/trac/changeset/21829
Modified:
gnucash/trunk/src/libqof/qof/Makefile.am
gnucash/trunk/src/libqof/qof/qofsession-p.h
gnucash/trunk/src/libqof/qof/qofsession.c
Log:
[GSOC][Testing] Modifications to qofsession for testability
Author: Muslim Chochlov
Modified: gnucash/trunk/src/libqof/qof/Makefile.am
===================================================================
--- gnucash/trunk/src/libqof/qof/Makefile.am 2012-01-08 21:32:21 UTC (rev 21828)
+++ gnucash/trunk/src/libqof/qof/Makefile.am 2012-01-09 23:09:47 UTC (rev 21829)
@@ -1,4 +1,6 @@
+include $(top_srcdir)/test-templates/Makefile.decl
SUBDIRS = . test
+TEST_SUBDIRS = test
lib_LTLIBRARIES = libgnc-qof.la
@@ -77,7 +79,7 @@
qofquerycore-p.h \
qofsession-p.h
-EXTRA_DIST = \
+EXTRA_DIST += \
qofmath128.c
if OS_WIN32
Modified: gnucash/trunk/src/libqof/qof/qofsession-p.h
===================================================================
--- gnucash/trunk/src/libqof/qof/qofsession-p.h 2012-01-08 21:32:21 UTC (rev 21828)
+++ gnucash/trunk/src/libqof/qof/qofsession-p.h 2012-01-09 23:09:47 UTC (rev 21829)
@@ -66,6 +66,16 @@
gint lock;
};
+typedef struct qof_instance_copy_data
+{
+ QofInstance *from;
+ QofInstance *to;
+ QofParam *param;
+ GList *referenceList;
+ GSList *param_list;
+ QofSession *new_session;
+ gboolean error;
+} QofInstanceCopyData;
QofBackend * qof_session_get_backend (const QofSession *session);
Modified: gnucash/trunk/src/libqof/qof/qofsession.c
===================================================================
--- gnucash/trunk/src/libqof/qof/qofsession.c 2012-01-08 21:32:21 UTC (rev 21828)
+++ gnucash/trunk/src/libqof/qof/qofsession.c 2012-01-09 23:09:47 UTC (rev 21829)
@@ -57,6 +57,36 @@
static GSList *provider_list = NULL;
static gboolean qof_providers_initialized = FALSE;
+/*
+ * These getters are used in tests to reach static vars from outside
+ * They should be removed when no longer needed
+ */
+
+GHookList* get_session_closed_hooks (void );
+GSList* get_provider_list (void );
+gboolean get_qof_providers_initialized (void );
+void unregister_all_providers (void );
+
+GHookList*
+get_session_closed_hooks (void) { return session_closed_hooks; }
+
+GSList*
+get_provider_list (void) { return provider_list; }
+
+gboolean
+get_qof_providers_initialized (void) { return qof_providers_initialized; }
+
+void
+unregister_all_providers (void)
+{
+ if (provider_list)
+ {
+ g_slist_foreach (provider_list, (GFunc) g_free, NULL);
+ g_slist_free (provider_list);
+ provider_list = NULL;
+ }
+}
+
/* ====================================================================== */
void
@@ -283,6 +313,683 @@
qof_session_push_error (session, qof_backend_get_error(backend), NULL);
}
+/* =============================================================== */
+
+static void
+qof_book_set_partial (QofBook *book)
+{
+ gboolean partial;
+
+ partial =
+ (gboolean)GPOINTER_TO_INT (qof_book_get_data (book, PARTIAL_QOFBOOK));
+ if (!partial)
+ {
+ qof_book_set_data (book, PARTIAL_QOFBOOK, GINT_TO_POINTER (TRUE));
+ }
+}
+
+/** \brief Adds a new reference to the partial book data hash.
+
+ * Retrieves any existing reference list and appends the new reference.
+
+ * If the book is not already marked as partial, it will be marked as
+ * partial.
+ */
+static void
+qof_session_update_reference_list (QofSession *session,
+ QofInstanceReference *reference)
+{
+ QofBook *book;
+ GList *book_ref_list;
+
+ book = qof_session_get_book (session);
+ book_ref_list = (GList*)qof_book_get_data (book, ENTITYREFERENCE);
+ book_ref_list = g_list_append (book_ref_list, reference);
+ qof_book_set_data (book, ENTITYREFERENCE, book_ref_list);
+ qof_book_set_partial (book);
+}
+
+static void
+qof_instance_param_cb (QofParam *param, gpointer data)
+{
+ QofInstanceCopyData *qecd;
+
+ g_return_if_fail (data != NULL);
+ qecd = (QofInstanceCopyData*)data;
+ g_return_if_fail (param != NULL);
+ /* KVP doesn't need a set routine to be copied. */
+ if (0 == safe_strcmp (param->param_type, QOF_TYPE_KVP))
+ {
+ qecd->param_list = g_slist_prepend (qecd->param_list, param);
+ return;
+ }
+ if ((param->param_getfcn != NULL) && (param->param_setfcn != NULL))
+ {
+ qecd->param_list = g_slist_prepend (qecd->param_list, param);
+ }
+}
+
+static void
+col_ref_cb (QofInstance* ref_ent, gpointer user_data)
+{
+ QofInstanceReference *ref;
+ QofInstanceCopyData *qecd;
+ QofInstance *ent;
+ const GncGUID *cm_guid;
+ char cm_sa[GUID_ENCODING_LENGTH + 1];
+ gchar *cm_string;
+
+ g_return_if_fail (user_data);
+ qecd = (QofInstanceCopyData*)user_data;
+ ent = qecd->from;
+ g_return_if_fail (ent);
+ ref = g_new0 (QofInstanceReference, 1);
+ ref->type = ent->e_type;
+ ref->ref_guid = g_new (GncGUID, 1);
+ ref->ent_guid = qof_instance_get_guid (ent);
+ ref->param = qof_class_get_parameter (ent->e_type,
+ qecd->param->param_name);
+ cm_guid = qof_entity_get_guid (ref_ent);
+ guid_to_string_buff (cm_guid, cm_sa);
+ cm_string = g_strdup (cm_sa);
+ if (TRUE == string_to_guid (cm_string, ref->ref_guid))
+ {
+ g_free (cm_string);
+ qof_session_update_reference_list (qecd->new_session, ref);
+ }
+}
+
+static void
+qof_instance_foreach_copy (gpointer data, gpointer user_data)
+{
+ QofInstance *importEnt, *targetEnt/*, *referenceEnt*/;
+ QofInstanceCopyData *context;
+ QofInstanceReference *reference;
+ gboolean registered_type;
+ /* cm_ prefix used for variables that hold the data to commit */
+ QofParam *cm_param;
+ gchar *cm_string, *cm_char;
+ const GncGUID *cm_guid;
+ KvpFrame *cm_kvp;
+ QofCollection *cm_col;
+ /* function pointers and variables for parameter getters that don't
+ * use pointers normally */
+ gnc_numeric cm_numeric, (*numeric_getter) (QofInstance*, QofParam*);
+ double cm_double, (*double_getter) (QofInstance*, QofParam*);
+ gboolean cm_boolean, (*boolean_getter) (QofInstance*, QofParam*);
+ gint32 cm_i32, (*int32_getter) (QofInstance*, QofParam*);
+ gint64 cm_i64, (*int64_getter) (QofInstance*, QofParam*);
+ Timespec cm_date, (*date_getter) (QofInstance*, QofParam*);
+ /* function pointers to the parameter setters */
+ void (*string_setter) (QofInstance*, const char*);
+ void (*date_setter) (QofInstance*, Timespec);
+ void (*numeric_setter) (QofInstance*, gnc_numeric);
+ void (*guid_setter) (QofInstance*, const GncGUID*);
+ void (*double_setter) (QofInstance*, double);
+ void (*boolean_setter) (QofInstance*, gboolean);
+ void (*i32_setter) (QofInstance*, gint32);
+ void (*i64_setter) (QofInstance*, gint64);
+ void (*char_setter) (QofInstance*, char*);
+ void (*kvp_frame_setter) (QofInstance*, KvpFrame*);
+
+ g_return_if_fail (user_data != NULL);
+ context = (QofInstanceCopyData*) user_data;
+ cm_date.tv_nsec = 0;
+ cm_date.tv_sec = 0;
+ importEnt = context->from;
+ targetEnt = context->to;
+ registered_type = FALSE;
+ cm_param = (QofParam*) data;
+ g_return_if_fail (cm_param != NULL);
+ context->param = cm_param;
+ if (safe_strcmp (cm_param->param_type, QOF_TYPE_STRING) == 0)
+ {
+ cm_string = (gchar*)cm_param->param_getfcn (importEnt, cm_param);
+ if (cm_string)
+ {
+ string_setter = (void (*)(QofInstance*, const char*))cm_param->param_setfcn;
+ if (string_setter != NULL)
+ {
+ string_setter (targetEnt, cm_string);
+ }
+ }
+ registered_type = TRUE;
+ }
+ if (safe_strcmp (cm_param->param_type, QOF_TYPE_DATE) == 0)
+ {
+ date_getter = (Timespec (*)(QofInstance*, QofParam*))cm_param->param_getfcn;
+ cm_date = date_getter (importEnt, cm_param);
+ date_setter = (void (*)(QofInstance*, Timespec))cm_param->param_setfcn;
+ if (date_setter != NULL)
+ {
+ date_setter (targetEnt, cm_date);
+ }
+ registered_type = TRUE;
+ }
+ if ((safe_strcmp (cm_param->param_type, QOF_TYPE_NUMERIC) == 0) ||
+ (safe_strcmp (cm_param->param_type, QOF_TYPE_DEBCRED) == 0))
+ {
+ numeric_getter = (gnc_numeric (*)(QofInstance*, QofParam*))cm_param->param_getfcn;
+ cm_numeric = numeric_getter (importEnt, cm_param);
+ numeric_setter = (void (*)(QofInstance*, gnc_numeric))cm_param->param_setfcn;
+ if (numeric_setter != NULL)
+ {
+ numeric_setter (targetEnt, cm_numeric);
+ }
+ registered_type = TRUE;
+ }
+ if (safe_strcmp (cm_param->param_type, QOF_TYPE_GUID) == 0)
+ {
+ cm_guid = (const GncGUID*)cm_param->param_getfcn (importEnt, cm_param);
+ guid_setter = (void (*)(QofInstance*, const GncGUID*))cm_param->param_setfcn;
+ if (guid_setter != NULL)
+ {
+ guid_setter (targetEnt, cm_guid);
+ }
+ registered_type = TRUE;
+ }
+ if (safe_strcmp (cm_param->param_type, QOF_TYPE_INT32) == 0)
+ {
+ int32_getter = (gint32 (*)(QofInstance*, QofParam*)) cm_param->param_getfcn;
+ cm_i32 = int32_getter (importEnt, cm_param);
+ i32_setter = (void (*)(QofInstance*, gint32))cm_param->param_setfcn;
+ if (i32_setter != NULL)
+ {
+ i32_setter (targetEnt, cm_i32);
+ }
+ registered_type = TRUE;
+ }
+ if (safe_strcmp (cm_param->param_type, QOF_TYPE_INT64) == 0)
+ {
+ int64_getter = (gint64 (*)(QofInstance*, QofParam*)) cm_param->param_getfcn;
+ cm_i64 = int64_getter (importEnt, cm_param);
+ i64_setter = (void (*)(QofInstance*, gint64))cm_param->param_setfcn;
+ if (i64_setter != NULL)
+ {
+ i64_setter (targetEnt, cm_i64);
+ }
+ registered_type = TRUE;
+ }
+ if (safe_strcmp (cm_param->param_type, QOF_TYPE_DOUBLE) == 0)
+ {
+ double_getter = (double (*)(QofInstance*, QofParam*)) cm_param->param_getfcn;
+ cm_double = double_getter (importEnt, cm_param);
+ double_setter = (void (*)(QofInstance*, double))cm_param->param_setfcn;
+ if (double_setter != NULL)
+ {
+ double_setter (targetEnt, cm_double);
+ }
+ registered_type = TRUE;
+ }
+ if (safe_strcmp (cm_param->param_type, QOF_TYPE_BOOLEAN) == 0)
+ {
+ boolean_getter = (gboolean (*)(QofInstance*, QofParam*)) cm_param->param_getfcn;
+ cm_boolean = boolean_getter (importEnt, cm_param);
+ boolean_setter = (void (*)(QofInstance*, gboolean))cm_param->param_setfcn;
+ if (boolean_setter != NULL)
+ {
+ boolean_setter (targetEnt, cm_boolean);
+ }
+ registered_type = TRUE;
+ }
+ if (safe_strcmp (cm_param->param_type, QOF_TYPE_KVP) == 0)
+ {
+ cm_kvp = (KvpFrame*)cm_param->param_getfcn (importEnt, cm_param);
+ kvp_frame_setter = (void (*)(QofInstance*, KvpFrame*))cm_param->param_setfcn;
+ if (kvp_frame_setter != NULL)
+ {
+ kvp_frame_setter (targetEnt, cm_kvp);
+ }
+ else
+ {
+ QofInstance *target_inst;
+
+ target_inst = (QofInstance*)targetEnt;
+ kvp_frame_delete (target_inst->kvp_data);
+ target_inst->kvp_data = kvp_frame_copy (cm_kvp);
+ }
+ registered_type = TRUE;
+ }
+ if (safe_strcmp (cm_param->param_type, QOF_TYPE_CHAR) == 0)
+ {
+ cm_char = (gchar*)cm_param->param_getfcn (importEnt, cm_param);
+ char_setter = (void (*)(QofInstance*, char*))cm_param->param_setfcn;
+ if (char_setter != NULL)
+ {
+ char_setter (targetEnt, cm_char);
+ }
+ registered_type = TRUE;
+ }
+ if (safe_strcmp (cm_param->param_type, QOF_TYPE_COLLECT) == 0)
+ {
+ cm_col = (QofCollection*)cm_param->param_getfcn (importEnt, cm_param);
+ if (cm_col)
+ {
+ /* create one reference for each member of the collection. */
+ qof_collection_foreach (cm_col, col_ref_cb, context);
+ }
+ registered_type = TRUE;
+ }
+ if (registered_type == FALSE)
+ {
+ /* referenceEnt = QOF_INSTANCE (cm_param->param_getfcn (importEnt, cm_param));
+ if (!referenceEnt) { return; }
+ if (!referenceEnt->e_type) { return; }*/
+ reference = qof_instance_get_reference_from (importEnt, cm_param);
+ if (reference)
+ {
+ qof_session_update_reference_list (context->new_session, reference);
+ }
+ }
+}
+
+static gboolean
+qof_instance_guid_match (QofSession *new_session, QofInstance *original)
+{
+ QofInstance *copy;
+ const GncGUID *g;
+ QofIdTypeConst type;
+ QofBook *targetBook;
+ QofCollection *coll;
+
+ copy = NULL;
+ g_return_val_if_fail (original != NULL, FALSE);
+ targetBook = qof_session_get_book (new_session);
+ g_return_val_if_fail (targetBook != NULL, FALSE);
+ g = qof_instance_get_guid (original);
+ type = g_strdup (original->e_type);
+ coll = qof_book_get_collection (targetBook, type);
+ copy = qof_collection_lookup_entity (coll, g);
+ if (copy)
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void
+qof_instance_list_foreach (gpointer data, gpointer user_data)
+{
+ QofInstanceCopyData *qecd;
+ QofInstance *original;
+ QofInstance *inst;
+ QofBook *book;
+ const GncGUID *g;
+
+ g_return_if_fail (data != NULL);
+ original = QOF_INSTANCE (data);
+ g_return_if_fail (user_data != NULL);
+ qecd = (QofInstanceCopyData*)user_data;
+ if (qof_instance_guid_match (qecd->new_session, original))
+ {
+ return;
+ }
+ qecd->from = original;
+ if (!qof_object_compliance (original->e_type, FALSE))
+ {
+ qecd->error = TRUE;
+ return;
+ }
+ book = qof_session_get_book (qecd->new_session);
+ inst = (QofInstance*)qof_object_new_instance (original->e_type, book);
+ if (!inst)
+ {
+ PERR (" failed to create new entity type=%s.", original->e_type);
+ qecd->error = TRUE;
+ return;
+ }
+ qecd->to = inst;
+ g = qof_instance_get_guid (original);
+ qof_instance_set_guid (qecd->to, g);
+ if (qecd->param_list != NULL)
+ {
+ g_slist_free (qecd->param_list);
+ qecd->param_list = NULL;
+ }
+ qof_class_param_foreach (original->e_type, qof_instance_param_cb, qecd);
+ qof_begin_edit (inst);
+ g_slist_foreach (qecd->param_list, qof_instance_foreach_copy, qecd);
+ qof_commit_edit (inst);
+}
+
+static void
+qof_instance_coll_foreach (QofInstance *original, gpointer user_data)
+{
+ QofInstanceCopyData *qecd;
+ const GncGUID *g;
+ QofBook *targetBook;
+ QofCollection *coll;
+ QofInstance *copy;
+
+ g_return_if_fail (original != NULL);
+ g_return_if_fail (user_data != NULL);
+ copy = NULL;
+ qecd = (QofInstanceCopyData*)user_data;
+ targetBook = qof_session_get_book (qecd->new_session);
+ g = qof_instance_get_guid (original);
+ coll = qof_book_get_collection (targetBook, original->e_type);
+ copy = qof_collection_lookup_entity (coll, g);
+ if (copy)
+ {
+ qecd->error = TRUE;
+ }
+}
+
+static void
+qof_instance_coll_copy (QofInstance *original, gpointer user_data)
+{
+ QofInstanceCopyData *qecd;
+ QofBook *book;
+ QofInstance *inst;
+ const GncGUID *g;
+
+ g_return_if_fail (original != NULL);
+ g_return_if_fail (user_data != NULL);
+ qecd = (QofInstanceCopyData*)user_data;
+ book = qof_session_get_book (qecd->new_session);
+ if (!qof_object_compliance (original->e_type, TRUE))
+ {
+ return;
+ }
+ inst = (QofInstance*)qof_object_new_instance (original->e_type, book);
+ qecd->to = inst;
+ qecd->from = original;
+ g = qof_instance_get_guid (original);
+ qof_instance_set_guid (qecd->to, g);
+ qof_begin_edit (inst);
+ g_slist_foreach (qecd->param_list, qof_instance_foreach_copy, qecd);
+ qof_commit_edit (inst);
+}
+
+gboolean
+qof_instance_copy_to_session (QofSession* new_session, QofInstance* original)
+{
+ QofInstanceCopyData qecd;
+ QofInstance *inst;
+ QofBook *book;
+
+ if (!new_session || !original)
+ {
+ return FALSE;
+ }
+ if (qof_instance_guid_match (new_session, original))
+ {
+ return FALSE;
+ }
+ if (!qof_object_compliance (original->e_type, TRUE))
+ {
+ return FALSE;
+ }
+ qof_event_suspend ();
+ qecd.param_list = NULL;
+ book = qof_session_get_book (new_session);
+ qecd.new_session = new_session;
+ qof_book_set_partial (book);
+ inst = (QofInstance*)qof_object_new_instance (original->e_type, book);
+ qecd.to = inst;
+ qecd.from = original;
+ qof_instance_set_guid (qecd.to, qof_instance_get_guid (original));
+ qof_begin_edit (inst);
+ qof_class_param_foreach (original->e_type, qof_instance_param_cb, &qecd);
+ qof_commit_edit (inst);
+ if (g_slist_length (qecd.param_list) == 0)
+ {
+ return FALSE;
+ }
+ g_slist_foreach (qecd.param_list, qof_instance_foreach_copy, &qecd);
+ g_slist_free (qecd.param_list);
+ qof_event_resume ();
+ return TRUE;
+}
+
+gboolean qof_instance_copy_list (QofSession *new_session, GList *entity_list)
+{
+ QofInstanceCopyData *qecd;
+
+ if (!new_session || !entity_list)
+ {
+ return FALSE;
+ }
+ ENTER (" list=%d", g_list_length (entity_list));
+ qecd = g_new0 (QofInstanceCopyData, 1);
+ qof_event_suspend ();
+ qecd->param_list = NULL;
+ qecd->new_session = new_session;
+ qof_book_set_partial (qof_session_get_book (new_session));
+ g_list_foreach (entity_list, qof_instance_list_foreach, qecd);
+ qof_event_resume ();
+ if (qecd->error)
+ {
+ PWARN (" some/all entities in the list could not be copied.");
+ }
+ g_free (qecd);
+ LEAVE (" ");
+ return TRUE;
+}
+
+gboolean
+qof_instance_copy_coll (QofSession *new_session, QofCollection *entity_coll)
+{
+ QofInstanceCopyData qecd;
+
+ g_return_val_if_fail (new_session, FALSE);
+ if (!entity_coll)
+ {
+ return FALSE;
+ }
+ qof_event_suspend ();
+ qecd.param_list = NULL;
+ qecd.new_session = new_session;
+ qof_book_set_partial (qof_session_get_book (qecd.new_session));
+ qof_collection_foreach (entity_coll, qof_instance_coll_foreach, &qecd);
+ qof_class_param_foreach (qof_collection_get_type (entity_coll),
+ qof_instance_param_cb, &qecd);
+ qof_collection_foreach (entity_coll, qof_instance_coll_copy, &qecd);
+ if (qecd.param_list != NULL)
+ {
+ g_slist_free (qecd.param_list);
+ }
+ qof_event_resume ();
+ return TRUE;
+}
+
+struct recurse_s
+{
+ QofSession *session;
+ gboolean success;
+ GList *ref_list;
+ GList *ent_list;
+};
+
+static void
+recurse_collection_cb (QofInstance *ent, gpointer user_data)
+{
+ struct recurse_s *store;
+
+ if (user_data == NULL)
+ {
+ return;
+ }
+ store = (struct recurse_s*)user_data;
+ if (!ent || !store)
+ {
+ return;
+ }
+ store->success = qof_instance_copy_to_session (store->session, ent);
+ if (store->success)
+ {
+ store->ent_list = g_list_append (store->ent_list, ent);
+ }
+}
+
+static void
+recurse_ent_cb (QofInstance *ent, gpointer user_data)
+{
+ GList *ref_list, *i, *j, *ent_list, *child_list;
+ QofParam *ref_param;
+ QofInstance *ref_ent, *child_ent;
+ QofSession *session;
+ struct recurse_s *store;
+ gboolean success;
+
+ if (user_data == NULL)
+ {
+ return;
+ }
+ store = (struct recurse_s*)user_data;
+ session = store->session;
+ success = store->success;
+ ref_list = NULL;
+ child_ent = NULL;
+ ref_list = g_list_copy (store->ref_list);
+ if ((!session) || (!ent))
+ {
+ return;
+ }
+ ent_list = NULL;
+ child_list = NULL;
+ i = NULL;
+ j = NULL;
+ for (i = ref_list; i != NULL; i = i->next)
+ {
+ if (i->data == NULL)
+ {
+ continue;
+ }
+ ref_param = (QofParam*)i->data;
+ if (ref_param->param_name == NULL)
+ {
+ continue;
+ }
+ if (0 == safe_strcmp (ref_param->param_type, QOF_TYPE_COLLECT))
+ {
+ QofCollection *col;
+
+ col = ref_param->param_getfcn (ent, ref_param);
+ if (col)
+ {
+ qof_collection_foreach (col, recurse_collection_cb, store);
+ }
+ continue;
+ }
+ ref_ent = QOF_INSTANCE (ref_param->param_getfcn (ent, ref_param));
+ if ((ref_ent) && (ref_ent->e_type))
+ {
+ store->success = qof_instance_copy_to_session (session, ref_ent);
+ if (store->success)
+ {
+ ent_list = g_list_append (ent_list, ref_ent);
+ }
+ }
+ }
+ for (i = ent_list; i != NULL; i = i->next)
+ {
+ if (i->data == NULL)
+ {
+ continue;
+ }
+ child_ent = QOF_INSTANCE (i->data);
+ if (child_ent == NULL)
+ {
+ continue;
+ }
+ ref_list = qof_class_get_referenceList (child_ent->e_type);
+ for (j = ref_list; j != NULL; j = j->next)
+ {
+ if (j->data == NULL)
+ {
+ continue;
+ }
+ ref_param = (QofParam*)j->data;
+ ref_ent = ref_param->param_getfcn (child_ent, ref_param);
+ if (ref_ent != NULL)
+ {
+ success = qof_instance_copy_to_session (session, ref_ent);
+ if (success)
+ {
+ child_list = g_list_append (child_list, ref_ent);
+ }
+ }
+ }
+ }
+ for (i = child_list; i != NULL; i = i->next)
+ {
+ if (i->data == NULL)
+ {
+ continue;
+ }
+ ref_ent = QOF_INSTANCE (i->data);
+ if (ref_ent == NULL)
+ {
+ continue;
+ }
+ ref_list = qof_class_get_referenceList (ref_ent->e_type);
+ for (j = ref_list; j != NULL; j = j->next)
+ {
+ if (j->data == NULL)
+ {
+ continue;
+ }
+ ref_param = (QofParam*)j->data;
+ child_ent = ref_param->param_getfcn (ref_ent, ref_param);
+ if (child_ent != NULL)
+ {
+ qof_instance_copy_to_session (session, child_ent);
+ }
+ }
+ }
+}
+
+gboolean
+qof_instance_copy_coll_r (QofSession *new_session, QofCollection *coll)
+{
+ struct recurse_s store;
+ gboolean success;
+
+ if ((!new_session) || (!coll))
+ {
+ return FALSE;
+ }
+ store.session = new_session;
+ success = TRUE;
+ store.success = success;
+ store.ent_list = NULL;
+ store.ref_list = qof_class_get_referenceList (qof_collection_get_type (coll));
+ success = qof_instance_copy_coll (new_session, coll);
+ if (success)
+ {
+ qof_collection_foreach (coll, recurse_ent_cb, &store);
+ }
+ return success;
+}
+
+gboolean qof_instance_copy_one_r (QofSession *new_session, QofInstance *ent)
+{
+ struct recurse_s store;
+ QofCollection *coll;
+ gboolean success;
+
+ if ((!new_session) || (!ent))
+ {
+ return FALSE;
+ }
+ store.session = new_session;
+ success = TRUE;
+ store.success = success;
+ store.ref_list = qof_class_get_referenceList (ent->e_type);
+ success = qof_instance_copy_to_session (new_session, ent);
+ if (success == TRUE)
+ {
+ coll = qof_book_get_collection (qof_session_get_book (new_session), ent->e_type);
+ if (coll)
+ {
+ qof_collection_foreach (coll, recurse_ent_cb, &store);
+ }
+ }
+ return success;
+}
+
+
/* ====================================================================== */
/** Programs that use their own backends also need to call
@@ -909,4 +1616,20 @@
return TRUE;
}
+/* ================= Static function access for testing ================= */
+
+void init_static_qofsession_pointers (void);
+
+void (*p_qof_session_load_backend) (QofSession * session, const char * access_method);
+void (*p_qof_session_clear_error) (QofSession *session);
+void (*p_qof_session_destroy_backend) (QofSession *session);
+
+void
+init_static_qofsession_pointers (void)
+{
+ p_qof_session_load_backend = qof_session_load_backend;
+ p_qof_session_clear_error = qof_session_clear_error;
+ p_qof_session_destroy_backend = qof_session_destroy_backend;
+}
+
/* =================== END OF FILE ====================================== */
More information about the gnucash-changes
mailing list