End of the Line Moose

Its Big Boss day here in the Moose-Pen

I was thinking of continuing on with the gum-shoe motif in my post but once it funny twice is dull and three times is just annoying so I will just dive into the real work for today. Looking at the test suite of Driver::DBI and fixing what has broke since I changes up the API all these many days ago.

I ran the full suite and the only one that failed was 't/40_joins.t' and it dies with about 300 lines of of waring and fails. Fortuntely 90% of them where;


Use of uninitialized value in hash element at ./Database/Accessor/Driver/DBI.pm line 325

so better get that one first to make my debugging a little easier on the eyes;

What I traced it back to was this input hash for a static link


links => {
type => 'LEFT',
to => { name => 'address' },
conditions => [
{
left => { name => 'id',
view => 'people' },
right => {
name => 'user_id',
view => 'address'
}
}
]
},

it was producing this Predicate instance

'left' => bless( {
'_lookup_name' => 'peopleid',
'view' => 'people',
'name' => 'id'
}, 'Database::Accessor::Element' ),
'right' => bless( {
'_lookup_name' => 'testuser_id',
'view' => 'test',
'name' => 'user_id'
}, 'Database::Accessor::Element' ),
'close_parentheses' => 0,
'condition' => undef,
'open_parentheses' => 0
}, 'Database::Accessor::Predicate' );

and it is missing the 'operator' attribute. I did a little more dumping of instance data and I determined that this bug must be in 'Database::Accessor' as the predicate above comes from there. So back I go.

Well after a few mins of blundering about in the code of Accesosr.pm I discover that I never checked the 'Link' instances to see if their predicates had their 'operators' and 'condition' attributes set to the default if they where not on the input hash.

This little patch;


foreach my $link (@{ $self->links }){
push(@items,$link->conditions);
}

in the BUILD of the 'Database::Accessor' class will fix it I think;

On my next run those annoying warnings are gone!.

Now I am getting a number of errors like this one;


not ok 3 - Left Link with 1 condition retrieve SQL correct

where the details are;

Expected: LEFT JOIN address ON people.id = address.user_id WHERE people.first_name = ?
Generated: LEFT JOIN address ON AND people.id = address.user_id WHERE people.first_name = ?

So that pesky AND is going in there where I do not want it. This one might be a little harder to solve.

I did spend some 30 mins tracking this one down and in the end it was my own silly fault; Yesterday in my eagerness to squish bugs I add this in on the '_elements_check' sub;


$self->_reset_conditions();
if ($type ne 'static');

This was letting my conditions count run on when dealing with any 'static' conditions and thus this code in _check_elements;

$element->predicates->condition(undef)
if ( $self->_add_condition<=1 );

would never fire and so my default 'AND' would go in every time. Taking this out;

$element->predicates->condition(undef);
-- if ( $self->_add_condition<=1 );

fixed all of the other errors in the case and now I am getting a full pass.

However I am not 100% sure that this will cause me problems someplace else so I did a full regression test run and to my surprise I am 100% error free for the fist time in a long time.

Now for the pratical tests and I go though most of them until '30_where_basit.t' and I was hit with the good old;


dynamic Error on Database::Accessor::->RETRIEVE: Element {name=>salary, view=>people} not in
the elements array...

Now the odd thing about this one is I am doing this to cause the above;

...
$da->reset_sorts();
$da->add_sort({name=>'salary',
view=>'people',
descending => 1});
$da->retrieve($dbh);
...

and this the test code I was playing with that started me on the API change. I am just gong to take it out but I do see that the error message that is coming back is rather cryptic. I know that is happens on the retriever but where is this 'salary' Element.

It is a simple case here but what if I had a long set of 'where conditions ' or more that one sort??

I will have to come back and see if I can fix this later for now I will just clean up the test cases.

It all it took another 30 min or so to clean up those extended test case and there where no surprises but I did notice that I was able to call the '$da->reset_gather();' and I was wondering if that would remove the static gather as well.

I checked my tests suite and did not find a test for this so I though one more test for today. So I added this;


$in_hash->{gather} = $gather;
$da = Database::Accessor->new( $in_hash );
ok( ref($da->gather) eq "Database::Accessor::Gather",
'have a static Gather' );
$da->add_gather($gather2);
$da->retrieve( Data::Test->new(), $return );
ok( ref($da->dynamic_gather) eq "Database::Accessor::Gather",
'have a dynamic Gather' );
$da->reset_gather();
ok( ref($da->gather) eq "Database::Accessor::Gather",
'sill have a static Gather' );

to the bottom of '47_dynamic_gathers.t' in Database::Accessor and gave it a try;


ok 21 - elements 1 is a function
ok 22 - have a static Gather
ok 23 - have a dynamic Gather
ok 24 - sill have a static Gather

Great so I can end the day with piece of mind.

mangymoose-b.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