plugins/kolab_notes plugins/libkolab

Aleksander Machniak machniak at kolabsys.com
Thu Aug 21 17:09:26 CEST 2014


 plugins/kolab_notes/kolab_notes.php                        |   89 +------------
 plugins/libkolab/lib/kolab_format_configuration.php        |   25 +++
 plugins/libkolab/lib/kolab_storage_cache_configuration.php |    6 
 plugins/libkolab/lib/kolab_storage_config.php              |   79 +++++++++++
 4 files changed, 123 insertions(+), 76 deletions(-)

New commits:
commit 07308521792a182e9cd4de10d067b96c190d21a5
Author: Aleksander Machniak <machniak at kolabsys.com>
Date:   Tue Aug 19 08:20:47 2014 -0400

    Cache relation members for better performance (#3452)

diff --git a/plugins/kolab_notes/kolab_notes.php b/plugins/kolab_notes/kolab_notes.php
index 7553fd1..a5723a1 100644
--- a/plugins/kolab_notes/kolab_notes.php
+++ b/plugins/kolab_notes/kolab_notes.php
@@ -391,7 +391,7 @@ class kolab_notes extends rcube_plugin
                 $this->rc->output->set_env('kolab_notes_template', array(
                     '_from_mail' => true,
                     'title' => $message->get('subject'),
-                    'links' => array($this->get_message_reference($this->get_message_uri($message, $folder))),
+                    'links' => array($this->get_message_reference(kolab_storage_config::get_message_uri($message, $folder))),
                 ));
             }
         }
@@ -996,7 +996,6 @@ class kolab_notes extends rcube_plugin
         foreach ($relations as $relation) {
             if (empty($links)) {
                 $config->delete($relation['uid']);
-                $this->relations = null; // clear in-memory cache
             }
             else {
                 // make relation members up-to-date
@@ -1010,7 +1009,6 @@ class kolab_notes extends rcube_plugin
                 if (count($diff1) || count($diff2)) {
                     $relation['members'] = $members;
                     $config->save($relation, 'relation');
-                    $this->relations = null; // clear in-memory cache
                 }
 
                 $links = null;
@@ -1025,7 +1023,6 @@ class kolab_notes extends rcube_plugin
             );
 
             $config->save($relation, 'relation');
-            $this->relations = null; // clear in-memory cache
         }
     }
 
@@ -1070,33 +1067,11 @@ class kolab_notes extends rcube_plugin
      */
     private function get_message_notes($message, $folder)
     {
-        $result = array();
-        $uids   = array();
-
-        // TODO: only query for notes if message was flagged with $KolabNotes ?
-
-        // get UIDs of assigned notes
-        foreach ($this->get_relations() as $relation) {
-            // get Folder/UIDs of relation members
-            $messages = kolab_storage_config::resolve_members($relation);
-
-            if (!empty($messages[$folder]) && in_array($message->uid, $messages[$folder])) {
-                // find note UID(s)
-                foreach ($relation['members'] as $member) {
-                    if (strpos($member, 'urn:uuid:') === 0) {
-                        $uids[] = substr($member, 9);
-                    }
-                }
-            }
-        }
+        $config = kolab_storage_config::get_instance();
+        $result = $config->get_message_relations($message, $folder, 'note');
 
-        // get Note objects
-        if (!empty($uids)) {
-            $query = array(array('uid', '=', $uids));
-            foreach (kolab_storage::select($query, 'note') as $record) {
-                $record['list'] = kolab_storage::folder_id($record['_mailbox']);
-                $result[] = $record;
-            }
+        foreach ($result as $idx => $note) {
+            $result[$idx]['list'] = kolab_storage::folder_id($note['_mailbox']);
         }
 
         return $result;
@@ -1105,55 +1080,17 @@ class kolab_notes extends rcube_plugin
     /**
      * Find relation objects referring to specified note
      */
-    private function get_relations($uid = null)
-    {
-        if (!isset($this->relations)) {
-            $config      = kolab_storage_config::get_instance();
-            $default     = true;
-            $filter      = array(
-                array('type', '=', 'relation'),
-                array('category', '=', 'generic')
-            );
-
-            $this->relations = $config->get_objects($filter, $default);
-        }
-
-        if ($uid === null) {
-            return $this->relations;
-        }
-
-        $result = array();
-        $search = kolab_storage_config::build_member_url($uid);
-
-        foreach ($this->relations as $relation) {
-            if (in_array($search, (array) $relation['members'])) {
-                $result[] = $relation;
-            }
-        }
-
-        return $result;
-    }
-
-    /**
-     * Build a URI representing the given message reference
-     */
-    private function get_message_uri($headers, $folder)
+    private function get_relations($uid)
     {
-        $params = array(
-            'folder' => $headers->folder ?: $folder,
-            'uid'    => $headers->uid,
+        $config      = kolab_storage_config::get_instance();
+        $default     = true;
+        $filter      = array(
+            array('type', '=', 'relation'),
+            array('category', '=', 'generic'),
+            array('member', '=', $uid),
         );
 
-        if (($messageid = $headers->get('message-id', false)) && ($date = $headers->get('date', false))) {
-            $params['message-id'] = $messageid;
-            $params['date']       = $date;
-
-            if ($subject = $headers->get('subject')) {
-                $params['subject'] = $subject;
-            }
-        }
-
-        return kolab_storage_config::build_member_url($params);
+        return $config->get_objects($filter, $default, 100);
     }
 
     /**
diff --git a/plugins/libkolab/lib/kolab_format_configuration.php b/plugins/libkolab/lib/kolab_format_configuration.php
index 6b71f3e..17b46a7 100644
--- a/plugins/libkolab/lib/kolab_format_configuration.php
+++ b/plugins/libkolab/lib/kolab_format_configuration.php
@@ -220,4 +220,29 @@ class kolab_format_configuration extends kolab_format
 
         return $tags;
     }
+
+    /**
+     * Callback for kolab_storage_cache to get words to index for fulltext search
+     *
+     * @return array List of words to save in cache
+     */
+    public function get_words()
+    {
+        $words = array();
+
+        foreach ((array)$this->data['members'] as $url) {
+            $member = kolab_storage_config::parse_member_url($url);
+
+            if (empty($member)) {
+                if (strpos($url, 'urn:uuid:') === 0) {
+                    $words[] = substr($url, 9);
+                }
+            }
+            else if (!empty($member['params']['message-id'])) {
+                $words[] = $member['params']['message-id'];
+            }
+        }
+
+        return $words;
+    }
 }
diff --git a/plugins/libkolab/lib/kolab_storage_cache_configuration.php b/plugins/libkolab/lib/kolab_storage_cache_configuration.php
index 97315da..ec015dd 100644
--- a/plugins/libkolab/lib/kolab_storage_cache_configuration.php
+++ b/plugins/libkolab/lib/kolab_storage_cache_configuration.php
@@ -52,6 +52,12 @@ class kolab_storage_cache_configuration extends kolab_storage_cache
                     $query[$idx][0] = 'tags';
                     $query[$idx][2] = count($param[2]) > 1 ? $param[2] : $param[2][0];
                 }
+                // convert member filter (we support only = operator with single value)
+                else if ($param[0] == 'member') {
+                    $query[$idx][0] = 'words';
+                    $query[$idx][1] = '~';
+                    $query[$idx][2] = '^' . $param[2] . '$';
+                }
             }
         }
 
