Introducing DBIx::Class::Helper::ResultSet::SearchOr

Arguably the most important design decision that mst made when first writing DBIx::Class was the choice to make chainable resultsets. A fundamental part of that design is that when you chain off of a resultset you should always get a subset of what you started with. This is important because it’s what makes searching from a user object or similarly using DBIx::Class::Schema::RestrictWithObject work in a safe manner. Most everyone should know at this point that the best way to use DBIx::Class it to make various ResultSet methods that return named subsets of data.

Posted Fri, Jun 1, 2012

Introducing DBIx::Class::Helper::ResultSet::CorrelateRelationship

Recently at work we ran into an issue where a report was timing out. At first I thought it was because the server was overloaded, or the clients that were connecting to it were doing so improperly. Both of those things were true, but they weren’t the cause of the problem. The problem was this: sub TO_JSON { my $self = shift; return { %{$self->next::method}, failed_location_tests => $self->test_computer_links->failed->count, location_tests => $self->test_computer_links->count, device_tests => $self->test_device_links->count, total_pcs => $self->all_computers->count, total_pcs_failed => $self->failed_computers->count, total_pcs_succeeded => $self->succeeded_computers->count, total_pcs_untested => $self->untested_computers->count, } } So to be clear, with our standard pagination of 25 rows per grid, this was doing the initial query to get the data, and then SEVEN additional queries per row.

Posted Wed, May 30, 2012

Introducing JavaScript::Dependency::Manager

Nearly a year ago my grandfather passed away. He had some form of dementia for a long time and I personally wasn’t hit very hard by it, but as is the custom I went home to visit my family when it happened. On the drive down I listened to Childhood’s End and Rendezvous with Rama. At work I’d been tackling the problem of users with custom dashboards and possibly even the ability to have gadgets that we sell separately.

Posted Mon, May 28, 2012

Introducing DBIx::Class::UnicornLogger

