SF #2095433: regression in 0.8: one-way sync of virtual birthday calendar
"refresh-from-client" works again for the birthday calendar. In contrast to previous releases SyncEvolution now does some sanity checks that the sync mode is right. For all modes other than "refresh-from-server" and "slow" the following error is reported: 22:39:34 [INFO] ical20: sync mode is 'refresh from server' 22:39:34 [ERROR] ical20: could not read revision identifier for item pas-id-43C0ED3900000001-anniversary-rid: only refresh-from-client synchronization is supported "slow" syncs may or may not work, depending on whether the server sends back updates. Better don't use it. If the server sends back items during a slow sync, then the error message is a bit cryptic: 22:47:02 [INFO] ical20: eg2fVHx6bZ6VF2MR5TgdHQ==: add 22:47:02 [INFO] ical20: eg2fVHx6bZ6VF2MR5TgdHQ==: exists already, updating instead 22:47:02 [ERROR] ical20: updating item eg2fVHx6bZ6VF2MR5TgdHQ==: Unknown error git-svn-id: https://zeitsenke.de/svn/SyncEvolution/trunk@752 15ad00c4-1369-45f4-8270-35d70d36bdcd
This commit is contained in:
parent
777d91b915
commit
0cb88c7cd1
|
@ -726,8 +726,12 @@ string EvolutionCalendarSource::getItemModTime(ECalComponent *ecomp)
|
|||
{
|
||||
struct icaltimetype *modTime;
|
||||
e_cal_component_get_last_modified(ecomp, &modTime);
|
||||
eptr<struct icaltimetype, struct icaltimetype, EvolutionUnrefFree<struct icaltimetype> > modTimePtr(modTime, "item without modification time");
|
||||
eptr<struct icaltimetype, struct icaltimetype, EvolutionUnrefFree<struct icaltimetype> > modTimePtr(modTime);
|
||||
if (!modTimePtr) {
|
||||
return "";
|
||||
} else {
|
||||
return icalTime2Str(*modTimePtr);
|
||||
}
|
||||
}
|
||||
|
||||
string EvolutionCalendarSource::getItemModTime(const ItemID &id)
|
||||
|
@ -735,11 +739,11 @@ string EvolutionCalendarSource::getItemModTime(const ItemID &id)
|
|||
eptr<icalcomponent> icomp(retrieveItem(id));
|
||||
icalproperty *lastModified = icalcomponent_get_first_property(icomp, ICAL_LASTMODIFIED_PROPERTY);
|
||||
if (!lastModified) {
|
||||
throwError("getItemModTime(): item without modification time");
|
||||
}
|
||||
return "";
|
||||
} else {
|
||||
struct icaltimetype modTime = icalproperty_get_lastmodified(lastModified);
|
||||
return icalTime2Str(modTime);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
string EvolutionCalendarSource::icalTime2Str(const icaltimetype &tt)
|
||||
|
|
|
@ -151,12 +151,14 @@ class EvolutionCalendarSource : public TrackingSyncSource
|
|||
|
||||
/**
|
||||
* Extract modification string from calendar item.
|
||||
* @return empty string if no time was available
|
||||
*/
|
||||
string getItemModTime(ECalComponent *ecomp);
|
||||
|
||||
/**
|
||||
* Extract modification string of an item stored in
|
||||
* the calendar.
|
||||
* @return empty string if no time was available
|
||||
*/
|
||||
string getItemModTime(const ItemID &id);
|
||||
|
||||
|
|
|
@ -53,6 +53,18 @@ void TrackingSyncSource::beginSyncThrow(bool needAll,
|
|||
const string &uid = mapping.first;
|
||||
const string &revision = mapping.second;
|
||||
|
||||
// uid must always be non-empty whereas
|
||||
// revision may be empty when doing refresh-from-client
|
||||
// syncs; refresh-from-client cannot be distinguished
|
||||
// from slow syncs, so allow slow syncs, too
|
||||
if (uid.empty()) {
|
||||
throwError("could not read UID for an item");
|
||||
}
|
||||
bool fromClient = needAll && !needPartial && !deleteLocal;
|
||||
if (!fromClient && revision.empty()) {
|
||||
throwError(string("could not read revision identifier for item ") + uid + ": only refresh-from-client synchronization is supported");
|
||||
}
|
||||
|
||||
if (deleteLocal) {
|
||||
deleteItem(uid);
|
||||
} else {
|
||||
|
@ -132,6 +144,9 @@ int TrackingSyncSource::addItemThrow(SyncItem& item)
|
|||
{
|
||||
InsertItemResult res = insertItem("", item);
|
||||
item.setKey(res.m_uid.c_str());
|
||||
if (res.m_uid.empty() || res.m_revision.empty()) {
|
||||
throwError("could not add item");
|
||||
}
|
||||
m_trackingNode->setProperty(res.m_uid, res.m_revision);
|
||||
return res.m_merged ? STC_CONFLICT_RESOLVED_WITH_MERGE : STC_OK;
|
||||
}
|
||||
|
@ -144,6 +159,9 @@ int TrackingSyncSource::updateItemThrow(SyncItem& item)
|
|||
m_trackingNode->removeProperty(uid);
|
||||
}
|
||||
item.setKey(res.m_uid.c_str());
|
||||
if (res.m_uid.empty() || res.m_revision.empty()) {
|
||||
throwError("could not update item");
|
||||
}
|
||||
m_trackingNode->setProperty(res.m_uid, res.m_revision);
|
||||
return res.m_merged ? STC_CONFLICT_RESOLVED_WITH_MERGE : STC_OK;
|
||||
}
|
||||
|
|
|
@ -92,6 +92,14 @@ class TrackingSyncSource : public EvolutionSyncSource
|
|||
/**
|
||||
* fills the complete mapping from UID to revision string of all
|
||||
* currently existing items
|
||||
*
|
||||
* Usually both UID and revision string must be non-empty. The
|
||||
* only exception is a refresh-from-client: in that case the
|
||||
* revision string may be empty. The implementor of this call
|
||||
* cannot know whether empty strings are allowed, therefore it
|
||||
* should not throw errors when it cannot create a non-empty
|
||||
* string. The caller of this method will detect situations where
|
||||
* a non-empty string is necessary and none was provided.
|
||||
*/
|
||||
virtual void listAllItems(RevisionMap_t &revisions) = 0;
|
||||
|
||||
|
@ -130,7 +138,9 @@ class TrackingSyncSource : public EvolutionSyncSource
|
|||
* This error should be reported instead of covering it up by
|
||||
* (re)creating the item.
|
||||
*
|
||||
* Errors are signalled by throwing an exception.
|
||||
* Errors are signalled by throwing an exception. Returning empty
|
||||
* strings in the result is an error which triggers an "item could
|
||||
* not be stored" error.
|
||||
*
|
||||
* @param uid identifies the item to be modified, empty for creating
|
||||
* @param item contains the new content of the item and its MIME type
|
||||
|
|
Loading…
Reference in a new issue