Start caching the result of various bind_attribute_by_data_type invocations
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI / Pg.pm
index f4dbda6..371f185 100644 (file)
@@ -11,6 +11,7 @@ use mro 'c3';
 use Scope::Guard ();
 use Context::Preserve 'preserve_context';
 use DBIx::Class::Carp;
+use Try::Tiny;
 use namespace::clean;
 
 __PACKAGE__->sql_limit_dialect ('LimitOffset');
@@ -163,25 +164,34 @@ sub sqlt_type {
   return 'PostgreSQL';
 }
 
-my $type_cache;
 sub bind_attribute_by_data_type {
   my ($self,$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" );
+  if ($self->_is_binary_lob_type($data_type)) {
+    # this is a hot-ish codepath, use an escape flag to minimize
+    # amount of function/method calls
+    # additionally version.pm is cock, and memleaks on multiple
+    # ->VERSION calls
+    # the flag is stored in the DBD namespace, so that Class::Unload
+    # will work (unlikely, but still)
+    unless ($DBD::Pg::__DBIC_DBD_VERSION_CHECK_DONE__) {
+      if ($self->_server_info->{normalized_dbms_version} >= 9.0) {
+        try { DBD::Pg->VERSION('2.17.2'); 1 } or carp (
+          __PACKAGE__.': BYTEA columns are known to not work on Pg >= 9.0 with DBD::Pg < 2.17.2'
+        );
+      }
+      elsif (not try { DBD::Pg->VERSION('2.9.2'); 1 } ) { carp (
+        __PACKAGE__.': DBD::Pg 2.9.2 or greater is strongly recommended for BYTEA column support'
+      )}
+
+      $DBD::Pg::__DBIC_DBD_VERSION_CHECK_DONE__ = 1;
+    }
+
+    return { pg_type => DBD::Pg::PG_BYTEA() };
   }
-
-  # 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
+  else {
+    return undef;
   }
-
-  $type_cache->{$data_type};
 }
 
 sub _exec_svp_begin {