lib/kolab_sync_data_email.php lib/kolab_sync_data.php lib/plugins
Aleksander Machniak
machniak at kolabsys.com
Thu Jan 2 13:30:58 CET 2014
lib/kolab_sync_data.php | 87 +++++++++++++++--------
lib/kolab_sync_data_email.php | 11 ++
lib/plugins/libkolab/lib/kolab_storage_cache.php | 25 +++++-
3 files changed, 88 insertions(+), 35 deletions(-)
New commits:
commit e46f49b16a35c3cd01c492d022f6965be3fe408e
Author: Aleksander Machniak <alec at alec.pl>
Date: Thu Jan 2 13:30:31 2014 +0100
Improve errors handling to prevent removing all objects from the device (Bug #2698)
diff --git a/lib/kolab_sync_data.php b/lib/kolab_sync_data.php
index eae8630..15db5bd 100644
--- a/lib/kolab_sync_data.php
+++ b/lib/kolab_sync_data.php
@@ -536,6 +536,7 @@ abstract class kolab_sync_data implements Syncroton_Data_IData
}
$result = $result_type == self::RESULT_COUNT ? 0 : array();
+ $found = 0;
foreach ($folders as $folderid) {
$foldername = $this->backend->folder_id2name($folderid, $this->device->deviceid);
@@ -550,23 +551,51 @@ abstract class kolab_sync_data implements Syncroton_Data_IData
continue;
}
+ $found++;
+ $error = false;
+
switch ($result_type) {
case self::RESULT_COUNT:
- $result += (int) $folder->count($filter);
+ $count = $folder->count($filter);
+
+ if ($count === null || $count === false) {
+ $error = true;
+ }
+ else {
+ $result += (int) count;
+ }
break;
case self::RESULT_UID:
- if ($uids = $folder->get_uids($filter)) {
+ $uids = $folder->get_uids($filter);
+
+ if (!is_array($uids)) {
+ $error = true;
+ }
+ else {
$result = array_merge($result, $uids);
}
break;
case self::RESULT_OBJECT:
default:
- if ($objects = $folder->select($filter)) {
+ $objects = $folder->select($filter);
+
+ if (!is_array($objects)) {
+ $error = true;
+ }
+ else {
$result = array_merge($result, $objects);
}
}
+
+ if ($error) {
+ throw new Syncroton_Exception_Status(Syncroton_Exception_Status::SERVER_ERROR);
+ }
+ }
+
+ if (!$found) {
+ throw new Syncroton_Exception_Status(Syncroton_Exception_Status::SERVER_ERROR);
}
return $result;
@@ -586,58 +615,54 @@ abstract class kolab_sync_data implements Syncroton_Data_IData
}
/**
- * get all entries changed between to dates
+ * get all entries changed between two dates
*
- * @param string $folderId
+ * @param string $folderId
* @param DateTime $start
* @param DateTime $end
- * @param int $filterType
+ * @param int $filterType
*
* @return array
*/
public function getChangedEntries($folderId, DateTime $start, DateTime $end = null, $filter_type = null)
{
- $filter = $this->filter($filter_type);
+ $filter = $this->filter($filter_type);
$filter[] = array('changed', '>', $start);
if ($end) {
$filter[] = array('changed', '<=', $end);
}
- $result = $this->searchEntries($folderId, $filter, self::RESULT_UID);
-
- return $result;
+ return $this->searchEntries($folderId, $filter, self::RESULT_UID);
}
/**
* get count of entries changed between two dates
*
- * @param string $folderId
+ * @param string $folderId
* @param DateTime $start
* @param DateTime $end
- * @param int $filterType
+ * @param int $filterType
*
* @return int
*/
public function getChangedEntriesCount($folderId, DateTime $start, DateTime $end = null, $filter_type = null)
{
- $filter = $this->filter($filter_type);
+ $filter = $this->filter($filter_type);
$filter[] = array('changed', '>', $start);
if ($end) {
$filter[] = array('changed', '<=', $end);
}
- $result = $this->searchEntries($folderId, $filter, self::RESULT_COUNT);
-
- return $result;
+ return $this->searchEntries($folderId, $filter, self::RESULT_COUNT);
}
/**
* get id's of all entries available on the server
*
* @param string $folderId
- * @param int $filterType
+ * @param int $filterType
*
* @return array
*/
@@ -696,21 +721,27 @@ abstract class kolab_sync_data implements Syncroton_Data_IData
*/
public function hasChanges(Syncroton_Backend_IContent $contentBackend, Syncroton_Model_IFolder $folder, Syncroton_Model_ISyncState $syncState)
{
- if ($this->getChangedEntriesCount($folder->serverId, $syncState->lastsync, null, $folder->lastfiltertype)) {
- return true;
- }
+ try {
+ if ($this->getChangedEntriesCount($folder->serverId, $syncState->lastsync, null, $folder->lastfiltertype)) {
+ return true;
+ }
- $allClientEntries = $contentBackend->getFolderState($this->device, $folder);
+ $allClientEntries = $contentBackend->getFolderState($this->device, $folder);
- // @TODO: Consider looping over all folders here, not in getServerEntries() and
- // getChangedEntriesCount(). This way we could break the loop and not check all folders
- // or at least skip redundant cache sync of the same folder
- $allServerEntries = $this->getServerEntries($folder->serverId, $folder->lastfiltertype);
+ // @TODO: Consider looping over all folders here, not in getServerEntries() and
+ // getChangedEntriesCount(). This way we could break the loop and not check all folders
+ // or at least skip redundant cache sync of the same folder
+ $allServerEntries = $this->getServerEntries($folder->serverId, $folder->lastfiltertype);
- $addedEntries = array_diff($allServerEntries, $allClientEntries);
- $deletedEntries = array_diff($allClientEntries, $allServerEntries);
+ $addedEntries = array_diff($allServerEntries, $allClientEntries);
+ $deletedEntries = array_diff($allClientEntries, $allServerEntries);
- return count($addedEntries) > 0 || count($deletedEntries) > 0;
+ return count($addedEntries) > 0 || count($deletedEntries) > 0;
+ }
+ catch (Exception $e) {
+ // return "no changes" if something failed
+ return false;
+ }
}
/**
diff --git a/lib/kolab_sync_data_email.php b/lib/kolab_sync_data_email.php
index 18b8b54..3d7f835 100644
--- a/lib/kolab_sync_data_email.php
+++ b/lib/kolab_sync_data_email.php
@@ -779,6 +779,7 @@ class kolab_sync_data_email extends kolab_sync_data implements Syncroton_Data_ID
$result = $result_type == self::RESULT_COUNT ? 0 : array();
// no sorting for best performance
$sort_by = null;
+ $found = 0;
foreach ($folders as $folder_id) {
$foldername = $this->backend->folder_id2name($folder_id, $this->device->deviceid);
@@ -787,6 +788,8 @@ class kolab_sync_data_email extends kolab_sync_data implements Syncroton_Data_ID
continue;
}
+ $found++;
+
$this->storage->set_folder($foldername);
// Syncronize folder (if it wasn't synced in this request already)
@@ -837,8 +840,8 @@ class kolab_sync_data_email extends kolab_sync_data implements Syncroton_Data_ID
$search = $this->storage->search_once($foldername, $filter_str);
- if (!($search instanceof rcube_result_index)) {
- continue;
+ if (!($search instanceof rcube_result_index) || $search->is_error()) {
+ throw new Syncroton_Exception_Status(Syncroton_Exception_Status::SERVER_ERROR);
}
switch ($result_type) {
@@ -864,6 +867,10 @@ class kolab_sync_data_email extends kolab_sync_data implements Syncroton_Data_ID
}
}
+ if (!$found) {
+ throw new Syncroton_Exception_Status(Syncroton_Exception_Status::SERVER_ERROR);
+ }
+
if (!empty($modseq_update)) {
$this->backend->modseq_set($this->device->id, $folderid,
$this->syncTimeStamp, $modseq_data);
diff --git a/lib/plugins/libkolab/lib/kolab_storage_cache.php b/lib/plugins/libkolab/lib/kolab_storage_cache.php
index 651dc18..732ce8f 100644
--- a/lib/plugins/libkolab/lib/kolab_storage_cache.php
+++ b/lib/plugins/libkolab/lib/kolab_storage_cache.php
@@ -411,6 +411,10 @@ class kolab_storage_cache
$this->folder_id
);
+ if ($this->db->is_error($sql_result)) {
+ return null;
+ }
+
while ($sql_arr = $this->db->fetch_assoc($sql_result)) {
if ($uids) {
$this->uid2msg[$sql_arr['uid']] = $sql_arr['msguid'];
@@ -431,7 +435,11 @@ class kolab_storage_cache
}
else { // search by object type
$search = 'UNDELETED HEADER X-Kolab-Type ' . kolab_format::KTYPE_PREFIX . $filter['type'];
- $index = $this->imap->search_once($this->folder->name, $search)->get();
+ $index = $this->imap->search_once($this->folder->name, $search)->get();
+ }
+
+ if ($index->is_error()) {
+ return null;
}
// fetch all messages in $index from IMAP
@@ -461,8 +469,6 @@ class kolab_storage_cache
*/
public function count($query = array())
{
- $count = 0;
-
// cache is in sync, we can count records in local DB
if ($this->synched) {
$this->_read_folder_data();
@@ -473,14 +479,23 @@ class kolab_storage_cache
$this->folder_id
);
+ if ($this->db->is_error($sql_result)) {
+ return null;
+ }
+
$sql_arr = $this->db->fetch_assoc($sql_result);
- $count = intval($sql_arr['numrows']);
+ $count = intval($sql_arr['numrows']);
}
else {
// search IMAP by object type
$filter = $this->_query2assoc($query);
$ctype = kolab_format::KTYPE_PREFIX . $filter['type'];
- $index = $this->imap->search_once($this->folder->name, 'UNDELETED HEADER X-Kolab-Type ' . $ctype);
+ $index = $this->imap->search_once($this->folder->name, 'UNDELETED HEADER X-Kolab-Type ' . $ctype);
+
+ if ($index->is_error()) {
+ return null;
+ }
+
$count = $index->count();
}
More information about the commits
mailing list