X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FStorage%2FDBI%2FReplicated.pm;h=22f6399a30520425f2445e3abe26c2d906fd9142;hb=7fb60fb192f4df2341b17e2b877eecd5f5dadd5a;hp=d6eb2fdd42194723123e35392c97a0fd81ac2b7a;hpb=ee356d004e088518205ac720b37c31a64c9cd861;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/Storage/DBI/Replicated.pm b/lib/DBIx/Class/Storage/DBI/Replicated.pm index d6eb2fd..22f6399 100644 --- a/lib/DBIx/Class/Storage/DBI/Replicated.pm +++ b/lib/DBIx/Class/Storage/DBI/Replicated.pm @@ -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 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, C, C and C. 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,29 +347,42 @@ 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); + $self->pool($self->_build_pool) + if $self->pool; } if (@opts{qw/balancer_type balancer_args/}) { $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); + $self->balancer($self->_build_balancer) + if $self->balancer; } $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 @@ -388,7 +416,6 @@ Lazy builder for the L 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 } @@ -466,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; @@ -585,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 is set to. We overload this in order to wrap in inside a -L 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.