From 007e15c31862df83bc47775d819e18a568362ae4 Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Thu, 18 Jan 2018 15:35:13 -0800 Subject: [PATCH] fix tests that uses scrollable cursor with AE --- .../pdo_fetch_cursor_scroll_random.phpt | 3 +- .../pdostatement_fetch_orientation.phpt | 56 +-- ...dostatement_fetchmode_emulate_prepare.phpt | 5 +- test/functional/sqlsrv/0052.phpt | 132 +++--- .../sqlsrv/TC48_FetchScrollable.phpt | 40 +- .../sqlsrv/TC55_StreamScrollable.phpt | 58 +-- test/functional/sqlsrv/test_scrollable.phpt | 421 +++++++++--------- 7 files changed, 322 insertions(+), 393 deletions(-) diff --git a/test/functional/pdo_sqlsrv/pdo_fetch_cursor_scroll_random.phpt b/test/functional/pdo_sqlsrv/pdo_fetch_cursor_scroll_random.phpt index a0bb02f9..5195bca6 100644 --- a/test/functional/pdo_sqlsrv/pdo_fetch_cursor_scroll_random.phpt +++ b/test/functional/pdo_sqlsrv/pdo_fetch_cursor_scroll_random.phpt @@ -41,8 +41,7 @@ function cursorScrollFetchRows($conn, $tableName) $stmt = $conn->prepare("SELECT * FROM $tableName ORDER BY c1_int", array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL)); } else { // ORDER BY is not supported for encrypted columns - // scrollable cursor is not supported for encrypted tablee; use client side buffered cursor - $stmt = $conn->prepare("SELECT * FROM $tableName", array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); + $stmt = $conn->prepare("SELECT * FROM $tableName", array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL)); } $stmt->execute(); diff --git a/test/functional/pdo_sqlsrv/pdostatement_fetch_orientation.phpt b/test/functional/pdo_sqlsrv/pdostatement_fetch_orientation.phpt index f884daaf..c6a49f0a 100644 --- a/test/functional/pdo_sqlsrv/pdostatement_fetch_orientation.phpt +++ b/test/functional/pdo_sqlsrv/pdostatement_fetch_orientation.phpt @@ -3,28 +3,20 @@ Test the fetch() method for different fetch orientations with PDO::ATTR_CURSOR s --ENV-- PHPT_EXEC=true --SKIPIF-- - + --FILE-- "varchar(10)")); + insertRow($conn1, $tableName, array("id" => 1, "val" => "A")); + insertRow($conn1, $tableName, array("id" => 2, "val" => "B")); + insertRow($conn1, $tableName, array("id" => 3, "val" => "C")); // Query table and retrieve data $stmt1 = $conn1->prepare( "SELECT val FROM $tableName", array( PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL )); @@ -158,33 +150,15 @@ function FetchAll($execMode, $fetchMode) } // Cleanup - DropTable($conn1, $tableName); - $stmt1 = null; - $conn1 = null; + dropTable($conn1, $tableName); + unset($stmt1); + unset($conn1); - EndTest($testName); + echo "Test 'PDO Statement - Fetch Scrollable' completed successfully.\n"; +} catch (Exception $e) { + echo $e->getMessage(); } - -//-------------------------------------------------------------------- -// Repro -// -//-------------------------------------------------------------------- -function Repro() -{ - - try - { - FetchAll(false, PDO::FETCH_BOTH); - } - catch (Exception $e) - { - echo $e->getMessage(); - } -} - -Repro(); - ?> --EXPECT-- -Test "PDO Statement - Fetch Scrollable" completed successfully. \ No newline at end of file +Test 'PDO Statement - Fetch Scrollable' completed successfully. \ No newline at end of file diff --git a/test/functional/pdo_sqlsrv/pdostatement_fetchmode_emulate_prepare.phpt b/test/functional/pdo_sqlsrv/pdostatement_fetchmode_emulate_prepare.phpt index cccac782..8791a96b 100644 --- a/test/functional/pdo_sqlsrv/pdostatement_fetchmode_emulate_prepare.phpt +++ b/test/functional/pdo_sqlsrv/pdostatement_fetchmode_emulate_prepare.phpt @@ -61,9 +61,7 @@ try { echo "Now selecting....\n"; $tsql = "SELECT * FROM [$tableName]"; $stmtOptions[PDO::ATTR_CURSOR] = PDO::CURSOR_SCROLL; - if (isColEncrypted()) { - $stmtOptions[PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE] = PDO::SQLSRV_CURSOR_BUFFERED; - } + $stmt1 = $conn1->prepare($tsql, $stmtOptions); $stmt1->execute(); // The row order in the resultset when the column is encrypted (which is dependent on the encrytion key used) @@ -114,7 +112,6 @@ try { } else { // more and less than operators do not work for encrypted columns $tsql = "SELECT * FROM [$tableName] WHERE NOT ID = :id"; - unset($stmtOptions[PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE]); $stmt2 = $conn1->prepare($tsql, $stmtOptions); $id = 3; $stmt2->bindParam(':id', $id); diff --git a/test/functional/sqlsrv/0052.phpt b/test/functional/sqlsrv/0052.phpt index ad412d12..f0f55056 100644 --- a/test/functional/sqlsrv/0052.phpt +++ b/test/functional/sqlsrv/0052.phpt @@ -1,69 +1,63 @@ ---TEST-- -scrollable results with no rows. ---DESCRIPTION-- -this test is very similar to test_scrollable.phpt... might consider removing this test as a duplicate ---SKIPIF-- - ---FILE-- - SQLSRV_CURSOR_FORWARD); - } else { - $options = array('Scrollable' => 'static'); - } - - $stmt = sqlsrv_query($conn, $query, array(), $options); - $rows = sqlsrv_has_rows($stmt); - if ($rows != false) { - fatalError("Should be no rows present"); - }; - - if ($stmt === false) { - die(print_r(sqlsrv_errors(), true)); - } - $row = sqlsrv_fetch_array($stmt); - print_r($row); - if ($row === false) { - print_r(sqlsrv_errors(), true); - } - - $stmt = sqlsrv_query($conn, $query); - $rows = sqlsrv_has_rows($stmt); - if ($rows != false) { - fatalError("Should be no rows present"); - }; - - if ($stmt === false) { - die(print_r(sqlsrv_errors(), true)); - } - $row = sqlsrv_fetch_array($stmt); - print_r($row); - if ($row === false) { - print_r(sqlsrv_errors(), true); - } - - dropTable($conn, $tableName); - echo "Test succeeded.\n"; - -?> ---EXPECT-- -Test succeeded. +--TEST-- +scrollable results with no rows. +--DESCRIPTION-- +this test is very similar to test_scrollable.phpt... might consider removing this test as a duplicate +--SKIPIF-- + +--FILE-- + 'static'); + + $stmt = sqlsrv_query($conn, $query, array(), $options); + $rows = sqlsrv_has_rows($stmt); + if ($rows != false) { + fatalError("Should be no rows present"); + }; + + if ($stmt === false) { + die(print_r(sqlsrv_errors(), true)); + } + $row = sqlsrv_fetch_array($stmt); + print_r($row); + if ($row === false) { + print_r(sqlsrv_errors(), true); + } + + $stmt = sqlsrv_query($conn, $query); + $rows = sqlsrv_has_rows($stmt); + if ($rows != false) { + fatalError("Should be no rows present"); + }; + + if ($stmt === false) { + die(print_r(sqlsrv_errors(), true)); + } + $row = sqlsrv_fetch_array($stmt); + print_r($row); + if ($row === false) { + print_r(sqlsrv_errors(), true); + } + + dropTable($conn, $tableName); + echo "Test succeeded.\n"; + +?> +--EXPECT-- +Test succeeded. diff --git a/test/functional/sqlsrv/TC48_FetchScrollable.phpt b/test/functional/sqlsrv/TC48_FetchScrollable.phpt index 0b3df349..3f14f52e 100644 --- a/test/functional/sqlsrv/TC48_FetchScrollable.phpt +++ b/test/functional/sqlsrv/TC48_FetchScrollable.phpt @@ -45,30 +45,26 @@ function fetchRow($noRows) sqlsrv_free_stmt($stmt2); checkData($noRowsInserted, $numFields, $actual, $expected); - // Always Encrypted feature does not support the following options - // https://github.com/Microsoft/msphpsql/wiki/Features#aelimitation - if (!AE\isColEncrypted()) { - // fetch object - STATIC cursor - $options = array('Scrollable' => SQLSRV_CURSOR_STATIC); - $stmt2 = AE\executeQueryEx($conn1, $query, $options); - $actual = fetchObject($stmt2, $noRowsInserted, $numFields, SQLSRV_SCROLL_RELATIVE); - sqlsrv_free_stmt($stmt2); - checkData($noRowsInserted, $numFields, $actual, $expected); + // fetch object - STATIC cursor + $options = array('Scrollable' => SQLSRV_CURSOR_STATIC); + $stmt2 = AE\executeQueryEx($conn1, $query, $options); + $actual = fetchObject($stmt2, $noRowsInserted, $numFields, SQLSRV_SCROLL_RELATIVE); + sqlsrv_free_stmt($stmt2); + checkData($noRowsInserted, $numFields, $actual, $expected); - // fetch object - DYNAMIC cursor - $options = array('Scrollable' => SQLSRV_CURSOR_DYNAMIC); - $stmt2 = AE\executeQueryEx($conn1, $query, $options); - $actual = fetchObject($stmt2, $noRowsInserted, $numFields, SQLSRV_SCROLL_ABSOLUTE); - sqlsrv_free_stmt($stmt2); - checkData($noRowsInserted, $numFields, $actual, $expected); + // fetch object - DYNAMIC cursor + $options = array('Scrollable' => SQLSRV_CURSOR_DYNAMIC); + $stmt2 = AE\executeQueryEx($conn1, $query, $options); + $actual = fetchObject($stmt2, $noRowsInserted, $numFields, SQLSRV_SCROLL_ABSOLUTE); + sqlsrv_free_stmt($stmt2); + checkData($noRowsInserted, $numFields, $actual, $expected); - // fetch object - KEYSET cursor - $options = array('Scrollable' => SQLSRV_CURSOR_KEYSET); - $stmt2 = AE\executeQueryEx($conn1, $query, $options); - $actual = fetchObject($stmt2, $noRowsInserted, $numFields, SQLSRV_SCROLL_PRIOR, 0); - sqlsrv_free_stmt($stmt2); - checkData($noRowsInserted, $numFields, $actual, $expected); - } + // fetch object - KEYSET cursor + $options = array('Scrollable' => SQLSRV_CURSOR_KEYSET); + $stmt2 = AE\executeQueryEx($conn1, $query, $options); + $actual = fetchObject($stmt2, $noRowsInserted, $numFields, SQLSRV_SCROLL_PRIOR, 0); + sqlsrv_free_stmt($stmt2); + checkData($noRowsInserted, $numFields, $actual, $expected); dropTable($conn1, $tableName); diff --git a/test/functional/sqlsrv/TC55_StreamScrollable.phpt b/test/functional/sqlsrv/TC55_StreamScrollable.phpt index c3127efa..a59f336c 100644 --- a/test/functional/sqlsrv/TC55_StreamScrollable.phpt +++ b/test/functional/sqlsrv/TC55_StreamScrollable.phpt @@ -29,57 +29,31 @@ function streamScroll($noRows, $startRow) AE\insertTestRowsByRange($conn1, $tableName, $startRow, $startRow + $noRows - 1); $query = "SELECT * FROM [$tableName] ORDER BY c27_timestamp"; - // Always Encrypted feature does not support SQLSRV_CURSOR_STATIC - // https://github.com/Microsoft/msphpsql/wiki/Features#aelimitation - if (AE\isColEncrypted()) { - $options = array('Scrollable' => SQLSRV_CURSOR_FORWARD); - } else { - $options = array('Scrollable' => SQLSRV_CURSOR_STATIC); - } + $options = array('Scrollable' => SQLSRV_CURSOR_STATIC); $stmt1 = AE\executeQueryEx($conn1, $query, $options); $numFields = sqlsrv_num_fields($stmt1); - if (AE\isColEncrypted()) { - $row = $startRow; - while ($row <= $noRows) { - if (!sqlsrv_fetch($stmt1, SQLSRV_SCROLL_NEXT)) { + $row = $noRows; + while ($row >= 1) { + if ($row == $noRows) { + if (!sqlsrv_fetch($stmt1, SQLSRV_SCROLL_LAST)) { fatalError("Failed to fetch row ".$row); } - trace("\nStreaming row $row:\n"); - for ($j = 0; $j < $numFields; $j++) { - $col = $j + 1; - if (!isUpdatable($col)) { - continue; - } - if (isStreamable($col)) { - verifyStream($stmt1, $startRow + $row - 1, $j); - } + } else { + if (!sqlsrv_fetch($stmt1, SQLSRV_SCROLL_PRIOR)) { + fatalError("Failed to fetch row ".$row); } - $row++; } - } else { - $row = $noRows; - while ($row >= 1) { - if ($row == $noRows) { - if (!sqlsrv_fetch($stmt1, SQLSRV_SCROLL_LAST)) { - fatalError("Failed to fetch row ".$row); - } - } else { - if (!sqlsrv_fetch($stmt1, SQLSRV_SCROLL_PRIOR)) { - fatalError("Failed to fetch row ".$row); - } + trace("\nStreaming row $row:\n"); + for ($j = 0; $j < $numFields; $j++) { + $col = $j + 1; + if (!isUpdatable($col)) { + continue; } - trace("\nStreaming row $row:\n"); - for ($j = 0; $j < $numFields; $j++) { - $col = $j + 1; - if (!isUpdatable($col)) { - continue; - } - if (isStreamable($col)) { - verifyStream($stmt1, $startRow + $row - 1, $j); - } + if (isStreamable($col)) { + verifyStream($stmt1, $startRow + $row - 1, $j); } - $row--; } + $row--; } sqlsrv_free_stmt($stmt1); diff --git a/test/functional/sqlsrv/test_scrollable.phpt b/test/functional/sqlsrv/test_scrollable.phpt index 29d20113..7e67a597 100644 --- a/test/functional/sqlsrv/test_scrollable.phpt +++ b/test/functional/sqlsrv/test_scrollable.phpt @@ -1,213 +1,208 @@ ---TEST-- -scrollable result sets. ---SKIPIF-- - ---FILE-- - $idx, 'value' => 'Row ' . $idx), $res, AE\INSERT_QUERY_PARAMS); - - if (!$stmt || $res === false) { - fatalError("failed to insert row $idx!\n"); - } - hasRows($stmt, $expectedFail); - sqlsrv_free_stmt($stmt); -} - -$conn = AE\connect(); -$tableName = 'ScrollTest'; -$numRows = 4; - -$columns = array(new AE\ColumnMeta('int', 'id'), - new AE\ColumnMeta('char(10)', 'value')); -$stmt = AE\createTable($conn, $tableName, $columns); - -$rows = sqlsrv_has_rows($stmt); -if($rows == true) { - die("Shouldn't have rows"); -} -sqlsrv_free_stmt($stmt); - -for ($i = 1; $i <= $numRows; $i++) { - insertOneRow($conn, $tableName, $i, true); -} - -// Always Encrypted feature only supports SQLSRV_CURSOR_FORWARD, so skip the rest of the test -// when AE is enabled -// https://github.com/Microsoft/msphpsql/wiki/Features#aelimitation -$query = "SELECT * FROM $tableName"; -$options = array('Scrollable' => SQLSRV_CURSOR_FORWARD); -$stmt = sqlsrv_query($conn, $query, array(), $options); - -hasRows($stmt, false); -countRows($stmt, $numRows, 'forward only'); -sqlsrv_free_stmt($stmt); - -if (! AE\isColEncrypted()) { - $options = array('Scrollable' => 'static'); - $stmt = sqlsrv_query($conn, $query, array(), $options); - - $result = sqlsrv_fetch($stmt, SQLSRV_SCROLL_ABSOLUTE, 4); - if($result !== null) { - die("Should have failed with an invalid row number"); - } - hasRows($stmt, false); - // this is empty - print_r(sqlsrv_errors()); - $result = sqlsrv_fetch($stmt, SQLSRV_SCROLL_ABSOLUTE, -1); - if($result !== null) { - die("Should have failed with an invalid row number"); - } - // this is empty - print_r(sqlsrv_errors()); - - // expected an error here - $rows = sqlsrv_rows_affected($stmt); - $message = !empty(sqlsrv_errors()) ? sqlsrv_errors()[0]['message'] : ''; - $expected = 'This function only works with statements that are not scrollable.'; - if (strcmp($message, $expected)) { - echo "Expected this error message: \'$expected\'\nbut it is: \'$message\'\n"; - } - - $rows = sqlsrv_num_rows($stmt); - if ($rows != $numRows) { - echo "Error: Query returned $rows rows\n"; - } - - $row = 3; - $result = sqlsrv_fetch($stmt, SQLSRV_SCROLL_ABSOLUTE, $row); - do { - $result = sqlsrv_fetch($stmt, SQLSRV_SCROLL_ABSOLUTE, $row); - if($result === false) { - die(print_r(sqlsrv_errors(), true)); - } - $field1 = sqlsrv_get_field($stmt, 0); - $field2 = sqlsrv_get_field($stmt, 1); - $idx = $row + 1; - - if ($field1 != $idx || trim($field2) != "Row $idx") - echo "Field values unexpected $field1 $field2!\n"; - - $row = $row - 1; - } while($row >= 0); - sqlsrv_free_stmt($stmt); - - $options = array('Scrollable' => 'static'); - $stmt = sqlsrv_query($conn, $query, array(), $options); - - hasRows($stmt, false); - countRows($stmt, $numRows, 'static'); - sqlsrv_free_stmt($stmt); - - $options = array('Scrollable' => 'dynamic'); - $stmt = sqlsrv_query($conn, $query, array(), $options); - - sqlsrv_fetch($stmt); - sqlsrv_fetch($stmt); - - insertOneRow($conn, $tableName, 5, true); - insertOneRow($conn, $tableName, 6, true); - $numRows = 6; - - // to account for the two fetches above - countRows($stmt, $numRows, 'dynamic', 2); - sqlsrv_free_stmt($stmt); - - $options = array('Scrollable' => SQLSRV_CURSOR_STATIC); - $stmt = sqlsrv_query($conn, $query, array(), $options); - - $row_count = sqlsrv_num_rows($stmt); - if($row_count != $numRows) { - die("sqlsrv_num_rows should have returned 6 rows in the static cursor\n"); - } - $row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC, SQLSRV_SCROLL_ABSOLUTE, -1); - if($row !== null) { - die("sqlsrv_fetch_array should have returned null\n"); - } - - $row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC, SQLSRV_SCROLL_ABSOLUTE, 6); - if($row !== null) { - die("sqlsrv_fetch_array should have returned null\n"); - } - - $options = array('Scrollable' => SQLSRV_CURSOR_DYNAMIC); - $stmt = sqlsrv_query($conn, $query, array(), $options); - - $result = sqlsrv_num_rows($stmt); - if($result !== false) { - die("sqlsrv_num_rows should have failed for a dynamic cursor."); - } - sqlsrv_fetch($stmt); - sqlsrv_fetch($stmt); - - $stmt2 = sqlsrv_query($conn, "DELETE FROM ScrollTest WHERE id = 2"); - if($stmt2 === false) { - die(print_r(sqlsrv_errors(), true)); - } - - $row = sqlsrv_get_field($stmt, 0); - if($row !== false) { - die("sqlsrv_get_field should have returned false retrieving a field deleted by another query"); - } - $error = sqlsrv_errors()[0]; - $message = $error['message']; - $sqlstate = $error['SQLSTATE']; - if (strcmp($sqlstate, 'HY109') || strpos($message, 'Invalid cursor position') === false) { - die("Unexpected SQL state $sqlstate or error \'$message\'"); - } - - // verify the sqlsrv_fetch_object is working - $obj = sqlsrv_fetch_object($stmt, null, array(null), SQLSRV_SCROLL_LAST, 1); - if($obj === false) { - print_r(sqlsrv_errors()); - } else { - if ($obj->id != $numRows || trim($obj->value) != "Row $numRows") - echo "Field values unexpected $obj->id $obj->value!\n"; - } - sqlsrv_free_stmt($stmt); -} - -dropTable($conn, $tableName); -sqlsrv_close($conn); - -echo "Test succeeded.\n"; - -?> ---EXPECT-- -Test succeeded. +--TEST-- +scrollable result sets. +--SKIPIF-- + +--FILE-- + $idx, 'value' => 'Row ' . $idx), $res, AE\INSERT_QUERY_PARAMS); + + if (!$stmt || $res === false) { + fatalError("failed to insert row $idx!\n"); + } + hasRows($stmt, $expectedFail); + sqlsrv_free_stmt($stmt); +} + +$conn = AE\connect(); +$tableName = 'ScrollTest'; +$numRows = 4; + +$columns = array(new AE\ColumnMeta('int', 'id'), + new AE\ColumnMeta('char(10)', 'value')); +$stmt = AE\createTable($conn, $tableName, $columns); + +$rows = sqlsrv_has_rows($stmt); +if($rows == true) { + die("Shouldn't have rows"); +} +sqlsrv_free_stmt($stmt); + +for ($i = 1; $i <= $numRows; $i++) { + insertOneRow($conn, $tableName, $i, true); +} + +$query = "SELECT * FROM $tableName"; +$options = array('Scrollable' => SQLSRV_CURSOR_FORWARD); +$stmt = sqlsrv_query($conn, $query, array(), $options); + +hasRows($stmt, false); +countRows($stmt, $numRows, 'forward only'); +sqlsrv_free_stmt($stmt); + +$options = array('Scrollable' => 'static'); +$stmt = sqlsrv_query($conn, $query, array(), $options); + +$result = sqlsrv_fetch($stmt, SQLSRV_SCROLL_ABSOLUTE, 4); +if($result !== null) { + die("Should have failed with an invalid row number"); +} +hasRows($stmt, false); +// this is empty +print_r(sqlsrv_errors()); +$result = sqlsrv_fetch($stmt, SQLSRV_SCROLL_ABSOLUTE, -1); +if($result !== null) { + die("Should have failed with an invalid row number"); +} +// this is empty +print_r(sqlsrv_errors()); + +// expected an error here +$rows = sqlsrv_rows_affected($stmt); +$message = !empty(sqlsrv_errors()) ? sqlsrv_errors()[0]['message'] : ''; +$expected = 'This function only works with statements that are not scrollable.'; +if (strcmp($message, $expected)) { + echo "Expected this error message: \'$expected\'\nbut it is: \'$message\'\n"; +} + +$rows = sqlsrv_num_rows($stmt); +if ($rows != $numRows) { + echo "Error: Query returned $rows rows\n"; +} + +$row = 3; +$result = sqlsrv_fetch($stmt, SQLSRV_SCROLL_ABSOLUTE, $row); +do { + $result = sqlsrv_fetch($stmt, SQLSRV_SCROLL_ABSOLUTE, $row); + if($result === false) { + die(print_r(sqlsrv_errors(), true)); + } + $field1 = sqlsrv_get_field($stmt, 0); + $field2 = sqlsrv_get_field($stmt, 1); + $idx = $row + 1; + + if ($field1 != $idx || trim($field2) != "Row $idx") + echo "Field values unexpected $field1 $field2!\n"; + + $row = $row - 1; +} while($row >= 0); +sqlsrv_free_stmt($stmt); + +$options = array('Scrollable' => 'static'); +$stmt = sqlsrv_query($conn, $query, array(), $options); + +hasRows($stmt, false); +countRows($stmt, $numRows, 'static'); +sqlsrv_free_stmt($stmt); + +$options = array('Scrollable' => 'dynamic'); +$stmt = sqlsrv_query($conn, $query, array(), $options); + +sqlsrv_fetch($stmt); +sqlsrv_fetch($stmt); + +insertOneRow($conn, $tableName, 5, true); +insertOneRow($conn, $tableName, 6, true); +$numRows = 6; + +// to account for the two fetches above +countRows($stmt, $numRows, 'dynamic', 2); +sqlsrv_free_stmt($stmt); + +$options = array('Scrollable' => SQLSRV_CURSOR_STATIC); +$stmt = sqlsrv_query($conn, $query, array(), $options); + +$row_count = sqlsrv_num_rows($stmt); +if($row_count != $numRows) { + die("sqlsrv_num_rows should have returned 6 rows in the static cursor\n"); +} +$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC, SQLSRV_SCROLL_ABSOLUTE, -1); +if($row !== null) { + die("sqlsrv_fetch_array should have returned null\n"); +} + +$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC, SQLSRV_SCROLL_ABSOLUTE, 6); +if($row !== null) { + die("sqlsrv_fetch_array should have returned null\n"); +} + +$options = array('Scrollable' => SQLSRV_CURSOR_DYNAMIC); +$stmt = sqlsrv_query($conn, $query, array(), $options); + +$result = sqlsrv_num_rows($stmt); +if($result !== false) { + die("sqlsrv_num_rows should have failed for a dynamic cursor."); +} +sqlsrv_fetch($stmt); +sqlsrv_fetch($stmt); + +$stmt2 = AE\executeQuery($conn, "DELETE FROM $tableName", "id = ?", array(2)); +if($stmt2 === false) { + die(print_r(sqlsrv_errors(), true)); +} + +$row = sqlsrv_get_field($stmt, 0); +if($row !== false) { + die("sqlsrv_get_field should have returned false retrieving a field deleted by another query"); +} +$error = sqlsrv_errors()[0]; +$message = $error['message']; +$sqlstate = $error['SQLSTATE']; +if (strcmp($sqlstate, 'HY109') || strpos($message, 'Invalid cursor position') === false) { + die("Unexpected SQL state $sqlstate or error \'$message\'"); +} + +// verify the sqlsrv_fetch_object is working +$obj = sqlsrv_fetch_object($stmt, null, array(null), SQLSRV_SCROLL_LAST, 1); +if($obj === false) { + print_r(sqlsrv_errors()); +} else { + if ($obj->id != $numRows || trim($obj->value) != "Row $numRows") + echo "Field values unexpected $obj->id $obj->value!\n"; +} +sqlsrv_free_stmt($stmt); + +dropTable($conn, $tableName); +sqlsrv_close($conn); + +echo "Test succeeded.\n"; + +?> +--EXPECT-- +Test succeeded.