summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Machniak <machniak@kolabsys.com>2014-08-25 16:10:34 (GMT)
committerAleksander Machniak <machniak@kolabsys.com>2014-08-25 16:10:34 (GMT)
commitbde4a2325ca38726a47e7c9069505df8e1a15e95 (patch)
treef1f24cf63011e8a91306bfb46fc41bef472b16c9
parent813c7becb7f561e5af6c5ed2641703bf66235059 (diff)
downloadkolab-syncroton-bde4a2325ca38726a47e7c9069505df8e1a15e95.tar.gz
Fix various issues in email flags change detection and synchronization
-rw-r--r--lib/kolab_sync_backend.php63
-rw-r--r--lib/kolab_sync_data_email.php27
2 files changed, 53 insertions, 37 deletions
diff --git a/lib/kolab_sync_backend.php b/lib/kolab_sync_backend.php
index 363351e..b1ccc4e 100644
--- a/lib/kolab_sync_backend.php
+++ b/lib/kolab_sync_backend.php
@@ -818,55 +818,62 @@ class kolab_sync_backend
*/
public function modseq_set($deviceid, $folderid, $synctime, $data)
{
- $synctime = $synctime->format('Y-m-d h:i:s');
+ $synctime = $synctime->format('Y-m-d H:i:s');
$rcube = rcube::get_instance();
$db = $rcube->get_dbh();
+ $old_data = $this->modseq[$folderid][$synctime];
- $this->modseq[$deviceid][$folderid][$synctime] = $data;
-
- $data = json_encode($data);
-
- $db->query("UPDATE syncroton_modseq"
- ." SET data = ?"
- ." WHERE device_id = ? AND folder_id = ? AND synctime = ?",
- $data, $deviceid, $folderid, $synctime);
+ if (empty($old_data)) {
+ $this->modseq[$folderid][$synctime] = $data;
+ $data = json_encode($data);
- if (!$db->affected_rows()) {
+ $db->set_option('ignore_key_errors', true);
$db->query("INSERT INTO syncroton_modseq (device_id, folder_id, synctime, data)"
." VALUES (?, ?, ?, ?)",
$deviceid, $folderid, $synctime, $data);
+ $db->set_option('ignore_key_errors', false);
}
}
public function modseq_get($deviceid, $folderid, $synctime)
{
- $synctime = $synctime->format('Y-m-d h:i:s');
+ $synctime = $synctime->format('Y-m-d H:i:s');
- if (!isset($this->modseq[$deviceid]) || !isset($this->modseq[$deviceid][$folderid])
- || !isset($this->modseq[$deviceid][$folderid][$synctime])
- ) {
+ if (empty($this->modseq[$folderid][$synctime])) {
$rcube = rcube::get_instance();
$db = $rcube->get_dbh();
- $db->limitquery("SELECT data, synctime FROM syncroton_modseq"
- ." WHERE device_id = ? AND folder_id = ? AND synctime <= ?"
- ." ORDER BY synctime DESC",
- 0, 2, $deviceid, $folderid, $synctime);
+ $db->query("SELECT data, synctime FROM syncroton_modseq"
+ ." WHERE device_id = ? AND folder_id = ? AND synctime = ?",
+ $deviceid, $folderid, $synctime);
- if ($row = $db->fetch_assoc()) {
- // @TODO: make sure synctime from sql is in "Y-m-d h:i:s" format
- $this->modseq[$deviceid][$folderid][$row['synctime']] = json_decode($row['data']);
+ $row = $db->fetch_assoc();
- // Cleanup: remove old records (keep last two)
- if ($row = $db->fetch_assoc()) {
- $db->query("DELETE FROM syncroton_modseq"
- ." WHERE device_id = ? AND folder_id = ? AND synctime < ?",
- $deviceid, $folderid, $row['synctime']);
- }
+ // record doesn't exist, get previous one
+ if (!$row) {
+ $db->limitquery("SELECT data, synctime FROM syncroton_modseq"
+ ." WHERE device_id = ? AND folder_id = ? AND synctime < ?"
+ ." ORDER BY synctime DESC",
+ 0, 1, $deviceid, $folderid, $synctime);
+
+ $row = $db->fetch_assoc();
}
+
+ $this->modseq[$folderid] = array();
+
+ if ($row) {
+ $synctime = $row['synctime'];
+ // @TODO: make sure synctime from sql is in "Y-m-d H:i:s" format
+ $this->modseq[$folderid][$synctime] = json_decode($row['data']);
+ }
+
+ // Cleanup: remove all records except the current one
+ $db->query("DELETE FROM syncroton_modseq"
+ ." WHERE device_id = ? AND folder_id = ? AND synctime <> ?",
+ $deviceid, $folderid, $synctime);
}
- return @$this->modseq[$deviceid][$folderid][$synctime];
+ return @$this->modseq[$folderid][$synctime];
}
/**
diff --git a/lib/kolab_sync_data_email.php b/lib/kolab_sync_data_email.php
index 4fb436a..5b2268e 100644
--- a/lib/kolab_sync_data_email.php
+++ b/lib/kolab_sync_data_email.php
@@ -779,11 +779,12 @@ class kolab_sync_data_email extends kolab_sync_data implements Syncroton_Data_ID
// convert filter into one IMAP search string
foreach ($filter as $idx => $filter_item) {
if (is_array($filter_item)) {
- // This is a request for changes since list time
+ // This is a request for changes since last time
// we'll use HIGHESTMODSEQ value from the last Sync
if ($filter_item[0] == 'changed' && $filter_item[1] == '>') {
- $modseq = (array) $this->backend->modseq_get($this->device->id, $folderid, $filter_item[2]);
- $modseq_data = array();
+ $modseq_lasttime = $filter_item[2];
+ $modseq_data = array();
+ $modseq = (array) $this->backend->modseq_get($this->device->id, $folderid, $modseq_lasttime);
}
}
else {
@@ -795,6 +796,7 @@ class kolab_sync_data_email extends kolab_sync_data implements Syncroton_Data_ID
// no sorting for best performance
$sort_by = null;
$found = 0;
+ $ts = time();
foreach ($folders as $folder_id) {
$foldername = $this->backend->folder_id2name($folder_id, $this->device->deviceid);
@@ -807,16 +809,13 @@ class kolab_sync_data_email extends kolab_sync_data implements Syncroton_Data_ID
$this->storage->set_folder($foldername);
- // Syncronize folder (if it wasn't synced in this request already)
- if ($this->lastsync_folder != $foldername
- || $this->lastsync_time < time() - Syncroton_Registry::getPingTimeout()
+ // Synchronize folder (if it wasn't synced in this request already)
+ if ($this->lastsync_folder != $folderid
+ || $this->lastsync_time <= $ts - Syncroton_Registry::getPingTimeout()
) {
$this->storage->folder_sync($foldername);
}
- $this->lastsync_folder = $foldername;
- $this->lastsync_time = time();
-
// We're in "get changes" mode
if (isset($modseq_data)) {
$folder_data = $this->storage->folder_data($foldername);
@@ -879,9 +878,19 @@ class kolab_sync_data_email extends kolab_sync_data implements Syncroton_Data_ID
throw new Syncroton_Exception_Status(Syncroton_Exception_Status::SERVER_ERROR);
}
+ $this->lastsync_folder = $folderid;
+ $this->lastsync_time = $ts;
+
if (!empty($modseq_update)) {
$this->backend->modseq_set($this->device->id, $folderid,
$this->syncTimeStamp, $modseq_data);
+
+ // if previous modseq information does not exist save current set as it,
+ // we would at least be able to detect changes since now
+ if (empty($result) && empty($modseq)) {
+ $this->backend->modseq_set($this->device->id, $folderid,
+ $modseq_lasttime, $modseq_data);
+ }
}
return $result;