[Catalyst] One App, multiple databases

Jose Luis Martinez jlmartinez-lists-catalyst at capside.com
Thu Nov 20 14:51:47 GMT 2008


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);
>   }
> 
> Then your user class should do something like:
> 
>   sub get_database {
>       my ($self, $database_info) = @_;
> 
>       $self->database_connection($self->connect_to_database($database_info))
>         unless $self->has_database_connection;
> 
>       return $self->database_connection;
>   }
> 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?

Regards,

Jose Luis Martinez
jlmartinez at capside.com



More information about the Catalyst mailing list