use min dbms_version for ::Replicated
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI / Replicated.pm
index 7e84f7c..37f13d7 100644 (file)
@@ -14,7 +14,7 @@ use DBIx::Class::Storage::DBI::Replicated::Balancer;
 use DBIx::Class::Storage::DBI::Replicated::Types qw/BalancerClassNamePart DBICSchema DBICStorageDBI/;
 use MooseX::Types::Moose qw/ClassName HashRef Object/;
 use Scalar::Util 'reftype';
-use Hash::Merge 'merge';
+use Hash::Merge;
 use List::Util qw/min max/;
 
 use namespace::clean -except => 'meta';
@@ -306,6 +306,7 @@ has 'write_handler' => (
 
     backup
     is_datatype_numeric
+    _supports_insert_returning
     _count_select
     _subq_count_select
     _subq_update_delete
@@ -365,9 +366,12 @@ has 'write_handler' => (
     _do_query
     _dbh_sth
     _dbh_execute
+    _prefetch_insert_auto_nextvals
+    _server_info_hash
   /],
 );
 
+
 has _master_connect_info_opts =>
   (is => 'rw', isa => HashRef, default => sub { {} });
 
@@ -384,10 +388,12 @@ around connect_info => sub {
 
   my $wantarray = wantarray;
 
+  my $merge = Hash::Merge->new('LEFT_PRECEDENT');
+
   my %opts;
   for my $arg (@$info) {
     next unless (reftype($arg)||'') eq 'HASH';
-    %opts = %{ merge($arg, \%opts) };
+    %opts = %{ $merge->merge($arg, \%opts) };
   }
   delete $opts{dsn};
 
@@ -396,7 +402,7 @@ around connect_info => sub {
       if $opts{pool_type};
 
     $self->pool_args(
-      merge((delete $opts{pool_args} || {}), $self->pool_args)
+      $merge->merge((delete $opts{pool_args} || {}), $self->pool_args)
     );
 
     $self->pool($self->_build_pool)
@@ -408,7 +414,7 @@ around connect_info => sub {
       if $opts{balancer_type};
 
     $self->balancer_args(
-      merge((delete $opts{balancer_args} || {}), $self->balancer_args)
+      $merge->merge((delete $opts{balancer_args} || {}), $self->balancer_args)
     );
 
     $self->balancer($self->_build_balancer)
@@ -553,7 +559,8 @@ around connect_replicants => sub {
     $self->throw_exception('too many hashrefs in connect_info')
       if @hashes > 2;
 
-    my %opts = %{ merge(reverse @hashes) };
+    my $merge = Hash::Merge->new('LEFT_PRECEDENT');
+    my %opts = %{ $merge->merge(reverse @hashes) };
 
 # delete them
     splice @$r, $i+1, ($#{$r} - $i), ();
@@ -566,7 +573,7 @@ around connect_replicants => sub {
     delete $master_opts{dbh_maker};
 
 # merge with master
-    %opts = %{ merge(\%opts, \%master_opts) };
+    %opts = %{ $merge->merge(\%opts, \%master_opts) };
 
 # update
     $r->[$i] = \%opts;
@@ -1003,6 +1010,33 @@ sub _ping {
   return min map $_->_ping, $self->all_storages;
 }
 
+sub _server_info {
+  my $self = shift;
+
+  if (not $self->_server_info_hash) {
+    no warnings 'numeric'; # in case dbms_version doesn't normalize
+
+    my @infos = 
+      map $_->[1],
+      sort { $a->[0] <=> $b->[0] } 
+      map [ (defined $_->{normalized_dbms_version} ? $_->{normalized_dbms_version}
+              : $_->{dbms_version}), $_ ],
+      map $_->_server_info, $self->all_storages;
+
+    my $min_version_info = $infos[0];
+
+    $self->_server_info_hash($min_version_info); # on master
+  }
+
+  return $self->_server_info_hash;
+}
+
+sub _get_server_version {
+  my $self = shift;
+
+  return $self->_server_info->{dbms_version};
+}
+
 =head1 GOTCHAS
 
 Due to the fact that replicants can lag behind a master, you must take care to