Hello Patrick,
On Jun 14, 2011, at 15:21 , Patrick Ohly wrote:
> The documentation for a comparescript describes return codes for the
> cases where the two items are equal, but one is more recent than the
> other:
>
> script returning 0 if target equals reference, 1 if target is
> newer than reference, -1 if target is older than reference,-999
> if items are not comparable or not equal but age of items is not
> known.
I admit this is a bit confusing, because the description above mixes age and
equality.
More precisely it was meant to say:
0 = the two items are equal (within the scope of the eqMode). In this
case, age is considered irrelevant.
-1 / 1 = the two items are not equal (within the scope of the eqMode). In
this case, age MIGHT be a relevant
information for merging the data, so it should be returned.
-999 = the two items are not equal, but no information about age is
available
> I have written a compare script which checks UID/RECURRENCE-ID to
> determine matching items and then looks at LAST-MODIFIED to determine
> which one is more recent:
>
> if (TARGET.UID == REFERENCE.UID &&
> TARGET.ORIGSTART == REFERENCE.ORIGSTART) {
> RES = COMPARE(TARGET.DMODIFIED, REFERENCE.DMODIFIED);
> } else {
> RES = -999;
> }
The conceptional problem is that UID match is a different kind of "equal" than
actual matching data.
Matching UIDs (assuming stable UIDs...) say: "I know these two items REPRESENT
the same item, even if they are not really equal in content".
Matching content ays: "I see these two items ARE the same, so these can be
unified into one"
While the latter match case requires no further data operation (items ARE
already equal), the former might selection of the "better" representation,
usually the newer one. I guess that's what you wanted to achieve above.
> [...] Is a comparescript expected to always return
> zero for a match and skip the age comparison?
Yes, according to the above (at least, in eqm_slowsyc or eqm_always comparison
modes).
That's what determines a match for slowsync in the first place.
But then, if the the engine is in "newer-wins" conflict strategy mode, it will
do a second comparison in eqm_none mode. eqm_none mode does the comparison
without checking for equal, but only for age.
Now the only thing that seems missing is a way to reference the comparison mode
from within your script, so that it can behave differently in eqm_none mode.
See the attached patch for a new script function COMPARISONMODE(), compiles but
is UNTESTED.
With this, your comparescript could probably look like:
if (COMPARISONMODE!="age" &&
TARGET.UID == REFERENCE.UID &&
TARGET.ORIGSTART == REFERENCE.ORIGSTART) {
RES = 0;
} else {
RES = COMPARE(TARGET.DMODIFIED, REFERENCE.DMODIFIED);
}
Best Regards,
Lukas
From: Lukas Zeller <[email protected]>
Date: Fri, 17 Jun 2011 15:35:31 +0200
Subject: [PATCH] engine: added COMPARISONMODE() script function to allow
<comparescript> to behave differently in different modes
---
sysync/multifielditemtype.cpp | 15 +++++++++++++++
sysync/syncitem.cpp | 12 ++++++++++++
sysync/syncitem.h | 3 +++
3 files changed, 30 insertions(+), 0 deletions(-)
diff --git a/sysync/multifielditemtype.cpp b/sysync/multifielditemtype.cpp
index 88ce300..e9e5dec 100755
--- a/sysync/multifielditemtype.cpp
+++ b/sysync/multifielditemtype.cpp
@@ -220,6 +220,20 @@ public:
}
}; // func_CompareFields
+
+ // string COMPARISONMODE()
+ // returns mode of comparison
+ static void func_ComparisonMode(TItemField *&aTermP, TScriptContext
*aFuncContextP)
+ {
+ TMultiFieldItemType *mfitP = static_cast<TMultiFieldItemType
*>(aFuncContextP->getCallerContext());
+ if (!mfitP->fFirstItemP) aTermP->unAssign(); // no comparison
+ else {
+ aTermP->setAsString(comparisonModeNames[mfitP->fEqMode]);
+ }
+ }; // func_CompareFields
+
+
+
#endif
@@ -325,6 +339,7 @@ const TBuiltInFuncDef DataTypeFuncDefs[] = {
{ "SETWINNINGCHANGED", TMFTypeFuncs::func_SetWinningChanged, fty_none, 1,
param_IntArg },
{ "SETLOOSINGCHANGED", TMFTypeFuncs::func_SetLoosingChanged, fty_none, 1,
param_IntArg },
{ "COMPAREFIELDS", TMFTypeFuncs::func_CompareFields, fty_integer, 0, NULL },
+ { "COMPARISONMODE", TMFTypeFuncs::func_ComparisonMode, fty_string, 0, NULL },
#endif
{ "SYNCOP", TMFTypeFuncs::func_SyncOp, fty_string, 0, NULL },
{ "REJECTITEM", TMFTypeFuncs::func_RejectItem, fty_none, 1, param_IntArg },
diff --git a/sysync/syncitem.cpp b/sysync/syncitem.cpp
index a1a5dda..14a93f1 100755
--- a/sysync/syncitem.cpp
+++ b/sysync/syncitem.cpp
@@ -37,6 +37,18 @@ const char * const sysync::compareRelevanceNames[numEQmodes]
= {
"n/a"
};
+
+const char * const sysync::comparisonModeNames[numEQmodes] = {
+ "all", // compare all fields, even irrelevant ones
+ "n/a", // n/a (scripted)
+ "conflict", // compare fields relevant for (normal sync) conflict detection
+ "slowsync", // compare fields relevant for slow sync match
+ "firstsync", // compare fields relevant for first time slow sync match
(possibly relaxed comparison rules)
+ "age", // no test for equality, only for age (returns SYSYNC_NOT_COMPARABLE
if age comparison not possible)
+};
+
+
+
/*
* Implementation of TSyncItem
*/
diff --git a/sysync/syncitem.h b/sysync/syncitem.h
index 0221e91..df40c15 100755
--- a/sysync/syncitem.h
+++ b/sysync/syncitem.h
@@ -44,7 +44,10 @@ typedef enum { // RELEVANCE
COMPARE MODE
// be modified
// Fields with eqm_none will also not be included in CRC calculations for
detecting changes.
+// Names for TEqualityMode when used as field relevance
extern const char * const compareRelevanceNames[numEQmodes];
+ // Names for TEqualityMode when used as comparison mode
+extern const char * const comparisonModeNames[numEQmodes];
// merge options
--
1.7.4.4+GitX
_______________________________________________
os-libsynthesis mailing list
[email protected]
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis