Another overhaul of transaction/savepoint handling
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI / Pg.pm
index 50a1112..f4dbda6 100644 (file)
@@ -8,16 +8,14 @@ use base qw/
 /;
 use mro 'c3';
 
-use DBD::Pg qw(:pg_types);
 use Scope::Guard ();
 use Context::Preserve 'preserve_context';
+use DBIx::Class::Carp;
 use namespace::clean;
 
 __PACKAGE__->sql_limit_dialect ('LimitOffset');
-
-# Ask for a DBD::Pg with array support
-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__->sql_quote_char ('"');
+__PACKAGE__->datetime_parser_type ('DateTime::Format::Pg');
 
 sub _determine_supports_insert_returning {
   return shift->_server_info->{normalized_dbms_version} >= 8.002
@@ -68,7 +66,7 @@ sub _sequence_fetch {
   $self->throw_exception('No sequence to fetch') unless $sequence;
 
   my ($val) = $self->_get_dbh->selectrow_array(
-    sprintf ("select %s('%s')", $function, $sequence)
+    sprintf ("select %s('%s')", $function, (ref $sequence eq 'SCALAR') ? $$sequence : $sequence)
   );
 
   return $val;
@@ -165,40 +163,43 @@ sub sqlt_type {
   return 'PostgreSQL';
 }
 
-sub datetime_parser_type { return "DateTime::Format::Pg"; }
-
+my $type_cache;
 sub bind_attribute_by_data_type {
   my ($self,$data_type) = @_;
 
-  my $bind_attributes = {
-    bytea => { pg_type => DBD::Pg::PG_BYTEA },
-    blob  => { pg_type => DBD::Pg::PG_BYTEA },
-  };
-
-  if( defined $bind_attributes->{$data_type} ) {
-    return $bind_attributes->{$data_type};
+  # Ask for a DBD::Pg with array support
+  # pg uses (used?) version::qv()
+  require DBD::Pg;
+  if ($DBD::Pg::VERSION < 2.009002) {
+    carp_once( __PACKAGE__.": DBD::Pg 2.9.2 or greater is strongly recommended\n" );
   }
-  else {
-    return;
+
+  # cache the result of _is_binary_lob_type
+  if (!exists $type_cache->{$data_type}) {
+    $type_cache->{$data_type} = $self->_is_binary_lob_type($data_type)
+      ? +{ pg_type => DBD::Pg::PG_BYTEA() }
+      : undef
   }
+
+  $type_cache->{$data_type};
 }
 
-sub _svp_begin {
+sub _exec_svp_begin {
     my ($self, $name) = @_;
 
-    $self->_get_dbh->pg_savepoint($name);
+    $self->_dbh->pg_savepoint($name);
 }
 
-sub _svp_release {
+sub _exec_svp_release {
     my ($self, $name) = @_;
 
-    $self->_get_dbh->pg_release($name);
+    $self->_dbh->pg_release($name);
 }
 
-sub _svp_rollback {
+sub _exec_svp_rollback {
     my ($self, $name) = @_;
 
-    $self->_get_dbh->pg_rollback_to($name);
+    $self->_dbh->pg_rollback_to($name);
 }
 
 sub deployment_statements {