Multiple Database Connections with Solar Dependency Injection

In an email the other day, a person asked about being able to connect to multiple databases in Solar. While this is quite easy to do, it probably isn’t officially documented anywhere. If you poke around in Solar’s code, you will soon discover that it can be accomplished using dependency injection (technically this is a combined dependency injection and service locator).

Each of your application’s models extend the Solar_Sql_Model class. If you examine the Solar_Sql_Model class, you’ll notice that one of the config elements is ‘sql’. This is a key that refers to a Solar dependency. The default value for this is key is ‘sql’. That might seem strange at first. How is the string ‘sql’ a dependency? Well, first, we need to dig into the Solar_Sql_Model class. In the _preSetup() method there is a call to Solar::dependency(), which populates the $_sql property using the config[‘sql’] element.

protected function _preSetup()
{
...
// connect to the database
$this->_sql = Solar::dependency('Solar_Sql', $this->_config['sql']);
}

The first parameter is a hint to the the type of object, and the second is either an object OR a string that refers to an object in Solar’s registry. If you remember, the default value of Solar_Sql_Model’s ‘sql’ config element was a string ‘sql’. Therefore, there must be an object in Solar’s registry named ‘sql’. If not, Solar will throw and exception.

If you look at the Solar vendor’s default config (SYSTEM/source/solar/config/default.php) you will see the following:

$config['Solar']['registry_set'] = array(
    'sql'=>'Solar_Sql',
    'user'=>'Solar_User',
    'model_catalog'=>'Solar_Sql_Model_Catalog',
    'mail_transport'=>'Solar_Mail_Transport',
    'controller_front'=>'Solar_Controller_Front',
);

The ‘sql’=>’Solar_Sql’ tells Solar to register a Solar_Sql object in the registry keyed on the string ‘sql’. If you look again at the default.php config file, you should see a config entry for for Solar_Sql where you can define the options for the Solar_Sql object.

/**
* sql adapter to use
*/
$config['Solar_Sql'] = array(
    'adapter' => 'Solar_Sql_Adapter_Sqlite',
);

That is the background information. To summarize what we now know…

  1. Solar’s models connect to the database using a dependency injection/service locator keyed on the string ‘sql’.
  2. Because the default value for the ‘sql’ key is the string ‘sql’, then we know we are looking for something located in Solar’s registry.
  3. Looking at the Solar default.php config file, we see that there is a ‘registry_set’ config element indicating that ‘sql’ should be registered in the registry as a Solar_Sql object.
  4. Finally, the Solar_Sql object is also configured in the default.php file, and in our example, it is configured to use Solar_Sql_Adapter_Sqlite as its adapter class.

Understanding how this works, we can start setting up other sql dependencies to be used by our models. Here is one way you can do it.

First, we need to add another item to our registry. We can call it ‘sql_acme’. One thing to note is that you can specify an array as its value in the registry, not just a class name. It might look like this:

// configuration for the acme Solar_Sql object to be added to the registry
$sql_acme = array(
    'adapter'=>'Solar_Sql_Adapter_Mysql',
    'host'=>'localhost',
    'name'=>'acme',
    'user'=>'juser',
    'pass'=>'S3cr3t'
);
 
// define what will be added to the regsitry
$config['Solar']['registry_set'] = array(
    'sql'=> 'Solar_Sql',
    'sql_acme'=>array('Solar_Sql', $sql_acme),
    'user'=> 'Solar_User',
    'model_catalog'=>'Solar_Sql_Model_Catalog',
    'mail_transport'=>'Solar_Mail_Transport',
    'controller_front'=>'Solar_Controller_Front',
);

Now, we need to tell Solar what registry entry to use for one of our models. You can set that up like this. Assume the model is for a table of articles.

$config['Acme_Model_Articles']['sql'] = 'sql_acme';

That’s all there is to the setup and configuration. There is, however; one important thing to keep in mind. If you are using Solar’s command line tools to create your models then, by default, Solar will use the default ‘sql’ dependency since it can’t read the configuration for a model that doesn’t yet exist. Luckily, you can specify the required configuration options at the command line. For example, if your user credentials and host were the same for both databases, and the only difference was the database name, then you could do this:

$ ./script/solar make-model Acme_Model_Articles --name acme

If you want to know all the options available to the make model (or any) command, use the following:

$ ./script/solar help make-model

So that is one way you can set up multiple databases at the model level in Solar. You can also set up multiple databases for each vendor. I will save that for another post.

Leave a Reply