From d9d0e6d5021bc27ffcdbb63243039760dd61d2e1 Mon Sep 17 00:00:00 2001 From: Tim Bunce Date: Sun, 1 Feb 2004 11:32:45 +0000 Subject: [PATCH] Updating source to current work-in-progress and adding some non-source files git-svn-id: https://svn.perl.org/modules/dbi/trunk@48 50811bd7-b8ce-0310-adc1-d9db26280581 --- Changes | 31 + DBI.pm | 224 ++++-- DBI.xs | 244 ++++-- DBIXS.h | 6 +- MANIFEST.SKIP | 24 + META.yml | 2 +- README | 16 +- ToDo | 344 ++++---- err_new/err_disconchk.msg | 142 ++++ err_new/err_docsmissingexe.msg | 69 ++ err_new/err_exe_for_fetch_empty.msg | 61 ++ err_new/err_ithead_clone_modglobal.msg | 622 +++++++++++++++ err_new/err_leaktracking.msg | 315 ++++++++ err_new/err_metadatadocs.msg | 149 ++++ err_new/err_metayml.mgs | 65 ++ err_new/err_modeling.msg | 69 ++ err_new/err_modglobalclone.msg | 103 +++ err_new/err_mxauth.msg | 110 +++ err_new/err_nonrefattr.msg | 93 +++ err_new/err_oldconnect.patch | 225 ++++++ err_new/err_perl582thr.msg | 275 +++++++ err_new/err_plserverbug.msg | 66 ++ err_new/err_prof_empty_stmts.msg | 99 +++ err_new/err_profilewin32hires.msg | 319 ++++++++ err_new/err_proxyrpc.msg | 52 ++ err_new/err_registry.msg | 37 + err_new/err_signal-docs.msg | 696 +++++++++++++++++ err_new/err_type_info_all.patch.msg | 65 ++ err_shelved/err_add-defaults-last-insid.msg | 104 +++ err_shelved/err_breaks.msg | 253 ++++++ err_shelved/err_dbtype.msg | 400 ++++++++++ err_shelved/err_leakdetection.msg | 83 ++ err_shelved/err_multidrivercore.msg | 825 ++++++++++++++++++++ err_shelved/err_paramtypeattr.msg | 127 +++ err_shelved/err_poddocs.msg | 69 ++ err_shelved/err_priv_attr_subclass.msg | 71 ++ err_shelved/err_provide_sth_reset.msg | 130 +++ err_shelved/err_proxybindnamed.msg | 400 ++++++++++ err_shelved/err_proxytest.msg | 70 ++ err_shelved/err_setmagic_rowfetch.msg | 82 ++ err_shelved/err_state.msg | 76 ++ err_shelved/err_successwithinfo.msg | 89 +++ err_shelved/err_svpv.msg | 98 +++ err_shelved/err_utf8trsnacodexs.msg | 78 ++ err_shelved/err_warnhandler.msg | 523 +++++++++++++ err_shelved/ref_croakxs.msg | 76 ++ err_shelved/ref_gotoxs.msg | 25 + err_shelved/ref_in_eval.msg | 179 +++++ err_shelved/ref_magicsv.txt | 53 ++ err_shelved/ref_tie_xs.info | 129 +++ lib/DBI/DBD.pm | 12 +- lib/DBI/DBD/Metadata.pm | 14 +- lib/DBI/PurePerl.pm | 146 +++- t/01basics.t | 3 + t/02dbidrv.t | 5 +- t/03handle.t | 6 +- t/08keeperr.t | 125 ++- t/15array.t | 21 +- t/40profile.t | 6 + test.pl | 8 +- 60 files changed, 8454 insertions(+), 355 deletions(-) create mode 100644 MANIFEST.SKIP create mode 100644 err_new/err_disconchk.msg create mode 100644 err_new/err_docsmissingexe.msg create mode 100644 err_new/err_exe_for_fetch_empty.msg create mode 100644 err_new/err_ithead_clone_modglobal.msg create mode 100644 err_new/err_leaktracking.msg create mode 100644 err_new/err_metadatadocs.msg create mode 100644 err_new/err_metayml.mgs create mode 100644 err_new/err_modeling.msg create mode 100644 err_new/err_modglobalclone.msg create mode 100644 err_new/err_mxauth.msg create mode 100644 err_new/err_nonrefattr.msg create mode 100644 err_new/err_oldconnect.patch create mode 100644 err_new/err_perl582thr.msg create mode 100644 err_new/err_plserverbug.msg create mode 100644 err_new/err_prof_empty_stmts.msg create mode 100644 err_new/err_profilewin32hires.msg create mode 100644 err_new/err_proxyrpc.msg create mode 100644 err_new/err_registry.msg create mode 100644 err_new/err_signal-docs.msg create mode 100644 err_new/err_type_info_all.patch.msg create mode 100644 err_shelved/err_add-defaults-last-insid.msg create mode 100644 err_shelved/err_breaks.msg create mode 100644 err_shelved/err_dbtype.msg create mode 100644 err_shelved/err_leakdetection.msg create mode 100644 err_shelved/err_multidrivercore.msg create mode 100644 err_shelved/err_paramtypeattr.msg create mode 100644 err_shelved/err_poddocs.msg create mode 100644 err_shelved/err_priv_attr_subclass.msg create mode 100644 err_shelved/err_provide_sth_reset.msg create mode 100644 err_shelved/err_proxybindnamed.msg create mode 100644 err_shelved/err_proxytest.msg create mode 100644 err_shelved/err_setmagic_rowfetch.msg create mode 100644 err_shelved/err_state.msg create mode 100644 err_shelved/err_successwithinfo.msg create mode 100644 err_shelved/err_svpv.msg create mode 100644 err_shelved/err_utf8trsnacodexs.msg create mode 100644 err_shelved/err_warnhandler.msg create mode 100644 err_shelved/ref_croakxs.msg create mode 100644 err_shelved/ref_gotoxs.msg create mode 100644 err_shelved/ref_in_eval.msg create mode 100644 err_shelved/ref_magicsv.txt create mode 100644 err_shelved/ref_tie_xs.info diff --git a/Changes b/Changes index 8617547e..0ea5a5da 100644 --- a/Changes +++ b/Changes @@ -6,6 +6,37 @@ DBI::Changes - List of significant changes to the DBI =head1 CHANGES +set_err -> set_state? +Add clear_state / clear_err +Document smarts in set_err +Drivers to change how they get debug level (with masked bits). + + Fixed execute_for_array() so tuple_status parameter is optional + as per docs, thanks to Ed Avis. + Fixed execute_for_array() docs to say that it returns undef if + any of the execute() calls fail. + Fixed take_imp_data() test on m68k reported by Christian Hammers. + Fixed write_typeinfo_pm inconsistencies in DBI::DBD::Metadata + thanks to Andy Hassall. + + Changed set_err() to append to errstr, with a leading "\n" if it's + not empty, so that multiple error/warning messages are recorded. + Changed trace to limit elements dumped when an array reference is + returned from a method to the max(40, $DBI::neat_maxlen/10) + so that fetchall_arrayref(), for example, doesn't flood the trace. + + Added way for drivers to indicate 'success with info' or 'warning' + by setting err to "0" for warning and "" for information. + Both values are false and so don't trigger RaiseError etc. + Warnings (err="0") are automatically printed if PrintError is set. + Thanks to Steffen Goeldner for the original idea. + Added $h->{HandleSetError} = sub { ... } to be called at the + point that an error, warn, or info state is recorded. + The code can alter the err, errstr, and state values + (e.g., to promote an error to a warning, or the reverse). + Added details of DBI::Const::GetInfoType module to get_info() docs. + Added ref count of inner handle to "DESTROY ignored for outer" msg. + =head2 Changes in DBI 1.40, 7th January 2004 Fixed handling of CachedKids when DESTROYing threaded handles. diff --git a/DBI.pm b/DBI.pm index 2355a2be..548e50e9 100644 --- a/DBI.pm +++ b/DBI.pm @@ -1,4 +1,4 @@ -# $Id: DBI.pm,v 11.42 2004/01/08 14:03:46 timbo Exp $ +# $Id: DBI.pm,v 11.43 2004/02/01 11:16:16 timbo Exp $ # vim: ts=8:sw=4 # # Copyright (c) 1994-2004 Tim Bunce Ireland @@ -9,7 +9,7 @@ require 5.006_00; BEGIN { -$DBI::VERSION = "1.40"; # ==> ALSO update the version in the pod text below! +$DBI::VERSION = "1.41"; # ==> ALSO update the version in the pod text below! } =head1 NAME @@ -118,8 +118,8 @@ Tim he's very likely to just forward it to the mailing list. =head2 NOTES -This is the DBI specification that corresponds to the DBI version 1.40 -(C<$Date: 2004/01/08 14:03:46 $>). +This is the DBI specification that corresponds to the DBI version 1.41 +(C<$Date: 2004/02/01 11:16:16 $>). The DBI is evolving at a steady pace, so it's good to check that you have the latest copy. @@ -150,7 +150,7 @@ L<"http://search.cpan.org/search?query=DBI&mode=all">. package DBI; -my $Revision = substr(q$Revision: 11.42 $, 10); +my $Revision = substr(q$Revision: 11.43 $, 10); use Carp(); use DynaLoader (); @@ -532,7 +532,7 @@ sub connect { # Set $driver. Old style driver, if specified, overrides new dsn style. $driver = $old_driver || $1 || $ENV{DBI_DRIVER} - or Carp::croak("Can't connect(@_), no database driver specified " + or Carp::croak("Can't connect to data source $dsn, no database driver specified " ."and DBI_DSN env var not set"); if ($ENV{DBI_AUTOPROXY} && $driver ne 'Proxy' && $driver ne 'Sponge' && $driver ne 'Switch') { @@ -594,6 +594,7 @@ sub connect { $errstr = '(no error string)' if !defined $errstr; my $msg = "$class connect('$dsn','$user',...) failed: $errstr"; DBI->trace_msg(" $msg\n"); + # XXX HandleWarn unless ($attr->{HandleError} && $attr->{HandleError}->($msg, $drh, $dbh)) { Carp::croak($msg) if $attr->{RaiseError}; Carp::carp ($msg) if $attr->{PrintError}; @@ -633,7 +634,7 @@ sub connect { $dbh->{$a} = delete $attr->{$a}; } foreach $a (keys %$attr) { - $dbh->{$a} = $attr->{$a}; + eval { $dbh->{$a} = $attr->{$a} } or $@ && warn $@; } } @@ -1719,7 +1720,8 @@ sub _new_sth { # called by DBD::::db::prepare) sub execute_for_fetch { my ($sth, $fetch_tuple_sub, $tuple_status) = @_; - @$tuple_status = () if $tuple_status; # reset the status array + # start with empty status array + ($tuple_status) ? @$tuple_status = () : $tuple_status = []; my ($err_count, %errstr_cache); while ( my $tuple = &$fetch_tuple_sub() ) { @@ -2214,7 +2216,7 @@ Returns a database handle object if the connection succeeds. Use C<$dbh-Edisconnect> to terminate the connection. If the connect fails (see below), it returns C and sets both C<$DBI::err> -and C<$DBI::errstr>. (It does I set C<$!>, etc.) You should generally +and C<$DBI::errstr>. (It does I explicitly set C<$!>.) You should generally test the return status of C and C if it has failed. Multiple simultaneous connections to multiple databases through multiple @@ -2593,30 +2595,47 @@ method called. The code is typically an integer but you should not assume that. The DBI resets $h->err to undef before most DBI method calls, so the -value only has a short lifespan. Also, most drivers share the same -error variables across all their handles, so calling a method on -one handle will typically reset the error on all the other handles -that are children of that driver. +value only has a short lifespan. Also, for most drivers, the statement +handles share the same error variable as the parent database handle, +so calling a method on one handle may reset the error on the +related handles. If you need to test for individual errors I have your program be portable to different database engines, then you'll need to determine what the corresponding error codes are for all those engines and test for all of them. +A driver may return C<0> from err() to indicate a warning condition +after a method call. Similarly, a driver may return an empty string +to indicate a 'success with information' condition. In both these +cases the value is false but not undef. The errstr() and state() +methods may be used to retrieve extra information. + +See L for more information. + =item C $str = $h->errstr; -Returns the native database engine error message from the last driver +Returns the native database engine error message from the last DBI method called. This has the same lifespan issues as the L method described above. +The returned string may contain multiple messages separated by +newline characters. + +The errstr() method should not be used to test for errors, use err() +for that, because drivers may return 'success with information' or +warning messages via errstr() for methods that have not 'failed'. + +See L for more information. + =item C $str = $h->state; -Returns an error code in the standard SQLSTATE five character format. -Note that the specific success code C<00000> is translated to 'C<>' +Returns a state code in the standard SQLSTATE five character format. +Note that the specific success code C<00000> is translated to any empty string (false). If the driver does not support SQLSTATE (and most don't), then state will return C (General Error) for all errors. @@ -2624,24 +2643,60 @@ The driver is free to return any value via C, e.g., warning codes, even if it has not declared an error by returning a true value via the L method described above. +The state() method should not be used to test for errors, use err() +for that, because drivers may return a 'success with information' or +warning state code via errstr() for methods that have not 'failed'. + =item C $rv = $h->set_err($err, $errstr); + $rv = $h->set_err($err, $errstr, $state); $rv = $h->set_err($err, $errstr, $state, $method); $rv = $h->set_err($err, $errstr, $state, $method, $rv); Set the C, C, and C values for the handle. -This will trigger the normal DBI error handling mechanisms, -such as C and C, if they are enabled. This method is typically only used by DBI drivers and DBI subclasses. -The $method parameter provides an alternate method name, instead -of the fairly unhelpful 'C', for the -C/C error string. +If the L attribute holds a reference to a subroutine +it is called first. The subroutine can alter the $err, $errstr, $state, +and $method values. See L for full details. +If the subroutine returns a true value then the handle C, +C, and C values are not altered and set_err() returns +an empty list (it normally returns $rv which defaults to undef, see below). + +Setting C to a I value indicates an error and will trigger +the normal DBI error handling mechanisms, such as C and +C, if they are enabled, when execution returns from +the DBI back to the application. + +Setting C to C<""> indicates an 'information' state, and setting +it to C<"0"> indicates a 'warning' state. + +The $method parameter provides an alternate method name for the +C/C error string instead of the fairly +unhelpful 'C'. The C method normally returns undef. The $rv parameter -provides an alternate return value. The C subroutine -can access and alter this value. +provides an alternate return value. + +Some special rules apply if the C or C +values for the handle are already set... + +If C is true then: "C< [err was %s now %s]>" is appended if +$err is true and C is already true; "C< [state was %s now %s]>" +is appended if $state is true and C is already true; then +"C<\n>" and the new $errstr are appended. Obviously the C<%s>'s +above are replaced by the corresponding values. + +The handle C value is set to $err if: $err is true; or handle +C value is undef; or $err is defined and the length is greater +than the handle C length. The effect is that an 'information' +state only overides undef; a 'warning' overrides undef or 'information', +and an 'error' state overrides anything. + +The handle C value is set to $state if $state is true and +the handle C value was set (by the rules above). + =item C @@ -2917,7 +2972,7 @@ and altering the return value of the failed method. For example: $h->{HandleError} = sub { return 0 unless $_[0] =~ /^\S+ fetchrow_arrayref failed:/; return 0 unless $_[1]->err == 1234; # the error to 'hide' - $h->set_err(0,""); # turn off the error + $h->set_err(undef,undef); # turn off the error $_[2] = [ ... ]; # supply alternative return value return 1; }; @@ -2927,6 +2982,40 @@ to make reliable (avoiding infinite loops, for example) and so isn't recommended for general use! If you find a I use for it then please let me know. +=item C (code ref, inherited) + +The C attribute can be used to intercept +the setting of handle C, C, and C values. +If set to a reference to a subroutine then that subroutine is called +whenever set_err() is called, typically by the driver or a subclass. + +The subroutine is called with five arguments, the first five that +were passed to set_err(): the handle, the C, C, and +C values being set, and the method name. These can be altered +by changing the values in the @_ array. The return value affects +set_err() behaviour, see L for details. + +It is possible to 'stack' multiple HandleSetError handlers by using +closures. See L for an example. + +The C and C subroutines differ in subtle +but significant ways. HandleError is only invoked at the point where +the DBI is about to return to the application with C set true. +It's not invoked by the failure of a method that's been caled by +another DBI method. HandleSetError, on the other hand, is called +whenever set_err() is called with a defined C value, even if false. +So it's not just for errors, despite the name, but also warn and info states. +The set_err method, and thus HandleSetError, may be called multiple +times within a method and is usually invoked from deep within driver code. + +In theory a driver can use the return value from HandleSetError via +set_err() to decide whether to continue or not. If set_err() returns +an empty list, indicating that the HandleSetError code has 'handled' +the 'error', the driver could then continue instead of failing (if +that's a reasonable thing to do). This isn't excepted to be +common and any such cases should be clearly marked in the driver +documentation. + =item C (boolean, inherited) @@ -2973,11 +3062,12 @@ does not support it must arrange to return C as the attribute value. =item C (unsigned integer, inherited) -The C attribute may be used to control the maximum length of long fields -("blob", "memo", etc.) which the driver will read from the -database automatically when it fetches each row of data. The -C attribute only relates to fetching and reading long values; it -is not involved in inserting or updating them. +The C attribute may be used to control the maximum +length of 'long' fields ("blob", "memo", etc.) which the driver will +read from the database automatically when it fetches each row of data. + +The C attribute only relates to fetching and reading +long values; it is not involved in inserting or updating them. A value of 0 means not to automatically fetch any long data. (C should return C for long fields when C is 0.) @@ -2987,23 +3077,36 @@ Applications fetching long fields should set this value to slightly larger than the longest long field value to be fetched. Some databases return some long types encoded as pairs of hex digits. -For these types, C relates to the underlying data length and not the -doubled-up length of the encoded string. +For these types, C relates to the underlying data +length and not the doubled-up length of the encoded string. Changing the value of C for a statement handle after it has been C'd will typically have no effect, so it's common to set C on the C<$dbh> before calling C. -Note that the value used here has a direct effect on the memory used -by the application, so don't be too generous. +For most drivers the value used here has a direct effect on the +memory used by the statement handle while it's active, so don't be +too generous. If you can't be sure what value to use you could +execute an extra select statement to determine the longest value. +For example: + + $dbh->{LongReadLen} = $dbh->selectrow_array{qq{ + SELECT MAX(long_column_name) FROM table WHERE ... + }); + $sth = $dbh->prepare(qq{ + SELECT long_column_name, ... FROM table WHERE ... + }); + +You may need to take etra care if the table can be modified between +the first select and the second being executed. See L for more information on truncation behaviour. =item C (boolean, inherited) -The C attribute may be used to control the effect of fetching a long -field value which has been truncated (typically because it's longer -than the value of the C attribute). +The C attribute may be used to control the effect of +fetching a long field value which has been truncated (typically +because it's longer than the value of the C attribute). By default, C is false and so fetching a long value that needs to be truncated will cause the fetch to fail. @@ -3625,19 +3728,22 @@ unknown or unimplemented information types. For example: See L for more detailed information about the information types and their meanings and possible return values. -The DBI curently doesn't provide a name to number mapping for the -information type codes or the results. Applications are expected to use -the integer values directly, with the name in a comment, or define -their own named values using something like the L pragma. +The DBI::Const::GetInfoType module exports a %GetInfoType hash that +can be used to map info type names to numbers. For example: + + $database_version = $dbh->get_info( $GetInfoType{SQL_DBMS_VER} ); + +The names are a merging of the ANSI and ODBC standards (which differ +in some cases). See L for more details. Because some DBI methods make use of get_info(), drivers are strongly encouraged to support I the following very minimal set of information types to ensure the DBI itself works properly: Type Name Example A Example B - ---- -------------------------- ------------ ------------ + ---- -------------------------- ------------ ---------------- 17 SQL_DBMS_NAME 'ACCESS' 'Oracle' - 18 SQL_DBMS_VER '03.50.0000' '08.01.0721' + 18 SQL_DBMS_VER '03.50.0000' '08.01.0721 ...' 29 SQL_IDENTIFIER_QUOTE_CHAR '`' '"' 41 SQL_CATALOG_NAME_SEPARATOR '.' '@' 114 SQL_CATALOG_LOCATION 1 2 @@ -4809,8 +4915,9 @@ The execute_for_fetch() method calls $fetch_tuple_sub, without any 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, regardless of the success -or failure of those executions. Use tuple_status to check. +The number of tuples executed is returned I there were no errors. +If there were any errors then C is returned and the @tuple_status +array can be used to discover which tuples failed and with what errors. If \@tuple_status is passed then the execute_for_fetch method uses it to return status information. The tuple_status array holds one @@ -4824,7 +4931,8 @@ to call $sth->execute(@$tuple_array_ref) the exact timing may vary. Drivers are free to accumulate sets of tuples to pass to the database server in bulk group operations for more efficient execution. However, the $fetch_tuple_sub is specifically allowed to return -the same array reference each time. +the same array reference each time (which is what fetchrow_arrayref() +usually does). For example: @@ -5173,7 +5281,7 @@ of these attributes are read-only. Changes to these statement handle attributes do not affect any other existing or future statement handles. -Attempting to set or get the value of an unknown attribute is fatal, +Attempting to set or get the value of an unknown attribute is I, except for private driver specific attributes (which all have names starting with a lowercase letter). @@ -5181,8 +5289,13 @@ Example: ... = $h->{NUM_OF_FIELDS}; # get/read -Note that some drivers cannot provide valid values for some or all of -these attributes until after C<$sth-Eexecute> has been called. +Some drivers cannot provide valid values for some or all of these +attributes until after C<$sth-Eexecute> has been successfully +called. Typically the attribute will be C in these situations. + +Some attributes, like NAME, are not appropriate to some types of +statement, like SELECT. Typically the attribute will be C +in these situations. See also L to learn more about the effect it may have on some attributes. @@ -5510,10 +5623,13 @@ databases can't usually know in advance the length of the longest long that will be returned from a C