sfPropelMemcachePlugin - 1.0.6

provides model cache in Propel

You are currently browsing
the website for symfony 1

Visit the Symfony2 website


« Back to the Plugins Home

Signin


Forgot your password?
Create an account

Tools

Stats

advanced search
Information Readme Releases Changelog Contribute
Show source

sfPropelMemcache plugin

The sfPropelMemcache is a symfony plugin that provides model cache in Propel 1.2-1.6.

This plugin CACHE DATA, NOT OBJECTS.

This plugin overrides the classes generating objects Propel.

Details

It overwrite four model methods:

     public static function addInstanceToPool($obj, $key = null);
     public static function removeInstanceFromPool($value);
     public static function getInstanceFromPool($key);
     public static function clearInstancePool();

Model pool after that use memcache to store objects.

  • After the execute method save stored object is reload.
  • After execute method delete object deletes from database
  • Method retrieveByPK loads an object from the cache (or from database)

For example:

     $oUser->save(); //execute addInstanceToPool($this)
     $oUser->delete(); //execute removeInstanceFromPool()
     UserPeer::retrieveByPk(); //execute getInstanceFromPool and addInstanceToPool()
     UserPeer::doDelete(); //clearInstancePool() or removeInstanceFromPool()

Links for Russian-speaking:

  • http://habrahabr.ru/blogs/symfony/74654/
  • http://habrahabr.ru/blogs/symfony/74873/

Installation

  • Change or Add Propel generation classes in config/propel.ini

      propel.builder.peer.class = plugins.sfPropelMemcachePlugin.lib.builder.SfPeerBuilderMemcache
      propel.builder.object.class = plugins.sfPropelMemcachePlugin.lib.builder.SfObjectBuilderMemcache
    
  • Activate the plugin in the config/ProjectConfiguration.class.php

    class ProjectConfiguration extends sfProjectConfiguration
    {
      public function setup()
      {
        $this->enablePlugins(array(
          'sfPropelPlugin',
          'sfPropelMemcachePlugin',
          '...'
        ));
      }
    }
  • Add cache: on to table attributes

      [yml]
      user:
        _attributes:  { phpName: User, cache: on }
    
  • Rebuild model

      $ symfony propel:build-model
    

Use keys for cache

  • Add parameter cache_key: "column" to any column ( MUST BE UNIQ )

      [yml]
      user:
        username:  { type: varchar, size: 128, required: true, index: unique, cache_key: "username" }
    
  • rebuild model

      $ symfony propel:build-model
    

Keys may be multiple: cache_key: "username+some_column"

Configure example

      [yml]
      sf_guard_user:
        _attributes:    { phpName: sfGuardUser, cache: on }
        id:             ~
        username:       { type: varchar, size: 128, required: true, index: unique, cache_key: "username" }
        algorithm:      { type: varchar, size: 128, required: true, default: sha1 }
        salt:           { type: varchar, size: 128, required: true }
        password:       { type: varchar, size: 128, required: true }
        created_at:     ~
        is_active:      { type: boolean, required: true, default: 1 }
        is_super_admin: { type: boolean, required: true, default: 0 }
        avatar_id:      { type: INTEGER, size: '11', required: false, foreignTable: photo, foreignReference: id, onDelete: RESTRICT, onUpdate: RESTRICT }
        _indexes:       { sf_guard_user_fk: [avatar_id] }

     sf_guard_user_profile:
        _attributes:         { phpName: sfGuardUserProfile, cache: on }
        id:                  { type: INTEGER, size: '11', primaryKey: true, autoIncrement: true, required: true }
        user_id:             { type: INTEGER, size: '11', required: true, foreignTable: sf_guard_user, foreignReference: id, onDelete: CASCADE, onUpdate: RESTRICT, index: unique, cache_key: "user_id" }
        first_name:          { type: VARCHAR, size: '100', required: false }
        second_name:         { type: VARCHAR, size: '100', required: false }
        last_name:           { type: VARCHAR, size: '100', required: false }
        email:               { type: VARCHAR, size: '200', required: true }
       _indexes:            { sf_guard_user_profile_FI_1: [user_id] }
       _uniques:            { ux_email: [email] }

     photo:
       _attributes:    { phpName: Photo, cache: on }
       id:             { type: INTEGER,   size: '11',  required: true, primaryKey: true, autoIncrement: true }
       user_id:        { type: INTEGER,   size: '11',  required: true, foreignKey: true, foreignTable: sf_guard_user, foreignReference: id, onDelete: CASCADE }
       photo_album_id: { type: INTEGER,   size: '11',  required: true, foreignKey: true, foreignTable: photo_album, foreignReference: id, onDelete: CASCADE }
       name:           { type: VARCHAR,   size: '100', required: false, defaultValue: '' }
       _indexes:       { user_id: [user_id], photo_album_id: [photo_album_id] }

     photo_album:
       _attributes:    { phpName: PhotoAlbum, cache: on }
       id:             { type: INTEGER,   size: '11',  required: true,  primaryKey: true, autoIncrement: true }
       user_id:        { type: INTEGER,   size: '11',  required: true, foreignKey: true, foreignTable: sf_guard_user, foreignReference: id, onDelete: CASCADE }
       name:           { type: VARCHAR,   size: '100', required: true }
       _indexes:       { user_id: [user_id] }

Now:

  • in photo object and photo_album object method getSfGuardUser() execute sfGuardUserPeer::retrieveByPk(). Yes from cache :)
  • in user object method getPhoto() execute PhotoPeer::retrieveByPK(); Yes from cache :)
  • in profile object method getCountry() execute CountryPeer::retrieveByPK() :)))))
  • add method to retriveByUserId to sfGuardUserProfilePeer and takes profile object from cache ($oUser->getProfile())

    public static function retriveByUserId($id)
    {
      $key = 'user_id-'.$id;
     
      if (null !== ($obj = self::getInstanceFromPool($key)))
      {
        return $obj;
      }
     
      $c = new Criteria();
      $c->add(self::USER_ID, $id);
     
      return parent::doSelectOne($c);
    }

Cache in object

if cache: on in model you can use new generated methods which provide local object cache:

  • getFromCache($key, $default = null)
  • setToCache($key, $data)
  • removeFromCache($key)
  • clearCustomPropelCache()

Example:

  • We have Articles and tags. Cache will be cleaned then executed method save()!

    public function getTags()
    {
         $key = 'article-tags';
     
         if(is_null($tags = $this->getFromCache($key)))
         {
             $links = $this->getArticle2tags();
             $tags = array();
     
             foreach ( $links as $link )
             {
               $tags[] = $link->getTagId();
             }
     
             $this->setToCache($key, serialize($tags));
         }
     
         //get string from cache
         if(is_string($tags))
         {
            $tags = unserialize($tags);
         }
     
         $oTags = array();
     
         foreach($tags as $pk)
         {
            // get from cache ))
            $oTags[] = ArticleTagPeer::retrieveByPK($pk);
         }
     
         return $oTags;
    }

NEW 10.02.2010

  • Cache in object

NEW 23.10.2011

  • add support sfPropelORMPlugin