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 => [ ],
conditions=>[{
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 Accessor.pm and have a poke about.
has elements => (
isa => 'ArrayRefofElements',
is => 'rw',
traits => ['Array'],
handles => { element_count => 'count',
},
required=>1,
);
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