Late Night Moose

In today's Moose-pen we are going to have a look on one of the first my compound Database::Accessor classes 'Database::Accessor::Condition'. By compound I simply mean a class that holds other classes.

The Condition class is just as it sounds a class to add a logical condition to an Accessor. In SQL it would be a 'where' clause and Mongo some of the 'Aggregate' clauses. So basically this is a class that holds a number of 'Predicate' classes. So all I need to add is;

 has predicates => (
        is      => 'rw',
        isa     => 'ArrayRefofPredicates',
        coerce  => 1,
        alias   => 'conditions',
        traits  => ['Array'],
         handles => {
            add_predicate   => 'push',
            count_predicates => 'count',
        },
    );

More Than One?

Well today in the Moose-pen I am going to have a look at my Database::Accessor::Parm. Now this is one of the more use full of my classes, This is the one that is used to supply data to a DB query. So in DBI you may have something like this

 sub some_sql{
     my ($in) = @_;
     my $sql =  'SELECT * FROM person where person.id=?'
     my $sth -= $dbh->prepare($sql);
     my $person =   $sth->execute($in);
     ...
 
The '?' is replaced with the '4' in the execute. Now in my model that '4' would be my 'param' and I would pass it as a scalar value. Now I would hope the person writing my DAD SQL write would do it like above and not like this

sub some_sql{
     my ($in) = @_;
     my $sql =  'SELECT * FROM person where person.id=$in';
     my $sth -= $dbh->prepare($sql);
     my $person =   $sth->execute();
    ...
 
I would not like to see that JAVA SQL-Injection attack

Simple (Date) Range Overlap Detection

I started down this particular rabbit hole when (a) I had to check for date range overlaps when worrying about scheduling appraisals; and (b) my attempts to use SQL BETWEEN resulted in complicated, hard-to-read SQL.

Now you would think that BETWEEN should give you easy-to-understand SQL for date ranges. Maybe in the hands of others BETWEEN does, but for me by the time I accounted for all of the cases the BETWEEN-based SQL date range overlap detection got more complicated than I thought it needed to be. So I drew up some diagrams, which eventually led me to the realization that this:

dateA.start <= dateB.end
        AND
dateB.start <= dateA.end

is all that you need. No BETWEEN needed, simple to read, and should work in any useful dialect of SQL.

The Moose Collective

Well in my last post I added a few new attributes to my Database::Accessor::Element class and when playing about bout today I think I will have to revisit one of them 'aggregate'.

If I just leave it as it is

 has 'aggregate' => (
        is  => 'rw',
        isa => 'Str',
     );
 
It will begin to break-down my API as a programmer could come along and enter a very specific Mongo item such as 'mergeObjects' or something odd from an SQL DB like 'DENSERANK' and that makes for a very inconstant API.

So I am just going to bite the bullet and add in a 'Type' for this attribute so lets have a look at that.

Well to start I will have to narrow down what I want aggregate to mean. In Mongo it is a command word with some thirty+ operators and in SQL, depending on the DB, as few as five to many more than Mongo. So after a few hours of reading and revising I came up with this short list;

A Simple Telegram Bot

I just wrote a small post A Simple Telegram Bot in my blog... with a tiny introduction to Bot::ChatBots::Telegram. Comments more than welcome!

A Few Moose Never Hurt

So continuing on with the attribute fun today in the Moose-pen I am going to have a look at my 'Element' Database::Accessor class. So far like View there is not much to it only 'alias' and 'name'

Now putting my fore-ward looking Moose glasses you can see that I am going to need some more attributes. Well in SQL this class is being used as a field so I will need at least a 'table name' but then again I do not have a table in Classes so I guess I need a 'View' object now I could do this.

has 'view' => (
        is  => 'rw',
        isa => 'View',
    );

Cool Moose

In yesterday's Moose-pen I hinted that I would be getting all my test in order. Well I did that and checked them in but there really was not that much to report on. Just a lot of repetitive code. I suppose I could write one test case to check all of my Database::Accessor classes using some simpler iteration over a list but I really like having a separate test case for all my classes as there really is only a small part that is common between them, so onto something different today.

I am going to start filling in the attributes of my various embedded Database::Accessor classes and I guess the best place to start in with Database::Accessor::View.

Abusing Multiple Dispatch in Perl 6 for fun and profit

Abusing Multiple Dispatch Creatively is avallable on my blog for perusal. Comments and questions welcome as always.

Moose Attributes Cheeper by the Doz

So today in the Moose-pen I am going to stub in the rest of my Database::Accessor classes and the rest of my Accessor.pm attributes.

It seems I have six outstanting Database::Accessor classes to add in namely;
  • Param
  • Condition
  • Link
  • Gather
  • Filter
  • Sort
That was easy enough just a quick copy and rename job of the Predicate class without its attributes, so six more classes like this one

 package 
           Database::Accessor::Param;
    use Moose;
    with qw(Database::Accessor::Roles::Base);
     has '+name' => ( required => 0 );
1;
Now I quickly realized I should update my Roles a little seems that

 has '+name' => ( required => 0 );
is reused seven times. Thinking one step ahead again, in SQL there are really only three SQL clauses that would use an alias so that makes to take that required out the base and have in only on the ones with alias. So in 'Database::Accessor::Roles::Base' I do this

--  required => 1,
in my View, Element and Filter classes I add in

Two Moose at Play

So today in the Moose pen I am going to have a closer look at my Role from my last post . So here it is

    package Database::Accessor::Roles::Base;
    BEGIN {
        $Database::Accessor::Roles::DAD::VERSION = "0.01";
    }
    use Moose::Role;
    has 'name' => (
        required => 1,
        is       => 'rw',
        isa      => 'Str'
    );
    has 'alias' => (
        is  => 'rw',
        isa => 'Str'
    );
Now the above is fine for my View and Element Database::Accessor classes but the above sort of breaks down when I have a look a the 'Database::Accessor::Predicate' class. Now it is always good to have a class to have a 'name', makes debugging a little easier, but is the name required in this Class. Thinking a few jumps ahead when when I go to write my say my SQL DAD I can not see much use for requiring a name in a predicateand I cannot think of any case where I will need an 'alias' so to do this;

 package 
           Database::Accessor::Predicate;
    use Moose;
    with qw(Database::Accessor::Roles::Base);

Perl 5 Porters Mailing List Summary: January 2nd-9th

Hey everyone,

Following is the p5p (Perl 5 Porters) mailing list summary for the past week.

Enjoy!

Perl 5 Porters Mailing List Summary: January 2nd-9th

Hey everyone,

Following is the p5p (Perl 5 Porters) mailing list summary for the past week.

Enjoy!

Testing FIDO/U2F Two Factor Authentication

This month, I was tasked with implementing FIDO/U2F support for two factor authentication for a client. U2F two factor authentication requires a FIDO/U2F hardware key that you insert into your devices USB port and press a button to complete two factor authentication. There are many different vendors that make these devices, such as Yubikey etc. Thanks to the excellent Authen::U2F module by CPAN author ROBN, and Google's u2f-api.js library, implementing support for this proved to be fairly straightforward, but the process for doing this is not the point of this blog post.

The point of this blog post is that, at the time, there was no easy way to write any kind of automated tests for this. As a result, I ended up writing Authen::U2F::Tester. Authen::U2F::Tester acts like a virtual hardware device to complete FIDO/U2F registration and authentication (known as signing in U2F terms) requests.

The Many Roles a Moose Can Play

So today in the Moose-pen I was going to move out of the testing mode and actually do a little more coding, well some re-factoring anyway.

One of the best things about re-factoring Moose code is how easy it is to use a Role to stomp out all sort of duplicated code.

So of you may of already spotted s little anti-patter I had going on on most of my Database::Accessor classes and that was the;

 has 'name' => (
        required => 1,
        is     => 'rw',
        isa      => 'Str'
    );
and

    has 'alias' => (
        is     => 'rw',
        isa      => 'Str'
    );
attributes repeated over at least twice and even three times in the case of the Name. So this is a great candidate for a Role. Now the question is for me is not, whether there should be a Role but rather where should this role go.

Just a little More 2.

So To carry on from my last short post another short post. I am going to expand and modify my 20_dad_load.t again this time digging a little deeper in Moose's MOP or to give its full name 'Meta-Object Protocol'

One of the things I like most about moose is how easy it is to do “Introspection” or I like to say 'Lets have a look under the hood'. So I have expanded my role test from the other day to this

foreach my $attribute ($da->meta->get_all_attributes){
    next
      if (index($attribute->name(),'_') eq 0);
    my $dad_attribute = ucfirst($attribute->name());
    if ($dad_role->can($dad_attribute)){
        pass("Role DAD can $dad_attribute");
        my $attr = $dad_role->meta->get_attribute($dad_attribute);
        if ($attribute->type_constraint() eq $attr->type_constraint()){
           pass("Role DAD attribute: $dad_attribute had correct type of ".$attribute->type_constraint());
        }
        else {
           fail("Role DAD attribute: $dad_attribute had in correct type of ".$attr->type_constraint().". Should be a ".$attribute->type_constraint());
        }
        ok ($attr->{is} eq 'ro', "Role DAD attribute: $dad_attribute is Read Only")  
    }
    else{
        fail("Role DAD can $dad_attribute");
    }
   
 }

Just a Little 1.

So just a quick one for the Moos-pen today.

I my last post I did create a Test DAD, but then I discovered the problem with doing this is you may spend considerable time just debugging that class to make sure it at least works with any roles it may have to consume and even if you get it to work you may have problems with the roles it is trying to consume.

So I really should test my Database::Accessor::Roles::DAD before I start any load tests,. My basic test I did in a previous post it a good start bur I want to be able to test it before I have says a 100% good DAD. So Moose come to the resque again with MooseX::Test::Role

With this MooseX I can test my role without a 100% perfect consuming class as it just stubs in any subs the role may require. So in 20_dad_load.t I add in

use strict;
++use MooseX::Test::Role;
use Test::More tests => 15;

Test::Snapshot - automate externalising "expected" data

During the ongoing development of graphql-perl, I have found it valuable to generate data structures, and to compare those with expected values. Often, these have been highly detailed rather than a subset, because I wanted to know when anything changed.

When, however, something does validly have to change, it might change quite a few "expected" outputs. If those all need updating manually, that is a lot of repetitive activity. What if the computer could do that instead? What if Perl had "snapshot testing" as used in JavaScript frontend development, most popularly in Jest?

use Test::Snapshot;
my $got = function_generating_data();
is_deeply_snapshot $got, 'test description'; # could also be in a subtest

Simple tree walking in Perl 6

Check out Tree Surgery for a quick guide on how to easily walk generic trees of Perl 6 data.

Moose Retest 2.5

So in today's Moose pen I am going to stick to the testing tree and have a look at my brand new 20_load_dad.t file in my brand new database-accessor repository

Now in past test cases like this, I did a little creative coding and made up a fake test class for SQL and Mongo drivers that where used when I called this

my $fake_dbh = DBI::db->new();
ok(
    $address->retrieve( $fake_dbh, $result ) eq
      'SELECT  street, city, country FROM person  AS me',
    'SQL correct'
);
Now there is no problem with the use of the fake DBI::db in a test case, the problem that I will encounter is the fact I have to test Database::Accessor as an independent bundle. So that means I have to assume that there will be no DAD present, as we don't want to get into a tail wagging dog situation now do we?

Some Maths for Dobble

I wrote an article about the maths behind the game Dobble (known as Spot-It in some countries). It has no pretense of strict formality but it works for reminding me the though process that leads to designing Dobble-like games. The whole process prodded me to write Math::GF, a module on Galois Fields that can be used together with Math::Polynomial, so... there's also Perl in it!

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.