Baby Moose About to Stand

Its actually do something day here in the Moose-Pen

So yesterday I left off with my Driver::DBI generating this SQL code;


INSERT INTO user (address,username) VALUES(?,?)

now I actually have to get that to run against a DB. I have the first DBI part done the prepare and it works

my $sth;
eval {
$sth = $dbh->prepare($sql);
};
if ($@) {
$result->is_error(1);
$result->error($@);
return 0;
}

as I get this result

ok 1 - Create function

from 10_crud_basic.t

So what I have to do next is bind and then execute that SQL statement so using that handy 'params' attribute I added a few days ago I can a simple iteration like this;


eval {
$sth = $dbh->prepare($sql);
++ foreach my $index (1..$self->param_count()){
++ $sth->bind_param( $index,$self->params->[$index-1]->value );
++ }

Now in DBI the binds are done from base 1 which I account for in the above loop using my good Moose fiend the param_count array trait. At this point in time I really am just going to get the simplest case to work. If you check DBI you will see that there are some extra thinks you can pass down on the bind_param, as it has this calling style


$sth->bind_param($p_num, $bind_value)
$sth->bind_param($p_num, $bind_value, \%attr)
$sth->bind_param($p_num, $bind_value, $bind_type)
I will have to make a note to myself in a future iteration I will have to take this extra '$bind_type' into account. There are also a number of other binding options 'bind_param_array' and 'bind_param_inout' which I should make work as well. For now I will just go with the simple use case.

Next I add in the finale DBI parts


my $rows_effected = $sth->execute();
$result->effected($rows_effected);
$dbh->commit()
unless($self->da_no_effect);

the execute which in this case should return the rows effected that I load into the $result class and then I do a DBI commit on no if the 'da_no_effect' flag is set. Again I am limited the scope in this iteration as this DBI pattern is just for an insert, update and delete. A Select command has a different patter as I will need to iterate over the returned record set somehow.

Anyway that is for later lets see what happens;


DBD::DBM::st execute failed: You passed 0 parameters where 2 required [for Statement "INSERT INTO user (address,username) VALUES(?,?)"] at

hmm

there is my problem in my sub _insert I forgot to add the param into the params attribute this;


my $param = Database::Accessor::Param->new({value=> $container->{$key}});
++ $self->add_param($param);

fixes that, and now I get

DBD::DBM::st execute failed: Cannot open D:\GitHub\database-accessor-driver-dbi\t\test\db\user.lck: No such file or directory (2) at C:/Dwimperl/perl/vendor/lib/DBD/File.pm line 730 at C:/Dwimperl/perl/vendor/lib/DBI/DBD/SqlEngine.pm line 795

which means it it not finding the DB so I am well on my way to getting this to work. Now the rest of my night was spent on getting connected to this puddling little db and making it work but I am not going to include that here as it has notihing to do with Driver::DBI or Database::Accessor.

In the end I did add in another test to my test case;


ok($user->result()->effected == 1,"One row effected");

and once I got the DB all nicely set up my test case gave me

ok 1 - Create function
ok 2 - One row effected

so I am getting along with this finally.

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