Branch 'kolab-syncroton-2.2' - lib/kolab_sync_backend.php lib/kolab_sync_data_email.php

Aleksander Machniak machniak at kolabsys.com
Mon Aug 25 20:38:34 CEST 2014


 lib/kolab_sync_backend.php    |   62 +++++++++++++++++++++++-------------------
 lib/kolab_sync_data_email.php |   27 ++++++++++++------
 2 files changed, 52 insertions(+), 37 deletions(-)

New commits:
commit 6b1cd214f0dfcde68d0504878917e7cf5217b563
Author: Aleksander Machniak <machniak at kolabsys.com>
Date:   Mon Aug 25 12:15:38 2014 -0400

    Fix various issues in email flags change detection and synchronization
    
    Conflicts:
    
    	lib/kolab_sync_backend.php

diff --git a/lib/kolab_sync_backend.php b/lib/kolab_sync_backend.php
index 1f6fd26..d954191 100644
--- a/lib/kolab_sync_backend.php
+++ b/lib/kolab_sync_backend.php
@@ -816,55 +816,61 @@ class kolab_sync_backend
      */
     public function modseq_set($deviceid, $folderid, $synctime, $data)
     {
-        $synctime = $synctime->format('Ymdhis');
+        $synctime = $synctime->format('YmdHis');
         $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('Ymdhis');
+        $synctime = $synctime->format('YmdHis');
 
-        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()) {
-                $current = $row['synctime'];
-                $this->modseq[$deviceid][$folderid][$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'];
+                $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 b032f7d..c305e2b 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);
@@ -886,9 +885,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;




More information about the commits mailing list