1use strict;
2use warnings;
3
4use Test::Deep;
5use Test::More;
6use DBI;
7use DBI::Const::GetInfoType;
8use Time::HiRes;
9
10use vars qw($test_dsn $test_user $test_password);
11use lib 't', '.';
12require 'lib.pl';
13
14my $dbh;
15eval {$dbh= DBI->connect($test_dsn, $test_user, $test_password,
16                      { RaiseError => 0, PrintError => 0, AutoCommit => 0 });};
17if (!$dbh) {
18    plan skip_all => "no database connection";
19}
20if ($dbh->{mysql_serverversion} < 50012) {
21    plan skip_all => "Servers < 5.0.12 do not support SLEEP()";
22}
23plan tests => 92;
24
25is $dbh->get_info($GetInfoType{'SQL_ASYNC_MODE'}), 2; # statement-level async
26is $dbh->get_info($GetInfoType{'SQL_MAX_ASYNC_CONCURRENT_STATEMENTS'}), 1;
27
28$dbh->do(<<SQL);
29CREATE TEMPORARY TABLE async_test (
30    value0 INTEGER,
31    value1 INTEGER,
32    value2 INTEGER
33);
34SQL
35
36ok $dbh->mysql_fd;
37ok !defined($dbh->mysql_async_ready);
38
39my ( $start, $end );
40my $rows;
41my $sth;
42my ( $a, $b, $c );
43
44$start = Time::HiRes::gettimeofday();
45$rows = $dbh->do('INSERT INTO async_test VALUES (SLEEP(2), 0, 0)');
46$end = Time::HiRes::gettimeofday();
47
48is $rows, 1;
49ok(($end - $start) >= 2);
50
51$start = Time::HiRes::gettimeofday();
52$rows = $dbh->do('INSERT INTO async_test VALUES (SLEEP(2), 0, 0)', { async => 1 });
53ok(defined($dbh->mysql_async_ready)) or die;
54$end = Time::HiRes::gettimeofday();
55
56ok $rows;
57is $rows, '0E0';
58
59ok(($end - $start) < 2);
60
61sleep 1 until $dbh->mysql_async_ready;
62$end = Time::HiRes::gettimeofday();
63ok(($end - $start) >= 2);
64
65$rows = $dbh->mysql_async_result;
66ok !defined($dbh->mysql_async_ready);
67
68is $rows, 1;
69
70( $rows ) = $dbh->selectrow_array('SELECT COUNT(1) FROM async_test');
71
72is $rows, 2;
73
74$dbh->do('DELETE FROM async_test');
75
76$start = Time::HiRes::gettimeofday();
77$rows = $dbh->do('INSERT INTO async_test VALUES(SLEEP(2), ?, ?)', { async => 1 }, 1, 2);
78$end = Time::HiRes::gettimeofday();
79
80ok $rows;
81is $rows, '0E0';
82
83ok(($end - $start) < 2);
84
85sleep 1 until $dbh->mysql_async_ready;
86$end = Time::HiRes::gettimeofday();
87ok(($end - $start) >= 2);
88
89$rows = $dbh->mysql_async_result;
90
91is $rows, 1;
92
93( $a, $b, $c ) = $dbh->selectrow_array('SELECT * FROM async_test');
94
95is $a, 0;
96is $b, 1;
97is $c, 2;
98
99$sth = $dbh->prepare('SELECT SLEEP(2)');
100ok !defined($sth->mysql_async_ready);
101$start = Time::HiRes::gettimeofday();
102ok $sth->execute;
103$end = Time::HiRes::gettimeofday();
104ok(($end - $start) >= 2);
105
106$sth = $dbh->prepare('SELECT SLEEP(2)', { async => 1 });
107ok !defined($sth->mysql_async_ready);
108$start = Time::HiRes::gettimeofday();
109ok $sth->execute;
110ok defined($sth->mysql_async_ready);
111$end = Time::HiRes::gettimeofday();
112ok(($end - $start) < 2);
113
114sleep 1 until $sth->mysql_async_ready;
115
116my $row = $sth->fetch;
117$end = Time::HiRes::gettimeofday();
118ok $row;
119is $row->[0], 0;
120ok(($end - $start) >= 2);
121
122$rows = $dbh->do('INSERT INTO async_test VALUES(SLEEP(2), ?, ?', { async => 1 }, 1, 2);
123
124ok $rows;
125ok !$dbh->errstr;
126$rows = $dbh->mysql_async_result;
127ok !$rows;
128ok $dbh->errstr;
129
130$dbh->do('DELETE FROM async_test');
131
132$sth = $dbh->prepare('INSERT INTO async_test VALUES(SLEEP(2), ?, ?)', { async => 1 });
133$start = Time::HiRes::gettimeofday();
134$rows = $sth->execute(1, 2);
135$end = Time::HiRes::gettimeofday();
136ok(($end - $start) < 2);
137ok $rows;
138is $rows, '0E0';
139
140$rows = $sth->mysql_async_result;
141$end = Time::HiRes::gettimeofday();
142ok(($end - $start) >= 2);
143is $rows, 1;
144
145( $a, $b, $c ) = $dbh->selectrow_array('SELECT * FROM async_test');
146
147is $a, 0;
148is $b, 1;
149is $c, 2;
150
151$sth  = $dbh->prepare('INSERT INTO async_test VALUES(SLEEP(2), ?, ?)', { async => 1 });
152$rows = $dbh->do('INSERT INTO async_test VALUES(SLEEP(2), ?, ?)', undef, 1, 2);
153is $rows, 1;
154
155$start = Time::HiRes::gettimeofday();
156$dbh->selectrow_array('SELECT SLEEP(2)', { async => 1 });
157$end = Time::HiRes::gettimeofday();
158
159ok(($end - $start) >= 2);
160ok !defined($dbh->mysql_async_result);
161ok !defined($dbh->mysql_async_ready);
162
163$rows = $dbh->do('UPDATE async_test SET value0 = 0 WHERE value0 = 999', { async => 1 });
164ok $rows;
165is $rows, '0E0';
166$rows = $dbh->mysql_async_result;
167ok $rows;
168is $rows, '0E0';
169
170$sth  = $dbh->prepare('UPDATE async_test SET value0 = 0 WHERE value0 = 999', { async => 1 });
171$rows = $sth->execute;
172ok $rows;
173is $rows, '0E0';
174$rows = $sth->mysql_async_result;
175ok $rows;
176is $rows, '0E0';
177
178$sth->execute;
179$rows = $dbh->do('INSERT INTO async_test VALUES(1, 2, 3)');
180ok !$rows;
181undef $sth;
182$rows = $dbh->do('INSERT INTO async_test VALUES(1, 2, 3)');
183is $rows, 1;
184
185$sth = $dbh->prepare('SELECT 1, value0, value1, value2 FROM async_test WHERE value0 = ?', { async => 1 });
186$sth->execute(1);
187is $sth->{'NUM_OF_FIELDS'}, undef;
188is $sth->{'NUM_OF_PARAMS'}, 1;
189is $sth->{'NAME'}, undef;
190is $sth->{'NAME_lc'}, undef;
191is $sth->{'NAME_uc'}, undef;
192is $sth->{'NAME_hash'}, undef;
193is $sth->{'NAME_lc_hash'}, undef;
194is $sth->{'NAME_uc_hash'}, undef;
195is $sth->{'TYPE'}, undef;
196is $sth->{'PRECISION'}, undef;
197is $sth->{'SCALE'}, undef;
198is $sth->{'NULLABLE'}, undef;
199is $sth->{'Database'}, $dbh;
200is $sth->{'Statement'}, 'SELECT 1, value0, value1, value2 FROM async_test WHERE value0 = ?';
201$sth->mysql_async_result;
202is $sth->{'NUM_OF_FIELDS'}, 4;
203is $sth->{'NUM_OF_PARAMS'}, 1;
204cmp_bag $sth->{'NAME'}, [qw/1 value0 value1 value2/];
205cmp_bag $sth->{'NAME_lc'}, [qw/1 value0 value1 value2/];
206cmp_bag $sth->{'NAME_uc'}, [qw/1 VALUE0 VALUE1 VALUE2/];
207cmp_bag [ keys %{$sth->{'NAME_hash'}} ], [qw/1 value0 value1 value2/];
208cmp_bag [ keys %{$sth->{'NAME_lc_hash'}} ], [qw/1 value0 value1 value2/];
209cmp_bag [ keys %{$sth->{'NAME_uc_hash'}} ], [qw/1 VALUE0 VALUE1 VALUE2/];
210is ref($sth->{'TYPE'}), 'ARRAY';
211is ref($sth->{'PRECISION'}), 'ARRAY';
212is ref($sth->{'SCALE'}), 'ARRAY';
213is ref($sth->{'NULLABLE'}), 'ARRAY';
214is $sth->{'Database'}, $dbh;
215is $sth->{'Statement'}, 'SELECT 1, value0, value1, value2 FROM async_test WHERE value0 = ?';
216$sth->finish;
217
218$sth->execute(1);
219$row = $sth->fetch;
220is_deeply $row, [1, 1, 2, 3];
221$sth->finish;
222
223$sth->execute(1);
224$row = $sth->fetchrow_arrayref;
225is_deeply $row, [1, 1, 2, 3];
226$sth->finish;
227
228$sth->execute(1);
229my @row = $sth->fetchrow_array;
230is_deeply \@row, [1, 1, 2, 3];
231$sth->finish;
232
233$sth->execute(1);
234$row = $sth->fetchrow_hashref;
235cmp_bag [ keys %$row ], [qw/1 value0 value1 value2/];
236cmp_bag [ values %$row ], [1, 1, 2, 3];
237$sth->finish;
238
239undef $sth;
240ok $dbh->disconnect;
241