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

Reply via email to