From 26bf4120c501fb890aa4dfb909a3b8513d6fafd0 Mon Sep 17 00:00:00 2001 From: Gunnar Wrobel Date: Mon, 3 Jan 2011 10:41:19 +0100 Subject: [PATCH] Support caching the folder list. --- .../lib/Horde/Kolab/Storage/Factory.php | 7 +- .../Kolab_Storage/lib/Horde/Kolab/Storage/List.php | 7 + .../lib/Horde/Kolab/Storage/List/Base.php | 10 ++ .../Horde/Kolab/Storage/List/Decorator/Cache.php | 56 ++++++- .../lib/Horde/Kolab/Storage/List/Decorator/Log.php | 10 ++ .../test/Horde/Kolab/Storage/TestCase.php | 14 ++ .../Horde/Kolab/Storage/Unit/Folder/TypeTest.php | 1 - .../Storage/Unit/List/Decorator/CacheTest.php | 162 +++++++++++++++++++++ 8 files changed, 262 insertions(+), 5 deletions(-) create mode 100644 framework/Kolab_Storage/test/Horde/Kolab/Storage/Unit/List/Decorator/CacheTest.php diff --git a/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Factory.php b/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Factory.php index a56a3c6b6..596c00ec3 100644 --- a/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Factory.php +++ b/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Factory.php @@ -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, ) diff --git a/framework/Kolab_Storage/lib/Horde/Kolab/Storage/List.php b/framework/Kolab_Storage/lib/Horde/Kolab/Storage/List.php index a670999f7..d144a0238 100644 --- a/framework/Kolab_Storage/lib/Horde/Kolab/Storage/List.php +++ b/framework/Kolab_Storage/lib/Horde/Kolab/Storage/List.php @@ -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. diff --git a/framework/Kolab_Storage/lib/Horde/Kolab/Storage/List/Base.php b/framework/Kolab_Storage/lib/Horde/Kolab/Storage/List/Base.php index 7be624b08..12e1cfeb9 100644 --- a/framework/Kolab_Storage/lib/Horde/Kolab/Storage/List/Base.php +++ b/framework/Kolab_Storage/lib/Horde/Kolab/Storage/List/Base.php @@ -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. diff --git a/framework/Kolab_Storage/lib/Horde/Kolab/Storage/List/Decorator/Cache.php b/framework/Kolab_Storage/lib/Horde/Kolab/Storage/List/Decorator/Cache.php index 0c709f314..756cd816d 100644 --- a/framework/Kolab_Storage/lib/Horde/Kolab/Storage/List/Decorator/Cache.php +++ b/framework/Kolab_Storage/lib/Horde/Kolab/Storage/List/Decorator/Cache.php @@ -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. diff --git a/framework/Kolab_Storage/lib/Horde/Kolab/Storage/List/Decorator/Log.php b/framework/Kolab_Storage/lib/Horde/Kolab/Storage/List/Decorator/Log.php index fb67d0f4e..4bf62b731 100644 --- a/framework/Kolab_Storage/lib/Horde/Kolab/Storage/List/Decorator/Log.php +++ b/framework/Kolab_Storage/lib/Horde/Kolab/Storage/List/Decorator/Log.php @@ -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. diff --git a/framework/Kolab_Storage/test/Horde/Kolab/Storage/TestCase.php b/framework/Kolab_Storage/test/Horde/Kolab/Storage/TestCase.php index d70c05686..5f6142a9a 100644 --- a/framework/Kolab_Storage/test/Horde/Kolab/Storage/TestCase.php +++ b/framework/Kolab_Storage/test/Horde/Kolab/Storage/TestCase.php @@ -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); diff --git a/framework/Kolab_Storage/test/Horde/Kolab/Storage/Unit/Folder/TypeTest.php b/framework/Kolab_Storage/test/Horde/Kolab/Storage/Unit/Folder/TypeTest.php index ff1722cb9..12cba48ab 100644 --- a/framework/Kolab_Storage/test/Horde/Kolab/Storage/Unit/Folder/TypeTest.php +++ b/framework/Kolab_Storage/test/Horde/Kolab/Storage/Unit/Folder/TypeTest.php @@ -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 index 000000000..4aa60a2d9 --- /dev/null +++ b/framework/Kolab_Storage/test/Horde/Kolab/Storage/Unit/List/Decorator/CacheTest.php @@ -0,0 +1,162 @@ + + * @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 + * @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(); + } +} -- 2.11.0