make schema a delegate for model
Rafael Kitover [Sat, 22 Aug 2009 12:52:35 +0000 (12:52 +0000)]
Changes
Makefile.PL
lib/Catalyst/Model/DBIC/Schema.pm

diff --git a/Changes b/Changes
index 3d71628..e0741a5 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,5 +1,7 @@
 Revision history for Perl extension Catalyst::Model::DBIC::Schema
 
+       - make schema a delegate for model
+
 0.26  Wed Jul 29 16:16:09 PDT 2009
         - fix loading connect_info from schema-defined connection
           (bluefeet, RT 48084)
index 47317b2..cb10ecf 100644 (file)
@@ -13,6 +13,7 @@ requires 'namespace::autoclean';
 requires 'Carp::Clan';
 requires 'List::MoreUtils';
 requires 'Tie::IxHash';
+requires 'Class::Inspector';
 
 test_requires 'Test::More';
 test_requires 'Test::Exception';
index 38a5e52..ab36772 100644 (file)
@@ -12,6 +12,7 @@ use Carp::Clan '^Catalyst::Model::DBIC::Schema';
 use Data::Dumper;
 use DBIx::Class ();
 use Moose::Autobox;
+use Class::Inspector ();
 
 use Catalyst::Model::DBIC::Schema::Types
     qw/ConnectInfo LoadedClass/;
@@ -384,6 +385,15 @@ Traits you used resolved to full class names.
 
 =head1 METHODS
 
+Methods not listed here are delegated to the connected schema used by the model
+instance, so the following are equivalent:
+
+    $c->model('DB')->schema->my_accessor('foo');
+    # or
+    $c->model('DB')->my_accessor('foo');
+
+Methods on the model take precedence over schema methods.
+
 =head2 new
 
 Instantiates the Model based on the above-documented ->config parameters.
@@ -431,8 +441,6 @@ Used often for debugging and controlling transactions.
 
 =cut
 
-has schema => (is => 'rw', isa => 'DBIx::Class::Schema');
-
 has schema_class => (
     is => 'ro',
     isa => LoadedClass,
@@ -451,6 +459,13 @@ has model_name => (
     lazy_build => 1,
 );
 
+# method names delegated to schema
+has _delegates => (
+    is => 'ro',
+    isa => ArrayRef,
+    lazy_build => 1
+);
+
 has _default_cursor_class => (
     is => 'ro',
     isa => LoadedClass,
@@ -485,6 +500,12 @@ sub BUILD {
 
     $self->composed_schema($schema_class->compose_namespace($class));
 
+    $self->meta->add_attribute('schema',
+        is => 'rw',
+        isa => $self->schema_class,
+        handles => $self->_delegates
+    );
+
     $self->schema($self->composed_schema->clone);
 
     $self->schema->storage_type($self->storage_type)
@@ -499,10 +520,6 @@ sub clone { shift->composed_schema->clone(@_); }
 
 sub connect { shift->composed_schema->connect(@_); }
 
-sub storage { shift->schema->storage(@_); }
-
-sub resultset { shift->schema->resultset(@_); }
-
 =head2 setup
 
 Called at C<BUILD>> time before configuration, but after L</connect_info> is
@@ -573,6 +590,24 @@ sub _build_model_name {
     return $model_name;
 }
 
+sub _build__delegates {
+    my $self = shift;
+
+# XXX change this to CMOP once CAG is updated
+    my @schema_methods = @{ Class::Inspector->methods($self->schema_class) };
+
+    my @my_methods     = $self->meta->get_all_method_names;
+    my %my_methods;
+    @my_methods{@my_methods} = ();
+
+    my @delegates;
+    for my $method (@schema_methods) {
+        push @delegates, $method unless exists $my_methods{$method};
+    }
+
+    return \@delegates;
+}
+
 __PACKAGE__->meta->make_immutable;
 
 =head1 SEE ALSO