mirror of
https://github.com/php/php-src.git
synced 2024-10-21 00:12:34 +00:00
825034cea5
Asynchronous queries for mysqli, when mysqlnd is enabled. Includes 4 tests for mysqli_poll
168 lines
4.7 KiB
PHP
168 lines
4.7 KiB
PHP
--TEST--
|
|
mysqli_poll() & INSERT SELECT
|
|
--SKIPIF--
|
|
<?php
|
|
require_once('skipif.inc');
|
|
require_once('skipifemb.inc');
|
|
require_once('connect.inc');
|
|
require_once('skipifconnectfailure.inc');
|
|
|
|
if (!$IS_MYSQLND)
|
|
die("skip mysqlnd only feature, compile PHP using --with-mysqli=mysqlnd");
|
|
?>
|
|
--FILE--
|
|
<?php
|
|
require_once('table.inc');
|
|
|
|
function get_connection() {
|
|
global $host, $user, $passwd, $db, $port, $socket;
|
|
|
|
if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket))
|
|
printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
|
|
return $link;
|
|
}
|
|
|
|
|
|
// Note: some queries will fail! They are supposed to fail.
|
|
$queries = array(
|
|
'CREATE TABLE IF NOT EXISTS bogus(id INT)',
|
|
'SET @a = 1',
|
|
'SELECT * FROM test ORDER BY id ASC LIMIT 2',
|
|
'INSERT INTO test(id, label) VALUES (100, "z")',
|
|
'SELECT * FROM test ORDER BY id ASC LIMIT 2',
|
|
'SELECT',
|
|
'UPDATE test SET id = 101 WHERE id > 3',
|
|
'UPDATE_FIX test SET id = 101 WHERE id > 3',
|
|
'DROP TABLE IF EXISTS bogus',
|
|
'DELETE FROM test WHERE id = @a',
|
|
'DELETE FROM test WHERE id = 1',
|
|
);
|
|
|
|
$link = get_connection();
|
|
$have_proc = false;
|
|
mysqli_real_query($link, "DROP PROCEDURE IF EXISTS p");
|
|
if (mysqli_real_query($link, 'CREATE PROCEDURE p(IN ver_in VARCHAR(25), OUT ver_out VARCHAR(25)) BEGIN SELECT ver_in INTO ver_out; END;')) {
|
|
$have_proc = true;
|
|
$queries[] = 'CALL p("myversion", @version)';
|
|
}
|
|
mysqli_close($link);
|
|
|
|
$links = array();
|
|
for ($i = 0; $i < count($queries); $i++) {
|
|
|
|
$link = get_connection();
|
|
|
|
if (true !== ($tmp = mysqli_query($link, $queries[$i], MYSQLI_ASYNC | MYSQLI_USE_RESULT)))
|
|
printf("[002] Expecting true got %s/%s\n", gettype($tmp), var_export($tmp, true));
|
|
|
|
// WARNING KLUDGE NOTE
|
|
// Add a tiny delay to ensure that queries get executed in a certain order
|
|
// If your MySQL server is very slow the test may randomly fail!
|
|
usleep(20000);
|
|
|
|
$links[mysqli_thread_id($link)] = array(
|
|
'query' => $queries[$i],
|
|
'link' => $link,
|
|
'processed' => false,
|
|
);
|
|
}
|
|
|
|
$saved_errors = array();
|
|
do {
|
|
$poll_links = $poll_errors = $poll_reject = array();
|
|
foreach ($links as $thread_id => $link) {
|
|
if (!$link['processed']) {
|
|
$poll_links[] = $link['link'];
|
|
$poll_errors[] = $link['link'];
|
|
$poll_reject[] = $link['link'];
|
|
}
|
|
}
|
|
if (0 == count($poll_links))
|
|
break;
|
|
|
|
if (0 == ($num_ready = mysqli_poll($poll_links, $poll_errors, $poll_reject, 0, 200000)))
|
|
continue;
|
|
|
|
if (!empty($poll_errors)) {
|
|
die(var_dump($poll_errors));
|
|
}
|
|
|
|
foreach ($poll_links as $link) {
|
|
$thread_id = mysqli_thread_id($link);
|
|
$links[$thread_id]['processed'] = true;
|
|
|
|
if (is_object($res = mysqli_reap_async_query($link))) {
|
|
// result set object
|
|
while ($row = mysqli_fetch_assoc($res)) {
|
|
// eat up all results
|
|
;
|
|
}
|
|
mysqli_free_result($res);
|
|
} else {
|
|
// either there is no result (no SELECT) or there is an error
|
|
if (mysqli_errno($link) > 0) {
|
|
$saved_errors[$thread_id] = mysqli_errno($link);
|
|
printf("[003] '%s' caused %d\n", $links[$thread_id]['query'], mysqli_errno($link));
|
|
}
|
|
}
|
|
}
|
|
|
|
} while (true);
|
|
|
|
// Checking if all lines are still usable
|
|
foreach ($links as $thread_id => $link) {
|
|
if (isset($saved_errors[$thread_id]) &&
|
|
$saved_errors[$thread_id] != mysqli_errno($link['link'])) {
|
|
printf("[004] Error state not saved for query '%s', %d != %d\n", $link['query'],
|
|
$saved_errors[$thread_id], mysqli_errno($link['link']));
|
|
}
|
|
|
|
if (!$res = mysqli_query($link['link'], 'SELECT * FROM test WHERE id = 100'))
|
|
printf("[005] Expecting true got %s/%s\n", gettype($tmp), var_export($tmp, true));
|
|
if (!$row = mysqli_fetch_row($res))
|
|
printf("[006] Expecting true got %s/%s\n", gettype($tmp), var_export($tmp, true));
|
|
|
|
mysqli_free_result($res);
|
|
}
|
|
|
|
if ($res = mysqli_query($link['link'], "SELECT * FROM test WHERE id = 100")) {
|
|
$row = mysqli_fetch_assoc($res);
|
|
var_dump($row);
|
|
mysqli_free_result($res);
|
|
}
|
|
|
|
if ($have_proc && ($res = mysqli_query($link['link'], "SELECT @version as _version"))) {
|
|
$row = mysqli_fetch_assoc($res);
|
|
if ($row['_version'] != 'myversion') {
|
|
printf("[007] Check procedures\n");
|
|
}
|
|
mysqli_free_result($res);
|
|
}
|
|
|
|
foreach ($links as $link)
|
|
mysqli_close($link['link']);
|
|
|
|
$link = get_connection();
|
|
if (!mysqli_query($link, 'SELECT 1', MYSQLI_ASYNC))
|
|
printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
|
|
|
if (!mysqli_query($link, 'SELECT 1', MYSQLI_ASYNC))
|
|
printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
|
|
|
mysqli_close($link);
|
|
|
|
print "done!";
|
|
?>
|
|
--EXPECTF--
|
|
[003] 'SELECT' caused 1064
|
|
[003] 'UPDATE test SET id = 101 WHERE id > 3' caused 1062
|
|
[003] 'UPDATE_FIX test SET id = 101 WHERE id > 3' caused 1064
|
|
array(2) {
|
|
["id"]=>
|
|
string(3) "100"
|
|
["label"]=>
|
|
string(1) "z"
|
|
}
|
|
[009] [2014] %s
|
|
done!
|