#!perl -w use strict; use File::Path; use Test::More; use Config qw(%Config); use DBI; use vars qw( @mldbm_types @dbm_types ); BEGIN { # Be conservative about what modules we use here. # We don't want to be tripped up by a badly installed module # so we remove from @INC any version-specific dirs that don't # also have an arch-specific dir. Plus, for 5.8 remove any <=5.7 # 0=SQL::Statement if avail, 1=DBI::SQL::Nano # next line forces use of Nano rather than default behaviour $ENV{DBI_SQL_NANO}=1; if (eval { require 'MLDBM.pm'; }) { push @mldbm_types, 'Data::Dumper' if eval { require 'Data/Dumper.pm' }; push @mldbm_types, 'Storable' if eval { require 'Storable.pm' }; } if ("@ARGV" eq "all") { # test with as many of the 5 major DBM types as are available for (qw( SDBM_File GDBM_File NDBM_File ODBM_File DB_File BerkeleyDB )){ push @dbm_types, $_ if eval { require "$_.pm" }; } } elsif (@ARGV) { @dbm_types = @ARGV; } else { # we only test SDBM_File by default to avoid tripping up # on any broken DBM's that may be installed in odd places. # It's only DBD::DBM we're trying to test here. @dbm_types = ("SDBM_File"); } print "Using DBM modules: @dbm_types\n"; print "Using MLDBM serializers: @mldbm_types\n" if @mldbm_types; my $num_tests = (1+@mldbm_types) * @dbm_types * 11; if (!$num_tests) { plan skip_all => "No DBM modules available"; } else { plan tests => $num_tests; } } my $dir = './test_output'; rmtree $dir; mkpath $dir; my( $two_col_sql,$three_col_sql ) = split /\n\n/,join '',; for my $mldbm ( '', @mldbm_types ) { my $sql = ($mldbm) ? $three_col_sql : $two_col_sql; my @sql = split /\s*;\n/, $sql; for my $dbm_type ( @dbm_types ) { print "\n--- Using $dbm_type ($mldbm) ---\n"; do_test( $dbm_type, \@sql, $mldbm ); } } rmtree $dir; sub do_test { my $dtype = shift; my $stmts = shift; my $mldbm = shift; $|=1; # The DBI can't test locking here, sadly, because of the risk it'll hang # on systems with broken NFS locking daemons. # (This test script doesn't test that locking actually works anyway.) my $dsn ="dbi:DBM(RaiseError=1,PrintError=0):dbm_type=$dtype;mldbm=$mldbm;lockfile=0"; my $dbh = DBI->connect( $dsn ); if ($DBI::VERSION >= 1.37 ) { # needed for install_method print $dbh->dbm_versions; } else { print $dbh->func('dbm_versions'); } isa_ok($dbh, 'DBI::db'); # test if it correctly accepts valid $dbh attributes # eval {$dbh->{f_dir}=$dir}; ok(!$@); eval {$dbh->{dbm_mldbm}=$mldbm}; ok(!$@); # test if it correctly rejects invalid $dbh attributes # eval {$dbh->{dbm_bad_name}=1}; ok($@); for my $sql ( @$stmts ) { $sql =~ s/\S*fruit/${dtype}_fruit/; # include dbm type in table name $sql =~ s/;$//; # in case no final \n on last line of __DATA__ #diag($sql); my $null = ''; my $expected_results = { 1 => 'oranges', 2 => 'apples', 3 => $null, }; $expected_results = { 1 => '11', 2 => '12', 3 => '13', } if $mldbm; print " $sql\n"; my $sth = $dbh->prepare($sql) or die $dbh->errstr; $sth->execute; 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, # different DBMs (or versions) will return different orders. while (my ($key, $value) = $sth->fetchrow_array) { ok exists $expected_results->{$key}; is $value, $expected_results->{$key}; } is $DBI::rows, keys %$expected_results; } $dbh->disconnect; } 1; __DATA__ DROP TABLE IF EXISTS fruit; CREATE TABLE fruit (dKey INT, dVal VARCHAR(10)); INSERT INTO fruit VALUES (1,'oranges' ); INSERT INTO fruit VALUES (2,'to_change' ); INSERT INTO fruit VALUES (3, NULL ); INSERT INTO fruit VALUES (4,'to delete' ); UPDATE fruit SET dVal='apples' WHERE dKey=2; DELETE FROM fruit WHERE dVal='to delete'; SELECT * FROM fruit; DROP TABLE fruit; DROP TABLE IF EXISTS multi_fruit; CREATE TABLE multi_fruit (dKey INT, dVal VARCHAR(10), qux INT); INSERT INTO multi_fruit VALUES (1,'oranges' , 11 ); INSERT INTO multi_fruit VALUES (2,'apples' , 0 ); INSERT INTO multi_fruit VALUES (3, NULL , 13 ); INSERT INTO multi_fruit VALUES (4,'to_delete', 14 ); UPDATE multi_fruit SET qux='12' WHERE dKey=2; DELETE FROM multi_fruit WHERE dKey=4; SELECT dKey,qux FROM multi_fruit; DROP TABLE multi_fruit;