Skip to content

Commit

Permalink
Added more pdo tests to verify different error conditions (#984)
Browse files Browse the repository at this point in the history
  • Loading branch information
yitam authored May 1, 2019
1 parent 9e90a42 commit e02db62
Show file tree
Hide file tree
Showing 5 changed files with 499 additions and 50 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
--TEST--
GitHub Issue #35 binary encoding error when binding by name
--DESCRIPTION--
Based on pdo_035_binary_encoding_error_bound_by_name.phpt but this includes error checking for various encoding errors
--SKIPIF--
<?php require('skipif_mid-refactor.inc'); ?>
--FILE--
<?php

function bindTypeNoEncoding($conn, $sql, $input)
{
try {
$value = 1;

$stmt = $conn->prepare($sql);
$stmt->bindParam(1, $value, PDO::PARAM_INT, 0, PDO::SQLSRV_ENCODING_DEFAULT);
$stmt->setAttribute(constant('PDO::SQLSRV_ATTR_ENCODING'), PDO::SQLSRV_ENCODING_BINARY);
$stmt->bindParam(2, $input, PDO::PARAM_LOB);
$stmt->execute();
} catch (PDOException $e) {
$error = '*An encoding was specified for parameter 1. Only PDO::PARAM_LOB and PDO::PARAM_STR can take an encoding option.';
if (!fnmatch($error, $e->getMessage())) {
echo "Error message unexpected in bindTypeNoEncoding\n";
var_dump($e->getMessage());
}
}
}

function bindDefaultEncoding($conn, $sql, $input)
{
try {
$value = 1;

$stmt = $conn->prepare($sql);
$stmt->bindParam(1, $value, PDO::PARAM_STR, 0, PDO::SQLSRV_ENCODING_DEFAULT);
$stmt->setAttribute(constant('PDO::SQLSRV_ATTR_ENCODING'), PDO::SQLSRV_ENCODING_BINARY);
$stmt->bindParam(2, $input, PDO::PARAM_LOB);
$stmt->execute();
} catch (PDOException $e) {
$error = '*Invalid encoding specified for parameter 1.';
if (!fnmatch($error, $e->getMessage())) {
echo "Error message unexpected in bindDefaultEncoding\n";
var_dump($e->getMessage());
}
}
}

function insertData($conn, $sql, $input)
{
try {
$value = 1;

$stmt = $conn->prepare($sql);
$stmt->bindParam(1, $value);
$stmt->setAttribute(constant('PDO::SQLSRV_ATTR_ENCODING'), PDO::SQLSRV_ENCODING_BINARY);
$stmt->bindParam(2, $input, PDO::PARAM_LOB);
$stmt->execute();
} catch (PDOException $e) {
echo "Error unexpected in insertData\n";
var_dump($e->getMessage());
}
}

function invalidEncoding1($conn, $sql)
{
try {
$stmt = $conn->prepare($sql);
$stmt->bindColumn(1, $id, PDO::PARAM_INT, 0, PDO::SQLSRV_ENCODING_UTF8);
$stmt->execute();
$stmt->fetch(PDO::FETCH_BOUND);
} catch (PDOException $e) {
$error = '*An encoding was specified for column 1. Only PDO::PARAM_LOB and PDO::PARAM_STR column types can take an encoding option.';
if (!fnmatch($error, $e->getMessage())) {
echo "Error message unexpected in invalidEncoding1\n";
var_dump($e->getMessage());
}
}
}

function invalidEncoding2($conn, $sql)
{
try {
$stmt = $conn->prepare($sql);
$stmt->bindColumn('Value', $val1, PDO::PARAM_LOB, 0, PDO::SQLSRV_ENCODING_DEFAULT);
$stmt->execute();
$stmt->fetch(PDO::FETCH_BOUND);
} catch (PDOException $e) {
$error = '*Invalid encoding specified for column 1.';
if (!fnmatch($error, $e->getMessage())) {
echo "Error message unexpected in invalidEncoding2\n";
var_dump($e->getMessage());
}
}
}

function invalidEncoding3($conn, $sql)
{
try {
$stmt = $conn->prepare($sql);
$stmt->bindColumn(1, $id, PDO::PARAM_STR, 0, "dummy");
$stmt->execute();
$stmt->fetch(PDO::FETCH_BOUND);
} catch (PDOException $e) {
$error = '*An invalid type or value was given as bound column driver data for column 1. Only encoding constants such as PDO::SQLSRV_ENCODING_UTF8 may be used as bound column driver data.';
if (!fnmatch($error, $e->getMessage())) {
echo "Error message unexpected in invalidEncoding3\n";
var_dump($e->getMessage());
}
}
}

try {
require_once( "MsCommon_mid-refactor.inc" );

// Connect
$conn = connect();

// Create a table
$tableName = "testTableIssue35";
createTable($conn, $tableName, array("ID" => "int", "Value" => "varbinary(max)"));

// Insert data using bind parameters
$sql = "INSERT INTO $tableName VALUES (?, ?)";
$message = "This is to test github issue 35.";
$value = base64_encode($message);

// Errors expected
bindTypeNoEncoding($conn, $sql, $value);
bindDefaultEncoding($conn, $sql, $value);

// No error expected
insertData($conn, $sql, $value);

// Fetch data, but test several invalid encoding issues (errors expected)
$sql = "SELECT * FROM $tableName";
invalidEncoding1($conn, $sql);
invalidEncoding2($conn, $sql);
invalidEncoding3($conn, $sql);

// Now fetch it back
$stmt = $conn->prepare("SELECT Value FROM $tableName");
$stmt->bindColumn('Value', $val1, PDO::PARAM_LOB, 0, PDO::SQLSRV_ENCODING_BINARY);
$stmt->execute();
$stmt->fetch(PDO::FETCH_BOUND);
var_dump($val1 === $value);

// Close connection
dropTable($conn, $tableName);
unset($stmt);
unset($conn);
print "Done\n";
} catch (PDOException $e) {
var_dump($e->errorInfo);
}
?>
--EXPECT--
bool(true)
Done
151 changes: 151 additions & 0 deletions test/functional/pdo_sqlsrv/pdo_fetch_column_twice.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
--TEST--
Test fetchColumn twice in a row. Intentionally trigger various error messages.
--DESCRIPTION--
This is similar to sqlsrv_fetch_field_twice_data_types.phpt.
--SKIPIF--
<?php require('skipif_mid-refactor.inc'); ?>
--FILE--
<?php
require_once("MsCommon_mid-refactor.inc");

function fetchBeforeExecute($conn, $tableName, $inputs)
{
try {
$tsql = "SELECT * FROM $tableName";
$stmt = $conn->prepare($tsql);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if ($row !== false) {
echo "fetchBeforeExecute: fetch should have failed before execute!\n";
}
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_NUM);

for ($i = 0; $i < count($inputs); $i++) {
if ($row[$i] !== $inputs[$i]) {
echo "fetchBeforeExecute: expected $inputs[$i] but got $row[$i]\n";
}
}

unset($stmt);
} catch (PDOException $e) {
var_dump($e->getMessage());
}
}

