Author: REHSACK
Date: Mon Jul  4 23:47:42 2011
New Revision: 14895

Modified:
   dbi/branches/sqlengine/   (props changed)
   dbi/branches/sqlengine/Changes
   dbi/branches/sqlengine/DBI.pm
   dbi/branches/sqlengine/DBI.xs
   dbi/branches/sqlengine/DBIXS.h
   dbi/branches/sqlengine/Driver.xst
   dbi/branches/sqlengine/TODO_2005.txt
   dbi/branches/sqlengine/dbixs_rev.h
   dbi/branches/sqlengine/lib/DBD/NullP.pm
   dbi/branches/sqlengine/lib/DBI/DBD.pm
   dbi/branches/sqlengine/lib/DBI/DBD/SqlEngine.pm
   dbi/branches/sqlengine/t/08keeperr.t
   dbi/branches/sqlengine/t/09trace.t
   dbi/branches/sqlengine/t/10examp.t
   dbi/branches/sqlengine/t/51dbm_file.t

Log:
merge DBI/trunk from r14623 to r14894


Modified: dbi/branches/sqlengine/Changes
==============================================================================
--- dbi/branches/sqlengine/Changes      (original)
+++ dbi/branches/sqlengine/Changes      Mon Jul  4 23:47:42 2011
@@ -6,6 +6,23 @@
 
 =cut
 
+=head2 Changes in DBI 1.617 (svn rXXX)
+
+  Added pod for default_user to DBI::DBD (Martin J. Evans)
+  Fixed ParamTypes example in the pod (Martin J. Evans)
+  Fixed the definition of ArrayTupleStatus and remove confusion over
+    rows affected in list context of execute_array (Martin J. Evans)
+  Fixed sql_type_cast example and typo in errors (Martin J. Evans)
+  Fixed parameter-count check for complicated statements using
+    DBI::DBD::SqlEngine + SQL::Statement::Param (H.Merijn Brand)
+
+  Enhanced and standardized driver trace level mechanism (Tim Bunce)
+  Removed old code that was an inneffective attempt to detect
+    people doing DBI->{Attrib}.
+
+  Added CON, ENC and DBD trace flags and extended 09trace.t (Martin J. Evans)
+  Added TXN trace flags and applied CON and TXN to relevant methods (Tim Bunce)
+
 =head2 Changes in DBI 1.616 (svn r14616) 30th December 2010
 
   Fixed spurious dbi_profile lines written to the log when

Modified: dbi/branches/sqlengine/DBI.pm
==============================================================================
--- dbi/branches/sqlengine/DBI.pm       (original)
+++ dbi/branches/sqlengine/DBI.pm       Mon Jul  4 23:47:42 2011
@@ -245,7 +245,7 @@
    ) ], # notionally "in" DBI::Profile and normally imported from there
 );
 
-$DBI::dbi_debug = 0;
+$DBI::dbi_debug = 0;          # mixture of bit fields and int sub-fields
 $DBI::neat_maxlen = 1000;
 $DBI::stderr = 2_000_000_000; # a very round number below 2**31
 
