![]() |
|
Snippets |
|
Doctrine's built-in support for multiple connections follows a baffling use-case that allows different Model objects to be saved on different connections. A more common usage of multiple connections is to send read commands to a slave database and write commands to a master. Here's how to do it.
Declare your connections in databases.yml as usual, name one of them master and one of them slave.
Override Doctrine's default Query and Record objects. Edit config/ProjectConfiguration.class.php and add the following method:
public function configureDoctrine(Doctrine_Manager $manager) { // Configure custom query and custom record classes $manager->setAttribute(Doctrine::ATTR_QUERY_CLASS, 'MyQuery'); $options = array('baseClassName' => 'MyRecord'); sfConfig::set('doctrine_model_builder_options', $options); }
Create your MyQuery class in lib/MyQuery
class MyQuery extends Doctrine_Query { public function preQuery() { // If this is a select query then set connection to the slave if (Doctrine_Query::SELECT == $this->getType()) { $this->_conn = Doctrine_Manager::getInstance()->getConnection('slave'); // All other queries are writes so they need to go to the master } else { $this->_conn = Doctrine_Manager::getInstance()->getConnection('master'); } } }
Create your MyRecord class in lib/MyRecord.class.php
abstract class MyRecord extends sfDoctrineRecord { public function save(Doctrine_Connection $conn = null) { $conn = Doctrine_Manager::getInstance()->getConnection('master'); parent::save($conn); } }
If you're using a Doctrine behaviour that creates new tables, like the Versionable behaviour, tell it to use MyRecord too.
Entity:
ActAs:
Versionable:
builderOptions:
baseClassName: MyRecord
Finally, rebuild your model
./symfony doctrine:build --all-classes
If you have multiple slaves, modify the ProjectConfiguration to pick one on startup then change the method on your Query object to retrieve it.