The qof_book_merge code is already documented.
A sample test program would use the three qof_book_merge API routines:
qof_book_merge *mergeData; mergeData = qof_merge_bookInit(QofBook *import, QofBook *target);
Make sure you check that mergeData is not NULL before proceeding with the user intervention loop. A NULL indicates a failure and your code MUST abort.
Write your loop to present the output for the user and take the results, ready to pass to qof_book_mergeUpdateResult(). Offer the user options to abort the merge at any/all stages of this loop - nothing in the target book is changed until the code proceeds to the qof_book_mergeCommit stage.
Only when all REPORT items have been re-assigned to NEW, DUPLICATE or UPDATE should you call qof_book_mergeCommit(mergeData).
![]() | Commit cannot be stopped or undone! |
|---|---|
Remember that the commit is a ONE WAY operation - there is NO going back or "unmerging" the books. Your user involvement routine must make it clear to the user that the user must take responsibility for either making a backup or unpicking the merge manually if they have chosen the wrong import file etc. Commit cannot be aborted - forcing a shutdown carries significant risks of corrupting the target book. |
This is the pseudo-code for the Init function where most of the work is done.
Processing starts with Init
Init calls ForeachType (once for each registered type of object)
ForeachType calls ForeachParam
parameter added to list of parameters for the object
Return to ForeachType
ForeachType calls Foreach (each entity in turn)
Foreach creates a new rule and looks up an absolute match in the target book
using Compare
If no absolute match, calls ForeachTypeTarget
Checks that the entity type matches and calls ForeachTarget
ForeachTarget calls orphan_check to prioritise the match
returns to ForeachTypeTarget
returns to Foreach
Sets target(s) or sets MERGE_NEW
returns to ForeachType
returns to Init
mergeData = qof_book_mergeInit( QofBook *importBook, QofBook *targetBook)
qof_object_foreach_type(qof_book_mergeForeachType, mergeData);
qof_class_param_foreach(merge_obj->e_type, qof_book_mergeForeachParam , mergeData);
qof_object_foreach(merge_obj->e_type, mergeData->mergeBook, qof_book_mergeForeach, mergeData);
mergeRule = g_new(qof_book_mergeRule,1);
targetEnt = qof_collection_lookup_entity (
qof_book_get_collection (mergeData->targetBook, mergeEnt->e_type), g);
g_return_if_fail(qof_book_mergeCompare(mergeData) != -1);
qof_object_foreach_type(qof_book_mergeForeachTypeTarget, mergeData);
if(safe_strcmp(merge_obj->e_type, currentRule->importEnt->e_type) == 0) {
qof_object_foreach(currentRule->importEnt->e_type, mergeData->targetBook,
qof_book_mergeForeachTarget, mergeData);
qof_book_merge_orphan_check(difference, mergeRule, mergeData);
}
}
mergeData->mergeList = g_slist_prepend(mergeData->mergeList,mergeRule);Note that qof_book_mergeForeach is the first time real user data is available.
The old examples have been removed - it was proving time-consuming to keep them up to date with changes in the merge API. For examples, please see the GnuCash source tree:
gnucash/src/engine/test/test-book-merge.c
gnucash/src/gnome/druid-merge.c