Even More Moosey

Today I am d going to start filling in my API a little and some might remember the table from this post looking at it a second time I think I need to make a few adjustments to this


+-------------------+-----------------+-----------------+
| Data Accessor | SQL | Mongo |
+-------------------+-----------------+-----------------+
| Param | Param | Param |
| Element | Field | Name Value Pair |
| Predicate | Predicate | Options |
| View | Table (or view) | Collection |
| Condition | Where | Find |
| Link | Join | Lookup |
| Gather | Group | Aggregate |
| Filter | having | ? |
| Sort | Order | Sort |
+-------------------+-----------------+-----------------+

Just so I updated the table to link the 'Condition' to the where clause in SQL and Find in Mongo, and just as a reminder here it is again;
Condition
A logical Predicate supplied to the target database by the Data Accessor to filter data.

Now it makes no sense to have just one condition on a query so this should be a collection of some form so I think I have to redefine this attribute as
Conditions
An Arry-Ref of logical Predicates supplied to the target database by the Data Accessor to filter data.
And in my code I added

has condtions => (
is => 'rw',
isa => 'ArrayRefofPredicates',
coerce => 1,
default => sub { [] },
);

Note I have a new type in there 'ArrayRefofPredicates' so I better add my Predicate class now as well.

{
package
Database::Accessor::Predicate;
use Moose;
has operator => (
is => 'rw',
isa => 'Str',
default => '='
);
has 'name' => (
isa => 'Str',
is => 'rw',
);
has left => (
is => 'rw',
isa => 'Element',
required => 1,
coerce => 1,
);
has right => (
is => 'rw',
isa => 'Element',
required => 1,
coerce => 1,
);
1;

Now some might ask what is a Predicate, well it is noting to be afraid of it is just the fancy work for a logic expression with a left and right value and a logic condtion between and you can see I replicated it above.
Now I will not bore you with the coding for the 'ArrayRefofPredicates' type as it is just the same as the last one 'ArrayRefofElements' but what I will says is I now have to add a 'coerce' command for an Element classe as well
coerce 'Element', from 'HashRef', via { Database::Accessor::Element->new( %{$_} ) };
So lets jump into my test with this little update

...
{ name => 'country', } ],
condtions=>[{left=>{name=>'city'},
operator=>'!=',
right=>{name=>'country'}}]
...

and then a test for that

foreach my $predicate (@{$address->condtions()}){
ok( ref($predicate) eq 'Database::Accessor::Predicate', "Condtion ".$predicate->name()." is a Database::Accessor::Predicate" );
ok( ref($predicate->left()) eq 'Database::Accessor::Element', "Left ".$predicate->left()->name()." is a Database::Accessor::Element");
ok( ref($predicate->right()) eq 'Database::Accessor::Element', "Right ".$predicate->right()->name()." is a Database::Accessor::Element");
ok( $predicate->operator eq '!=',"Operator is !=")
}

of course there is the adjustment to my test count as well, and run my test and get
1..13
ok 1 - use Database::Accessor;
ok 2 - Can only take a View Class
ok 3 - View is a Database::Accessor::View
ok 4 - Element street is a Database::Accessor::Element
ok 5 - Element city is a Database::Accessor::Element
ok 6 - Element country is a Database::Accessor::Element
ok 7 - Condtion country is not a city is a Database::Accessor::Predicate
ok 8 - Left country is a Database::Accessor::Element
ok 9 - Right city is a Database::Accessor::Element
ok 10 - Operator is !=
ok 11 - Address is a Database::Accessor
ok 12 - SQL correct
ok 13 - Mongo Query correct

It so neat that coercion woks so well. You might also notice that I did not update my SQL or Mongo tests at this time. Now there is really no reason for that test to be present as it really belongs in the test suite of the DAD so I think I will drop them as I go along. But just for now I did expand my SQL DAD a little like this

$sql . " WHERE "
if ($self->Condtions());
foreach my $condtion ($self->Condtions()){
return $sql . $self->element_sql($condtion->left)
. " "
.$condtion->operator
. " "
. $self->element_sql($condtion->right);
}

and my test like this

ok(
$address->retrieve( $fake_dbh, $result ) eq
'SELECT street, city, country FROM person AS me WHERE city != country',
'SQL correct'
);

and re-ran my tests and got this.
Can't locate object method "Condtions" via package "Database::Accessor::DAD::SQL" at D:\GitHub\DA-blog\lib/Database/Accessor/DAD/SQL.pm line 22.

Opps forgot to keep my DAD role up to date. Maybe I have to rethink taking those tests out and make something more cute than what I have.

Moose.1.gif

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