[Catalyst] One App, multiple databases

Tomas Doran bobtfish at bobtfish.net
Fri Nov 21 00:03:37 GMT 2008


On 20 Nov 2008, at 14:51, Jose Luis Martinez wrote:

> Jonathan Rockway escribió:
>> * On Wed, Nov 19 2008, Jose Luis Martinez wrote:
>>> sub ACCEPT_CONTEXT {
>>>     my ($self, $c) = @_;
>>>
>>>     my $user_db = $c->lookup_the_users_db();
>>>     $self->{'dsn'} =~ s/#DATABASE#/$user_db/;
>>>
>>>     return $self;
>>> }
>>>
>> I am really surprised that this works at all.  When do you  
>> actually ever
>> connect to the database with the DSN in $self->{dsn}?  (I am also
>> surprised that the DBIC version works.)
>
> It looks like the models don't connect to the database until it is  
> first needed, so changing the properties with which they connect  
> lets me get away with it. I think the fact that I'm working with  
> app_server.pl -f helps me start each request without preestablished  
> db connection.
>
>> Anyway, mutating objects is wrong.  You should do things like this:
>>   package MyApp::Model::UsersDatabase;
>>   ...
>>   sub ACCEPT_CONTEXT {
>>       my ($self, $c) = @_;
>>       return $c->user->get_database($c->config->database_info);
>>   }
>> <snip>
>> The idea is that each user has his own database connection, stored in
>> the user object, and Catalyst just returns the right thing when  
>> you say
>> $c->model('UsersDatabase').  This is much easier to reason about.
>
> But I'll still have to change Model::DBI and/or Model::DBIC::Schema  
> connection information on the fly... how should I do this in a  
> clean way?

No, you don't.

In your application code, instead of saying $c->model('DB')->dbh,  
with the example above, you would say $c->model('UsersDatabase'), and  
that would return you the dbh which the user object had generated.

You then work with it in exactly the same way as if you were using  
Catalyst::Model::DBI.

This means that you have to re-implement the connection logic of  
Catalst::Model::DBI in your user class. The only tricky bit is the  
stay_connected function, which is 16 lines long.

I don't think the code police will break down your door if you pinch  
this function verbatim. ;)

Cheers
t0m




More information about the Catalyst mailing list