PEPPLER.ORG
Michael Peppler
Sybase Consulting
Menu
Home
Sybase on Linux
Install Guide for Sybase on Linux
General Sybase Resources
General Perl Resources
Freeware
Sybperl
Sybase::Simple
DBD::Sybase
BCP Tool
Bug Tracker
Mailing List Archive
Downloads Directory
FAQs
Sybase on Linux FAQ
Sybperl FAQ
Personal
Michael Peppler's resume

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