Author: timbo
Date: Tue Mar 27 15:16:45 2007
New Revision: 9353

Modified:
   dbi/trunk/Changes
   dbi/trunk/lib/DBD/File.pm
   dbi/trunk/lib/DBD/Gofer.pm
   dbi/trunk/lib/DBD/Gofer/Policy/Base.pm
   dbi/trunk/lib/DBD/Gofer/Policy/classic.pm
   dbi/trunk/lib/DBD/Gofer/Policy/rush.pm
   dbi/trunk/lib/DBI/Gofer/Execute.pm
   dbi/trunk/t/85gofer.t

Log:
Implement skip_default_methods policy:
pass back info from server to client about which dbh methods are not overridden 
by the driver,
those need not be forwarded by gofer because the DBIs local default method will 
do the same.
(One t/85gofer test fails because Gofer needs to be smarted with the rush 
policy)


Modified: dbi/trunk/Changes
==============================================================================
--- dbi/trunk/Changes   (original)
+++ dbi/trunk/Changes   Tue Mar 27 15:16:45 2007
@@ -8,6 +8,9 @@
 
 
http://buildd.debian.org/fetch.cgi?&pkg=libdbi-perl&ver=1.54-1&arch=m68k&stamp=1174636818&file=log
 
+Implement quote() in C fallback to perl _quote() if $datatype true (and not 
var/char?)
+Implement tie in C.
+
 Add attr-passthru to prepare()?
 Terminology for client and server ends
 Document user/passwd issues at the various levels of the stack