@@ -308,13 +308,6 @@
 sub DBI::var::TIESCALAR{ my $var = $_[1]; bless \$var, 'DBI::var'; }
 sub DBI::var::STORE    { Carp::croak("Can't modify \$DBI::${$_[0]} special 
variable") }
 
-{   # used to catch DBI->{Attrib} mistake
-    sub DBI::DBI_tie::TIEHASH { bless {} }
-    sub DBI::DBI_tie::STORE   { Carp::carp("DBI->{$_[1]} is invalid syntax 
(you probably want \$h->{$_[1]})");}
-    *DBI::DBI_tie::FETCH = \&DBI::DBI_tie::STORE;
-}
-tie %DBI::DBI => 'DBI::DBI_tie';
-
 # --- Driver Specific Prefix Registry ---
 
 my $dbd_prefix_registry = {
@@ -414,21 +407,21 @@
         visit_child_handles => { U => [2,3,'$coderef [, $info ]'], O=>0x0404, 
T=>4 },
     },
     dr => {            # Database Driver Interface
-       'connect'  =>   { U =>[1,5,'[$db [,$user [,$passwd [,\%attr]]]]'], 
H=>3, O=>0x8000 },
-       'connect_cached'=>{U=>[1,5,'[$db [,$user [,$passwd [,\%attr]]]]'], 
H=>3, O=>0x8000 },
-       'disconnect_all'=>{ U =>[1,1], O=>0x0800 },
-       data_sources => { U =>[1,2,'[\%attr]' ], O=>0x0800 },
-       default_user => { U =>[3,4,'$user, $pass [, \%attr]' ] },
+       'connect'  =>   { U =>[1,5,'[$db [,$user [,$passwd [,\%attr]]]]'], 
H=>3, O=>0x8000, T=>0x200 },
+       'connect_cached'=>{U=>[1,5,'[$db [,$user [,$passwd [,\%attr]]]]'], 
H=>3, O=>0x8000, T=>0x200 },
+       'disconnect_all'=>{ U =>[1,1], O=>0x0800, T=>0x200 },
+       data_sources => { U =>[1,2,'[\%attr]' ], O=>0x0800, T=>0x200 },
+       default_user => { U =>[3,4,'$user, $pass [, \%attr]' ], T=>0x200 },
        dbixs_revision  => $keeperr,
     },
     db => {            # Database Session Class Interface
        data_sources    => { U =>[1,2,'[\%attr]' ], O=>0x0200 },
        take_imp_data   => { U =>[1,1], O=>0x10000 },
-       clone           => { U =>[1,2,'[\%attr]'] },
-       connected       => { U =>[1,0], O => 0x0004 },
-       begin_work      => { U =>[1,2,'[ \%attr ]'], O=>0x0400 },
-       commit          => { U =>[1,1], O=>0x0480|0x0800 },
-       rollback        => { U =>[1,1], O=>0x0480|0x0800 },
+       clone           => { U =>[1,2,'[\%attr]'], T=>0x200 },
+       connected       => { U =>[1,0], O => 0x0004, T=>0x200 },
+       begin_work      => { U =>[1,2,'[ \%attr ]'], O=>0x0400, T=>0x1000 },
+       commit          => { U =>[1,1], O=>0x0480|0x0800, T=>0x1000 },
+       rollback        => { U =>[1,1], O=>0x0480|0x0800, T=>0x1000 },
        'do'            => { U =>[2,0,'$statement [, \%attr [, @bind_params ] 
]'], O=>0x3200 },
        last_insert_id  => { U =>[5,6,'$catalog, $schema, $table_name, 
$field_name [, \%attr ]'], O=>0x2800 },
        preparse        => {  }, # XXX
@@ -441,7 +434,7 @@
        selectall_hashref=>{ U =>[3,0,'$statement, $keyfield [, \%attr [, 
@bind_params ] ]'], O=>0x2000 },
        selectcol_arrayref=>{U =>[2,0,'$statement [, \%attr [, @bind_params ] 
]'], O=>0x2000 },
        ping            => { U =>[1,1], O=>0x0404 },
-       disconnect      => { U =>[1,1], O=>0x0400|0x0800|0x10000 },
+       disconnect      => { U =>[1,1], O=>0x0400|0x0800|0x10000, T=>0x200 },
        quote           => { U =>[2,3, '$string [, $data_type ]' ], O=>0x0430 },
        quote_identifier=> { U =>[2,6, '$name [, ...] [, \%attr ]' ],    
O=>0x0430 },
        rows            => $keeperr,
@@ -495,7 +488,7 @@
     my $ima_trace = 0+($ENV{DBI_IMA_TRACE}||0);
     while ( my ($method, $info) = each %$meths ) {
        my $fullmeth = "DBI::${class}::$method";
-       if ($DBI::dbi_debug >= 15) { # quick hack to list DBI methods
+       if (($DBI::dbi_debug & 0xF) == 15) { # quick hack to list DBI methods
            # and optionally filter by IMA flags
            my $O = $info->{O}||0;
            printf "0x%04x %-20s\n", $O, $fullmeth
@@ -726,7 +719,7 @@
         # and finished the attribute setup. pass in the original arguments
        $dbh->connected(@orig_args); #if ref $dbh ne 'DBI::db' or $proxy;
 
-       DBI->trace_msg("    <- connect= $dbh\n") if $DBI::dbi_debug;
+       DBI->trace_msg("    <- connect= $dbh\n") if $DBI::dbi_debug & 0xF;
 
        return $dbh;
     };
@@ -770,7 +763,7 @@
 
     $class->trace_msg("    -> $class->install_driver($driver"
                        .") for $^O perl=$] pid=$$ ruid=$< euid=$>\n")
-       if $DBI::dbi_debug;
+       if $DBI::dbi_debug & 0xF;
 
     # --- load the code
     my $driver_class = "DBD::$driver";
@@ -800,7 +793,7 @@
        }
        Carp::croak("install_driver($driver) failed: $err$advice\n");
     }
-    if ($DBI::dbi_debug) {
+    if ($DBI::dbi_debug & 0xF) {
        no strict 'refs';
        (my $driver_file = $driver_class) =~ s/::/\//g;
        my $dbd_ver = ${"$driver_class\::VERSION"} || "undef";
@@ -823,7 +816,7 @@
     }
 
     $DBI::installed_drh{$driver} = $drh;
-    $class->trace_msg("    <- install_driver= $drh\n") if $DBI::dbi_debug;
+    $class->trace_msg("    <- install_driver= $drh\n") if $DBI::dbi_debug & 
0xF;
     $drh;
 }
 
@@ -1423,6 +1416,10 @@
        my ($h, $name) = @_;
        #      0xddDDDDrL (driver, DBI, reserved, Level)
        return 0x00000100 if $name eq 'SQL';
+    return 0x00000200 if $name eq 'CON';
+    return 0x00000400 if $name eq 'ENC';
+    return 0x00000800 if $name eq 'DBD';
+    return 0x00001000 if $name eq 'TXN';
        return;
     }
 
@@ -1479,7 +1476,7 @@
        };
        my $dbh = $cache->{$key};
         $drh->trace_msg(sprintf("    connect_cached: key '$key', cached dbh 
$dbh\n", DBI::neat($key), DBI::neat($dbh)))
-            if $DBI::dbi_debug >= 4;
+            if (($DBI::dbi_debug & 0xF) >= 4);
 
         my $cb = $attr->{Callbacks}; # take care not to autovivify
        if ($dbh && $dbh->FETCH('Active') && eval { $dbh->ping }) {
@@ -3076,7 +3073,7 @@
 
 =head3 C<sql_type_cast>
 
-  $sts = DBI->sql_type_cast($sv, $sql_type, $flags);
+  $sts = DBI::sql_type_cast($sv, $sql_type, $flags);
 
 sql_type_cast attempts to cast C<$sv> to the SQL type (see L<DBI
 Constants>) specified in C<$sql_type>. At present only the SQL types
@@ -3122,7 +3119,7 @@
   -2 sql_type is not handled
   -1 sv is undef so unchanged
    0 sv could not be cast cleanly and DBIstcf_STRICT was used
-   1 sv could not be case and DBIstcf_STRICT was not used
+   1 sv could not be cast and DBIstcf_STRICT was not used
    2 sv was cast successfully
 
 This method is exported by the :utils tag and was introduced in DBI
@@ -4216,7 +4213,7 @@
 in a C<connect_cached.reused> callback, like so:
 
   my $cb = {
-      ‘connect_cached.reused’ => sub { delete $_[4]->{AutoCommit} },
+      'connect_cached.reused' => sub { delete $_[4]->{AutoCommit} },
   };
 
   sub dbh {
@@ -6090,8 +6087,10 @@
 
 When called in list context the execute_array() method returns two scalars;
 $tuples is the same as calling execute_array() in scalar context and $rows is
-the sum of the number of rows affected for each tuple, if available or
--1 if the driver cannot determine this.
+the number of rows affected for each tuple, if available or
+-1 if the driver cannot determine this. NOTE, some drivers cannot determine
+the number of rows affected per tuple but can provide the number of rows
+affected for the batch.
 If you are doing an update operation the returned rows affected may not be what
 you expect if, for instance, one or more of the tuples affected the same row
 multiple times.  Some drivers may not yet support list context, in which case
@@ -6143,10 +6142,11 @@
 mandatory until DBI 1.38.
 
 For tuples which are successfully executed, the element at the same
-ordinal position in the status array is the resulting rowcount.
+ordinal position in the status array is the resulting rowcount (or -1
+if unknown).
 If the execution of a tuple causes an error, then the corresponding
 status array element will be set to a reference to an array containing
-the error code and error string set by the failed execution.
+L</err>, L</errstr> and L</state> set by the failed execution.
 
 If B<any> tuple execution returns an error, C<execute_array> will
 return C<undef>. In that case, the application should inspect the
@@ -6979,8 +6979,8 @@
   my $sth2 = $dbh->prepare( $sth1->{Statement} );
   my $ParamValues = $sth1->{ParamValues} || {};
   my $ParamTypes  = $sth1->{ParamTypes}  || {};
-  $sth2->bind_param($_, $PV->{$_} $PT->{$_})
-    for keys %{ %$PV, %$PT };
+  $sth2->bind_param($_, $ParamValues->{$_} $ParamTypes->{$_})
+    for keys %{ {%$ParamValues, %$ParamTypes} };
   $sth2->execute();
 
 The C<ParamTypes> attribute was added in DBI 1.49. Implementation
@@ -7605,6 +7605,13 @@
   ALL - turn on all DBI and driver flags (not recommended)
   SQL - trace SQL statements executed
         (not yet implemented in DBI but implemented in some DBDs)
+  CON - trace connection process
+  ENC - trace encoding (unicode translations etc)
+        (not yet implemented in DBI but implemented in some DBDs)
+  DBD - trace only DBD messages
+        (not implemented by all DBDs yet)
+  TXN - trace transactions
+        (not implemented in all DBDs yet)
 
 The L</parse_trace_flags> and L</parse_trace_flag> methods are used
 to convert trace flag names into the corresponding integer bit flags.

Modified: dbi/branches/sqlengine/DBI.xs
==============================================================================
--- dbi/branches/sqlengine/DBI.xs       (original)
+++ dbi/branches/sqlengine/DBI.xs       Mon Jul  4 23:47:42 2011
@@ -99,29 +99,35 @@
     U8 minargs;
     U8 maxargs;
     IV hidearg;
-    IV trace_level;
+    /* method_trace controls tracing of method calls in the dispatcher:
+    - if the current trace flags include a trace flag in method_trace
+    then set trace_level to min(2,trace_level) for duration of the call.
+    - else, if trace_level < (method_trace & DBIc_TRACE_LEVEL_MASK)
+    then don't trace the call
+    */
+    U32 method_trace;
     const char *usage_msg;
-    U32   flags;
+    U32 flags;
 } dbi_ima_t;
 
 /* These values are embedded in the data passed to install_method       */
-#define IMA_HAS_USAGE           0x0001  /* check parameter usage        */
-#define IMA_FUNC_REDIRECT       0x0002  /* is $h->func(..., "method")   */
-#define IMA_KEEP_ERR            0x0004  /* don't reset err & errstr     */
-#define IMA_KEEP_ERR_SUB        0x0008  /*  '' if in a nested call      */
-#define IMA_NO_TAINT_IN         0x0010  /* don't check for tainted args */
-#define IMA_NO_TAINT_OUT        0x0020  /* don't taint results          */
-#define IMA_COPY_UP_STMT        0x0040  /* copy sth Statement to dbh    */
-#define IMA_END_WORK            0x0080  /* method is commit or rollback */
-#define IMA_STUB                0x0100  /* donothing eg $dbh->connected */
-#define IMA_CLEAR_STMT          0x0200  /* clear Statement before call  */
-#define IMA_UNRELATED_TO_STMT   0x0400  /* profile as empty Statement   */
-#define IMA_NOT_FOUND_OKAY      0x0800  /* no error if not found        */
-#define IMA_EXECUTE             0x1000  /* do/execute: DBIcf_Executed   */
-#define IMA_SHOW_ERR_STMT       0x2000  /* dbh meth relates to Statement*/
-#define IMA_HIDE_ERR_PARAMVALUES 0x4000 /* ParamValues are not relevant */
-#define IMA_IS_FACTORY          0x8000  /* new h ie connect and prepare */
-#define IMA_CLEAR_CACHED_KIDS  0x10000  /* clear CachedKids before call */
+#define IMA_HAS_USAGE             0x00000001  /* check parameter usage        
*/
+#define IMA_FUNC_REDIRECT         0x00000002  /* is $h->func(..., "method")   
*/
+#define IMA_KEEP_ERR              0x00000004  /* don't reset err & errstr     
*/
+#define IMA_KEEP_ERR_SUB          0x00000008  /*  '' if in a nested call      
*/
+#define IMA_NO_TAINT_IN           0x00000010  /* don't check for tainted args 
*/
+#define IMA_NO_TAINT_OUT          0x00000020  /* don't taint results          
*/
+#define IMA_COPY_UP_STMT          0x00000040  /* copy sth Statement to dbh    
*/
+#define IMA_END_WORK              0x00000080  /* method is commit or rollback 
*/
+#define IMA_STUB                  0x00000100  /* donothing eg $dbh->connected 
*/
+#define IMA_CLEAR_STMT            0x00000200  /* clear Statement before call  
*/
+#define IMA_UNRELATED_TO_STMT     0x00000400  /* profile as empty Statement   
*/
+#define IMA_NOT_FOUND_OKAY        0x00000800  /* no error if not found        
*/
+#define IMA_EXECUTE               0x00001000  /* do/execute: DBIcf_Executed   
*/
+#define IMA_SHOW_ERR_STMT         0x00002000  /* dbh meth relates to 
Statement*/
+#define IMA_HIDE_ERR_PARAMVALUES  0x00004000  /* ParamValues are not relevant 
*/
+#define IMA_IS_FACTORY            0x00008000  /* new h ie connect and prepare 
*/
+#define IMA_CLEAR_CACHED_KIDS     0x00010000  /* clear CachedKids before call 
*/
 
 #define DBIc_STATE_adjust(imp_xxh, state)                                \
     (SvOK(state)        /* SQLSTATE is implemented by driver   */        \
@@ -3375,8 +3381,13 @@
         if (trace_flags) {
             SAVEI32(DBIS->debug);       /* fall back to orig value later */
             DBIS->debug = trace_flags;  /* make new value global (for now) */
-            if (ima && trace_level < ima->trace_level) {
-                trace_level = 0;        /* silence dispatch log for this 
method */
+            if (ima) {
+                /* enabling trace via flags takes precedence over disabling 
due to min level */
+                if ((trace_flags & DBIc_TRACE_FLAGS_MASK) & (ima->method_trace 
& DBIc_TRACE_FLAGS_MASK))
+                    trace_level = (trace_level < 2) ? 2 : trace_level; /* min 
*/
+                else
+                if (trace_level < (DBIc_TRACE_LEVEL_MASK & ima->method_trace))
+                    trace_level = 0;        /* silence dispatch log for this 
method */
             }
         }
 
@@ -4221,6 +4232,11 @@
         DBIpp_st_XX     = DBIpp_st_XX
         DBIstcf_DISCARD_STRING  = DBIstcf_DISCARD_STRING
         DBIstcf_STRICT          = DBIstcf_STRICT
+        DBIf_TRACE_SQL  = DBIf_TRACE_SQL
+        DBIf_TRACE_CON  = DBIf_TRACE_CON
+        DBIf_TRACE_ENC  = DBIf_TRACE_ENC
+        DBIf_TRACE_DBD  = DBIf_TRACE_DBD
+        DBIf_TRACE_TXN  = DBIf_TRACE_TXN
     CODE:
     RETVAL = ix;
     OUTPUT:
@@ -4380,13 +4396,13 @@
         ima = (dbi_ima_t*)(void*)SvPVX(sv);
         memzero((char*)ima, sizeof(*ima));
         DBD_ATTRIB_GET_IV(attribs, "O",1, svp, ima->flags);
-        DBD_ATTRIB_GET_IV(attribs, "T",1, svp, ima->trace_level);
+        DBD_ATTRIB_GET_UV(attribs, "T",1, svp, ima->method_trace);
         DBD_ATTRIB_GET_IV(attribs, "H",1, svp, ima->hidearg);
 
         if (trace_msg) {
             if (ima->flags)       sv_catpvf(trace_msg, ", flags 0x%04x", 
(unsigned)ima->flags);
-            if (ima->trace_level) sv_catpvf(trace_msg, ", T %d", 
(unsigned)ima->trace_level);
-            if (ima->hidearg)     sv_catpvf(trace_msg, ", H %d", 
(unsigned)ima->hidearg);
+            if (ima->method_trace)sv_catpvf(trace_msg, ", T 0x%08lx", 
(unsigned long)ima->method_trace);
+            if (ima->hidearg)     sv_catpvf(trace_msg, ", H %u", 
(unsigned)ima->hidearg);
         }
         if ( (svp=DBD_ATTRIB_GET_SVP(attribs, "U",1)) != NULL) {
             AV *av = (AV*)SvRV(*svp);

Modified: dbi/branches/sqlengine/DBIXS.h
==============================================================================
--- dbi/branches/sqlengine/DBIXS.h      (original)
+++ dbi/branches/sqlengine/DBIXS.h      Mon Jul  4 23:47:42 2011
@@ -197,11 +197,26 @@
 #define DBIc_ACTIVE_KIDS(imp)   _imp2com(imp, std.active_kids)
 #define DBIc_LAST_METHOD(imp)   _imp2com(imp, std.last_method)
 
+/*  d = DBD flags,  l = DBD level (needs to be shifted down)
+ *  D - DBI flags,  r = reserved,  L = DBI trace level
+ *  Trace level bit allocation: 0xddlDDDrL   */
 #define DBIc_TRACE_LEVEL_MASK   0x0000000F
-#define DBIc_TRACE_FLAGS_MASK   0xFFFFFF00
+#define DBIc_TRACE_FLAGS_MASK   0xFF0FFF00  /* includes DBD flag bits for 
DBIc_TRACE */
 #define DBIc_TRACE_SETTINGS(imp) (DBIc_DBISTATE(imp)->debug)
 #define DBIc_TRACE_LEVEL(imp)   (DBIc_TRACE_SETTINGS(imp) & 
DBIc_TRACE_LEVEL_MASK)
 #define DBIc_TRACE_FLAGS(imp)   (DBIc_TRACE_SETTINGS(imp) & 
DBIc_TRACE_FLAGS_MASK)
+/* DBI defined trace flags */
+#define DBIf_TRACE_SQL          0x00000100
+#define DBIf_TRACE_CON          0x00000200
+#define DBIf_TRACE_ENC          0x00000400
+#define DBIf_TRACE_DBD          0x00000800
+#define DBIf_TRACE_TXN          0x00001000
+
+#define DBDc_TRACE_LEVEL_MASK   0x00F00000
+#define DBDc_TRACE_LEVEL_SHIFT  20
+#define DBDc_TRACE_LEVEL(imp)         ( (DBIc_TRACE_SETTINGS(imp) & 
DBDc_TRACE_LEVEL_MASK) >> DBDc_TRACE_LEVEL_SHIFT )
+#define DBDc_TRACE_LEVEL_set(imp, l)  ( DBIc_TRACE_SETTINGS(imp) |= (((l) << 
DBDc_TRACE_LEVEL_SHIFT) & DBDc_TRACE_LEVEL_MASK ))
+
 /* DBIc_TRACE_MATCHES(this, crnt): true if this 'matches' (is within) crnt
    DBIc_TRACE_MATCHES(foo, DBIc_TRACE_SETTINGS(imp))
 */
@@ -210,10 +225,10 @@
         || ((crnt & DBIc_TRACE_FLAGS_MASK)  & (this & DBIc_TRACE_FLAGS_MASK)) )
 /* DBIc_TRACE: true if flags match & DBI level>=flaglevel, or if DBI 
level>level
    This is the main trace testing macro to be used by drivers.
-   (Drivers should define their own DBDtf_* macros for the top 8 bits: 
0xFF000000)
-   DBIc_TRACE(imp,         0, 0, 4) = if level >= 4
-   DBIc_TRACE(imp, DBDtf_FOO, 2, 4) = if tracing DBDtf_FOO & level>=2 or 
level>=4
-   DBIc_TRACE(imp, DBDtf_FOO, 2, 0) = as above but never trace just due to 
level
+   (Drivers should define their own DBDf_TRACE_* macros for the top 8 bits: 
0xFF000000)
+   DBIc_TRACE(imp,        0, 0, 4) = if level >= 4
+   DBIc_TRACE(imp, DBDf_FOO, 2, 4) = if tracing DBDf_FOO & level>=2 or level>=4
+   DBIc_TRACE(imp, DBDf_FOO, 2, 0) = as above but never trace just due to level
 */
 #define DBIc_TRACE(imp, flags, flaglevel, level)        \
         (  (flags && (DBIc_TRACE_FLAGS(imp) & flags) && (DBIc_TRACE_LEVEL(imp) 
>= flaglevel)) \
@@ -513,6 +528,10 @@
         if ((svp=DBD_ATTRIB_GET_SVP(attribs, key,klen)) != NULL)        \
             var = SvIV(*svp)
 
+#define DBD_ATTRIB_GET_UV(attribs, key,klen, svp, var)                  \
+        if ((svp=DBD_ATTRIB_GET_SVP(attribs, key,klen)) != NULL)        \
+            var = SvUV(*svp)
+
 #define DBD_ATTRIB_GET_BOOL(attribs, key,klen, svp, var)                \
         if ((svp=DBD_ATTRIB_GET_SVP(attribs, key,klen)) != NULL)        \
             var = SvTRUE(*svp)

Modified: dbi/branches/sqlengine/Driver.xst
==============================================================================
--- dbi/branches/sqlengine/Driver.xst   (original)
+++ dbi/branches/sqlengine/Driver.xst   Mon Jul  4 23:47:42 2011
@@ -90,10 +90,12 @@
     SV *        attribs
     CODE:
     {
-    STRLEN lna;
     D_imp_dbh(dbh);
+#if !defined(dbd_db_login6_sv)
+    STRLEN lna;
     char *u = (SvOK(username)) ? SvPV(username,lna) : "";
     char *p = (SvOK(password)) ? SvPV(password,lna) : "";
+#endif
 #ifdef dbd_db_login6_sv
     ST(0) = dbd_db_login6_sv(dbh, imp_dbh, dbname, username, password, 
attribs) ? &PL_sv_yes : &PL_sv_no;
 #elif defined(dbd_db_login6)

Modified: dbi/branches/sqlengine/TODO_2005.txt
==============================================================================
--- dbi/branches/sqlengine/TODO_2005.txt        (original)
+++ dbi/branches/sqlengine/TODO_2005.txt        Mon Jul  4 23:47:42 2011
@@ -1,12 +1,5 @@
-
-DBI Version 2
-=============
-
-v2.0 - infrastructure changes, mainly relevant for driver authors
-v2.x - incremental features
-
-Change plan for DBI v2.0
-========================
+Change ideas for DBI
+====================
 
 --- Changes that may impact applications:
 
@@ -105,9 +98,9 @@
        }
 Also need to consider $sth->more_results and its need for reset()-like 
behaviour.
 
-Need to enable drivers to work with DBI v1 or v2:
-means having both ::db::prepare and ::st::prepare
-In DBI v2 when a driver is loaded the ::db::prepare() method
+Need to enable drivers to work with old and new approaches,
+which means having both ::db::prepare and ::st::prepare
+When a driver is loaded the ::db::prepare() method
 will be deleted if a ::st::reset method exists.
 
 Make $DBI::err etc plain (untied) variables.

Modified: dbi/branches/sqlengine/dbixs_rev.h
==============================================================================
--- dbi/branches/sqlengine/dbixs_rev.h  (original)
+++ dbi/branches/sqlengine/dbixs_rev.h  Mon Jul  4 23:47:42 2011
@@ -1,4 +1,3 @@
-/* Tue Dec 14 22:26:28 2010 */
-/* Mixed revision working copy (14564M:14571) */
+/* Sun Feb  6 12:56:22 2011 */
 /* Code modified since last checkin */
-#define DBIXS_REVISION 14564
+#define DBIXS_REVISION 14685

Modified: dbi/branches/sqlengine/lib/DBD/NullP.pm
==============================================================================
--- dbi/branches/sqlengine/lib/DBD/NullP.pm     (original)
+++ dbi/branches/sqlengine/lib/DBD/NullP.pm     Mon Jul  4 23:47:42 2011
@@ -118,6 +118,7 @@
             $sth->{dbd_nullp_data} = [ @{$params}{ sort keys %$params } ];
             $sth->STORE(Active => 1); 
         }
+        # force a sleep - handy for testing
         elsif ($sth->{Statement} =~ m/^ \s* SLEEP \s+ (\S+) /xmsi) {
             my $secs = $1;
             if (eval { require Time::HiRes; defined &Time::HiRes::sleep }) {
@@ -127,6 +128,11 @@
                 sleep $secs;
             }
         }
+        # force an error - handy for testing
+        elsif ($sth->{Statement} =~ m/^ \s* ERROR \s+ (\d+) \s* (.*) /xmsi) {
+            return $sth->set_err($1, $2);
+        }
+        # anything else is silently ignored, sucessfully
        1;
     }
 

Modified: dbi/branches/sqlengine/lib/DBI/DBD.pm
==============================================================================
--- dbi/branches/sqlengine/lib/DBI/DBD.pm       (original)
+++ dbi/branches/sqlengine/lib/DBI/DBD.pm       Mon Jul  4 23:47:42 2011
@@ -2642,6 +2642,15 @@
 where I<A_TABLE_NAME> is the name of a table that always exists (such as a
 database system catalogue).
 
+=item $drh->default_user
+
+The default implementation of default_user will get the database
+username and password fields from C<$ENV{DBI_USER}> and
+C<$ENV{DBI_PASS}>. You can override this method. It is called as
+follows:
+
+  ($user, $pass) = $drh->default_user($user, $pass, $attr)
+
 =back
 
 =head1 METADATA METHODS

Modified: dbi/branches/sqlengine/lib/DBI/DBD/SqlEngine.pm
==============================================================================
--- dbi/branches/sqlengine/lib/DBI/DBD/SqlEngine.pm     (original)
+++ dbi/branches/sqlengine/lib/DBI/DBD/SqlEngine.pm     Mon Jul  4 23:47:42 2011
@@ -781,7 +781,9 @@
     {
         # bug in SQL::Statement 1.20 and below causes breakage
         # on all but the first call
-        unless ( ( my $req_prm = $stmt->params() ) == ( my $nparm = @$params ) 
)
+        my @req_prm = $stmt->params();
+        my $n_req = @req_prm == 1 && ref $req_prm[0] ? $req_prm[0]->num : 
scalar @req_prm;
+        unless ( $n_req == ( my $nparm = @$params ) )
         {
             my $msg = "You passed $nparm parameters where $req_prm required";
             $sth->set_err( $DBI::stderr, $msg );
@@ -877,7 +879,8 @@
 
     $attrib eq "NAME" and return [ $sth->sql_get_colnames() ];
 
-    $attrib eq "TYPE"      and return [ ("CHAR") x scalar 
$sth->sql_get_colnames() ];
+    $attrib eq "TYPE"      and return [ (DBI::SQL_VARCHAR()) x scalar 
$sth->sql_get_colnames() ];
+    $attrib eq "TYPE_NAME" and return [ ("VARCHAR") x scalar 
$sth->sql_get_colnames() ];
     $attrib eq "PRECISION" and return [ (0) x scalar $sth->sql_get_colnames() 
];
     $attrib eq "NULLABLE"  and return [ (1) x scalar $sth->sql_get_colnames() 
];
 

Modified: dbi/branches/sqlengine/t/08keeperr.t
==============================================================================
--- dbi/branches/sqlengine/t/08keeperr.t        (original)
+++ dbi/branches/sqlengine/t/08keeperr.t        Mon Jul  4 23:47:42 2011
@@ -2,7 +2,7 @@
 
 use strict;
 
-use Test::More tests => 69;
+use Test::More tests => 72;
 
 ## ----------------------------------------------------------------------------
 ## 08keeperr.t
@@ -69,6 +69,17 @@
 
 package main;
 
+# test ping does not destroy the errstr
+sub ping_keeps_err {
+    my $dbh = DBI->connect('DBI:Sponge:');
+    $dbh->{PrintError} = 0;
+    eval {$dbh->do(q/invalid sql statement/)};
+    ok(defined($dbh->errstr), "Error from invalid SQL");
+    ok($dbh->ping, "ping returns true"); # for me this returns false!
+    ok(defined($dbh->errstr), "Error exists after ping");
+    $dbh->disconnect;
+}
+
 ## ----------------------------------------------------------------------------
 print "Test HandleSetErr\n";
 
@@ -260,8 +271,9 @@
 cmp_ok($dbh->err, '==', 99,  '... $dbh->err is 99');
 is($dbh->errstr, "errstr99", '... $dbh->errstr is as we expected');
 is($dbh->state,  "OV123",    '... $dbh->state is as we expected');
-
 $dbh->disconnect;
 
+ping_keeps_err();
+
 1;
 # end

Modified: dbi/branches/sqlengine/t/09trace.t
==============================================================================
--- dbi/branches/sqlengine/t/09trace.t  (original)
+++ dbi/branches/sqlengine/t/09trace.t  Mon Jul  4 23:47:42 2011
@@ -3,7 +3,7 @@
 
 use strict;
 
-use Test::More tests => 67;
+use Test::More tests => 99;
 
 ## ----------------------------------------------------------------------------
 ## 09trace.t
@@ -60,6 +60,10 @@
 
 my @names = qw(
        SQL
+    CON
+    ENC
+    DBD
+    TXN
        foo bar baz boo bop
 );
 my %flag;

Modified: dbi/branches/sqlengine/t/10examp.t
==============================================================================
--- dbi/branches/sqlengine/t/10examp.t  (original)
+++ dbi/branches/sqlengine/t/10examp.t  Mon Jul  4 23:47:42 2011
@@ -5,6 +5,7 @@
 use Config;
 use Cwd;
 use strict;
+use Data::Dumper;
 
 $^W = 1;
 $| = 1;
@@ -354,6 +355,15 @@
 ok( !eval { $se_sth1->execute } );
 like $@, qr/\[for Statement "select mode from \?" with ParamValues: 1='val1', 
2='val2', 3='val3', 4='val4', 5='val5', 6='val6', 7='val7', 8='val8', 9='val9', 
10='val10', 11='val11'\]/;
 
+# this test relies on the fact that ShowErrorStatement is set above
+eval {
+    local $se_sth1->{PrintError} = 0;
+    $se_sth1->execute(1,2);
+};
+unlike($@, qr/ParamValues:/, 'error string does not contain ParamValues');
+is($se_sth1->{ParamValues}, undef, 'ParamValues is empty')
+    or diag(Dumper($se_sth1->{ParamValues}));
+
 # check that $dbh->{Statement} tracks last _executed_ sth
 $se_sth1 = $dbh->prepare("select mode from ?");
 ok($se_sth1->{Statement} eq "select mode from ?");

Modified: dbi/branches/sqlengine/t/51dbm_file.t
==============================================================================
--- dbi/branches/sqlengine/t/51dbm_file.t       (original)
+++ dbi/branches/sqlengine/t/51dbm_file.t       Mon Jul  4 23:47:42 2011
@@ -69,7 +69,7 @@
 unless ($using_dbd_gofer)
 {
     my $fn_tbl2 = $dbh->{dbm_tables}->{fred}->{f_fqfn};
-       $fn_tbl2 =~ s/fred(\.[^.]*)?/freddy$1/;
+       $fn_tbl2 =~ s/fred(\.[^.]*)?$/freddy$1/;
     my @dbfiles = grep { -f $_ } (
                                     $dbh->{dbm_tables}->{fred}->{f_fqfn},
                                     $dbh->{dbm_tables}->{fred}->{f_fqln},
@@ -78,7 +78,7 @@
     foreach my $fn (@dbfiles)
     {
        my $tgt_fn = $fn;
-       $tgt_fn =~ s/fred(\.[^.]*)?/freddy$1/;
+       $tgt_fn =~ s/fred(\.[^.]*)?$/freddy$1/;
        File::Copy::copy( $fn, $tgt_fn );
     }
     $dbh->{dbm_tables}->{krueger}->{file} = $fn_tbl2;

Reply via email to