fixed test resultclass formatting, added a few more DBIC::Storage::DBI methods that...
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI / Replicated.pm
index 465eec0..22f6399 100644 (file)
@@ -7,10 +7,11 @@ BEGIN {
   ## use, so we explicitly test for these.
        
   my %replication_required = (
-    Moose => '0.77',
-    MooseX::AttributeHelpers => '0.12',
-    MooseX::Types => '0.10',
-    namespace::clean => '0.11',
+    'Moose' => '0.77',
+    'MooseX::AttributeHelpers' => '0.12',
+    'MooseX::Types' => '0.10',
+    'namespace::clean' => '0.11',
+    'Hash::Merge' => '0.11'
   );
        
   my @didnt_load;
@@ -33,6 +34,7 @@ use DBIx::Class::Storage::DBI::Replicated::Types 'BalancerClassNamePart';
 use MooseX::Types::Moose qw/ClassName HashRef Object/;
 use Scalar::Util 'reftype';
 use Carp::Clan qw/^DBIx::Class/;
+use Hash::Merge 'merge';
 
 use namespace::clean -except => 'meta';
 
@@ -110,6 +112,7 @@ Replicated Storage has additional requirements not currently part of L<DBIx::Cla
   MooseX::AttributeHelpers => 0.12 
   MooseX::Types => 0.10
   namespace::clean => 0.11
+  Hash::Merge => 0.11
   
 You will need to install these modules manually via CPAN or make them part of the
 Makefile for your distribution.
@@ -285,7 +288,8 @@ has 'write_handler' => (
     create_ddl_dir
     deployment_statements
     datetime_parser
-    datetime_parser_type        
+    datetime_parser_type  
+    build_datetime_parser      
     last_insert_id
     insert
     insert_bulk
@@ -300,10 +304,19 @@ has 'write_handler' => (
     sth
     deploy
     with_deferred_fk_checks
-
+       dbh_do
     reload_row
+       with_deferred_fk_checks
     _prep_for_execute
-    
+
+       backup
+       is_datatype_numeric
+       _count_select
+       _subq_count_select
+       _subq_update_delete 
+       svp_rollback
+       svp_begin
+       svp_release
   /],
 );
 
@@ -321,10 +334,12 @@ C<pool_type>, C<pool_args>, C<balancer_type> and C<balancer_args>.
 around connect_info => sub {
   my ($next, $self, $info, @extra) = @_;
 
+  my $wantarray = wantarray;
+
   my %opts;
   for my $arg (@$info) {
     next unless (reftype($arg)||'') eq 'HASH';
-    %opts = (%opts, %$arg);
+    %opts = %{ merge($arg, \%opts) };
   }
   delete $opts{dsn};
 
@@ -332,10 +347,9 @@ around connect_info => sub {
     $self->pool_type(delete $opts{pool_type})
       if $opts{pool_type};
 
-    $self->pool_args({
-      %{ $self->pool_args },
-      %{ delete $opts{pool_args} || {} }
-    });
+    $self->pool_args(
+      merge((delete $opts{pool_args} || {}), $self->pool_args)
+    );
 
     $self->pool($self->_build_pool)
        if $self->pool;
@@ -345,10 +359,9 @@ around connect_info => sub {
     $self->balancer_type(delete $opts{balancer_type})
       if $opts{balancer_type};
 
-    $self->balancer_args({
-      %{ $self->balancer_args },
-      %{ delete $opts{balancer_args} || {} }
-    });
+    $self->balancer_args(
+      merge((delete $opts{balancer_args} || {}), $self->balancer_args)
+    );
 
     $self->balancer($self->_build_balancer)
        if $self->balancer;
@@ -356,7 +369,20 @@ around connect_info => sub {
 
   $self->_master_connect_info_opts(\%opts);
 
-  $self->$next($info, @extra);
+  my (@res, $res);
+  if ($wantarray) {
+    @res = $self->$next($info, @extra);
+  } else {
+    $res = $self->$next($info, @extra);
+  }
+
+  # Make sure master is blessed into the correct class and apply role to it.
+  my $master = $self->master;
+  $master->_determine_driver;
+  Moose::Meta::Class->initialize(ref $master);
+  DBIx::Class::Storage::DBI::Replicated::WithDSN->meta->apply($master);
+
+  $wantarray ? @res : $res;
 };
 
 =head1 METHODS
@@ -390,7 +416,6 @@ Lazy builder for the L</master> attribute.
 sub _build_master {
   my $self = shift @_;
   my $master = DBIx::Class::Storage::DBI->new($self->schema);
-  DBIx::Class::Storage::DBI::Replicated::WithDSN->meta->apply($master);
   $master
 }
 
@@ -468,11 +493,21 @@ around connect_replicants => sub {
     $r->[$i] = {} unless $r->[$i];
 
 # merge if two hashes
-    my %opts = map %$_, @$r[$i .. $#{$r}];
+    my @hashes = @$r[$i .. $#{$r}];
+
+    croak "invalid connect_info options"
+      if (grep { reftype($_) eq 'HASH' } @hashes) != @hashes;
+
+    croak "too many hashrefs in connect_info"
+      if @hashes > 2;
+
+    my %opts = %{ merge(reverse @hashes) };
+
+# delete them
     splice @$r, $i+1, ($#{$r} - $i), ();
 
 # merge with master
-    %opts = (%{ $self->_master_connect_info_opts }, %opts);
+    %opts = %{ merge(\%opts, $self->_master_connect_info_opts) };
 
 # update
     $r->[$i] = \%opts;
@@ -587,24 +622,11 @@ writea are sent to the master only
 sub set_balanced_storage {
   my $self = shift @_;
   my $schema = $self->schema;
-  my $write_handler = $self->schema->storage->balancer;
+  my $balanced_handler = $self->schema->storage->balancer;
   
-  $schema->storage->read_handler($write_handler);
+  $schema->storage->read_handler($balanced_handler);
 }
 
-=head2 around: txn_do ($coderef)
-
-Overload to the txn_do method, which is delegated to whatever the
-L<write_handler> is set to.  We overload this in order to wrap in inside a
-L</execute_reliably> method.
-
-=cut
-
-around 'txn_do' => sub {
-  my($txn_do, $self, $coderef, @args) = @_;
-  $self->execute_reliably(sub {$self->$txn_do($coderef, @args)}); 
-};
-
 =head2 connected
 
 Check that the master and at least one of the replicants is connected.