diff --git a/plugins/libkolab/lib/kolab_storage_config.php b/plugins/libkolab/lib/kolab_storage_config.php
index beaa928..9bc5d50 100644
--- a/plugins/libkolab/lib/kolab_storage_config.php
+++ b/plugins/libkolab/lib/kolab_storage_config.php
@@ -623,6 +623,12 @@ class kolab_storage_config
                 array('category', '=', 'tag')
             );
 
+            // use faster method
+            if ($uid && $uid != '*') {
+                $filter[] = array('member', '=', $uid);
+                return $this->get_objects($filter, $default);
+            }
+
             $this->tags = $this->get_objects($filter, $default);
         }
 
@@ -641,4 +647,77 @@ class kolab_storage_config
 
         return $result;
     }
+
+    /**
+     * Find kolab objects assigned to specified e-mail message
+     *
+     * @param rcube_message $message E-mail message
+     * @param string        $folder  Folder name
+     * @param string        $type    Result objects type
+     *
+     * @return array List of kolab objects
+     */
+    public function get_message_relations($message, $folder, $type)
+    {
+        $result  = array();
+        $uids    = array();
+        $default = true;
+        $uri     = self::get_message_uri($message, $folder);
+        $filter  = array(
+            array('type', '=', 'relation'),
+            array('category', '=', 'generic'),
+            // @TODO: what if Message-Id (and Date) does not exist?
+            array('member', '=', $message->get('message-id', false)),
+        );
+
+        // get UIDs of assigned notes
+        foreach ($this->get_objects($filter, $default) as $relation) {
+            // we don't need to update members if the URI is found
+            if (in_array($uri, $relation['members'])) {
+                // update members...
+                $messages = kolab_storage_config::resolve_members($relation);
+                // ...and check again
+                if (empty($messages[$folder]) || !in_array($message->uid, $messages[$folder])) {
+                    continue;
+                }
+            }
+
+            // find note UID(s)
+            foreach ($relation['members'] as $member) {
+                if (strpos($member, 'urn:uuid:') === 0) {
+                    $uids[] = substr($member, 9);
+                }
+            }
+        }
+
+        // get kolab objects of specified type
+        if (!empty($uids)) {
+            $query  = array(array('uid', '=', array_unique($uids)));
+            $result = kolab_storage::select($query, $type);
+        }
+
+        return $result;
+    }
+
+    /**
+     * Build a URI representing the given message reference
+     */
+    public static function get_message_uri($headers, $folder)
+    {
+        $params = array(
+            'folder' => $headers->folder ?: $folder,
+            'uid'    => $headers->uid,
+        );
+
+        if (($messageid = $headers->get('message-id', false)) && ($date = $headers->get('date', false))) {
+            $params['message-id'] = $messageid;
+            $params['date']       = $date;
+
+            if ($subject = $headers->get('subject')) {
+                $params['subject'] = $subject;
+            }
+        }
+
+        return self::build_member_url($params);
+    }
 }




More information about the commits mailing list