Rewrite hot-ish _dbi_attrs_for_bind codepath in a leaner way
Peter Rabbitson [Sun, 15 Feb 2015 10:08:01 +0000 (11:08 +0100)]
Document various caveats better

lib/DBIx/Class/Storage/DBI.pm
lib/DBIx/Class/Storage/DBI/ADO/Microsoft_SQL_Server.pm
lib/DBIx/Class/Storage/DBI/Oracle/Generic.pm

index 4e67f1b..990800a 100644 (file)
@@ -1773,31 +1773,28 @@ sub _query_end {
 }
 
 sub _dbi_attrs_for_bind {
-  my ($self, $ident, $bind) = @_;
+  #my ($self, $ident, $bind) = @_;
 
-  my @attrs;
+  return [ map {
 
-  for (map { $_->[0] } @$bind) {
-    push @attrs, do {
-      if (exists $_->{dbd_attrs}) {
-        $_->{dbd_attrs}
-      }
-      elsif($_->{sqlt_datatype}) {
-        # cache the result in the dbh_details hash, as it can not change unless
-        # we connect to something else
-        my $cache = $self->_dbh_details->{_datatype_map_cache} ||= {};
-        if (not exists $cache->{$_->{sqlt_datatype}}) {
-          $cache->{$_->{sqlt_datatype}} = $self->bind_attribute_by_data_type($_->{sqlt_datatype}) || undef;
-        }
-        $cache->{$_->{sqlt_datatype}};
-      }
-      else {
-        undef;  # always push something at this position
-      }
-    }
-  }
+    exists $_->{dbd_attrs}  ?  $_->{dbd_attrs}
+
+  : ! $_->{sqlt_datatype}   ? undef
+
+  :                           do {
+
+    # cache the result in the dbh_details hash, as it (usually) can not change
+    # unless we connect to something else
+    # FIXME: for the time being Oracle is an exception, pending a rewrite of
+    # the LOB storage
+    my $cache = $_[0]->_dbh_details->{_datatype_map_cache} ||= {};
+
+    $cache->{$_->{sqlt_datatype}} = $_[0]->bind_attribute_by_data_type($_->{sqlt_datatype})
+      if ! exists $cache->{$_->{sqlt_datatype}};
+
+    $cache->{$_->{sqlt_datatype}};
 
-  return \@attrs;
+  } } map { $_->[0] } @{$_[2]} ];
 }
 
 sub _execute {
index cd28c62..ac42a1e 100644 (file)
@@ -182,9 +182,11 @@ sub _dbi_attrs_for_bind {
 
   my $attrs = $self->next::method(@_);
 
-  foreach my $attr (@$attrs) {
-    $attr->{ado_size} ||= 8000 if $attr;
-  }
+  # The next::method above caches the returned hashrefs in a _dbh related
+  # structure. It is safe for us to modify it in this manner, as the default
+  # does not really change (albeit the entire logic is insane and is pending
+  # a datatype-objects rewrite)
+  $_ and $_->{ado_size} ||= 8000 for @$attrs;
 
   return $attrs;
 }
index 636e40e..1780d51 100644 (file)
@@ -422,6 +422,7 @@ sub _dbi_attrs_for_bind {
   # Push the column name into all bind attrs, make sure to *NOT* write into
   # the existing $attrs->[$idx]{..} hashref, as it is cached by the call to
   # next::method above.
+  # FIXME - this code will go away when the LobWriter refactor lands
   $attrs->[$_]
     and
   keys %{ $attrs->[$_] }