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