| 1 |
NAME |
| 2 |
AnyEvent::DBI - asynchronous DBI access |
| 3 |
|
| 4 |
SYNOPSIS |
| 5 |
use AnyEvent::DBI; |
| 6 |
|
| 7 |
my $cv = AnyEvent->condvar; |
| 8 |
|
| 9 |
my $dbh = new AnyEvent::DBI "DBI:SQLite:dbname=test.db", "", ""; |
| 10 |
|
| 11 |
$dbh->exec ("select * from test where num=?", 10, sub { |
| 12 |
my ($dbh, $rows, $rv) = @_; |
| 13 |
|
| 14 |
$#_ or die "failure: $@"; |
| 15 |
|
| 16 |
print "@$_\n" |
| 17 |
for @$rows; |
| 18 |
|
| 19 |
$cv->broadcast; |
| 20 |
}); |
| 21 |
|
| 22 |
# asynchronously do sth. else here |
| 23 |
|
| 24 |
$cv->wait; |
| 25 |
|
| 26 |
DESCRIPTION |
| 27 |
This module is an AnyEvent user, you need to make sure that you use and |
| 28 |
run a supported event loop. |
| 29 |
|
| 30 |
This module implements asynchronous DBI access by forking or executing |
| 31 |
separate "DBI-Server" processes and sending them requests. |
| 32 |
|
| 33 |
It means that you can run DBI requests in parallel to other tasks. |
| 34 |
|
| 35 |
With DBD::mysql, the overhead for very simple statements ("select 0") is |
| 36 |
somewhere around 50% compared to an explicit |
| 37 |
prepare_cached/execute/fetchrow_arrayref/finish combination. With |
| 38 |
DBD::SQlite3, it's more like a factor of 8 for this trivial statement. |
| 39 |
|
| 40 |
ERROR HANDLING |
| 41 |
This module defines a number of functions that accept a callback |
| 42 |
argument. All callbacks used by this module get their AnyEvent::DBI |
| 43 |
handle object passed as first argument. |
| 44 |
|
| 45 |
If the request was successful, then there will be more arguments, |
| 46 |
otherwise there will only be the $dbh argument and $@ contains an error |
| 47 |
message. |
| 48 |
|
| 49 |
A convenient way to check whether an error occurred is to check $#_ - if |
| 50 |
that is true, then the function was successful, otherwise there was an |
| 51 |
error. |
| 52 |
|
| 53 |
METHODS |
| 54 |
$dbh = new AnyEvent::DBI $database, $user, $pass, [key => value]... |
| 55 |
Returns a database handle for the given database. Each database |
| 56 |
handle has an associated server process that executes statements in |
| 57 |
order. If you want to run more than one statement in parallel, you |
| 58 |
need to create additional database handles. |
| 59 |
|
| 60 |
The advantage of this approach is that transactions work as state is |
| 61 |
preserved. |
| 62 |
|
| 63 |
Example: |
| 64 |
|
| 65 |
$dbh = new AnyEvent::DBI |
| 66 |
"DBI:mysql:test;mysql_read_default_file=/root/.my.cnf", "", ""; |
| 67 |
|
| 68 |
Additional key-value pairs can be used to adjust behaviour: |
| 69 |
|
| 70 |
on_error => $callback->($dbh, $filename, $line, $fatal) |
| 71 |
When an error occurs, then this callback will be invoked. On |
| 72 |
entry, $@ is set to the error message. $filename and $line is |
| 73 |
where the original request was submitted. |
| 74 |
|
| 75 |
If the fatal argument is true then the database connection is |
| 76 |
shut down and your database handle became invalid. In addition |
| 77 |
to invoking the "on_error" callback, all of your queued request |
| 78 |
callbacks are called without only the $dbh argument. |
| 79 |
|
| 80 |
If omitted, then "die" will be called on any errors, fatal or |
| 81 |
not. |
| 82 |
|
| 83 |
on_connect => $callback->($dbh[, $success]) |
| 84 |
If you supply an "on_connect" callback, then this callback will |
| 85 |
be invoked after the database connect attempt. If the connection |
| 86 |
succeeds, $success is true, otherwise it is missing and $@ |
| 87 |
contains the $DBI::errstr. |
| 88 |
|
| 89 |
Regardless of whether "on_connect" is supplied, connect errors |
| 90 |
will result in "on_error" being called. However, if no |
| 91 |
"on_connect" callback is supplied, then connection errors are |
| 92 |
considered fatal. The client will "die" and the "on_error" |
| 93 |
callback will be called with $fatal true. |
| 94 |
|
| 95 |
When on_connect is supplied, connect error are not fatal and |
| 96 |
AnyEvent::DBI will not "die". You still cannot, however, use the |
| 97 |
$dbh object you received from "new" to make requests. |
| 98 |
|
| 99 |
fork_template => $AnyEvent::Fork-object |
| 100 |
"AnyEvent::DBI" uses "AnyEvent::Fork->new" to create the |
| 101 |
database slave, which in turn either "exec"'s a new process |
| 102 |
(similar to the old "exec_server" constructor argument) or uses |
| 103 |
a process forked early (see AnyEvent::Fork::Early). |
| 104 |
|
| 105 |
With this argument you can provide your own fork template. This |
| 106 |
can be useful if you create a lot of "AnyEvent::DBI" handles and |
| 107 |
want to save memory (And speed up startup) by not having to load |
| 108 |
"AnyEvent::DBI" again and again into your child processes: |
| 109 |
|
| 110 |
my $template = AnyEvent::Fork |
| 111 |
->new # create new template |
| 112 |
->require ("AnyEvent::DBI::Slave"); # preload AnyEvent::DBI::Slave module |
| 113 |
|
| 114 |
for (...) { |
| 115 |
$dbh = new AnyEvent::DBI ... |
| 116 |
fork_template => $template; |
| 117 |
|
| 118 |
timeout => seconds |
| 119 |
If you supply a timeout parameter (fractional values are |
| 120 |
supported), then a timer is started any time the DBI handle |
| 121 |
expects a response from the server. This includes connection |
| 122 |
setup as well as requests made to the backend. The timeout spans |
| 123 |
the duration from the moment the first data is written (or |
| 124 |
queued to be written) until all expected responses are returned, |
| 125 |
but is postponed for "timeout" seconds each time more data is |
| 126 |
returned from the server. If the timer ever goes off then a |
| 127 |
fatal error is generated. If you have an "on_error" handler |
| 128 |
installed, then it will be called, otherwise your program will |
| 129 |
die(). |
| 130 |
|
| 131 |
When altering your databases with timeouts it is wise to use |
| 132 |
transactions. If you quit due to timeout while performing |
| 133 |
insert, update or schema-altering commands you can end up not |
| 134 |
knowing if the action was submitted to the database, |
| 135 |
complicating recovery. |
| 136 |
|
| 137 |
Timeout errors are always fatal. |
| 138 |
|
| 139 |
Any additional key-value pairs will be rolled into a hash reference |
| 140 |
and passed as the final argument to the "DBI->connect (...)" call. |
| 141 |
For example, to suppress errors on STDERR and send them instead to |
| 142 |
an AnyEvent::Handle you could do: |
| 143 |
|
| 144 |
$dbh = new AnyEvent::DBI |
| 145 |
"DBI:mysql:test;mysql_read_default_file=/root/.my.cnf", "", "", |
| 146 |
PrintError => 0, |
| 147 |
on_error => sub { |
| 148 |
$log_handle->push_write ("DBI Error: $@ at $_[1]:$_[2]\n"); |
| 149 |
}; |
| 150 |
|
| 151 |
$dbh->on_error ($cb->($dbh, $filename, $line, $fatal)) |
| 152 |
Sets (or clears, with "undef") the "on_error" handler. |
| 153 |
|
| 154 |
$dbh->timeout ($seconds) |
| 155 |
Sets (or clears, with "undef") the database timeout. Useful to |
| 156 |
extend the timeout when you are about to make a really long query. |
| 157 |
|
| 158 |
$dbh->attr ($attr_name[, $attr_value], $cb->($dbh, $new_value)) |
| 159 |
An accessor for the database handle attributes, such as |
| 160 |
"AutoCommit", "RaiseError", "PrintError" and so on. If you provide |
| 161 |
an $attr_value (which might be "undef"), then the given attribute |
| 162 |
will be set to that value. |
| 163 |
|
| 164 |
The callback will be passed the database handle and the attribute's |
| 165 |
value if successful. |
| 166 |
|
| 167 |
If an error occurs and the "on_error" callback returns, then only |
| 168 |
$dbh will be passed and $@ contains the error message. |
| 169 |
|
| 170 |
$dbh->exec ("statement", @args, $cb->($dbh, \@rows, $rv)) |
| 171 |
Executes the given SQL statement with placeholders replaced by |
| 172 |
@args. The statement will be prepared and cached on the server side, |
| 173 |
so using placeholders is extremely important. |
| 174 |
|
| 175 |
The callback will be called with a weakened AnyEvent::DBI object as |
| 176 |
the first argument and the result of "fetchall_arrayref" as (or |
| 177 |
"undef" if the statement wasn't a select statement) as the second |
| 178 |
argument. |
| 179 |
|
| 180 |
Third argument is the return value from the "DBI->execute" method |
| 181 |
call. |
| 182 |
|
| 183 |
If an error occurs and the "on_error" callback returns, then only |
| 184 |
$dbh will be passed and $@ contains the error message. |
| 185 |
|
| 186 |
$dbh->stattr ($attr_name, $cb->($dbh, $value)) |
| 187 |
An accessor for the statement attributes of the most recently |
| 188 |
executed statement, such as "NAME" or "TYPE". |
| 189 |
|
| 190 |
The callback will be passed the database handle and the attribute's |
| 191 |
value if successful. |
| 192 |
|
| 193 |
If an error occurs and the "on_error" callback returns, then only |
| 194 |
$dbh will be passed and $@ contains the error message. |
| 195 |
|
| 196 |
$dbh->begin_work ($cb->($dbh[, $rc])) |
| 197 |
$dbh->commit ($cb->($dbh[, $rc])) |
| 198 |
$dbh->rollback ($cb->($dbh[, $rc])) |
| 199 |
The begin_work, commit, and rollback methods expose the equivalent |
| 200 |
transaction control method of the DBI driver. On success, $rc is |
| 201 |
true. |
| 202 |
|
| 203 |
If an error occurs and the "on_error" callback returns, then only |
| 204 |
$dbh will be passed and $@ contains the error message. |
| 205 |
|
| 206 |
$dbh->func ('string_which_yields_args_when_evaled', $func_name, |
| 207 |
$cb->($dbh, $rc, $dbi_err, $dbi_errstr)) |
| 208 |
This gives access to database driver private methods. Because they |
| 209 |
are not standard you cannot always depend on the value of $rc or |
| 210 |
$dbi_err. Check the documentation for your specific driver/function |
| 211 |
combination to see what it returns. |
| 212 |
|
| 213 |
Note that the first argument will be eval'ed to produce the argument |
| 214 |
list to the func() method. This must be done because the |
| 215 |
serialization protocol between the AnyEvent::DBI server process and |
| 216 |
your program does not support the passage of closures. |
| 217 |
|
| 218 |
Here's an example to extend the query language in SQLite so it |
| 219 |
supports an intstr() function: |
| 220 |
|
| 221 |
$cv = AnyEvent->condvar; |
| 222 |
$dbh->func ( |
| 223 |
q{ |
| 224 |
instr => 2, sub { |
| 225 |
my ($string, $search) = @_; |
| 226 |
return index $string, $search; |
| 227 |
}, |
| 228 |
}, |
| 229 |
create_function => sub { |
| 230 |
return $cv->send ($@) |
| 231 |
unless $#_; |
| 232 |
$cv->send (undef, @_[1,2,3]); |
| 233 |
} |
| 234 |
); |
| 235 |
|
| 236 |
my ($err,$rc,$errcode,$errstr) = $cv->recv; |
| 237 |
|
| 238 |
die $err if defined $err; |
| 239 |
die "EVAL failed: $errstr" |
| 240 |
if $errcode; |
| 241 |
|
| 242 |
# otherwise, we can ignore $rc and $errcode for this particular func |
| 243 |
|
| 244 |
SEE ALSO |
| 245 |
AnyEvent, DBI, Coro::Mysql. |
| 246 |
|
| 247 |
AUTHOR AND CONTACT |
| 248 |
Marc Lehmann <schmorp@schmorp.de> (current maintainer) |
| 249 |
http://home.schmorp.de/ |
| 250 |
|
| 251 |
Adam Rosenstein <adam@redcondor.com> |
| 252 |
http://www.redcondor.com/ |
| 253 |
|