Baby Moose Promise

It is keeping promises day here in the Moose-pen

Keeping in step with yesterday's post I am continuing with my code-review of Accessor.pm. It was suggested that I explain a little more on my reasons for doing most of the validation on the Accessor.pm side rater than the DAD side so here we go.

As today’s title suggests I want to make a promise to the DAD from the Accessor.pm that all the attributes that I have passed down to it are ready to go into a the requested CRUD query, so only a minimal amount of extra Database::Accessor::Driver logic is required.

What this mean is that I will have to carefully explain to potential users that the Update and Create methods only work with the initial set of 'Elements' and only with elements that have the same View. I have already did this one in yesterday's post.

I also have a bunch of Element flags that will effect this list and I will only deliver to the DAD the Elements that will be acted on. In that vain my problem for today is to pass to the DAD only those Elements that will be effected by the CRUD action.

I had a quick think and I saw that I presently do this


my $dad = $driver->new(
{
view => $self->view,
elements => $self->elements,
conditions => $self->conditions,
...

so all I need to do is create a private function to replace that call to $self->elements and here is was I came up with;
         
private_method get_dad_elements => sub {
my $self = shift;
my ( $action) = @_;

my @allowed;
foreach my $element (@{$self->elements}){

next
if ($action eq Database::Accessor::Constants::CREATE
and $element->only_retrieve
or $element->no_create);
next
if ($action eq Database::Accessor::Constants::UPDATE
and $element->only_retrieve
or $element->no_update);

next
if ($action eq Database::Accessor::Constants::UPDATE
and $element->no_retrieve);
push(@allowed,$element);
}
return \@allowed;
};

and then

-- elements => $self->elements,
++ elements => $self->get_dad_elements($action),

and I need a test for this but I will do that a little later.

I could carry this basic concept along as there are situations where some DAD attributes should be empty for a given action.

A good example is 'Gather' which is 'Group By' in SQL and '$group' in Mongo both of which cannot be used directly (well easily anyway) with and Create Update and Delete type actions. As the 'Filter' only works with a 'Gather' that is something else I can't do and finally the 'Sort' is another attribute that can only be used with a 'Retrieve'. To eliminate all these attributes, or at least blank them out, I did the following;


dynamic_links => $self->dynamic_links,
--gathers => $self->gathers,
++gathers => ($action eq Database::Accessor::Constants::RETRIEVE) ? $self->gathers : [],
--dynamic_gathers => $self->dynamic_gathers ,
++dynamic_gathers => ($action eq Database::Accessor::Constants::RETRIEVE) ? $self->dynamic_gathers : [],
--filters => $self->filters,
++filters => ($action eq Database::Accessor::Constants::RETRIEVE) ? $self->filters : [],
--dynamic_filters =>$self->dynamic_filters ,
++dynamic_filters => ($action eq Database::Accessor::Constants::RETRIEVE) ? $self->dynamic_filters : [],
--sorts => $self->sorts,
++sorts => ($action eq Database::Accessor::Constants::RETRIEVE) ? $self->sorts : [],
--dynamic_sorts =>$self->dynamic_sorts,
++dynamic_sorts => ($action eq Database::Accessor::Constants::RETRIEVE) ? $self->dynamic_sorts : [],,
++da_compose_only => $self->da_compose_only,

Now I am not a big fan of the ? : operators but I do like to use them in situations as the above which reminds me of my 'c' coding days and how much I enjoy missing those days.

So that only leaves for now the 'is_identity' flag on the 'Element' which will be used in the future to handle 'identity' fields for some DBs, though the only one that comes to mind is Oracle so I have at least one that will be used by the DAD.

I was thinking how I was going to handle 'Function' and 'Expression' classes that are in the 'Elements' array, and I think I do not have to do anything with as it is valid to use a function and an expression in Updates and Create. So that just leaves 'Delete' and I think I have nothing special to do with that one as
you can do 'Links' (SQL Joins) on a Delete so that is about it.

Now a test for all of this but I think that is tomorrow's post.

44ed4d2a0d119ef3014bc7e1ada4fc1e.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