Modified: dbi/trunk/lib/DBD/File.pm
==============================================================================
--- dbi/trunk/lib/DBD/File.pm   (original)
+++ dbi/trunk/lib/DBD/File.pm   Tue Mar 27 15:16:45 2007
@@ -381,6 +381,7 @@
 
 sub quote ($$;$) {
     my($self, $str, $type) = @_;
+    if (!defined($str)) { return "NULL" }
     if (defined($type)  &&
        ($type == DBI::SQL_NUMERIC()   ||
         $type == DBI::SQL_DECIMAL()   ||
@@ -392,7 +393,6 @@
         $type == DBI::SQL_TINYINT())) {
        return $str;
     }
-    if (!defined($str)) { return "NULL" }
     $str =~ s/\\/\\\\/sg;
     $str =~ s/\0/\\0/sg;
     $str =~ s/\'/\\\'/sg;

Modified: dbi/trunk/lib/DBD/Gofer.pm
==============================================================================
--- dbi/trunk/lib/DBD/Gofer.pm  (original)
+++ dbi/trunk/lib/DBD/Gofer.pm  Tue Mar 27 15:16:45 2007
@@ -298,10 +298,19 @@
         func
     )) {
         my $policy_name = "cache_$method";
+        my $super_name  = "SUPER::$method";
         my $sub = sub {
             my $dbh = shift;
             my $rv;
 
+            # if we know the remote side doesn't override the DBI's default 
method
+            # then we might as well just call the DBI's default method on the 
client
+            # (which may, in turn, call other methods that are forwarded, like 
get_info)
+            if ($dbh->{dbi_default_methods}{$method} && 
$dbh->{go_policy}->skip_default_methods()) {
+                $dbh->trace_msg("    !! $method: using local default as remote 
method is also default\n");
+                return $dbh->$super_name(@_);
+            }
+
             my $cache;
             my $cache_key;
             if (my $cache_it = $dbh->{go_policy}->$policy_name(undef, $dbh, 
@_)) {
@@ -352,6 +361,15 @@
         my $super_name  = "SUPER::$method";
         my $sub = sub {
             my $dbh = shift;
+
+            # if we know the remote side doesn't override the DBI's default 
method
+            # then we might as well just call the DBI's default method on the 
client
+            # (which may, in turn, call other methods that are forwarded, like 
get_info)
+            if ($dbh->{dbi_default_methods}{$method} && 
$dbh->{go_policy}->skip_default_methods()) {
+                $dbh->trace_msg("    !! $method: using local default as remote 
method is also default\n");
+                return $dbh->$super_name(@_);
+            }
+
             # false:    use remote gofer
             # 1:        use local DBI default method
             # code ref: use the code ref

Modified: dbi/trunk/lib/DBD/Gofer/Policy/Base.pm
==============================================================================
--- dbi/trunk/lib/DBD/Gofer/Policy/Base.pm      (original)
+++ dbi/trunk/lib/DBD/Gofer/Policy/Base.pm      Tue Mar 27 15:16:45 2007
@@ -16,6 +16,7 @@
 
 my %policy_defaults = (
     skip_connect_check => 0,
+    skip_default_methods => 0,
     skip_prepare_check => 0,
     skip_ping => 0,
     dbh_attribute_update => 'every',

Modified: dbi/trunk/lib/DBD/Gofer/Policy/classic.pm
==============================================================================
--- dbi/trunk/lib/DBD/Gofer/Policy/classic.pm   (original)
+++ dbi/trunk/lib/DBD/Gofer/Policy/classic.pm   Tue Mar 27 15:16:45 2007
@@ -24,6 +24,9 @@
     # most code doesn't rely on sth attributes being set after prepare
     skip_prepare_check => 1,
 
+    # we're happy to use local method if that's the same as the remote
+    skip_default_methods => 1,
+
     # ping is not important for DBD::Gofer and most transports
     skip_ping => 1,
 

Modified: dbi/trunk/lib/DBD/Gofer/Policy/rush.pm
==============================================================================
--- dbi/trunk/lib/DBD/Gofer/Policy/rush.pm      (original)
+++ dbi/trunk/lib/DBD/Gofer/Policy/rush.pm      Tue Mar 27 15:16:45 2007
@@ -24,6 +24,9 @@
     # most code doesn't rely on sth attributes being set after prepare
     skip_prepare_check => 1,
 
+    # we're happy to use local method if that's the same as the remote
+    skip_default_methods => 1,
+
     # ping is almost meaningless for DBD::Gofer and most transports anyway
     skip_ping => 1,
 

Modified: dbi/trunk/lib/DBI/Gofer/Execute.pm
==============================================================================
--- dbi/trunk/lib/DBI/Gofer/Execute.pm  (original)
+++ dbi/trunk/lib/DBI/Gofer/Execute.pm  Tue Mar 27 15:16:45 2007
@@ -19,6 +19,8 @@
 our $VERSION = sprintf("0.%06d", q$Revision$ =~ /(\d+)/o);
 
 our $local_log = $ENV{DBI_GOFER_TRACE} || $ENV{DBI_GOFER_LOCAL_LOG};
+our @all_dbh_methods = sort map { keys %$_ } $DBI::DBI_methods{db}, 
$DBI::DBI_methods{common};
+our %all_dbh_methods = map { $_ => DBD::_::db->can($_) } @all_dbh_methods;
 
 __PACKAGE__->mk_accessors(qw(
     check_connect
@@ -265,6 +267,9 @@
         # XXX piggyback installed_methods onto dbh_attributes for now
         $dbh_attr_values{dbi_installed_methods} = { DBI->installed_methods };
         
+        # XXX piggyback default_methods onto dbh_attributes for now
+        $dbh_attr_values{dbi_default_methods} = _get_default_methods($dbh);
+        
         $response->dbh_attributes(\%dbh_attr_values);
     }
 
@@ -432,6 +437,22 @@
 }
 
 
+sub _get_default_methods {
+    my ($dbh) = @_;
+    # returns a ref to a hash of dbh method names for methods which the driver
+    # hasn't overridden i.e., quote(). These don't need to be forwarded via 
gofer.
+    my $ImplementorClass = $dbh->{ImplementorClass} or die;
+    my %default_methods;
+    for my $method (@all_dbh_methods) {
+        my $dbi_sub = $all_dbh_methods{$method}       || 42;
+        my $imp_sub = $ImplementorClass->can($method) || 42;
+        next if $imp_sub != $dbi_sub;
+        #warn("default $method\n");
+        $default_methods{$method} = 1;
+    }
+    return \%default_methods;
+}
+
 1;
 __END__
 

Modified: dbi/trunk/t/85gofer.t
==============================================================================
--- dbi/trunk/t/85gofer.t       (original)
+++ dbi/trunk/t/85gofer.t       Tue Mar 27 15:16:45 2007
@@ -169,14 +169,16 @@
     ok $go_request_count;
 
     ok $dbh->do("DROP TABLE fruit");
-    is $go_request_count + 1, $dbh->{go_request_count};
+    is ++$go_request_count, $dbh->{go_request_count};
 
+    my $use_remote = ($policy->skip_default_methods) ? 0 : 1;
+    warn "use_remote=$use_remote (policy=$policy_name, transport=$transport) 
$dbh->{dbi_default_methods}\n";
     $dbh->data_sources({ foo_bar => $go_request_count });
-    is $go_request_count + 2, $dbh->{go_request_count};
+    is $dbh->{go_request_count}, $go_request_count + 1*$use_remote;
     $dbh->data_sources({ foo_bar => $go_request_count }); # should use cache
-    is $go_request_count + 2, $dbh->{go_request_count};
+    is $dbh->{go_request_count}, $go_request_count + 1*$use_remote;
     @_=$dbh->data_sources({ foo_bar => $go_request_count }); # no cached yet 
due to wantarray
-    is $go_request_count + 3, $dbh->{go_request_count};
+    is $dbh->{go_request_count}, $go_request_count + 2*$use_remote;
 
 SKIP: {
     skip "caching of metadata methods returning sth not yet implemented", 2;

Reply via email to