Thinking Moose
For my Moose-pen today I am going to have to put my thinking moose and get out of my class, type, attribute and coercion rut that I have been and and look at how my Accessor will be used by other programmers.
Fortunetly I have not done a good deal of work in this area. So far I have only the retrieve and my 'BUILD' sub that I use to load in the DAD that might be out test. Now this is where I am getting into problems as the way it stands not thing will work fine with static Accessor but I will have problems with adding in dynamic attributes.
To illustrate this lets start with a simple example of two joined tables.
+------------+ +-----------+
| Users | | Countries |
+------------| +-----------+
| f_name | | id |
| l_name | | name |
| country_id | +-----------+
+------------+
now my Accessor call will look like this
my $da = Database::Accessor->new( {
view =>{name => 'users'},
elements =>[{name => 'f_name',
view => 'users' },
{name => 'l_name',
view => 'users' },
{name => 'name',
view => 'countries' },
],
links =>[{to =>{name=>'country'},
type =>'Left',
predicates =>[{left =>{name =>'country_id',
view =>'users'},
right =>{name=>'id',
view=>'country'},
}]},
]})
Now lets say the above is buried in some sort of data tier package that I have to call in my program to get the DA like this
my $client_da = Data::Tier::Clients->new();
Now I would love to be able to do this
$client_da->add_conditions()->({left =>{name=>'id',
view =>'country'},
right=>{param=>'6'}})
Which I could be my adding 'conditions' the 'ARRAY' trait to in and a handles delegate like this 'push=>'add_condtion'. Well here's the rub my Accessor 'conditions' attribute is read only so I can't do that.
I could just create a sub named 'add_conditions' and then add have it access the 'conditions' attribute of the underlying DAD object but because I built the system call like this
my $dad = $da->retrieve(Data::Test->new(),$container);
and so I do not have a DAD until after I do the retrieve command, cart before the horse or in this case moose.
There are some options here I could;
Change the way I instantiate my Accessor by adding it as a pram on new like this
my $da = Database::Accessor->new({DAD=>'Data::Test',
Well that is not what I wanted as I see two problems, first I get into the old DBI dilemma had having to a define the list of DADs my Accessor and havning to create a new version each time someone comes up with a new DAD. Secondly it has been my intention to allow multiple calls to differing data sources so If I wanted to call Mongo and SQL I would have to do this
my $da_sql = Database::Accessor->new({DAD=>'SQL',
my $da_mongo = Database::Accessor->new({DAD=>'Mongo',
I could re-define my API a little say by adding an extra 'execute' step something like this
my $client_da = Data::Tier::Clients->new();
$client_da->retrieve($dbh,$container);
$client_da->add_conditions({left =>{name=>'id',
view =>'country'},
right=>{param=>'6'}});
$client_da->execute();
Well that is a little clunky sort of reminds me of my Apple ][+ days back in the early 80s and playing with DB Master!! You had to create a form, create a report of that form, apply a filter and then run the report. Not a step forward my any means though it could work.
I could extend my Accessor to include a list of dynamic attributes by adding say this one
has dynamic_conditions => (
is => 'rw',
isa => 'ArrayRefofConditions',
…
and then hand these down to the DAD like I do my present ones. So I guess tomorrow I will have to give one of tests approaches a try.
Leave a comment