Condiment Moose

It is catch up day here in the Moose-Pen.

I was just about to add in the next operator on my, the 'Like' command but before I did that I added a few more tests for the 'in' operator and with this test;


{ caption => 'in right must not be an hash ref',
type => 'exception',
key => 'conditions',
conditions => [
{
left => { name => 'cost' },
right => { name => 'cost' } ,
operator => 'IN',
},
],
retrieve =>
{ message => 'right can only be a Database::Accessor or an Array Ref' },
},

for the fail I got a a fail;

not ok 1 - retrieve in right must not be an hash ref

so I better fix that.

After some playing about I made this quick change


die("$message '".$predicate->operator."' right can only be a Database::Accessor or an Array Ref!")
-- unless ( ref( $predicate->right()) ne "ARRAY"
++ if ( ref( $predicate->right()) ne "ARRAY"
or ref($predicate->right()) ne "Database::Accessor" );

but all that change accomplished was a 'die' at the frist 'In' tests with;

Database::Accessor::Driver::DBI::Error->Operator 'IN' right can only be a
Database::Accessor or an Array Ref! at D:\GitHub\database-accessor-driver-
dbi\lib/Database/Accessor/Driver/DBI.pm line 330.

Which I think I had before. Looking at what I had entered on the test that is actually a valid, if useless, SQL which should evaluate to

WHERE people.cost in (people.cost)

what would be invalid is any variation on this SQL

WHERE people.cost in (people.cost,SELECT cost FROM somplace)

So what I should check for here is a 'select' statement (DA) in an array of params or elements. So first change my test a little

right => { name => 'cost',
value =>Test::Utils::in_da_sql() },

retrieve =>
{ message => 'Array Ref can not contain a Database::Accessor' },

and my new logic in Driver::DBI;

if ( ref( $predicate->right()) eq "ARRAY") {
foreach my $param (@{ $predicate->right()}){
die("$message '".$predicate->operator."' Array Ref can not contain a
Database::Accessor")
if (ref($param) eq "Database::Accessor::Param"
and ref($param->value) eq "Database::Accessor");
}
}

and I get a pass


77 ok in right must not be and array ref with a DA and params
but this is also valid SQL though again I have never used it;

WHERE people.cost in (SELECT cost FROM somplace, 
SELECT price from Somplace)
So I what I can't have is a mixed array the above has to be fixed to;

            if ( ref( $predicate->right()) eq "ARRAY") {
              my $not_count = 0;
              foreach my $param (@{ $predicate->right()}){
                $not_count++
                  if (ref($param) eq "Database::Accessor::Param"
                     and ref($param->value) eq "Database::Accessor"); 
              }
              die("$message '".$predicate->operator."' Array Ref can not contain a Database::Accessor")
                if ($not_count and scalar(@{ $predicate->right()}) != $not_count);
            }
and that does the trick;

...
ok 77 - retrieve in right must not be and array ref with a DA and params
While I am here I think I will improve on this;

 elsif ($predicate->operator eq Database::Accessor::Driver::DBI::SQL::IS_NULL) {
      
       $clause .= join(" ",$self->_field_sql($predicate->left,1)
                          ,Database::Accessor::Driver::DBI::SQL::IS
                          ,Database::Accessor::Driver::DBI::SQL::NULL
                    );
      
    }
    elsif ($predicate->operator eq 
Database::Accessor::Driver::DBI::SQL::IS_NOT_NULL) {
     
       $clause .= join(" ",$self->_field_sql($predicate->left,1)
                          ,Database::Accessor::Driver::DBI::SQL::IS
                          ,Database::Accessor::Driver::DBI::SQL::NOT
                          ,Database::Accessor::Driver::DBI::SQL::NULL
                    );
      
    }
…
and change it to just one if using an 'or' and just use the '$predicate->operator' in place of the two or three constants;

   elsif ($predicate->operator eq Database::Accessor::Driver::DBI::SQL::IS_NULL
           or $predicate->operator eq 
Database::Accessor::Driver::DBI::SQL::IS_NOT_NULL) {
      
      $clause .= join(" ",$self->_field_sql($predicate->left,1)
                         ,$predicate->operator 
                    );
      
    }
and on retest I still get 100% pass. Not much forward progression today but cleaner code.

HPIM1161a.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