Mojolicious and DBI handles
From http://toroid.org/ams/etc/mojolicious-db-handles we find this bit of code:
sub startup {
my $app = shift;
my ($user, $pass);
# read $user and $pass from config file
(ref $app)->attr(db => sub {
DBI->connect("dbi:Mysql:database=$db",
$user, $pass)
}
);
}
The concept is that Morbo, or Starman, or whatever PSGI server is running your program, can use any kind of forking, but each instance of your program will execute the startup code and create its own database handle.
Some of the code is not too obvious:
ref $app
returns the class name of the main object. In my tests, replacing this line with the more obvious:$app->attr(db =>…
worked just fine. EDIT: Apparently theref
business is because he wanted the class method, although because there isn't an instance method by the same name ofattr
, it doesn't matter.The
attr(...)
call is a Mojolicious method (see here) that is described as, "Create attribute accessor for hash-based objects." What that means is, the call actually creates a function definition as a string, and then does an eval of the string, thereby creating the named function (db
in this case) in the given namespace(ref $app)
in this case.
And here's how you get the data back out:
$app->get('/test')->to(cb =>
sub{
my $self = shift;
$Data::Dumper::Indent = 1;
$self->render( 'text' => "TEST: ATTR of foo" . $self->app->foo .
"\n<pre>\n" . Dumper($self) . "</pre>" );
});
It's really a better idea to use DBIx::Connector anyway, but the startup attribute trick might come in handy elsewhere. One note on DBIX::Connector − Under the heading, Execution Methods we see the code:
<span class="sh_variable">$conn</span><span class="sh_symbol">-></span><span class="sh_function">run</span><span class="sh_symbol">(</span><span class="sh_keyword">sub</span> <span class="sh_cbracket">{</span> <span class="sh_variable">$_</span><span class="sh_symbol">-></span><span class="sh_keyword">do</span><span class="sh_symbol">(</span><span class="sh_variable">$query</span><span class="sh_symbol">)</span> <span class="sh_cbracket">}</span><span class="sh_symbol">);</span>
It is not documented, but by reading the source (let's hear it for free software!) what happens is that $_ is set, via the «local» keyword, to temporarily be the database handle (dbh) of the connection within execution of the code reference.
Thanks to mst and others on #perl for the assistance.