From af54c9eaeb87c578af444f47e9c00e8e9770967d Mon Sep 17 00:00:00 2001 From: v-susanh Date: Thu, 15 Mar 2018 22:29:41 -0700 Subject: [PATCH] sqlsrv tests for output parms with sqltypes (#720) * sqlsrv tests for output parms with sqltypes --- test/functional/sqlsrv/AEData.inc | 283 +++++++++++------- .../sqlsrv/sqlsrv_ae_output_param_all.phpt | 10 +- ...lsrv_ae_output_param_sqltype_datetime.phpt | 137 +++++++++ ...qlsrv_ae_output_param_sqltype_numeric.phpt | 187 ++++++++++++ ...sqlsrv_ae_output_param_sqltype_string.phpt | 137 +++++++++ 5 files changed, 634 insertions(+), 120 deletions(-) create mode 100755 test/functional/sqlsrv/sqlsrv_ae_output_param_sqltype_datetime.phpt create mode 100755 test/functional/sqlsrv/sqlsrv_ae_output_param_sqltype_numeric.phpt create mode 100755 test/functional/sqlsrv/sqlsrv_ae_output_param_sqltype_string.phpt diff --git a/test/functional/sqlsrv/AEData.inc b/test/functional/sqlsrv/AEData.inc index eebf1f45..3879efce 100644 --- a/test/functional/sqlsrv/AEData.inc +++ b/test/functional/sqlsrv/AEData.inc @@ -1,113 +1,170 @@ - + diff --git a/test/functional/sqlsrv/sqlsrv_ae_output_param_all.phpt b/test/functional/sqlsrv/sqlsrv_ae_output_param_all.phpt index f252de18..d7ff5db1 100644 --- a/test/functional/sqlsrv/sqlsrv_ae_output_param_all.phpt +++ b/test/functional/sqlsrv/sqlsrv_ae_output_param_all.phpt @@ -32,8 +32,7 @@ AE\createTable($conn, $tbname, $colMetaArr); // Create a Store Procedure $spname = 'selectAllColumns'; -$spSql = "CREATE PROCEDURE $spname ( - @c1_int int OUTPUT, @c2_smallint smallint OUTPUT, +createProc($conn, $spname, "@c1_int int OUTPUT, @c2_smallint smallint OUTPUT, @c3_tinyint tinyint OUTPUT, @c4_bit bit OUTPUT, @c5_bigint bigint OUTPUT, @c6_decimal decimal(18,5) OUTPUT, @c7_numeric numeric(10,5) OUTPUT, @c8_float float OUTPUT, @@ -41,8 +40,7 @@ $spSql = "CREATE PROCEDURE $spname ( @c11_datetime datetime OUTPUT, @c12_datetime2 datetime2 OUTPUT, @c13_datetimeoffset datetimeoffset OUTPUT, @c14_time time OUTPUT, @c15_char char(5) OUTPUT, @c16_varchar varchar(max) OUTPUT, - @c17_nchar nchar(5) OUTPUT, @c18_nvarchar nvarchar(max) OUTPUT) AS - SELECT @c1_int = c1_int, @c2_smallint = c2_smallint, + @c17_nchar nchar(5) OUTPUT, @c18_nvarchar nvarchar(max) OUTPUT", "SELECT @c1_int = c1_int, @c2_smallint = c2_smallint, @c3_tinyint = c3_tinyint, @c4_bit = c4_bit, @c5_bigint = c5_bigint, @c6_decimal = c6_decimal, @c7_numeric = c7_numeric, @c8_float = c8_float, @@ -51,9 +49,7 @@ $spSql = "CREATE PROCEDURE $spname ( @c13_datetimeoffset = c13_datetimeoffset, @c14_time = c14_time, @c15_char = c15_char, @c16_varchar = c16_varchar, @c17_nchar = c17_nchar, @c18_nvarchar = c18_nvarchar - FROM $tbname"; -sqlsrv_query($conn, $spSql); - + FROM $tbname"); // Insert data $inputs = array( "c1_int" => 2147483647, "c2_smallint" => 32767, diff --git a/test/functional/sqlsrv/sqlsrv_ae_output_param_sqltype_datetime.phpt b/test/functional/sqlsrv/sqlsrv_ae_output_param_sqltype_datetime.phpt new file mode 100755 index 00000000..19631bca --- /dev/null +++ b/test/functional/sqlsrv/sqlsrv_ae_output_param_sqltype_datetime.phpt @@ -0,0 +1,137 @@ +--TEST-- +Test for inserting and retrieving encrypted data of datetime types +--DESCRIPTION-- +Bind output params using sqlsrv_prepare with all sql_type +--SKIPIF-- + +--FILE-- + array( "SQLSRV_SQLTYPE_CHAR", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DATETIME", "SQLSRV_SQLTYPE_SMALLDATETIME", "SQLSRV_SQLTYPE_DATE", "SQLSRV_SQLTYPE_DATETIMEOFFSET", "SQLSRV_SQLTYPE_DATETIME2"), + "datetime" => array( "SQLSRV_SQLTYPE_CHAR", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DATETIME", "SQLSRV_SQLTYPE_SMALLDATETIME", "SQLSRV_SQLTYPE_DATE", "SQLSRV_SQLTYPE_TIME", "SQLSRV_SQLTYPE_DATETIMEOFFSET", "SQLSRV_SQLTYPE_DATETIME2"), + "datetime2" => array( "SQLSRV_SQLTYPE_CHAR", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DATETIME", "SQLSRV_SQLTYPE_SMALLDATETIME", "SQLSRV_SQLTYPE_DATE", "SQLSRV_SQLTYPE_TIME", "SQLSRV_SQLTYPE_DATETIMEOFFSET", "SQLSRV_SQLTYPE_DATETIME2"), + "smalldatetime" => array( "SQLSRV_SQLTYPE_CHAR", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DATETIME", "SQLSRV_SQLTYPE_SMALLDATETIME", "SQLSRV_SQLTYPE_DATE", "SQLSRV_SQLTYPE_TIME", "SQLSRV_SQLTYPE_DATETIMEOFFSET", "SQLSRV_SQLTYPE_DATETIME2"), + "time" => array( "SQLSRV_SQLTYPE_CHAR", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DATETIME", "SQLSRV_SQLTYPE_SMALLDATETIME", "SQLSRV_SQLTYPE_TIME", "SQLSRV_SQLTYPE_DATETIMEOFFSET", "SQLSRV_SQLTYPE_DATETIME2"), + "datetimeoffset" => array("SQLSRV_SQLTYPE_CHAR", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DATETIMEOFFSET") ); + +$conn = AE\connect(); + +foreach ($dataTypes as $dataType) { + echo "\nTesting $dataType:\n"; + $success = true; + + // create table + $tbname = GetTempTableName("", false); + $colMetaArr = array(new AE\ColumnMeta($dataType, "c_det"), new AE\ColumnMeta($dataType, "c_rand", null, false)); + AE\createTable($conn, $tbname, $colMetaArr); + + if (AE\isColEncrypted()) { + // Create a Store Procedure + $spname = 'selectAllColumns'; + createProc($conn, $spname, "@c_det $dataType OUTPUT, @c_rand $dataType OUTPUT", "SELECT @c_det = c_det, @c_rand = c_rand FROM $tbname"); + } + + // insert a row + $inputValues = array_slice(${explode("(", $dataType)[0] . "_params"}, 1, 2); + $r; + $stmt = AE\insertRow($conn, $tbname, array( $colMetaArr[0]->colName => $inputValues[0], $colMetaArr[1]->colName => $inputValues[1] ), $r); + if ($r === false) { + is_incompatible_types_error($dataType, "default type"); + } + + foreach($directions as $direction) { + echo "Testing as $direction:\n"; + + // test each SQLSRV_SQLTYPE_ constants + foreach ($sqlTypes as $sqlType) { + if (!AE\isColEncrypted()) { + $isCompatible = false; + foreach ($compatList[$dataType] as $compatType) { + if (stripos($compatType, $sqlType) !== false) { + $isCompatible = true; + } + } + // 22018 is the SQLSTATE for any incompatible conversion errors + if ($isCompatible && sqlsrv_errors()[0]['SQLSTATE'] == 22018) { + echo "$sqlType should be compatible with $dataType\n"; + $success = false; + } + } else { + // skip unsupported datetime types + if (!isDateTimeType($sqlType)) { + $sqlTypeConstant = get_sqlType_constant($sqlType); + + // Call store procedure + $outSql = AE\getCallProcSqlPlaceholders($spname, 2); + $c_detOut = ''; + $c_randOut = ''; + $stmt = sqlsrv_prepare( $conn, $outSql, + array(array( &$c_detOut, SQLSRV_PARAM_OUT, null, $sqlTypeConstant), + array(&$c_randOut, SQLSRV_PARAM_OUT, null, $sqlTypeConstant ))); + if (!$stmt) { + die(print_r(sqlsrv_errors(), true)); + } + sqlsrv_execute($stmt); + $errors = sqlsrv_errors(); + if (empty($errors)) { + // SQLSRV_PHPTYPE_DATETIME not supported + echo "$dataType should not be compatible with any datetime type.\n"; + $success = false; + } + } + + sqlsrv_free_stmt($stmt); + } + } + } + + if ($success) { + echo "Test successfully done.\n"; + } + + if (AE\isColEncrypted()) { + dropProc($conn, $spname); + } + dropTable($conn, $tbname); +} + +sqlsrv_close($conn); +?> +--EXPECT-- + +Testing date: +Testing as SQLSRV_PARAM_OUT: +Testing as SQLSRV_PARAM_INOUT: +Test successfully done. + +Testing datetime: +Testing as SQLSRV_PARAM_OUT: +Testing as SQLSRV_PARAM_INOUT: +Test successfully done. + +Testing datetime2: +Testing as SQLSRV_PARAM_OUT: +Testing as SQLSRV_PARAM_INOUT: +Test successfully done. + +Testing smalldatetime: +Testing as SQLSRV_PARAM_OUT: +Testing as SQLSRV_PARAM_INOUT: +Test successfully done. + +Testing time: +Testing as SQLSRV_PARAM_OUT: +Testing as SQLSRV_PARAM_INOUT: +Test successfully done. + +Testing datetimeoffset: +Testing as SQLSRV_PARAM_OUT: +Testing as SQLSRV_PARAM_INOUT: +Test successfully done. diff --git a/test/functional/sqlsrv/sqlsrv_ae_output_param_sqltype_numeric.phpt b/test/functional/sqlsrv/sqlsrv_ae_output_param_sqltype_numeric.phpt new file mode 100755 index 00000000..a5f20e43 --- /dev/null +++ b/test/functional/sqlsrv/sqlsrv_ae_output_param_sqltype_numeric.phpt @@ -0,0 +1,187 @@ +--TEST-- +Test for inserting and retrieving encrypted data of numeric types +--DESCRIPTION-- +Bind output params using sqlsrv_prepare with all sql_type +--SKIPIF-- + +--FILE-- + array( "SQLSRV_SQLTYPE_BINARY", "SQLSRV_SQLTYPE_VARBINARY", "SQLSRV_SQLTYPE_CHAR", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DATETIME", "SQLSRV_SQLTYPE_SMALLDATETIME", "SQLSRV_SQLTYPE_DECIMAL(18,5)", "SQLSRV_SQLTYPE_NUMERIC(10,5)", "SQLSRV_SQLTYPE_FLOAT", "SQLSRV_SQLTYPE_REAL", "SQLSRV_SQLTYPE_BIGINT", "SQLSRV_SQLTYPE_INT", "SQLSRV_SQLTYPE_SMALLINT", "SQLSRV_SQLTYPE_TINYINT", "SQLSRV_SQLTYPE_MONEY", "SQLSRV_SQLTYPE_SMALLMONEY", "SQLSRV_SQLTYPE_BIT", "SQLSRV_SQLTYPE_TIMESTAMP"), + "tinyint" => array( "SQLSRV_SQLTYPE_BINARY", "SQLSRV_SQLTYPE_VARBINARY", "SQLSRV_SQLTYPE_CHAR", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DATETIME", "SQLSRV_SQLTYPE_SMALLDATETIME", "SQLSRV_SQLTYPE_DECIMAL(18,5)", "SQLSRV_SQLTYPE_NUMERIC(10,5)", "SQLSRV_SQLTYPE_FLOAT", "SQLSRV_SQLTYPE_REAL", "SQLSRV_SQLTYPE_BIGINT", "SQLSRV_SQLTYPE_INT", "SQLSRV_SQLTYPE_SMALLINT", "SQLSRV_SQLTYPE_TINYINT", "SQLSRV_SQLTYPE_MONEY", "SQLSRV_SQLTYPE_SMALLMONEY", "SQLSRV_SQLTYPE_BIT", "SQLSRV_SQLTYPE_TIMESTAMP"), + "smallint" => array( "SQLSRV_SQLTYPE_BINARY", "SQLSRV_SQLTYPE_VARBINARY", "SQLSRV_SQLTYPE_CHAR", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DATETIME", "SQLSRV_SQLTYPE_SMALLDATETIME", "SQLSRV_SQLTYPE_DECIMAL(18,5)", "SQLSRV_SQLTYPE_NUMERIC(10,5)", "SQLSRV_SQLTYPE_FLOAT", "SQLSRV_SQLTYPE_REAL", "SQLSRV_SQLTYPE_BIGINT", "SQLSRV_SQLTYPE_INT", "SQLSRV_SQLTYPE_SMALLINT", "SQLSRV_SQLTYPE_TINYINT", "SQLSRV_SQLTYPE_MONEY", "SQLSRV_SQLTYPE_SMALLMONEY", "SQLSRV_SQLTYPE_BIT", "SQLSRV_SQLTYPE_TIMESTAMP"), + "int" => array( "SQLSRV_SQLTYPE_BINARY", "SQLSRV_SQLTYPE_VARBINARY", "SQLSRV_SQLTYPE_CHAR", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DATETIME", "SQLSRV_SQLTYPE_SMALLDATETIME", "SQLSRV_SQLTYPE_DECIMAL(18,5)", "SQLSRV_SQLTYPE_NUMERIC(10,5)", "SQLSRV_SQLTYPE_FLOAT", "SQLSRV_SQLTYPE_REAL", "SQLSRV_SQLTYPE_BIGINT", "SQLSRV_SQLTYPE_INT", "SQLSRV_SQLTYPE_SMALLINT", "SQLSRV_SQLTYPE_TINYINT", "SQLSRV_SQLTYPE_MONEY", "SQLSRV_SQLTYPE_SMALLMONEY", "SQLSRV_SQLTYPE_BIT", "SQLSRV_SQLTYPE_TIMESTAMP"), + "bigint" => array( "SQLSRV_SQLTYPE_BINARY", "SQLSRV_SQLTYPE_VARBINARY", "SQLSRV_SQLTYPE_CHAR", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DATETIME", "SQLSRV_SQLTYPE_SMALLDATETIME", "SQLSRV_SQLTYPE_DECIMAL(18,5)", "SQLSRV_SQLTYPE_NUMERIC(10,5)", "SQLSRV_SQLTYPE_FLOAT", "SQLSRV_SQLTYPE_REAL", "SQLSRV_SQLTYPE_BIGINT", "SQLSRV_SQLTYPE_INT", "SQLSRV_SQLTYPE_SMALLINT", "SQLSRV_SQLTYPE_TINYINT", "SQLSRV_SQLTYPE_MONEY", "SQLSRV_SQLTYPE_SMALLMONEY", "SQLSRV_SQLTYPE_BIT", "SQLSRV_SQLTYPE_TIMESTAMP" ), + "decimal(18,5)" => array( "SQLSRV_SQLTYPE_BINARY", "SQLSRV_SQLTYPE_VARBINARY", "SQLSRV_SQLTYPE_CHAR", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DATETIME", "SQLSRV_SQLTYPE_SMALLDATETIME", "SQLSRV_SQLTYPE_DECIMAL(18,5)", "SQLSRV_SQLTYPE_NUMERIC(10,5)", "SQLSRV_SQLTYPE_FLOAT", "SQLSRV_SQLTYPE_REAL", "SQLSRV_SQLTYPE_BIGINT", "SQLSRV_SQLTYPE_INT", "SQLSRV_SQLTYPE_SMALLINT", "SQLSRV_SQLTYPE_TINYINT", "SQLSRV_SQLTYPE_MONEY", "SQLSRV_SQLTYPE_SMALLMONEY", "SQLSRV_SQLTYPE_BIT", "SQLSRV_SQLTYPE_TIMESTAMP"), + "numeric(10,5)" => array( "SQLSRV_SQLTYPE_BINARY", "SQLSRV_SQLTYPE_VARBINARY", "SQLSRV_SQLTYPE_CHAR", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DATETIME", "SQLSRV_SQLTYPE_SMALLDATETIME", "SQLSRV_SQLTYPE_DECIMAL(18,5)", "SQLSRV_SQLTYPE_NUMERIC(10,5)", "SQLSRV_SQLTYPE_FLOAT", "SQLSRV_SQLTYPE_REAL", "SQLSRV_SQLTYPE_BIGINT", "SQLSRV_SQLTYPE_INT", "SQLSRV_SQLTYPE_SMALLINT", "SQLSRV_SQLTYPE_TINYINT", "SQLSRV_SQLTYPE_MONEY", "SQLSRV_SQLTYPE_SMALLMONEY", "SQLSRV_SQLTYPE_BIT", "SQLSRV_SQLTYPE_TIMESTAMP"), + "float" => array( "SQLSRV_SQLTYPE_BINARY", "SQLSRV_SQLTYPE_VARBINARY", "SQLSRV_SQLTYPE_CHAR", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DATETIME", "SQLSRV_SQLTYPE_SMALLDATETIME", "SQLSRV_SQLTYPE_DECIMAL(18,5)", "SQLSRV_SQLTYPE_NUMERIC(10,5)", "SQLSRV_SQLTYPE_FLOAT", "SQLSRV_SQLTYPE_REAL", "SQLSRV_SQLTYPE_BIGINT", "SQLSRV_SQLTYPE_INT", "SQLSRV_SQLTYPE_SMALLINT", "SQLSRV_SQLTYPE_TINYINT", "SQLSRV_SQLTYPE_MONEY", "SQLSRV_SQLTYPE_SMALLMONEY", "SQLSRV_SQLTYPE_BIT"), + "real" => array( "SQLSRV_SQLTYPE_BINARY", "SQLSRV_SQLTYPE_VARBINARY", "SQLSRV_SQLTYPE_CHAR", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DATETIME", "SQLSRV_SQLTYPE_SMALLDATETIME", "SQLSRV_SQLTYPE_DECIMAL(18,5)", "SQLSRV_SQLTYPE_NUMERIC(10,5)", "SQLSRV_SQLTYPE_FLOAT", "SQLSRV_SQLTYPE_REAL", "SQLSRV_SQLTYPE_BIGINT", "SQLSRV_SQLTYPE_INT", "SQLSRV_SQLTYPE_SMALLINT", "SQLSRV_SQLTYPE_TINYINT", "SQLSRV_SQLTYPE_MONEY", "SQLSRV_SQLTYPE_SMALLMONEY", "SQLSRV_SQLTYPE_BIT")); +$epsilon = 0.0001; + +$conn = AE\connect(); + +foreach ($dataTypes as $dataType) { + echo "\nTesting $dataType:\n"; + $success = true; + + // create table + $tbname = GetTempTableName("", false); + $colMetaArr = array(new AE\ColumnMeta($dataType, "c_det"), new AE\ColumnMeta($dataType, "c_rand", null, false)); + AE\createTable($conn, $tbname, $colMetaArr); + + // TODO: It's a good idea to test conversions between different datatypes when AE is off as well. + if (AE\isColEncrypted()) { + // Create a Store Procedure + $spname = 'selectAllColumns'; + createProc($conn, $spname, "@c_det $dataType OUTPUT, @c_rand $dataType OUTPUT", "SELECT @c_det = c_det, @c_rand = c_rand FROM $tbname"); + } + + // insert a row + $inputValues = array_slice(${explode("(", $dataType)[0] . "_params"}, 1, 2); + $r; + // convert input values to strings for decimals and numerics + if ($dataTypes == "decimal(18,5)" || $dataTypes == "numeric(10,5)") { + $stmt = AE\insertRow($conn, $tbname, array( $colMetaArr[0]->colName => (string) $inputValues[0], $colMetaArr[1]->colName => (string) $inputValues[1] ), $r); + } else { + $stmt = AE\insertRow($conn, $tbname, array( $colMetaArr[0]->colName => $inputValues[0], $colMetaArr[1]->colName => $inputValues[1] ), $r); + } + if ($r === false) { + is_incompatible_types_error($dataType, "default type"); + } + + foreach($directions as $direction) { + echo "Testing as $direction:\n"; + + // test each SQLSRV_SQLTYPE_ constants + foreach ($sqlTypes as $sqlType) { + + if (!AE\isColEncrypted()) { + $isCompatible = false; + foreach ($compatList[$dataType] as $compatType) { + if (stripos($compatType, $sqlType) !== false) { + $isCompatible = true; + } + } + // 22018 is the SQLSTATE for any incompatible conversion errors + if ($isCompatible && sqlsrv_errors()[0]['SQLSTATE'] == 22018) { + echo "$sqlType should be compatible with $dataType\n"; + $success = false; + } + } else { + // skip unsupported datetime types + if (!isDateTimeType($sqlType)) { + $sqlTypeConstant = get_sqlType_constant($sqlType); + + // Call store procedure + $outSql = AE\getCallProcSqlPlaceholders($spname, 2); + if ($sqlType == 'SQLSRV_SQLTYPE_FLOAT' || $sqlType == 'SQLSRV_SQLTYPE_REAL') { + $c_detOut = 0.0; + $c_randOut = 0.0; + } else { + $c_detOut = 0; + $c_randOut = 0; + } + $stmt = sqlsrv_prepare($conn, $outSql, + array(array( &$c_detOut, constant($direction), null, $sqlTypeConstant), + array(&$c_randOut, constant($direction), null, $sqlTypeConstant))); + + if (!$stmt) { + die(print_r(sqlsrv_errors(), true)); + } + sqlsrv_execute($stmt); + $errors = sqlsrv_errors(); + + if (!empty($errors)) { + if (stripos("SQLSRV_SQLTYPE_" . $dataType, $sqlType) !== false) { + var_dump(sqlsrv_errors()); + $success = false; + } + } + else { + if ($dataType == "float" || $dataType == "real") { + if (abs($c_detOut - $inputValues[0]) > $epsilon || abs($c_randOut - $inputValues[1]) > $epsilon) { + echo "Incorrect output retrieved for datatype $dataType and sqlType $sqlType:\n"; + print(" c_det: " . $c_detOut . "\n"); + print(" c_rand: " . $c_randOut . "\n"); + $success = false; + } + } else { + if ($c_detOut != $inputValues[0] || $c_randOut != $inputValues[1]) { + echo "Incorrect output retrieved for datatype $dataType and sqlType $sqlType:\n"; + print(" c_det: " . $c_detOut . "\n"); + print(" c_rand: " . $c_randOut . "\n"); + $success = false; + } + } + } + + sqlsrv_free_stmt($stmt); + } + } + } + } + + if (AE\isColEncrypted()) { + dropProc($conn, $spname); + } + + if ($success) { + echo "Test successfully done.\n"; + } + dropTable($conn, $tbname); +} + +sqlsrv_close($conn); +?> +--EXPECT-- + +Testing bit: +Testing as SQLSRV_PARAM_OUT: +Testing as SQLSRV_PARAM_INOUT: +Test successfully done. + +Testing tinyint: +Testing as SQLSRV_PARAM_OUT: +Testing as SQLSRV_PARAM_INOUT: +Test successfully done. + +Testing smallint: +Testing as SQLSRV_PARAM_OUT: +Testing as SQLSRV_PARAM_INOUT: +Test successfully done. + +Testing int: +Testing as SQLSRV_PARAM_OUT: +Testing as SQLSRV_PARAM_INOUT: +Test successfully done. + +Testing bigint: +Testing as SQLSRV_PARAM_OUT: +Testing as SQLSRV_PARAM_INOUT: +Test successfully done. + +Testing decimal(18,5): +Testing as SQLSRV_PARAM_OUT: +Testing as SQLSRV_PARAM_INOUT: +Test successfully done. + +Testing numeric(10,5): +Testing as SQLSRV_PARAM_OUT: +Testing as SQLSRV_PARAM_INOUT: +Test successfully done. + +Testing float: +Testing as SQLSRV_PARAM_OUT: +Testing as SQLSRV_PARAM_INOUT: +Test successfully done. + +Testing real: +Testing as SQLSRV_PARAM_OUT: +Testing as SQLSRV_PARAM_INOUT: +Test successfully done. diff --git a/test/functional/sqlsrv/sqlsrv_ae_output_param_sqltype_string.phpt b/test/functional/sqlsrv/sqlsrv_ae_output_param_sqltype_string.phpt new file mode 100755 index 00000000..44057427 --- /dev/null +++ b/test/functional/sqlsrv/sqlsrv_ae_output_param_sqltype_string.phpt @@ -0,0 +1,137 @@ +--TEST-- +Test for inserting and retrieving encrypted data of string types +--DESCRIPTION-- +Bind output params using sqlsrv_prepare with all sql_type +--SKIPIF-- + +--FILE-- + array( "SQLSRV_SQLTYPE_CHAR(5)", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR(5)", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DECIMAL", "SQLSRV_SQLTYPE_NUMERIC", "SQLSRV_SQLTYPE_NTEXT", "SQLSRV_SQLTYPE_TEXT", "SQLSRV_SQLTYPE_XML"), + "varchar(max)" => array( "SQLSRV_SQLTYPE_CHAR(5)", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR(5)", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DECIMAL", "SQLSRV_SQLTYPE_NUMERIC", "SQLSRV_SQLTYPE_NTEXT", "SQLSRV_SQLTYPE_TEXT", "SQLSRV_SQLTYPE_XML"), + "nchar(5)" => array( "SQLSRV_SQLTYPE_CHAR(5)", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR(5)", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DECIMAL", "SQLSRV_SQLTYPE_NUMERIC", "SQLSRV_SQLTYPE_NTEXT", "SQLSRV_SQLTYPE_TEXT", "SQLSRV_SQLTYPE_XML"), + "nvarchar(max)" => array( "SQLSRV_SQLTYPE_CHAR(5)", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR(5)", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DECIMAL", "SQLSRV_SQLTYPE_NUMERIC", "SQLSRV_SQLTYPE_NTEXT", "SQLSRV_SQLTYPE_TEXT", "SQLSRV_SQLTYPE_XML")); + +$conn = AE\connect(); + +foreach ($dataTypes as $dataType) { + echo "\nTesting $dataType:\n"; + $success = true; + + // create table + $tbname = GetTempTableName("", false); + $colMetaArr = array(new AE\ColumnMeta($dataType, "c_det"), new AE\ColumnMeta($dataType, "c_rand", null, false)); + AE\createTable($conn, $tbname, $colMetaArr); + + // TODO: It's a good idea to test conversions between different datatypes when AE is off as well. + if (AE\isColEncrypted()) { + // Create a Store Procedure + $spname = 'selectAllColumns'; + createProc($conn, $spname, "@c_det $dataType OUTPUT, @c_rand $dataType OUTPUT", "SELECT @c_det = c_det, @c_rand = c_rand FROM $tbname"); + } + + // insert a row + $inputValues = array_slice(${explode("(", $dataType)[0] . "_params"}, 1, 2); + $r; + $stmt = AE\insertRow($conn, $tbname, array( $colMetaArr[0]->colName => $inputValues[0], $colMetaArr[1]->colName => $inputValues[1] ), $r); + if ($r === false) { + is_incompatible_types_error($dataType, "default type"); + } + + foreach($directions as $direction) { + echo "Testing as $direction:\n"; + + // test each SQLSRV_SQLTYPE_ constants + foreach ($sqlTypes as $sqlType) { + if (!AE\isColEncrypted()) { + $isCompatible = false; + foreach ($compatList[$dataType] as $compatType) { + if (stripos($compatType, $sqlType) !== false) { + $isCompatible = true; + } + } + // 22018 is the SQLSTATE for any incompatible conversion errors + if ($isCompatible && sqlsrv_errors()[0]['SQLSTATE'] == 22018) { + echo "$sqlType should be compatible with $dataType\n"; + $success = false; + } + } else { + // skip unsupported datetime types + if (!isDateTimeType($sqlType)) { + $sqlTypeConstant = get_sqlType_constant($sqlType); + + // Call store procedure + $outSql = AE\getCallProcSqlPlaceholders($spname, 2); + $c_detOut = ''; + $c_randOut = ''; + $stmt = sqlsrv_prepare($conn, $outSql, + array(array(&$c_detOut, SQLSRV_PARAM_INOUT, null, $sqlTypeConstant), + array(&$c_randOut, SQLSRV_PARAM_INOUT, null, $sqlTypeConstant))); + + if (!$stmt) { + die(print_r(sqlsrv_errors(), true)); + } + + sqlsrv_execute($stmt); + $errors = sqlsrv_errors(); + + if (!empty($errors) ) { + if (stripos("SQLSRV_SQLTYPE_" . $dataType, $sqlType) !== false) { + var_dump(sqlsrv_errors()); + $success = false; + } + } + else + { + if ($c_detOut != $inputValues[0] || $c_randOut != $inputValues[1]) { + echo "Incorrect output retrieved for datatype $dataType and sqlType $sqlType:\n"; + print(" c_det: " . $c_detOut . "\n"); + print(" c_rand: " . $c_randOut . "\n"); + $success = false; + } + } + + sqlsrv_free_stmt($stmt); + } + } + } + } + + if (AE\isColEncrypted()) { + dropProc($conn, $spname); + } + if ($success) { + echo "Test successfully done.\n"; + } + dropTable($conn, $tbname); +} + +sqlsrv_close($conn); +?> +--EXPECT-- + +Testing char(5): +Testing as SQLSRV_PARAM_OUT: +Testing as SQLSRV_PARAM_INOUT: +Test successfully done. + +Testing varchar(max): +Testing as SQLSRV_PARAM_OUT: +Testing as SQLSRV_PARAM_INOUT: +Test successfully done. + +Testing nchar(5): +Testing as SQLSRV_PARAM_OUT: +Testing as SQLSRV_PARAM_INOUT: +Test successfully done. + +Testing nvarchar(max): +Testing as SQLSRV_PARAM_OUT: +Testing as SQLSRV_PARAM_INOUT: +Test successfully done.