local + remote sync: negotiate UID support via SyncCap (BMC #22783)
This uses the new libsynthesis support for adding and checking entries in the SyncCap to detect per datastore whether UID/RECURRENCE-ID are truly globally unique and thus can be used to finding pairs. The presence of the property alone is no guarantee for that. Previously this kind of pairing was enabled only for local sync, which was a hack which didn't work for local backends which didn't support UID (for example, Maemo 5 calendar). It also didn't work for mixtures of datastores with and without that kind of support. "1122583000" was randomly chosen as pseudo sync mode. It is a number because strings confuse Funambol. Note that SYNCMODESUPPORTED() only works inside the compare script.
This commit is contained in:
parent
2abbdbe1e9
commit
314f073638
|
@ -25,7 +25,7 @@ SE_CHECK_FOR_STABLE_RELEASE
|
|||
|
||||
# Minimum version of libsynthesis as defined in its
|
||||
# configure script and thus .pc files:
|
||||
define([SYNTHESIS_MIN_VERSION], [3.4.0.16.6])
|
||||
define([SYNTHESIS_MIN_VERSION], [3.4.0.16.7])
|
||||
|
||||
# Line above is patched by gen-autotools.sh. Handle
|
||||
# both "yes" and "no".
|
||||
|
|
|
@ -65,6 +65,15 @@ class EvolutionCalendarSource : public EvolutionSyncSource,
|
|||
virtual std::string getMimeType() const { return "text/calendar"; }
|
||||
virtual std::string getMimeVersion() const { return "2.0"; }
|
||||
|
||||
void getSynthesisInfo(SynthesisInfo &info,
|
||||
XMLConfigFragments &fragments)
|
||||
{
|
||||
// All EDS calendar storages must suppport UID/RECURRENCE-ID,
|
||||
// it's part of the API. Therefore we can rely on it.
|
||||
EvolutionSyncSource::getSynthesisInfo(info, fragments);
|
||||
info.m_globalIDs = true;
|
||||
}
|
||||
|
||||
protected:
|
||||
//
|
||||
// implementation of TrackingSyncSource callbacks
|
||||
|
|
|
@ -48,6 +48,7 @@ class CalDAVSource : public WebDAVSource,
|
|||
virtual void updateSynthesisInfo(SynthesisInfo &info,
|
||||
XMLConfigFragments &fragments) {
|
||||
info.m_backendRule = "HAVE-SYNCEVOLUTION-EXDATE-DETACHED";
|
||||
info.m_globalIDs = true;
|
||||
}
|
||||
|
||||
// implementation of SyncSourceLogging callback
|
||||
|
|
|
@ -2343,8 +2343,6 @@ void SyncContext::getConfigXML(string &xml, string &configname)
|
|||
" INTEGER alarmTimeToUTC;\n"
|
||||
" alarmTimeToUTC = FALSE;\n"
|
||||
" // for VCALENDAR_COMPARE_SCRIPT: don't use UID by default\n"
|
||||
" INTEGER VCALENDAR_COMPARE_UID;\n"
|
||||
" VCALENDAR_COMPARE_UID = FALSE;\n"
|
||||
" ]]></sessioninitscript>\n";
|
||||
|
||||
ostringstream clientorserver;
|
||||
|
@ -3441,17 +3439,6 @@ SyncMLStatus SyncContext::doSync()
|
|||
// (not needed for OBEX)
|
||||
}
|
||||
|
||||
// Choosing between comparing UID/RECURRENCE-ID vs. other
|
||||
// iCalendar 2.0 properties is a hack: in local sync mode, the
|
||||
// iCalendar 2.0 semantic is always picked.
|
||||
if (m_serverMode && m_localSync) {
|
||||
SharedKey sessionKey = m_engine.OpenSessionKey(session);
|
||||
SharedKey contextKey = m_engine.OpenKeyByPath(sessionKey, "/sessionvars");
|
||||
m_engine.SetInt32Value(contextKey,
|
||||
"VCALENDAR_COMPARE_UID",
|
||||
true);
|
||||
}
|
||||
|
||||
// Sync main loop: runs until SessionStep() signals end or error.
|
||||
// Exceptions are caught and lead to a call of SessionStep() with
|
||||
// parameter STEPCMD_ABORT -> abort session as soon as possible.
|
||||
|
|
|
@ -125,7 +125,12 @@ void SyncSourceBase::getDatastoreXML(string &xml, XMLConfigFragments &fragments)
|
|||
(serverModeEnabled() ? "yes" : "no") <<
|
||||
"</plugin_datastoreadmin>\n"
|
||||
" <fromremoteonlysupport> yes </fromremoteonlysupport>\n"
|
||||
" <canrestart>yes</canrestart>\n"
|
||||
" <canrestart>yes</canrestart>\n";
|
||||
if (info.m_globalIDs) {
|
||||
xmlstream <<
|
||||
" <syncmode>1122583000</syncmode>";
|
||||
}
|
||||
xmlstream <<
|
||||
"\n"
|
||||
" <!-- conflict strategy: Newer item wins\n"
|
||||
" You can set 'server-wins' or 'client-wins' as well\n"
|
||||
|
|
|
@ -1385,6 +1385,16 @@ class SyncSourceBase : public Logger {
|
|||
* might send back modified items.
|
||||
*/
|
||||
Bool m_readOnly;
|
||||
|
||||
/**
|
||||
* If true, then the storage preserves and supports UID and
|
||||
* (in iCalendar 2.0) RECURRENCE-ID with the "globally unique"
|
||||
* semantic from iCalendar 2.0 (id assigned once when item is
|
||||
* created). If both sides in a sync support this, then the
|
||||
* engine can rely on these properties to find matching items
|
||||
* during a slow sync.
|
||||
*/
|
||||
Bool m_globalIDs;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -213,8 +213,8 @@
|
|||
]]></macro>
|
||||
|
||||
<!-- Uses the UID/RECURRENCE-ID fields as the only criteria for
|
||||
comparing calendar data if the VCALENDAR_COMPARE_UID session
|
||||
variable is true, else does a normal comparison of the
|
||||
comparing calendar data if the parameter $1 (see GLOBALIDS in <initscript>)
|
||||
is true, else does a normal comparison of the
|
||||
fields. That comparison is based on the datatype definition
|
||||
and ignores UID because it is not trusted to be
|
||||
preserved and/or implemented by peers.
|
||||
|
@ -224,7 +224,7 @@
|
|||
-->
|
||||
<macro name="VCALENDAR_COMPARE_SCRIPT"><![CDATA[
|
||||
INTEGER RES;
|
||||
if (COMPARISONMODE() != "age" && SESSIONVAR("VCALENDAR_COMPARE_UID") ) {
|
||||
if (COMPARISONMODE() != "age" && SYNCMODESUPPORTED("1122583000")) {
|
||||
if (TARGET.UID == REFERENCE.UID &&
|
||||
TARGET.ORIGSTART == REFERENCE.ORIGSTART) {
|
||||
RES = 0;
|
||||
|
|
Loading…
Reference in New Issue