More Babay Moose

Well just another post-ette day here in the Moose-pen

Just another quick post-ette today as I want to quickly add in a feature to the results class that will help end uses with de-bugging.

Presently the results class look like thin when it is dumped

$VAR1 = bless( {
                 'is_error' => 0,
                 'DAD' => 'Database::Accessor::Driver::DBI',
                 'query' => 'UPDATE people SET people.first_name = ?, people.last_name = ? WHERE ( people.first_name = ? AND people.last_name = ? )',
                 'operation' => 'UPDATE'
               }, 'Database::Accessor::Result' );
useful info but it would also be nice to see what params are being used and if they are in the correct order; So a quick attribute add into the Database::Accessor::Result class;

++        has params => (
++           is       => 'rw',
++            isa      => 'ArrayRef|Undef',
++        );
and all I have to do in the Driver::DBI is;

...
    $result->query($sql);
++    $result->params([map({$_->value} @{$self->params} )]);
    $self->da_warn('execute',"SQL=$sql")
      if $self->da_warning()>=1;
…
and now the result cl;ass has all the params I passed in.

Little Moose Moves On.

Well test expand posette day here in the Moose-pen.

Not that have the first test in 20_where_basic.t working I figured I might as well expand on that tests and ensure the other SQL clauses are coming out in the format I like. So I added the following in;

my $container =  {first_name=>'Bill',
                  last_name =>'Bloggings'};
my $da     = Database::Accessor->new($in_hash);
ok($da->create( $utils->connect(),$container),"created something");
ok($da->result()->query() eq "INSERT INTO people ( people.first_name, people.last_name ) VALUES( ?, ? )","create SQL correct");
ok($da->retrieve( $utils->connect() ),"selected something");
ok($da->result()->query() eq "SELECT people.first_name, people.last_name, people.user_id FROM people WHERE ( people.first_name = ? AND people.last_name = ? )","Select SQL correct");
ok($da->update( $utils->connect(),$container),"updated something");
ok($da->result()->query() eq "UPDATE people SET people.first_name = ?, people.last_name = ? WHERE ( people.first_name = ? AND people.last_name = ? )","Update SQL correct");
ok($da->delete( $utils->connect() ),"deleted something");
ok($da->result()->query() eq "DELETE FROM people WHERE ( people.first_name = ? AND people.last_name = ? )","Delete SQL correct");

Baby Moose Sets Out

Still in re-factor mode here at the Moose-pen.

Yesterday I had quite the success in taking a little more of the logic out of the DAD side side of things now the DAD writes not longer have to check to see if a predicate in a condition or filter has miss-matched parentheses or is missing at least the the default 'and' condition.

Before I move on I want to squish this little warning

Use of uninitialized value in join or string at...
which is really just sloppy programming on my part as this

$predicate_clause .= join( " ",
                $predicate->left->view . "." . $predicate->left->name,
                $predicate->operator,
                "'" . $predicate->right->value . "'",
--                 $predicate->condition);
++                ($predicate->condition) ? $predicate->condition : "" );

Perl 6 Training at TPC - Salt Lake City

After TPC join me for The Hitch-Hiker's Guide to Perl 6 at The Little America in Salt Lake City.

PAUSE Privacy Policy

Today is GDPR Day, and to celebrate that, the PAUSE admins have added a Privacy Policy to PAUSE. This tells you:

  • what personal data is processed by PAUSE;
  • what PAUSE does with that data;
  • how that data is shared (with the rest of the CPAN ecosystem);
  • PAUSE's lawful basis for holding your information (this is a GDPR term, which essentially answers the question "what gives PAUSE the right to hold your personal data?")
  • what your rights are, and how to exercise them.

The policy is linked off the sidebar in PAUSE, and the source is a markdown document in PAUSE's github repo.

Test::Class Hierarchy Is an Antipattern

Test::Class is particularly good at testing object-oriented code, or so it is said. You can create a hierarchy of test classes that mirrors the hierarchy of classes under test. But this pattern, common in Perl projects, is conspicuously missing from the rest of the xUnit world, and with good reason.

Baby Moose Back with Mama

ts re-factor day again here at the Moose-pen

With all my test passing since yesterday's post I think it is time I spend a little time re factoring before I move onto other things. Now as I said many times before I would like to have whatever is going to the DAD, Driver::DBI in this case, to be as free of logic errors as possible.

In this vain I noticed that when dealing with a where clause and predicates in general there are a two rules that should be enforced before any conditions or filters are passed into a DAD, First any parentheses that is opened must be closed and second two or more predicates must be joined by a condition.

Module Adoption Opportunities! YAY!

