Refactor the version handling
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI / Pg.pm
index 10e7c5b..4428b1f 100644 (file)
@@ -3,7 +3,9 @@ package DBIx::Class::Storage::DBI::Pg;
 use strict;
 use warnings;
 
-use base qw/DBIx::Class::Storage::DBI::MultiColumnIn/;
+use base qw/
+    DBIx::Class::Storage::DBI::MultiColumnIn
+/;
 use mro 'c3';
 
 use DBD::Pg qw(:pg_types);
@@ -14,69 +16,22 @@ use Context::Preserve ();
 warn __PACKAGE__.": DBD::Pg 2.9.2 or greater is strongly recommended\n"
   if ($DBD::Pg::VERSION < 2.009002);  # pg uses (used?) version::qv()
 
-__PACKAGE__->mk_group_accessors(simple => qw/
-  _auto_cols
-/);
-
-sub _prep_for_execute {
+sub _supports_insert_returning {
   my $self = shift;
-  my ($op, $extra_bind, $ident, $args) = @_;
-
-  if ($op eq 'insert') {
-    $self->_auto_cols([]);
-
-    my %pk;
-    @pk{$ident->primary_columns} = ();
-
-    my @auto_inc_cols = grep {
-      my $inserting = $args->[0]{$_};
-
-      ($ident->column_info($_)->{is_auto_increment}
-        || exists $pk{$_})
-      && (
-        (not defined $inserting)
-        ||
-        (ref $inserting eq 'SCALAR' && $$inserting =~ /^null\z/i)
-      )
-    } $ident->columns;
-
-    if (@auto_inc_cols) {
-      $args->[1]{returning} = \@auto_inc_cols;
 
-      $self->_auto_cols->[0] = \@auto_inc_cols;
-    }
-  }
-
-  return $self->next::method(@_);
-}
-
-sub _execute {
-  my $self = shift;
-  my ($op) = @_;
-
-  my ($rv, $sth, @bind) = $self->dbh_do($self->can('_dbh_execute'), @_);
-
-  if ($op eq 'insert' && $self->_auto_cols) {
-    local $@;
-    my (@auto_cols) = eval {
-      local $SIG{__WARN__} = sub {};
-      $sth->fetchrow_array
-    };
-    $self->_auto_cols->[1] = \@auto_cols;
-    $sth->finish;
-  }
+  return 1
+    if $self->_server_info->{normalized_dbms_version} >= 8.002;
 
-  return wantarray ? ($rv, $sth, @bind) : $rv;
+  return 0;
 }
 
-
 sub with_deferred_fk_checks {
   my ($self, $sub) = @_;
 
   my $txn_scope_guard = $self->txn_scope_guard;
 
   $self->_do_query('SET CONSTRAINTS ALL DEFERRED');
-  
+
   my $sg = Scope::Guard->new(sub {
     $self->_do_query('SET CONSTRAINTS ALL IMMEDIATE');
   });
@@ -85,46 +40,37 @@ sub with_deferred_fk_checks {
     after => sub { $txn_scope_guard->commit });
 }
 
-sub insert {
-  my $self = shift;
+# only used when INSERT ... RETURNING is disabled
+sub last_insert_id {
+  my ($self,$source,@cols) = @_;
 
-  my $updated_cols = $self->next::method(@_);
+  my @values;
 
-  if ($self->_auto_cols->[0]) {
-    my %auto_cols;
-    @auto_cols{ @{ $self->_auto_cols->[0] } } = @{ $self->_auto_cols->[1] };
+  for my $col (@cols) {
+    my $seq = ( $source->column_info($col)->{sequence} ||= $self->dbh_do('_dbh_get_autoinc_seq', $source, $col) )
+      or $self->throw_exception( sprintf(
+        'could not determine sequence for column %s.%s, please consider adding a schema-qualified sequence to its column info',
+          $source->name,
+          $col,
+      ));
 
-    $updated_cols = { %$updated_cols, %auto_cols };
+    push @values, $self->_dbh->last_insert_id(undef, undef, undef, undef, {sequence => $seq});
   }
 
-  return $updated_cols;
-}
-
-sub last_insert_id {
-  my ($self, $source, @cols) = @_;
-  my @result;
-
-  my %auto_cols;
-  @auto_cols{ @{ $self->_auto_cols->[0] } } =
-    @{ $self->_auto_cols->[1] };
-
-  push @result, $auto_cols{$_} for @cols;
-
-  return @result;
+  return @values;
 }
 
 sub _sequence_fetch {
   my ($self, $function, $sequence) = @_;
 
   $self->throw_exception('No sequence to fetch') unless $sequence;
-  
+
   my ($val) = $self->_get_dbh->selectrow_array(
-    sprintf "select $function('%s')",
-      $sequence
+    sprintf ("select %s('%s')", $function, $sequence)
   );
 
   return $val;
-} 
+}
 
 sub _dbh_get_autoinc_seq {
   my ($self, $dbh, $source, $col) = @_;