Author: timbo
Date: Tue Mar  9 06:42:56 2004
New Revision: 206

Modified:
   dbi/trunk/lib/DBD/DBM.pm
   dbi/trunk/lib/DBD/File.pm
   dbi/trunk/t/50dbm.t
Log:
Fix up (or workaround) some issues with DBD::File/DBD::DBM
Works under PurePerl now (though there is an undef warning from BerkeleyDB
when inserting a record with a null column - but the warning only appears
with DBI::PurePerl - not sure what's happening there. Jeff!)


Modified: dbi/trunk/lib/DBD/DBM.pm
==============================================================================
--- dbi/trunk/lib/DBD/DBM.pm    (original)
+++ dbi/trunk/lib/DBD/DBM.pm    Tue Mar  9 06:42:56 2004
@@ -111,6 +111,7 @@
                 #
                 $var = 'dbm_' . $var unless $var =~ /^dbm_/
                                      or     $var eq 'f_dir';
+               # XXX should pass back to DBI via $attr for connect() to STORE
                $this->{$var} = $val;
            }
        }
@@ -174,7 +175,7 @@
 sub FETCH ($$) {
     my ($dbh, $attrib) = @_;
 
-    return $dbh->SUPER::STORE($attrib) unless $attrib =~ /^dbm_/;
+    return $dbh->SUPER::FETCH($attrib) unless $attrib =~ /^dbm_/;
 
     # throw an error if it has our prefix but isn't a valid attr name
     #
@@ -295,6 +296,8 @@
     my $ext =  '' if $dbm_type eq 'GDBM_File'
                   or $dbm_type eq 'DB_File'
                   or $dbm_type eq 'BerkeleyDB';
+    # XXX NDBM_File on FreeBSD (and elsewhere?) may actually be Berkeley
+    # behind the scenes and so create a single .db file.
     $ext = '.pag' if $dbm_type eq 'NDBM_File'
                   or $dbm_type eq 'SDBM_File'
                   or $dbm_type eq 'ODBM_File';
@@ -303,18 +306,11 @@
         if defined $dbh->{dbm_tables}->{$file}->{ext};
     $ext = '' unless defined $ext;
 
-    die "Cannot CREATE '$file$ext', already exists!"
-        if $createMode and (-e "$file$ext");
-    die "Cannot open '$file$ext', file not found!"
-        if !$createMode
-       and !($self->{command} eq 'DROP')
-       and !(-e "$file$ext");
-
     my $open_mode = O_RDONLY;
        $open_mode = O_RDWR                 if $lockMode;
        $open_mode = O_RDWR|O_CREAT|O_TRUNC if $createMode;
 
-    my(%h,$tie_type);
+    my($tie_type);
 
     if ( $serializer ) {
        require 'MLDBM.pm';
@@ -328,6 +324,19 @@
        $tie_type = $dbm_type;
     }
 
+    # Second-guessing the file extension isn't great here (or in general)
+    # could replace this by trying to open the file in non-create mode
+    # first and dieing if that succeeds.
+    # Currently this test doesn't work where NDBM is actually Berkeley (.db)
+    die "Cannot CREATE '$file$ext', already exists!"
+        if $createMode and (-e "$file$ext");
+
+    # let tie() fail instead of this explicit test
+    #die "Cannot open '$file$ext', file not found!"
+    #   if !$createMode
+    #  and !($self->{command} eq 'DROP')
+    #  and !(-e "$file$ext");
+
     # LOCKING
     #
     my($nolock,$lockext,$lock_table);
@@ -353,6 +362,7 @@
     #
     # allow users to pass in a pre-created tied object
     #
+    my @tie_args;
     if ($dbm_type eq 'BerkeleyDB') {
        my $DB_CREATE = 1;  # but import constants if supplied
        my $DB_RDONLY = 16; #
@@ -368,16 +378,17 @@
        $flags{'-Flags'} = $DB_CREATE if $lockMode or $createMode;
         my $t = 'BerkeleyDB::Hash';
            $t = 'MLDBM' if $serializer;
-        if ( $self->{command} ne 'DROP') {
-            eval { tie %h, $t, -Filename=>$file, %flags }
-        }
-        # warn $BerkeleyDB::db_version;
+       @tie_args = ($t, -Filename=>$file, %flags);
+    }
+    else {
+        @tie_args = ($tie_type, $file, $open_mode, 0666);
     }
-    elsif (!%h) {
-        eval { tie(%h, $tie_type, $file, $open_mode, 0666) }
-            unless $self->{command} eq 'DROP';
+    my %h;
+    if ( $self->{command} ne 'DROP') {
+       my $tie_class = shift @tie_args;
+       eval { tie %h, $tie_class, @tie_args };
+       die "Cannot tie(%h $tie_class @tie_args): $@" if $@;
     }
-    die "Cannot tie file '$file': $@" if $@;
 
 
     # COLUMN NAMES

Modified: dbi/trunk/lib/DBD/File.pm
==============================================================================
--- dbi/trunk/lib/DBD/File.pm   (original)
+++ dbi/trunk/lib/DBD/File.pm   Tue Mar  9 06:42:56 2004
@@ -45,6 +45,7 @@
     my($class, $attr) = @_;
     my $drh = eval '$' . $class . "::drh";
     if (!$drh) {
+        DBI->setup_driver('DBD::File');
        if (!$attr) { $attr = {} };
        if (!exists($attr->{Attribution})) {
            $attr->{Attribution} = eval '$' . $class . '::ATTRIBUTION';
@@ -137,7 +138,7 @@
        $attr->{'f_dir'} : $haveFileSpec ? File::Spec->curdir() : '.';
     my($dirh) = Symbol::gensym();
     if (!opendir($dirh, $dir)) {
-        DBI::set_err($drh, 1, "Cannot open directory $dir");
+        $drh->set_err(1, "Cannot open directory $dir: $!");
        return undef;
     }
     my($file, @dsns, %names, $driver);
@@ -173,11 +174,10 @@
 sub prepare ($$;@) {
     my($dbh, $statement, @attribs)= @_;
 
-    # create a 'blank' dbh
+    # create a 'blank' sth
     my $sth = DBI::_new_sth($dbh, {'Statement' => $statement});
 
     if ($sth) {
-       $@ = '';
        my $class = $sth->FETCH('ImplementorClass');
        $class =~ s/::st$/::Statement/;
        my($stmt);
@@ -190,9 +190,8 @@
              and $dbh->{sql_statement_version} > 1)
            {
             my $parser = $dbh->{csv_sql_parser_object};
-            eval { $parser ||= $dbh->func('csv_cache_sql_parser_object') };
+            $parser ||= eval { $dbh->func('csv_cache_sql_parser_object') };
             if ($@) {
-                undef $@;
                $stmt = eval { $class->new($statement) };
            }
             else {
@@ -203,7 +202,7 @@
            $stmt = eval { $class->new($statement) };
        }
        if ($@) {
-           DBI::set_err($dbh, 1, $@);
+           $dbh->set_err(1, $@);
            undef $sth;
        } else {
            $sth->STORE('f_stmt', $stmt);
@@ -231,7 +230,7 @@
         return $dbh->{$attrib};
     }
     # else pass up to DBI to handle
-    return $dbh->DBD::_::db::FETCH($attrib);
+    return $dbh->SUPER::FETCH($attrib);
 }
 
 sub STORE ($$$) {
@@ -268,7 +267,7 @@
        $dbh->{$attrib} = $value;
        return 1;
     }
-    return $dbh->DBD::_::db::STORE($attrib, $value);
+    return $dbh->SUPER::STORE($attrib, $value);
 }
 
 sub DESTROY ($) {
@@ -327,7 +326,7 @@
        my($dir) = $dbh->{f_dir};
        my($dirh) = Symbol::gensym();
        if (!opendir($dirh, $dir)) {
-           DBI::set_err($dbh, 1, "Cannot open directory $dir");
+           $dbh->set_err(1, "Cannot open directory $dir: $!");
            return undef;
        }
        my($file, @tables, %names);
@@ -338,7 +337,7 @@
            }
        }
        if (!closedir($dirh)) {
-           DBI::set_err($dbh, 1, "Cannot close directory $dir");
+           $dbh->set_err(1, "Cannot close directory $dir: $!");
            return undef;
        }
 
@@ -346,7 +345,7 @@
        if (!$dbh2) {
            $dbh2 = $dbh->{'csv_sponge_driver'} = DBI->connect("DBI:Sponge:");
            if (!$dbh2) {
-               DBI::set_err($dbh, 1, $DBI::errstr);
+               $dbh->set_err(1, $DBI::errstr);
                return undef;
            }
        }
@@ -357,7 +356,7 @@
        my $sth = $dbh2->prepare("TABLE_INFO", { 'rows' => [EMAIL PROTECTED],
                                                 'NAMES' => $names });
        if (!$sth) {
-           DBI::set_err($dbh, 1, $dbh2->errstr());
+           $dbh->set_err(1, $dbh2->errstr);
        }
        $sth;
     }
@@ -443,8 +442,7 @@
     my $sth = shift;
     my $data = $sth->{f_stmt}->{data};
     if (!$data  ||  ref($data) ne 'ARRAY') {
-       DBI::set_err($sth, 1,
-                    "Attempt to fetch row from a Non-SELECT statement");
+       $sth->set_err(1, "Attempt to fetch row from a Non-SELECT statement");
        return undef;
     }
     my $dav = shift @$data;
@@ -479,7 +477,7 @@
        return $sth->{$attrib};
     }
     # else pass up to DBI to handle
-    return $sth->DBD::_::st::FETCH($attrib);
+    return $sth->SUPER::FETCH($attrib);
 }
 
 sub STORE ($$$) {
@@ -489,7 +487,7 @@
        $sth->{$attrib} = $value;
        return 1;
     }
