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;