Author: timbo
Date: Sat Jul 10 14:15:09 2004
New Revision: 379

Modified:
   dbi/trunk/Changes
   dbi/trunk/DBI.pm
   dbi/trunk/ToDo
   dbi/trunk/t/15array.t
Log:
Changed bind_param_array() so it doesn't require all bind arrays
  to have the same number of elements.
Changed execute_array() definition, and default implementation,
  to effectively NULL-pad shorter bind arrays.
Changed execute_array() to return "0E0" for 0 as per the docs.
Changed execute_for_fetch() definition, and default implementation,
  to return "0E0" for 0 like execute() and execute_array().


Modified: dbi/trunk/Changes
==============================================================================
--- dbi/trunk/Changes   (original)
+++ dbi/trunk/Changes   Sat Jul 10 14:15:09 2004
@@ -4,6 +4,16 @@
 
 =cut
 
+=head1 CHANGES in DBI 1.44 (svn rev ???),    XXX
+
+  Changed bind_param_array() so it doesn't require all bind arrays
+    to have the same number of elements.
+  Changed execute_array() definition, and default implementation,
+    to effectively NULL-pad shorter bind arrays.
+  Changed execute_array() to return "0E0" for 0 as per the docs.
+  Changed execute_for_fetch() definition, and default implementation,
+    to return "0E0" for 0 like execute() and execute_array().
+
 =head1 CHANGES in DBI 1.43 (svn rev 377),    2nd July 2004
 
   Fixed connect() and connect_cached() RaiseError/PrintError
@@ -30,7 +40,7 @@
   Changed all tests to use Test::More and enhanced the tests thanks
     to Stevan Little and Andy Lester. See http://qa.perl.org/phalanx/
   Changed Test::More minimum prerequisite version to 0.40 (2001).
-  Change DBI::Profile header to include timestamp.
+  Changed DBI::Profile header to include the date and time.
 
   Added DBI->parse_dsn($dsn) method.
   Added warning if build directory path contains whitespace.

Modified: dbi/trunk/DBI.pm
==============================================================================
--- dbi/trunk/DBI.pm    (original)
+++ dbi/trunk/DBI.pm    Sat Jul 10 14:15:09 2004
@@ -1655,19 +1655,6 @@
        # get/create arrayref to hold params
        my $hash_of_arrays = $sth->{ParamArrays} ||= { };
 
-       if (ref $value_array eq 'ARRAY') {
-           # check that input has same length as existing
-           # find first arrayref entry (if any)
-           foreach (keys %$hash_of_arrays) {
-               my $v = $$hash_of_arrays{$_};
-               next unless ref $v eq 'ARRAY';
-               return $sth->set_err(1,
-                       "Arrayref for parameter $p_id has "[EMAIL PROTECTED]" elements"
-                       ." but parameter $_ has "[EMAIL PROTECTED])
-                   if @$value_array != @$v;
-           }
-       }
-
        # If the bind has attribs then we rely on the driver conforming to
        # the DBI spec in that a single bind_param() call with those attribs
        # makes them 'sticky' and apply to all later execute(@values) calls.
@@ -1763,17 +1750,18 @@
                if defined($NUM_OF_PARAMS) && $NUM_OF_PARAMS != $NUM_OF_PARAMS_given;
 
            # get the length of a bound array
-           my $len = 1; # in case all are scalars
+           my $maxlen = 0;
            my %hash_of_arrays = %{$sth->{ParamArrays}};
            foreach (keys(%hash_of_arrays)) {
                my $ary = $hash_of_arrays{$_};
-               $len = @$ary if ref $ary eq 'ARRAY';
+               my $len = (ref $ary eq 'ARRAY') ? @$ary : 1;
+               $maxlen = $len if $len > $maxlen;
            }
            my @bind_ids = 1..keys(%hash_of_arrays);
 
            my $tuple_idx = 0;
            $fetch_tuple_sub = sub {
-               return if $tuple_idx >= $len;
+               return if $tuple_idx >= $maxlen;
                my @tuple = map {
                    my $a = $hash_of_arrays{$_};
                    ref($a) ? $a->[$tuple_idx] : $a
@@ -1802,7 +1790,7 @@
                push @$tuple_status, [ $err, $errstr_cache{$err} ||= $sth->errstr, 
$sth->state ];
            }
        }
-       return ($err_count) ? undef : scalar @$tuple_status;
+       return ($err_count) ? undef : scalar(@$tuple_status)||"0E0";
     }
 
 
@@ -4884,10 +4872,6 @@
 WHERE bar IN (?)".  A placeholder can only ever represent one value
 per execution.)
 
-Each array bound to the statement must have the same number of
-elements.  Some drivers may define a method attribute to relax this
-safety check.
-
 Scalar values, including C<undef>, may also be bound by
 C<bind_param_array>. In which case the same value will be used for each
 L</execute> call. Driver-specific implementations may behave
@@ -4903,7 +4887,7 @@
 documentation as there may be driver specific issues to consider.
 
 Note that the default implementation currently only supports non-data
-returning statements (insert, update, but not select). Also,
+returning statements (INSERT, UPDATE, but not SELECT). Also,
 C<bind_param_array> and L</bind_param> cannot be mixed in the same
 statement execution, and C<bind_param_array> must be used with
 L</execute_array>; using C<bind_param_array> will have no effect
@@ -4963,9 +4947,16 @@
 attribute below for how to determine the execution status for each
 tuple.
 
