ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-DBI/DBI.pm
(Generate patch)

Comparing AnyEvent-DBI/DBI.pm (file contents):
Revision 1.2 by root, Fri Jun 6 15:44:34 2008 UTC vs.
Revision 1.9 by root, Thu Nov 6 13:56:58 2008 UTC

3AnyEvent::DBI - asynchronous DBI access 3AnyEvent::DBI - asynchronous DBI access
4 4
5=head1 SYNOPSIS 5=head1 SYNOPSIS
6 6
7 use AnyEvent::DBI; 7 use AnyEvent::DBI;
8
9 my $cv = AnyEvent->condvar;
10
11 my $dbh = new AnyEvent::DBI "DBI:SQLite:dbname=test.db", "", "";
12
13 $dbh->exec ("select * from test where num=?", 10, sub {
14 my ($rows, $rv) = @_;
15
16 print "@$_\n"
17 for @$rows;
18
19 $cv->broadcast;
20 });
21
22 # asynchronously do sth. else here
23
24 $cv->wait;
8 25
9=head1 DESCRIPTION 26=head1 DESCRIPTION
10 27
11This module is an L<AnyEvent> user, you need to make sure that you use and 28This module is an L<AnyEvent> user, you need to make sure that you use and
12run a supported event loop. 29run a supported event loop.
13 30
14This module implements asynchronous DBI access my forking or executing 31This module implements asynchronous DBI access by forking or executing
15separate "DBI-Server" processes and sending them requests. 32separate "DBI-Server" processes and sending them requests.
16 33
17It means that you can run DBI requests in parallel to other tasks. 34It means that you can run DBI requests in parallel to other tasks.
35
36The overhead for very simple statements ("select 0") is somewhere
37around 120% to 200% (dual/single core CPU) compared to an explicit
38prepare_cached/execute/fetchrow_arrayref/finish combination.
18 39
19=cut 40=cut
20 41
21package AnyEvent::DBI; 42package AnyEvent::DBI;
22 43
31use DBI (); 52use DBI ();
32 53
33use AnyEvent (); 54use AnyEvent ();
34use AnyEvent::Util (); 55use AnyEvent::Util ();
35 56
36our $VERSION = '1.0'; 57our $VERSION = '1.1';
37 58
38# this is the forked server code 59# this is the forked server code
39 60
40our $DBH; 61our $DBH;
41 62
50sub req_exec { 71sub req_exec {
51 my (undef, $st, @args) = @{+shift}; 72 my (undef, $st, @args) = @{+shift};
52 73
53 my $sth = $DBH->prepare_cached ($st, undef, 1); 74 my $sth = $DBH->prepare_cached ($st, undef, 1);
54 75
55 $sth->execute (@args) 76 my $rv = $sth->execute (@args)
56 or die $sth->errstr; 77 or die $sth->errstr;
57 78
58 [$sth->fetchall_arrayref] 79 [1, $sth->{NUM_OF_FIELDS} ? $sth->fetchall_arrayref : undef, { rv => $rv }]
59} 80}
60 81
61sub serve { 82sub serve {
62 my ($fh) = @_; 83 my ($fh) = @_;
63 84
90 } 111 }
91 } 112 }
92 } 113 }
93 }; 114 };
94 115
116 if (AnyEvent::WIN32) {
95 kill 9, $$; # no other way on the broken windows platform 117 kill 9, $$; # no other way on the broken windows platform
118 # and the above doesn't even work on windows, it seems the only
119 # way to is to leak memory and kill 9 from the parent. yay.
120 }
121
122 require POSIX;
123 POSIX::_exit (0);
124 # and the above kills the parent process on windows
96} 125}
97 126
98=head2 METHODS 127=head2 METHODS
99 128
100=over 4 129=over 4
184 } else { 213 } else {
185 $wself->_error ("read error: $!", @caller, 1); 214 $wself->_error ("read error: $!", @caller, 1);
186 } 215 }
187 }); 216 });
188 217
218 $self->{ww_cb} = sub {
219 my $len = syswrite $client, $wself->{wbuf}
220 or return delete $wself->{ww};
221
222 substr $wself->{wbuf}, 0, $len, "";
223 };
224
189 my $pid = fork; 225 my $pid = fork;
190 226
191 if ($pid) { 227 if ($pid) {
192 # parent 228 # parent
193 close $server; 229 close $server;
214 delete $self->{ww}; 250 delete $self->{ww};
215 delete $self->{fh}; 251 delete $self->{fh};
216 252
217 $@ = $error; 253 $@ = $error;
218 254
255 if ($self->{on_error}) {
219 $self->{on_error}($self, $filename, $line, $fatal) 256 $self->{on_error}($self, $filename, $line, $fatal);
220 if $self->{on_error}; 257 return unless $fatal;
258 }
221 259
222 die "$error at $filename, line $line\n"; 260 die "$error at $filename, line $line\n";
223} 261}
224 262
225sub _req { 263sub _req {
231 269
232 unless ($self->{ww}) { 270 unless ($self->{ww}) {
233 my $len = syswrite $self->{fh}, $self->{wbuf}; 271 my $len = syswrite $self->{fh}, $self->{wbuf};
234 substr $self->{wbuf}, 0, $len, ""; 272 substr $self->{wbuf}, 0, $len, "";
235 273
236 #TODO, ww_cb
237 # still any left? then install a write watcher 274 # still any left? then install a write watcher
238 $self->{ww} = AnyEvent->io (fh => $self->{fh}, poll => "w", cb => $self->{ww_cb}) 275 $self->{ww} = AnyEvent->io (fh => $self->{fh}, poll => "w", cb => $self->{ww_cb})
239 if length $self->{wbuf}; 276 if length $self->{wbuf};
240 } 277 }
241} 278}
242 279
243=item $dbh->exec ("statement", @args, $cb->($rows, %extra)) 280=item $dbh->exec ("statement", @args, $cb->($rows, $rv, ...))
244 281
245Executes the given SQL statement with placeholders replaced by 282Executes the given SQL statement with placeholders replaced by
246C<@args>. The statement will be prepared and cached on the server side, so 283C<@args>. The statement will be prepared and cached on the server side, so
247using placeholders is compulsory. 284using placeholders is compulsory.
248 285
249The callback will be called with the result of C<fetchall_arrayref> as 286The callback will be called with the result of C<fetchall_arrayref> as
250first argument and possibly a hash reference with additional information. 287first argument (or C<undef> if the statement wasn't a select statement)
288and the return value of C<execute> as second argument. Additional
289arguments might get passed as well.
251 290
252If an error occurs and the C<on_error> callback returns, then no arguments 291If an error occurs and the C<on_error> callback returns, then no arguments
253will be passed and C<$@> contains the error message. 292will be passed and C<$@> contains the error message.
254 293
255=cut 294=cut
267 306
268L<AnyEvent>, L<DBI>. 307L<AnyEvent>, L<DBI>.
269 308
270=head1 AUTHOR 309=head1 AUTHOR
271 310
272 Marc Lehmann <schmorp@schmorp.de> 311 Marc Lehmann <schmorp@schmorp.de>
273 http://home.schmorp.de/ 312 http://home.schmorp.de/
274 313
275=cut 314=cut
276 315
2771 3161
278 317

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines