DBD-Unify
view release on metacpan or search on metacpan
lib/DBD/Unify.pm view on Meta::CPAN
# Copyright (c) 1999-2026 H.Merijn Brand
#
# You may distribute under the terms of either the GNU General Public
# License or the Artistic License, as specified in the Perl README file.
use 5.008004;
use strict;
use warnings;
package DBD::Unify;
our $VERSION = "0.96";
=head1 NAME
DBD::Unify - DBI driver for Unify database systems
=head1 SYNOPSIS
# Examples marked NYT are Not Yet Tested, they might work
# all others have been tested.
# man DBI for explanation of each method (there's more than listed here)
$dbh = DBI->connect ("DBI:Unify:[\$dbname]", "", $schema, {
AutoCommit => 0,
ChopBlanks => 1,
uni_unicode => 0,
uni_verbose => 0,
uni_scanlevel => 2,
});
$dbh = DBI->connect_cached (...); # NYT
$dbh->do ($statement);
$dbh->do ($statement, \%attr);
$dbh->do ($statement, \%attr, @bind);
$dbh->commit;
$dbh->rollback;
$dbh->disconnect;
$all = $dbh->selectall_arrayref ($statement);
@row = $dbh->selectrow_array ($statement);
$col = $dbh->selectcol_arrayref ($statement);
$sth = $dbh->prepare ($statement);
$sth = $dbh->prepare ($statement, \%attr);
$sth = $dbh->prepare_cached ($statement); # NYT
$sth->execute;
@row = $sth->fetchrow_array;
$row = $sth->fetchrow_arrayref;
$row = $sth->fetchrow_hashref;
$all = $sth->fetchall_arrayref;
$sth->finish;
# Statement has placeholders like where field = ?
$sth = $dbh->prepare ($statement);
$sth->bind_param ($p_num, $bind_value); # NYT
$sth->bind_param ($p_num, $bind_value, $bind_type); # NYT
$sth->bind_param ($p_num, $bind_value, \%attr); # NYT
$sth->bind_col ($col_num, \$col_variable); # NYT
$sth->bind_columns (@list_of_refs_to_vars_to_bind);
$sth->execute (@bind_values);
$cnt = $sth->rows;
$sql = $dbh->quote ($string);
$err = $dbh->err;
$err = $sth->err;
$str = $dbh->errstr;
$str = $sth->errstr;
$stt = $dbh->state;
$stt = $sth->state;
For large DB fetches the combination $sth->bind_columns ()
with $sth->fetchrow_arrayref is the fastest (DBI
documentation).
=cut
# The POD text continues at the end of the file.
###############################################################################
use Carp;
use DBI 1.42;
use DynaLoader ();
use vars qw(@ISA);
lib/DBD/Unify.pm view on Meta::CPAN
CURRENT_USER => $user,
});
# Connect to the database..
DBD::Unify::db::_login ($dbh, $dbname, $user, $auth) or return;
# if ($attr) {
# if ($attr->{dbd_verbose}) {
# $dbh->trace ("DBD");
# }
# }
$dbh;
} # connect
sub data_sources {
my ($dr_h) = @_;
$dr_h->{Warn} and
Carp::carp "\$dr_h->data_sources () not defined for Unify\n";
"";
} # data_sources
1;
####### Database ##############################################################
package DBD::Unify::db;
$DBD::Unify::db::imp_data_size = 0;
sub parse_trace_flag {
my ($dbh, $name) = @_;
# print STDERR "# Flags: $name\n";
return 0x7FFFFF00 if $name eq "DBD"; # $h->trace ("DBD"); -- ALL
# return 0x01000000 if $name eq "select"; # $h->trace ("SQL|select");
# return 0x02000000 if $name eq "update"; # $h->trace ("1|update");
# return 0x04000000 if $name eq "delete";
# return 0x08000000 if $name eq "insert";
return $dbh->SUPER::parse_trace_flag ($name);
} # parse_trace_flag
sub type_info_all {
#my ($dbh) = @_;
require DBD::Unify::TypeInfo;
return [ @$DBD::Unify::TypeInfo::type_info_all ];
} # type_info_all
sub get_info {
my ($dbh, $info_type) = @_;
require DBD::Unify::GetInfo;
my $v = $DBD::Unify::GetInfo::info{int $info_type};
ref $v eq "CODE" and $v = $v->($dbh);
return $v;
} # get_info
sub private_attribute_info {
return {
dbd_verbose => undef,
uni_verbose => undef,
uni_unicode => undef,
};
} # private_attribute_info
sub ping {
my $dbh = shift;
$dbh->prepare ("select USER_NAME from SYS.DATABASE_USERS") or return 0;
return 1;
} # ping
sub prepare {
my ($dbh, $statement, @attribs) = @_;
# Strip comments
$statement = join "" => map {
my $s = $_;
$s =~ m/^'.*'$/ or $s =~ s/(--.*)$//m;
$s;
} split m/('[^']*')/ => $statement;
# create a 'blank' sth
my $sth = DBI::_new_sth ($dbh, {
Statement => $statement,
});
# Setup module specific data
# $sth->STORE ("driver_params" => []);
# $sth->STORE ("NUM_OF_PARAMS" => ($statement =~ tr/?//));
DBD::Unify::st::_prepare ($sth, $statement, @attribs) or return;
$sth;
} # prepare
sub _is_or_like {
my ($fld, $val) = @_;
$val =~ m/[_%]/ ? "$fld like '$val'" : "$fld = '$val'";
} # _is_or_like
sub table_info {
my $dbh = shift;
my ($catalog, $schema, $table, $type, $attr);
ref $_[0] or ($catalog, $schema, $table, $type) = splice @_, 0, 4;
if ($attr = shift) {
ref ($attr) eq "HASH" or
Carp::croak qq{usage: table_info ({ TABLE_NAME => "foo", ... })};
exists $attr->{TABLE_SCHEM} and $schema = $attr->{TABLE_SCHEM};
exists $attr->{TABLE_NAME} and $table = $attr->{TABLE_NAME};
exists $attr->{TABLE_TYPE} and $type = $attr->{TABLE_TYPE};
}
if ($catalog) {
$dbh->{Warn} and
Carp::carp "Unify does not support catalogs in table_info\n";
return;
}
my @where;
$schema and push @where => _is_or_like ("OWNR", $schema);
$table and push @where => _is_or_like ("TABLE_NAME", $table);
$type and $type = uc substr $type, 0, 1;
$type and push @where => _is_or_like ("TABLE_TYPE", $type);
local $" = " and ";
lib/DBD/Unify.pm view on Meta::CPAN
(Huge) amounts, floats, reals and doubles are returned as strings for which
numeric context (perl's NV's) has been invoked already, so adding zero to
force convert to numeric context is not needed.
Chars are returned as strings (perl's PV's).
Chars, Dates, Huge Dates and Times are returned as strings (perl's PV's).
Unify represents midnight with 00:00, not 24:00.
=item connect
connect ("DBI:Unify:dbname[;options]" [, user [, auth [, attr]]]);
Options to the connection are passed in the data-source
argument. This argument should contain the database
name possibly followed by a semicolon and the database options
which are ignored.
Since Unify database authorization is done using grant's using the
user name, the I<user> argument may be empty or undef. The I<auth>
field will be used as a default schema. If the I<auth> field is empty
or undefined connect will check for the environment variable $USCHEMA
to use as a default schema. If neither exists, you will end up in your
default schema, or if none is assigned, in the schema PUBLIC.
At the moment none of the attributes documented in DBI's "ATTRIBUTES
COMMON TO ALL HANDLES" are implemented specifically for the Unify
DBD driver, but they might have been inherited from DBI. The I<ChopBlanks>
attribute is implemented, but defaults to 1 for DBD::Unify.
The Unify driver supports "uni_scanlevel" to set the transaction scan
level to a value between 1 and 16 and "uni_verbose" to set DBD specific
debugging, allowing to show only massages from DBD-Unify without using
the default DBI->trace () call.
The connect call will result in statements like:
CONNECT;
SET CURRENT SCHEMA TO PUBLIC; -- if auth = "PUBLIC"
SET TRANSACTION SCAN LEVEL 7; -- if attr has { uni_scanlevel => 7 }
local database
connect ("/data/db/unify/v63AB", "", "SYS")
=item AutoCommit
It is recommended that the C<connect> call ends with the attributes
S<{ AutoCommit => 0 }>, although it is not implemented (yet).
If you don't want to check for errors after B<every> call use
S<{ AutoCommit => 0, RaiseError => 1 }> instead. This will C<die> with
an error message if any DBI call fails.
=item Unicode
By default, this driver is completely Unicode unaware: what you put into
the database will be returned to you without the encoding applied.
To enable automatic decoding of UTF-8 when fetching from the database,
set the C<uni_unicode> attribute to a true value for the database handle
(statement handles will inherit) or to the statement handle.
$dbh->{uni_unicode} = 1;
When CHAR or TEXT fields are retrieved and the content fetched is valid
UTF-8, the value will be marked as such.
=item re-connect
Though both the syntax and the module support connecting to different
databases, even at the same time, the Unify libraries seem to quit
connecting to a new database, even if the old one is closed following
every rule of precaution.
To be safe in closing a handle of all sorts, undef it after it is done with,
it will than be destroyed. (As of 0.12 this is tried internally for handles
that proved to be finished)
explicit:
my $dbh = DBI->connect (...);
my $sth = $dbh->prepare (...);
:
$sth->finish; undef $sth;
$dbh->disconnect; undef $dbh;
or implicit:
{ my $dbh = DBI->connect (...);
{ my $sth = $dbh->prepare (...);
while (my @data = $sth->fetchrow_array) {
:
}
} # $sth implicitly destroyed by end-of-scope
$dbh->disconnect;
} # $dbh implicitly destroyed by end-of-scope
=item do
$dbh->do ($statement)
This is implemented as a call to 'EXECUTE IMMEDIATE' with all the
limitations that this implies.
=item commit and rollback invalidates open cursors
DBD::Unify does warn when a commit or rollback is issued on a $dbh
with open cursors.
Possibly a commit/rollback/disconnect should also undef the $sth's.
(This should probably be done in the DBI-layer as other drivers will
have the same problems).
After a commit or rollback the cursors are all ->finish'ed, i.e. they
are closed and the DBI/DBD will warn if an attempt is made to fetch
from them.
A future version of DBD::Unify might re-prepare the statement.
=back
=head2 Stuff implemented in perl
( run in 0.694 second using v1.01-cache-2.11-cpan-39bf76dae61 )