Quite some time back I was anxious to find a Perl module or two to work on and gain some experience in the process of releasing modules to the CPAN. Like I'm sure many of you do, I looked through the ADOPTME list to see what looked simple and or fun to work on.

WWW::Shorten and friends came on my radar and I started there. I reached out to the authors of many modules in the WWW::Shorten to see if they wouldn't mind joining me in the effort to bring them all to a similar point. I seem to recall everyone being happy and eager to work together, so this part went well. We created a GitHub organization to house the various modules.

Inevitably, though, I began working on other things and unfortunately have let WWW::Shorten and friends languish. This, however, opens the opportunity for you to take on the task of maintaining a family of modules and bring their test coverage up to date and add in modules for the new shortening services that are available now.

Please let me know if you're interested and I'll happily pass off some commit and PAUSE permissions!

Baby Moose Starts Yet Again

Well is bug squish day here in the Moost-Pen

Yesterday I manged to get my test to fail properly I guess today I better start looking at fixing the code that is breaking starting with my update;

I left print warn on and in my output I am getting this

DBD::DBM::db prepare failed: Couldn't parse at C:/Dwimperl/perl/site/lib/DBI/DBD/SqlEngine.pm line 340
 [for Statement "UPDATE user SET address = ?"] at 
and a little playing about with a small test script I discovered that I have to add in a 'where' clause to make an update work. I first have to change my test a little;

delete($container->{username});
$container->{address} ='Achanged';
++$user->add_condition({left  =>{ name  => 'username',
++                               view  => 'user'},
++                      right =>{ value => 'user_new'}
++                    });
ok($user->update($utils->connect(),$container),"Update function");

New Dancer trial version released

David Precious has just released a new trial version of Dancer. There are some rather significant changes under the hood, and community testing and feedback is welcomed and encouraged.

Please find us here, Github, Twitter, or on irc.perl.org#dancer with any questions, problems, or feedback.

Thanks! Keep dancing!

Ducktaping The Internet To The Desktop

Simple desktop applications are generally not what one considers a Perl specialization. Its expertise lies in generating processing and transforming textual data, hence its use in the web, and in tools like GUIDeFATE. This 'duct tape' manages to parse text, extracting relevant data, and absorbing information and producing a meaningful output efficiently. Displaying this output in a desktop application shouldn't be too difficult.

Challenge accepted

Baby Moose All in a Row

It is getting all my Baby Moose in a row day here in the Moose-Pen

So after yesterday's major TARFU with five tests failing and worse three tests reporting false positives I think a good review is needed.

The first thing I am going to clean up is the false positive test like this one;

eval{
   $user->update($utils->connect(),
                 $container);
};
if ($@) {
    fail("Update function error=$@");
}
else {
    pass("Update function");
}
Now there are two parts to this, a design flaw with the test and a config issue with DBI. I will start with the DBI issue first. It has been a while since I worked directly with DBI and I had to dig pretty deep in my little mind till I remembered, that by default DBI does not raise any errors it only warns. This means that code block in Data::Driver;

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

Baby Moose Takes a Break

Its find a flaw here in the Moose-Pen

Well today did start out well and I began work on expanding Driver::DBI a little when I just wanted to check to see if that DBD::DBM driver of mine could do a little more that what I played with in '10_crud_basic.t' and I go it to take this SQL;

SELECT username as name,address, addresses.street FROM users join addresses on users.address = addresses.id
after adding in the 'addresses' table and a few rows. I thought that was a little odd as DBD::DBM is suppose to use DBI::SQL::Nano so to figure out what SHQ driver I was using I added this into some of code;

print $dbh->{sql_handler}
and that printed out

SQL::Statement

Building Rakudo.js with JavaScript from the near future

