Back to API Moose

Its go back and rethink day here in the Moose-Pen

You might remember form yesterday I really did not like this bit of code


next
if ((($field->view)
and ($field->view ne $self->view()->name())
or ($self->view()->alias() and ($field->view ne $self->view()->alias()))));

from the '_clean_up_container' sub in Database::Accessor. Today now that my brain is a little less foggy I started to poke about on what I am doing with the various classes before I send them down to the DAD layer. I started to wonder if I mad the same sort of API blunder by trying to do some, in this case 'SQL' codeing high up when all of the should be down in the DAD.

I had a look at the elements class that I was passing down to the DAD in for this $in_hash;


my $in_hash = {
da_compose_only => 1,
update_requires_condition => 0,
delete_requires_condition => 0,
view => {
name => 'people',
alias => 'sys_users'
},
elements => [ { name => 'last_name', }, { name => 'first_name', }, ],
};

and I get these two classes;

bless( {'view' => 'sys_users',
'name' => 'last_name'
}, 'Database::Accessor::Element' ),
bless( {'view' => 'sys_users',
'name' => 'first_name'
}, 'Database::Accessor::Element' )

So at some point I am converting the 'view' to 'sys_users' which though not incorrect, it goes against my API as I am assuming the what ever DB this is being sent to is going to use the 'alias' from the view. This is fine for SQL but might not work for Mongo.

What I should see above for these two elements is


bless( {'view' => 'people',
'name' => 'last_name'
}, 'Database::Accessor::Element' ),
bless( {'view' => 'people',
'name' => 'first_name'
}, 'Database::Accessor::Element' )

and then the Driver::DBI writer figure out what to do with them. That 'view' is really only used when the element is not in the present view as in a join.

I better document and fix this. First I have to stop the view alias being used in the 'Accessor.pm' code.

Fortunately I only do this alias check at one place in the code in the '_check_elements' sub;


if (ref($element) eq 'Database::Accessor::Element'){
unless ( $element->view() ) {
$element->view( $self->view->name() );
$element->view( $self->view()->alias() )
if ( $self->view()->alias() );
$element->view($alias )
if ($alias and $right);
}
}

So I can just drop most of that out.

if (ref($element) eq 'Database::Accessor::Element'){
unless ( $element->view() ) {
$element->view( $self->view->name() );
}
}

and with that change I get what I want

bless( {'view' => 'people',
'name' => 'last_name'
}, 'Database::Accessor::Element' ),
bless( {'view' => 'people',
'name' => 'first_name'
}, 'Database::Accessor::Element' )

Now how many bugs will this cause??

Running though the test suite I found only one test case had some fails; t/57_dad_elements.t and it raises the very valid point as I get an error like this on


Link index 2 condition 2 right- inherits view

What I have here is a 'link/join' and I and checking to see if it is getting is view from the link. Now it is not 100% against my API I think to allow one to do this. Let see if I can add just enough code to get this to work;

if (ref($element) eq 'Database::Accessor::Element'){
unless ( $element->view() ) {
$element->view( $self->view->name() );
++ $element->view($alias )
++ if ($alias and $right);
}
}

I think this is all I need to do becauase the only place I make a call to the '_check_element' sub with an alias is when I am checking a 'link'

foreach my $link ((@{ $self->links },@{ $self->dynamic_links })){
my $view = $link->to;
my $alias = !$view->alias ? $view->name : $view->alias;
$self->_check_element($link->conditions,0,$alias);
push(@items,$link->conditions);
}

and without changing any of my test I now get a full pass. I wonder now what Driver::DBI will look like;

Hmm not too bad only 3 fails and all on 't/15_alias.t' of well something to look at tomorrow.


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