The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

AnyEvent::DBI::MySQL - Asynchronous MySQL queries

SYNOPSIS

    use AnyEvent::DBI::MySQL;

    # get cached but not in use $dbh
    $dbh = AnyEvent::DBI::MySQL->connect(…);

    # async
    $dbh->do(…,                 sub { my ($rv, $dbh) = @_; … });
    $sth = $dbh->prepare(…);
    $sth->execute(…,            sub { my ($rv, $sth) = @_; … });
    $dbh->selectall_arrayref(…, sub { my ($ary_ref)  = @_; … });
    $dbh->selectall_hashref(…,  sub { my ($hash_ref) = @_; … });
    $dbh->selectcol_arrayref(…, sub { my ($ary_ref)  = @_; … });
    $dbh->selectrow_array(…,    sub { my (@row_ary)  = @_; … });
    $dbh->selectrow_arrayref(…, sub { my ($ary_ref)  = @_; … });
    $dbh->selectrow_hashref(…,  sub { my ($hash_ref) = @_; … });

    # sync
    $rv = $dbh->do('…');
    $dbh->do('…', {async=>0}, sub { my ($rv, $dbh) = @_; … });

DESCRIPTION

This module is an AnyEvent user, you need to make sure that you use and run a supported event loop.

This module implements asynchronous MySQL queries using "ASYNCHRONOUS QUERIES" in DBD::mysql feature. Unlike AnyEvent::DBI it doesn't spawn any processes.

You shouldn't use {RaiseError=>1} with this module and should check returned values in your callback to detect errors. This is because with {RaiseError=>1} exception will be thrown instead of calling your callback function, which isn't what you want in most cases.

INTERFACE

The API is trivial: use it just like usual DBI, but instead of expecting return value from functions which may block add one extra parameter: callback. That callback will be executed with usual returned value of used method in params (only exception is extra $dbh/$sth param in do() and execute() for convenience).

SYNCHRONOUS QUERIES

In most cases to make usual synchronous query it's enough to don't provide callback - use standard DBI params and it will work just like usual DBI. Only exception is prepare()/execute() pair: you should use {async=>0} attribute for prepare() to have synchronous execute().

For convenience, you can quickly turn asynchronous query to synchronous by adding {async=>0} attribute - you don't have to rewrite code to remove callback function. In this case your callback will be called immediately after executing this synchronous query.

connect(…)

DBD::mysql support only single asynchronous query per MySQL connection. To make it easier to overcome this limitation provided connect() constructor work using DBI->connect_cached() under the hood, but it reuse only inactive $dbh - i.e. one which you didn't use anymore. So, connect() guarantee to not return $dbh which is already in use in your code. For example, in FastCGI or Mojolicious app you can safely use connect() to get own $dbh per each incoming connection; after you send response and close this connection that $dbh should automatically go out of scope and become inactive (you can force this by $dbh=undef;); after that this $dbh may be returned by connect() when handling next incoming request. As result you should automatically get a pool of connected $dbh which size should match peak amount of simultaneously handled CGI requests. You can flush that $dbh cache as documented by DBI at any time.

NOTE: To implement this caching behavior this module catch DESTROY() for $dbh and instead of destroying it (and calling $dbh->disconnect()) make it available for next connect() call in cache. So, if you need to call $dbh->disconnect() - do it manually and don't expect it to happens automatically on $dbh DESTROY(), like it work in DBI.

Also, usual limitations for cached connections apply as documented by DBI (read: don't change $dbh configuration).

$dbh->do(…, sub { my ($rv, $dbh) = @_; … });
$sth->execute(…, sub { my ($rv, $sth) = @_; … });
$dbh->selectall_arrayref(…, sub { my ($ary_ref) = @_; … });
$dbh->selectall_hashref(…, sub { my ($hash_ref) = @_; … });
$dbh->selectcol_arrayref(…, sub { my ($ary_ref) = @_; … });
$dbh->selectrow_array(…, sub { my (@row_ary) = @_; … });
$dbh->selectrow_arrayref(…, sub { my ($ary_ref) = @_; … });
$dbh->selectrow_hashref(…, sub { my ($hash_ref) = @_; … });

BUGS AND LIMITATIONS

No bugs have been reported.

These DBI methods not supported yet (i.e. they work as usually - in blocking mode), mostly because they internally run several queries and should be completely rewritten to support non-blocking mode.

NOTE: You have to provide {async=>0} attribute to prepare() before using execute_array() or execute_for_fetch().

    $sth->execute_array(…)
    $sth->execute_for_fetch(…)
    $dbh->table_info(…)
    $dbh->column_info(…)
    $dbh->primary_key_info(…)
    $dbh->foreign_key_info(…)
    $dbh->statistics_info(…)
    $dbh->primary_key(…)
    $dbh->tables(…)

SUPPORT

Please report any bugs or feature requests through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=AnyEvent-DBI-MySQL. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

You can also look for information at:

SEE ALSO

AnyEvent, DBI, AnyEvent::DBI

AUTHOR

Alex Efros <powerman@cpan.org>

LICENSE AND COPYRIGHT

Copyright 2013 Alex Efros <powerman@cpan.org>.

This program is distributed under the MIT (X11) License: http://www.opensource.org/licenses/mit-license.php

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.