|
|
sybperl-l Archive
Up Prev Next
From: "W dot Phillip Moore" <wpm at ms dot com>
Subject: [PATCH] Improved error handling in nsql() method
Date: May 5 1998 8:52PM
Michael --
Please apply this patch to your baseline source tree for 2.09_04 for
the next release.
This patch implements the following changes:
[*] Sybase::BCP exports $DB_ERROR
This allows the nsql() method to be used for with Sybase::BCP
objects, not only Sybase::DBlib objects (I only recently became
aware that BCP is derived from DBlib).
[*] Improved error trapping in nsql()
When dbcmd() and dbsqlexec() fail, the previous version explicitly
set $DB_ERROR, effectively overriding the error messages trapped
by the nsql handlers. This patch forces nsql() to trust the
handler routines.
[*] nsql() return empty list, instead of under, on failure
Rather than get a list with one element with an undef value, it
now gets an emtpy list.
[*] nsql handler routines properly trap dblogin() failure
The first argument to these routines is the object ($db), but if
dblogin fails, then this is NOT an object against which one can
make method calls. The nsql handler routines:
nsql_message_handler()
nsql_error_handler()
now both protect the method calls by first verifying that $db is
in fact a referenece. This allows the code to properly trap
errors in dblogin(), and propogate them to $DB_ERROR.
[*] Documentation updates for the above
---------
diff -rc sybperl-2.09_04.orig/BCP/BCP.pm sybperl-2.09_04/BCP/BCP.pm
*** sybperl-2.09_04.orig/BCP/BCP.pm Thu Mar 5 19:26:32 1998
--- sybperl-2.09_04/BCP/BCP.pm Tue May 5 10:52:53 1998
***************
*** 281,287 ****
use vars qw(@ISA @EXPORT $VERSION $Version);
@ISA = qw(Exporter Sybase::DBlib);
! @EXPORT = qw(dbmsghandle dberrhandle TRUE FALSE INT_CANCEL SYBESMSG);
use strict;
--- 281,287 ----
use vars qw(@ISA @EXPORT $VERSION $Version);
@ISA = qw(Exporter Sybase::DBlib);
! @EXPORT = qw(dbmsghandle dberrhandle TRUE FALSE INT_CANCEL SYBESMSG $DB_ERROR);
use strict;
diff -rc sybperl-2.09_04.orig/DBlib/DBlib.pm sybperl-2.09_04/DBlib/DBlib.pm
*** sybperl-2.09_04.orig/DBlib/DBlib.pm Thu Mar 5 19:28:18 1998
--- sybperl-2.09_04/DBlib/DBlib.pm Wed Apr 1 13:38:24 1998
***************
*** 383,388 ****
--- 403,410 ----
#
# Enhanced sql routine.
#
+ sub DB_ERROR { return $DB_ERROR; }
+
sub nsql {
my ($db,$sql,$type) = @_;
my (@res,@data,%data);
***************
*** 396,410 ****
undef $DB_ERROR;
! unless ( $db->dbcmd($sql) ) {
! $DB_ERROR = "Unable to submit SQL to Sybase server.";
! return undef;
! }
! unless ( $db->dbsqlexec ) {
! $DB_ERROR = "Error executing SQL.";
! return undef;
! }
while ( $db->dbresults != $db->NO_MORE_RESULTS ) {
if ( ref $type eq "HASH" || $type eq "HASH" ) {
--- 418,426 ----
undef $DB_ERROR;
! return unless $db->dbcmd($sql);
! return unless $db->dbsqlexec;
while ( $db->dbresults != $db->NO_MORE_RESULTS ) {
if ( ref $type eq "HASH" || $type eq "HASH" ) {
***************
*** 430,436 ****
#
# If we picked any sort of error, then don't feed the data back.
#
! return ( $DB_ERROR ? undef : @res );
}
--- 446,452 ----
#
# If we picked any sort of error, then don't feed the data back.
#
! return ( $DB_ERROR ? () : @res );
}
***************
*** 443,449 ****
$DB_ERROR .= "OS Error: $os_error_msg\n" if defined $os_error_msg;
}
! $db->INT_CANCEL;
}
sub nsql_message_handler {
--- 459,465 ----
$DB_ERROR .= "OS Error: $os_error_msg\n" if defined $os_error_msg;
}
! $db->INT_CANCEL if ref $db;
}
sub nsql_message_handler {
***************
*** 458,463 ****
--- 474,481 ----
$DB_ERROR .= "Line: $line\n" if defined $line;
$DB_ERROR .= "Text: $text\n";
+ return unless ref $db;
+
my ($lineno) = 1;
my $row;
foreach $row ( split(/\n/,$db->dbstrcpy) ) {
diff -rc sybperl-2.09_04.orig/pod/sybperl.pod sybperl-2.09_04/pod/sybperl.pod
*** sybperl-2.09_04.orig/pod/sybperl.pod Thu Mar 26 17:07:52 1998
--- sybperl-2.09_04/pod/sybperl.pod Tue May 5 10:57:39 1998
***************
*** 792,821 ****
print "col1 = $ret\n";
}
! The nsql() routine will return success or failure in the exported
! variable DB_ERROR, and a pair of Sybase message/error handler routines
! are also provided which will use DB_ERROR for the Sybase messages and
! errors as well. However, these must be installed by the client
! application:
dbmsghandle("Sybase::DBlib::nsql_message_handler");
dberrhandle("Sybase::DBlib::nsql_error_handler");
- Success of failure of an nsql() call cannot necessarily be judged
- based on the value of the return code, as an emtpy array may be a
- perfectly valid result for certain sql code.
-
The following code is the proper method for handling errors with use
of nsql.
@ret = $dbh->nsql("select stuff from table where stuff = 'nothing'","ARRAY");
if ( $DB_ERROR ) {
! # error handling code goes here
}
! NOTE: This routine was contributed by W. Phillip Moore.
!
=back
B
--- 792,831 ----
print "col1 = $ret\n";
}
! Success of failure of an nsql() call cannot necessarily be judged
! based on the value of the return code, as an empty array may be a
! perfectly valid result for certain sql code.
+ The nsql() routine will maintain the success or failure state in a
+ variable $DB_ERROR, exported into the callers namespace, and a pair of
+ Sybase message/error handler routines are also provided which will use
+ $DB_ERROR for the Sybase messages and errors as well. However, these
+ must be installed by the client application:
+
dbmsghandle("Sybase::DBlib::nsql_message_handler");
dberrhandle("Sybase::DBlib::nsql_error_handler");
The following code is the proper method for handling errors with use
of nsql.
@ret = $dbh->nsql("select stuff from table where stuff = 'nothing'","ARRAY");
if ( $DB_ERROR ) {
! # error handling code goes here, perhaps:
! die "Unable to get stuff from table: $DB_ERROR";
}
! Both Sybase::DBlib and Sybase::BCP objects support the nsql() method,
! and the $DB_ERROR variable.
+ NOTE: In a previous release, access to $DB_ERROR was provided
+ via a method (i.e. $dbh->DB_ERROR()). This has been deprecated.
+ While it made subclassing of Sybase::DBlib easier, since the $DB_ERROR
+ variable no longer needed to be exported, error checking the
+ constructor (i.e. new()) was not possible using the method (since you
+ could not create a new object).
+
+ NOTE: This routine was contributed by W. Phillip Moore .
+
=back
B
|