Baby Moose Grows Strong
Back to Accessor.pm day here in the Moose-Pen.
Starting where I left off in my last post I needed to figure out some way to get the raw query results back from Accessor.pm. I gave this a little though as there are a number of things to consider. First I never want to expose the underlying DAD to the end user of Accessor.pm, Second I have to make the name of call generic in the same way the CRUD calls are. Finally as I see this used largely for debugging it should return more than just a string.
To address the three above I started with an new sub called 'raw_query' ;
sub raw_query {
my $self = shift;
my ($conn, $type) = @_;
$self->_try_one_of(Database::Accessor::Constants::OPERATORS)
unless (exists( Database::Accessor::Constants::OPERATORS->{ uc($type) } ));
my $drivers = $self->_ldad();
my $driver = $drivers->{ ref($conn) };
die "$type No Database::Accessor::Driver loaded for "
…
and the I quickly saw I was getting into anti-pattern territory as the code after 'my $drivers' is the same block as found in 'sub _execute' therefor I had to re-factor a little before I wen too far and this is what I now have
private_method _execute => sub {
my $self = shift;
my ( $type, $conn, $container, $opt ) = @_;
my $dad = $self->_get_dad($conn);
$dad->execute( $type, $conn, $container, $opt );
return $container;
};
# DADNote: The DAD will have to have the same function call 'raw_query' with one param ($type) CRUD return a string representation of the query.
sub raw_query {
my $self = shift;
my ($conn, $type) = @_;
$self->_try_one_of(Database::Accessor::Constants::OPERATORS)
unless (exists( Database::Accessor::Constants::OPERATORS->{ uc($type) } ));
my $dad = $self->_get_dad($conn);
my $raw = $dad->raw_query(uc($type));
my $hash = {DAD=>ref($dad),
query=>$raw};
return $hash;
}
private_method _get_dad => sub {
my $self = shift;
my ($conn) = @_;
my $drivers = $self->_ldad();
my $driver = $drivers->{ ref($conn) };
die "No Database::Accessor::Driver loaded for "
. ref($conn)
. " Maybe you have to install a Database::Accessor::Driver::?? for it?"
unless ($driver);
my $dad = $driver->new(
{
view => $self->view,
elements => $self->elements,
dynamic_elements => $self->dynamic_elements,
conditions => $self->conditions,
dynamic_conditions => $self->dynamic_conditions,
links => $self->links,
dynamic_links => $self->dynamic_links,
gathers => $self->gathers,
dynamic_gathers => $self->dynamic_gathers,
filters => $self->filters,
dynamic_filters => $self->dynamic_filters,
sorts => $self->sorts,
dynamic_sorts => $self->dynamic_sorts,
}
);
return $dad;
};
Ok quite a few changes thrown in there.
The first thing I did was I imported a new MooseX called 'MooseX::Privacy' which lets me mark the '_get_dad' sub as a private method so some smarty pants can't read my code and then get a DAD directly by doing this;
my $dad=$some_da->_get_dad($dbh);
I also did the same for '_execute' and I may add in some more later. So that is requirement one, never expose the underlying DAD, the second requirement a simple generic name as 'raw_query' is about as plain as it gets, and for the third requirement I return a hash-ref with both the query and the DAD type.
You will also note some other little things. I added in a #DADNote to remind me to add to to the DAD writers guide and that I am using;
$self->_try_one_of(
and this is coming from 'Database::Accessor::Types' which I import at the beginning, one of the nice Moose bits is my Types class is just a Role and I have access to all it contains like any other Role.
Next I have to adjust my 'Database::Accessor::Roles::Driver' a little like this
requires 'execute';
++ requires 'raw_query';
and I should be good to go, but I need a test case for this or at least test it someplace I think 20_dad_load.t is the best spot, and I think this;
foreach my $type (qw(Create retrieve UPDATE DeLeTe)){
my $raw = $da->raw_query(Data::Test->new(),$type);
ok($raw->{DAD} eq 'Database::Accessor::Driver::Test','correct raw DAD class');
ok($raw->{query} eq uc($type).' query','correct '.uc($type)." raw query returned");
}
will do. I will also have to update my 'Database::Accessor::Driver::Test' to work with the changes to the Driver Role and the above test and this is what I added in;
sub raw_query {
my $self = shift;
my ($type) = @_;
return $type.' query',
}
and I run my tests (after a little debugging and correcting the # of tests run) I get
…
ok 44 - DA is a Database::Accessor
ok 45 - correct raw DAD class
ok 46 - correct CREATE raw query returned
ok 47 - correct raw DAD class
ok 48 - correct RETRIEVE raw query returned
ok 49 - correct raw DAD class
ok 50 - correct UPDATE raw query returned
ok 51 - correct raw DAD class
ok 52 - correct DELETE raw query returned
and to be thorough I ran the full test suite with this result
All tests successful.
Files=26, Tests=325, 37 wallclock secs ( 0.19 usr 0.06 sys + 34.75 cusr 2.02 csys = 37.02 CPU)
Result: PASS
So looks like I am ready to go back and play with my Driver::DBI tomorrow.
Leave a comment