Improved DBIx::Class usage with arbitrary SQL

A few months ago I write about using arbitrary SQL to generate DBIx::Class resultsets. These DBIx::Class::Report resultsets are read-only, but I found that I needed to add additional methods to each result and now I can. This makes the software much more flexible.

Fluent interfaces in Perl 6

I've been digging into Perl 6 more lately and I noticed the Wikipedia example of fluent interfaces didn't have a Perl 6 example, so I fixed that.

To be fair, Martin Fowler's explanation (as usual) of fluent interfaces does a much better job of explaining them, but a key point is that setters have a return value. For many fluent interfaces, the setters set a value and actually return a new instance of a different object for you to call methods on. Thus, the examples in Wikipedia don't always meet the criteria of a fluent interface, but I added a Perl 6 version that closely modeled the PHP version (but more concisely, and with much better type safety). I sidestepped the entire fluent interface debate.

Dave Cross and Modern PERL

At this year's YAPC::EU, we've been having a blast in Granada, Spain, an incredibly beautiful city. The conference has been fun and Dave Cross gave a great lightning talk about Modern PERL (sic). These are devs who are using 5.8, often aren't allowed to use modules, and use for param handling, but print cookies manually. In a similar spirit, I present a subroutine from some client code. It's here with their permission, and it's one of reasons they've hired All Around The World to fix their system. Pay close attention to the sprintf lines.


sub getDate {

       my $DATE = "0";
       # Get the date
       ($day, $month, $year, $hour, $min, $sec) = (localtime)[3, 4, 5, 2, 1, 0];

       # Reformat numbers to have two digits
       $day = sprintf ( "%.2d", $day % 100 );
       $month = sprintf ( "%.2d", ($month++) % 100 );
       $hour = sprintf ( "%.2d", $hour % 100 );
       $min = sprintf ( "%.2d", $min % 100 );
       $sec = sprintf ( "%.2d", $sec % 100 );

       # Fix the year
       $year = $year + 1900;

       # Format the date.
       $DATE = "$day$month$year$hour$min$sec";

       # Return the date
       return $DATE;

I should add that this is some of the nicer code in their system.

Testing your sqitch changes

When you work on larger projects, you'll often find that database changes are hard. Multiple developers, working on the same project, changing the same tables, can be difficult. Database migration tools often (but not always), come with one or more standard flaws:

  • Reliance on migration numbers (in other words, two or more developers commit migration number 6 and get a conflict)
  • Reliance on an ORM, such as DBIx::Class (sucks for the Python devs)
  • Reliance on something other than the Data Definition Language, or DDL (sucks when your custom tool can't represent the stored procedure you want to define)

There are plenty of other ways database migration tools fail, but the best standard tool I've worked with so far is sqitch. Its documentation needs some work, including more explanations of how to deal with common failure modes, but it avoids the above problems and provides you with a rich set of tools to make database migrations easier for large teams.

However, its common failure modes include:

  1. Creating a "revert" change that doesn't revert.
  2. "verify" scripts that work now but don't work in the future (for example, when MySQL is changed to "strict" mode)
  3. Hard-to-comprehend error messages about changes not appearing in the plan (usually a merge conflict that can be solved with reverting some changes and re-deploying)

There's work being done on some of these issues, but the first two can be mitigated with a simple test script I wrote.

git stashed

A quick 'n useful git tip:

$ git config --global alias.stashed "stash list --pretty=format:'%gd: %Cred%h%Creset %Cgreen[%ar]%Creset %s'"
$ git stashed
stash@{0}: 2d7f38b [19 minutes ago] On variable-travel-times-207: variable station travel times
stash@{1}: 1e4207e [6 weeks ago] WIP on custom-mission-actions-30-2: a00a646 Don't show intelligence since we're not using it.

Typically, git stash just shows you the items in your stash. Now, git stashed shows you how long ago an items was stashed (I had no idea I had a 6 week old stash item) and colorizes the relevant bits to make it easy to read (admittedly not visible in the bit above).

About Ovid

user-pic Freelance Perl/Testing/Agile consultant and trainer. See for our services. If you have a problem with Perl, we will solve it for you. And don't forget to buy my book!