Luckily for us the JavaScript language is constantly evolving towards being a better Perl 6 target (this is a general case of the world in general evolving in this direction).
The next Chrome release will support bigints natively in a matter of days.
Node.js is expected to upgrade the V8 soon too.
The major browsers are expected to follow suite.
Rakudo.js is already ready to use that new functionality.
As part of working on making Rakudo.js run in the browser I'm replacing all the node.js dependent stuff.
For some bignum operations we use a node.js binding to OpenSSL, after the pure js alternatives proved incomplete and/or buggy I have decided that it's not worth to spend the effort towards supporting stuff that will be obsolete soon and use the new features.
My current philosophy towards running on legacy JavaScripts is that with the velocity of the JS ecosystem by the time Rakudo.js is production ready the current once will be widespread.
Obviously if someone needs legacy support he is welcome to work on that (and I'll try my best to help him).

Making Baby Moose Better

Its Moose day here in the Moose-Pen today.

Still playing about with re-factoring things before I move along too far and what I wan to fix today is this block of code;

package Test::DB::User;
use Moose;
use parent qw(Database::Accessor);
  around BUILDARGS => sub {
      my $orig = shift;
      my $class = shift;
      my $ops   = shift(@_);       
return $class->$orig({
                 view=> {name=>'user'},
             elements=>[{view=>'user',
                         name=>'username'},
                        {name=>'address',
                         view=>'user'}],
    update_requires_condition=>0,
    delete_requires_condition=>0
                  });
  };
1;
You will remember that I was using this in my 10_crud_basic.t test case like this;

use Test::Utils;
use Test::DB::User;
my $utils = Test::Utils->new();
$utils->create_users_table();
my $user = Test::DB::User->new();
my $container =  {username=>'user_new',
                  address =>'address_new'};
eval{
   $user->create($utils->connect(),
                 $container);
};
I wanted to have a reusable hunk of code and provide a good real world example of a class that is using Database::Accessor properly. However looking again at that first block of code I have made a number of Moose boo-boos.

Baby Moose tries again

It a little re-factor days here in the Moose-Pen

So just a quick re-factoring post-ette now that I have the basic CRUD working.

This line of code

my $field = $self->get_element_by_name(sub {$_->name eq $key}); 
was bugging me a little. You really have to have to be a fairly experienced Perl programmer before this type of call is second nature, or you have to be a real fan of List::Util to have this sort of call in you bag of tricks. So I think I will tone the level of this one down a little. This means going back into Database::Accessor yet again and this time I will change only Database::Accessor::Roles::Common by first doing this;

has elements => (
            isa => 'ArrayRefofElements',
            is  => 'ro',
            traits  => ['Array'],
            handles => { element_count => 'count',
--                        get_element_by_name  => 'first',
++                       _get_element_by_name  => 'first',
                       },
            default => sub { [] },
        );
and then adding a new sub into that role like this;

sub get_element_by_name {
           my $self = shift;
           my ($name) = @_;
           my $found = $self->_get_element_by_name(sub {$_->name eq $name});
           return $found;
 }

Baby Moose All Tuckered out

It if put the 'D' in CRUD day here at the Moose-pen.

So yeaterday I fininsed off Retreive/Select after I pulled a few hairs out trying to debug and issues that was not there I thouhg today I wiyld finish of my CRUD subs by doing the _delete sub today.

At least this is the most simple of all four functions as there is not need to iterate over fields or contrainers so the code is just;

sub _delete {
    my $self             = shift;
    my ($container)      = @_;
    my @fields           = ();
    my $delete_clause    = join(" ",Database::Accessor::Driver::DBI::SQL::DELETE
                                   ,Database::Accessor::Driver::DBI::SQL::FROM
                                   ,$self->view()->name());
    $self->da_warn("_delete","Delete clause='$delete_clause'")
      if $self->da_warning()>=5;
    return $delete_clause;
}

Bye, bye search.cpan.org

For me, at least, a sad moment. But you can read the details at log.perl.org and make up your own mind.

Baby Moose Selection

Well if carry on as if you are normal day here in the Moose-pen

In yesterday's post I manged to get the update sub working with a real DB and today I am going to try the 'retrieve' sub which is a little more tricky.

The basic concept is much the same as for the other two and it really did not take me long to get it up and working, the only real gaff was this one

Subroutine _select redefined at 
as I had a stubbed in version that I simply got rid of. Apart from that and the sact one does not spell alias as alais things when together quickly and here is what I have;

Baby Moose Update

Its get more done day here in the Moose-Pen

Now that I have got 'create/insert' to work in yesterday's post I think I will move on down the line and get the next one easy one to work 'update'.

This first thing though is to get rig of this waring;

Commit ineffective while AutoCommit is on-1 at D:\GitHub\database-accessor-driver-dbi\lib/Database/Accessor/Driver/DBI.pm line 64
ok 1 - Create function
nothing major really the waring is perfectly harmless but I could see some people getting annoyed at that and the fix is simple, if the DBI 'AutoCommit' flag is set don't try and commit. So here is that change;

$dbh->commit()
 --          unless($self->da_no_effect);
++         if ($dbh->{AutoCommit} == 0 and !$self->da_no_effect);
might as well get the easy stuff early, now onto update sub. It is much the same as the 'insert' and it really only took me one quick iteration to correct a few syntax typos and I had it working, so here you go;

About blogs.perl.org

blogs.perl.org is a common blogging platform for the Perl community. Written in Perl and offering the modern features you’ve come to expect in blog platforms, the site is hosted by Dave Cross and Aaron Crane, with a design donated by Six Apart, Ltd.