QofBook
structures with collision handling.
Definition in file qofbookmerge.h.
#include "qofutil.h"
#include "qofbook.h"
#include "qofclass.h"
#include "qofobject.h"
#include "qofinstance.h"
#include "qoflog.h"
Go to the source code of this file.
Data Structures | |
struct | QofBookMergeRule |
One rule per entity, built into a single GList for the entire merge. More... | |
struct | QofBookMergeData |
mergeData contains the essential context data for any merge. More... | |
qof_book_merge API | |
typedef void(* | QofBookMergeRuleForeachCB )(QofBookMergeData *, QofBookMergeRule *, guint) |
Definition of the dialogue control callback routine. | |
QofBookMergeData * | qof_book_merge_init (QofBook *importBook, QofBook *targetBook) |
Initialise the QofBookMerge process. | |
void | qof_book_merge_rule_foreach (QofBookMergeData *mergeData, QofBookMergeRuleForeachCB callback, QofBookMergeResult mergeResult) |
Dialogue Control Callback. | |
gchar * | qof_book_merge_param_as_string (QofParam *qtparam, QofEntity *qtEnt) |
provides easy string access to parameter data for dialogue use | |
QofBookMergeData * | qof_book_merge_update_result (QofBookMergeData *mergeData, QofBookMergeResult tag) |
called by dialogue callback to set the result of user intervention | |
gint | qof_book_merge_commit (QofBookMergeData *mergeData) |
Commits the import data to the target book. | |
void | qof_book_merge_abort (QofBookMergeData *mergeData) |
Abort the merge and free all memory allocated by the merge. | |
Defines | |
#define | QOF_MOD_MERGE "qof-merge" |
Enumerations | |
enum | QofBookMergeResult { MERGE_UNDEF, MERGE_ABSOLUTE, MERGE_NEW, MERGE_REPORT, MERGE_DUPLICATE, MERGE_UPDATE, MERGE_INVALID } |
Results of collisions and user resolution. More... |
|
Definition of the dialogue control callback routine.
All MERGE_REPORT rules must be offered for user intervention using this template. Calling processes are free to also offer MERGE_NEW, MERGE_UPDATE, MERGE_DUPLICATE and MERGE_ABSOLUTE for user intervention. Attempting to query MERGE_INVALID rules will cause an error. For an example, consider test_rule_loop, declared as:
The dialogue is free to call qof_book_merge_update_result in the loop or at the end as long as the link between the rule and the result is maintained, e.g. by using a GHashTable.
If the dialogue sets any rule result to MERGE_INVALID, the import will abort when qof_book_merge_commit is called. It is the responsibility of the calling function to handle the error code from qof_book_merge_commit, close the dialogue and return. The merge routines in these files will already have halted the merge operation and freed any memory allocated to merge structures before returning the error code. There is no need for the dialogue process to report back to QofBookMerge in this situation. Definition at line 321 of file qofbookmerge.h. |
|
Abort the merge and free all memory allocated by the merge. Sometimes, setting MERGE_INVALID is insufficient: e.g. if the user aborts the merge from outside the functions dealing with the merge ruleset. This function causes an immediate abort - the calling process must start again at Init if a new merge is required. Definition at line 837 of file qofbookmerge.c. 00841 { 00842 param_string = g_strdup(qtparam->param_getfcn(qtEnt,qtparam)); 00843 if(param_string == NULL) { param_string = ""; } 00844 return param_string; 00845 } 00846 if(safe_strcmp(paramType, QOF_TYPE_DATE) == 0) { 00847 date_getter = (Timespec (*)(QofEntity*, QofParam*))qtparam->param_getfcn; 00848 param_ts = date_getter(qtEnt, qtparam); 00849 param_t = timespecToTime_t(param_ts); 00850 strftime(param_date, QOF_DATE_STRING_LENGTH, QOF_UTC_DATE_FORMAT, gmtime(¶m_t)); 00851 param_string = g_strdup(param_date); 00852 return param_string; 00853 } 00854 if((safe_strcmp(paramType, QOF_TYPE_NUMERIC) == 0) || 00855 (safe_strcmp(paramType, QOF_TYPE_DEBCRED) == 0)) { 00856 numeric_getter = (gnc_numeric (*)(QofEntity*, QofParam*)) qtparam->param_getfcn; 00857 param_numeric = numeric_getter(qtEnt,qtparam); 00858 param_string = g_strdup(gnc_numeric_to_string(param_numeric)); 00859 return param_string; 00860 }
|
|
Commits the import data to the target book. The last function in the API and the final part of any QofBookMerge operation. qof_book_merge_commit will abort the entire merge operation if any rule is set to MERGE_INVALID. It is the responsibility of the calling function to handle the error code from qof_book_mergeCommit, close the dialogue and return. qof_book_merge_commit will already have halted the merge operation and freed any memory allocated to all merge structures before returning the error code. There is no way for the dialogue process to report back to qof_book_merge in this situation.
qof_book_merge_commit checks for any entities still tagged as MERGE_REPORT and then proceeds to import all entities tagged as MERGE_UPDATE or MERGE_NEW into the target book.
Definition at line 997 of file qofbookmerge.c. 01008 { 01009 currentRule = node->data; 01010 if(currentRule->mergeResult == mergeResult) { 01011 matching_rules = g_list_prepend(matching_rules, currentRule); 01012 } 01013 } 01014 iter.remainder = g_list_length(matching_rules); 01015 g_list_foreach (matching_rules, qof_book_merge_rule_cb, &iter); 01016 g_list_free(matching_rules); 01017 } 01018 01019 /* End of file. */ 01020 /* ==================================================================== */ 01021 /* ==================================================================== */
|
|
Initialise the QofBookMerge process. First function of the QofBookMerge API. Every merge must begin with init.
Requires the book to import (QofBook *) and the book to receive the import, the target book (QofBook *). Returns a pointer to QofBookMergeData which must be checked for a NULL before continuing.
Definition at line 801 of file qofbookmerge.c. 00803 { g_slist_free(mergeData->orphan_list); } 00804 g_hash_table_destroy(mergeData->target_table); 00805 g_free(mergeData); 00806 } 00807 00808 /* The QOF_TYPE_DATE output format from 00809 qof_book_merge_param_as_string has been changed to QSF_XSD_TIME, 00810 a UTC formatted timestring: 2005-01-01T10:55:23Z 00811 If you change QOF_UTC_DATE_FORMAT, change 00812 backend/file/qsf-xml.c : qsf_entity_foreach to 00813 reformat to QSF_XSD_TIME or the QSF XML will 00814 FAIL the schema validation and QSF exports will become invalid. 00815 00816 The QOF_TYPE_BOOLEAN is lowercase for the same reason. 00817 00818 \todo deprecate and replace with 00819 gchar* qof_instance_param_as_string(const QofParam*, QofInstance*); 00820 and then add 00821 gchar* qof_class_get_param_as_string(QofIdTypeConst, QofInstance*); ? 00822 */ 00823 gchar* 00824 qof_book_merge_param_as_string(QofParam *qtparam, QofEntity *qtEnt) 00825 { 00826 gchar *param_string, param_date[QOF_DATE_STRING_LENGTH]; 00827 gchar param_sa[GUID_ENCODING_LENGTH + 1]; 00828 QofType paramType; 00829 const GUID *param_guid; 00830 time_t param_t; 00831 gnc_numeric param_numeric, (*numeric_getter) (QofEntity*, QofParam*); 00832 Timespec param_ts, (*date_getter) (QofEntity*, QofParam*); 00833 double param_double, (*double_getter) (QofEntity*, QofParam*); 00834 gboolean param_boolean, (*boolean_getter) (QofEntity*, QofParam*);
|
|
provides easy string access to parameter data for dialogue use Uses the param_getfcn to retrieve the parameter value as a string, suitable for display in dialogues and user intervention output. Within a QofBookMerge context, only the parameters used in the merge are available, i.e. parameters where both param_getfcn and param_setfcn are not NULL. Note that the object type description (a full text version of the object name) is also available to the dialogue as QofBookMergeRule::mergeLabel. This allows the dialog to display the description of the object and all parameter data. Definition at line 878 of file qofbookmerge.c. 00879 { 00880 double_getter = (double (*)(QofEntity*, QofParam*)) qtparam->param_getfcn; 00881 param_double = double_getter(qtEnt, qtparam); 00882 param_string = g_strdup_printf("%f", param_double); 00883 return param_string; 00884 } 00885 if(safe_strcmp(paramType, QOF_TYPE_BOOLEAN) == 0){ 00886 boolean_getter = (gboolean (*)(QofEntity*, QofParam*)) qtparam->param_getfcn; 00887 param_boolean = boolean_getter(qtEnt, qtparam); 00888 /* Boolean values need to be lowercase for QSF validation. */ 00889 if(param_boolean == TRUE) { param_string = g_strdup("true"); } 00890 else { param_string = g_strdup("false"); } 00891 return param_string; 00892 } 00893 /* "kvp" contains repeating values, cannot be a single string for the frame. */ 00894 if(safe_strcmp(paramType, QOF_TYPE_KVP) == 0) { return param_string; } 00895 if(safe_strcmp(paramType, QOF_TYPE_CHAR) == 0) { 00896 char_getter = (gchar (*)(QofEntity*, QofParam*)) qtparam->param_getfcn; 00897 param_char = char_getter(qtEnt, qtparam); 00898 param_string = g_strdup_printf("%c", param_char); 00899 return param_string; 00900 } 00901 return NULL; 00902 } 00903 00904 QofBookMergeData* 00905 qof_book_merge_update_result(QofBookMergeData *mergeData, 00906 QofBookMergeResult tag) 00907 { 00908 QofBookMergeRule *resolved; 00909 00910 g_return_val_if_fail((mergeData != NULL), NULL); 00911 g_return_val_if_fail((tag > 0), NULL); 00912 g_return_val_if_fail((tag != MERGE_REPORT), NULL); 00913 resolved = mergeData->currentRule; 00914 g_return_val_if_fail((resolved != NULL), NULL); 00915 if((resolved->mergeAbsolute == TRUE)&&(tag == MERGE_DUPLICATE)) 00916 { 00917 tag = MERGE_ABSOLUTE; 00918 } 00919 if((resolved->mergeAbsolute == TRUE)&&(tag == MERGE_NEW)) 00920 { 00921 tag = MERGE_UPDATE; 00922 } 00923 if((resolved->mergeAbsolute == FALSE)&& (tag == MERGE_ABSOLUTE)) 00924 { 00925 tag = MERGE_DUPLICATE; 00926 } 00927 if((resolved->mergeResult == MERGE_NEW)&&(tag == MERGE_UPDATE)) 00928 { 00929 tag = MERGE_NEW; 00930 } 00931 if(resolved->updated == FALSE) { resolved->mergeResult = tag; } 00932 resolved->updated = TRUE; 00933 if(tag >= MERGE_INVALID) { 00934 mergeData->abort = TRUE; 00935 mergeData->currentRule = resolved; 00936 return NULL; 00937 } 00938 mergeData->currentRule = resolved; 00939 return mergeData; 00940 } 00941 00942 gint 00943 qof_book_merge_commit(QofBookMergeData *mergeData ) 00944 { 00945 QofBookMergeRule *currentRule; 00946 GList *check, *node; 00947 00948 g_return_val_if_fail(mergeData != NULL, -1); 00949 g_return_val_if_fail(mergeData->mergeList != NULL, -1); 00950 g_return_val_if_fail(mergeData->targetBook != NULL, -1); 00951 if(mergeData->abort == TRUE) return -1; 00952 check = g_list_copy(mergeData->mergeList); 00953 g_return_val_if_fail(check != NULL, -1); 00954 for (node = check; node != NULL; node = node->next) 00955 { 00956 currentRule = node->data;
|
|
Dialogue Control Callback. This function is designed to be used to iterate over all rules tagged with a specific QofBookMergeResult value.
Uses qof_book_get_collection with the QofBookMergeRule::mergeType object type to return a collection of QofEntity entities from either the QofBookMergeData::mergeBook or QofBookMergeData::targetBook. Then uses qof_collection_lookup_entity to lookup the QofBookMergeRule::importEnt and again the qof_book_mergeRule::targetEnt to return the two specific entities. Definition at line 1044 of file qofbookmerge.c. |
|
called by dialogue callback to set the result of user intervention Set any rule result to MERGE_INVALID to abort the import when qof_book_merge_commit is called, without changing the target book. The calling process should make it absolutely clear that a merge operation cannot be undone and that a backup copy should always be available before a merge is initialised. Recommended method: Only offer three options to the user per rule:
Handle the required result changes in code: Check the value of qof_book_mergeRule::mergeAbsolute and use these principles: To ignore entities tagged as:
To merge entities that are not pre-set to MERGE_NEW, set MERGE_UPDATE.
To add entities, check mergeAbsolute is FALSE and set MERGE_NEW. It is not possible to update the same rule more than once.
qof_book_merge_commit only commits entities tagged with MERGE_NEW and MERGE_UPDATE results. The calling process must check the return value and call qof_book_merge_abort(mergeData) if non-zero.
Definition at line 959 of file qofbookmerge.c. 00962 { 00963 g_list_free(check); 00964 return 1; 00965 } 00966 } 00967 g_list_free(check); 00968 qof_book_merge_commit_foreach(qof_book_merge_commit_rule_loop, 00969 MERGE_NEW, mergeData); 00970 qof_book_merge_commit_foreach(qof_book_merge_commit_rule_loop, 00971 MERGE_UPDATE, mergeData); 00972 /* Placeholder for QofObject merge_helper_cb - all objects 00973 and all parameters set */ 00974 while(mergeData->mergeList != NULL) { 00975 currentRule = mergeData->mergeList->data; 00976 g_slist_free(currentRule->mergeParam); 00977 g_slist_free(currentRule->linkedEntList); 00978 mergeData->mergeList = g_list_next(mergeData->mergeList); 00979 } 00980 g_list_free(mergeData->mergeList); 00981 g_slist_free(mergeData->mergeObjectParams); 00982 g_slist_free(mergeData->targetList); 00983 if(mergeData->orphan_list != NULL) { g_slist_free(mergeData->orphan_list); } 00984 g_hash_table_destroy(mergeData->target_table); 00985 g_free(mergeData); 00986 return 0; 00987 } 00988 00989 void 00990 qof_book_merge_rule_foreach(QofBookMergeData *mergeData, 00991 QofBookMergeRuleForeachCB cb, 00992 QofBookMergeResult mergeResult ) 00993 { 00994 struct QofBookMergeRuleIterate iter;
|