Author: timbo
Date: Wed Mar 21 14:56:10 2007
New Revision: 9292
Modified:
dbi/trunk/lib/DBD/Gofer.pm
dbi/trunk/lib/DBI/Gofer/Execute.pm
dbi/trunk/lib/DBI/Gofer/Transport/mod_perl.pm
Log:
Support prepare & prepare_cached naturally (ie prepare_cached works on both
client and gofer server)
Support bind_param_array and execute_array (but not execute_for_fetch)
Modified: dbi/trunk/lib/DBD/Gofer.pm
==============================================================================
--- dbi/trunk/lib/DBD/Gofer.pm (original)
+++ dbi/trunk/lib/DBD/Gofer.pm Wed Mar 21 14:56:10 2007
@@ -423,7 +423,10 @@
my ($sth, $sth_inner) = DBI::_new_sth($dbh, {
Statement => $statement,
- go_prepare_call => [ 'prepare', $statement, $attr ],
+ go_prepare_call => [
+ $attr->{go_prepare} || $dbh->{go_prepare} || 'prepare',
+ $statement, $attr
+ ],
# go_method_calls => [], # autovivs if needed
go_request => $dbh->{go_request},
go_trans => $dbh->{go_trans},
@@ -441,11 +444,11 @@
}
sub prepare_cached {
- my ($dbh, @args)= @_;
- my $sth = $dbh->SUPER::prepare_cached(@args)
- or return undef;
- $sth->{go_prepare_call}->[0] = 'prepare_cached';
- return $sth;
+ my ($dbh, $sql, $attr, $if_active)= @_;
+ return $dbh->SUPER::prepare_cached($sql, {
+ ($attr ? %$attr : ()),
+ go_prepare => 'prepare_cached',
+ }, $if_active);
}
}
@@ -649,6 +652,18 @@
return $sth->set_err(1, $msg);
}
+ # sub bind_param_array
+ # we use DBI's default, which sets $sth->{ParamArrays}{$param} = $value
+ # and calls bind_param($param, undef, $attr) if $attr.
+
+ sub execute_array {
+ my $sth = shift;
+ my $attr = shift;
+ $sth->bind_param_array($_, $_[$_-1]) for ([EMAIL PROTECTED]);
+ push @{ $sth->{go_method_calls} }, [ 'execute_array', $attr ];
+ return $sth->go_sth_method($attr);
+ }
+
}
1;
@@ -737,7 +752,7 @@
=head3 Fewer Network Round-trips
-DBD::Gofer sends as few requests as possible.
+DBD::Gofer sends as few requests as possible (dependent on the policy being
used).
=head3 Thin Clients / Unsupported Platforms
@@ -779,7 +794,7 @@
Some drivers provide sth attributes that relate to the row that was just
fetched (e.g., Sybase and syb_result_type). These aren't supported.
-=head1 CAVEATS
+=head1 GENERAL CAVEATS
A few important things to keep in mind when using DBD::Gofer:
@@ -792,7 +807,7 @@
This is an easy trap to fall into and a difficult one to debug.
The pipeone transport may help as it forces a new connection for each request.
(It is very slow though, so I plan to add a way for the stream driver to use
-connect instead of connect cache to achive the same effect much more
efficiently.)
+connect instead of connect_cache to achive the same effect much more
efficiently.)
=head2 Driver-private Database Handle Attributes
@@ -811,23 +826,6 @@
Multiple resultsets are supported only if the driver supports the
more_results() method
(an exception is made for DBD::Sybase).
-=head2 Use of last_insert_id requires a minor code change
-
-To enable use of last_insert_id you need to indicate to DBD::Gofer that you'd
-like to use it. You do that my adding a C<go_last_insert_id_args> attribute to
-the do() or prepare() method calls. For example:
-
- $dbh->do($sql, { go_last_insert_id_args => [...] });
-
-or
-
- $sth = $dbh->prepare($sql, { go_last_insert_id_args => [...] });
-
-The array reference should contains the args that you want passed to the
-last_insert_id() method.
-
-XXX allow $dbh->{go_last_insert_id_args} = [] to enable it by default?
-
=head2 Statement activity that also updates dbh attributes
Some drivers may update one or more dbh attributes after performing activity on
@@ -845,11 +843,32 @@
The RootClass and DbTypeSubclass attributes are not passed to the Gofer server.
-=head2 Array methods are not fully supported
+=head1 CAVEATS FOR SPECIFIC METHODS
+
+=head2 last_insert_id
+
+To enable use of last_insert_id you need to indicate to DBD::Gofer that you'd
+like to use it. You do that my adding a C<go_last_insert_id_args> attribute to
+the do() or prepare() method calls. For example:
+
+ $dbh->do($sql, { go_last_insert_id_args => [...] });
+
+or
+
+ $sth = $dbh->prepare($sql, { go_last_insert_id_args => [...] });
-The array methods (bind_param_inout bind_param_array bind_param_inout_array
execute_array execute_for_fetch)
-use the DBI's default fallback behaviour which simply executes the statement
once for each tuple.
-So they work, but offer no speed up.
+The array reference should contains the args that you want passed to the
+last_insert_id() method.
+
+=head2 execute_for_fetch
+
+The array methods bind_param_array() and execute_array() are supported.
+When execute_array() is called the data is serialized and executed in a single
+round-trip to the Gofer server.
+
+The execute_for_fetch() method currently isn't optimised, it uses the DBI
+fallback behaviour of executing each tuple individually.
+(It could be implemented as a wrapper for execute_array() - patches welcome.)
=head1 TRANSPORTS
@@ -994,7 +1013,7 @@
=head1 TODO
-This is just a random brain dump...
+This is just a random brain dump... (There's more in Changes)
Document policy mechanism
@@ -1004,8 +1023,6 @@
Caching of get_info values
-prepare vs prepare_cached
-
add hooks into transport base class for checking & updating a result set cache
ie via a standard cache interface such as:
http://search.cpan.org/~robm/Cache-FastMmap/FastMmap.pm
@@ -1026,9 +1043,7 @@
Make sth_result_attr more like dbh_attributes (using '*' etc)
-Add @val = FETCH_many(@names) to DBI in C and use in Gofer/Execute
-
-Add ($err, $errstr, $state) = $h->get_err
+Add @val = FETCH_many(@names) to DBI in C and use in Gofer/Execute?
Implement DBI::st::TIEHASH etc in C.
Modified: dbi/trunk/lib/DBI/Gofer/Execute.pm
==============================================================================
--- dbi/trunk/lib/DBI/Gofer/Execute.pm (original)
+++ dbi/trunk/lib/DBI/Gofer/Execute.pm Wed Mar 21 14:56:10 2007
@@ -113,7 +113,7 @@
# just a quick hack for now
my $stats = $self->{stats};
- if (++$stats->{requests_served} % 1000 == 0) { # XXX config
+ if (++$stats->{_requests_served} % 1000 == 0) { # XXX config
# discard CachedKids from time to time
my %drivers = DBI->installed_drivers();
while ( my ($driver, $drh) = each %drivers ) {
@@ -209,9 +209,11 @@
sub execute_request {
my ($self, $request) = @_;
# should never throw an exception
+
+ DBI->trace_msg("-----> execute_request\n");
+
my @warnings;
local $SIG{__WARN__} = sub { push @warnings, @_; warn @_ if $local_log };
- DBI->trace_msg("-----> execute_request\n");
my $response = eval {
@@ -223,8 +225,7 @@
? $self->execute_sth_request($request)
: $self->execute_dbh_request($request);
};
- $response = $self->new_response_with_err(undef, $@)
- if $@;
+ $response ||= $self->new_response_with_err(undef, $@);
$response->warnings([EMAIL PROTECTED]) if @warnings;
DBI->trace_msg("<----- execute_request\n");
@@ -423,6 +424,11 @@
1;
+__END__
+
+TODO
+
+Pruning of cached dbh and sth
=head1 AUTHOR AND COPYRIGHT
Modified: dbi/trunk/lib/DBI/Gofer/Transport/mod_perl.pm
==============================================================================
--- dbi/trunk/lib/DBI/Gofer/Transport/mod_perl.pm (original)
+++ dbi/trunk/lib/DBI/Gofer/Transport/mod_perl.pm Wed Mar 21 14:56:10 2007
@@ -316,6 +316,11 @@
configurations can be mix-n-matched to create specific configurations for
specific location urls.
+=head1 Apache::Status
+
+DBI::Gofer::Transport::mod_perl installs extra menu items into the
Apache::Status
+menu, so long as the Apache::Status is loaded first.
+
=head1 AUTHOR AND COPYRIGHT
The DBD::Gofer, DBD::Gofer::* and DBI::Gofer::* modules are