Subject: | DBunit can't deal with mixed-case or upper-case columns |
I ran into this issue with Test::DBunit. MySQL, PgSQL, possibly others
allow column names to be case-insensitive, but DBunit only does
case-sensitive comparisons. e.g. in your database:
create table Foo (
FooID int(10) primary key not null auto_increment,
Bar varchar(255) not null,
);
In your test:
my @data = (
Foo => [ FooID => 1, Bar => 'blah' ],
Foo => [ FooID => 2, Bar => 'mung' ],
);
dataset_ok( @data );
expected_dataset_ok( @data, Foo => [] );
What happens:
In retrive_table_data, DBIx::Connection->primary_key_columns returns [
'FooID' ] but the $result_set hash contains keys 'fooid' and 'bar'
because DBIx::Connection uses the NAME_lc attribute of DBI::st.
primary_key_hash_value returns undef because it can't find FooID in the
result set, and so $key = undef, causing this warning:
Use of uninitialized value in hash element at
/usr/lib/perl5/site_perl/5.8.8/DBUnit.pm line 1760.
Perl uses the empty string ('') and so all the rows get entered into
$result using the same key, which causes the test to fail.
To fix this, primary_key_hash_value should lowercase all the keys of
$field_values and lowercase all of $primary_key_columns prior to
building $result.
The test still fails because the resultset returns lowercase columns
while expected_dataset_ok is given mixed-case column names. To fix this,
lowercase all the keys of $exp_dataset at the start of compare_datasets.
A patch is attached as a starting point.
Richard Harris
Internet Services Developer
Netcraft Ltd.
Subject: | dbunit_case_insensitive_columns.patch |
--- DBUnit.pm 2009-08-26 03:42:43.000000000 +0000
+++ DBUnit.new.pm 2009-08-26 03:45:18.000000000 +0000
@@ -1699,7 +1700,6 @@
sub compare_datasets {
my ($dataset, $exp_dataset, $table_name, @keys) = @_;
- $exp_dataset = lc_keys($exp_dataset);
for my $k (@keys) {
if (ref $exp_dataset->{$k}) {
my $result = $exp_dataset->{$k}->($dataset->{$k});
@@ -1774,10 +1774,9 @@
sub primary_key_hash_value {
my ($primary_key_columns, $field_values) = @_;
- $field_values = lc_keys($field_values);
my $result = "";
- for (map { lc } @$primary_key_columns) {
- return undef unless defined $field_values->{$_};
+ for (@$primary_key_columns) {
+ return undef unless defined($field_values->{$_});
$result .= $field_values->{$_} . "#";
}
$result;
@@ -1875,13 +1874,6 @@
$content;
}
-# Lowercase all of the keys in a hash
-sub lc_keys {
- my $hash = shift;
- my %new = map { lc $_, $hash->{$_} } keys %$hash;
- return \%new;
-}
-
1;
__END__