$VERSION = substr(q
$Revision: 1.2 $, 9,-1) -1;
# $Id: Multiplex.pm,v 1.2 1999/07/29 00:11:57 timbo Exp $
# Copyright (c) 1999, Tim Bunce & Thomas Kishel
# You may distribute under the terms of either the GNU General Public
# License or the Artistic License, as specified in the Perl README file.
$drh = undef; # holds driver handle once initialised
$err = 0; # The $DBI::err value
($drh) = DBI
::_new_drh
($class, {
'Attribution' => 'DBD Multiplex by Tim Bunce & Thomas Kishel',
# functions for calling a method for each child handle
sub mplx_do_calls
{ # 'bottom-level' support function to do the calls
my ($method, $handles, $wantarray, $opts) = (shift,shift,shift,shift);
my $errh = $opts->{errh
}; # handle to record error on
my $stop = $opts->{stop_on
}||'';# stop on first 'err' or 'ok' else do all
my $trace= $opts->{trace
};
my @errors; # sparse array paralleling $results[0..n]
warn "mplx_do_calls $method for (@$handles)" if $trace;
foreach my $h (@
$handles) { # child handle
push @results, ($wantarray) ?
[ $h->$method(@_) ]
: [ scalar $h->$method(@_) ];
$errors[ @results-1 ] = [ $err, $errstr ];
DBI
::set_err
($errh, $err, $errstr) if $errh;
warn "mplx_do_calls $h->$method ERROR: $err, $errstr" if $trace;
warn "mplx_do_calls $h->$method OK: @{ $results[-1] }" if $trace;
return (\
@results, \
@errors);
# XXX need variants/flags for
# - call-each-till-first-success-then-stop
# - call-all-return-first-success-else-error
# - call-all-return-most-common-result (eg three-way-voting etc)
# In some cases the default behaviour may depend on the method being called.
# In others the application may want to override that for specific cases
my $handles = $ph->{mplx_h
} || die;
my %opts = ( errh
=> $ph, stop_on
=> 'err', trace
=> $mplx_trace );
= mplx_do_calls
($method, $handles, wantarray, \
%opts, @_);
my $result = $results->[0]; # pick results to return
return $result->[0] unless wantarray;
{ package DBD
::Multiplex
::dr
; # ====== DRIVER ======
sub connect { my ($drh, $dsn, $user, $auth, $attr) = @_;
# XXX parse $dsn and make multiple connects
# need to define good syntax
my $dbh1 = DBI
->connect($dsn, $user, $auth, $attr);
return DBI
::set_err
($drh, $DBI::err
, $DBI::errstr
) unless $dbh1;
my ($this) = DBI
::_new_dbh
($drh, {
{ package DBD
::Multiplex
::db
; # ====== DATABASE ======
my ($statement, $attribs) = @_;
my $handles = $dbh->{mplx_h
} || die;
my %opts = ( errh
=> $dbh );
= DBD
::Multiplex
::mplx_do_calls
('prepare', $handles, wantarray, \
%opts, @_);
my ($outer, $sth) = DBI
::_new_sth
($dbh, {
'Statement' => $statement,
mplx_h
=> [ map { $_->[0] } @
$results ],
# XXX replace this with dynamic info from updated DBI
# XXX needs expanding manually in the short term
use subs
qw(FETCH STORE DESTROY);
my $method = $DBD::Multiplex
::db
::AUTOLOAD
;
$method =~ s/^DBD::Multiplex::db:://;
warn "db AUTOLOAD $method(@_)" if $mplx_trace;
my @results = (wantarray)
?
( DBD
::Multiplex
::mplx_method_all
($method, @_))
: (scalar DBD
::Multiplex
::mplx_method_all
($method, @_));
return $results[0] unless wantarray;
{ package DBD
::Multiplex
::st
; # ====== STATEMENT ======
# XXX replace this with dynamic info from updated DBI
# XXX needs expanding manually in the short term
use subs
qw(execute fetch fetchrow_arrayref finish STORE FETCH DESTROY);
my $method = $DBD::Multiplex
::st
::AUTOLOAD
;
$method =~ s/^DBD::Multiplex::st:://;
warn "st AUTOLOAD $method(@_)" if $mplx_trace;
my @results = (wantarray)
?
( DBD
::Multiplex
::mplx_method_all
($method, @_))
: (scalar DBD
::Multiplex
::mplx_method_all
($method, @_));
return $results[0] unless wantarray;
DBD::Multiplex - A DBI driver multiplexer
$dbh = DBI->connect("dbi:Multiplex:dsn", $user, $passwd);
# See the DBI module documentation for full details