Thanks much. I didn't realize the old (and easy) method of doing this
was deprecated.

On Jan 19, 10:04 am, Andreas Hofmann
<[email protected]> wrote:
> Hi all,
>
> we have discovered a way how to realize master/slave support with cake
> (also with multiple slaves).
> This old post is completely 
> depricated:http://groups.google.com/group/cake-php/browse_thread/thread/58ea010f...
> Because Model::find() and Model::save() create the $db-handle lines
> before it calles the callbacks 'beforeFind' and 'beforeSave'.
>
> The way we realized is to overwrite the save() and updateAll()
> methodes and to set the default db-config in the AppModel::__construct
> ().
>
> Note: One thing remains: It's not possible to do a bindModel in the
> 'beforeSave' and 'afterSave' callbacks, because they get the wrong db-
> config... If you find a way to do it, please let us know!
>
> 1. Define your Database-Configs in app/config/database.php. You should
> have master and as much slaves you want to have:
>
> class DATABASE_CONFIG {
>
>   var $master = array(
>     driver' => 'mysql',
>     'persistent' => false,
>     'host' => 'localhost',
>     'login' => 'login',
>     'password' => 'password',
>     'database' => 'database',
>     'encoding' => 'utf8'
>   );
>
>   // Config for Slave #1
>   var $slave1 = array(
>     driver' => 'mysql',
>     'persistent' => false,
>     'host' => 'slave1',
>     'login' => 'login',
>     'password' => 'password',
>     'database' => 'database',
>     'encoding' => 'utf8'
>   );
>
>   // Config for Slave #2
>   var $slave2 = array(
>     driver' => 'mysql',
>     'persistent' => false,
>     'host' => 'slave2',
>     'login' => 'login',
>     'password' => 'password',
>     'database' => 'database',
>     'encoding' => 'utf8'
>   );
> ...
>
> }
>
> 2. Create/Alter app/models/app_model.php and create/alter the
> constructor '__construct' of it like the following:
>
> class AppModel extends Model {
>
>   public function __construct($id = false, $table = null, $ds = null)
> {
>
>     /**********************************
>      * USED FOR MASTER/SLAVE MECHANIC *
>      **********************************/
>     // If a datasource is set via params, use it and return
>     if((is_array($id) && isset($id['ds'])) || $ds) {
>       parent::__construct($id, $table, $ds);
>
>       return;
>     }
>
>     // Use a static variable, to only use one connection per page-call
> (otherwise we would get a new handle every time a Model is created)
>     static $_useDbConfig;
>     if(!isset($_useDbConfig)) {
>       // Get all available database-configs
>       $sources_list = ConnectionManager::enumConnectionObjects();
>
>       // Find the slaves we have
>       $slaves = array();
>       foreach($sources_list as $name => $values) {
>         // Slaves have to be named "slave1", "slave2", etc...
>         if(preg_match('/^slave[0-9]+$/i', $name) == 1) {
>           $slaves[] = $name;
>         }
>       }
>
>       // Randomly use a slave
>       $_useDbConfig = $slaves[rand(0, count($slaves) - 1)];
>       $this->_usedSlave = $_useDbConfig;
>     }
>     $this->useDbConfig = $_useDbConfig;
>
>     parent::__construct($id, $table, $ds);
>   }
> ...
>
> }
>
> This method uses a local static variable to save the db-config
> application-wide. It collects all configs from the database.php that
> start with "slave#" and selects a random one for it. This is now the
> "default"-config for the application that is used with every query
> done via the Model-class UNTIL we do the next step:
>
> 3. We now overwrite the Model::save() and Model::find() methods to use
> another database-config for write-queries!
> Note: We discovered, that it's not enough to just overwrite Model::save
> (), because Model::updateAll() doesn't use the callbacks, neither the
> Model::save() method.
>
>   function save($data = null, $validate = true, $fieldList = array())
> {
>     // Remember the old config
>     $oldDb = $this->useDbConfig;
>     // Set the new config
>     $this->setDataSource('master');
>     // Call the original Model::save() method
>     $return = parent::save($data, $validate, $fieldList);
>     // Reset the config/datasource
>     $this->setDataSource($oldDb);
>
>     return $return;
>   }
>
>   function updateAll($fields, $conditions = true) {
>     $oldDb = $this->useDbConfig;
>     $this->setDataSource('master');
>     $return = parent::updateAll($fields, $conditions);
>     $this->setDataSource($oldDb);
>
>     return $return;
>   }
>
> Now you should have full master/slave support within your cake-
> application.
> The way it works:
> When your application is called, the AppModel will be called the first
> time and realizes, that the local $_useDbConfig variable is not set.
> So it randomly selects one of your slave-configs and sets this to the
> default used database-config (AppModel::useDbConfig). Every further
> instance of AppModel will recognize that the local $_useDbConfig
> variable already exists and will use the same config.
> Now every query you do will use this slave-config, EXCEPT all save's
> and updateAll's, because you've overwritten these methods to use your
> master-config.
>
> Hope this tutorial was helpful to you!
>
> Greetings,
>
> Andreas Hofmann!
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"CakePHP" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/cake-php?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to