Support caching the folder list.
authorGunnar Wrobel <p@rdus.de>
Mon, 3 Jan 2011 09:41:19 +0000 (10:41 +0100)
committerGunnar Wrobel <p@rdus.de>
Tue, 4 Jan 2011 07:54:22 +0000 (08:54 +0100)
framework/Kolab_Storage/lib/Horde/Kolab/Storage/Factory.php
framework/Kolab_Storage/lib/Horde/Kolab/Storage/List.php
framework/Kolab_Storage/lib/Horde/Kolab/Storage/List/Base.php
framework/Kolab_Storage/lib/Horde/Kolab/Storage/List/Decorator/Cache.php
framework/Kolab_Storage/lib/Horde/Kolab/Storage/List/Decorator/Log.php
framework/Kolab_Storage/test/Horde/Kolab/Storage/TestCase.php
framework/Kolab_Storage/test/Horde/Kolab/Storage/Unit/Folder/TypeTest.php
framework/Kolab_Storage/test/Horde/Kolab/Storage/Unit/List/Decorator/CacheTest.php [new file with mode: 0644]

index a56a3c6..596c00e 100644 (file)
@@ -103,6 +103,9 @@ class Horde_Kolab_Storage_Factory
         } else {
             $config = array();
         }
+        $config = array_merge(
+            array('host' => 'localhost', 'port' => 143), $config
+        );
         if (!empty($params['timelog'])) {
             $timer = new Horde_Support_Timer();
             $timer->push();
@@ -137,7 +140,7 @@ class Horde_Kolab_Storage_Factory
             $driver = new Horde_Kolab_Storage_Driver_Cclient($this, $config);
             break;
         case 'pear':
-            $client = new Net_IMAP($config['host']);
+            $client = new Net_IMAP($config['host'], $config['port']);
             Horde_Kolab_Storage_Exception_Pear::catchError(
                 $client->login($config['username'], $config['password'])
             );
@@ -153,7 +156,7 @@ class Horde_Kolab_Storage_Factory
                 array(
                     'debug_mode' => false,
                     'ssl_mode' => false,
-                    'port' => 143,
+                    'port' => $config['port'],
                     'timeout' => 0,
                     'force_caps' => false,
                 )
index a670999..d144a02 100644 (file)
@@ -29,6 +29,13 @@ interface Horde_Kolab_Storage_List
 extends Horde_Kolab_Storage_Queriable
 {
     /**
+     * Return the ID of the underlying connection.
+     *
+     * @return string The connection ID.
+     */
+    public function getConnectionId();
+
+    /**
      * Returns the list of folders visible to the current user.
      *
      * @return array The list of folders, represented as strings.
index 7be624b..12e1cfe 100644 (file)
@@ -57,6 +57,16 @@ implements Horde_Kolab_Storage_List
     }
 
     /**
+     * Return the ID of the underlying connection.
+     *
+     * @return string The connection ID.
+     */
+    public function getConnectionId()
+    {
+        return $this->_driver->getId();
+    }
+
+    /**
      * Returns the list of folders visible to the current user.
      *
      * @return array The list of folders, represented as a list of strings.
index 0c709f3..756cd81 100644 (file)
@@ -58,14 +58,56 @@ implements Horde_Kolab_Storage_List
     }
 
     /**
+     * Return the ID of the underlying connection.
+     *
+     * @return string The connection ID.
+     */
+    public function getConnectionId()
+    {
+        return $this->_list->getConnectionId();
+    }
+
+    /**
+     * Check if the cache has been initialized at all and synchronize it if not.
+     *
+     * @return NULL
+     */
+    private function _init()
+    {
+    }
+
+    /**
      * Returns the list of folders visible to the current user.
      *
      * @return array The list of folders, represented as a list of strings.
      */
     public function listFolders()
     {
-        $result = $this->_list->listFolders();
-        return $result;
+        $this->_init();
+        $a = $this->_cache->loadListData(
+            $this->_list->getConnectionId(),
+            'FOLDERS'
+        );
+        if (empty($a)) {
+            $a = $this->_cacheFolders();
+        }
+        return $a;
+    }
+
+    /**
+     * Caches and returns the list of folders visible to the current user.
+     *
+     * @return array The list of folders, represented as a list of strings.
+     */
+    private function _cacheFolders()
+    {
+        $list = $this->_list->listFolders();
+        $this->_cache->storeListData(
+            $this->_list->getConnectionId(),
+            'FOLDERS',
+            $list
+        );
+        return $list;
     }
 
     /**
@@ -93,6 +135,16 @@ implements Horde_Kolab_Storage_List
     }
 
     /**
+     * Synchronize the list information with the information from the backend.
+     *
+     * @return NULL
+     */
+    public function synchronize()
+    {
+        $this->_cacheFolders();
+    }
+
+    /**
      * Return the specified query type.
      *
      * @param string $name The query name.
index fb67d0f..4bf62b7 100644 (file)
@@ -58,6 +58,16 @@ implements Horde_Kolab_Storage_List
     }
 
     /**
+     * Return the ID of the underlying connection.
+     *
+     * @return string The connection ID.
+     */
+    public function getConnectionId()
+    {
+        return $this->_list->getConnectionId();
+    }
+
+    /**
      * Returns the list of folders visible to the current user.
      *
      * @return array The list of folders, represented as a list of strings.
index d70c056..5f6142a 100644 (file)
@@ -188,12 +188,26 @@ extends PHPUnit_Framework_TestCase
         );
     }
 
+    protected function getMockDriverList()
+    {
+        $this->mockDriver = $this->getMock('Horde_Kolab_Storage_Driver');
+        return new Horde_Kolab_Storage_List_Base(
+            $this->mockDriver,
+            new Horde_Kolab_Storage_Factory()
+        );
+    }
+
     protected function getMockLogger()
     {
         $this->logHandler = new Horde_Log_Handler_Mock();
         return new Horde_Log_Logger($this->logHandler);
     }
 
+    protected function getMockCache()
+    {
+        return new Horde_Kolab_Storage_Cache(new Horde_Cache_Storage_Mock());
+    }
+
     protected function assertLogCount($count)
     {
         $this->assertEquals(count($this->logHandler->events), $count);
index ff1722c..12cba48 100644 (file)
@@ -69,5 +69,4 @@ extends Horde_Kolab_Storage_TestCase
         $type = new Horde_Kolab_Storage_Folder_Type('contact');
         $this->assertFalse($type->isDefault());
     }
-
 }
diff --git a/framework/Kolab_Storage/test/Horde/Kolab/Storage/Unit/List/Decorator/CacheTest.php b/framework/Kolab_Storage/test/Horde/Kolab/Storage/Unit/List/Decorator/CacheTest.php
new file mode 100644 (file)
index 0000000..4aa60a2
--- /dev/null
@@ -0,0 +1,162 @@
+<?php
+/**
+ * Test the folder list cache decorator.
+ *
+ * PHP version 5
+ *
+ * @category   Kolab
+ * @package    Kolab_Storage
+ * @subpackage UnitTests
+ * @author     Gunnar Wrobel <wrobel@pardus.de>
+ * @license    http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link       http://pear.horde.org/index.php?package=Kolab_Storage
+ */
+
+/**
+ * Prepare the test setup.
+ */
+require_once dirname(__FILE__) . '/../../../Autoload.php';
+
+/**
+ * Test the folder list cache decorator.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @category   Kolab
+ * @package    Kolab_Storage
+ * @subpackage UnitTests
+ * @author     Gunnar Wrobel <wrobel@pardus.de>
+ * @license    http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link       http://pear.horde.org/index.php?package=Kolab_Storage
+ */
+class Horde_Kolab_Storage_Unit_List_Decorator_CacheTest
+extends Horde_Kolab_Storage_TestCase
+{
+    public function testListFolderIsArray()
+    {
+        $list = new Horde_Kolab_Storage_List_Decorator_Cache(
+            $this->getNullList(),
+            $this->getMockCache()
+        );
+        $this->assertType('array', $list->listFolders());
+    }
+
+    public function testListFolder()
+    {
+        $list = new Horde_Kolab_Storage_List_Decorator_Cache(
+            $this->getTwoFolderList(),
+            $this->getMockCache()
+        );
+        $this->assertEquals(
+            array('INBOX', 'INBOX/a'),
+            $list->listFolders()
+        );
+    }
+
+    public function testLongerList()
+    {
+        $list = new Horde_Kolab_Storage_List_Decorator_Cache(
+            $this->getAnnotatedList(),
+            $this->getMockCache()
+        );
+        $this->assertEquals(
+            array('INBOX', 'INBOX/a', 'INBOX/Calendar', 'INBOX/Contacts', 'INBOX/Notes', 'INBOX/Tasks'),
+            $list->listFolders()
+        );
+    }
+
+    public function testMockedList()
+    {
+        $list = new Horde_Kolab_Storage_List_Decorator_Cache(
+            $this->getMockDriverList(),
+            $this->getMockCache()
+        );
+        $this->mockDriver->expects($this->once())
+            ->method('getMailboxes') 
+            ->will($this->returnValue(array('INBOX')));
+        $this->assertEquals(
+            array('INBOX'),
+            $list->listFolders()
+        );
+    }
+
+    public function testCachedList()
+    {
+        $list = new Horde_Kolab_Storage_List_Decorator_Cache(
+            $this->getMockDriverList(),
+            $this->getMockCache()
+        );
+        $this->mockDriver->expects($this->once())
+            ->method('getMailboxes') 
+            ->will($this->returnValue(array('INBOX')));
+        $list->listFolders();
+        $this->assertEquals(
+            array('INBOX'),
+            $list->listFolders()
+        );
+    }
+
+    public function testTwoCachedLists()
+    {
+        $cache = $this->getMockCache();
+        $list = new Horde_Kolab_Storage_List_Decorator_Cache(
+            $this->getMockDriverList(),
+            $cache
+        );
+        $this->mockDriver->expects($this->once())
+            ->method('getMailboxes') 
+            ->will($this->returnValue(array('INBOX')));
+        $this->mockDriver->expects($this->any())
+            ->method('getId') 
+            ->will($this->returnValue(array('A')));
+        $mockDriver2 = $this->getMock('Horde_Kolab_Storage_Driver');
+        $list2 = new Horde_Kolab_Storage_List_Decorator_Cache(
+            new Horde_Kolab_Storage_List_Base(
+                $mockDriver2,
+                new Horde_Kolab_Storage_Factory()
+            ),
+            $cache
+        );
+        $mockDriver2->expects($this->once())
+            ->method('getMailboxes') 
+            ->will($this->returnValue(array('NOTHING')));
+        $this->mockDriver->expects($this->any())
+            ->method('getId') 
+            ->will($this->returnValue(array('B')));
+
+        $list->listFolders();
+        $list2->listFolders();
+        $this->assertEquals(
+            array('NOTHING'),
+            $list2->listFolders()
+        );
+    }
+
+    public function testSynchronizeFolders()
+    {
+        $list = new Horde_Kolab_Storage_List_Decorator_Cache(
+            $this->getMockDriverList(),
+            $this->getMockCache()
+        );
+        $this->mockDriver->expects($this->once())
+            ->method('getMailboxes') 
+            ->will($this->returnValue(array('INBOX')));
+        $list->synchronize();
+    }
+
+    public function testSynchronizeFolderCache()
+    {
+        $list = new Horde_Kolab_Storage_List_Decorator_Cache(
+            $this->getMockDriverList(),
+            $this->getMockCache()
+        );
+        $this->mockDriver->expects($this->once())
+            ->method('getMailboxes') 
+            ->will($this->returnValue(array('INBOX')));
+        $list->synchronize();
+        $list->listFolders();
+    }
+}