-    return $sth->DBD::_::st::STORE($attrib, $value);
+    return $sth->SUPER::STORE($attrib, $value);
 }
 
 sub DESTROY ($) {

Modified: dbi/trunk/t/50dbm.t
==============================================================================
--- dbi/trunk/t/50dbm.t (original)
+++ dbi/trunk/t/50dbm.t Tue Mar  9 06:42:56 2004
@@ -48,6 +48,7 @@
 );
 for my $mldbm ( @mldbm_types ) {
     for my $dbm_type ( @dbm_types ) {
+       print "\n--- Using $dbm_type ($mldbm) ---\n";
         do_test( $dbm_type, $sql{$mldbm}, $mldbm );
     }
 }
@@ -63,10 +64,10 @@
     my $dsn ="dbi:DBM(RaiseError=1,PrintError=0):dbm_type=$dtype;mldbm=$ml";
     my $dbh = DBI->connect( $dsn );
     if ($DBI::VERSION >= 1.37 ) { # needed for install_method
-        diag( $dbh->dbm_versions );
+        print $dbh->dbm_versions;
     }
     else {
-        diag( $dbh->func('dbm_versions') );
+        print $dbh->func('dbm_versions');
     }
     ok($dbh);
 
@@ -97,9 +98,10 @@
             2 => '12',
             3 => '13',
         } if $ml;
+       print " $sql\n";
         my $sth = $dbh->prepare($sql) or die $dbh->errstr;
         $sth->execute;
-        die $sth->errstr if $sth->errstr and $sql !~ /DROP/;
+        die $sth->errstr if $sth->err and $sql !~ /DROP/;
         next unless $sql =~ /SELECT/;
         my $results='';
         # Note that we can't rely on the order here, it's not portable,

Reply via email to