32 struct QofBookMergeRuleIterate
47 #define DEFAULT_MERGE_WEIGHT 1
48 #define QOF_STRING_WEIGHT 3
49 #define QOF_DATE_STRING_LENGTH MAX_DATE_LENGTH
60 if (absolute && !match)
64 if (!absolute && !match)
75 GSList *linkedEntList;
79 collect_reference_cb (
QofEntity * ent, gpointer user_data)
81 struct collect_list_s *s;
83 s = (
struct collect_list_s *) user_data;
86 s->linkedEntList = g_slist_prepend (s->linkedEntList, ent);
94 gchar *stringImport, *stringTarget;
95 QofEntity *mergeEnt, *targetEnt, *referenceEnt;
96 const GUID *guidImport, *guidTarget;
102 gboolean absolute, mergeError, knowntype, mergeMatch, booleanImport,
105 (*numeric_getter) (QofEntity *,
QofParam *);
106 gdouble doubleImport, doubleTarget, (*double_getter) (QofEntity *,
108 gint32 i32Import, i32Target, (*int32_getter) (QofEntity *,
QofParam *);
109 gint64 i64Import, i64Target, (*int64_getter) (QofEntity *,
QofParam *);
110 gchar charImport, charTarget, (*char_getter) (QofEntity *,
QofParam *);
112 g_return_val_if_fail ((mergeData != NULL), -1);
114 g_return_val_if_fail ((currentRule != NULL), -1);
122 g_return_val_if_fail ((targetEnt) || (mergeEnt) || (paramList), -1);
126 while (paramList != NULL)
130 qtparam = paramList->data;
131 mergeParamName = qtparam->param_name;
132 g_return_val_if_fail (mergeParamName != NULL, -1);
133 mergeType = qtparam->param_type;
136 stringImport = qtparam->param_getfcn (mergeEnt, qtparam);
137 stringTarget = qtparam->param_getfcn (targetEnt, qtparam);
139 if (stringImport == NULL)
141 if (stringTarget == NULL)
146 currentRule = qof_book_merge_update_rule (currentRule,
147 mergeMatch, QOF_STRING_WEIGHT);
148 stringImport = stringTarget = NULL;
155 qtImport = qtparam->param_getfcn (mergeEnt, qtparam);
156 qtTarget = qtparam->param_getfcn (targetEnt, qtparam);
158 currentRule = qof_book_merge_update_rule (currentRule,
159 mergeMatch, DEFAULT_MERGE_WEIGHT);
162 #ifndef QOF_DISABLE_DEPRECATED
169 tsImport = date_getter (mergeEnt, qtparam);
170 tsTarget = date_getter (targetEnt, qtparam);
171 if (timespec_cmp (&tsImport, &tsTarget) == 0)
173 currentRule = qof_book_merge_update_rule (currentRule,
174 mergeMatch, DEFAULT_MERGE_WEIGHT);
178 if ((
safe_strcmp (mergeType, QOF_TYPE_NUMERIC) == 0) ||
184 numericImport = numeric_getter (mergeEnt, qtparam);
185 numericTarget = numeric_getter (targetEnt, qtparam);
188 currentRule = qof_book_merge_update_rule (currentRule,
189 mergeMatch, DEFAULT_MERGE_WEIGHT);
194 guidImport = qtparam->param_getfcn (mergeEnt, qtparam);
195 guidTarget = qtparam->param_getfcn (targetEnt, qtparam);
196 if (guid_compare (guidImport, guidTarget) == 0)
198 currentRule = qof_book_merge_update_rule (currentRule,
199 mergeMatch, DEFAULT_MERGE_WEIGHT);
205 (gint32 (*)(QofEntity *,
207 i32Import = int32_getter (mergeEnt, qtparam);
208 i32Target = int32_getter (targetEnt, qtparam);
209 if (i32Target == i32Import)
211 currentRule = qof_book_merge_update_rule (currentRule,
212 mergeMatch, DEFAULT_MERGE_WEIGHT);
218 (gint64 (*)(QofEntity *,
220 i64Import = int64_getter (mergeEnt, qtparam);
221 i64Target = int64_getter (targetEnt, qtparam);
222 if (i64Target == i64Import)
224 currentRule = qof_book_merge_update_rule (currentRule,
225 mergeMatch, DEFAULT_MERGE_WEIGHT);
231 (double (*)(QofEntity *,
233 doubleImport = double_getter (mergeEnt, qtparam);
234 doubleTarget = double_getter (mergeEnt, qtparam);
235 if (doubleImport == doubleTarget)
237 currentRule = qof_book_merge_update_rule (currentRule,
238 mergeMatch, DEFAULT_MERGE_WEIGHT);
241 if (
safe_strcmp (mergeType, QOF_TYPE_BOOLEAN) == 0)
244 (gboolean (*)(QofEntity *,
246 booleanImport = boolean_getter (mergeEnt, qtparam);
247 booleanTarget = boolean_getter (targetEnt, qtparam);
248 if (booleanImport != FALSE && booleanImport != TRUE)
249 booleanImport = FALSE;
250 if (booleanTarget != FALSE && booleanTarget != TRUE)
251 booleanTarget = FALSE;
252 if (booleanImport == booleanTarget)
254 currentRule = qof_book_merge_update_rule (currentRule,
255 mergeMatch, DEFAULT_MERGE_WEIGHT);
267 currentRule = qof_book_merge_update_rule (currentRule,
268 mergeMatch, DEFAULT_MERGE_WEIGHT);
274 (gchar (*)(QofEntity *,
QofParam *)) qtparam->param_getfcn;
275 charImport = char_getter (mergeEnt, qtparam);
276 charTarget = char_getter (targetEnt, qtparam);
277 if (charImport == charTarget)
279 currentRule = qof_book_merge_update_rule (currentRule,
280 mergeMatch, DEFAULT_MERGE_WEIGHT);
289 struct collect_list_s s;
290 s.linkedEntList = NULL;
291 mergeColl = qtparam->param_getfcn (mergeEnt, qtparam);
292 targetColl = qtparam->param_getfcn (targetEnt, qtparam);
298 currentRule = qof_book_merge_update_rule (currentRule,
299 mergeMatch, DEFAULT_MERGE_WEIGHT);
304 referenceEnt = qtparam->param_getfcn (mergeEnt, qtparam);
307 if (referenceEnt == qtparam->param_getfcn (targetEnt, qtparam))
311 if (knowntype == FALSE)
313 referenceEnt = qtparam->param_getfcn (mergeEnt, qtparam);
314 if ((referenceEnt != NULL)
315 && (
safe_strcmp (referenceEnt->e_type, mergeType) == 0))
321 qtparam->param_getfcn (targetEnt, qtparam))
323 currentRule = qof_book_merge_update_rule (currentRule,
324 mergeMatch, DEFAULT_MERGE_WEIGHT);
327 paramList = g_slist_next (paramList);
336 qof_book_merge_commit_foreach_cb (gpointer rule, gpointer arg)
338 struct QofBookMergeRuleIterate *qiter;
340 g_return_if_fail (arg != NULL);
341 qiter = (
struct QofBookMergeRuleIterate *) arg;
342 g_return_if_fail (qiter->data != NULL);
352 struct QofBookMergeRuleIterate qiter;
354 GList *subList, *node;
356 g_return_if_fail (cb != NULL);
357 g_return_if_fail (mergeData != NULL);
359 g_return_if_fail (currentRule != NULL);
360 g_return_if_fail (mergeResult > 0);
367 qiter.ruleList = NULL;
368 for (node = mergeData->
mergeList; node != NULL; node = node->next)
370 currentRule = node->data;
371 if (currentRule->mergeResult == mergeResult)
372 subList = g_list_prepend (subList, currentRule);
374 qiter.remainder = g_list_length (subList);
375 qiter.data = mergeData;
376 g_list_foreach (subList, qof_book_merge_commit_foreach_cb, &qiter);
406 qof_book_merge_rule_cmp (gconstpointer a, gconstpointer b)
417 qof_book_merge_orphan_check (
double difference,
425 g_return_if_fail (mergeRule != NULL);
426 g_return_if_fail (mergeData != NULL);
446 GSList *orphans, *targets;
448 QofEntity *best_matchEnt;
451 g_return_if_fail (mergeData != NULL);
453 g_return_if_fail (currentRule != NULL);
457 targets = g_slist_copy (mergeData->
targetList);
458 while (orphans != NULL)
460 rule = orphans->data;
461 g_return_if_fail (rule != NULL);
468 g_list_prepend (mergeData->
mergeList, rule);
469 orphans = g_slist_next (orphans);
473 g_return_if_fail (qof_book_merge_compare (mergeData) != -1);
480 g_list_prepend (mergeData->
mergeList, rule);
481 qof_book_merge_orphan_check (difference, rule, mergeData);
483 orphans = g_slist_next (orphans);
486 g_slist_free (targets);
490 qof_book_merge_foreach_target (QofEntity * targetEnt, gpointer user_data)
494 g_return_if_fail (user_data != NULL);
496 g_return_if_fail (targetEnt != NULL);
498 g_slist_prepend (mergeData->
targetList, targetEnt);
502 qof_book_merge_foreach_type_target (
QofObject * merge_obj,
508 g_return_if_fail (user_data != NULL);
511 g_return_if_fail (currentRule != NULL);
512 g_return_if_fail (merge_obj != NULL);
518 qof_book_merge_foreach_target, user_data);
523 qof_book_merge_foreach (QofEntity * mergeEnt, gpointer user_data)
527 QofEntity *targetEnt, *best_matchEnt;
532 g_return_if_fail (user_data != NULL);
534 g_return_if_fail (mergeEnt != NULL);
536 g_return_if_fail (currentRule != NULL);
550 targetEnt = best_matchEnt = NULL;
553 (mergeData->
targetBook, mergeEnt->e_type), g);
554 if (targetEnt != NULL)
558 g_return_if_fail (qof_book_merge_compare (mergeData) != -1);
562 g_list_prepend (mergeData->
mergeList, mergeRule);
570 if (g_slist_length (mergeData->
targetList) == 0)
572 difference = g_slist_length (mergeRule->
mergeParam);
577 currentRule = mergeRule;
579 g_return_if_fail (qof_book_merge_compare (mergeData) != -1);
603 qof_book_merge_orphan_check (difference, mergeRule, mergeData);
605 c = g_slist_next (c);
608 if (best_matchEnt != NULL)
617 g_return_if_fail (qof_book_merge_compare (mergeData) != -1);
630 g_list_prepend (mergeData->
mergeList, mergeRule);
636 qof_book_merge_foreach_param (
QofParam * param, gpointer user_data)
640 g_return_if_fail (user_data != NULL);
642 g_return_if_fail (param != NULL);
643 if ((param->param_getfcn != NULL) && (param->param_setfcn != NULL))
651 qof_book_merge_foreach_type (
QofObject * merge_obj, gpointer user_data)
655 g_return_if_fail (user_data != NULL);
657 g_return_if_fail ((merge_obj != NULL));
659 if ((merge_obj->
create == NULL) || (merge_obj->
foreach == NULL))
661 DEBUG (
" merge_obj QOF support failed %s", merge_obj->e_type);
668 qof_book_merge_foreach_param, mergeData);
670 qof_book_merge_foreach, mergeData);
674 qof_book_merge_rule_cb (gpointer rule, gpointer arg)
676 struct QofBookMergeRuleIterate *qiter;
679 g_return_if_fail (arg != NULL);
680 qiter = (
struct QofBookMergeRuleIterate *) arg;
681 mergeData = qiter->data;
682 g_return_if_fail (mergeData != NULL);
683 g_return_if_fail (mergeData->
abort == FALSE);
685 qiter->data = mergeData;
694 gboolean registered_type;
695 QofEntity *referenceEnt;
705 gdouble cm_double, (*double_getter) (QofEntity *,
QofParam *);
706 gboolean cm_boolean, (*boolean_getter) (QofEntity *,
QofParam *);
707 gint32 cm_i32, (*int32_getter) (QofEntity *,
QofParam *);
708 gint64 cm_i64, (*int64_getter) (QofEntity *,
QofParam *);
709 gchar cm_char, (*char_getter) (QofEntity *,
QofParam *);
711 void (*string_setter) (QofEntity *,
const gchar *);
712 void (*time_setter) (QofEntity *,
QofTime *);
713 void (*numeric_setter) (QofEntity *,
QofNumeric);
714 void (*guid_setter) (QofEntity *,
const GUID *);
715 void (*double_setter) (QofEntity *, double);
716 void (*boolean_setter) (QofEntity *, gboolean);
717 void (*i32_setter) (QofEntity *, gint32);
718 void (*i64_setter) (QofEntity *, gint64);
719 void (*char_setter) (QofEntity *, gchar);
720 void (*kvp_frame_setter) (QofEntity *,
KvpFrame *);
721 void (*reference_setter) (QofEntity *, QofEntity *);
724 g_return_if_fail (rule != NULL);
725 g_return_if_fail (mergeData != NULL);
726 g_return_if_fail (mergeData->
targetBook != NULL);
736 g_return_if_fail (inst != NULL);
748 registered_type = FALSE;
754 cm_string = cm_param->param_getfcn (rule->
importEnt, cm_param);
756 (void (*)(QofEntity *,
757 const gchar *)) cm_param->param_setfcn;
758 if (string_setter != NULL)
759 string_setter (rule->
targetEnt, cm_string);
760 registered_type = TRUE;
769 time_getter (rule->
importEnt, cm_param));
771 (void (*)(QofEntity *,
QofTime *))
772 cm_param->param_setfcn;
773 if ((time_setter != NULL) && (qof_time_is_valid (cm_qt)))
775 registered_type = TRUE;
777 #ifndef QOF_DISABLE_DEPRECATED
781 void (*date_setter) (QofEntity *,
Timespec);
786 cm_date = date_getter (rule->
importEnt, cm_param);
788 (void (*)(QofEntity *,
Timespec)) cm_param->param_setfcn;
789 if (date_setter != NULL)
791 registered_type = TRUE;
800 cm_numeric = numeric_getter (rule->
importEnt, cm_param);
802 (void (*)(QofEntity *,
804 if (numeric_setter != NULL)
805 numeric_setter (rule->
targetEnt, cm_numeric);
806 registered_type = TRUE;
810 cm_guid = cm_param->param_getfcn (rule->
importEnt, cm_param);
812 (void (*)(QofEntity *,
813 const GUID *)) cm_param->param_setfcn;
814 if (guid_setter != NULL)
816 registered_type = TRUE;
821 (gint32 (*)(QofEntity *,
822 QofParam *)) cm_param->param_getfcn;
823 cm_i32 = int32_getter (rule->
importEnt, cm_param);
825 (void (*)(QofEntity *, gint32)) cm_param->param_setfcn;
826 if (i32_setter != NULL)
828 registered_type = TRUE;
833 (gint64 (*)(QofEntity *,
834 QofParam *)) cm_param->param_getfcn;
835 cm_i64 = int64_getter (rule->
importEnt, cm_param);
837 (void (*)(QofEntity *, gint64)) cm_param->param_setfcn;
838 if (i64_setter != NULL)
840 registered_type = TRUE;
845 (double (*)(QofEntity *,
846 QofParam *)) cm_param->param_getfcn;
847 cm_double = double_getter (rule->
importEnt, cm_param);
849 (void (*)(QofEntity *, double)) cm_param->param_setfcn;
850 if (double_setter != NULL)
851 double_setter (rule->
targetEnt, cm_double);
852 registered_type = TRUE;
857 (gboolean (*)(QofEntity *,
QofParam *)) cm_param->
859 cm_boolean = boolean_getter (rule->
importEnt, cm_param);
861 (void (*)(QofEntity *, gboolean)) cm_param->param_setfcn;
862 if (boolean_setter != NULL)
863 boolean_setter (rule->
targetEnt, cm_boolean);
864 registered_type = TRUE;
870 param_getfcn (rule->
importEnt, cm_param));
872 (void (*)(QofEntity *,
KvpFrame *)) cm_param->param_setfcn;
873 if (kvp_frame_setter != NULL)
874 kvp_frame_setter (rule->
targetEnt, cm_kvp);
875 registered_type = TRUE;
880 (gchar (*)(QofEntity *,
881 QofParam *)) cm_param->param_getfcn;
882 cm_char = char_getter (rule->
importEnt, cm_param);
884 (void (*)(QofEntity *, gchar)) cm_param->param_setfcn;
885 if (char_setter != NULL)
887 registered_type = TRUE;
891 cm_coll = cm_param->param_getfcn (rule->
importEnt, cm_param);
895 if (collection_setter != NULL)
896 collection_setter (rule->
targetEnt, cm_coll);
897 registered_type = TRUE;
902 cm_param->param_getfcn (rule->
importEnt, cm_param);
904 (void (*)(QofEntity *,
905 QofEntity *)) cm_param->param_setfcn;
906 if (reference_setter != NULL)
907 reference_setter (rule->
targetEnt, referenceEnt);
908 registered_type = TRUE;
910 if (registered_type == FALSE)
913 cm_param->param_getfcn (rule->
importEnt, cm_param);
917 (void (*)(QofEntity *, QofEntity *)) cm_param->
919 if (reference_setter != NULL)
921 reference_setter (rule->
targetEnt, referenceEnt);
939 g_return_val_if_fail ((importBook != NULL)
940 && (targetBook != NULL), NULL);
942 mergeData->
abort = FALSE;
950 g_hash_table_new (g_direct_hash, qof_book_merge_rule_cmp);
956 qof_book_merge_match_orphans (mergeData);
957 for (check = mergeData->
mergeList; check != NULL; check = check->next)
959 currentRule = check->data;
962 mergeData->
abort = TRUE;
974 g_return_if_fail (mergeData != NULL);
977 currentRule = mergeData->
mergeList->data;
985 g_free (currentRule);
1012 gchar *param_string;
1015 const GUID *param_guid;
1018 gdouble param_double, (*double_getter) (QofEntity *,
QofParam *);
1019 gboolean param_boolean, (*boolean_getter) (QofEntity *,
QofParam *);
1020 gint32 param_i32, (*int32_getter) (QofEntity *,
QofParam *);
1021 gint64 param_i64, (*int64_getter) (QofEntity *,
QofParam *);
1022 gchar param_char, (*char_getter) (QofEntity *,
QofParam *);
1024 param_string = NULL;
1025 paramType = qtparam->param_type;
1026 if (
safe_strcmp (paramType, QOF_TYPE_STRING) == 0)
1028 param_string = qtparam->param_getfcn (qtEnt, qtparam);
1029 if (param_string == NULL)
1031 return param_string;
1038 qtparam->param_getfcn (qtEnt, qtparam));
1045 return param_string;
1047 #ifndef QOF_DISABLE_DEPRECATED
1052 gchar param_date[QOF_DATE_STRING_LENGTH];
1056 param_ts = date_getter (qtEnt, qtparam);
1057 param_t = timespecToTime_t (param_ts);
1060 param_string = g_strdup (param_date);
1061 return param_string;
1064 if ((
safe_strcmp (paramType, QOF_TYPE_NUMERIC) == 0) ||
1069 QofParam *)) qtparam->param_getfcn;
1070 param_numeric = numeric_getter (qtEnt, qtparam);
1072 return param_string;
1076 param_guid = qtparam->param_getfcn (qtEnt, qtparam);
1078 param_string = g_strdup (param_sa);
1079 return param_string;
1084 (gint32 (*)(QofEntity *,
QofParam *)) qtparam->param_getfcn;
1085 param_i32 = int32_getter (qtEnt, qtparam);
1086 param_string = g_strdup_printf (
"%d", param_i32);
1087 return param_string;
1092 (gint64 (*)(QofEntity *,
QofParam *)) qtparam->param_getfcn;
1093 param_i64 = int64_getter (qtEnt, qtparam);
1094 param_string = g_strdup_printf (
"%" G_GINT64_FORMAT, param_i64);
1095 return param_string;
1097 if (
safe_strcmp (paramType, QOF_TYPE_DOUBLE) == 0)
1100 (double (*)(QofEntity *,
QofParam *)) qtparam->param_getfcn;
1101 param_double = double_getter (qtEnt, qtparam);
1102 param_string = g_strdup_printf (
"%f", param_double);
1103 return param_string;
1105 if (
safe_strcmp (paramType, QOF_TYPE_BOOLEAN) == 0)
1108 (gboolean (*)(QofEntity *,
QofParam *)) qtparam->param_getfcn;
1109 param_boolean = boolean_getter (qtEnt, qtparam);
1111 if (param_boolean == TRUE)
1112 param_string = g_strdup (
"true");
1114 param_string = g_strdup (
"false");
1115 return param_string;
1119 return param_string;
1123 (gchar (*)(QofEntity *,
QofParam *)) qtparam->param_getfcn;
1124 param_char = char_getter (qtEnt, qtparam);
1125 param_string = g_strdup_printf (
"%c", param_char);
1126 return param_string;
1137 g_return_val_if_fail ((mergeData != NULL), NULL);
1138 g_return_val_if_fail ((tag > 0), NULL);
1141 g_return_val_if_fail ((resolved != NULL), NULL);
1150 if (resolved->
updated == FALSE)
1155 mergeData->
abort = TRUE;
1167 GList *check, *node;
1169 g_return_val_if_fail (mergeData != NULL, -1);
1170 g_return_val_if_fail (mergeData->
mergeList != NULL, -1);
1171 g_return_val_if_fail (mergeData->
targetBook != NULL, -1);
1172 if (mergeData->
abort == TRUE)
1174 check = g_list_copy (mergeData->
mergeList);
1175 g_return_val_if_fail (check != NULL, -1);
1176 for (node = check; node != NULL; node = node->next)
1178 currentRule = node->data;
1182 g_list_free (check);
1187 g_list_free (check);
1191 g_list_free (check);
1192 qof_book_merge_commit_foreach (qof_book_merge_commit_rule_loop,
1194 qof_book_merge_commit_foreach (qof_book_merge_commit_rule_loop,
1200 currentRule = mergeData->
mergeList->data;
1219 struct QofBookMergeRuleIterate qiter;
1221 GList *matching_rules, *node;
1223 g_return_if_fail (cb != NULL);
1224 g_return_if_fail (mergeData != NULL);
1226 g_return_if_fail (mergeResult > 0);
1228 g_return_if_fail (mergeData->
abort == FALSE);
1230 qiter.data = mergeData;
1231 matching_rules = NULL;
1232 for (node = mergeData->
mergeList; node != NULL; node = node->next)
1234 currentRule = node->data;
1235 if (currentRule->mergeResult == mergeResult)
1236 matching_rules = g_list_prepend (matching_rules,
1239 qiter.remainder = g_list_length (matching_rules);
1240 g_list_foreach (matching_rules, qof_book_merge_rule_cb, &qiter);
1241 g_list_free (matching_rules);