[Catalyst] Mason + DBI + Catalyst?

Octavian Râsnita orasnita at gmail.com
Tue May 26 18:04:41 GMT 2009


> On Tue, May 26, 2009 at 01:37:40AM +0200, Daniel Carrera wrote:
>> >Being able to chain resultsets makes it much much easier than using
>> >straight SQL, and you write less code.  If you have a query you've
>> >constructed called $query, and lets say you now only want active records
>> >you can do $query = $query->search({ active => 1 });  In this way you
>> >can filter many things incrementally.
>>
>> But is that efficient? It looks like you are getting MySQL to return the
>> entire data set and then making Perl filter it. That can't be efficient.

Here it is a short code example that might appear in a controller:

sub author : Local {
  my ($self, $c) = @_;

#Variables you might get after the user submits a form:

  my $name = $c->req->params->{name};
  my $country = $c->req->params->{country};

#Search the database for all fiction authors:

  my $authors = $c->model("DB::Authors")->search({
    style => 'fiction',
  });

#Until this point DBIC doesn't touch the database.

#Add filters based on what the user searched using the form:

  $authors = $authors->search({name => {-like => "%$name%"}) if $name;

  $authors = $authors->search({country => $country}) if $country;

#Until this point, DBIC also didn't touch the database.

#Add the $authors object to the stash, to be able to print it in a template:
  $c->stash->{authors} = $authors;

#Until here, DBIC didn't touch the database
}

#And the subroutine ended.

And then you can print some things using a Template-Toolkit template 
(authors.tt):

[% IF some_variable = 1 %]
  [% FOREACH author = authors.next %]
    Name: [% author.name %]
    Country: [% author.country %]
    Localized birthday month: [% author.birthday.set_locale('fr').month_name 
%]

    The books of this author:
    [% FOREACH book = author.books %]
      [% book.title %] - [% book.editor %]
    [% END %]
  [% END %]
[% END %]


And at this point, DBIC still doesn't touch the database if the variable 
"some_variable" is not equal to 1 so the code below the IF line shouldn't be 
executed.

But if the variable is 1, only at this point DBIC executes the necessary 
queries and get the data. And you have seen that due to the relations that 
were created in the DBIC result classes, it would be very simple to access 
not only data about the authors, but about his books or data that can be 
found in other related tables, without needing to define a new query.

I wrote this code in Outlook Express and it might have bugs because I didn't 
test it, but I hope it helps to make an idea about what DBIC can do.

Octavian




More information about the Catalyst mailing list