Baby Moose All in a Row

It is getting all my Baby Moose in a row day here in the Moose-Pen

So after yesterday's major TARFU with five tests failing and worse three tests reporting false positives I think a good review is needed.

The first thing I am going to clean up is the false positive test like this one;


eval{
$user->update($utils->connect(),
$container);
};
if ($@) {
fail("Update function error=$@");
}
else {
pass("Update function");
}

Now there are two parts to this, a design flaw with the test and a config issue with DBI. I will start with the DBI issue first. It has been a while since I worked directly with DBI and I had to dig pretty deep in my little mind till I remembered, that by default DBI does not raise any errors it only warns. This means that code block in Data::Driver;

eval {
$sth = $dbh->prepare($sql);
foreach my $index (1..$self->param_count()){
$sth->bind_param( $index,$self->params->[$index-1]->value );
}


will always pass unless the db handle, that comes in, happens to have the 'RaiseError' flag set. Now I want is all my DADs to work alike and fail with an error that I can capture. Thus, the first part of the fix is to add this;

has [
qw(da_raise_error_off
)
] => (
is => 'ro',
isa => 'Bool',
default => 0,
traits => ['ENV'],
);

into the Database::Accessor::Roles::Common. That gives me a flag I can use in DADs like this

local $dbh->{RaiseError} = 1
unless($self->raise_error_off);

Now unless the user explicitly ask to turn error throwing off it will be on. Fortunately I had to do this sort of thing before and I learned that the addition of 'local' to the flag set will save me all sorts of trouble. With it 'local' I only effect the db handle for the current block of code, thus keeping the original attributes of the handle unaffected. If this was not set I could see the odd developer pulling their hair out and cursing me, my children and my children's children, if a cached db handle suddenly starts to throw errors rather than warnings because a call to Database::Accessor changed its attributes.

Now that I have that in place it is time to fix the next problem which is the test. I guess I was little excited about getting my tests running with I did the 'update' test above. Accessor.pm is set up not to throw an error if something goes amiss in the underlying DAD. It either returns 1 pass or 0 error and reports that error on the results class. Here is my new test;


ok($user->update($utils->connect(),$container),"Update function");

and I make the same change for the other CRUD functions and this little change;

unless($user->result()->is_error) {
ok($user->result()->set->[0]->[0] eq 'Uchanged','username changed');
ok($user->result()->set->[0]->[1] eq 'Achanged','address changed');
}
else{
fail("No Result set->[0]->[0]");
fail("No Result set->[0]->[1]");
}

around the tests check a result set so I do not get an

Can't use an undefined value as an ARRAY reference

with a 255 exit because there is no result set. Now I run my test case and I get;

ok 1 - Create function
ok 2 - One row effected
not ok 3 - Update function
not ok 4 - Two rows effected
not ok 5 - retrieve function
not ok 6 - One row returned
not ok 7 - No Result set->[0]->[0]
not ok 8 - No Result set->[0]->[1]
ok 9 - delete function
not ok 10 - One row Deleted
not ok 11 - retrieve function
not ok 12 - No Result set

Now that my test case is reporting correctly I think I have my topic for tomorrow's post.

DSC08536a.jpg


Leave a comment

About byterock

user-pic Long time Perl guy, a few CPAN mods allot of work on DBD::Oracle and a few YAPC presentations