More than a 1.5 years ago we added color coded, formatted SQL output to DBIx::Class. Since then I’ve tried adding various configurable logging facilities to the core, but I haven’t had much luck getting the API for that whipped into shape. So I’m giving up on getting it into the core for now and releasing it separately. It’s pretty rough around the edges, but it’s a logger, so it’s not like you could depend on it working a certain way and get into any kind of trouble with it (yet.

Posted Fri, May 25, 2012

Introducing Catalyst::ActionRole::DetachOnDie

In my last post I introduced Catalyst::Controller::Accessors, which is mostly aimed at users who do a lot of chaining. This module is similarly targeted for chaining users. Anyone who has used chaining for more than a few weeks will know that exceptions in chains are stupid; an exception will not stop the chain, but merely end the current part of the chain, add to $c->errors, and run the next part of the chain.

Posted Wed, May 23, 2012

Introducing Catalyst::Controller::Accessors

Ugh, I first released this eight months ago, but I fell off the blogging wagon pretty badly. It’s so hard to write when I could be writing code, docs, and tests! So anyway, I’m trying to get caught up on the eight announcements that need to be made as well as a few DBIx::Class::DeploymentHandler related PSA’s. I’ll schedule them to get auto posted with at least a few days between so I don’t melt your feed reader or bore you too much.

Posted Mon, May 21, 2012

Using search.cpan.org AND metacpan

I appreciate the effort and openness of metacpan, but their search is still pretty bad. To be clear, compare the results of the search for DBIx:Class::Source on SCO and metacpan. That’s why I made the following greasemonkey/dotjs script: $('a').each(function(i,x){ var obj = $(this); var href = obj.attr('href'); var re = new RegExp('^/~([^/]+)/(.*)$'); this.href = href.replace(re, 'https://metacpan.org/module/$1/$2'); }) Put this in ~/.js/search.cpan.org.js to install it with dotjs. Feel free to extend it to work for more than just modules.

Posted Wed, May 16, 2012

The Rise and Fall of Event Loops (in one very small place of my code)

In the spirit of one of my other posts I’ve decided to chronicle my path with at least a couple event loops. More than eighteen months ago I documented my decision to start using an event loop as it would handle things I may not have considered, the example mentioned specifically in that post being exceptions. Things went well! I used the code I documented in that post for a long time with no issues until recently.

Posted Wed, Mar 7, 2012

Perl Event Loop

I have some extremely basic code using AnyEvent but I recently found out that I was doing it wrong. That is, the entire reason I am using an event loop is to catch errors, log them, and keep going. That’s one of the great benefits that Catalyst gives me; I override one thing and I get universal error logging. The problem is that AnyEvent specifically does not handle this use case.

Posted Sun, Mar 4, 2012

Using Catalyst::Plugin::Authentication with an old setup

Recently I took it upon myself to make Catalyst::Plugin::Authentication know users had logged in after users had logged in in a completely non-Catalyst part of our app. After LOTS of frustration, code spelunking, and bugging a couple people in #catalyst (hobbs and t0m) I got it working. Basically what I did was have the session plugin look at a different cookie and load information from our own strange brew of session table.

Posted Wed, Jan 18, 2012

Cloning Objects in Perl

Recently I needed to do some deep cloning of some objects at work. I think I ended up looking at all of the major ways to do it, and I figure I might as well discuss them here. What is deep cloning? Nearly everyone should be able to answer this, but it doesn’t hurt to define it anyway. Deep cloning means you clone other things the current object is related to, recursively.

Posted Tue, Sep 20, 2011

Shortcut Constructor Method & Conversion

I left my book and notes at work yesterday, hence the late post. Shortcut Constructor Method What is the external interface for creating a new object when a Constructor Method is too wordy? Sometimes creating an object is exorbitantly wordy. The example that the author gives (in javascript) is the following: var p = new Point({ x: 1, y: 2 }) Add methods to a lower level object that can construct your objects.

Posted Wed, Sep 7, 2011

Creating a pseudo attribute with DBIx::Class

I’m surprised I haven’t actually blogged this before. I had to do it recently for the first time in a long time and I figured I’d share the secret sauce. At work we just added a complete permission system on top of our existing user system, but we didn’t want to make the UI as flexible as the underlying code. We ended up making a single role (which has all permissions) called “Full Control”.

Posted Sun, Sep 4, 2011

Smalltalk Best Practice Patterns - Constructor Parameter Method

How do you set instance variables from a constructor method? The fundamental issue here is that often validation is bypassed at construction time, for whatever reason. So one’s accessor may look something like this: sub x { my $self = shift; if ($self->constructing) { if (exists $_[0]) { $self->{x} = $_[0]; } else { return $self->{x} } } else { if (exists $_[0]) { die 'too high!' if $_[0] > 100; die 'too low!

Posted Sat, Sep 3, 2011

Smalltalk Best Practice Patterns: Constructor Method

Sadly reading is going slower than expected due to being so busy with various things in life. Oh well, just a single pattern today. Constructor Method How do you represent instantiation? In addition to a vanilla constructor, add methods for common cases to instantiate typical objects. For strange cases allow the use of accessors. Using Perl (with Moose) an example might be: package Point; use Moose; has x => (is => 'ro'); has y => (is => 'ro'); sub r_theta { my ($class, $r, $theta) = @_; $class->new( x => $r * cos($theta), y => $r * sin($theta), ); } 1; So now both of the following work:

Posted Thu, Sep 1, 2011

Smalltalk Best Practice Patterns - Chapter 3 - Behavior - Methods

Today I had to spend time taking care of passport stuff for my upcoming honeymoon, so I only got to read a handful of pages. I’ll post my notes nonetheless. Methods are more important that state because, correctly factored, methods paper over any changes in state over time. Most of us who took OO classes in college had this hammered into our brains :-) Methods should be written to get something done, but should also be written to communicate with the reader.

Posted Thu, Sep 1, 2011

Smalltalk Best Practice Patterns, Chapters 1 and 2

For work I decided I’d start reading some technical books, taking notes, and then trying to reiterate what I’ve learned. Yesterday I read the Preface and Chapter 1 and today I read Chapter 2, but sadly it’s all still introductory. I might as well discuss what I’ve read nonetheless. First though, I should say that I am reading the book because Thomas Doran of Catalyst development recommended it, and it clearly applies to Perl with Moose.

Posted Tue, Aug 30, 2011

Weekly Status Report 4

This week I finished the following three git conversions: Catalyst-Authentication-Store-DBIx-Class Catalyst-Authentication-Credential-FBConnect Catalyst-Authentication-Credential-OAuth And I started on the following four git conversions (I think they are ready but I want t0m to sign off on them) : Task-Catalyst Catalyst-Plugin-Authentication HTTP-Request-AsCGI Catalyst-Action-RenderView

Posted Mon, Aug 29, 2011

Stop accidentally committing all with git

One of the things that annoys me a lot when using git is if I go through a lot of work to stage some changes, probably using git add -p to stage parts of files, and then from muscle memory I type git ci -am 'lolol I dummy'. If you didn’t know the -a says commit everything, so then of my painstaking staging is gone. Well, on Thursday I finally fixed this problem.

Posted Mon, Aug 29, 2011

Refactoring Dispatch Tables into Objects

One of the cool ways of doing things in Perl is to use a dispatch table. The most obvious dispatch table is a hash of subroutines: my $x; my $table = { GET => sub { return $x }, PUT => sub { $x = $_[0] }, }; sub dispatch { my ($method, $data) = @_; if (my $fn = $table->{$method}) { $fn->($data) } else { die 'METHOD NOT ALLOWED!' } } This is a pretty cool thing to be able to do easily.

Posted Thu, Aug 25, 2011

New Stuff in Catalyst::ActionRole::PseudoCache 1.000001

I’m excited to announce a new version of Catalyst::ActionRole::PseudoCache. New in the current release of Catalyst::ActionRole::PseudoCache is that it can now use Catalyst::Plugin::Cache as the underlying cache mechanism. The main reason was that the existing architecture didn’t work for multiple servers, which is how our system works. Plus this is just better overall. In the long term I will be removing the old “Pseudo” cache. It might be a good idea to make a separate package with a better name at some point, but that will be for the next release.

Posted Tue, Aug 23, 2011

Weekly Status Report 3

I don’t feel great about this past week, but I was really busy with wedding planning stuff. I barely made either of my two main goals (2 blog posts and 2 patches/releases a week.) Last week I: Released a new version of Log::Contextual Released a new version of DBIx::Class::Helpers I have high hopes for the coming week, that I can get more important releases and more interesting blog posts written.

Posted Mon, Aug 22, 2011

Using Cygwin instead of msysGit

Our main product at work is a Windows product. The reasons are complicated, but the main reason is that that is what our customers seem to want. What this means is that I do some of my development on a virtual machine. For a long time I was just using msysGit. msysGit goes a long way; you have a real bash console, a bunch of standard unix commands, and very good windows integration.

Posted Mon, Aug 22, 2011

Git aliases for your life

I only use a handful of git aliases, but the ones I do I really like. First off, the basic ones: [alias] ci = commit co = checkout st = status br = branch Also, another handy tip, as pointed out by a commenter is aliasing g to git (alias g=git) so that after you do the above instead of git ci you can merely do g ci. Neat.

Posted Wed, Aug 17, 2011

Weekly Status Report 2

This week I: Released a new version of Class::C3::Componentised Released a new version of DBIx::Class::Candy

Posted Tue, Aug 16, 2011

You should be using git grep

Usually when searching through files I use ack which is an awesome tool indeed. Unfortunately, though ack does indeed work on windows, using it on windows is a painful experience. The main two problems are that it’s slow and the color coding doesn’t work. I figured I’d try out git grep, with the hope that it might be marginally better. I try my best to at least be familiar with all the git commands, so this is one of those things I had been meaning to do anyway.

Posted Sun, Aug 14, 2011

Powerful benchmarking with Perl and ab

One of my projects at work was to make an SMS (and voice actually) gateway. The gist is that instead of our customers each having an account with whatever text message company, they go through us. The benefit is that with a larger pool of users for the text messages users can have a lot more flexibility with how they use their messages. Most gateways sell you messages per month, and we sell yearly messages.

Posted Fri, Aug 12, 2011

New Stuff in Class::C3::Componentised 1.001000

I’m very excited to finally announce a feature that I’ve toyed with in Class::C3::Componentised for over a year now. New in the current release of Class::C3::Compontised is Class::C3::Componentised::ApplyHooks. The gist is that you can run code, or more importantly methods, against the class being injected into. I wouldn’t be surprised if few people reading this actually know what Class::C3::Componentised is actually used in; the answer is DBIx::Class. The upshot of this new feature is that you could write a component to add columns or relationships much more nicely than before.

Posted Wed, Aug 10, 2011

Weekly Status Report 1

This week I sent a small patch (along with a lot of discussion) to Exodist for Exporter::Declare released an awesome new version of Log::Contextual

Posted Mon, Aug 8, 2011

New Stuff in Log::Contextual 0.004000

I just released Log::Contextual 0.004000 and it has a handful of great features. It now supports arbitrary levels, so where before you simply had: trace debug info warn error fatal Now you can have any levels by just saying use Log::Contextual -levels => [qw(lol wut zomg)], ':log'; which would import functions for log levels lol, wut, and zomg. But the really exciting thing is that now you can make a base class of Log::Contextual and set defaults for all of the different import options:

Posted Sun, Aug 7, 2011

DBIx::Class Extended Relationships

Since the dawn of time DBIx::Class relationships were simply a set of columns related to each other via equality. For the most part this is good enough, but DBIx::Class aims at 100% power for all databases (unlike some other ORMs… :-) .) In May what we internally called “extended relationships” was added to DBIx::Class. (docs here) Basically this allows you to use the full power of SQL::Abstract to define your join conditions.

Posted Fri, Aug 5, 2011

Event Loops are better than while (1)

One of the projects that I worked on last year had a number, five I think, of background daemons. Basically the way we implemented this was by making a DoesRun role that looked something like the following: package Lynx::SMS::DoesRun; use Moose::Role; requires 'single_run'; has period => ( is => 'ro', required => 1, ); sub run { my $self = shift; while (1) { $self->single_run; sleep $self->period; } } no Moose::Role; 1; And then a typical Runner class looked something like this:

Posted Wed, Aug 3, 2011

Getting More Done

Today I purchased 59 Seconds, recommended by Jeff Atwood. I struggle with procrastination as much as anyone else so I’m willing to spend 10 bucks to try to get more done. The author recommends four things to attain a given goal: plan well reward yourself focus on benefits tell people I’ve kinda slacked off with Open Source stuff the past year (see the graph at metacpan) and I’d like to remedy that.

Posted Tue, Aug 2, 2011

My Ideal workflow tool

super fetch: git fetch git fetch –tags git pull –ff-only (all local branches) git reset –hard (specified branches) pull issues: “rebase” issues from github “rebase” issues from RT “rebase” issues from JIRA sync issues from remote repo super status: Dirty? Non-Tracking branches? How many? Ahead tracking branches? How many commits total? Unmerged branches? Unreleased master? (no tag) How many issues? My last post was about Distributed Issue Tracking.

Posted Tue, Jul 12, 2011

Distributed Issue Tracking

Ever since I heard about SD (Simple Defects) I’ve been enamored with the idea of distributed issue tracking. Unfortunately SD is mostly unmaintained, undocumented, slow, and has lots of deps. I could probably get over the latter two, but the first two are deal breakers. Fast forward eighteen months and I saw genehack’s App::GitGot. It’s a little sluggish (1.35s to merely list repos on my SSD) but it’s exciting because it can easily list my repos that are dirty or ahead by X commits.

Posted Thu, Jul 7, 2011

FUD and Loathing in JavaScript

A coworker sent this to our internal mailing list, partially to goad me into responding to the stupid comments. I don’t have an ars account, so I’ll just hope that trackbacks work. Here are the arguments that someone actually put effort into making: a) Magic ‘this’. This is this, except when this is that. JavaScript pushes you to use anonymous functions all over the place, except they always end up losing the proper context for the ‘this’ variable, so you end up having goofy code like “var _this = this” all over the place and then using that inside your callbacks or other functions.

Posted Fri, Jun 24, 2011

Nicer git remote URLs

Most open source git repositories that I interact with are hosted at git.shadowcat.co.uk. A few typical repo urls (read/write) hosted here looks like: [email protected]:DBIx-Class.git [email protected]:Catalyst-Runtime.git [email protected]:Devel-Declare.git [email protected]:Moose.git A handy trick is to make a file at ~/.ssh/config with the following in it: host catagits user catagits hostname git.shadowcat.co.uk port 22 identityfile ~/.ssh/id_dsa host dbsrgits user dbsrgits hostname git.shadowcat.co.uk port 22 identityfile ~/.ssh/id_dsa host p5sagit user p5sagit hostname git.shadowcat.co.uk port 22 identityfile ~/.

Posted Wed, May 25, 2011

Converting repos from Subversion to Git

I have now converted something like 25 repositories from svn to git. I can fix undetected merges, correctly import tags, and clean up ugly (svk) commit messages. With this knowledge I hope to write a small, non-free eBook (7.50 USD I think.) But first I’d like a chance to convert your repository! The more repositories that I convert the more ground the ebook can cover. I’ve converted a number of repos for CPAN modules and I’d love to do more.

Posted Wed, May 18, 2011

New Stuff in DBIx::Class::DeploymentHandler

I’m just releasing my first new release of DBIx::Class::DeploymentHandler in six months! For the most part the release is just a few doc tweaks, but it does have one important new feature, the “_any” version. If you didn’t already know, DBICDH has a handy little directory structure for how your deploys work. If you haven’t seen it, take a look. This new release allows you to use _any in place of a version or version set, which will run the given files no matter what version you are deploying to.

Posted Wed, Apr 13, 2011

Chai Tea Mix

I’ve been using this for a couple years now, and I figure I’ll repost it so that it’s easy to find (for me.) Ingredient Amount Sugar, White Granulated 1 Cup Instant Non Fat Dry Milk 1 Cup Non Dairy Creamer 1⁄2 Cup Instant Tea 1⁄2 Cup Cinnamon, Ground 1 Teaspoon Ginger, Ground 1 Teaspoon Salt, Table 1⁄2 Teaspoon Nutmeg, Ground 1⁄2 Teaspoon Allspice, Ground 1⁄4 Teaspoon Cloves, Ground 1⁄4 Teaspoon Cayenne Pepper 1⁄8 Teaspoon And for convenience, here is the recipe x 4, which is how much I like to make:

Posted Thu, Apr 7, 2011

DBIx::Class::Helper::Row::RelationshipDWIM: Awesome!

Thanks to some idle chatting in the #dbix-class channel on irc.perl.org I came up with DBIx::Class::Helper::Row::RelationshipDWIM. The gist of it is that you get to type __PACKAGE__->has_many(addresses => '::Address', 'person_id' ) instead of __PACKAGE__->has_many(addresses => 'MyApp::Schema::Result::Address', 'person_id' ) That yields a total sugar (with candy) of the following: package Lynx::SMS::Schema::Result::MessageParent; use Lynx::SMS::Schema::Candy; primary_column id => { data_type => 'int', is_auto_increment => 1, }; column account_id => { data_type => 'int' }; column type_id => { data_type => 'int' }; column caller_id => { data_type => 'int', size => 11, is_nullable => 1, }; column message => { data_type => 'nvarchar', size => 1000, }; column when_created => { data_type => 'datetime', set_on_create => 1, }; column voice_id => { data_type => 'int', is_nullable => 1, }; belongs_to account => '::Account', 'account_id'; belongs_to voice => '::Voice', 'voice_id'; belongs_to type => '::Type', 'type_id'; has_many children => '::MessageChild', 'message_parent_id'; 1; Pretty nice.

Posted Tue, Mar 15, 2011

New Stuff in DBIx::Class::Candy

I’m extremely proud to announce a fairly major release of DBIx::Class::Candy, 0.002000. Not only are the tests much more complete as well as the underlying code much more comprehensible, but the usage of the Candy can now be even sweeter. To get the full features of DBIx::Class::Candy you’ll want to first create the following base class: (Of course you can call this sugar if you hate my naming scheme or rainbows if you love it.

Posted Wed, Mar 9, 2011

Git 1.7.5.1 from git on ubuntu

I really like git. It has an excellent suite of tools bundled with it from the start and it gets lots of updates and active development. Today I was looking at the latest git version (1.7.4) because I was installing it on a new machine and, as usual with new versions of things, I perused the release notes. What really caught my eye was this: * "git log -G<pattern>" limits the output to commits whose change has added or deleted lines that match the given pattern.

Posted Wed, Mar 2, 2011

Screen Scrape for Love with Web::Scraper

My fiancée and I have not yet picked out a date for our wedding, but we do know that we want it outdoors. We have scoped out a number of locations that can handle indoor and outdoor weddings just in case there is bad weather, but we’d prefer to have perfect weather. After some searching I found NOAA’s NSSL, which has ridiculous amounts of data. Instead of most websites, which give you the average high temperature and average low temperature for a given day of the year from the past three years, this gives hourly measurements for basically anything back to 1910.

Posted Fri, Feb 18, 2011

Catalyst Git Conversion

Hello All! Some of you already know that I am working on converting the Catalyst repository to git. I am happy to announce that I am closing in on completion! The current state of the git repo: https://github.com/frioux/Catalyst The script to convert it: https://github.com/frioux/Git-Conversions/blob/master/cat-convert The only things I know of that we must have before we finalize this conversion is: Is it correct that the svn user rjk is Ronald J Kimball: rjk AT linguist DOT dartmouth DAWT edu ?

Posted Sat, Feb 12, 2011

My Fork of ExtJS

Sencha has been pretty slow at fixing bugs for the company where I work. We not only pay for usage but also for forum support. I’ve decided to personally (that is, me, not my company) fork ExtJS and maintain a set of patches on top of it. Those patches will be licensed as GPLv3 (because they must, because ExtJS is licensed as GPLv3) and Sencha can take them and merge them into core whenever they want.

Posted Wed, Feb 9, 2011

New stuff in DBIx::Class::Helpers

I just released a new version of DBIx::Class::Helpers and it has two new components: DBIx::Class::Helper::ResultSet::ResultClassDWIM and DBIx::Class::Helper::Schema::GenerateSource. Helper::ResultSet::ResultClassDWIM This component solves an issue I’ve seen both by myself and with my coworkers; it’s too hard to remember/type the following: my $rs = $schema->resultset('Foo')->search($q, { result_class => 'DBIx::Class::ResultClass::HashRefInflator', }); So I wrote this component which will let you generically write: my $rs = $schema->resultset('Foo')->search($q, { result_class => '::HashRefInflator', }); or use the specially hardcoded:

Posted Tue, Feb 1, 2011

New Stuff in Data::Dumper::Concise (Devel::Dwarn)

I just released a new Data::Dumper::Concise. There are new features! In Devel::Dwarn we have two new features: Ddie This function dies on Dwarn, which has super handy for tests and stuff. Ddie { frew => 1, }; DwarnF This is like Log::Contextual’s Dlog methods. So you now can do the following: DwarnF { "user: $_[0]\n session: $_[1]" } $user, $session; DumperObject Apparently people needed this. It’s part of Data::Dumper::Concise.

Posted Fri, Jan 21, 2011

Announcing Config::ZOMG

For a while now I’ve wanted to tear Config::JFDI up. Since I first used it it’s always been too heavy and had too many little weird things. Well, I did that last night and it ended up getting three times faster! I’ve released the fork as Config::ZOMG (I considered GTFO and STFU, but thought better of it.) For the most part it’s the same as Config::JFDI of course, but basically what I did was remove the substitution and install_accessor features, removed isa checks, and switched from Any::Moose to Moo with inlined defaults.

Posted Wed, Jan 12, 2011

Predefined Schema Additions for DBIx::Class

At work we have a tiny set of classes and relationships that we’ve reused for a few projects now. The idea is that it’s a package deal of users, roles, permissions, and a way to map permissions to parts of the application. I’m actually pretty fond of it, but its usage is a little awkward and not very flexible. If I could I’d put it on CPAN as that would mean tests, docs, and more importantly, a way to make it more useful for disparate projects.

Posted Tue, Dec 28, 2010