Some Moose Today

Its a good day for code but a bad one for posts here in the Moose-Pen

I started off today by adding in some 38 new tests to 40_joins.t in Driver::DBI and after one or two runs to get rid of some typos in my expected results they are all passing. So like the title says a good day for code but a bad one for posts as I have nothing to much to report on.

Undaunted I moved into 50_having.t and the first thing I did was rename it to 50_group_by.t as that is a little more SQLish.

After coming up with some 34 new tests and after a few runs to get rid of my usual typos in my expected SQL I still got two errors on the generated SQLthat where far from obvious.

In both cases

not ok 3 - group by with 3 elements retrieve SQL correct
not ok 9 - group by with 3 elements mixed retrieve SQL correct

the error was on the generated SQL when I had only elements present. A close look at the expected and generated SQL I released I had an extra space tacked on the end of the generated SQL

# Expected SQL--> “GROUP BY people.first_name, left(people.last_name,?), people.user_id”
# Generated SQL->”GROUP BY people.first_name, left(people.last_name,?), people.user_id “

which was easy enough to get rid of by modifying the '_group_by_clause' sub to account for the fact I may not have any conditions on my group by.

-- return " ".join(" "
-- ,Database::Accessor::Driver::DBI::SQL::GROUP_BY
-- ,$self->_fields_sql($having->elements())
-- ,$having->condition_count >=1
-- ? join(" "
-- ,Database::Accessor::Driver::DBI::SQL::HAVING
-- ,$self->_predicate_clause( Database::Accessor::Driver::DBI::SQL::GROUP_BY,
-- $having->conditions ) )
-- : "");
++ my $group_by = " ".join(" "
++ ,Database::Accessor::Driver::DBI::SQL::GROUP_BY
++ ,$self->_fields_sql($having->elements()));
++ $group_by .= join(" "
++ ,""
++ ,Database::Accessor::Driver::DBI::SQL::HAVING
++ ,$self->_predicate_clause( Database::Accessor::Driver::DBI::SQL::GROUP_BY,
++ $having->conditions ) )
++ if ($self->gather->condition_count >=1);
++ return $group_by;

Finally for today I wanted to see what would happen if I added in a gather without elements;

elements => [ ],
left => {
name => 'last_name',

and unfortunately this did not fail as I expected but generated this SQL;

SELECT people.first_name, people.last_name, people.user_id FROM people GROUP BY HAVING people.last_name = ?

as the above is incorrect for any SQL I think I will have to go back into and have a poke about.

has elements => (
isa => 'ArrayRefofElements',
is => 'rw',
traits => ['Array'],
handles => { element_count => 'count',

The above it the code for the 'elements' from Accessor and had left the elements key out of the hash I would get the expected error

Attribute (elements) is required at …

as the 'required' trait is there. So the problem lies in my coercion code someplace.

So I do have a neat little bug for today; This coerce code;

coerce 'Gather', from 'HashRef', via { Database::Accessor::Gather->new( %{$_} ) };

found in 'Database::Accessor::Types' will have to change. In this case the quick an easy way to do this is check the incoming '$_' and when it has an 'elements' key and it is an array ref and it is empty die with the appropriate message. This patch accomplishes that;

coerce 'Gather', from 'HashRef', via {
die "Attribute (elements) does not pass the type constraint because:
Validation failed for 'ArrayRefofElements' with []"
if (exists($_->{elements})
and ref($_->{elements}) eq 'ARRAY'
and scalar(@{$_->{elements}} ==0));
Database::Accessor::Gather->new( %{$_} ) };

With the above code I will get this error back from the system;

Attribute (elements) does not pass the type constraint because: Validation failed for 'ArrayRefofElements' with [] at …

The next thing to do was drop that test from my test case and then carry on. To think I though today was going to be a very boring post. Who knew.


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