Fix More Moose API

Its deal with change day here in the Moose-Pen

Today the first thing I am going to fix is this little line of code in Database::Accessor;


foreach my $link ((@{ $self->links },@{ $self->dynamic_links })){
            my $view = $link->to;
            my $alias = !$view->alias ? $view->name : $view->alias;
            $self->_check_element($link->conditions,0,$alias);
           push(@items,$link->conditions);

namily I want the above to work the same as the other parts of my API ie I only pass down the view name not its alias; here is my first change of the day;

my $view = $link->to;
--          my $alias = !$view->alias ? $view->name : $view->alias;
--          $self->_check_element($link->conditions,0,$alias);
++          $self->_check_element($link->conditions,0,$view->name);

and on my test re-runs I had some problem as expected with '57_dad_elements.t' but I managed to fix all of those up quick quickly as it was just a swap out of one value for another in a test.

Now I get a full test pass for Database::Accessor and I better re-run things from 'Driver::DBI' as well as I may have some problems with that?

After a full fun of the Driver::DBI test suite I did get some problems mostly my table alias on my SQL where not correct; I was getting fails like this;


Expected SQL: SELECT sys_users.last_name, sys_users.first_name FROM people
sys_users
Generated SQL: SELECT people.last_name, people.first_name FROM people
sys_users

so better go and look at that and the first one is the good old 't/15_alias.t' test case;

Now that my API is working as it should I will not have to change any of my tests but what I am doing wrong can be found in the '_field_sql' sub at the final default values of a very long 'if else'


if ( ref($element) eq "Database::Accessor::If" ) {

}
else {
my $sql = $element->name;

$sql = $element->view . "." . $element->name
if ( $use_view and !$self->da_suppress_view_name );
return $sql;
}


So in the above code I was just assuming the view would be correct as the old API would of corrected for table alias name. All I have now is the view name. I could make this change;

...
else {
my $sql = $element->name;
my $view = $element->view;
$view = $self->view->alias()
if ($view eq $self->view->name() and $self->view->alias());
$sql = $element->view . "." . $element->name
if ( $use_view and !$self->da_suppress_view_name );

return $sql;
}


and that works like a charm for ''t/15_alias.t' but for the 't/40_joins.t' case I still get fails like this

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

so obviously on a join I will have to test the Joins view/table for the right sided of condtions. I wonder if there is an easy way to figure this out??

Looking at my '_join_clause' sub I do not call the '_field_sql' directly only very indirectly via the '_predicate_clause' call;


my $clause = join(
" ",
$join->type,
,
Database::Accessor::Driver::DBI::SQL::JOIN,
$self->_table_sql( $join->to, 1 ),
Database::Accessor::Driver::DBI::SQL::ON,
$self->_predicate_clause(
Database::Accessor::Driver::DBI::SQL::JOIN,
$join->conditions()
)
);

so no quick path to salvation here; I have to look into that '_predicate_clause'

Now the fix for this was a little involved and I am not 100% sure I have full coverage with my test suite but me thinks I am very close; All I had to do is pass the 'Joins' filed (to) down along the sub line; In the '_join_clause' sub I start out


$self->_predicate_clause(
Database::Accessor::Driver::DBI::SQL::JOIN,
$join->conditions(),
++ $join->to
)

and then I change the calling signature of the '_predicate_clause' sub a little;

sub _predicate_clause {
my $self = shift;
-- my ( $clause_type, $conditions) = @_;
++ my ( $clause_type, $conditions,$view ) = @_;

and likewise I carry this on though the '_predicate_sql' and the '_field_sql' sub until I get back to the bottom of that big if and I change that code as follows;

}
else {
my $sql = $element->name;
my $view = $element->view;
$view = $self->view->alias()
if ($view eq $self->view->name() and $self->view->alias());

++ if ($in_view) {
++ $view = $in_view->name();
++ $view = $in_view->alias()
++ if ($in_view->alias());
++ }
$sql = $view . "." . $element->name
if ( $use_view and !$self->da_suppress_view_name );

return $sql;

}


and now 't/40_joins.t' passes. I should be safe here as the '$in_view' is only added in with the '_join_clause' so it should be null at all other times and thus not factor in.

Now to see what happens on the full test suite;

Wow I get


All tests successful.
Files=11, Tests=462, ...
Result: PASS

so moving forward now if I can only shake this illness.

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