function fetchColumnTwice($conn, $tableName, $col, $input)
{
try {
$tsql = "SELECT * FROM $tableName";
$stmt = $conn->query($tsql);
$result = $stmt->fetchColumn($col);
if ($result !== $input) {
echo "fetchColumnTwice (1): expected $input but got $result\n";
}
$result = $stmt->fetchColumn($col);
if ($result !== false) {
echo "fetchColumnTwice (2): expected the second fetchColumn to fail\n";
}

// Re-run the query with fetch style
$stmt = $conn->query($tsql, PDO::FETCH_COLUMN, $col);
$result = $stmt->fetch();
if ($result !== $input) {
echo "fetchColumnTwice (3): expected $input but got $result\n";
}
$result = $stmt->fetch();
if ($result !== false) {
echo "fetchColumnTwice (4): expected the second fetch to fail\n";
}
$result = $stmt->fetchColumn($col);
echo "fetchColumnTwice (5): expected fetchColumn to throw an exception\n";
unset($stmt);
} catch (PDOException $e) {
$error = '*There are no more rows in the active result set. Since this result set is not scrollable, no more data may be retrieved.';

if (!fnmatch($error, $e->getMessage())) {
echo "Error message unexpected in fetchColumnTwice\n";
var_dump($e->getMessage());
}
}
}

