Tim Bunce wrote:
> 
> On Wed, Jan 23, 2002 at 04:34:03PM -0800, Schuyler Erle wrote:
> > Hello. I've written a DBD module to wrap other DBD handles and provide
> > intelligent drop-in support for asymmetrically replicated databases
> > (e.g., MySQL v3)... [snip] Suggestions?
> 
> Is it not possible to implement the functionality you need by using
> (or extending) DBD::Multiplex?
> 
> http://www.cpan.org/modules/by-authors/id/T/TK/TKISHEL/Multiplex-1.6.pm
> 
> It's exactly the kind of application that DBD::Multiplex exists for
> and if DBD::Multiplex can't support it now then it needs to be
> fixed/extended so it can. Edwin Pratomo recently contributed
> some master/slave logic that may already do exactly want you need.

Thanks, Tim. I was in fact able to get DBD::Multiplex to work
brilliantly with our application. I ran into two problems, which I would
be happy to help resolve.

First, DBD::Multiplex doesn't ship as a perl module distribution. This
makes it impossible to find or install using the usual CPAN utilities
(e.g. search.cpan.org, CPAN.pm, etc.) ... If Thomas would like
assistance whipping this into a distributable tarball, I'll be honored
to help.

Second, Apache::DBI does the Wrong Thing with DBD::Multiplex, since
DBD::Multiplex always calls DBI->connect() on its subhandles with nested
hashes in the attribute hash. Apache::DBI 1.88 just stringifies these
hashrefs, meaning that it comes up with a different value on effectively
*every* call to connect(). This is definitely a deficiency in
Apache::DBI, so I've cc'd Edmund Mergl and included a full patch at the
end of this e-mail. Edmund -- if you could review my patch, and let me
know whether you'll accept it, and how soon we might expect a new
release of Apache::DBI, I would *really* appreciate it. I'm definitely
open to tinkering with the patch to make it suit your needs and
preferences.

I'd really like to see these two issues resolved as soon as possible,
and I put myself at your respective disposals towards sorting them out.
Thanks very much to everyone involved for your code and your time.

SDE

--- DBI.pm      Fri Jan 12 10:59:00 2001
+++ DBI.pm.new  Mon Jan 28 13:25:31 2002
@@ -23,6 +23,45 @@
 my %LastPingTime; # keeps track of last ping per data_source
 my $Idx;          # key of %Connected and %Rollback.
 
+# Auxilliary code to serialize arguments to connect(). 
+
+my @serializers = (
+    Storable       => "freeze",
+    FreezeThaw     => "freeze",
+    "Data::Denter" => "Indent",
+    "Data::Dumper" => "Dumper"
+);
+
+my $serialize;
+
+sub _load_serializer {
+    my @modules = @serializers;
+    while ( @modules and not $serialize ) {
+       my ($pkg, $method) = splice(@modules, 0, 2);
+       next unless eval "require $pkg";
+       $serialize = $pkg->can( $method );
+    }
+    $serialize = 0 unless ref $serialize; # Don't try again next time.
+    return $serialize;
+}
+
+sub _serialize {
+    _load_serializer() unless defined $serialize;
+    if ( ref $serialize ) {
+       return $serialize->( @_ );
+    } else {
+       require Carp;
+       Carp::carp "References in attribute hash not serialized properly
",
+           "by Apache::DBI (i.e., you should install Storable or ",
+           "Data::Denter)";
+       return _stringify_hash( @_ );
+    }
+}
+
+sub _stringify_hash {
+    my $hash = shift;
+    return join($;, map( "$_=$hash->{$_}", keys %$hash ));
+}
 
 # supposed to be called in a startup script.
 # stores the data_source of all connections, which are supposed to be
created upon
@@ -68,11 +106,15 @@
 
     # the hash-reference differs between calls even in the same
     # process, so de-reference the hash-reference 
+    #
+    # Do a full serialization if there are references in the hash.
+    # Otherwise, just stringify the thing.
     if (3 == $#args and ref $args[3] eq "HASH") {
-       my ($key, $val);
-       while (($key,$val) = each %{$args[3]}) {
-           $Idx .= "$;$key=$val";
-       }
+       if (grep( ref $_, values %{$args[3]} )) {
+           $Idx .= $; . _serialize( $args[3] );
+       } else {
+           $Idx .= $; . _stringify_hash( $args[3] );
+       }
     } elsif (3 == $#args) {
         pop @args;
     }

Reply via email to