* Fixed the potential error reported by Prefast code analysis

* Use SQLSRV_ASSERT for checking NULL ptrs

* For these AKV tests check env despite not AE connected

* Added the driver option to run functional tests

* Fixed connection pooling tests for more than one ODBC drivers

* added driver option to pdo isPooled.php

* Removed win32 ifdefs re connection resiliency (#802)

* Set the driver argument for getDSN to null by default (#798)

* Added the driver argument to getDSN

* Dropped the driver argument but set to null as default

* Removed the AE condition in locale support

* Modified the AE condition for locale support

* Changed int to SQLLEN to avoid infinite loop (#806)

* Version 5.3.0 (#803)

* Version 5.3.0

* Fixed the wrong replacements

* Added comments block to m4 files

* Use dnl for comments

*  Modified AE fetch phptypes test to insert only one row at a time and loop through php types (#801)

* Modified AE fetch phptypes test to insert only one row at a time and loop through php types

* Fixed formatting

* Streamlined two very similar large column name tests (#807)

* Streamlined two very similar large column name tests

* Changed the EOL

* Updates to change log and readme (#811)

* Updates to change log and readme

* Dropped support for Ubuntu 17

* Modified as per review comments

* Fixed connection resiliency tests for Unix, updated AppVeyor for ODBC 17.2

* Fixed expected output

* Fixed output and skipifs

* Fixed skipifs and output

* Fixed driver name

* Updated installation instructions and sample script (#813)

* Updated instructions and sample test for 5.3.0 RTW

* Fixed sample code to adhere to php coding standard

* Fixed cases and spaces

* Modified NOTE for UB 18.04 based on review comments

* Added 'exit'

* Modified change log and readme based on review to PR 811

* Applied review comments

* build output to debug appveyor failure

* removed debug output

* Streamlined two very similar large column name tests (#815)

* Streamlined two very similar large column name tests

* Added random number of test table names to avoid operand clash issues

* Replaced to with for based on review

* Changelog updated

* changelog updated, test skipif changed to run on unix platforms

* Fixed skipif typo

* Fixed typo in skipif for pdo

* Fixed some output for Travis

* Moved error checking inside pdo connres tests

* Added links back to changelog

* Fixed output for sqlsrv connres tests

* Fixed output

* Fixed output again
This commit is contained in:
Jenny Tam 2018-07-20 17:24:48 -07:00 committed by GitHub
parent 8f9ecdebce
commit 9654020d67
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
97 changed files with 763 additions and 814 deletions

View file

@ -3,6 +3,41 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
## 5.3.0 - 2018-07-20
Updated PECL release packages. Here is the list of updates:
### Added
- Added support for Azure Key Vault for Always Encrypted functionality. Always Encrypted functionality is supported on Linux and macOS through Azure Key Vault
- Added support for connection resiliency on Linux and macOS (requires version 17.2 or higher of the [ODBC driver](https://docs.microsoft.com/en-us/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server?view=sql-server-2017))
- Added support for macOS High Sierra (requires version 17 or higher of the [ODBC driver](https://docs.microsoft.com/en-us/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server?view=sql-server-2017))
- Added support for Ubuntu 18.04 (requires version 17.2 or higher of the [ODBC driver](https://docs.microsoft.com/en-us/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server?view=sql-server-2017))
### Fixed
- Issue [#577](https://github.com/Microsoft/msphpsql/issues/577) - Idle Connection Resiliency doesn't work with Column Encryption enabled connections (fixed in MS ODBC Driver 17.1)
- Issue [#678](https://github.com/Microsoft/msphpsql/issues/678) - Idle Connection Resiliency doesn't work with Connection Pooling (fixed in MS ODBC Driver 17.1)
- Issue [#699](https://github.com/Microsoft/msphpsql/issues/699) - Binding output parameters fails when the query in the stored procedure returns no data. The test case has been added to the test lab.
- Issue [#705](https://github.com/Microsoft/msphpsql/issues/705) - Always Encrypted - Retrieving a negative decimal value (edge case) as output parameter causes truncation
- Issue [#706](https://github.com/Microsoft/msphpsql/issues/706) - Always Encrypted - Cannot insert double with precision and scale (38, 38)
- Issue [#707](https://github.com/Microsoft/msphpsql/issues/707) - Always Encrypted - Fetching decimals / numerics as output parameters bound to PDO::PARAM_BOOL or PDO::PARAM_INT returns floats, not integers
- Issue [#735](https://github.com/Microsoft/msphpsql/issues/735) - Extended the buffer size for PDO::lastInsertId so that data types other than integers can be supported
- Pull Request [#759](https://github.com/Microsoft/msphpsql/pull/759) - Removed the limitation of binding a binary as inout param as PDO::PARAM_STR with SQLSRV_ENCODING_BINARY
- Pull Request [#775](https://github.com/Microsoft/msphpsql/pull/775) - Fixed the truncation problem for output params with SQL types specified as SQLSRV_SQLTYPE_DECIMAL or SQLSRV_SQLTYPE_NUMERIC
### Limitations
- No support for inout / output params when using sql_variant type
- In Linux and macOS, setlocale() only takes effect if it is invoked before the first connection. Attempting to set the locale after connecting will not work
- Always Encrypted requires [MS ODBC Driver 17+](https://docs.microsoft.com/en-us/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server?view=sql-server-2017)
- Only Windows Certificate Store and Azure Key Vault are supported. Custom Keystores are not yet supported
- Issue [#716](https://github.com/Microsoft/msphpsql/issues/716) - With Always Encrypted enabled, named parameters in subqueries are not supported
- [Always Encrypted limitations](https://docs.microsoft.com/en-us/sql/connect/php/using-always-encrypted-php-drivers?view=sql-server-2017#limitations-of-the-php-drivers-when-using-always-encrypted)
### Known Issues
- Connection pooling on Linux or macOS is not recommended with [unixODBC](http://www.unixodbc.org/) < 2.3.6
- When pooling is enabled in Linux or macOS
- unixODBC <= 2.3.4 (Linux and macOS) might not return proper diagnostic information, such as error messages, warnings and informative messages
- due to this unixODBC bug, fetch large data (such as xml, binary) as streams as a workaround. See the examples [here](https://github.com/Microsoft/msphpsql/wiki/Features#pooling)
- With ColumnEncryption enabled, calling stored procedures with XML parameters does not work (Issue [#674](https://github.com/Microsoft/msphpsql/issues/674))
## 5.2.1-preview - 2018-06-01
Updated PECL release packages. Here is the list of updates:

26
LICENSE
View file

@ -1,14 +1,14 @@
Copyright(c) 2017 Microsoft Corporation
All rights reserved.
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
Copyright(c) 2018 Microsoft Corporation
All rights reserved.
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.

View file

@ -1,20 +1,24 @@
# PHP Linux and Mac Drivers Installation Tutorial
The following instructions assume a clean environment and show how to install PHP 7.x, the Microsoft ODBC driver, Apache, and the Microsoft drivers for PHP for Microsoft SQL Server on Ubuntu 16.04 and 17.10, RedHat 7, Debian 8 and 9, Suse 12, and macOS 10.11 and 10.12. These instructions advise installing the drivers using PECL, but you can also download the prebuilt binaries from the [Microsoft Drivers for PHP for Microsoft SQL Server](https://github.com/Microsoft/msphpsql/releases) Github project page and install them following the instructions in [Loading the Microsoft Drivers for PHP for Microsoft SQL Server](https://docs.microsoft.com/sql/connect/php/loading-the-php-sql-driver)). For an explanation of extension loading and why we do not add the extensions to php.ini, see the section on [loading the drivers](https://docs.microsoft.com/sql/connect/php/loading-the-php-sql-driver#loading-the-driver-at-php-startup).
# Linux and macOS Installation Tutorial for the Microsoft Drivers for PHP for SQL Server
The following instructions assume a clean environment and show how to install PHP 7.x, the Microsoft ODBC driver, Apache, and the Microsoft drivers for PHP for Microsoft SQL Server on Ubuntu 16.04, 17.10 and 18.04, RedHat 7, Debian 8 and 9, Suse 12, and macOS 10.11, 10.12 and 10.13. These instructions advise installing the drivers using PECL, but you can also download the prebuilt binaries from the [Microsoft Drivers for PHP for Microsoft SQL Server](https://github.com/Microsoft/msphpsql/releases) Github project page and install them following the instructions in [Loading the Microsoft Drivers for PHP for Microsoft SQL Server](https://docs.microsoft.com/sql/connect/php/loading-the-php-sql-driver)). For an explanation of extension loading and why we do not add the extensions to php.ini, see the section on [loading the drivers](https://docs.microsoft.com/sql/connect/php/loading-the-php-sql-driver#loading-the-driver-at-php-startup).
These instruction install PHP 7.2 by default -- see the notes at the beginning of each section to install PHP 7.0 or 7.1.
These instructions install PHP 7.2 by default -- see the notes at the beginning of each section to install PHP 7.0 or 7.1.
## Contents of this page:
- [Installing the drivers on Ubuntu 16.04 and 17.10](#installing-the-drivers-on-ubuntu-1604-and-1710)
- [Installing the drivers on Ubuntu 16.04, 17.10, and 18.04](#installing-the-drivers-on-ubuntu-1604-1710-and-1804)
- [Installing the drivers on Red Hat 7](#installing-the-drivers-on-red-hat-7)
- [Installing the drivers on Debian 8 and 9](#installing-the-drivers-on-debian-8-and-9)
- [Installing the drivers on Suse 12](#installing-the-drivers-on-suse-12)
- [Installing the drivers on macOS El Capitan, Sierra and High Sierra](#installing-the-drivers-on-macos-el-capitan-sierra-and-high-sierra)
## Installing the drivers on Ubuntu 16.04 and 17.10
## Installing the drivers on Ubuntu 16.04, 17.10 and 18.04
> [!NOTE]
> To install PHP 7.0 or 7.1, replace 7.2 with 7.0 or 7.1 in the following commands.
> For Ubuntu 18.04, the step to add the ondrej repository is not required unless
> PHP 7.0 or 7.1 is needed. However, installing PHP 7.0 or 7.1 in Ubuntu 18.04 may
> not work as packages from the ondrej repository come with dependencies that may
> conflict with a base Ubuntu 18.04 install.
### Step 1. Install PHP
```
@ -44,6 +48,7 @@ a2enmod mpm_prefork
a2enmod php7.2
echo "extension=pdo_sqlsrv.so" >> /etc/php/7.2/apache2/conf.d/30-pdo_sqlsrv.ini
echo "extension=sqlsrv.so" >> /etc/php/7.2/apache2/conf.d/20-sqlsrv.ini
exit
```
### Step 5. Restart Apache and test the sample script
```
@ -86,11 +91,11 @@ echo extension=pdo_sqlsrv.so >> `php --ini | grep "Scan for additional .ini file
echo extension=sqlsrv.so >> `php --ini | grep "Scan for additional .ini files" | sed -e "s|.*:\s*||"`/20-sqlsrv.ini
exit
```
An issue in PECL may prevent correct installation of the latest version of the drivers even if you have upgraded GCC. To install, download the packages and compile manually:
An issue in PECL may prevent correct installation of the latest version of the drivers even if you have upgraded GCC. To install, download the packages and compile manually (similar steps for pdo_sqlsrv):
```
pecl download sqlsrv
tar xvzf sqlsrv-5.2.0.tgz
cd sqlsrv-5.2.0/
tar xvzf sqlsrv-5.3.0.tgz
cd sqlsrv-5.3.0/
phpize
./configure --with-php-config=/usr/bin/php-config
make
@ -196,6 +201,7 @@ zypper install apache2 apache2-mod_php7
a2enmod php7
echo "extension=sqlsrv.so" >> /etc/php7/apache2/php.ini
echo "extension=pdo_sqlsrv.so" >> /etc/php7/apache2/php.ini
exit
```
### Step 5. Restart Apache and test the sample script
```
@ -266,47 +272,47 @@ To test this sample script, create a file called testsql.php in your system's do
<?php
$serverName = "yourServername";
$connectionOptions = array(
"Database" => "yourDatabase",
"Uid" => "yourUsername",
"PWD" => "yourPassword"
"database" => "yourDatabase",
"uid" => "yourUsername",
"pwd" => "yourPassword"
);
//Establishes the connection
// Establishes the connection
$conn = sqlsrv_connect($serverName, $connectionOptions);
if( $conn === false ) {
die( FormatErrors( sqlsrv_errors()));
if ($conn === false) {
die(formatErrors(sqlsrv_errors()));
}
//Select Query
$tsql= "SELECT @@Version as SQL_VERSION";
// Select Query
$tsql = "SELECT @@Version AS SQL_VERSION";
//Executes the query
$getResults= sqlsrv_query($conn, $tsql);
// Executes the query
$stmt = sqlsrv_query($conn, $tsql);
//Error handling
if ($getResults == FALSE)
die(FormatErrors(sqlsrv_errors()));
// Error handling
if ($stmt === false) {
die(formatErrors(sqlsrv_errors()));
}
?>
<h1> Results : </h1>
<?php
while ($row = sqlsrv_fetch_array($getResults, SQLSRV_FETCH_ASSOC)) {
echo ($row['SQL_VERSION']);
echo ("<br/>");
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
echo $row['SQL_VERSION'] . PHP_EOL;
}
sqlsrv_free_stmt($getResults);
sqlsrv_free_stmt($stmt);
sqlsrv_close($conn);
function FormatErrors( $errors )
function formatErrors($errors)
{
/* Display errors. */
// Display errors
echo "Error information: <br/>";
foreach ( $errors as $error )
{
echo "SQLSTATE: ".$error['SQLSTATE']."<br/>";
echo "Code: ".$error['code']."<br/>";
echo "Message: ".$error['message']."<br/>";
foreach ($errors as $error) {
echo "SQLSTATE: ". $error['SQLSTATE'] . "<br/>";
echo "Code: ". $error['code'] . "<br/>";
echo "Message: ". $error['message'] . "<br/>";
}
}
?>

View file

@ -47,7 +47,7 @@ For full details on the system requirements for the drivers, see the [system req
On the client machine:
- PHP 7.0.x, 7.1.x, or 7.2.x (7.2.0 and up on Unix, 7.2.1 and up on Windows)
- A Web server such as Internet Information Services (IIS) is required. Your Web server must be configured to run PHP
- [Microsoft ODBC Driver 17][odbc17], [Microsoft ODBC Driver 13][odbc13], or [Microsoft ODBC Driver 11][odbc11]
- [Microsoft ODBC Driver 17, Microsoft ODBC Driver 13, or Microsoft ODBC Driver 11](https://docs.microsoft.com/en-us/sql/connect/odbc/download-odbc-driver-for-sql-server?view=sql-server-2017)
On the server side, Microsoft SQL Server 2008 R2 and above on Windows are supported, as are Microsoft SQL Server 2016 and above on Linux.
@ -86,14 +86,14 @@ The version number may have trailing pre-release version identifiers to indicate
- Build metadata may be denoted by a plus sign followed by 4 or 5 digits, such as `1.2.3-preview+5678` or `1.2.3+5678`. Build metadata does not figure into the precedence order.
## Future Plans
- Expand SQL Server 2016 feature support (example: Always Encrypted)
- Expand SQL Server 2016 feature support (example: Azure Active Directory)
- Add more verification/fundamental tests
- Bug fixes
## Guidelines for Reporting Issues
We appreciate you taking the time to test the driver, provide feedback and report any issues. It would be extremely helpful if you:
- First check the [FAQ](https://github.com/Microsoft/msphpsql/wiki/FAQ)
- First check the [FAQ](https://github.com/Microsoft/msphpsql/wiki/FAQ) for common problems
- Report each issue as a new issue (but check first if it's already been reported)
- Please address the questions in the new issue template and provide scripts, table schema, and/or any details that may help reproduce the problem(s)
@ -106,15 +106,15 @@ Thank you!
**Q:** What's next?
**A:** On March 23, 2018 we released the production release version 5.2.0 of our PHP Driver. We will continue working on our future plans and releasing previews of upcoming releases frequently.
**A:** On July 20, 2018 we released the production release version 5.3.0 of our PHP Driver. We will continue working on our future plans and releasing previews of upcoming releases.
**Q:** Is Microsoft taking pull requests for this project?
**A:** Yes. Please submit pull requests to the **dev** branch and not the **master** branch.
**A:** Yes. Please submit pull requests to the **dev** branch, not the **master** branch.
## License
The Microsoft Drivers for PHP for SQL Server are licensed under the MIT license. See the LICENSE file for more details.
The Microsoft Drivers for PHP for SQL Server are licensed under the MIT license. See the LICENSE file for more details.
## Code of conduct
@ -138,12 +138,6 @@ This project has adopted the Microsoft Open Source Code of Conduct. For more inf
[phpbuild]: https://wiki.php.net/internals/windows/stepbystepbuild
[phpdoc]: http://msdn.microsoft.com/library/dd903047%28SQL.11%29.aspx
[odbc11]: https://www.microsoft.com/download/details.aspx?id=36434
[odbc13]: https://www.microsoft.com/download/details.aspx?id=50420
[odbc17]: https://www.microsoft.com/download/details.aspx?id=56567
[phpdoc]: https://docs.microsoft.com/en-us/sql/connect/php/microsoft-php-driver-for-sql-server?view=sql-server-2017
[PHPMan]: http://php.net/manual/install.unix.php

View file

@ -81,10 +81,10 @@ install:
} Else {
$env:PHP_VERSION=$env:PHP_MAJOR_VER + '.' + $env:PHP_MINOR_VER;
}
- echo Downloading MSODBCSQL 17.1
- echo Downloading MSODBCSQL 17.2
# AppVeyor build works are x64 VMs and 32-bit ODBC driver cannot be installed on it
- ps: (new-object net.webclient).DownloadFile('https://download.microsoft.com/download/E/6/B/E6BFDC7A-5BCD-4C51-9912-635646DA801E/msodbcsql_17.1.0.1_x64.msi', 'c:\projects\msodbcsql_17.1.0.1_x64.msi')
- cmd /c start /wait msiexec /i "c:\projects\msodbcsql_17.1.0.1_x64.msi" /q IACCEPTMSODBCSQLLICENSETERMS=YES ADDLOCAL=ALL
- ps: (new-object net.webclient).DownloadFile('https://download.microsoft.com/download/E/6/B/E6BFDC7A-5BCD-4C51-9912-635646DA801E/en-US/msodbcsql_17.2.0.1_x64.msi', 'c:\projects\msodbcsql_17.2.0.1_x64.msi')
- cmd /c start /wait msiexec /i "c:\projects\msodbcsql_17.2.0.1_x64.msi" /q IACCEPTMSODBCSQLLICENSETERMS=YES ADDLOCAL=ALL
- echo Checking the version of MSODBCSQL
- reg query "HKLM\SOFTWARE\ODBC\odbcinst.ini\ODBC Driver 17 for SQL Server"
- dir %WINDIR%\System32\msodbcsql*.dll

View file

@ -1,3 +1,23 @@
dnl ----------------------------------------------------------------------------------------------------------------------------------
dnl File: config.m4
dnl
dnl Contents: the code that will go into the configure script, indicating options,
dnl external libraries and includes, and what source files are to be compiled.
dnl
dnl Microsoft Drivers 5.3 for PHP for SQL Server
dnl Copyright(c) Microsoft Corporation
dnl All rights reserved.
dnl MIT License
dnl Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the ""Software""),
dnl to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
dnl and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
dnl The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
dnl THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
dnl FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
dnl LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
dnl IN THE SOFTWARE.
dnl ---------------------------------------------------------------------------------------------------------------------------------
PHP_ARG_WITH(pdo_sqlsrv, for pdo_sqlsrv support,
[ --with-pdo_sqlsrv Include pdo_sqlsrv support])

View file

@ -3,7 +3,7 @@
//
// Contents: JScript build configuration used by buildconf.bat
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -3,7 +3,7 @@
//
// Contents: Implements the PDO object for PDO_SQLSRV
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License
@ -43,10 +43,8 @@ const char AttachDBFileName[] = "AttachDbFileName";
const char Authentication[] = "Authentication";
const char ColumnEncryption[] = "ColumnEncryption";
const char ConnectionPooling[] = "ConnectionPooling";
#ifdef _WIN32
const char ConnectRetryCount[] = "ConnectRetryCount";
const char ConnectRetryInterval[] = "ConnectRetryInterval";
#endif // _WIN32
const char Database[] = "Database";
const char Driver[] = "Driver";
const char Encrypt[] = "Encrypt";
@ -109,7 +107,6 @@ struct pdo_txn_isolation_conn_attr_func
static void func( connection_option const* /*option*/, _In_ zval* value_z, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/ TSRMLS_DC );
};
#ifdef _WIN32
struct pdo_int_conn_str_func {
static void func( _In_ connection_option const* option, _In_ zval* value, sqlsrv_conn* /*conn*/, _Out_ std::string& conn_str TSRMLS_DC )
@ -125,7 +122,6 @@ struct pdo_int_conn_str_func {
conn_str += "};";
}
};
#endif // _WIN32
template <unsigned int Attr>
struct pdo_int_conn_attr_func {
@ -243,7 +239,6 @@ const connection_option PDO_CONN_OPTS[] = {
CONN_ATTR_STRING,
column_encryption_set_func::func
},
#ifdef _WIN32
{
PDOConnOptionNames::ConnectRetryCount,
sizeof( PDOConnOptionNames::ConnectRetryCount ),
@ -262,7 +257,6 @@ const connection_option PDO_CONN_OPTS[] = {
CONN_ATTR_INT,
pdo_int_conn_str_func::func
},
#endif // _WIN32
{
PDOConnOptionNames::Database,
sizeof( PDOConnOptionNames::Database ),
@ -1276,7 +1270,7 @@ char * pdo_sqlsrv_dbh_last_id( _Inout_ pdo_dbh_t *dbh, _In_z_ const char *name,
try {
char last_insert_id_query[ LAST_INSERT_ID_QUERY_MAX_LEN ];
char last_insert_id_query[ LAST_INSERT_ID_QUERY_MAX_LEN ] = {'\0'};
if( name == NULL ) {
strcpy_s( last_insert_id_query, sizeof( last_insert_id_query ), LAST_INSERT_ID_QUERY );
}
@ -1300,7 +1294,7 @@ char * pdo_sqlsrv_dbh_last_id( _Inout_ pdo_dbh_t *dbh, _In_z_ const char *name,
sqlsrv_malloc_auto_ptr<SQLWCHAR> wsql_string;
unsigned int wsql_len;
wsql_string = utf16_string_from_mbcs_string( SQLSRV_ENCODING_CHAR, reinterpret_cast<const char*>( last_insert_id_query ), static_cast<unsigned int>( strnlen_s( last_insert_id_query )), &wsql_len );
wsql_string = utf16_string_from_mbcs_string( SQLSRV_ENCODING_CHAR, reinterpret_cast<const char*>( last_insert_id_query ), sizeof(last_insert_id_query), &wsql_len );
CHECK_CUSTOM_ERROR( wsql_string == 0, driver_stmt, SQLSRV_ERROR_QUERY_STRING_ENCODING_TRANSLATE, get_last_error_message() ) {
throw core::CoreException();

View file

@ -3,7 +3,7 @@
//
// Contents: initialization routines for PDO_SQLSRV
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -5,7 +5,7 @@
//
// Copyright Microsoft Corporation
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -3,7 +3,7 @@
//
// Contents: Implements the PDOStatement object for the PDO_SQLSRV
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -3,7 +3,7 @@
//
// Contents: Utility functions used by both connection or statement functions
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -6,7 +6,7 @@
//
// Contents: Declarations for the extension
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -3,7 +3,7 @@
//
// Contents: Version resource
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -6,7 +6,7 @@
// Contents: Contains functions for handling Windows format strings
// and UTF-16 on non-Windows platforms
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -4,7 +4,7 @@
// Contents: Contains functions for handling Windows format strings
// and UTF-16 on non-Windows platforms
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -3,7 +3,7 @@
//
// Contents: Contains functions for handling UTF-16 on non-Windows platforms
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -3,7 +3,7 @@
//
// Contents: Contains functions for handling UTF-16 on non-Windows platforms
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -3,7 +3,7 @@
//
// Contents: Core routines that use connection handles shared between sqlsrv and pdo_sqlsrv
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -3,7 +3,7 @@
//
// Contents: common initialization routines shared by PDO and sqlsrv
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -3,7 +3,7 @@
//
// Contents: Result sets
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License
@ -345,7 +345,8 @@ sqlsrv_error* odbc_get_diag_rec( _In_ sqlsrv_stmt* odbc, _In_ SQLSMALLINT record
SQLWCHAR wnative_message[ SQL_MAX_ERROR_MESSAGE_LENGTH + 1 ];
SQLINTEGER native_code;
SQLSMALLINT wnative_message_len = 0;
SQLSRV_ASSERT(odbc != NULL, "odbc_get_diag_rec: sqlsrv_stmt* odbc was null.");
SQLRETURN r = SQLGetDiagRecW( SQL_HANDLE_STMT, odbc->handle(), record_number, wsql_state, &native_code, wnative_message,
SQL_MAX_ERROR_MESSAGE_LENGTH + 1, &wnative_message_len );
if( !SQL_SUCCEEDED( r ) || r == SQL_NO_DATA ) {
@ -963,7 +964,7 @@ SQLRETURN binary_to_string( _Inout_ SQLCHAR* field_data, _Inout_ SQLLEN& read_so
// to_copy contains the number of bytes to copy, so we divide the number in half (or quarter)
// to get the number of hex digits we can copy
SQLLEN to_copy_hex = to_copy / (2 * extra);
for( int i = 0; i < to_copy_hex; ++i ) {
for( SQLLEN i = 0; i < to_copy_hex; ++i ) {
*h = hex_chars[ (*b & 0xf0) >> 4 ];
h++;
*h = hex_chars[ (*b++ & 0x0f) ];

View file

@ -6,7 +6,7 @@
//
// Contents: Core routines and constants shared by the Microsoft Drivers for PHP for SQL Server
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License
@ -1112,10 +1112,8 @@ const char Driver[] = "Driver";
const char CharacterSet[] = "CharacterSet";
const char ConnectionPooling[] = "ConnectionPooling";
const char ColumnEncryption[] = "ColumnEncryption";
#ifdef _WIN32
const char ConnectRetryCount[] = "ConnectRetryCount";
const char ConnectRetryInterval[] = "ConnectRetryInterval";
#endif // _WIN32
const char Database[] = "Database";
const char Encrypt[] = "Encrypt";
const char Failover_Partner[] = "Failover_Partner";
@ -1168,10 +1166,8 @@ enum SQLSRV_CONN_OPTIONS {
SQLSRV_CONN_OPTION_KEYSTORE_PRINCIPAL_ID,
SQLSRV_CONN_OPTION_KEYSTORE_SECRET,
SQLSRV_CONN_OPTION_TRANSPARENT_NETWORK_IP_RESOLUTION,
#ifdef _WIN32
SQLSRV_CONN_OPTION_CONN_RETRY_COUNT,
SQLSRV_CONN_OPTION_CONN_RETRY_INTERVAL,
#endif // _WIN32
// Driver specific connection options
SQLSRV_CONN_OPTION_DRIVER_SPECIFIC = 1000,

View file

@ -3,7 +3,7 @@
//
// Contents: Core routines that use statement handles shared between sqlsrv and pdo_sqlsrv
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -3,7 +3,7 @@
//
// Contents: Implementation of PHP streams for reading SQL Server data
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License
@ -26,7 +26,7 @@ namespace {
int sqlsrv_stream_close( _Inout_ php_stream* stream, int /*close_handle*/ TSRMLS_DC )
{
sqlsrv_stream* ss = static_cast<sqlsrv_stream*>( stream->abstract );
SQLSRV_ASSERT( ss != NULL, "sqlsrv_stream_close: sqlsrv_stream* ss was null." );
SQLSRV_ASSERT( ss != NULL && ss->stmt != NULL, "sqlsrv_stream_close: sqlsrv_stream* ss was null." );
// free the stream resources in the Zend engine
php_stream_free( stream, PHP_STREAM_FREE_RELEASE_STREAM );
@ -52,7 +52,7 @@ size_t sqlsrv_stream_read( _Inout_ php_stream* stream, _Out_writes_bytes_(count)
sqlsrv_malloc_auto_ptr<char> temp_buf;
sqlsrv_stream* ss = static_cast<sqlsrv_stream*>( stream->abstract );
SQLSRV_ASSERT( ss != NULL, "sqlsrv_stream_read: sqlsrv_stream* ss is NULL." );
SQLSRV_ASSERT( ss != NULL && ss->stmt != NULL, "sqlsrv_stream_read: sqlsrv_stream* ss is NULL." );
try {

View file

@ -5,7 +5,7 @@
//
// Comments: Mostly error handling and some type handling
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -4,7 +4,7 @@
// Contents: Contains functions for handling Windows format strings
// and UTF-16 on non-Windows platforms
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -4,7 +4,7 @@
// Contents: Contains a portable abstraction for interlocked, atomic
// operations on int32_t and pointer types.
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -4,7 +4,7 @@
// Contents: Contains a portable abstraction for interlocked, atomic
// operations on int32_t and pointer types.
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -4,7 +4,7 @@
// Contents: Contains a portable abstraction for interlocked, singly
// linked list.
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -3,7 +3,7 @@
//
// Contents: Contains portable classes for localization
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -5,7 +5,7 @@
// Must be included in one c/cpp file per binary
// A build error will occur if this inclusion policy is not followed
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -20,7 +20,7 @@
// pecuniary loss) arising out of the use of or inability to use
// this SDK, even if Microsoft has been advised of the possibility
// of such damages.
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -3,7 +3,7 @@
//
// Contents: Contains the minimal definitions to build on non-Windows platforms
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -1,7 +1,7 @@
//---------------------------------------------------------------------------------------------------------------------------------
// File: typedefs_for_linux.h
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -4,7 +4,7 @@
// File: version.h
// Contents: Version number constants
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License
@ -26,12 +26,12 @@
// Increase Minor with backward compatible new functionalities and API changes.
// Increase Patch for backward compatible fixes.
#define SQLVERSION_MAJOR 5
#define SQLVERSION_MINOR 2
#define SQLVERSION_PATCH 1
#define SQLVERSION_MINOR 3
#define SQLVERSION_PATCH 0
#define SQLVERSION_BUILD 0
// For previews, set this constant to 1. Otherwise, set it to 0
#define PREVIEW 1
#define PREVIEW 0
#define SEMVER_PRERELEASE
// Semantic versioning build metadata, build meta data is not counted in precedence order.

View file

@ -3,7 +3,7 @@
//
// Contents: include for definition of Windows types for non-Windows platforms
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -4,7 +4,7 @@
// Contents: This module defines helper functions to prevent
// integer overflow bugs.
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -3,7 +3,7 @@
//
// Contents: Contains the minimal definitions to build on non-Windows platforms
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -3,7 +3,7 @@
//
// Contents: Contains the minimal definitions to build on non-Windows platforms
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -1,3 +1,23 @@
dnl ----------------------------------------------------------------------------------------------------------------------------------
dnl File: config.m4
dnl
dnl Contents: the code that will go into the configure script, indicating options,
dnl external libraries and includes, and what source files are to be compiled.
dnl
dnl Microsoft Drivers 5.3 for PHP for SQL Server
dnl Copyright(c) Microsoft Corporation
dnl All rights reserved.
dnl MIT License
dnl Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the ""Software""),
dnl to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
dnl and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
dnl The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
dnl THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
dnl FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
dnl LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
dnl IN THE SOFTWARE.
dnl ---------------------------------------------------------------------------------------------------------------------------------
PHP_ARG_ENABLE(sqlsrv, whether to enable sqlsrv functions,
[ --disable-sqlsrv Disable sqlsrv functions], yes)

View file

@ -3,7 +3,7 @@
//
// Contents: JScript build configuration used by buildconf.bat
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -3,7 +3,7 @@
//
// Contents: Routines that use connection handles
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License
@ -95,7 +95,6 @@ struct bool_conn_str_func {
}
};
#ifdef _WIN32
struct int_conn_str_func {
static void func( _In_ connection_option const* option, _In_ zval* value, sqlsrv_conn* /*conn*/, _Out_ std::string& conn_str TSRMLS_DC )
@ -111,7 +110,6 @@ struct int_conn_str_func {
conn_str += "};";
}
};
#endif // _WIN32
template <unsigned int Attr>
struct int_conn_attr_func {
@ -188,10 +186,8 @@ const char Authentication[] = "Authentication";
const char CharacterSet[] = "CharacterSet";
const char ColumnEncryption[] = "ColumnEncryption";
const char ConnectionPooling[] = "ConnectionPooling";
#ifdef _WIN32
const char ConnectRetryCount[] = "ConnectRetryCount";
const char ConnectRetryInterval[] = "ConnectRetryInterval";
#endif // _WIN32
const char Database[] = "Database";
const char DateAsString[] = "ReturnDatesAsStrings";
const char Driver[] = "Driver";
@ -324,7 +320,6 @@ const connection_option SS_CONN_OPTS[] = {
CONN_ATTR_STRING,
column_encryption_set_func::func
},
#ifdef _WIN32
{
SSConnOptionNames::ConnectRetryCount,
sizeof( SSConnOptionNames::ConnectRetryCount ),
@ -343,7 +338,6 @@ const connection_option SS_CONN_OPTS[] = {
CONN_ATTR_INT,
int_conn_str_func::func
},
#endif // _WIN32
{
SSConnOptionNames::Database,
sizeof( SSConnOptionNames::Database ),

View file

@ -2,7 +2,7 @@
// File: init.cpp
// Contents: initialization routines for the extension
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -8,7 +8,7 @@
//
// Comments: Also contains "internal" declarations shared across source files.
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -3,7 +3,7 @@
//
// Contents: Routines that use statement handles
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -3,7 +3,7 @@
//
// Contents: Version resource
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -5,7 +5,7 @@
//
// Comments: Mostly error handling and some type handling
//
// Microsoft Drivers 5.2 for PHP for SQL Server
// Microsoft Drivers 5.3 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License

View file

@ -8,30 +8,6 @@
*/
//
// looks like an additional file (in addition to pdo_test_base.inc) may be needed for these PHPTs
// to be runnable from the MSSQL teams' internal proprietary test running system
//
function IsAEQualified($conn)
{
$msodbcsql_ver = $conn->getAttribute(PDO::ATTR_CLIENT_VERSION)["DriverVer"];
$msodbcsql_maj = explode(".", $msodbcsql_ver)[0];
if ($msodbcsql_maj < 17) {
return false;
}
require 'MsSetup.inc';
if ($daasMode) {
// running against Azure
return true;
}
// if not Azure, check the server version
$server_ver = $conn->getAttribute(PDO::ATTR_SERVER_VERSION);
if (explode('.', $server_ver)[0] < 13)
return false;
return true;
}
// TO BE DELETED
function connect($options=array())
{
@ -40,7 +16,7 @@ function connect($options=array())
// simply use $databaseName from MsSetup.inc to facilitate testing in Azure,
// which does not support switching databases
require 'MsSetup.inc';
$conn = new PDO( "sqlsrv:Server=$server;database=$databaseName;ConnectionPooling=false;" , $uid, $pwd, $options);
$conn = new PDO( "sqlsrv:Server=$server;database=$databaseName;Driver=$driver;ConnectionPooling=false;" , $uid, $pwd, $options);
$conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
return $conn;
}
@ -58,138 +34,6 @@ function connect($options=array())
}
}
/**
* Connect to the database specified in MsSetup.inc; Column Encryption keywords automatically added when $keystore is not none
* @param string $keywords : string to append to the dsn string in PDO::_construct
* @param array $options : attributes to pass to PDO::_construct
* @param bool $disableCE : flag for disabling column encryption even when keystore is NOT none
* for testing fetching encrypted data when connection column encryption is off
* @return PDO connection object
*/
function ae_connect( $keywords='', $options=array(), $disableCE = false )
{
try
{
// simply use $databaseName from MsSetup.inc to facilitate testing in Azure,
// which does not support switching databases
require 'MsSetup.inc';
$dsn = "sqlsrv:Server=$server;database=$databaseName;ConnectionPooling=false;";
if ( $keystore != "none" && !$disableCE )
{
$dsn .= "ColumnEncryption=Enabled;";
}
if ( $keystore == "ksp" && !$disableCE )
{
require( 'AE_Ksp.inc' );
$ksp_path = getKSPPath();
$dsn .= "CEKeystoreProvider=$ksp_path;CEKeystoreName=$ksp_name;CEKeystoreEncryptKey=$encrypt_key;";
}
if ( $keywords )
{
$dsn .= $keywords;
}
$conn = new PDO( $dsn, $uid, $pwd, $options );
$conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
return $conn;
}
catch( PDOException $e )
{
var_dump( $e );
exit;
}
catch(Exception $e)
{
var_dump( $e );
exit;
}
}
/**
* @return string CEK name depending on the connection keywords
*/
function getCekName()
{
require 'MsSetup.inc';
$cekName = '';
switch ( $keystore ) {
case "none":
$cekName = '';
break;
case "win":
$cekName = 'AEColumnKey';
break;
case "ksp":
$cekName = 'CustomCEK';
break;
case "akv":
$cekName = 'AKVColumnKey';
break;
default:
echo "getCekName: Invalid keystore name.\n";
}
return $cekName;
}
/**
* class for encapsulating column metadata needed for creating a table
*/
class columnMeta {
public $colName;
public $dataType; //a string that includes the size of the type if necessary (e.g., decimal(10,5))
public $encType; //randomized or deterministic; default is deterministic
public $options; //a string that is null by default (e.g. NOT NULL Identity (1,1) )
function __construct( $dataType, $colName = null, $options = null, $encType = "deterministic" )
{
if ( is_null( $colName ))
{
$this->colName = get_default_colname( $dataType );
}
else
{
$this->colName = $colName;
}
$this->dataType = $dataType;
$this->encType = $encType;
$this->options = $options;
}
/**
* @return string column definition for creating a table
*/
function getColDef()
{
require 'MsSetup.inc';
$append = " ";
// an identity column is not encrypted because a select query with identity column as the where clause is often run and the user want to have to bind parameter every time
if ( $keystore != "none" && stripos( $this->options, "identity" ) === false )
{
$cekName = getCekName();
if ( stripos( $this->dataType, "char" ) !== false )
$append .= "COLLATE Latin1_General_BIN2 ";
$append .= sprintf( "ENCRYPTED WITH (ENCRYPTION_TYPE = %s, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = $cekName) ", $this->encType );
}
$append .= $this->options;
$colDef = "[" . $this->colName . "] " . $this->dataType . $append;
return $colDef;
}
}
/**
* @return string default column name when a name is not provided in the columnMeta class
*/
function get_default_colname( $dataType )
{
$colName = "c_" . str_replace( ",", "_", str_replace( "(", "_", $dataType ));
$colName = rtrim( $colName, ")" );
return $colName;
}
/**
* Create a table
* @param object $conn : PDO connection object

View file

@ -13,10 +13,6 @@
// to be runnable from the MSSQL teams' internal proprietary test running system
//
const KSP_NAME = 'MyCustomKSPName';
const ENCRYPT_KEY = 'LPKCWVD07N3RG98J0MBLG4H2';
const KSP_TEST_TABLE = 'CustomKSPTestTable';
function isAEQualified($conn)
{
$msodbcsql_ver = $conn->getAttribute(PDO::ATTR_CLIENT_VERSION)["DriverVer"];
@ -52,7 +48,7 @@ function connect($keywords = '', $options=array(), $errmode = PDO::ERRMODE_EXCEP
// simply use $databaseName from MsSetup.inc to facilitate testing in Azure,
// which does not support switching databases
require("MsSetup.inc");
$dsn = getDSN($server, $databaseName, $keywords, $disableCE);
$dsn = getDSN($server, $databaseName, $driver, $keywords, $disableCE);
$conn = new PDO($dsn, $uid, $pwd, $options);
if ($errmode == PDO::ERRMODE_EXCEPTION || $errmode == PDO::ERRMODE_WARNING || $errmode == PDO::ERRMODE_SILENT) {
$conn->setAttribute(PDO::ATTR_ERRMODE, $errmode);
@ -76,7 +72,7 @@ function connect($keywords = '', $options=array(), $errmode = PDO::ERRMODE_EXCEP
* @param bool $disableCE : flag for disabling column encryption even when keystore is NOT none
* @return string dsn string used for PDO constructor
*/
function getDSN($sqlsrvserver, $database, $keywords = '', $disableCE = false)
function getDSN($sqlsrvserver, $database, $driver = null, $keywords = '', $disableCE = false)
{
require("MsSetup.inc");
$dsn = "";
@ -89,6 +85,9 @@ function getDSN($sqlsrvserver, $database, $keywords = '', $disableCE = false)
if ($database) {
$dsn .= "database=$database;";
}
if (!is_null($driver)) {
$dsn .= "driver=$driver;";
}
if ($keystore != "none" && !$disableCE) {
$dsn .= "ColumnEncryption=Enabled;";
}

View file

@ -18,7 +18,6 @@ if (isset($_ENV['MSSQL_SERVER']) || isset($_ENV['MSSQL_USER']) || isset($_ENV['M
$uid = 'TARGET_USERNAME';
$pwd = 'TARGET_PASSWORD';
$databaseName = 'TARGET_DATABASE';
$DriverName = "ODBC Driver 11 for SQL Server";
}
$adServer = 'TARGET_AD_SERVER';
@ -27,13 +26,12 @@ $adUser = 'TARGET_AD_USERNAME';
$adPassword = 'TARGET_AD_PASSWORD';
$driverType = true;
$PhpDriver = "ODBC Driver 11 for SQL Server";
$driver = "ODBC Driver 17 for SQL Server";
$tableName = 'pdo_test_table';
$tableIndex = 'php_test_table_idx';
$procName = 'php_test_proc';
$fileName = 'php_test_file.dat';
$dsn = "odbc:Driver={$DriverName};Server=$server";
$connectionOptions = array();
$daasMode = false;
$marsMode = true;

View file

@ -1,76 +1,77 @@
--TEST--
PDO - Large Column Name Test
--DESCRIPTION--
Verifies that long column names are supported (up to 128 chars).
--ENV--
PHPT_EXEC=true
--SKIPIF--
<?php require('skipif.inc'); ?>
--FILE--
--TEST--
PDO - Large Column Name Test
--DESCRIPTION--
Verifies that long column names are supported (up to 128 chars).
--ENV--
PHPT_EXEC=true
--SKIPIF--
<?php require('skipif.inc'); ?>
--FILE--
<?php
include 'MsCommon.inc';
require_once('MsCommon.inc');
function LargeColumnNameTest($columnName, $expectfail)
function largeColumnNameTest($columnName)
{
include 'MsSetup.inc';
Setup();
$conn = Connect();
$conn = connect();
$tableName = "LargeColumnNameTest";
$tableName = "largeColumnNameTest";
DropTable($conn, $tableName);
dropTable($conn, $tableName);
$conn->query("CREATE TABLE [$tableName] ([$columnName] int)");
$conn->query("INSERT INTO [$tableName] ([$columnName]) VALUES (5)");
$stmt = $conn->query("SELECT * from [$tableName]");
if ( null == $stmt )
{
if (!$expectfail)
FatalError("Possible regression: Unable to retrieve inserted value.");
}
DropTable($conn, $tableName);
dropTable($conn, $tableName);
}
//--------------------------------------------------------------------
// Repro
// repro
//
//--------------------------------------------------------------------
function Repro()
function repro()
{
$testName = "PDO - Large Column Name Test";
StartTest($testName);
startTest($testName);
// The maximum size of a column name is 128 characters
$maxlen = 128;
$columnName = str_repeat('A', $maxlen);
$columnName = "a";
try
{
for ($a = 1; $a <= 128; $a++)
{
LargeColumnNameTest($columnName, $a > 128);
$columnName .= "A";
}
}
catch (Exception $e)
{
echo $e->getMessage();
try {
largeColumnNameTest($columnName);
} catch (Exception $e) {
echo "Possible regression: Unable to retrieve inserted value\n";
print_r($e->getMessage());
echo "\n";
}
// Now add another character to the name
$columnName .= 'A';
try {
largeColumnNameTest($columnName);
} catch (Exception $e) {
// Expects to fail
$expected = 'is too long. Maximum length is 128.';
if (strpos($e->getMessage(), $expected) === false) {
print_r($e->getMessage());
echo "\n";
}
}
EndTest($testName);
endTest($testName);
}
Repro();
?>
--EXPECT--
Test "PDO - Large Column Name Test" completed successfully.
repro();
?>
--EXPECT--
Test "PDO - Large Column Name Test" completed successfully.

View file

@ -8,69 +8,70 @@ PHPT_EXEC=true
<?php require('skipif.inc'); ?>
--FILE--
<?php
require_once('MsCommon.inc');
include 'MsCommon.inc';
function LargeColumnNameTest($columnName, $expectfail)
function largeColumnNameTest($columnName)
{
include 'MsSetup.inc';
Setup();
$conn = Connect();
$conn = connect();
$tableName = "LargeColumnNameTest";
$tableName = "largeColumnNameTest";
DropTable($conn, $tableName);
dropTable($conn, $tableName);
$conn->query("CREATE TABLE [$tableName] ([$columnName] int)");
$conn->query("INSERT INTO [$tableName] ([$columnName]) VALUES (5)");
$stmt = $conn->query("SELECT * from [$tableName]");
if ( null == $stmt )
{
if (!$expectfail)
FatalError("Possible regression: Unable to retrieve inserted value.");
}
DropTable($conn, $tableName);
dropTable($conn, $tableName);
}
//--------------------------------------------------------------------
// Repro
// repro
//
//--------------------------------------------------------------------
function Repro()
function repro()
{
$testName = "PDO - Large Column Name Test";
StartTest($testName);
startTest($testName);
$columnName = "是";
// The maximum size of a column name is 128 characters
$maxlen = 128;
$columnName = str_repeat('是', $maxlen);
try
{
for ($a = 1; $a <= 128; $a++)
{
LargeColumnNameTest($columnName, $a > 128);
$columnName .= "是";
try {
largeColumnNameTest($columnName);
} catch (Exception $e) {
echo "Possible regression: Unable to retrieve inserted value\n";
print_r($e->getMessage());
echo "\n";
}
// Now add another character to the name
$columnName .= '是';
try {
largeColumnNameTest($columnName);
} catch (Exception $e) {
// Expects to fail
$expected = 'is too long. Maximum length is 128.';
if (strpos($e->getMessage(), $expected) === false) {
print_r($e->getMessage());
echo "\n";
}
}
catch (Exception $e)
{
echo $e->getMessage();
}
EndTest($testName);
endTest($testName);
}
Repro();
repro();
?>
--EXPECT--
Test "PDO - Large Column Name Test" completed successfully.

View file

@ -15,7 +15,7 @@ try {
// Invalid connection attempt => errors are expected
$serverName="InvalidServerName";
$dsn = getDSN($serverName, $databaseName);
$dsn = getDSN($serverName, $databaseName, $driver);
$conn1 = new PDO($dsn, $uid, $pwd, $connectionOptions);
if ($conn1) {
printf("Invalid connection attempt should have failed.\n");

View file

@ -6,6 +6,15 @@ This test assumes the default odbcinst.ini has not been modified.
<?php if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') die("Skipped: Test for Linux and Mac"); ?>
--FILE--
<?php
function findODBCDriver($content, $lines_to_add)
{
require_once('MsSetup.inc');
$command = "odbcinst -q -d -n '$driver'";
$info = shell_exec($command);
return str_replace($info, $info.$lines_to_add, $content);
}
$lines_to_add="CPTimeout=5\n[ODBC]\nPooling=Yes\n";
//get default odbcinst.ini location
@ -18,8 +27,8 @@ copy( $odbcinst_ini, $custom_odbcinst_ini);
//enable pooling by modifying the odbcinst.ini file
$current = file_get_contents($custom_odbcinst_ini);
$current.=$lines_to_add;
file_put_contents($custom_odbcinst_ini, $current);
$new_content = findODBCDriver($current, $lines_to_add);
file_put_contents($custom_odbcinst_ini, $new_content);
//Creating a new php process, because for changes in odbcinst.ini file to affect pooling, drivers must be reloaded.
//Also setting the odbcini path to the current folder for the same process.

View file

@ -1,10 +1,10 @@
<?php
include 'MsSetup.inc';
$conn1 = new PDO("sqlsrv:Server=$server; database=$databaseName", $uid, $pwd);
$conn1 = new PDO("sqlsrv:Server=$server; database=$databaseName; driver=$driver", $uid, $pwd);
$connId1 = ConnectionID($conn1);
$conn1 = null;
$conn2 = new PDO("sqlsrv:Server=$server; database=$databaseName", $uid, $pwd);
$conn2 = new PDO("sqlsrv:Server=$server; database=$databaseName; driver=$driver", $uid, $pwd);
$connId2 = ConnectionID($conn2);
$conn2 = null;

View file

@ -12,6 +12,8 @@ try {
// Create table
$tableName = 'bindParams';
dropTable($conn, $tableName);
$sql = "CREATE TABLE $tableName (ID TINYINT, SID CHAR(5))";
$stmt = $conn->exec($sql);

View file

@ -12,6 +12,8 @@ try {
// Create table
$tableName = 'pdo_040test';
dropTable($conn, $tableName);
// common function insertRow() is not used here since the test deliberately
// executes an invalid insertion statement
// thus it's not necessary to create an encrypted column for testing column encryption

View file

@ -13,7 +13,7 @@ require_once("MsCommon_mid-refactor.inc");
try {
echo "Testing a connection with ATTR_PERSISTENT...\n";
// setting PDO::ATTR_PERSISTENT in PDO constructor returns an exception
$dsn = getDSN($server, $databaseName);
$dsn = getDSN($server, $databaseName, $driver);
$attr = array(PDO::ATTR_PERSISTENT => true);
$conn = new PDO($dsn, $uid, $pwd, $attr);
//free the connection

View file

@ -10,7 +10,7 @@ require_once("MsSetup.inc");
require_once("MsCommon_mid-refactor.inc");
try {
echo "Testing a connection with ATTR_PREFETCH before ERRMODE_EXCEPTION...\n";
$dsn = getDSN($server, $databaseName);
$dsn = getDSN($server, $databaseName, $driver);
$attr = array(PDO::ATTR_PREFETCH => true, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
$conn = new PDO($dsn, $uid, $pwd, $attr);

View file

@ -7,7 +7,7 @@ do not need to be encrypted
--ENV--
PHPT_EXEC=true
--SKIPIF--
<?php require('skipif_unix.inc'); ?>
<?php require('skipif_mid-refactor.inc'); ?>
--FILE--
<?php
require_once("MsSetup.inc");

View file

@ -1,7 +1,7 @@
--TEST--
Test client ID/secret credentials for Azure Key Vault for Always Encrypted.
--SKIPIF--
<?php require('skipif_mid-refactor.inc'); ?>
<?php require('skipif_not_akv.inc'); ?>
--FILE--
<?php
require_once('pdo_ae_azure_key_vault_common.php');

View file

@ -1,7 +1,7 @@
--TEST--
Test connection keywords for Azure Key Vault for Always Encrypted.
--SKIPIF--
<?php require('skipif_mid-refactor.inc'); ?>
<?php require('skipif_not_akv.inc'); ?>
--FILE--
<?php
require_once('pdo_ae_azure_key_vault_common.php');

View file

@ -1,7 +1,7 @@
--TEST--
Test username/password credentials for Azure Key Vault for Always Encrypted.
--SKIPIF--
<?php require('skipif_mid-refactor.inc'); ?>
<?php require('skipif_not_akv.inc'); ?>
--FILE--
<?php
require_once('pdo_ae_azure_key_vault_common.php');

View file

@ -29,6 +29,7 @@ $colMetaArr = array("c1_int" => "int",
createTable($conn, $tbname, $colMetaArr);
// Create a Store Procedure
$spname = 'selectAllColumns';
dropProc($conn, $spname);
$spSql = "CREATE PROCEDURE $spname (
@c1_int int OUTPUT, @c2_smallint smallint OUTPUT,
@c3_tinyint tinyint OUTPUT, @c4_bit bit OUTPUT,

View file

@ -1,7 +1,7 @@
--TEST--
Test new connection keyword ColumnEncryption
--SKIPIF--
<?php require('skipif_unix.inc'); ?>
<?php require('skipif_mid-refactor.inc'); ?>
--FILE--
<?php
require_once("MsSetup.inc");

View file

@ -161,7 +161,11 @@ try {
echo $rowcount." rows in result set.\n";
} catch (PDOException $e) {
echo "Error executing statement 6.\n";
print_r($e->getMessage());
$err = $e->getMessage();
if (strpos($err, 'SQLSTATE[08S02]')===false or (strpos($err, 'TCP Provider')===false and strpos($err, 'SMux Provider')===false)) {
echo "Error: Wrong error message.\n";
print_r($err);
}
}
unset($conn);
@ -200,14 +204,18 @@ try {
}
} catch (PDOException $e) {
echo "Error executing statement 8.\n";
print_r($e->getMessage());
$err = $e->getMessage();
if (strpos($err, 'SQLSTATE[IMSSP]')===false or strpos($err, 'The connection cannot process this operation because there is a statement with pending results')===false) {
echo "Error: Wrong error message.\n";
print_r($err);
}
}
unset($conn);
unset($conn_break);
?>
--EXPECTREGEX--
--EXPECT--
Statement 1 successful.
16 rows in result set.
Statement 2 successful.
@ -219,7 +227,5 @@ Statement 4 successful.
Statement 5 successful.
-1 rows in result set.
Error executing statement 6.
SQLSTATE\[08S02\]: \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: An existing connection was forcibly closed by the remote host.
Statement 7 successful.
Error executing statement 8.
SQLSTATE\[IMSSP\]: The connection cannot process this operation because there is a statement with pending results. To make the connection available for other queries, either fetch all results or cancel or free the statement. For more information, see the product documentation about the MultipleActiveResultSets connection option.

View file

@ -1,8 +1,7 @@
--TEST--
Test the connection resiliency keywords ConnectRetryCount and ConnectRetryInterval and their ranges of acceptable values
--SKIPIF--
<?php require('skipif_unix.inc');
require('skipif_version_less_than_2k14.inc'); ?>
<?php require('skipif_version_less_than_2k14.inc'); ?>
--FILE--
<?php
require_once( "MsSetup.inc" );
@ -70,15 +69,15 @@ catch( PDOException $e )
Connected successfully on first attempt.
Connected successfully on second attempt.
Could not connect on third attempt.
SQLSTATE\[08001\]: \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryCount'
SQLSTATE\[08001\]: (\[unixODBC\]|)\[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryCount'
Could not connect on fourth attempt.
SQLSTATE\[08001\]: \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryInterval'
SQLSTATE\[08001\]: (\[unixODBC\]|)\[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryInterval'
Could not connect on fifth attempt.
SQLSTATE\[08001\]: \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryCount'
SQLSTATE\[08001\]: (\[unixODBC\]|)\[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryCount'
Could not connect on sixth attempt.
SQLSTATE\[08001\]: \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryCount'
SQLSTATE\[08001\]: (\[unixODBC\]|)\[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryCount'
Could not connect on seventh attempt.
SQLSTATE\[08001\]: \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryInterval'
SQLSTATE\[08001\]: (\[unixODBC\]|)\[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryInterval'
Could not connect on eighth attempt.
SQLSTATE\[IMSSP\]: The DSN string ended unexpectedly.
Could not connect on ninth attempt.

View file

@ -190,7 +190,12 @@ try
}
catch ( PDOException $e )
{
print_r( $e->getMessage() );
echo "Transaction failed.\n";
$err = $e->getMessage();
if (strpos($err, 'SQLSTATE[08S02]')===false or (strpos($err, 'TCP Provider')===false and strpos($err, 'SMux Provider')===false)) {
echo "Error: Wrong error message.\n";
print_r($err);
}
}
// This try catch block prevents an Uncaught PDOException error that occurs
@ -201,17 +206,20 @@ try
}
catch ( PDOException $e )
{
print_r( $e->getMessage() );
$err = $e->getMessage();
if (strpos($err, 'SQLSTATE[08S01]')===false or strpos($err, 'Communication link failure')===false) {
echo "Error: Wrong error message.\n";
print_r($err);
}
}
$conn_break = null;
?>
--EXPECTREGEX--
--EXPECT--
Statement 1 prepared.
Statement 1 executed.
Transaction begun.
Transaction was committed.
Transaction begun.
SQLSTATE\[08S02\]: \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: An existing connection was forcibly closed by the remote host.
SQLSTATE\[08S01\]: \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Communication link failure
Transaction failed.

View file

@ -40,7 +40,11 @@ try
catch( PDOException $e )
{
echo "Error executing statement 1.\n";
print_r( $e->getMessage() );
$err = $e->getMessage();
if (strpos($err, 'SQLSTATE[08S02]')===false or (strpos($err, 'TCP Provider')===false and strpos($err, 'SMux Provider')===false)) {
echo "Error: Wrong error message.\n";
print_r($err);
}
}
$conn = null;
@ -82,7 +86,6 @@ $conn_break = null;
DropTables( $server, $uid, $pwd, $tableName1, $tableName2 );
?>
--EXPECTREGEX--
--EXPECT--
Error executing statement 1.
SQLSTATE\[08S02\]: \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: An existing connection was forcibly closed by the remote host.
Query successfully executed.

View file

@ -4,6 +4,7 @@ UTF-8 connection strings
<?php require('skipif_mid-refactor.inc'); ?>
--FILE--
<?php
require_once("MsSetup.inc");
require_once("MsCommon_mid-refactor.inc");
$server = 'localhost';
@ -11,7 +12,7 @@ $databaseName = 'test';
$uid = 'sa';
$pwd = 'Sunshine4u';
$dsn = getDSN($server, $databaseName);
$dsn = getDSN($server, $databaseName, $driver);
// test an invalid connection credentials
$c = new PDO($dsn, $uid, $pwd);

View file

@ -0,0 +1,20 @@
<?php
if (!extension_loaded("pdo") || !extension_loaded('pdo_sqlsrv')) {
die("PDO driver cannot be loaded; skipping test.\n");
}
require_once("MsSetup.inc");
if ($driver != "ODBC Driver 17 for SQL Server") {
// the testing is not set to use ODBC 17
die("skip - AE feature not supported in the current environment.");
}
require_once("MsCommon_mid-refactor.inc");
$dsn = getDSN($server, null);
$conn = new PDO($dsn, $uid, $pwd);
if (! $conn) {
echo("Error: could not connect during SKIPIF!");
} elseif (!isAEQualified($conn)) {
die("skip - AE feature not supported in the current environment.");
}

View file

@ -1,6 +1,4 @@
<?php
if ( !( strtoupper( substr( php_uname( 's' ),0,3 ) ) === 'WIN' ) ) die( "Skip Test on windows only." );
if (!extension_loaded("pdo_sqlsrv")) {
die("skip Extension not loaded");
}

View file

@ -1,10 +1,14 @@
<?php
if ( !( strtoupper( substr( php_uname( 's' ),0,3 ) ) === 'WIN' ) ) die( "Skip Test on windows only." );
// For connection resiliency, must check that
// 1. Either running Windows, or ODBC driver 17.2 or greater on unix
// 2. Either SQL Server version is 2014 or greater, or using Azure
if (!extension_loaded("pdo_sqlsrv")) {
die("skip Extension not loaded");
}
$is_win = ( strtoupper( substr( php_uname( 's' ),0,3 ) ) === 'WIN' );
require_once( "MsSetup.inc" );
$conn = new PDO( "sqlsrv:server = $server ;", $uid, $pwd );
@ -12,17 +16,30 @@ if ($conn === false) {
die( "skip Could not connect during SKIPIF." );
}
// Get SQL Server Version
$stmt = $conn->query( "SELECT @@VERSION" );
if ($stmt) {
$ver_string = $stmt->fetch(PDO::FETCH_NUM)[0];
} else {
die( "skip Could not fetch SQL Server version during SKIPIF.");
$msodbcsql_ver = $conn->getAttribute(PDO::ATTR_CLIENT_VERSION)["DriverVer"];
$msodbcsql_maj = explode(".", $msodbcsql_ver)[0];
$msodbcsql_min = explode(".", $msodbcsql_ver)[1];
if (!$is_win) {
if ($msodbcsql_maj < 17 or $msodbcsql_min < 2) {
die("skip Unsupported ODBC driver version");
}
}
$version = explode(' ', $ver_string);
// Get SQL Server Version
// Exclude this check if running on Azure
if (!$daasMode) {
$stmt = $conn->query( "SELECT @@VERSION" );
if ($stmt) {
$ver_string = $stmt->fetch(PDO::FETCH_NUM)[0];
} else {
die( "skip Could not fetch SQL Server version during SKIPIF.");
}
if ($version[3] < '2014') {
die("skip Wrong version of SQL Server, 2014 or later required");
$version = explode(' ', $ver_string);
if ($version[3] < '2014') {
die("skip Wrong version of SQL Server, 2014 or later required");
}
}
?>

View file

@ -1,10 +1,14 @@
<?php
if ( !( strtoupper( substr( php_uname( 's' ),0,3 ) ) === 'WIN' ) ) die( "Skip Test on windows only." );
// For Azure ActiveDirectory, must check that
// 1. Either running Windows, or ODBC driver 17 or greater on unix
// 2. Either SQL Server version is 2016 or greater, or using Azure
if (!extension_loaded("pdo_sqlsrv")) {
die("skip Extension not loaded");
}
$is_win = ( strtoupper( substr( php_uname( 's' ),0,3 ) ) === 'WIN' );
require_once( "MsSetup.inc" );
$conn = new PDO( "sqlsrv:server = $server ;", $uid, $pwd );
@ -12,17 +16,30 @@ if ($conn === false) {
die( "skip Could not connect during SKIPIF." );
}
// Get SQL Server Version
$stmt = $conn->query( "SELECT @@VERSION" );
if ($stmt) {
$ver_string = $stmt->fetch(PDO::FETCH_NUM)[0];
} else {
die( "skip Could not fetch SQL Server version during SKIPIF.");
$msodbcsql_ver = $conn->getAttribute(PDO::ATTR_CLIENT_VERSION)["DriverVer"];
$msodbcsql_maj = explode(".", $msodbcsql_ver)[0];
$msodbcsql_min = explode(".", $msodbcsql_ver)[1];
if (!$is_win) {
if ($msodbcsql_maj < 17) {
die("skip Unsupported ODBC driver version");
}
}
$version = explode(' ', $ver_string);
// Get SQL Server Version
// Exclude this check if running on Azure
if (!$daasMode) {
$stmt = $conn->query( "SELECT @@VERSION" );
if ($stmt) {
$ver_string = $stmt->fetch(PDO::FETCH_NUM)[0];
} else {
die( "skip Could not fetch SQL Server version during SKIPIF.");
}
if ($version[3] < '2016') {
die("skip Wrong version of SQL Server, 2016 or later required");
$version = explode(' ', $ver_string);
if ($version[3] < '2016') {
die("skip Wrong version of SQL Server, 2016 or later required");
}
}
?>

View file

@ -1,36 +1,49 @@
--TEST--
retrieval of names of column master key and column encryption key generated in the database setup
--SKIPIF--
<?php require('skipif_unix.inc'); ?>
--FILE--
<?php
sqlsrv_configure( 'WarningsReturnAsErrors', 0 );
sqlsrv_configure( 'LogSeverity', SQLSRV_LOG_SEVERITY_ALL );
require( 'MsCommon.inc' );
$conn = Connect();
if (IsAEQualified($conn)){
$query = "SELECT name FROM sys.column_master_keys";
$stmt = $conn->query($query);
$master_key_row = $stmt->fetch();
$query = "SELECT name FROM sys.column_encryption_keys";
$stmt = $conn->query($query);
$encryption_key_row = $stmt->fetch();
if ($master_key_row[0] == 'AEMasterKey' && $encryption_key_row[0] == 'AEColumnKey'){
echo "Test Successfully done.\n";
}
else {
die("Column Master Key and Column Encryption Key not created.\n");
}
unset($stmt);
}
else {
echo "Test Successfully done.\n";
}
unset($conn);
?>
--EXPECT--
--TEST--
Test the existence of Windows Always Encrypted keys generated in the database setup
--DESCRIPTION--
This test iterates through the rows of sys.column_master_keys and/or
sys.column_encryption_keys to look for the specific column master key and
column encryption key generated in the database setup
--SKIPIF--
<?php require('skipif_unix.inc'); ?>
--FILE--
<?php
require_once('MsCommon_mid-refactor.inc');
$conn = connect();
if (isAEQualified($conn)){
$query = "SELECT name FROM sys.column_master_keys";
$stmt = $conn->query($query);
// Do not assume the master key must be the first one created
$found = false;
while ($master_key_row = $stmt->fetch()) {
if ($master_key_row[0] == 'AEMasterKey') {
$found = true;
}
}
if (!$found) {
die("Windows Column Master Key not created.\n");
}
// Do not assume the encryption key must be the first one created
$query = "SELECT name FROM sys.column_encryption_keys";
$stmt = $conn->query($query);
$found = false;
while ($encryption_key_row = $stmt->fetch()) {
if ($encryption_key_row[0] == 'AEColumnKey') {
$found = true;
}
}
if (!$found) {
die("Windows Column Encryption Key not created.\n");
}
unset($stmt);
}
echo "Test Successfully done.\n";
unset($conn);
?>
--EXPECT--
Test Successfully done.

View file

@ -472,7 +472,7 @@ function isLocaleSupported()
if (isWindows()) {
return true;
}
if (AE\isColEncrypted()) {
if (AE\isDataEncrypted()) {
return false;
}
// now check ODBC version

View file

@ -18,7 +18,9 @@ $tableIndex = "php_test_table_index";
$procName = "php_test_proc";
$fileName = "php_test_file.dat";
$connectionOptions = array("Database"=>$database, "UID"=>$userName, "PWD"=>$userPassword, "TraceOn"=>false);
$driver = "ODBC Driver 17 for SQL Server";
$connectionOptions = array("Database" => $database, "UID" => $userName, "PWD" => $userPassword, "TraceOn" => false, "Driver" => $driver);
$daasMode = false;
$marsMode = true;

View file

@ -19,7 +19,7 @@ function sendStream($minType, $maxType, $atExec)
startTest($testName);
setup();
$tableName = "TC52test";
$tableName = "TC52test" . rand(0, 100);
$fileName = "TC52test.dat";
$conn1 = AE\connect();

View file

@ -18,7 +18,7 @@ function sendStream($minType, $maxType)
startTest($testName);
setup();
$tableName = "TC54test";
$tableName = "TC54test" . rand(0, 100);
$fileName = "TC53test.dat";
$conn1 = AE\connect();

View file

@ -10,7 +10,7 @@ PHPT_EXEC=true
<?php
require_once('MsCommon.inc');
function LargeColumnNameTest($columnName, $expectfail)
function largeColumnNameTest($columnName, $expectFail = false)
{
setup();
@ -20,26 +20,32 @@ function LargeColumnNameTest($columnName, $expectfail)
dropTable($conn, $tableName);
sqlsrv_query($conn, "CREATE TABLE [$tableName] ([$columnName] int)");
sqlsrv_query($conn, "INSERT INTO [$tableName] ([$columnName]) VALUES (5)");
$stmt = sqlsrv_query($conn, "SELECT * from [$tableName]");
if (null == $stmt) {
echo "$";
echo "stmt = null";
echo "\n";
$stmt = sqlsrv_query($conn, "CREATE TABLE [$tableName] ([$columnName] int)");
if ($stmt == null) {
if (!$expectFail) {
fatalError("Possible regression: Unable to create test $tableName.");
} else {
$expected = 'is too long. Maximum length is 128.';
if (strpos(sqlsrv_errors()[0]['message'], $expected) === false) {
print_r(sqlsrv_errors());
}
echo "$";
echo "stmt = null";
echo "\n";
}
} else {
sqlsrv_query($conn, "INSERT INTO [$tableName] ([$columnName]) VALUES (5)");
$stmt = sqlsrv_query($conn, "SELECT * from [$tableName]");
if (null == sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
if (!$expectfail) {
if (!$expectFail) {
fatalError("Possible regression: Unable to retrieve inserted value.");
}
}
sqlsrv_free_stmt($stmt);
}
dropTable($conn, $tableName);
sqlsrv_close($conn);
@ -56,17 +62,16 @@ function repro()
startTest($testName);
$columnName = "a";
try {
for ($a = 1; $a <= 129; $a++) {
LargeColumnNameTest($columnName, $a > 128);
$columnName .= "A";
}
} catch (Exception $e) {
echo $e->getMessage();
}
// The maximum size of a column name is 128 characters
$maxlen = 128;
$columnName = str_repeat('a', $maxlen);
largeColumnNameTest($columnName);
// Now add another character to the name
$columnName .= "A";
largeColumnNameTest($columnName, true);
endTest($testName);
}

View file

@ -10,35 +10,44 @@ PHPT_EXEC=true
<?php
require_once('MsCommon.inc');
function LargeColumnNameTest($columnName, $expectfail)
function largeColumnNameTest($columnName, $expectFail = false)
{
setup();
$conn = connect(array( 'CharacterSet'=>'UTF-8' ));
$conn = connect(array('CharacterSet'=>'UTF-8'));
$tableName = "LargeColumnNameTest";
dropTable($conn, $tableName);
sqlsrv_query($conn, "CREATE TABLE [$tableName] ([$columnName] int)");
sqlsrv_query($conn, "INSERT INTO [$tableName] ([$columnName]) VALUES (5)");
$stmt = sqlsrv_query($conn, "SELECT * from [$tableName]");
if (null == $stmt) {
echo "$";
echo "stmt = null";
echo "\n";
$stmt = sqlsrv_query($conn, "CREATE TABLE [$tableName] ([$columnName] int)");
if ($stmt == null) {
if (!$expectFail) {
fatalError("Possible regression: Unable to create test $tableName.");
} else {
$expected = 'is too long. Maximum length is 128.';
if (strpos(sqlsrv_errors()[0]['message'], $expected) === false) {
print_r(sqlsrv_errors());
}
echo "$";
echo "stmt = null";
echo "\n";
}
} else {
sqlsrv_query($conn, "INSERT INTO [$tableName] ([$columnName]) VALUES (5)");
$stmt = sqlsrv_query($conn, "SELECT * from [$tableName]");
if (null == sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
if (!$expectfail) {
if (!$expectFail) {
fatalError("Possible regression: Unable to retrieve inserted value.");
}
}
sqlsrv_free_stmt($stmt);
}
dropTable($conn, $tableName);
sqlsrv_close($conn);
}
@ -53,16 +62,16 @@ function repro()
startTest($testName);
$columnName = "银";
// The maximum size of a column name is 128 characters
$maxlen = 128;
$columnName = str_repeat('银', $maxlen);
try {
for ($a = 1; $a <= 129; $a++) {
LargeColumnNameTest($columnName, $a > 128);
$columnName .= "银";
}
} catch (Exception $e) {
echo $e->getMessage();
}
largeColumnNameTest($columnName);
// Now add another character to the name
$columnName .= "银";
largeColumnNameTest($columnName, true);
endTest($testName);
}

View file

@ -1,75 +0,0 @@
--TEST--
PHP - Large Unicode Column Name Test
--DESCRIPTION--
Verifies that long column names are supported (up to 128 chars).
--ENV--
PHPT_EXEC=true
--SKIPIF--
<?php require('skipif.inc'); ?>
--FILE--
<?php
require_once('MsCommon.inc');
function LargeColumnNameTest($columnName, $expectfail)
{
setup();
$conn = connect(array( 'CharacterSet'=>'UTF-8' ));
$tableName = "LargeColumnNameTest";
dropTable($conn, $tableName);
sqlsrv_query($conn, "CREATE TABLE [$tableName] ([$columnName] int)");
sqlsrv_query($conn, "INSERT INTO [$tableName] ([$columnName]) VALUES (5)");
$stmt = sqlsrv_query($conn, "SELECT * from [$tableName]");
if (null == $stmt) {
echo "$";
echo "stmt = null";
echo "\n";
} else {
if (null == sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
if (!$expectfail) {
fatalError("Possible regression: Unable to retrieve inserted value.");
}
}
sqlsrv_free_stmt($stmt);
}
sqlsrv_close($conn);
}
//--------------------------------------------------------------------
// repro
//
//--------------------------------------------------------------------
function repro()
{
$testName = "PHP - Large Unicode Column Name Test";
startTest($testName);
$columnName = "银";
try {
for ($a = 1; $a <= 129; $a++) {
LargeColumnNameTest($columnName, $a > 128);
$columnName .= "银";
}
} catch (Exception $e) {
echo $e->getMessage();
}
endTest($testName);
}
repro();
?>
--EXPECT--
$stmt = null
Test "PHP - Large Unicode Column Name Test" completed successfully.

View file

@ -144,7 +144,12 @@ $stmt6 = sqlsrv_query( $conn, "SELECT * FROM $tableName2" );
if( $stmt6 === false )
{
echo "Error in statement 6.\n";
print_r( sqlsrv_errors() );
$err = sqlsrv_errors();
if (strpos($err[0][0], '08S01')===false or
(strpos($err[0][2], 'TCP Provider:')===false and strpos($err[0][2], 'SMux Provider:')===false and strpos($err[0][2], 'Session Provider:')===false)) {
echo "Error: Wrong error message.\n";
print_r($err);
}
}
else
{
@ -188,7 +193,12 @@ $stmt8 = sqlsrv_query( $conn, "SELECT * FROM $tableName2" );
if( $stmt8 === false )
{
echo "Error in statement 8.\n";
print_r( sqlsrv_errors() );
$err = sqlsrv_errors();
if (strpos($err[0][0], 'IMSSP')===false or
strpos($err[0][2], 'The connection cannot process this operation because there is a statement with pending results')===false) {
echo "Error: Wrong error message.\n";
print_r($err);
}
}
else
{
@ -199,7 +209,7 @@ sqlsrv_close( $conn );
sqlsrv_close( $conn_break );
?>
--EXPECTREGEX--
--EXPECT--
Statement 1 successful.
16 rows in result set.
Statement 2 successful.
@ -211,53 +221,5 @@ Statement 4 successful.
Statement 5 successful.
rows in result set.
Error in statement 6.
Array
\(
\[0\] => Array
\(
\[0\] => 08S01
\[SQLSTATE\] => 08S01
\[1\] => 10054
\[code\] => 10054
\[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: An existing connection was forcibly closed by the remote host.
\[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: An existing connection was forcibly closed by the remote host.
\)
\[1\] => Array
\(
\[0\] => 08S01
\[SQLSTATE\] => 08S01
\[1\] => 10054
\[code\] => 10054
\[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Communication link failure
\[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Communication link failure
\)
\)
Statement 7 successful.
Error in statement 8.
Array
\(
\[0\] => Array
\(
\[0\] => IMSSP
\[SQLSTATE\] => IMSSP
\[1\] => -44
\[code\] => -44
\[2\] => The connection cannot process this operation because there is a statement with pending results. To make the connection available for other queries, either fetch all results or cancel or free the statement. For more information, see the product documentation about the MultipleActiveResultSets connection option.
\[message\] => The connection cannot process this operation because there is a statement with pending results. To make the connection available for other queries, either fetch all results or cancel or free the statement. For more information, see the product documentation about the MultipleActiveResultSets connection option.
\)
\[1\] => Array
\(
\[0\] => HY000
\[SQLSTATE\] => HY000
\[1\] => 0
\[code\] => 0
\[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Connection is busy with results for another command
\[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Connection is busy with results for another command
\)
\)

View file

@ -3,8 +3,7 @@ Test the connection resiliency keywords
--DESCRIPTION--
Test the connection resiliency keywords ConnectRetryCount and ConnectRetryInterval and their ranges of acceptable values
--SKIPIF--
<?php require('skipif_unix.inc');
require('skipif_version_less_than_2k14.inc'); ?>
<?php require('skipif_version_less_than_2k14.inc'); ?>
--FILE--
<?php
require_once( "MsSetup.inc" );
@ -76,8 +75,8 @@ Array
\[SQLSTATE\] => 08001
\[1\] => 0
\[code\] => 0
\[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryCount'
\[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryCount'
\[2\] => (\[unixODBC\]|)\[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryCount'
\[message\] => (\[unixODBC\]|)\[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryCount'
\)
\)
@ -90,8 +89,8 @@ Array
\[SQLSTATE\] => 08001
\[1\] => 0
\[code\] => 0
\[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryInterval'
\[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryInterval'
\[2\] => (\[unixODBC\]|)\[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryInterval'
\[message\] => (\[unixODBC\]|)\[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryInterval'
\)
\)
@ -104,8 +103,8 @@ Array
\[SQLSTATE\] => 08001
\[1\] => 0
\[code\] => 0
\[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryCount'
\[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryCount'
\[2\] => (\[unixODBC\]|)\[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryCount'
\[message\] => (\[unixODBC\]|)\[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryCount'
\)
\)

View file

@ -167,42 +167,22 @@ else
else
{
echo "Statement not valid and rollback failed.\n";
print_r( sqlsrv_errors() );
$err = sqlsrv_errors();
if (strpos($err[0][0], '08S02')===false or
(strpos($err[0][2], 'TCP Provider:')===false and strpos($err[0][2], 'SMux Provider:')===false and strpos($err[0][2], 'Session Provider:')===false)) {
echo "Error: Wrong error message.\n";
print_r($err);
}
}
}
sqlsrv_close( $conn );
sqlsrv_close( $conn_break );
?>
--EXPECTREGEX--
--EXPECT--
Statement 1 prepared.
Statement 1 executed.
Transaction begun.
Transaction was committed.
Transaction begun.
Statement not valid and rollback failed.
Array
\(
\[0\] => Array
\(
\[0\] => 08S02
\[SQLSTATE\] => 08S02
\[1\] => 10054
\[code\] => 10054
\[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: An existing connection was forcibly closed by the remote host.
\[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: An existing connection was forcibly closed by the remote host.
\)
\[1\] => Array
\(
\[0\] => 08S02
\[SQLSTATE\] => 08S02
\[1\] => 10054
\[code\] => 10054
\[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Unable to open a logical session
\[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Unable to open a logical session
\)
\)

View file

@ -33,7 +33,12 @@ $stmt1 = sqlsrv_query( $conn, "SELECT * FROM $tableName1" );
if( $stmt1 === false )
{
echo "Error in statement 1.\n";
print_r( sqlsrv_errors() );
$err = sqlsrv_errors();
if (strpos($err[0][0], '08S01')===false or
(strpos($err[0][2], 'TCP Provider:')===false and strpos($err[0][2], 'SMux Provider:')===false and strpos($err[0][2], 'Session Provider:')===false)) {
echo "Error: Wrong error message.\n";
print_r($err);
}
}
else
{
@ -78,29 +83,4 @@ DropTables( $server, $uid, $pwd, $tableName1, $tableName2 )
?>
--EXPECTREGEX--
Error in statement 1.
Array
\(
\[0\] => Array
\(
\[0\] => 08S01
\[SQLSTATE\] => 08S01
\[1\] => 10054
\[code\] => 10054
\[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: An existing connection was forcibly closed by the remote host.
\[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: An existing connection was forcibly closed by the remote host.
\)
\[1\] => Array
\(
\[0\] => 08S01
\[SQLSTATE\] => 08S01
\[1\] => 10054
\[code\] => 10054
\[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Communication link failure
\[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Communication link failure
\)
\)
Statement 2 successful.

View file

@ -0,0 +1,21 @@
<?php
if (! extension_loaded("sqlsrv")) {
die("skip extension not loaded");
}
require_once("MsSetup.inc");
if ($driver != "ODBC Driver 17 for SQL Server") {
// the testing is not set to use ODBC 17
die("skip - AE feature not supported in the current environment.");
}
require_once('MsCommon.inc');
$conn = AE\connect();
if (! $conn) {
echo("Error: could not connect during SKIPIF!");
} elseif (!AE\isQualified($conn)) {
die("skip - AE feature not supported in the current environment.");
}
?>

View file

@ -1,6 +1,4 @@
<?php
if ( !( strtoupper( substr( php_uname( 's' ),0,3 ) ) === 'WIN' ) ) die( "Skip Test on windows only." );
if (!extension_loaded("sqlsrv")) {
die("skip Extension not loaded");
}

View file

@ -1,10 +1,14 @@
<?php
if ( !( strtoupper( substr( php_uname( 's' ),0,3 ) ) === 'WIN' ) ) die( "Skip Test on windows only." );
// For connection resiliency, must check that
// 1. Either SQL Server version is 2014 or greater, or using Azure;
// 2. Either running Windows, or ODBC driver 17.2 or greater on unix
if (!extension_loaded("sqlsrv")) {
die("skip Extension not loaded");
}
$is_win = ( strtoupper( substr( php_uname( 's' ),0,3 ) ) === 'WIN' );
require_once( "MsSetup.inc" );
$connectionInfo = array( "UID"=>$userName, "PWD"=>$userPassword );
@ -14,17 +18,30 @@ if ($conn === false) {
die( "skip Could not connect during SKIPIF." );
}
// Get SQL Server version
$stmt = sqlsrv_query( $conn, "SELECT @@VERSION" );
if (sqlsrv_fetch($stmt)) {
$ver_string = sqlsrv_get_field( $stmt, 0 );
} else {
die("skip Could not fetch SQL Server version.");
$msodbcsql_ver = sqlsrv_client_info($conn)["DriverVer"];
$msodbcsql_maj = explode(".", $msodbcsql_ver)[0];
$msodbcsql_min = explode(".", $msodbcsql_ver)[1];
if (!$is_win) {
if ($msodbcsql_maj < 17 or $msodbcsql_min < 2) {
die("skip Unsupported ODBC driver version");
}
}
$version = explode(' ', $ver_string);
// Get SQL Server version
// Exclude this check if running on Azure
if (!$daasMode) {
$stmt = sqlsrv_query( $conn, "SELECT @@VERSION" );
if (sqlsrv_fetch($stmt)) {
$ver_string = sqlsrv_get_field( $stmt, 0 );
} else {
die("skip Could not fetch SQL Server version.");
}
if ($version[3] < '2014') {
die("skip Wrong version of SQL Server, 2014 or later required");
$version = explode(' ', $ver_string);
if ($version[3] < '2014') {
die("skip Wrong version of SQL Server, 2014 or later required");
}
}
?>

View file

@ -1,10 +1,14 @@
<?php
if ( !( strtoupper( substr( php_uname( 's' ),0,3 ) ) === 'WIN' ) ) die( "Skip Test on windows only." );
// For Azure ActiveDirectory, must check that
// 1. Either running Windows, or ODBC driver 17 or greater on unix
// 2. Either SQL Server version is 2016 or greater, or using Azure
if (!extension_loaded("sqlsrv")) {
die("skip Extension not loaded");
}
$is_win = ( strtoupper( substr( php_uname( 's' ),0,3 ) ) === 'WIN' );
require_once( "MsSetup.inc" );
$connectionInfo = array( "UID"=>$userName, "PWD"=>$userPassword );
@ -14,17 +18,29 @@ if ($conn === false) {
die( "skip Could not connect during SKIPIF." );
}
// Get SQL Server version
$stmt = sqlsrv_query( $conn, "SELECT @@VERSION" );
if (sqlsrv_fetch($stmt)) {
$ver_string = sqlsrv_get_field( $stmt, 0 );
} else {
die("skip Could not fetch SQL Server version.");
$msodbcsql_ver = sqlsrv_client_info($conn)["DriverVer"];
$msodbcsql_maj = explode(".", $msodbcsql_ver)[0];
if (!$is_win) {
if ($msodbcsql_maj < 17) {
die("skip Unsupported ODBC driver version");
}
}
$version = explode(' ', $ver_string);
// Get SQL Server version
// Exclude this check if running on Azure
if (!$daasMode) {
$stmt = sqlsrv_query( $conn, "SELECT @@VERSION" );
if (sqlsrv_fetch($stmt)) {
$ver_string = sqlsrv_get_field( $stmt, 0 );
} else {
die("skip Could not fetch SQL Server version.");
}
if ($version[3] < '2016') {
die("skip Wrong version of SQL Server, 2016 or later required");
$version = explode(' ', $ver_string);
if ($version[3] < '2016') {
die("skip Wrong version of SQL Server, 2016 or later required");
}
}
?>

View file

@ -6,6 +6,15 @@ This test assumes the default odbcinst.ini has not been modified.
<?php if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') die("Skipped: Test for Linux and Mac"); ?>
--FILE--
<?php
function findODBCDriver($content, $lines_to_add)
{
require_once('MsSetup.inc');
$command = "odbcinst -q -d -n '$driver'";
$info = shell_exec($command);
return str_replace($info, $info.$lines_to_add, $content);
}
$lines_to_add="CPTimeout=5\n[ODBC]\nPooling=Yes\n";
//get default odbcinst.ini location
@ -18,8 +27,8 @@ copy( $odbcinst_ini, $custom_odbcinst_ini);
//enable pooling by modifying the odbcinst.ini file
$current = file_get_contents($custom_odbcinst_ini);
$current.=$lines_to_add;
file_put_contents($custom_odbcinst_ini, $current);
$new_content = findODBCDriver($current, $lines_to_add);
file_put_contents($custom_odbcinst_ini, $new_content);
//Creating a new php process, because for changes in odbcinst.ini file to affect pooling, drivers must be reloaded.
//Also setting the odbcini path to the current folder for the same process.

View file

@ -1,7 +1,7 @@
--TEST--
Test client ID/secret credentials for Azure Key Vault for Always Encrypted.
--SKIPIF--
<?php require('skipif_versions_old.inc'); ?>
<?php require('skipif_not_akv.inc'); ?>
--FILE--
<?php
require_once('sqlsrv_ae_azure_key_vault_common.php');

View file

@ -1,7 +1,7 @@
--TEST--
Test connection keywords for Azure Key Vault for Always Encrypted.
--SKIPIF--
<?php require('skipif_versions_old.inc'); ?>
<?php require('skipif_not_akv.inc'); ?>
--FILE--
<?php
require_once('sqlsrv_ae_azure_key_vault_common.php');

View file

@ -1,7 +1,7 @@
--TEST--
Test username/password credentials for Azure Key Vault for Always Encrypted.
--SKIPIF--
<?php require('skipif_versions_old.inc'); ?>
<?php require('skipif_not_akv.inc'); ?>
--FILE--
<?php
require_once('sqlsrv_ae_azure_key_vault_common.php');

View file

@ -1,16 +1,17 @@
--TEST--
Test insert data and fetch as all possible php types
--DESCRIPTION--
Test insert data of most common column types and fetch them all as possible php types
--SKIPIF--
<?php require('skipif_versions_old.inc'); ?>
--FILE--
<?php
require_once('MsCommon.inc');
require_once('tools.inc');
require_once('values.php');
// Set up the columns and build the insert query. Each data type has an
// AE-encrypted and a non-encrypted column side by side in the table.
function FormulateSetupQuery($tableName, &$dataTypes, &$columns, &$insertQuery, $strsize, $strsize2)
function formulateSetupQuery($tableName, &$dataTypes, &$columns, &$insertQuery)
{
$columns = array();
$queryTypes = "(";
@ -45,20 +46,22 @@ $SQLSRV_PHPTYPE_CONST = array(SQLSRV_PHPTYPE_INT,
SQLSRV_PHPTYPE_STRING("UTF-8")
);
// Two sizes for the string types so we can test conversion from
// a shorter type to a longer type
$strsize = 256;
$strsize2 = 384;
$dataTypes = array ("binary($strsize)", "varbinary($strsize)", "varbinary(max)", "char($strsize)",
"varchar($strsize)", "varchar(max)", "nchar($strsize)", "nvarchar($strsize)",
"nvarchar(max)", "datetime", "smalldatetime", "date", "time(5)", "datetimeoffset(5)",
"datetime2(5)", "decimal(28,4)", "numeric(32,4)", "float", "real", "bigint", "int",
"smallint", "tinyint", "bit",
"binary($strsize2)", "varbinary($strsize2)", "char($strsize2)",
"varchar($strsize2)", "nchar($strsize2)", "nvarchar($strsize2)",
"time", "datetimeoffset", "datetime2", "decimal(32,4)", "numeric(36,4)"
);
// Two constants STRSIZE and LONG_STRSIZE for the string types so we can test
// conversion from a shorter type to a longer type
$strsize = STRSIZE;
$strsize2 = LONG_STRSIZE;
$dataTypes = array("binary($strsize)", "varbinary($strsize)", "varbinary(max)",
"char($strsize)", "varchar($strsize)", "varchar(max)",
"nchar($strsize)", "nvarchar($strsize)", "nvarchar(max)",
"datetime", "smalldatetime", "date", "time(5)", "datetimeoffset(5)",
"datetime2(5)", "decimal(28,4)", "numeric(32,4)", "float", "real",
"bigint", "int", "smallint", "tinyint", "bit",
"binary($strsize2)", "varbinary($strsize2)", "char($strsize2)",
"varchar($strsize2)", "nchar($strsize2)", "nvarchar($strsize2)",
"time", "datetimeoffset", "datetime2", "decimal(32,4)", "numeric(36,4)"
);
set_time_limit(0);
sqlsrv_configure('WarningsReturnAsErrors', 1);
@ -74,16 +77,15 @@ $tableName = "type_conversion_table";
$columns = array();
$insertQuery = "";
FormulateSetupQuery($tableName, $dataTypes, $columns, $insertQuery, $strsize, $strsize2);
formulateSetupQuery($tableName, $dataTypes, $columns, $insertQuery);
$stmt = AE\createTable($conn, $tableName, $columns);
if (!$stmt) {
fatalError("Failed to create table $tableName\n");
}
// The data we test against is in values.php
for ($v = 0; $v < sizeof($values);++$v)
{
for ($v = 0; $v < sizeof($values); ++$v) {
// Each value must be inserted twice because the AE and non-AE column are side by side.
$testValues = array();
for ($i=0; $i<sizeof($values[$v]); ++$i) {
@ -92,101 +94,111 @@ for ($v = 0; $v < sizeof($values);++$v)
}
// Insert the data using sqlsrv_prepare()
// Insert one set of data for each PHPTYPE
$stmt = sqlsrv_prepare($conn, $insertQuery, $testValues);
if ($stmt == false) {
print_r(sqlsrv_errors());
fatalError("sqlsrv_prepare failed\n");
}
for ($i = 0; $i < sizeof($SQLSRV_PHPTYPE_CONST); ++$i) {
if (sqlsrv_execute($stmt) == false) {
print_r(sqlsrv_errors());
fatalError("sqlsrv_execute failed\n");
}
if (sqlsrv_execute($stmt) == false) {
print_r(sqlsrv_errors());
fatalError("sqlsrv_execute failed\n");
}
$selectQuery = "SELECT * FROM $tableName";
// Two select statements for selection using
// Two select statements for selection using
// sqlsrv_get_field and sqlsrv_fetch_array
$stmt = sqlsrv_query($conn, $selectQuery);
// Use sqlsrv_prepare() for the first one
// such that sqlsrv_execute() can be invoked for
// each PHP type
$stmt = sqlsrv_prepare($conn, $selectQuery);
if ($stmt == false) {
print_r(sqlsrv_errors());
fatalError("First sqlsrv_prepare failed\n");
fatalError("SELECT using sqlsrv_prepare failed\n");
}
$stmt2 = sqlsrv_query($conn, $selectQuery);
if ($stmt2 == false) {
print_r(sqlsrv_errors());
fatalError("Second sqlsrv_prepare failed\n");
fatalError("SELECT using sqlsrv_query failed\n");
}
$numFields = sqlsrv_num_fields($stmt);
$i = 0;
$valueAE = null;
$valueFromArrayAE = null;
while ($result = sqlsrv_fetch($stmt)) {
$dataArray = sqlsrv_fetch_array($stmt2, SQLSRV_FETCH_NUMERIC);
for ($j = 0; $j < $numFields; $j++) {
$value = sqlsrv_get_field($stmt, $j, $SQLSRV_PHPTYPE_CONST[$i]);
$valueFromArray = $dataArray[$j];
// PHPTYPE_STREAM returns a PHP resource, so check the type
if (is_resource($value)) $value = get_resource_type($value);
// For each type, the AE values come first and non-AE values second
// So let's do the comparison every second field
if ($j%2 == 0) {
$valueAE = $value;
$valueFromArrayAE = $valueFromArray;
} elseif ($j%2 == 1) {
// If returning a DateTime PHP type from a date only SQL type,
// PHP adds the current timestamp to make a DateTime object,
// and in this case the AE and non-AE times may be off by a
// fraction of a second since they are retrieved at ever-so-slightly
// different times. This not a test-failing discrepancy, so
// below the DateTime objects are made equal again for the next if
// block.
if ($value instanceof DateTime) {
// date_diff returns a DateInterval object, and s is
// the difference in seconds. s should be zero because
// the difference should be just a fraction of a second.
$datediff = date_diff($value, $valueAE);
$diff = $datediff->s;
if ($diff == 0) {
$value = $valueAE;
}
$dataArray = sqlsrv_fetch_array($stmt2, SQLSRV_FETCH_NUMERIC);
for ($i = 0; $i < sizeof($SQLSRV_PHPTYPE_CONST); ++$i) {
if (!sqlsrv_execute($stmt)) {
fatalError("Execute failed for $SQLSRV_PHPTYPE_CONST[$i]\n");
}
if ($result = sqlsrv_fetch($stmt)) {
for ($j = 0; $j < $numFields; $j++) {
$value = sqlsrv_get_field($stmt, $j, $SQLSRV_PHPTYPE_CONST[$i]);
$valueFromArray = $dataArray[$j];
// PHPTYPE_STREAM returns a PHP resource, so check the type
if (is_resource($value)) {
$value = get_resource_type($value);
}
if ($valueAE != $value or $valueFromArrayAE != $valueFromArray) {
echo "Values do not match! PHPType $i Field $j\n";
print_r($valueAE);echo "\n";
print_r($value);echo "\n";
print_r($valueFromArrayAE);echo "\n";
print_r($valueFromArray);echo "\n";
print_r(sqlsrv_errors());
fatalError("Test failed, values do not match.\n");
// For each type, the AE values come first and non-AE values second
// So let's do the comparison every second field
if ($j%2 == 0) {
$valueAE = $value;
$valueFromArrayAE = $valueFromArray;
} elseif ($j%2 == 1) {
// If returning a DateTime PHP type from a date only SQL type,
// PHP adds the current timestamp to make a DateTime object,
// and in this case the AE and non-AE times may be off by a
// fraction of a second since they are retrieved at ever-so-slightly
// different times. This not a test-failing discrepancy, so
// below the DateTime objects are made equal again for the next if
// block.
if ($value instanceof DateTime) {
// date_diff returns a DateInterval object, and s is
// the difference in seconds. s should be zero because
// the difference should be just a fraction of a second.
$datediff = date_diff($value, $valueAE);
$diff = $datediff->s;
if ($diff == 0) {
$value = $valueAE;
}
}
if ($valueAE != $value or $valueFromArrayAE != $valueFromArray) {
$index = floor($j / 2);
echo "Values do not match! PHPType $i Field $dataTypes[$index]\n";
print_r($valueAE);
echo "\n--------\n\n";
print_r($value);
echo "\n--------\n\n";
print_r($valueFromArrayAE);
echo "\n--------\n\n";
print_r($valueFromArray);
echo "\n--------\n\n";
print_r(sqlsrv_errors());
echo("Test failed, values do not match.\n");
}
}
}
}
++$i;
}
sqlsrv_free_stmt($stmt);
sqlsrv_free_stmt($stmt2);
$deleteQuery = "DELETE FROM $tableName";
$deleteQuery = "TRUNCATE TABLE $tableName";
$stmt = sqlsrv_query($conn, $deleteQuery);
if ($stmt == false) {
print_r(sqlsrv_errors());
fatalError("Delete statement failed");
fatalError("Truncate statement failed");
}
sqlsrv_free_stmt($stmt);
}

View file

@ -1,7 +1,7 @@
--TEST--
Test new connection keyword ColumnEncryption
--SKIPIF--
<?php require('skipif_unix.inc'); ?>
<?php require('skipif.inc'); ?>
--FILE--
<?php
sqlsrv_configure( 'WarningsReturnAsErrors', 0 );

View file

@ -1,5 +1,9 @@
--TEST--
retrieval of names of column master key and column encryption key generated in the database setup
Test the existence of Windows Always Encrypted keys generated in the database setup
--DESCRIPTION--
This test iterates through the rows of sys.column_master_keys and/or
sys.column_encryption_keys to look for the specific column master key and
column encryption key generated in the database setup
--SKIPIF--
<?php require('skipif_unix.inc'); ?>
--FILE--
@ -13,23 +17,34 @@ $conn = connect();
if (AE\IsQualified($conn)) {
$query = "SELECT name FROM sys.column_master_keys";
$stmt = sqlsrv_query($conn, $query);
sqlsrv_fetch($stmt);
$master_key_name = sqlsrv_get_field($stmt, 0);
$found = false;
while (sqlsrv_fetch($stmt)) {
$master_key_name = sqlsrv_get_field($stmt, 0);
if ($master_key_name == 'AEMasterKey') {
$found = true;
}
}
// $master_key_name = sqlsrv_get_field($stmt, 0);
if (!$found) {
die("Windows Column Master Key not created.\n");
}
$query = "SELECT name FROM sys.column_encryption_keys";
$stmt = sqlsrv_query($conn, $query);
sqlsrv_fetch($stmt);
$encryption_key_name = sqlsrv_get_field($stmt, 0);
if ($master_key_name == 'AEMasterKey' && $encryption_key_name == 'AEColumnKey') {
echo "Test Successfully done.\n";
} else {
echo "Column Master Key and Column Encryption Key not created.\n";
$found = false;
while (sqlsrv_fetch($stmt)) {
$encryption_key_name = sqlsrv_get_field($stmt, 0);
if ($encryption_key_name == 'AEColumnKey') {
$found = true;
}
}
if (!$found) {
die("Windows Column Encryption Key not created.\n");
}
sqlsrv_free_stmt($stmt);
} else {
echo "Test Successfully done.\n";
}
echo "Test Successfully done.\n";
sqlsrv_close($conn);
?>
--EXPECT--