Fix conflict handling issues

This commit is contained in:
Jörg Lehrke 2009-11-11 20:16:34 +00:00
parent b3a1f2de10
commit 81d8ea7bbb
4 changed files with 40 additions and 27 deletions

View File

@ -417,9 +417,18 @@ class Horde_SyncML_State {
$this->_addedItems[$_type] = $_addedItems; $this->_addedItems[$_type] = $_addedItems;
} }
function pushAddedItem($_type, $_addedItems) function mergeAddedItems($_type, $_addedItems)
{ {
$this->_addedItems[$_type] = $_addedItems; if (is_array($this->_addedItems[$_type])) {
$this->_addedItems[$_type] = array_merge($this->_addedItems[$_type], $_addedItems);
} else {
$this->_addedItems[$_type] = $_addedItems;
}
}
function pushAddedItem($_type, $_addedItem)
{
$this->_addedItems[$_type][] = $_addedItem;
} }
function setChangedItems($_type, $_changedItems) function setChangedItems($_type, $_changedItems)
@ -427,6 +436,20 @@ class Horde_SyncML_State {
$this->_changedItems[$_type] = $_changedItems; $this->_changedItems[$_type] = $_changedItems;
} }
function mergeChangedItems($_type, $_changedItems)
{
if (is_array($this->_changedItems[$_type])) {
$this->_changedItems[$_type] = array_merge($this->_changedItems[$_type], $_changedItems);
} else {
$this->_changedItems[$_type] = $_changedItems;
}
}
function pushChangedItem($_type, $_changedItem)
{
$this->_changedItems[$_type][] = $_changedItem;
}
function setClientDeviceInfo($clientDeviceInfo) function setClientDeviceInfo($clientDeviceInfo)
{ {
$this->_clientDeviceInfo = $clientDeviceInfo; $this->_clientDeviceInfo = $clientDeviceInfo;

View File

@ -235,7 +235,7 @@ class Horde_SyncML_Sync {
Horde::logMessage('SyncML: Server RO! REMOVE ' Horde::logMessage('SyncML: Server RO! REMOVE '
. $syncItem->getLocURI() . ' from client', . $syncItem->getLocURI() . ' from client',
__FILE__, __LINE__, PEAR_LOG_WARNING); __FILE__, __LINE__, PEAR_LOG_WARNING);
$state->addConflictItem($type, '!D' . $syncItem->getLocURI()); $state->addConflictItem($type, $syncItem->getLocURI());
} else { } else {
Horde::logMessage('SyncML: Server RO! ' Horde::logMessage('SyncML: Server RO! '
. 'REJECT all client changes', . 'REJECT all client changes',
@ -275,7 +275,7 @@ class Horde_SyncML_Sync {
Horde::logMessage('SyncML: Server RO! ADD ' Horde::logMessage('SyncML: Server RO! ADD '
. $guid . ' to client again', . $guid . ' to client again',
__FILE__, __LINE__, PEAR_LOG_WARNING); __FILE__, __LINE__, PEAR_LOG_WARNING);
// $state->addConflictItem($type, $guid); $state->pushAddedItem($type, $guid);
} else { } else {
Horde::logMessage('SyncML: '. Horde::logMessage('SyncML: '.
'Server RO! REJECT all client changes', 'Server RO! REJECT all client changes',
@ -298,7 +298,7 @@ class Horde_SyncML_Sync {
Horde::logMessage('SyncML: Server Merge Only: ADD ' Horde::logMessage('SyncML: Server Merge Only: ADD '
. $guid . ' to client again', . $guid . ' to client again',
__FILE__, __LINE__, PEAR_LOG_WARNING); __FILE__, __LINE__, PEAR_LOG_WARNING);
// $state->addConflictItem($type, $guid); $state->pushAddedItem($type, $guid);
$state->log('Client-DeleteIgnored'); $state->log('Client-DeleteIgnored');
continue; continue;
} }
@ -368,7 +368,7 @@ class Horde_SyncML_Sync {
Horde::logMessage('SyncML: Server RO! UNDO client change for locuri ' . Horde::logMessage('SyncML: Server RO! UNDO client change for locuri ' .
$syncItem->getLocURI() . ' guid ' . $guid , $syncItem->getLocURI() . ' guid ' . $guid ,
__FILE__, __LINE__, PEAR_LOG_WARNING); __FILE__, __LINE__, PEAR_LOG_WARNING);
$state->addConflictItem($type, $guid); $state->pushChangedItem($type, $guid);
$ok = true; $ok = true;
$replace = false; $replace = false;
} }
@ -421,7 +421,7 @@ class Horde_SyncML_Sync {
// delete this item from client // delete this item from client
Horde::logMessage('SyncML: Server RO! REMOVE ' . $syncItem->getLocURI() . ' from client', Horde::logMessage('SyncML: Server RO! REMOVE ' . $syncItem->getLocURI() . ' from client',
__FILE__, __LINE__, PEAR_LOG_WARNING); __FILE__, __LINE__, PEAR_LOG_WARNING);
$state->addConflictItem($type, '!D' . $syncItem->getLocURI()); $state->addConflictItem($type, $syncItem->getLocURI());
} else { } else {
Horde::logMessage('SyncML: Server RO! REJECT all client changes', Horde::logMessage('SyncML: Server RO! REJECT all client changes',
__FILE__, __LINE__, PEAR_LOG_WARNING); __FILE__, __LINE__, PEAR_LOG_WARNING);

View File

@ -226,7 +226,7 @@ class Horde_SyncML_Sync_SlowSync extends Horde_SyncML_Sync_TwoWaySync {
// delete this item from client // delete this item from client
Horde::logMessage('SyncML: Server RO! REMOVE ' . $syncItem->getLocURI() Horde::logMessage('SyncML: Server RO! REMOVE ' . $syncItem->getLocURI()
. ' from client', __FILE__, __LINE__, PEAR_LOG_WARNING); . ' from client', __FILE__, __LINE__, PEAR_LOG_WARNING);
$state->addConflictItem($type, '!D' . $syncItem->getLocURI()); $state->addConflictItem($type, $syncItem->getLocURI());
} else { } else {
Horde::logMessage('SyncML: Server RO! REJECT all client changes', Horde::logMessage('SyncML: Server RO! REJECT all client changes',
__FILE__, __LINE__, PEAR_LOG_WARNING); __FILE__, __LINE__, PEAR_LOG_WARNING);
@ -274,7 +274,7 @@ class Horde_SyncML_Sync_SlowSync extends Horde_SyncML_Sync_TwoWaySync {
'timestamp' => $future, 'timestamp' => $future,
'type' => $syncType, 'type' => $syncType,
'filter' => $this->_filterExpression))); 'filter' => $this->_filterExpression)));
$state->setAddedItems($syncType, $registry->call($hordeType. '/list', array('filter' => $this->_filterExpression))); $state->mergeAddedItems($syncType, $registry->call($hordeType. '/list', array('filter' => $this->_filterExpression)));
$this->_syncDataLoaded = TRUE; $this->_syncDataLoaded = TRUE;
return count($state->getAddedItems($syncType)) - $delta_add; return count($state->getAddedItems($syncType)) - $delta_add;

View File

@ -82,20 +82,10 @@ class Horde_SyncML_Sync_TwoWaySync extends Horde_SyncML_Sync {
$adds = & $state->getAddedItems($syncType); $adds = & $state->getAddedItems($syncType);
$conflicts = & $state->getConflictItems($syncType); $conflicts = & $state->getConflictItems($syncType);
// manage the conflict items
foreach ( $conflicts as $refresh) {
if (preg_match('/^!D(.*)/', $refresh, $matches)) {
// delete locuri
$remoteDeletes[] = $matches[1];
} else {
$adds[] = $refresh;
}
}
Horde :: logMessage('SyncML: ' . count($changes) . ' changed items found for ' . $syncType, __FILE__, __LINE__, PEAR_LOG_DEBUG); Horde :: logMessage('SyncML: ' . count($changes) . ' changed items found for ' . $syncType, __FILE__, __LINE__, PEAR_LOG_DEBUG);
Horde :: logMessage('SyncML: ' . count($deletes) . ' deleted items found for ' . $syncType, __FILE__, __LINE__, PEAR_LOG_DEBUG); Horde :: logMessage('SyncML: ' . count($deletes) . ' deleted items found for ' . $syncType, __FILE__, __LINE__, PEAR_LOG_DEBUG);
Horde :: logMessage('SyncML: ' . count($remoteDeletes) . ' items to delete on client found for ' . $syncType, __FILE__, __LINE__, PEAR_LOG_DEBUG); Horde :: logMessage('SyncML: ' . count($conflicts) . ' items to delete on client found for ' . $syncType, __FILE__, __LINE__, PEAR_LOG_DEBUG);
Horde :: logMessage('SyncML: ' . count($adds) . ' added items (' . count($refresh) . ' refreshs) found for ' . $syncType, __FILE__, __LINE__, PEAR_LOG_DEBUG); Horde :: logMessage('SyncML: ' . count($adds) . ' added items found for ' . $syncType, __FILE__, __LINE__, PEAR_LOG_DEBUG);
// handle changes // handle changes
if (is_array($changes)) { if (is_array($changes)) {
@ -254,8 +244,8 @@ class Horde_SyncML_Sync_TwoWaySync extends Horde_SyncML_Sync {
} }
// handle remote deletes due to conflicts // handle remote deletes due to conflicts
if (count($remoteDeletes) > 0) { if (count($conflicts) > 0) {
while ($locid = array_shift($remoteDeletes)) { while ($locid = array_shift($conflicts)) {
$currentSize = $output->getOutputSize(); $currentSize = $output->getOutputSize();
// return if we have to much data // return if we have to much data
if (($maxEntries && ($state->getNumberOfElements() >= $maxEntries) if (($maxEntries && ($state->getNumberOfElements() >= $maxEntries)
@ -264,7 +254,7 @@ class Horde_SyncML_Sync_TwoWaySync extends Horde_SyncML_Sync {
|| ($maxMsgSize || ($maxMsgSize
&& (($currentSize +MIN_MSG_LEFT * 2) > $maxMsgSize))) { && (($currentSize +MIN_MSG_LEFT * 2) > $maxMsgSize))) {
// put the item back in the queue // put the item back in the queue
$remoteDeletes[] = $locid; $conflicts[] = $locid;
$state->maxNumberOfElements(); $state->maxNumberOfElements();
$state->setSyncStatus(SERVER_SYNC_DATA_PENDING); $state->setSyncStatus(SERVER_SYNC_DATA_PENDING);
return $currentCmdID; return $currentCmdID;
@ -420,7 +410,7 @@ class Horde_SyncML_Sync_TwoWaySync extends Horde_SyncML_Sync {
'type' => $syncType, 'type' => $syncType,
'filter' => $this->_filterExpression 'filter' => $this->_filterExpression
))); )));
$state->setChangedItems($syncType, $registry->call($hordeType . '/listBy', array ( $state->mergeChangedItems($syncType, $registry->call($hordeType . '/listBy', array (
'action' => 'modify', 'action' => 'modify',
'timestamp' => $refts, 'timestamp' => $refts,
'type' => $syncType, 'type' => $syncType,
@ -442,7 +432,7 @@ class Horde_SyncML_Sync_TwoWaySync extends Horde_SyncML_Sync {
'type' => $syncType, 'type' => $syncType,
'filter' => $this->_filterExpression 'filter' => $this->_filterExpression
))); )));
$state->setAddedItems($syncType, $registry->call($hordeType . '/listBy', array ( $state->mergeAddedItems($syncType, $registry->call($hordeType . '/listBy', array (
'action' => 'add', 'action' => 'add',
'timestamp' => $refts, 'timestamp' => $refts,
'type' => $syncType, 'type' => $syncType,
@ -451,6 +441,6 @@ class Horde_SyncML_Sync_TwoWaySync extends Horde_SyncML_Sync {
$this->_syncDataLoaded = TRUE; $this->_syncDataLoaded = TRUE;
return count($state->getChangedItems($syncType)) - $delta_mod +count($state->getDeletedItems($syncType)) + count($state->getAddedItems($syncType)) - $delta_add +count($state->getConflictItems($syncType)); return count($state->getChangedItems($syncType)) - $delta_mod + count($state->getDeletedItems($syncType)) + count($state->getAddedItems($syncType)) - $delta_add +count($state->getConflictItems($syncType));
} }
} }