-Bind values for the tuples to be executed may be supplied by an
-C<ArrayTupleFetch> attribute, or else in the C<@bind_values> argument,
-or else by prior calls to L</bind_param_array>.
+Bind values for the tuples to be executed may be supplied row-wise
+by an C<ArrayTupleFetch> attribute, or else column-wise in the
+C<@bind_values> argument, or else column-wise by prior calls to
+L</bind_param_array>.
+
+Where column-wise binding is used (via the C<@bind_values> argument
+or calls to bind_param_array()) the maximum number of elements in
+any one of the bound value arrays determines the number of tuples
+executed. Placeholders with fewer values in their parameter arrays
+are treated as if padded with undef (NULL) values.
 
 The C<ArrayTupleFetch> attribute can be used to specify a reference
 to a subroutine that will be called to provide the bind values for
@@ -5031,7 +5022,7 @@
       }
   }
 
-Support for data returning statements, i.e., select, is driver-specific
+Support for data returning statements such as SELECT is driver-specific
 and subject to change. At present, the default implementation
 provided by DBI only supports non-data returning statements.
 
@@ -5071,9 +5062,11 @@
 parameters, until it returns a false value. Each tuple returned is
 used to provide bind values for an $sth->execute(@$tuple) call.
 
-The number of tuples executed is returned I<only if> there were no errors.
 If there were any errors then C<undef> is returned and the @tuple_status
 array can be used to discover which tuples failed and with what errors.
+If there were no errors then execute_for_fetch() returns the number
+of tuples executed. Like execute() and execute_array() a zero is
+returned as "0E0" so execute_for_fetch() is only false on error.
 
 If [EMAIL PROTECTED] is passed then the execute_for_fetch method uses
 it to return status information. The tuple_status array holds one

Modified: dbi/trunk/ToDo
==============================================================================
--- dbi/trunk/ToDo      (original)
+++ dbi/trunk/ToDo      Sat Jul 10 14:15:09 2004
@@ -415,8 +415,12 @@
 
 Add %time to per-node DBI::Profile dump
 
-DBI::Profile: some way to get count of 'executions' only, not all method calls.
-So avg time is totaltime/executions not totaltime/methodcalls.
+Add 'executer' and 'fetcher' method attributes and increment
+corresponding counters in DBIS when method with those attributes
+are called. When profiling record in the profile data the amount
+they have incremented.
+Add DBI_PROFILE option so count is executions and avg time can be
+totaltime/executions not totaltime/methodcalls.
 
 DBI::Profile: add simple way to normalise the sql (convert constants
 to placeholders) so profiling is more effective for drivers/applications

Modified: dbi/trunk/t/15array.t
==============================================================================
--- dbi/trunk/t/15array.t       (original)
+++ dbi/trunk/t/15array.t       Sat Jul 10 14:15:09 2004
@@ -2,7 +2,7 @@
 
 use strict;
 
-use Test::More tests => 42;
+use Test::More tests => 47;
 
 ## ----------------------------------------------------------------------------
 ## 15array.t
@@ -24,6 +24,7 @@
 # check that our db handle is good
 isa_ok($dbh, "DBI::db");
 
+my $rv;
 my $rows         = [];
 my $tuple_status = [];
 my $dumped;
@@ -97,12 +98,26 @@
 # --- with no values for bind params, should execute zero times
 
 @$rows = ();
-ok(!$sth->execute_array( { ArrayTupleStatus => $tuple_status }, [], [], [], []), '... 
execute_array should return false');
+$rv = $sth->execute_array( { ArrayTupleStatus => $tuple_status }, [], [], [], []);
+ok($rv,   '... execute_array should return true');
+ok(!($rv+0), '... execute_array should return 0 (but true)');
 
 cmp_ok(scalar @{$rows}, '==', 0, '... we should have 0 rows');
 cmp_ok(scalar @{$tuple_status}, '==', 0,'... we should have 0 tuple_status');
 
 # -----------------------------------------------
+# --- with only scalar values for bind params, should execute just once
+
[EMAIL PROTECTED] = ();
+$rv = $sth->execute_array( { ArrayTupleStatus => $tuple_status }, 5, 6, 7, 8);
+cmp_ok($rv, '==', 1,   '... execute_array should return 1');
+
+cmp_ok(scalar @{$rows}, '==', 1, '... we should have 1 rows');
+ok(eq_array( $rows, [ [5,6,7,8] ]), '... our rows are as expected');
+cmp_ok(scalar @{$tuple_status}, '==', 1,'... we should have 1 tuple_status');
+ok(eq_array( $tuple_status, [1]), '... our tuple_status is as expected');
+
+# -----------------------------------------------
 # --- catch 'undefined value' bug with zero bind values
 
 @$rows = ();
@@ -113,7 +128,9 @@
 
 isa_ok($sth_other, "DBI::st");
 
-ok(!$sth_other->execute_array( {}, [] ), '... execute_array should return false'); 
+$rv = $sth_other->execute_array( {}, [] );
+ok($rv,   '... execute_array should return true');
+ok(!($rv+0), '... execute_array should return 0 (but true)');
 # no ArrayTupleStatus
 
 cmp_ok(scalar @{$rows}, '==', 0, '... we should have 0 rows');
@@ -206,9 +223,6 @@
 ok(!defined $sth->execute_array( { ArrayTupleStatus => $tuple_status }, 1,{},3,4), 
'... execute_array should return undef');
 is( $sth->errstr, 'Value for parameter 2 must be a scalar or an arrayref, not a 
HASH', '... errstr is as expected');
 
-ok(!defined $sth->execute_array( { ArrayTupleStatus => $tuple_status }, 
1,[1],[2,2],3), '... execute_array should return undef');
-is( $sth->errstr, 'Arrayref for parameter 3 has 2 elements but parameter 2 has 1', 
'... errstr is as expected');
-
 ok(!defined $sth->bind_param_array(":foo", [ qw(a b c) ]), '... bind_param_array 
should return undef');
 is( $sth->errstr, "Can't use named placeholders for non-driver supported 
bind_param_array", '... errstr is as expected');
 

Reply via email to