Add time stamp and version to the cache.
authorGunnar Wrobel <p@rdus.de>
Mon, 3 Jan 2011 13:38:19 +0000 (14:38 +0100)
committerGunnar Wrobel <p@rdus.de>
Tue, 4 Jan 2011 07:54:23 +0000 (08:54 +0100)
framework/Kolab_Storage/lib/Horde/Kolab/Storage/List/Decorator/Cache.php
framework/Kolab_Storage/test/Horde/Kolab/Storage/Unit/List/Decorator/CacheTest.php

index 31cf8aa..2b4bba0 100644 (file)
 class Horde_Kolab_Storage_List_Decorator_Cache
 implements Horde_Kolab_Storage_List
 {
-    /** Marks the folder list. */
+    /** Key for the folder list. */
     const FOLDERS = 'F';
 
-    /** Marks the type list. */
+    /** Key for the type list. */
     const TYPES = 'T';
 
+    /** Key for the last time the list was synchronized. */
+    const SYNC = 'S';
+
+    /** Holds query cache results. */
+    const QUERIES = 'Q';
+
+    /** Key for the cache format version. */
+    const VERSION = 'V';
+
+    /** Holds the version number of the cache format. */
+    const FORMAT_VERSION = '1';
+
     /**
      * Decorated list handler.
      *
@@ -49,6 +61,13 @@ implements Horde_Kolab_Storage_List
     private $_cache;
 
     /**
+     * Has the cache already been loaded and validated?
+     *
+     * @var boolean
+     */
+    private $_init = false;
+
+    /**
      * Constructor.
      *
      * @param Horde_Kolab_Storage_List  $list  The original list handler.
@@ -80,6 +99,24 @@ implements Horde_Kolab_Storage_List
      */
     private function _init()
     {
+        if ($this->_init) {
+            return;
+        }
+        $last_sync = $this->_cache->loadListData(
+            $this->_list->getConnectionId(),
+            self::SYNC
+        );
+        if (empty($last_sync)) {
+            $this->synchronize();
+            return;
+        }
+        $version = $this->_cache->loadListData(
+            $this->_list->getConnectionId(),
+            self::VERSION
+        );
+        if ($version != self::FORMAT_VERSION) {
+            $this->synchronize();
+        }
     }
 
     /**
@@ -90,30 +127,10 @@ implements Horde_Kolab_Storage_List
     public function listFolders()
     {
         $this->_init();
-        $a = $this->_cache->loadListData(
+        return $this->_cache->loadListData(
             $this->_list->getConnectionId(),
             self::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(),
-            self::FOLDERS,
-            $list
-        );
-        return $list;
     }
 
     /**
@@ -125,41 +142,44 @@ implements Horde_Kolab_Storage_List
     public function listFolderTypes()
     {
         $this->_init();
-        $a = $this->_cache->loadListData(
+        return $this->_cache->loadListData(
             $this->_list->getConnectionId(),
             self::TYPES
         );
-        if (empty($a)) {
-            $a = $this->_cacheFolderTypes();
-        }
-        return $a;
     }
 
     /**
-     * Cache and returns the folder type annotation as associative array.
+     * Synchronize the list information with the information from the backend.
      *
-     * @return array The list folder types with the folder names as key and the
-     *               folder type as values.
+     * @return NULL
      */
-    private function _cacheFolderTypes()
+    public function synchronize()
     {
-        $types = $this->_list->listFolderTypes();
+        $this->_cache->storeListData(
+            $this->_list->getConnectionId(),
+            self::QUERIES,
+            array()
+        );
+        $this->_cache->storeListData(
+            $this->_list->getConnectionId(),
+            self::FOLDERS,
+            $this->_list->listFolders()
+        );
         $this->_cache->storeListData(
             $this->_list->getConnectionId(),
             self::TYPES,
-            $types
+            $this->_list->listFolderTypes()
         );
-        return $types;
-    }
-
-    /**
-     * Synchronize the list information with the information from the backend.
-     *
-     * @return NULL
-     */
-    public function synchronize()
-    {
-        $this->_cacheFolders();
-        $this->_cacheFolderTypes();
+        $this->_cache->storeListData(
+            $this->_list->getConnectionId(),
+            self::VERSION,
+            self::FORMAT_VERSION
+        );
+        $this->_cache->storeListData(
+            $this->_list->getConnectionId(),
+            self::SYNC,
+            time()
+        );
+        $this->_init = true;
     }
 }
\ No newline at end of file
index 0a9e8eb..11e27e7 100644 (file)
@@ -253,4 +253,64 @@ extends Horde_Kolab_Storage_TestCase
         $list->synchronize();
         $list->listFolderTypes();
     }
+
+    public function testSynchronizeIfEmpty()
+    {
+        $list = new Horde_Kolab_Storage_List_Decorator_Cache(
+            $this->getMockDriverList(),
+            $this->getMockCache()
+        );
+        $this->mockDriver->expects($this->once())
+            ->method('listAnnotation')
+            ->will($this->returnValue(array('INBOX' => 'mail.default')));
+        $list->listFolders();
+    }
+
+    public function testEmptyIfFooled()
+    {
+        $cache = $this->getMockCache();
+        $list = new Horde_Kolab_Storage_List_Decorator_Cache(
+            $this->getMockDriverList(),
+            $cache
+        );
+        $cache->storeListData($list->getConnectionId(), 'S', time());
+        $cache->storeListData($list->getConnectionId(), 'V', '1');
+        $this->mockDriver->expects($this->never())
+            ->method('getMailboxes') 
+            ->will($this->returnValue(array('INBOX')));
+        $this->assertEmpty($list->listFolders());
+    }
+
+    public function testInvalidVersion()
+    {
+        $cache = $this->getMockCache();
+        $list = new Horde_Kolab_Storage_List_Decorator_Cache(
+            $this->getMockDriverList(),
+            $cache
+        );
+        $cache->storeListData($list->getConnectionId(), 'S', time());
+        $cache->storeListData($list->getConnectionId(), 'V', '2');
+        $this->mockDriver->expects($this->once())
+            ->method('getMailboxes') 
+            ->will($this->returnValue(array('INBOX')));
+        $this->mockDriver->expects($this->once())
+            ->method('listAnnotation')
+            ->will($this->returnValue(array('INBOX' => 'mail.default')));
+        $list->listFolders();
+    }
+
+    public function testInitialization()
+    {
+        $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')));
+        $list->listFolders();
+        $cache->storeListData($list->getConnectionId(), 'V', '2');
+        $list->listFolders();
+    }
 }