X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FCatalyst%2FModel%2FDBIC%2FSchema.pm;h=2e4ed99c988c9ee51cc9fbb0df6e2953b61c4193;hb=41bcf32fb6ca94efe78f9b67d564357dbf291b1f;hp=9c5c2f52bd969c5ad43a62561b1114c2c605563a;hpb=a75b6e588e4dfc332d5d6b342ca6386c550b7092;p=catagits%2FCatalyst-Model-DBIC-Schema.git diff --git a/lib/Catalyst/Model/DBIC/Schema.pm b/lib/Catalyst/Model/DBIC/Schema.pm index 9c5c2f5..2e4ed99 100644 --- a/lib/Catalyst/Model/DBIC/Schema.pm +++ b/lib/Catalyst/Model/DBIC/Schema.pm @@ -3,7 +3,6 @@ package Catalyst::Model::DBIC::Schema; use Moose; use mro 'c3'; extends 'Catalyst::Model'; -with 'MooseX::Object::Pluggable'; our $VERSION = '0.24'; @@ -13,11 +12,12 @@ use DBIx::Class (); use Scalar::Util 'reftype'; use MooseX::ClassAttribute; use Moose::Autobox; +use Moose::Util (); use Catalyst::Model::DBIC::Schema::Types qw/ConnectInfo SchemaClass CursorClass/; -use MooseX::Types::Moose qw/ArrayRef Str ClassName/; +use MooseX::Types::Moose qw/ArrayRef Str ClassName Undef/; use namespace::clean -except => 'meta'; @@ -240,11 +240,11 @@ Or using L: schema_class MyApp::Schema::FilmDB - roles Caching + traits Caching dsn dbi:Pg:dbname=mypgdb user postgres - password '' + password "" auto_savepoint 1 quote_char """ on_connect_do some SQL statement @@ -292,36 +292,35 @@ supported: } ] -=head2 roles +=head2 traits -Array of Roles to apply at BUILD time. Roles are relative to the -C< then C<> -namespaces, unless prefixed with C<+> in which case they are taken to be a -fully qualified name. E.g.: +Array of Traits to apply to the instance. Traits are Ls. - roles Caching - roles +MyApp::DB::Role::Foo +They are relative to the C<< MyApp::Model::DB::Trait:: >>, then the C<< +Catalyst::Model::DBIC::Schema::Trait:: >> namespaces, unless prefixed with C<+> +in which case they are taken to be a fully qualified name. E.g.: -This is done using L. + traits Caching + traits +MyApp::DB::Trait::Foo A new instance is created at application time, so any consumed required attributes, coercions and modifiers will work. -Roles are applied before setup, schema and connection are set. +Traits are applied before setup, schema and connection are set. -C will be an anon class if any roles are applied. +C will be an anon class if any traits are applied, C<< +$self->_original_class_name >> will be the original class. -You cannot modify C or C, modify C instead. +You cannot modify C in a trait, as that is when traits are applied, +modify L instead. -L and L can also be modified. - -Roles that come with the distribution: +Traits that come with the distribution: =over 4 -=item L +=item L -=item L +=item L =back @@ -381,28 +380,20 @@ Used often for debugging and controlling transactions. =cut -class_has 'composed_schema' => (is => 'rw', isa => 'DBIx::Class::Schema'); - -has 'schema' => (is => 'rw', isa => 'DBIx::Class::Schema'); +has schema => (is => 'rw', isa => 'DBIx::Class::Schema'); -has 'schema_class' => ( +has schema_class => ( is => 'ro', isa => SchemaClass, coerce => 1, required => 1 ); -has 'storage_type' => (is => 'rw', isa => Str); - -has 'connect_info' => (is => 'ro', isa => ConnectInfo, coerce => 1); +has storage_type => (is => 'rw', isa => Str); -# ref $self changes to anon after roles are applied, and _original_class_name is -# broken in MX::O::P 0.0009 -has '_class_name' => (is => 'ro', isa => ClassName, default => sub { - ref shift -}); +has connect_info => (is => 'ro', isa => ConnectInfo, coerce => 1); -has 'model_name' => (is => 'ro', isa => Str, default => sub { +has model_name => (is => 'ro', isa => Str, default => sub { my $self = shift; my $class = ref $self; @@ -411,15 +402,24 @@ has 'model_name' => (is => 'ro', isa => Str, default => sub { $model_name }); -has 'roles' => (is => 'ro', isa => ArrayRef|Str); +has traits => (is => 'ro', isa => ArrayRef|Str); + +has _trait_fqns => (is => 'ro', isa => ArrayRef|Undef, lazy_build => 1); -has '_default_cursor_class' => ( +has _default_cursor_class => ( is => 'ro', isa => CursorClass, default => 'DBIx::Class::Storage::DBI::Cursor', coerce => 1 ); +has _original_class_name => ( + is => 'ro', + required => 1, + isa => Str, + default => sub { blessed $_[0] }, +); + sub BUILD { my $self = shift; my $class = ref $self; @@ -443,9 +443,8 @@ sub BUILD { . " ".$self->connect_info->{cursor_class}.": $@"; } - $self->_plugin_ns('Role'); - - $self->load_plugins($self->roles->flatten) if $self->roles; + Moose::Util::apply_all_roles($self, $self->_trait_fqns->flatten) + if $self->_trait_fqns; $self->setup; @@ -469,9 +468,11 @@ sub connect { shift->composed_schema->connect(@_); } sub storage { shift->schema->storage(@_); } +sub resultset { shift->schema->resultset(@_); } + =head2 setup -Called at C<> time before configuration. +Called at C> time before configuration. =cut @@ -487,7 +488,7 @@ sub finalize { 1 } =head2 ACCEPT_CONTEXT -Point of extension for doing things at C<<$c->model>> time, returns the model +Point of extension for doing things at C<< $c->model >> time, returns the model instance, see L for more information. =cut @@ -496,7 +497,7 @@ sub ACCEPT_CONTEXT { shift } sub _install_rs_models { my $self = shift; - my $class = $self->_class_name; + my $class = $self->_original_class_name; no strict 'refs'; @@ -523,6 +524,50 @@ sub _reset_cursor_class { } } +{ + my %COMPOSED_CACHE; + + sub composed_schema { + my $self = shift; + my $class = $self->_original_class_name; + my $store = \$COMPOSED_CACHE{$class}{$self->schema_class}; + + $$store = shift if @_; + + return $$store + } +} + +sub _build__trait_fqns { + my $self = shift; + my $class = $self->_original_class_name; + my $base = 'Trait'; + + my @names = $self->traits->flatten if $self->traits; + return unless @names; + + my @search_ns = grep !/^(?:Moose|Class::MOP)::/, + $class->meta->class_precedence_list; + + my @traits; + + OUTER: for my $name (@names) { + if ($name =~ /^\+(.*)/) { + push @traits, $1; + next; + } + for my $ns (@search_ns) { + my $full = "${ns}::${base}::${name}"; + if (eval { Class::MOP::load_class($full) }) { + push @traits, $full; + next OUTER; + } + } + } + + return @traits ? \@traits : undef; +} + __PACKAGE__->meta->make_immutable; =head1 SEE ALSO @@ -538,10 +583,10 @@ L, L, L, L, L -Roles: +Traits: -L, -L +L, +L =head1 AUTHOR @@ -549,7 +594,7 @@ Brandon L Black, C Contributors: -Rafael Kitover, C<> +Rafael Kitover, C =head1 COPYRIGHT @@ -559,3 +604,4 @@ under the same terms as Perl itself. =cut 1; +# vim:sts=4 sw=4: