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:
Patrick Ohly 2012-04-26 14:27:22 +02:00
parent 2abbdbe1e9
commit 314f073638
7 changed files with 30 additions and 18 deletions

View File

@ -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".

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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"

View File

@ -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;
};
/**

View File

@ -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;