Branch 'dev/kolab3' - 3 commits - plugins/calendar plugins/kolab_config plugins/libkolab

Thomas Brüderli bruederli at kolabsys.com
Wed May 9 19:03:02 CEST 2012


 plugins/calendar/drivers/kolab/kolab_calendar.php |   45 ++++++-------
 plugins/kolab_config/kolab_config.php             |   11 ---
 plugins/libkolab/SQL/mysql.sql                    |    2 
 plugins/libkolab/lib/kolab_storage_cache.php      |   72 +++++++++++++++++++++-
 plugins/libkolab/lib/kolab_storage_folder.php     |   35 ++++++++++
 plugins/libkolab/libkolab.php                     |    2 
 6 files changed, 128 insertions(+), 39 deletions(-)

New commits:
commit b37784bb3ba3b3e89b54b542242d568c4d5af20a
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Wed May 9 19:02:46 2012 +0200

    Query objects directly from the storage layer; no need to fetch all for every operation

diff --git a/plugins/calendar/drivers/kolab/kolab_calendar.php b/plugins/calendar/drivers/kolab/kolab_calendar.php
index 7763159..53a8d83 100644
--- a/plugins/calendar/drivers/kolab/kolab_calendar.php
+++ b/plugins/calendar/drivers/kolab/kolab_calendar.php
@@ -38,8 +38,7 @@ class kolab_calendar
   public $storage;
 
   private $cal;
-  private $events;
-  private $id2uid;
+  private $events = array();
   private $imap_folder = 'INBOX/Calendar';
   private $search_fields = array('title', 'description', 'location', '_attendees');
   private $sensitivity_map = array('public', 'private', 'confidential');
@@ -175,17 +174,21 @@ class kolab_calendar
    */
   public function get_event($id)
   {
-    $this->_fetch_events();
-    
+    // directly access storage object
+    if (!$this->events[$id] && ($record = $this->storage->get_object($id)))
+        $this->events[$id] = $this->_to_rcube_event($record);
+
     // event not found, maybe a recurring instance is requested
     if (!$this->events[$id]) {
       $master_id = preg_replace('/-\d+$/', '', $id);
-      if ($this->events[$master_id] && $this->events[$master_id]['recurrence']) {
-        $master = $this->events[$master_id];
+      if ($record = $this->storage->get_object($master_id))
+        $this->events[$master_id] = $this->_to_rcube_event($record);
+
+      if (($master = $this->events[$master_id]) && $master['recurrence']) {
         $this->_get_recurring_events($master, $master['start'], $master['start'] + 86400 * 365 * 10, $id);
       }
     }
-    
+
     return $this->events[$id];
   }
 
@@ -199,8 +202,16 @@ class kolab_calendar
    */
   public function list_events($start, $end, $search = null, $virtual = 1)
   {
-    $this->_fetch_events();
-    
+    // query Kolab storage
+    $query = array(
+      array('dtstart', '<=', $end),
+      array('dtend',   '>=', $start),
+    );
+    foreach ((array)$this->storage->select($query) as $record) {
+      $event = $this->_to_rcube_event($record);
+      $this->events[$event['id']] = $event;
+    }
+
     if (!empty($search))
       $search =  mb_strtolower($search);
     
@@ -345,22 +356,6 @@ class kolab_calendar
     return false;
   }
 
-  /**
-   * Simply fetch all records and store them in private member vars
-   * We thereby rely on cahcing done by the Horde classes
-   */
-  private function _fetch_events()
-  {
-    if (!isset($this->events)) {
-      $this->events = array();
-
-      foreach ((array)$this->storage->get_objects() as $record) {
-        $event = $this->_to_rcube_event($record);
-        $this->events[$event['id']] = $event;
-      }
-    }
-  }
-
 
   /**
    * Create instances of a recurring event


commit 86c1d510f1c192880920085fd7b77d65f3f848ad
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Wed May 9 19:01:51 2012 +0200

    Add select() method to query objects from cache; Use locks to avoid multiple threads synching the same folder simultaneously

diff --git a/plugins/libkolab/SQL/mysql.sql b/plugins/libkolab/SQL/mysql.sql
index 376eb4f..5f49e92 100644
--- a/plugins/libkolab/SQL/mysql.sql
+++ b/plugins/libkolab/SQL/mysql.sql
@@ -6,7 +6,7 @@
  * @licence GNU AGPL
  **/
 
-CREATE TABLE `kolab_cache` (
+CREATE TABLE IF NOT EXISTS `kolab_cache` (
   `resource` VARCHAR(255) CHARACTER SET ascii NOT NULL,
   `type` VARCHAR(32) CHARACTER SET ascii NOT NULL,
   `msguid` BIGINT UNSIGNED NOT NULL,
diff --git a/plugins/libkolab/lib/kolab_storage_cache.php b/plugins/libkolab/lib/kolab_storage_cache.php
index 9f80691..65aa4cb 100644
--- a/plugins/libkolab/lib/kolab_storage_cache.php
+++ b/plugins/libkolab/lib/kolab_storage_cache.php
@@ -81,6 +81,9 @@ class kolab_storage_cache
         if ($this->synched)
             return;
 
+        // lock synchronization for this folder or wait if locked
+        $this->_sync_lock();
+
         // synchronize IMAP mailbox cache
         $this->imap->folder_sync($this->folder->name);
 
@@ -92,8 +95,9 @@ class kolab_storage_cache
         if ($this->ready) {
             // read cache index
             $sql_result = $this->db->query(
-                "SELECT msguid, uid FROM kolab_cache WHERE resource=?",
-                $this->resource_uri
+                "SELECT msguid, uid FROM kolab_cache WHERE resource=? AND type<>?",
+                $this->resource_uri,
+                'lock'
             );
 
             $old_index = array();
@@ -120,6 +124,9 @@ class kolab_storage_cache
             }
         }
 
+        // remove lock
+        $this->_sync_unlock();
+
         $this->synched = time();
     }
 
@@ -349,6 +356,7 @@ class kolab_storage_cache
                 $this->db->quote($param[2])
             );
         }
