Fixed the error in Issue 570 (#952)
This commit is contained in:
parent
1332e3b5f8
commit
840ebc2378
|
@ -89,7 +89,8 @@ size_t sqlsrv_stream_read( _Inout_ php_stream* stream, _Out_writes_bytes_(count)
|
|||
break;
|
||||
}
|
||||
|
||||
SQLRETURN r = SQLGetData( ss->stmt->handle(), ss->field_index + 1, c_type, get_data_buffer, count /*BufferLength*/, &read );
|
||||
// Warnings will be handled below
|
||||
SQLRETURN r = ss->stmt->current_results->get_data(ss->field_index + 1, c_type, get_data_buffer, count /*BufferLength*/, &read, false /*handle_warning*/ TSRMLS_CC);
|
||||
|
||||
CHECK_SQL_ERROR( r, ss->stmt ) {
|
||||
stream->eof = 1;
|
||||
|
|
143
test/functional/sqlsrv/srv_570_fetch_varbinary.phpt
Normal file
143
test/functional/sqlsrv/srv_570_fetch_varbinary.phpt
Normal file
|
@ -0,0 +1,143 @@
|
|||
--TEST--
|
||||
GitHub issue #570 - fetching a varbinary field as a stream using client buffer
|
||||
--DESCRIPTION--
|
||||
Verifies that a varbinary field (with size or max) can be successfully fetched even when a client buffer is used. There is no more "Invalid cursor state" error.
|
||||
--ENV--
|
||||
PHPT_EXEC=true
|
||||
--SKIPIF--
|
||||
<?php require('skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function compareStreams($input, $result)
|
||||
{
|
||||
while (($line1 = fread($input, 80)) && ($line2 = fread($result, 80))) {
|
||||
if ($line1 != $line2) {
|
||||
echo "Stream not identical\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function fetchData($stmt, $data, $buffered)
|
||||
{
|
||||
if ($buffered) {
|
||||
$result = sqlsrv_fetch($stmt, SQLSRV_SCROLL_FIRST);
|
||||
} else {
|
||||
$result = sqlsrv_fetch($stmt);
|
||||
}
|
||||
if ($result === false) {
|
||||
fatalError('Error when fetching data');
|
||||
}
|
||||
|
||||
// Get image data as a binary stream
|
||||
$image = sqlsrv_get_field($stmt, 0, SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_BINARY));
|
||||
if ($image === false) {
|
||||
fatalError('Error in calling sqlsrv_get_field');
|
||||
}
|
||||
|
||||
// Does the retrieved stream match with the original?
|
||||
compareStreams($data, $image);
|
||||
|
||||
fclose($image);
|
||||
}
|
||||
|
||||
function runQuery($conn, $data, $tsql, $buffered, $prepared)
|
||||
{
|
||||
if ($prepared) {
|
||||
if ($buffered) {
|
||||
// Pick a random size for the buffer large enough for this test
|
||||
$stmt = sqlsrv_prepare($conn, $tsql, array(), array("Scrollable" => SQLSRV_CURSOR_CLIENT_BUFFERED, "ClientBufferMaxKBSize" => 51200));
|
||||
} else {
|
||||
$stmt = sqlsrv_prepare($conn, $tsql);
|
||||
}
|
||||
if ($stmt === false) {
|
||||
fatalError("Error in preparing the query ($buffered).");
|
||||
}
|
||||
|
||||
$result = sqlsrv_execute($stmt);
|
||||
if ($result === false) {
|
||||
fatalError("Error in executing the query ($buffered).");
|
||||
}
|
||||
} else {
|
||||
if ($buffered) {
|
||||
// Use the default buffer size in this case
|
||||
$stmt = sqlsrv_query($conn, $tsql, array(), array("Scrollable"=>SQLSRV_CURSOR_CLIENT_BUFFERED));
|
||||
} else {
|
||||
$stmt = sqlsrv_query($conn, $tsql);
|
||||
}
|
||||
|
||||
if ($stmt === false) {
|
||||
fatalError("Error in sqlsrv_query ($buffered).");
|
||||
}
|
||||
}
|
||||
|
||||
fetchData($stmt, $data, $buffered);
|
||||
}
|
||||
|
||||
function runTest($conn, $columnType, $path)
|
||||
{
|
||||
$tableName = 'srvTestTable_570' . rand(0, 10);
|
||||
dropTable($conn, $tableName);
|
||||
|
||||
// Create the test table with only one column
|
||||
$tsql = "CREATE TABLE $tableName([picture] $columnType NOT NULL)";
|
||||
$stmt = sqlsrv_query($conn, $tsql);
|
||||
if (!$stmt) {
|
||||
fatalError("Failed to create table $tableName\n");
|
||||
}
|
||||
|
||||
// Insert php.gif as stream data
|
||||
$tsql = "INSERT INTO $tableName (picture) VALUES (?)";
|
||||
|
||||
$data = fopen($path, 'rb');
|
||||
if (!$data) {
|
||||
fatalError('Could not open image for reading.');
|
||||
}
|
||||
|
||||
$params = array($data, SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_BINARY));
|
||||
$stmt = sqlsrv_query($conn, $tsql, array($params));
|
||||
if ($stmt === false) {
|
||||
fatalError("Failed to insert image into $tableName");
|
||||
}
|
||||
do {
|
||||
$read = sqlsrv_send_stream_data($stmt);
|
||||
} while ($read);
|
||||
sqlsrv_free_stmt($stmt);
|
||||
|
||||
// Start testing, with or without client buffer, using prepared statement or direct query
|
||||
$tsql = "SELECT picture FROM $tableName";
|
||||
runQuery($conn, $data, $tsql, false, true);
|
||||
runQuery($conn, $data, $tsql, true, true);
|
||||
runQuery($conn, $data, $tsql, false, false);
|
||||
runQuery($conn, $data, $tsql, true, false);
|
||||
|
||||
// Clean up
|
||||
fclose($data);
|
||||
|
||||
dropTable($conn, $tableName);
|
||||
}
|
||||
|
||||
require_once('MsCommon.inc');
|
||||
|
||||
$conn = connect();
|
||||
if ($conn === false) {
|
||||
die(print_r(sqlsrv_errors(), true));
|
||||
}
|
||||
|
||||
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
|
||||
$pic = '\\php.gif';
|
||||
} else { // other than Windows
|
||||
$pic = '/php.gif';
|
||||
}
|
||||
$path = dirname($_SERVER['PHP_SELF']) . $pic;
|
||||
|
||||
runTest($conn, 'VARBINARY(MAX)', $path);
|
||||
runTest($conn, 'VARBINARY(4096)', $path);
|
||||
|
||||
echo "Done\n";
|
||||
|
||||
sqlsrv_close($conn);
|
||||
?>
|
||||
--EXPECT--
|
||||
Done
|
Loading…
Reference in a new issue