From: Rafael Kitover Date: Wed, 28 Apr 2010 12:43:21 +0000 (+0000) Subject: allow configuring ResultSets through the SchemaProxy trait X-Git-Tag: v0.41^0 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Model-DBIC-Schema.git;a=commitdiff_plain;h=21d8159f80adbd21755cdd5481e9f4cf2f9a5ac2;hp=510629748f0214f9e8bed35502a90edf7b6d589e allow configuring ResultSets through the SchemaProxy trait --- diff --git a/Changes b/Changes index fbf2716..2085137 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,8 @@ Revision history for Perl extension Catalyst::Model::DBIC::Schema +0.41 Wed Apr 28 08:42:13 EDT 2010 + - allow configuring ResultSets using the SchemaProxy trait + 0.40 Wed Feb 3 23:12:16 EST 2010 - fix Replicated trait deps diff --git a/lib/Catalyst/Helper/Model/DBIC/Schema.pm b/lib/Catalyst/Helper/Model/DBIC/Schema.pm index d35bfb8..eb89068 100644 --- a/lib/Catalyst/Helper/Model/DBIC/Schema.pm +++ b/lib/Catalyst/Helper/Model/DBIC/Schema.pm @@ -4,7 +4,7 @@ use namespace::autoclean; use Moose; no warnings 'uninitialized'; -our $VERSION = '0.40'; +our $VERSION = '0.41'; $VERSION = eval $VERSION; use Carp; diff --git a/lib/Catalyst/Model/DBIC/Schema.pm b/lib/Catalyst/Model/DBIC/Schema.pm index 8adb800..8ef4bf4 100644 --- a/lib/Catalyst/Model/DBIC/Schema.pm +++ b/lib/Catalyst/Model/DBIC/Schema.pm @@ -5,7 +5,7 @@ use mro 'c3'; extends 'Catalyst::Model'; with 'CatalystX::Component::Traits'; -our $VERSION = '0.40'; +our $VERSION = '0.41'; $VERSION = eval $VERSION; use namespace::autoclean; @@ -348,6 +348,13 @@ Unresolved arrayref of traits passed in the config. Traits you used resolved to full class names. +=head1 CONFIGURING YOUR SCHEMA AND RESULTSETS + +See the documentation for +L for instructions on how +to pass config values from your L config to your +L and/or L classes. + =head1 METHODS =head2 new @@ -401,7 +408,8 @@ Shortcut for ->schema->txn_scope_guard =head2 storage Provides an accessor for the connected schema's storage object. -Used often for debugging and controlling transactions. + +See L and L. =cut @@ -432,6 +440,14 @@ has _default_cursor_class => ( has schema => (is => 'rw', isa => Schema); +my $app_class; + +before COMPONENT => sub { + $app_class = ref $_[1] || $_[1]; +}; + +sub app_class { $app_class } + sub BUILD { my ($self, $args) = @_; my $class = $self->_original_class_name; @@ -660,7 +676,7 @@ Pavel I. Shaydo C =head1 COPYRIGHT -Copyright (c) 2006 - 2009 +Copyright (c) 2006 - 2010 the Catalyst::Model::DBIC::Schema L and L as listed above. @@ -672,4 +688,4 @@ under the same terms as Perl itself. =cut 1; -# vim:sts=4 sw=4 et: +# vim:sts=4 sw=4 et tw=80: diff --git a/lib/Catalyst/TraitFor/Model/DBIC/Schema/SchemaProxy.pm b/lib/Catalyst/TraitFor/Model/DBIC/Schema/SchemaProxy.pm index 3fe2973..0f97e97 100644 --- a/lib/Catalyst/TraitFor/Model/DBIC/Schema/SchemaProxy.pm +++ b/lib/Catalyst/TraitFor/Model/DBIC/Schema/SchemaProxy.pm @@ -13,11 +13,72 @@ Options from Model =head1 DESCRIPTION Allows you to call your L methods directly on the Model -instance, and passes config options to the C attributes at C -time. +instance, and passes config options to your L and +L attributes at C time. -Methods and attributes local to your C take precedence over C -methods and attributes. +Methods and attributes local to your C take precedence over +L or L methods and attributes. + +=head1 CREATING SCHEMA CONFIG ATTRIBUTES + +To create attributes in your C, use either Moose or +L, which is inherited from by all L +classes automatically. E.g.: + + __PACKAGE__->mk_group_accessors(simple => qw/ + config_key1 + config_key2 + ... + /); + +Or with L: + + use Moose; + has config_key1 => (is => 'rw', default => 'default_value'); + +This code can be added after the md5sum on L +generated schemas. + +At app startup, any non-local options will be passed to these accessors, and can +be accessed as usual via C<< $schema->config_key1 >>. + +These config values go into your C block, along with normal config +values. + +=head1 CREATING RESULTSET CONFIG ATTRIBUTES + +You can create classdata on L classes to hold values +from L config. + +The code for this looks something like this: + + package MySchema::ResultSet::Foo; + + use base 'DBIx::Class::ResultSet'; + + __PACKAGE__->mk_group_accessors(inherited => qw/ + rs_config_key1 + rs_config_key2 + ... + /); + __PACKAGE__->rs_config_key1('default_value'); + +Or, if you prefer L: + + package MySchema::ResultSet::Foo; + + use Moose; + use MooseX::NonMoose; + use MooseX::ClassAttribute; + extends 'DBIx::Class::ResultSet'; + + class_has rs_config_key1 => (is => 'rw', default => 'default_value'); + +In your catalyst config, use the generated Model name as the config key, e.g.: + + + strict_passwords 1 + =cut @@ -43,6 +104,13 @@ after BUILD => sub { my ($self, $args) = @_; $self->_pass_options_to_schema($args); + + for my $source ($self->schema->sources) { + my $config_key = 'Model::' . $self->model_name . '::' . $source; + my $config = $self->app_class->config->{$config_key}; + next unless $config; + $self->_pass_options_to_resultset($source, $config); + } }; sub _delegates { @@ -89,7 +157,26 @@ sub _pass_options_to_schema { for my $opt (keys %$args) { if (not exists $attributes{$opt}) { next unless $self->schema->can($opt); - $self->schema->$opt($self->{$opt}); + $self->schema->$opt($args->{$opt}); + } + } +} + +sub _pass_options_to_resultset { + my ($self, $source, $args) = @_; + + my @attributes = map { + $_->init_arg || () + } $self->meta->get_all_attributes; + + my %attributes; + @attributes{@attributes} = (); + + for my $opt (keys %$args) { + if (not exists $attributes{$opt}) { + my $rs_class = $self->schema->source($source)->resultset_class; + next unless $rs_class->can($opt); + $rs_class->$opt($args->{$opt}); } } } diff --git a/t/09schema_options.t b/t/09schema_options.t index d1e1c80..af1356c 100644 --- a/t/09schema_options.t +++ b/t/09schema_options.t @@ -8,8 +8,10 @@ use Test::More; use Test::Exception; use Catalyst::Model::DBIC::Schema; use ASchemaClass; +use AnotherSchemaClass; -plan tests => 4; +# reusing the same app for 2 models, gets a redefined warning +$SIG{__WARN__} = sub { warn $_[0] unless $_[0] =~ /redefined/ }; ok((my $m = instance(a_schema_option => 'mtfnpy')), 'instance'); @@ -19,8 +21,15 @@ lives_ok { $m->a_schema_option('pass the crack pipe') } 'delegate called'; is $m->schema->a_schema_option, 'pass the crack pipe', 'delegation works'; +ok(($m = instance(schema_class => 'AnotherSchemaClass')), 'instance'); + +is $m->resultset('Users')->rs_config_option, 'configured rs value', + 'ResultSet option passed from config'; + +done_testing; + sub instance { - Catalyst::Model::DBIC::Schema->COMPONENT('MyApp', { + MyApp::Model::DB->COMPONENT('MyApp', { traits => 'SchemaProxy', schema_class => 'ASchemaClass', connect_info => ['dbi:SQLite:foo.db', '', ''], @@ -28,4 +37,17 @@ sub instance { }) } -{ package MyApp; use Catalyst; } +BEGIN { + package MyApp; + use Catalyst; + __PACKAGE__->config({ + 'Model::DB::Users' => { + rs_config_option => 'configured rs value', + }, + }); +} + +{ + package MyApp::Model::DB; + use base 'Catalyst::Model::DBIC::Schema'; +} diff --git a/t/lib/ASchemaClass.pm b/t/lib/ASchemaClass.pm index 09c4f36..db1c6fc 100644 --- a/t/lib/ASchemaClass.pm +++ b/t/lib/ASchemaClass.pm @@ -2,8 +2,9 @@ package ASchemaClass; use base 'DBIx::Class::Schema'; -__PACKAGE__->mk_group_accessors(inherited => 'a_schema_option'); - __PACKAGE__->load_classes; +use Moose; +has a_schema_option => (is => 'rw'); + 1; diff --git a/t/lib/AnotherSchemaClass/ResultSet/Users.pm b/t/lib/AnotherSchemaClass/ResultSet/Users.pm new file mode 100644 index 0000000..f422ff8 --- /dev/null +++ b/t/lib/AnotherSchemaClass/ResultSet/Users.pm @@ -0,0 +1,11 @@ +package AnotherSchemaClass::ResultSet::Users; + +use strict; +use warnings; +use base 'DBIx::Class::ResultSet'; + +__PACKAGE__->mk_group_accessors(inherited => qw/ + rs_config_option +/); + +1;