+
         return $sql_where;
     }
 
@@ -400,6 +408,11 @@ class kolab_storage_cache
             // database runs in server's timezone so using date() is what we want
             $sql_data['dtstart'] = date('Y-m-d H:i:s', is_object($object['start']) ? $object['start']->format('U') : $object['start']);
             $sql_data['dtend']   = date('Y-m-d H:i:s', is_object($object['end'])   ? $object['end']->format('U')   : $object['end']);
+
+            // extend date range for recurring events
+            if ($object['recurrence']) {
+                $sql_data['dtend'] = date('Y-m-d H:i:s', $object['recurrence']['UNTIL'] ?: strtotime('now + 2 years'));
+            }
         }
 
         if ($object['_formatobj'])
@@ -454,6 +467,61 @@ class kolab_storage_cache
     }
 
     /**
+     * Check lock record for this folder and wait if locked or set lock
+     */
+    private function _sync_lock()
+    {
+        if (!$this->ready)
+            return;
+
+        $sql_arr = $this->db->fetch_assoc($this->db->query(
+            "SELECT msguid AS locked FROM kolab_cache ".
+            "WHERE resource=? AND type=?",
+            $this->resource_uri,
+            'lock'
+        ));
+
+        // create lock record if not exists
+        if (!$sql_arr) {
+            $this->db->query(
+                "INSERT INTO kolab_cache (resource, type, msguid, uid, data, xml)".
+                " VALUES (?, ?, ?, '', '', '')",
+                $this->resource_uri,
+                'lock',
+                time()
+            );
+        }
+        // wait if locked (expire locks after 10 minutes)
+        else if (intval($sql_arr['locked']) > 0 && (time() - $sql_arr['locked']) < 600) {
+            usleep(500000);
+            return $this->_sync_lock();
+        }
+        // set lock
+        else {
+            $this->db->query(
+                "UPDATE kolab_cache SET msguid=? ".
+                "WHERE resource=? AND type=?",
+                time(),
+                $this->resource_uri,
+                'lock'
+            );
+        }
+    }
+
+    /**
+     * Remove lock for this folder
+     */
+    private function _sync_unlock()
+    {
+        $this->db->query(
+            "UPDATE kolab_cache SET msguid=0 ".
+            "WHERE resource=? AND type=?",
+            $this->resource_uri,
+            'lock'
+        );
+    }
+
+    /**
      * Resolve an object UID into an IMAP message UID
      *
      * @param string  Kolab object UID
diff --git a/plugins/libkolab/lib/kolab_storage_folder.php b/plugins/libkolab/lib/kolab_storage_folder.php
index c55a34f..eed7b08 100644
--- a/plugins/libkolab/lib/kolab_storage_folder.php
+++ b/plugins/libkolab/lib/kolab_storage_folder.php
@@ -318,6 +318,41 @@ class kolab_storage_folder
 
 
     /**
+     * Select *some* Kolab objects matching the given query
+     *
+     * @param array Pseudo-SQL query as list of filter parameter triplets
+     *   triplet: array('<colname>', '<comparator>', '<value>')
+     * @return array List of Kolab data objects (each represented as hash array)
+     */
+    public function select($query = array())
+    {
+        // check query argument
+        if (empty($query))
+            return $this->get_objects();
+
+        $type = null;
+        foreach ($query as $i => $param) {
+            if ($param[0] == 'type') {
+                $type = $param[2];
+            }
+            else if (($param[0] == 'dtstart' || $param[0] == 'dtend') && is_numeric($param[2])) {
+              $query[$i][2] = date('Y-m-d H:i:s', $param[2]);
+            }
+        }
+
+        // add type selector if not in $query
+        if (!$type)
+            $query[] = array('type','=',$this->type);
+
+        // synchronize caches
+        $this->cache->synchronize();
+
+        // fetch objects from cache
+        return $this->cache->select($query);
+    }
+
+
+    /**
      * Getter for a single Kolab object, identified by its UID
      *
      * @param string Object UID
diff --git a/plugins/libkolab/libkolab.php b/plugins/libkolab/libkolab.php
index 3d0709b..fd911be 100644
--- a/plugins/libkolab/libkolab.php
+++ b/plugins/libkolab/libkolab.php
@@ -63,9 +63,7 @@ class libkolab extends rcube_plugin
      */
     function storage_init($p)
     {
-        $rcmail = rcmail::get_instance();
         $p['fetch_headers'] = trim($p['fetch_headers'] .' X-KOLAB-TYPE');
-
         return $p;
     }
 


commit ed467e73f910f56e50759ad35f9a6bacf030bbe0
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Wed May 9 17:20:39 2012 +0200

    Disable kolab_config plugin for now

diff --git a/plugins/kolab_config/kolab_config.php b/plugins/kolab_config/kolab_config.php
index 24d569e..b785306 100644
--- a/plugins/kolab_config/kolab_config.php
+++ b/plugins/kolab_config/kolab_config.php
@@ -61,16 +61,9 @@ class kolab_config extends rcube_plugin
         if ($this->config)
             return;
 
-        $this->require_plugin('kolab_folders');
+        return;  // CURRENTLY DISABLED until libkolabxml has support for config objects
 
-        // load dependencies
-        require_once 'Horde/Util.php';
-        require_once 'Horde/Kolab/Format.php';
-        require_once 'Horde/Kolab/Format/XML.php';
-        require_once $this->home . '/lib/configuration.php';
-        require_once $this->home . '/lib/kolab_configuration.php';
-
-        String::setDefaultCharset('UTF-8');
+        $this->require_plugin('libkolab');
 
         $this->config = new kolab_configuration();
 





More information about the commits mailing list