Modified tests as per review comments

This commit is contained in:
Jenny Tam 2017-10-26 10:48:36 -07:00
parent 2bcaf17c0a
commit 4d364e1a5b
15 changed files with 122 additions and 103 deletions

View file

@ -352,7 +352,7 @@ function createProc($conn, $procName, $procArgs, $procCode)
dropProc($conn, $procName);
$stmt = sqlsrv_query($conn, "CREATE PROC [$procName] ($procArgs) AS BEGIN $procCode END");
if ($stmt === false) {
fatalError("Failed to create test procedure", true);
fatalError("Failed to create test procedure");
}
sqlsrv_free_stmt($stmt);
}
@ -376,7 +376,7 @@ function callProcEx($conn, $procName, $procPrefix, $procArgs, $procValues)
{
$stmt = sqlsrv_query($conn, "{ $procPrefix CALL [$procName] ($procArgs)}", $procValues);
if ($stmt === false) {
fatalError("Failed to call test procedure", true);
fatalError("Failed to call test procedure");
}
return ($stmt);
}

View file

@ -51,9 +51,11 @@ class ColumnMeta
$this->options = $options;
// first asssumes the column is not encryptable
$this->encryptable = false;
// $this->encryptable = false;
if (!$noEncrypt) {
$this->checkIfUnsupported();
} else {
$this->encryptable = false;
}
}
@ -63,8 +65,6 @@ class ColumnMeta
*/
protected function checkIfUnsupported()
{
$this->encryptable = true;
// Always Encrypted is not supported for columns with the IDENTITY property
// or any column using one of the following datatypes:
//
@ -72,22 +72,14 @@ class ColumnMeta
// user defined-types.
// https://docs.microsoft.com/en-us/sql/relational-databases/security/encryption/always-encrypted-database-engine
$unsupported = array("xml", "timestamp", "image", "ntext", "text", "sql_variant", "hierarchyid", "geography", "geometry", "alias");
if (stripos($this->options, "identity") !== false) {
$this->encryptable = false;
// } elseif (stripos($this->dataType, "money") !== false) {
// // this is a limitation in ODBC, including money and smallmoney
// $this->encryptable = false;
} elseif (!strcasecmp($this->dataType, "xml") ||
!strcasecmp($this->dataType, "timestamp") ||
!strcasecmp($this->dataType, "image") ||
!strcasecmp($this->dataType, "ntext") ||
!strcasecmp($this->dataType, "text") ||
!strcasecmp($this->dataType, "sql_variant") ||
!strcasecmp($this->dataType, "hierarchyid") ||
!strcasecmp($this->dataType, "geography") ||
!strcasecmp($this->dataType, "geometry") ||
!strcasecmp($this->dataType, "alias")) {
} elseif (in_array($this->dataType, $unsupported)) {
$this->encryptable = false;
} else {
$this->encryptable = true;
}
}
/**
@ -374,10 +366,10 @@ function connect($options = array(), $disableCE = false)
/**
* Create a table
* @param object $conn : sqlsrv connection object
* @param resource $conn : sqlsrv connection resource
* @param string $tbname : name of the table to be created
* @param array $columnMetaArr : array of ColumnMeta objects, which contain metadata for one column
* @return object sqlsrv statement
* @return resource sqlsrv statement resource
*/
function createTable($conn, $tbname, $columnMetaArr)
{
@ -394,14 +386,14 @@ function createTable($conn, $tbname, $columnMetaArr)
/**
* Insert a row into a table
* @param object $conn : sqlsrv connection object
* @param resource $conn : sqlsrv connection resource
* @param string $tbname : name of the table for the row to be inserted
* @param array $inputs : an associative array column name and its value, which may be a
* literal or a BindParamOption object
* @param bool $r : true if the row was successfully inserted, otherwise false. Default value is null to make this parameter optional.
* $param string $api : SQLSRV API used for executing the insert query
* $param int $api : SQLSRV API used for executing the insert query
* accepted values: INSERT_QUERY, INSERT_PREPARE, INSERT_QUERY_PARAMS, INSERT_PREPARE_PARAMS
* @return object sqlsrv statement object of the insert statement
* @return resource sqlsrv statement resource of the insert statement
*/
function insertRow($conn, $tbname, $inputs, &$r = null, $api = INSERT_QUERY)
{
@ -425,7 +417,7 @@ function insertRow($conn, $tbname, $inputs, &$r = null, $api = INSERT_QUERY)
$params = array();
foreach ($inputs as $key => $input) {
if (is_object($input)) {
array_push($params, $input->bindParamArr($input->value));
array_push($params, $input->bindParamArr($inputs[$key]));
} else {
array_push($params, $inputs[$key]);
}
@ -436,6 +428,8 @@ function insertRow($conn, $tbname, $inputs, &$r = null, $api = INSERT_QUERY)
$stmt = sqlsrv_prepare($conn, $insertSql, $params);
if ($stmt) {
$r = sqlsrv_execute($stmt);
} else {
fatalError("insertRow: failed to prepare insert query!");
}
} else {
$stmt = sqlsrv_query($conn, $insertSql, $params);
@ -450,7 +444,7 @@ function insertRow($conn, $tbname, $inputs, &$r = null, $api = INSERT_QUERY)
* @param string $tbname : name of the table
* @param string $conds : string of condition(s) with placeholders, null by default
* @param array $values : array of parameters, null by default
* @return object sqlsrv statement upon success or false otherwise
* @return resource sqlsrv statement upon success or false otherwise
*/
function selectFromTable($conn, $tbname, $conds = null, $values = null)
{
@ -462,22 +456,38 @@ function selectFromTable($conn, $tbname, $conds = null, $values = null)
* Perform a query from a table with or without where condition(s)
* @param resource $conn : connection resource
* @param string $sql : T-SQL query
* @param string $conds : string of condition(s) with placeholders, null by default
* @param string $conds : string of condition(s) possibly with placeholders, null by default
* @param array $values : array of parameters, null by default
* @return object sqlsrv statement upon success or false otherwise
* @return resource sqlsrv statement upon success or false otherwise
*/
function executeQuery($conn, $sql, $conds = null, $values = null)
{
// when AE is enabled, use sqlsrv_prepare() to handle fields with unlimited size
if (!isColEncrypted() && (is_null($conds) || empty($values))) {
if (!isColEncrypted()) {
if (!empty($values)) {
$tmpArray = explode('?', $conds);
$i = 0;
foreach ($values as $value) {
if (!is_numeric($value)) {
$tmpArray[$i++] .= "'$value'";
} else {
$tmpArray[$i++] .= "$value";
}
}
$clause = implode($tmpArray);
$sql = $sql . " WHERE $clause ";
} elseif (!empty($conds)) {
$sql = $sql . " WHERE $conds ";
}
$stmt = sqlsrv_query($conn, $sql);
} else {
if (is_string($conds) && is_array($values)) {
// with AE enabled, use sqlsrv_prepare() in case there are
// fields with unlimited size
if (empty($conds) || empty($values)) {
$stmt = sqlsrv_prepare($conn, $sql);
} else {
$sql = $sql . " WHERE $conds ";
$stmt = sqlsrv_prepare($conn, $sql, $values);
} else {
$stmt = sqlsrv_prepare($conn, $sql);
}
}
if ($stmt) {
$r = sqlsrv_execute($stmt);
if (!$r) {
@ -494,7 +504,7 @@ function executeQuery($conn, $sql, $conds = null, $values = null)
/**
* Similar to executeQuery() but with query options
* @return object sqlsrv statement upon success or false otherwise
* @return resource sqlsrv statement upon success or false otherwise
*/
function executeQueryEx($conn, $sql, $options)
{
@ -544,11 +554,10 @@ function fetchAll($conn, $tbname)
* all deterministic if AE is enabled
* @param resource $conn : connection resource
* @param string $tbname : name of the table to create
* @return object sqlsrv statement
* @return resource sqlsrv statement
*/
function createTestTable($conn, $tbname)
{
$columns = array(new ColumnMeta('int', 'c1_int'),
new ColumnMeta('tinyint', 'c2_tinyint'),
new ColumnMeta('smallint', 'c3_smallint'),
@ -634,7 +643,7 @@ function insertTestRowsByRange($conn, $tbame, $minIndex, $maxIndex)
* @param resource $conn : connection resource
* @param string $tbname : name of the table to create
* @param int $index : the index of a certain row of test data
* @return object sqlsrv statement upon success or false otherwise
* @return resource sqlsrv statement upon success or false otherwise
*/
function insertTestRow($conn, $tbname, $index)
{
@ -651,7 +660,7 @@ function insertTestRow($conn, $tbname, $index)
$result = null;
if (isColEncrypted()) {
$stmt = insertRow($conn, $tbname, $inputArray, $result, INSERT_PREPARE_PARAMS);
$stmt = insertRow($conn, $tbname, $inputArray, $result);
} else {
// do not use the generic insertRow as the binary data needs some pre-processing
// before calling sqlsrv_query()
@ -716,7 +725,7 @@ function getInsertData($rowIndex, $colIndex)
// get array of input values
$inputArray = getInsertArray($rowIndex);
if (empty($inputArray)) {
fatalError("getInsertData: failed to retrieve data at row $rowIndex and column $colIndex.\n");
fatalError("getInsertData: failed to retrieve data at row $rowIndex.\n");
}
$count = 0;
foreach ($inputArray as $key => $value) {
@ -773,7 +782,7 @@ function getSqlType($k)
return ("udt");
}
function getDriverType($k, $dataSize = 512)
function getSqlsrvSqlType($k, $dataSize)
{
switch ($k) {
case 1: return (SQLSRV_SQLTYPE_INT);

View file

@ -19,9 +19,9 @@ function connectionClose()
$conn1 = AE\connect();
$tableName = 'TC24test';
// Insert a couple of random rows
// Insert some random rows
AE\createTestTable($conn1, $tableName);
AE\insertTestRows($conn1, $tableName, 2);
AE\insertTestRows($conn1, $tableName, 5);
// Close connection twice
for ($i = 0; $i < 2; $i++) {
@ -39,7 +39,7 @@ function connectionClose()
// Invalid Statement
$conn2 = AE\connect();
$stmt2 = sqlsrv_query($conn2, "SELECT * FROM [$tableName]");
$stmt2 = AE\selectFromTable($conn2, $tableName);
sqlsrv_close($conn2);
if (sqlsrv_fetch($stmt2)) {
die("Fetch should fail when connection is closed");

View file

@ -26,20 +26,21 @@ function simpleQuery()
$conn1 = AE\connect();
// just create an empty table
$stmt1 = sqlsrv_query($conn1, "CREATE TABLE $tableName (dummyColumn int)");
$columns = array(new AE\ColumnMeta('int', 'dummyColumn'));
AE\createTable($conn1, $tableName, $columns);
trace("Executing SELECT query on $tableName ...");
$stmt1 = sqlsrv_query($conn1, "SELECT * FROM $tableName");
$stmt1 = AE\selectFromTable($conn1, $tableName);
$rows = rowCount($stmt1);
sqlsrv_free_stmt($stmt1);
trace(" $rows rows retrieved.\n");
dropTable($conn1, $tableName);
if ($rows > 0) {
die("Table $tableName, expected to be empty, has $rows rows.");
}
dropTable($conn1, $tableName);
sqlsrv_close($conn1);
endTest($testName);

View file

@ -44,7 +44,6 @@ function deleteQuery()
$cond = "(c1_int = ?)";
$params = array($keyValue);
$stmt3 = AE\selectFromTable($conn1, $tableName, $cond, $params);
$delRows = rowCount($stmt3);
sqlsrv_free_stmt($stmt3);
@ -60,7 +59,7 @@ function deleteQuery()
$row += $numRows1;
}
$stmt3 = AE\executeQuery($conn1, "DELETE TOP(1) FROM [$tableName]");
$stmt3 = executeQuery($conn1, "DELETE TOP(1) FROM [$tableName]");
$numRows2 = sqlsrv_rows_affected($stmt3);
sqlsrv_free_stmt($stmt3);

View file

@ -27,7 +27,8 @@ function invalidQuery()
$tableName = 'TC38test';
$columns = array(new AE\ColumnMeta('int', 'c1'),
new AE\ColumnMeta('int', 'c2'));
AE\createTable($conn1, $tableName, $columns);
// Invalid PHPTYPE parameter
$stmt2 = sqlsrv_query(
$conn1,

View file

@ -65,8 +65,8 @@ function fetchFields()
}
}
}
if ($r1 = sqlsrv_next_result($stmt1) ||
$r2 = sqlsrv_next_result($stmt2)) {
if (sqlsrv_next_result($stmt1) ||
sqlsrv_next_result($stmt2)) {
setUTF8Data(false);
fatalError("No more results were expected", true);
}

View file

@ -24,7 +24,7 @@ function paramQuery($minType, $maxType)
$data = getSampleData($k);
if ($data != null) {
$sqlType = getSqlType($k);
$phpDriverType = getDriverType($k, strlen($data));
$phpDriverType = getSqlsrvSqlType($k, strlen($data));
$columns = array(new AE\ColumnMeta('int', 'c1'),
new AE\ColumnMeta($sqlType, 'c2'));
traceData($sqlType, $data);

View file

@ -102,7 +102,7 @@ function sendStream($minType, $maxType, $atExec)
$fname2 = fopen($fileName, "r");
$sqlType = getSqlType($k);
$phpDriverType = getDriverType($k, strlen($data));
$phpDriverType = getSqlsrvSqlType($k, strlen($data));
traceData($sqlType, $data);
// create table

View file

@ -53,7 +53,7 @@ function sendStream($minType, $maxType)
$fname2 = fopen($fileName, "r");
$sqlType = getSqlType($k);
$phpDriverType = getDriverType($k, strlen($data));
$phpDriverType = getSqlsrvSqlType($k, strlen($data));
$dataOptions = array(array($k, SQLSRV_PARAM_IN),
array(&$fname2, SQLSRV_PARAM_IN, null, $phpDriverType));

View file

@ -23,6 +23,7 @@ function transaction($minType, $maxType)
$conn1 = AE\connect();
$colName = "c1";
$dataSize = 512;
for ($k = $minType; $k <= $maxType; $k++) {
switch ($k) {
case 20: // binary
@ -36,7 +37,7 @@ function transaction($minType, $maxType)
}
if ($data != null) {
$sqlType = getSqlType($k);
$driverType = getDriverType($k);
$driverType = getSqlsrvSqlType($k, $dataSize);
AE\createTable($conn1, $tableName, array(new AE\ColumnMeta($sqlType, $colName)));
createTransactionProc($conn1, $tableName, $colName, $procName, $sqlType);

View file

@ -25,43 +25,43 @@ function procQuery($minType, $maxType)
for ($k = $minType; $k <= $maxType; $k++) {
switch ($k) {
case 1: // TINYINT
execprocQuery($conn1, $procName, $k, "TINYINT", 11, 12, 23);
execProcQuery($conn1, $procName, $k, "TINYINT", 11, 12, 23);
break;
case 2: // SMALLINT
execprocQuery($conn1, $procName, $k, "SMALLINT", 4.3, 5.5, 9);
execProcQuery($conn1, $procName, $k, "SMALLINT", 4.3, 5.5, 9);
break;
case 3: // INT
execprocQuery($conn1, $procName, $k, "INT", 3.2, 4, 7);
execProcQuery($conn1, $procName, $k, "INT", 3.2, 4, 7);
break;
case 4: // BIGINT
execprocQuery($conn1, $procName, $k, "BIGINT", 5.2, 3.7, 8);
execProcQuery($conn1, $procName, $k, "BIGINT", 5.2, 3.7, 8);
break;
case 5: // FLOAT
execprocQuery($conn1, $procName, $k, "FLOAT", 2.5, 5.25, 7.75);
execProcQuery($conn1, $procName, $k, "FLOAT", 2.5, 5.25, 7.75);
break;
case 6: // REAL
execprocQuery($conn1, $procName, $k, "REAL", 3.4, 6.6, 10);
execProcQuery($conn1, $procName, $k, "REAL", 3.4, 6.6, 10);
break;
case 7: // DECIMAL
execprocQuery($conn1, $procName, $k, "DECIMAL", 2.1, 5.3, 7);
execProcQuery($conn1, $procName, $k, "DECIMAL", 2.1, 5.3, 7);
break;
case 8: // NUMERIC
execprocQuery($conn1, $procName, $k, "NUMERIC", 2.8, 5.4, 8);
execProcQuery($conn1, $procName, $k, "NUMERIC", 2.8, 5.4, 8);
break;
case 9: // SMALLMONEY
execprocQuery($conn1, $procName, $k, "SMALLMONEY", 10, 11.7, 21.7);
execProcQuery($conn1, $procName, $k, "SMALLMONEY", 10, 11.7, 21.7);
break;
case 10:// MONEY
execprocQuery($conn1, $procName, $k, "MONEY", 22.3, 16.1, 38.4);
execProcQuery($conn1, $procName, $k, "MONEY", 22.3, 16.1, 38.4);
break;
default:// default
@ -74,7 +74,7 @@ function procQuery($minType, $maxType)
endTest($testName);
}
function execprocQuery($conn, $procName, $type, $dataType, $inData1, $inData2, $outData)
function execProcQuery($conn, $procName, $type, $dataType, $inData1, $inData2, $outData)
{
$procArgs = "@p1 $dataType, @p2 $dataType, @p3 $dataType OUTPUT";
$procCode = "SELECT @p3 = CONVERT($dataType, @p1 + @p2)";

View file

@ -13,8 +13,6 @@ require_once('MsCommon.inc');
function storedProcRoundtrip($minType, $maxType)
{
// include 'MsSetup.inc';
$testName = "Stored Proc Roundtrip";
startTest($testName);
@ -28,7 +26,7 @@ function storedProcRoundtrip($minType, $maxType)
for ($i = $minType; $i <= $maxType; $i++) {
$dataTypeIn = getSqlType($i);
$phpTypeIn = getDriverType($i, $dataSize);
$phpTypeIn = getSqlsrvSqlType($i, $dataSize);
for ($j = $minType; $j <= $maxType; $j++) {
$k = $j;
@ -48,7 +46,7 @@ function storedProcRoundtrip($minType, $maxType)
}
$dataTypeOut = getSqlType($k);
$phpTypeOut = getDriverType($k, 512);
$phpTypeOut = getSqlsrvSqlType($k, 512);
execProcRoundtrip($conn1, $procName, $dataTypeIn, $dataTypeOut, $phpTypeIn, $phpTypeOut, $data);
}
}

View file

@ -20,7 +20,6 @@ function bugRepro()
$conn1 = AE\connect();
// empty parameter array
$tableName = "test_bq";
dropTable($conn1, $tableName);
$columns = array(new AE\ColumnMeta("int", "id", "IDENTITY NOT NULL"),
new AE\ColumnMeta("varchar(max)", "test_varchar_max"));
$s = AE\createTable($conn1, $tableName, $columns);

View file

@ -45,27 +45,38 @@ function main($minType, $maxType)
startTest($testName);
setup();
$conn = connect();
$conn = AE\connect();
for ($k = $minType; $k <= $maxType; $k++) {
if ($k == 18 || $k == 19) {
// skip text and ntext types; not supported as output params
continue;
}
$sqlType = GetSqlType($k);
}
$sqlType = getSqlType($k);
// for each data type create a table with two columns, 1: dataType id 2: data type
$dataType = "[$columnNames[0]] int, [$columnNames[1]] $sqlType";
createTableEx($conn, $tableName, $dataType);
// createTableEx($conn, $tableName, $dataType);
if ($k == 10 || $k == 11) {
// do not encrypt money type -- ODBC restrictions
$noEncrypt = true;
} else {
$noEncrypt = false;
}
$columns = array(new AE\ColumnMeta('int', $columnNames[0]),
new AE\ColumnMeta($sqlType, $columnNames[1], null, true, $noEncrypt));
AE\createTable($conn, $tableName, $columns);
// data to populate the table, false since we don't want to initialize a variable using this data.
$data = GetData($k, false);
$data = getData($k, false);
TraceData($sqlType, $data);
traceData($sqlType, $data);
$dataValues = array($k, $data);
InsertRowNoOption($conn, $tableName, $columnNames, $dataValues);
insertRowNoOption($conn, $tableName, $columnNames, $dataValues);
ExecProc($conn, $tableName, $columnNames, $k, $data, $sqlType);
execProc($conn, $tableName, $columnNames, $k, $data, $sqlType);
}
dropTable($conn, $tableName, $k);
@ -84,9 +95,11 @@ function main($minType, $maxType)
* @param $data is used to get the SQLSRV_PHPTYPE_*
* @param $sqlType the same datatype used to create the table with
*/
function ExecProc($conn, $tableName, $columnNames, $k, $data, $sqlType)
function execProc($conn, $tableName, $columnNames, $k, $data, $sqlType)
{
$phpDriverType = GetDriverType($k, strlen($data));
// With AE enabled it is stricter with data size
$dataSize = AE\isColEncrypted() ? 512 : strlen($data);
$phpDriverType = getSqlsrvSqlType($k, $dataSize);
$spArgs = "@p1 int, @p2 $sqlType OUTPUT";
@ -97,11 +110,12 @@ function ExecProc($conn, $tableName, $columnNames, $k, $data, $sqlType)
$callArgs = "?, ?";
//get data to initialize $callResult variable, this variable should be different than inserted data in the table
$initData = GetData($k, true);
$initData = getData($k, true);
$callResult = $initData;
$params = array( array( $k, SQLSRV_PARAM_IN ),
array( &$callResult, SQLSRV_PARAM_OUT, null, $phpDriverType ));
$inType = AE\isColEncrypted() ? SQLSRV_SQLTYPE_INT : null;
$params = array(array($k, SQLSRV_PARAM_IN, null, $inType),
array(&$callResult, SQLSRV_PARAM_OUT, null, $phpDriverType));
callProc($conn, $procName, $callArgs, $params);
// check if it is updated
@ -118,11 +132,17 @@ function ExecProc($conn, $tableName, $columnNames, $k, $data, $sqlType)
* @param $columnNames array containig the column names
* @param $dataValues array of values to be insetred in the table
*/
function InsertRowNoOption($conn, $tableName, $columnNames, $dataValues)
function insertRowNoOption($conn, $tableName, $columnNames, $dataValues)
{
$tsql = "INSERT INTO [$tableName] ($columnNames[0], $columnNames[1]) VALUES (?, ?)";
$stmt = sqlsrv_query($conn, $tsql, $dataValues);
if (false === $stmt) {
$res = null;
$stmt = AE\insertRow($conn,
$tableName,
array($columnNames[0] => $dataValues[0], $columnNames[1] => $dataValues[1]),
$res,
AE\INSERT_QUERY_PARAMS
);
if ($stmt === false || $res === false) {
print_r(sqlsrv_errors());
}
}
@ -132,7 +152,7 @@ function InsertRowNoOption($conn, $tableName, $columnNames, $dataValues)
* @param $k data type id, this id of each datatype are the same as the one in the MsCommon.inc file
* @param $initData boolean parameter, if true it means the returned data value is used to initialize a variable.
*/
function GetData($k, $initData)
function getData($k, $initData)
{
if (false == $initData) {
switch ($k) {
@ -218,21 +238,12 @@ function GetData($k, $initData)
}
}
//--------------------------------------------------------------------
// Repro
//
//--------------------------------------------------------------------
function Repro()
{
try {
main(1, 22);
} catch (Exception $e) {
echo $e->getMessage();
}
try {
main(1, 22);
} catch (Exception $e) {
echo $e->getMessage();
}
Repro();
?>
--EXPECTREGEX--