1--TEST-- 2mysqli_poll() & INSERT SELECT 3--EXTENSIONS-- 4mysqli 5--SKIPIF-- 6<?php 7require_once 'skipifconnectfailure.inc'; 8?> 9--FILE-- 10<?php 11 require_once 'table.inc'; 12 13 function get_connection() { 14 global $host, $user, $passwd, $db, $port, $socket; 15 16 if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) 17 printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); 18 return $link; 19 } 20 21 22 // Note: some queries will fail! They are supposed to fail. 23 $queries = array( 24 'CREATE TABLE IF NOT EXISTS bogus(id INT)', 25 'SET @a = 1', 26 'SELECT * FROM test ORDER BY id ASC LIMIT 2', 27 "INSERT INTO test(id, label) VALUES (100, 'z')", 28 'SELECT * FROM test ORDER BY id ASC LIMIT 2', 29 'SELECT', 30 'UPDATE test SET id = 101 WHERE id > 3', 31 'UPDATE_FIX test SET id = 101 WHERE id > 3', 32 'DROP TABLE IF EXISTS bogus', 33 'DELETE FROM test WHERE id = @a', 34 'DELETE FROM test WHERE id = 1', 35 ); 36 37 $link = get_connection(); 38 $have_proc = false; 39 mysqli_real_query($link, "DROP PROCEDURE IF EXISTS p"); 40 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;')) { 41 $have_proc = true; 42 $queries[] = "CALL p('myversion', @version)"; 43 } 44 mysqli_close($link); 45 46 $links = array(); 47 for ($i = 0; $i < count($queries); $i++) { 48 49 $link = get_connection(); 50 51 if (true !== ($tmp = mysqli_query($link, $queries[$i], MYSQLI_ASYNC | MYSQLI_USE_RESULT))) 52 printf("[002] Expecting true got %s/%s\n", gettype($tmp), var_export($tmp, true)); 53 54 // WARNING KLUDGE NOTE 55 // Add a tiny delay to ensure that queries get executed in a certain order 56 // If your MySQL server is very slow the test may randomly fail! 57 usleep(20000); 58 59 $links[mysqli_thread_id($link)] = array( 60 'query' => $queries[$i], 61 'link' => $link, 62 'processed' => false, 63 ); 64 } 65 66 $saved_errors = array(); 67 do { 68 $poll_links = $poll_errors = $poll_reject = array(); 69 foreach ($links as $thread_id => $link) { 70 if (!$link['processed']) { 71 $poll_links[] = $link['link']; 72 $poll_errors[] = $link['link']; 73 $poll_reject[] = $link['link']; 74 } 75 } 76 if (0 == count($poll_links)) 77 break; 78 79 if (0 === ($num_ready = mysqli_poll($poll_links, $poll_errors, $poll_reject, 0, 200000))) 80 continue; 81 82 if (!empty($poll_errors)) { 83 die(var_dump($poll_errors)); 84 } 85 86 if (FALSE === $num_ready) { 87 die("Some mysqli indicated error"); 88 } 89 90 foreach ($poll_links as $link) { 91 $thread_id = mysqli_thread_id($link); 92 $links[$thread_id]['processed'] = true; 93 94 if (is_object($res = mysqli_reap_async_query($link))) { 95 // result set object 96 while ($row = mysqli_fetch_assoc($res)) { 97 // eat up all results 98 ; 99 } 100 mysqli_free_result($res); 101 } else { 102 // either there is no result (no SELECT) or there is an error 103 if (mysqli_errno($link) > 0) { 104 $saved_errors[$thread_id] = mysqli_errno($link); 105 } 106 } 107 } 108 109 } while (true); 110 111 // Checking if all lines are still usable 112 foreach ($links as $thread_id => $link) { 113 if (isset($saved_errors[$thread_id])) { 114 printf("[003] '%s' caused %d\n", 115 $links[$thread_id]['query'], $saved_errors[$thread_id]); 116 if ($saved_errors[$thread_id] != mysqli_errno($link['link'])) { 117 printf("[004] Error state not saved for query '%s', %d != %d\n", $link['query'], 118 $saved_errors[$thread_id], mysqli_errno($link['link'])); 119 } 120 } 121 122 if (!$res = mysqli_query($link['link'], 'SELECT * FROM test WHERE id = 100')) 123 printf("[005] Expecting true got %s/%s\n", gettype($tmp), var_export($tmp, true)); 124 if (!$row = mysqli_fetch_row($res)) 125 printf("[006] Expecting true got %s/%s\n", gettype($tmp), var_export($tmp, true)); 126 127 mysqli_free_result($res); 128 } 129 130 if ($res = mysqli_query($link['link'], "SELECT * FROM test WHERE id = 100")) { 131 $row = mysqli_fetch_assoc($res); 132 var_dump($row); 133 mysqli_free_result($res); 134 } 135 136 if ($have_proc && ($res = mysqli_query($link['link'], "SELECT @version as _version"))) { 137 $row = mysqli_fetch_assoc($res); 138 if ($row['_version'] != 'myversion') { 139 printf("[007] Check procedures\n"); 140 } 141 mysqli_free_result($res); 142 } 143 144 foreach ($links as $link) 145 mysqli_close($link['link']); 146 147 $link = get_connection(); 148 if (!mysqli_query($link, 'SELECT 1', MYSQLI_ASYNC)) 149 printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 150 151 if (!mysqli_query($link, 'SELECT 1', MYSQLI_ASYNC)) 152 printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 153 154 mysqli_close($link); 155 156 print "done!"; 157?> 158--CLEAN-- 159<?php 160require_once 'connect.inc'; 161if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) 162 printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); 163 164if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) 165 printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 166 167if (!mysqli_query($link, "DROP TABLE IF EXISTS bogus")) 168 printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 169 170mysqli_query($link, "DROP PROCEDURE IF EXISTS p"); 171 172mysqli_close($link); 173?> 174--EXPECTF-- 175[003] 'SELECT' caused 1064 176[003] 'UPDATE test SET id = 101 WHERE id > 3' caused 1062 177[003] 'UPDATE_FIX test SET id = 101 WHERE id > 3' caused 1064 178array(2) { 179 ["id"]=> 180 string(3) "100" 181 ["label"]=> 182 string(1) "z" 183} 184[009] [2014] %s 185done! 186