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',

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'},

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->add_conditions({left =>{name=>'id',
view =>'country'},

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

About byterock

user-pic Long time Perl guy, a few CPAN mods allot of work on DBD::Oracle and a few YAPC presentations