function fetchColumnOutOfBound1($conn, $tableName, $col)
{
try {
$tsql = "SELECT * FROM $tableName";
$stmt = $conn->query($tsql);
$result = $stmt->fetchColumn($col);
echo "fetchColumnOutOfBound1: expected fetchColumn to throw an exception\n";
unset($stmt);
} catch (PDOException $e) {
$error1 = '*General error: Invalid column index';
$error2 = '*An invalid column number was specified.';

// Different errors may be returned depending on running with run-tests.php or not
if (fnmatch($error1, $e->getMessage()) || fnmatch($error2, $e->getMessage())) {
;
} else {
echo "Error message unexpected in fetchColumnOutOfBound1\n";
var_dump($e->getMessage());
}
}
}

function fetchColumnOutOfBound2($conn, $tableName, $col)
{
try {
$tsql = "SELECT * FROM $tableName";
$stmt = $conn->query($tsql, PDO::FETCH_COLUMN, $col);
$result = $stmt->fetch();
unset($stmt);
} catch (PDOException $e) {
var_dump($e->getMessage());
}
}

try {
$conn = connect();
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$tableName = 'pdoFetchColumnTwice';
$colMeta = array(new ColumnMeta('int', 'c1_int'),
new ColumnMeta('varchar(20)', 'c2_varchar'),
new ColumnMeta('decimal(5, 3)', 'c3_decimal'),
new ColumnMeta('datetime', 'c4_datetime'));
createTable($conn, $tableName, $colMeta);

$inputs = array('968580013', 'dummy value', '3.438', ('1756-04-16 23:27:09.130'));
$numCols = count($inputs);

$tsql = "INSERT INTO $tableName(c1_int, c2_varchar, c3_decimal, c4_datetime) VALUES (?,?,?,?)";
$stmt = $conn->prepare($tsql);

for ($i = 0; $i < $numCols; $i++) {
$stmt->bindParam($i + 1, $inputs[$i]);
}
$stmt->execute();
unset($stmt);

fetchBeforeExecute($conn, $tableName, $inputs);
for ($i = 0; $i < $numCols; $i++) {
fetchColumnTwice($conn, $tableName, $i, $inputs[$i]);
}

fetchColumnOutOfBound1($conn, $tableName, -1);

// Change to warning mode
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
fetchColumnOutOfBound2($conn, $tableName, $numCols + 1);

dropTable($conn, $tableName);
unset($conn);
echo "Done\n";
} catch (PDOException $e) {
var_dump($e);
}
?>
--EXPECTREGEX--
Warning: PDOStatement::fetch\(\): SQLSTATE\[HY000\]: General error: Invalid column index in .+(\/|\\)pdo_fetch_column_twice.php on line [0-9]+

Warning: PDOStatement::fetch\(\): SQLSTATE\[HY000\]: General error in .+(\/|\\)pdo_fetch_column_twice.php on line [0-9]+
Done
4 changes: 2 additions & 2 deletions test/functional/pdo_sqlsrv/pdo_output_decimal.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ try {
$expected1 = "7.4";
$expected2 = "7";
if ($outValue1 == $expected1 && $outValue2 == $expected2) {
echo "Test Successfully\n";
echo "Test Successful\n";
}

dropProc($conn, $proc_scale);
Expand All @@ -56,4 +56,4 @@ try {
?>

--EXPECT--
Test Successfully
Test Successful
Loading

0 comments on commit e02db62

Please sign in to comment.