[Dbix-class] Runtime database name and table name changes +
Catalyst
Matt S Trout
dbix-class at trout.me.uk
Thu Jan 25 08:55:22 GMT 2007
On 24 Jan 2007, at 20:58, James R. Leu wrote:
> Hello Matt,
>
> Thank you for your response. Your recommendation has started me
> down the
> right path. I have a working implementation, but I'm not sure if I'm
> following proper DBIx::Class practices.
>
> I've implemented a template source 'Foo' which is used for
> defining the relationships. In addition I implemented a
> ACCEPT_CONTEXT
> in my Catalyst::Model::DBIC::Schema.
>
> Here is a simplified version of what I've done, I've framed it in
> Catalyst code, but I my question at this point is specific to my
> DBIx::Class handling:
>
> package MyApp::Model::Config
> use base 'Catalyst::Model::DBIC::Schema';
>
> ...
>
> sub ACCEPT_CONTEXT {
> my ($self, $c) = @_;
> if ($c->user_exists) {
> my $name = $c->user->username;
> $self->{connect_info} = [
> 'DBI:mysql:config_'.$name,
> 'username',
> 'password',
> ];
> my $schema = $self->clone();
> $schema->source('Foo')->name('data.foo_01');
> $schema->connection(@{$self->{connect_info}});
> $self->schema($schema);
> }
> return $self;
> }
> 1;
>
> Am I conducting an layer violations by calling connection() and
> source()?
> Do I need special handling for when the connection has already been
> created?
Hmm ... I wonder if the better way, actually, isn't to set the
default database to 'data' and then go across the other sources and
set their name to 'config_'.$name.'.tblname', that way you can
maintain a single persistent connection but still have a given
request access the right place.
>
> I have other questions about Catalyst, but I will ask those on the
> Catalyst mailing list.
>
> Thank you for your time.
>
> On Wed, Jan 24, 2007 at 09:15:21AM +0000, Matt S Trout wrote:
>>
>> On 23 Jan 2007, at 21:34, James R. Leu wrote:
>>
>>> Disclaimer:
>>> I'm a noob to DBIx::Class. I checked the archives, but was unable to
>>> find an answer to the following question. If I've overlooked an
>>> obvious
>>> source to my answers, please scold me and point me the the relevant
>>> URL.
>>>
>>> Hello,
>>>
>>> I'm trying to use DBIx::Class to access a database for which the
>>> name
>>> changes based on who is authenticated. In addition the
>>> authorization
>>> of the use affects what dynamically name table they 'link' to in
>>> another
>>> database.
>>>
>>> I read about DBIx::Class::Schema::Loader, but was unable to grok
>>> how I would define relationships to a dynamically named table.
>>>
>>> To better illustrate here is a simplified example:
>>>
>>> The following database reside within a common mysql instance.
>>>
>>> Database: config_alpha
>>> Table: common
>>>
>>> Database: config_beta
>>> Table: common
>>>
>>> Database: data
>>> Table: foo_01
>>> Table: foo_88
>>> Table: foo_34
>>> Table: foo_39
>>>
>>> Depending which user logged in 'alpha' or 'beta' they would
>>> connect to the appropriate 'config' database. In addition they are
>>> connected the the 'data' database. Depending on additional
>>> authorization data they would have permission to see data in one of
>>> the
>>> 'foo' tables. I would like to define a has_many relationship
>>> between
>>> entries in the 'common' and the 'foo' table.
>>>
>>> I think I can image ways to make some of this work in a stand-alone
>>> script, but I haven't the foggiest idea how to make this work within
>>> a Catalyst environment.
>>>
>>> Any pointers would be much appreciated.
>>
>> Ok, basically, define a has_many across to 'data.PLACEHOLDER', then
>> wrap ->connect so on the schema object -to be returned-, which will
>> have a copy of the ResultSource objects, then if your Foo_* tables
>> are different you'll want -
>>
>> $schema->source('Common')->relationship_info
>> ('data_has_many_rel_name')->{source} = 'Foo_1';
>>
>> or similar, or if your foo_* tables are all the same define a single
>> Foo class and
>>
>> $schema->source('Foo')->name('data.foo_1');
>>
>> then return the $schema.
>>
>> For doing this dynamically in Catalyst on a per-user basis I'd
>> provide an ACCEPT_CONTEXT method in your DBIC::Schema model -
>>
>> sub ACCEPT_CONTEXT {
>> my ($self, $c) = @_;
>> if ($c->user_exists) {
>> return $self->copy_and_modify_schema_with_user($c->user);
>> } else {
>> return $self;
>> }
>> }
>>
>> --
>> Matt S Trout, Technical Director, Shadowcat Systems Ltd.
>> Offering custom development, consultancy and support contracts for
>> Catalyst,
>> DBIx::Class and BAST. Contact mst (at) shadowcatsystems.co.uk for
>> details.
>> + Help us build a better perl ORM: http://dbix-
>> class.shadowcatsystems.co.uk/ +
>>
>
> --
> James R. Leu
> jleu at mindspring.com
--
Matt S Trout, Technical Director, Shadowcat Systems Ltd.
Offering custom development, consultancy and support contracts for
Catalyst,
DBIx::Class and BAST. Contact mst (at) shadowcatsystems.co.uk for
details.
+ Help us build a better perl ORM: http://dbix-
class.shadowcatsystems.co.uk/ +
More information about the Dbix-class
mailing list