views:

59

answers:

1

Hi,

I'm looking to implement a cache within Zend_Db, there isn't any native method to provide a cache to Zend_Db, so I'm wondering where should I do it.

I took a look to the Zend_Db_Table_Abstract (I'm extending it in a custom App_Model_DbTable_Abstract) and I found a protected method _fetch() which directly take a Zend_Db_Table_Select instance and looks like to be the last step before the adapter.

I was thinking override this method, serialize the $select object, hash it, and finally cache it, and check against each $select object provided to return the cache or an up-to-date rowset.

Is it a correct way to do?

Here is what I just did:

class App_Model_DbTable_Abstract extends Zend_Db_Table_Abstract
{
    protected function _fetch(Zend_Db_Table_Select $select)
    {
        $hashedQuery = sha1(serialize($select->__toString()));
        $cacheManager = Zend_Registry::get('Zend_Cache_Manager');
        $cache = $cacheManager->getCache('database');
        if (!($data = $cache->load($hashedQuery))) {
            $data = parent::_fetch($select);
            $cache->save($data, $hashedQuery);
        }
        return $data;
    }
}
+2  A: 

As far as I know, the zf create db-table <name> will always create a class inheriting Zend_Db_Table_Abstract which would make your proposal difficult to manage.

Besides, you're coupling the cache & db modules of ZF so one could argue that it's not right to place cache mechanisms under the dbtable scope. For example: you should not know where the data is being fetched from but still be able to cache it, so the process becomes this:

  1. check cache for data, serve if found
  2. fetch data from X (could be dbtable, could also be a Service, an XML-file, some JSON etc)
  3. save data in cache and serve data

So although your solution makes sense now since you're only using dbtable models, it could be placed in a more suiting layer. I would check out http://www.slideshare.net/weierophinney/playdoh-modelling-your-objects-1766001 (around slide #35) for a practical solution.

Summary: the dbtable module and your code concerning it should always be about using the db.

chelmertz
Thank you for your answer, after reading the slide, I think decorators will do the trick, since I sometimes bypass controllers when only accessing model in views, and I wouldn't like to implement my cache there, but a decoated object is ok since the caching is not done in the views, and/or controllers.
John
@John: good luck! I'm not sure I agree with calling models in views but as long as you feel comfortable with it.. :) (My view on views is that they're supposed to be dumb and just accept whatever data being thrown at theme - i.e. they shouldn't know about anything but the simplest methods of your models).
chelmertz