$Id: README,v 1.8 1999/05/17 05:57:21 mpeppler Exp $
	
	   DBD::Sybase  --  a Sybase DBI driver for Perl 5.

   Copyright (c) 1996, 1997, 1998, 1999  Michael Peppler

   You may distribute under the terms of either the GNU General Public
   License or the Artistic License, as specified in the Perl README file.

		WARNING: THIS IS ALPHA SOFTWARE.
		    IT IS INCOMPLETE!
		IT IS POSSIBLY UNRELIABLE!



This Sybase DBI driver is built using the Sybase OpenClient Client
Library (aka CT-library). You will need to have that installed before
you can do anything with this package. You will also need Tim Bunce's
DBI module, latest release. DBI is available from CPAN, in

    "CPAN"/authors/id/TIMB/DBI/DBI-1.xx-tar.gz

The Sybase OpenClient libraries are of course available from Sybase.
For Linux you can get the full Sybase ASE 11.0.3.3 release for free
(this includes the server and the client libraries.) 
See http://linux.sybase.com for details, or my homepage 
(http://www.mbay.net/~mpeppler).

DBD::Sybase is a reasonably complete implementation of the DBI spec, but 
there are still some features that are missing. Please see the DBD::Sybase
man page for details.

Recent changes:

Release 0.15

	Added an error handler callback which can intercept error messages
	and provide ad-hoc handling of error situations.
	In AutoCommit == 0 mode, use CS_OPT_CHAINXACTS mode on the 
	server instead of issuing explicit transactions.
	$dbh->LongReadLen and LongTruncOK now work.
	First cut at the type_info() and type_info_all() methods.
	perl Makefile.PL now attempts to discover the libraries directly
	based on what it finds in $SYBASE/lib.

Release 0.14

	Added a 'timeout' connection attribute (contributed by Tom May) 
	to handle timeout errors during normal processing.
	SQL PRINT statements are now handled by a warn() call (instead
	a printf() call) so that they can be caught by a __WARN__ handler.
        Make sure $dbh->do() returns immediately when an error is encountered.
	Include dbd-sybase.pod (Tim Bunce's Driver Summary for DBD::Sybase).



Building:

This version attempts to find out which libraries it needs by looking
at $SYBASE/lib. This behaviour is experimental, and will only work
on Unix systems (ie on Win32 and VMS you still have to edit the CONFIG
file the old way), but appears to work fine on the two systems I have
access to (Sybase 11.5/Solaris 7 & Sybase 11.0.3.3/linux). It assumes
that $SYBASE is set and points to the Sybase installation directory that
you want to use to build DBD::Sybase.

Run perl Makefile.PL in the normal way, without editing CONFIG. If 
there are no error messages (ie no missing libraries), run make & make test.

If either of these fail you will probably need to use the CONFIG file.

To force perl Makefile.PL to make use of the information in the CONFIG file
you need to run it with the --file option:
	perl Makefile.PL --file

The CONFIG file can be used to set certain system variables that
are needed for the build. 
	SYBASE is the root directory of your Sybase installation. DBD::Sybase
	will use $SYBASE/lib and $SYBASE/include during the build.

	EXTRA_LIBS lists any extra libraries that are required on your
	system. For example, Solaris 2.x needs -ltli. See your OS specific
	documentation supplement from Sybase to determine what is required.

	DBI_INCLUDE is the directory where DBI installed its include files.
	Makefile.PL will normally deduce this directory from perl's Config
	module, so you only need to set this if Makefile.PL fails.

	LINKTYPE. Uncomment and set to 'static' if you want to build
	DBD::Sybase statically (ie always included in a new perl binary).

Run perl Makefile.PL, make, make test.

If everything's fine, run "make install" to move the files to your 
installed perl library tree.

On Solaris 2.x make test will fail if LD_LIBRARY_PATH is set and has
/usr/lib or /lib before $SYBASE/lib. This is because both Solaris 2.x
and Sybase have a library called libintl.so, and if /usr/lib is placed 
before $SYBASE/lib in LD_LIBRARY_PATH the dynamic loader will search
the wrong library when loading DBD::Sybase. In general it is not
necessary to set LD_LIBRARY_PATH on Solaris, and it is only rarely
necessary to include /usr/lib or /lib in the LD_LIBRARY_PATH as those
directories will be searched by default.


The regression tests are minimal at the moment so don't necessarily
believe all is fine if the tests succeed...



Let me repeat: this is ALPHA software - testing has been minimal!!!



So what is implemented?

Lets take the list at the bottom of DBI.pm:

$dbh = DBI->connect($data_source, $username, $auth);
$dbh = DBI->connect($data_source, $username, $auth, \%attr);

$rc  = $dbh->disconnect;

$rv  = $dbh->do($statement);
$rv  = $dbh->do($statement, \%attr);			%attr is ignored
$rv  = $dbh->do($statement, \%attr, @bind_values);	%attr is ignored

$sth = $dbh->prepare($statement);
$sth = $dbh->prepare($statement, \%attr);		%attr is ignored

$rc = $sth->bind_col($col_num, \$col_variable);
$rc = $sth->bind_columns(\%attr, @list_of_refs_to_vars_to_bind);

$rv = $sth->bind_param($param_num, $bind_value);
$rv = $sth->bind_param($param_num, $bind_value, $bind_type);	$bind_type ignored
$rv = $sth->bind_param($param_num, $bind_value, \%attr);	%attr ignored

$rv = $sth->execute;
$rv = $sth->execute(@bind_values);

@row_ary  = $sth->fetchrow_array;
$ary_ref  = $sth->fetchrow_arrayref;
$hash_ref = $sth->fetchrow_hashref;

$rc = $sth->finish;

$rv = $sth->rows;

$rc  = $dbh->commit;
$rc  = $dbh->rollback;

$sql = $dbh->quote($string);

$rc  = $h->err;
$str = $h->errstr;
$rv  = $h->state;				Not supported


$sth->{NAME}       (\@)				Yes
$sth->{NULLABLE}   (\@)				Yes
$sth->{TYPE}       (\@)				Yes
$sth->{PRECISION}  (\@)				Yes
$sth->{SCALE}      (\@)				Yes

$sth->{NUM_OF_FIELDS}  ($)			Yes
$sth->{NUM_OF_PARAMS}  ($)			Yes

---------------------------------------------------------------


Special behaviour:
==================

The Sybase API allows you to submit SQL code to the server that can
return multiple result sets. When using Sybase::CTlib, for example, this is
handled by using a nested while loop:

while($dbh->ct_results($restype) == CS_SUCCEED) {
    next unless $dbh->ct_fetchable($restype);

    while(@dat = $dbh->ct_fetch) {
       ....
    }
}

The DBI API does not (normally) handle this situation. But because
this situation can arise without the user knowing (typically when
executing a stored procedure) I have coded fetchrow() logic
so that multiple result sets can still be fetched. 

This is done via special attribute in $sth (syb_more_results) which
you should check after $sth->fetchrow() returns an empty array. If this
attribute is true, then you can call $sth->fetchrow() again to get the
next result set.

One problem with this is that the standard $sth attributes (NAME,
NULLABLE, etc) will have the values of the NEXT result set if
$sth->{syb_more_results} is true and $sth->fetchrow returns an empty
array.

Here is an example script:


use DBI;

$dbh = DBI->connect('dbi:Sybase:', 'mpeppler', '', {RaiseError => 1});

$sth = $dbh->prepare("
select log_date, log_by from BugTrack..bug_log
where id < 10
order by id
compute count(id) by id
select * from BugTrack..bug where id < 10

declare \@acc char(10)
declare \@date datetime
declare \@open_val money
declare \@open_val_t money
select \@acc='abcd', \@date='Jan 1 1997'
exec BugTrack..t_proc \@acc, \@date out, \@open_val out, \@open_val_t out
");

$sth->execute;
AGAIN:
while($dat = $sth->fetchrow_hashref) {
    foreach (keys(%$dat)) {
	print "$_: $dat->{$_} ";
    }
    print "\n";
}
if($sth->{syb_more_results}) {
    print "More data on the way...\n";
    goto AGAIN;
}

__END__

Comments, criticism, etc. welcome!

Michael
--
Michael Peppler, Data Migrations, Inc.
mpeppler@datamig.com - http://www.mbay.net/~mpeppler

