From bbc2701140a5ef867c88e677367190eceea6291b Mon Sep 17 00:00:00 2001 From: Jenny Tam Date: Fri, 29 Sep 2017 15:54:34 -0700 Subject: [PATCH] Made changes as per review comments --- source/pdo_sqlsrv/pdo_util.cpp | 2 +- source/shared/core_conn.cpp | 131 ++++++++--------- source/shared/core_sqlsrv.h | 2 +- source/sqlsrv/util.cpp | 2 +- .../pdo_sqlsrv/pdo_connect_driver.phpt | 136 +++++++----------- .../sqlsrv/sqlsrv_connect_driver.phpt | 95 ++++++------ 6 files changed, 158 insertions(+), 210 deletions(-) diff --git a/source/pdo_sqlsrv/pdo_util.cpp b/source/pdo_sqlsrv/pdo_util.cpp index 63cad9d2..310b66a4 100644 --- a/source/pdo_sqlsrv/pdo_util.cpp +++ b/source/pdo_sqlsrv/pdo_util.cpp @@ -398,7 +398,7 @@ pdo_error PDO_ERRORS[] = { { IMSSP, (SQLCHAR*) "Invalid value for loading a custom keystore provider.", -77, false} }, { - SQLSRV_ERROR_AE_DRIVER_REQUIRED, + SQLSRV_ERROR_CE_DRIVER_REQUIRED, { IMSSP, (SQLCHAR*) "The Always Encrypted feature requires Microsoft ODBC Driver 17 for SQL Server.", -78, false } }, { diff --git a/source/shared/core_conn.cpp b/source/shared/core_conn.cpp index 70450a12..30749676 100644 --- a/source/shared/core_conn.cpp +++ b/source/shared/core_conn.cpp @@ -110,9 +110,9 @@ sqlsrv_conn* core_sqlsrv_connect( _In_ sqlsrv_context& henv_cp, _In_ sqlsrv_cont #endif // _WIN32 try { - // Due to the limitations on connection pooling in unixODBC 2.3.1 driver manager, we do not consider - // the connection string attributes to set (enable/disable) connection pooling. - // Instead, MSPHPSQL connection pooling is set according to the ODBCINST.INI file in [ODBC] section. + // Due to the limitations on connection pooling in unixODBC 2.3.1 driver manager, we do not consider + // the connection string attributes to set (enable/disable) connection pooling. + // Instead, MSPHPSQL connection pooling is set according to the ODBCINST.INI file in [ODBC] section. #ifndef _WIN32 char pooling_string[ 128 ] = {0}; @@ -125,9 +125,9 @@ sqlsrv_conn* core_sqlsrv_connect( _In_ sqlsrv_context& henv_cp, _In_ sqlsrv_cont is_pooled = true; } #else - // check the connection pooling setting to determine which henv to use to allocate the connection handle - // we do this earlier because we have to allocate the connection handle prior to setting attributes on - // it in build_connection_string_and_set_conn_attr. + // check the connection pooling setting to determine which henv to use to allocate the connection handle + // we do this earlier because we have to allocate the connection handle prior to setting attributes on + // it in build_connection_string_and_set_conn_attr. if( options_ht && zend_hash_num_elements( options_ht ) > 0 ) { @@ -150,14 +150,13 @@ sqlsrv_conn* core_sqlsrv_connect( _In_ sqlsrv_context& henv_cp, _In_ sqlsrv_cont build_connection_string_and_set_conn_attr( conn, server, uid, pwd, options_ht, valid_conn_opts, driver, conn_str TSRMLS_CC ); -#ifndef _WIN32 if( conn->ce_option.enabled ) { - // when AE is enabled, must use ODBC driver 17 + // when column encryption is enabled, must use ODBC driver 17 if( conn->driver_version != ODBC_DRIVER_UNKNOWN ) { - CHECK_CUSTOM_ERROR( conn->driver_version != ODBC_DRIVER_17, conn, SQLSRV_ERROR_AE_DRIVER_REQUIRED, get_processor_arch() ) { + CHECK_CUSTOM_ERROR( conn->driver_version != ODBC_DRIVER_17, conn, SQLSRV_ERROR_CE_DRIVER_REQUIRED, get_processor_arch() ) { throw core::CoreException(); } - +#ifndef _WIN32 // check if ODBC 17 actually exists, if not, throw an exception CHECK_CUSTOM_ERROR( ! core_search_odbc_driver_unix( ODBC_DRIVER_17 ), conn, SQLSRV_ERROR_SPECIFIED_DRIVER_NOT_FOUND ) { throw core::CoreException(); @@ -171,11 +170,11 @@ sqlsrv_conn* core_sqlsrv_connect( _In_ sqlsrv_context& henv_cp, _In_ sqlsrv_cont // If it fails to connect using ODBC 17, it is unreliable to check for a certain sql state error. // Thus, we will simply throw an exception. if( core_search_odbc_driver_unix( ODBC_DRIVER_17 ) ) { - conn_str = conn_str + CONNECTION_STRING_DRIVER_NAME[ DRIVER_VERSION::ODBC_DRIVER_17 ]; + conn_str = conn_str + CONNECTION_STRING_DRIVER_NAME[ODBC_DRIVER_17]; r = core_odbc_connect( conn, conn_str, is_pooled ); } else { - CHECK_CUSTOM_ERROR( true, conn, SQLSRV_ERROR_AE_DRIVER_REQUIRED, get_processor_arch()) { + CHECK_CUSTOM_ERROR( true, conn, SQLSRV_ERROR_CE_DRIVER_REQUIRED, get_processor_arch()) { throw core::CoreException(); } } @@ -192,36 +191,28 @@ sqlsrv_conn* core_sqlsrv_connect( _In_ sqlsrv_context& henv_cp, _In_ sqlsrv_cont r = core_odbc_connect( conn, conn_str, is_pooled ); } else { - DRIVER_VERSION odbc_version = ODBC_DRIVER_UNKNOWN; - for( short i = DRIVER_VERSION::FIRST; i <= DRIVER_VERSION::LAST; ++i ) { - // skip ODBC 11 in a non-Windows environment -- only available in Red Hat / SUSE (preview) - // https://docs.microsoft.com/en-us/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server#microsoft-odbc-driver-11-for-sql-server-on-linux - if (i == DRIVER_VERSION::ODBC_DRIVER_11) - continue; + // skip ODBC 11 in a non-Windows environment -- only available in Red Hat / SUSE (preview) + // https://docs.microsoft.com/en-us/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server#microsoft-odbc-driver-11-for-sql-server-on-linux - if( core_search_odbc_driver_unix( DRIVER_VERSION( i ) ) ) { - odbc_version = DRIVER_VERSION( i ); - break; - } + DRIVER_VERSION odbc_version = ODBC_DRIVER_UNKNOWN; + if( core_search_odbc_driver_unix( ODBC_DRIVER_13 ) ) { + odbc_version = ODBC_DRIVER_13; + } + else if ( core_search_odbc_driver_unix( ODBC_DRIVER_17 ) ) { + odbc_version = ODBC_DRIVER_17; } - CHECK_CUSTOM_ERROR( odbc_version == ODBC_DRIVER_UNKNOWN, conn, SQLSRV_ERROR_DRIVER_NOT_INSTALLED, get_processor_arch()) { + + CHECK_CUSTOM_ERROR( odbc_version == ODBC_DRIVER_UNKNOWN, conn, SQLSRV_ERROR_DRIVER_NOT_INSTALLED, get_processor_arch() ) { throw core::CoreException(); } - std::string conn_str_driver = conn_str + CONNECTION_STRING_DRIVER_NAME[ DRIVER_VERSION( odbc_version ) ]; + std::string conn_str_driver = conn_str + CONNECTION_STRING_DRIVER_NAME[odbc_version]; r = core_odbc_connect( conn, conn_str_driver, is_pooled ); } // else driver_version not unknown } // else ce_option enabled #else - if( conn->ce_option.enabled ) { - // when AE is enabled, must use ODBC driver 17 - if( conn->driver_version != ODBC_DRIVER_UNKNOWN ) { - CHECK_CUSTOM_ERROR( conn->driver_version != ODBC_DRIVER_17, conn, SQLSRV_ERROR_AE_DRIVER_REQUIRED, get_processor_arch() ) { - throw core::CoreException(); - } - r = core_odbc_connect( conn, conn_str, is_pooled ); - if( ! SQL_SUCCEEDED( r ) && core_compare_error_state( conn, r, "IM002" ) ) { + if( core_compare_error_state( conn, r, "IM002" ) ) { // sql state IM002 means that the specified ODBC driver is not installed CHECK_CUSTOM_ERROR( true, conn, SQLSRV_ERROR_SPECIFIED_DRIVER_NOT_FOUND ) { throw core::CoreException(); @@ -230,14 +221,12 @@ sqlsrv_conn* core_sqlsrv_connect( _In_ sqlsrv_context& henv_cp, _In_ sqlsrv_cont } else { // driver not specified, so connect using ODBC 17 - conn_str = conn_str + CONNECTION_STRING_DRIVER_NAME[ DRIVER_VERSION::ODBC_DRIVER_17 ]; + conn_str = conn_str + CONNECTION_STRING_DRIVER_NAME[ODBC_DRIVER_17]; r = core_odbc_connect( conn, conn_str, is_pooled ); - if(! SQL_SUCCEEDED( r ) ) { - // sql state IM002 means that the specified ODBC driver is not installed - CHECK_CUSTOM_ERROR( core_compare_error_state( conn, r, "IM002" ) , conn, SQLSRV_ERROR_AE_DRIVER_REQUIRED, get_processor_arch() ) { - throw core::CoreException(); - } + // sql state IM002 means that the specified ODBC driver is not installed + CHECK_CUSTOM_ERROR( core_compare_error_state( conn, r, "IM002" ) , conn, SQLSRV_ERROR_CE_DRIVER_REQUIRED, get_processor_arch() ) { + throw core::CoreException(); } } } @@ -246,34 +235,36 @@ sqlsrv_conn* core_sqlsrv_connect( _In_ sqlsrv_context& henv_cp, _In_ sqlsrv_cont if( conn->driver_version != ODBC_DRIVER_UNKNOWN ) { r = core_odbc_connect( conn, conn_str, is_pooled ); - if( ! SQL_SUCCEEDED( r ) && core_compare_error_state( conn, r, "IM002" ) ) { + if( core_compare_error_state( conn, r, "IM002" ) ) { // sql state IM002 means that the specified ODBC driver is not installed - CHECK_CUSTOM_ERROR( true, conn, SQLSRV_ERROR_SPECIFIED_DRIVER_NOT_FOUND, CONNECTION_STRING_DRIVER_NAME[ conn->driver_version ].c_str() ) { + CHECK_CUSTOM_ERROR( true, conn, SQLSRV_ERROR_SPECIFIED_DRIVER_NOT_FOUND, CONNECTION_STRING_DRIVER_NAME[conn->driver_version].c_str() ) { throw core::CoreException(); } } } else { - for( short i = DRIVER_VERSION::FIRST; i <= DRIVER_VERSION::LAST; ++i ) { - std::string conn_str_driver = conn_str + CONNECTION_STRING_DRIVER_NAME[ DRIVER_VERSION(i) ]; + bool done = false; + for( short i = DRIVER_VERSION::FIRST; i <= DRIVER_VERSION::LAST && ! done; ++i ) { + std::string conn_str_driver = conn_str + CONNECTION_STRING_DRIVER_NAME[i]; r = core_odbc_connect( conn, conn_str_driver, is_pooled ); - if( SQL_SUCCEEDED( r ) ) { - // successfully connected! - break; + if( SQL_SUCCEEDED( r ) ) { + done = true; } - else if(! core_compare_error_state( conn, r, "IM002" ) ) { - // sql state IM002 means that the specified ODBC driver is not installed - // something went wrong other than missing the ODBC driver - break; - } - else if( i == DRIVER_VERSION::LAST ) { - // failed to connect even using the last valid ODBC driver - CHECK_CUSTOM_ERROR( true, conn, SQLSRV_ERROR_DRIVER_NOT_INSTALLED, get_processor_arch()) { - throw core::CoreException(); + else if( core_compare_error_state( conn, r, "IM002" ) ) { + if(i == DRIVER_VERSION::LAST ) { + // sql state IM002 means that the specified ODBC driver is not installed + // failed to connect even using the last valid ODBC driver + CHECK_CUSTOM_ERROR( true, conn, SQLSRV_ERROR_DRIVER_NOT_INSTALLED, get_processor_arch()) { + throw core::CoreException(); + } } } - } // for + else { + // something else went wrong other than missing the ODBC driver, exit the loop now + done = true; + } + } // for } } // else ce_option enabled #endif // !_WIN32 @@ -349,11 +340,7 @@ bool core_compare_error_state( _In_ sqlsrv_conn* conn, _In_ SQLRETURN rc, _In_ SQLSMALLINT len; SQLRETURN sr = SQLGetDiagField( SQL_HANDLE_DBC, conn->handle(), 1, SQL_DIAG_SQLSTATE, state, SQL_SQLSTATE_BUFSIZE, &len ); - bool same = false; - if( SQL_SUCCEEDED(sr) && ! strcmp(error_state, reinterpret_cast( state ) ) ) - same = true; - - return same; + return ( SQL_SUCCEEDED(sr) && ! strcmp(error_state, reinterpret_cast( state ) ) ); } // core_search_odbc_driver_unix @@ -365,7 +352,7 @@ bool core_compare_error_state( _In_ sqlsrv_conn* conn, _In_ SQLRETURN rc, _In_ bool core_search_odbc_driver_unix( _In_ DRIVER_VERSION driver_version ) { - char szBuf[DEFAULT_CONN_STR_LEN+1]; // use an arbitrary large enough buffer size + char szBuf[DEFAULT_CONN_STR_LEN+1]; // use a large enough buffer size WORD cbBufMax = DEFAULT_CONN_STR_LEN; WORD cbBufOut; char *pszBuf = szBuf; @@ -379,7 +366,7 @@ bool core_search_odbc_driver_unix( _In_ DRIVER_VERSION driver_version ) } // extract the ODBC driver name - std::string driver = CONNECTION_STRING_DRIVER_NAME[ DRIVER_VERSION(driver_version) ]; + std::string driver = CONNECTION_STRING_DRIVER_NAME[driver_version]; std::size_t pos1 = driver.find_first_of("{"); std::size_t pos2 = driver.find_first_of("}"); std::string driver_str = driver.substr( pos1 + 1, pos2 - pos1 - 1); @@ -390,8 +377,7 @@ bool core_search_odbc_driver_unix( _In_ DRIVER_VERSION driver_version ) { if( strstr( pszBuf, driver_name ) != 0 ) { - found_driver = true; - break; + return true; } // get the next driver pszBuf = strchr( pszBuf, '\0' ) + 1; @@ -399,7 +385,7 @@ bool core_search_odbc_driver_unix( _In_ DRIVER_VERSION driver_version ) while( pszBuf[1] != '\0' ); // end when there are two consecutive null characters #endif // !_WIN32 - return found_driver; + return false; } // core_odbc_connect @@ -429,19 +415,17 @@ SQLRETURN core_odbc_connect( _Inout_ sqlsrv_conn* conn, _Inout_ std::string& con #ifndef _WIN32 // unixODBC 2.3.1 requires a non-wide SQLDriverConnect call while pooling enabled. // connection handle has been allocated using henv_cp, means pooling enabled in a PHP script - if (is_pooled) - { + if (is_pooled) { r = SQLDriverConnect( conn->handle(), NULL, (SQLCHAR*)conn_str.c_str(), SQL_NTS, NULL, 0, &output_conn_size, SQL_DRIVER_NOPROMPT ); } - else - { + else { r = SQLDriverConnectW( conn->handle(), NULL, wconn_string, static_cast( wconn_len ), NULL, 0, &output_conn_size, SQL_DRIVER_NOPROMPT ); } #else r = SQLDriverConnectW( conn->handle(), NULL, wconn_string, static_cast( wconn_len ), NULL, 0, &output_conn_size, SQL_DRIVER_NOPROMPT ); #endif // !_WIN32 - // clear the connection string from memory to remove sensitive data (such as a password). + // clear the connection string from memory memset( wconn_string, 0, wconn_len * sizeof( SQLWCHAR )); // wconn_len is the number of characters, not bytes conn_str.clear(); @@ -1069,16 +1053,15 @@ void driver_set_func::func( _In_ connection_option const* option, _In_ zval* val common_conn_str_append_func( option->odbc_name, val_str, val_len, driver_option TSRMLS_CC ); conn->driver_version = ODBC_DRIVER_UNKNOWN; - for ( short i = DRIVER_VERSION::FIRST; i <= DRIVER_VERSION::LAST; ++i ) { - std::string driver_name = CONNECTION_STRING_DRIVER_NAME[ DRIVER_VERSION( i ) ]; + for ( short i = DRIVER_VERSION::FIRST; i <= DRIVER_VERSION::LAST && conn->driver_version == ODBC_DRIVER_UNKNOWN; ++i ) { + std::string driver_name = CONNECTION_STRING_DRIVER_NAME[i]; if (! driver_name.compare( driver_option ) ) { conn->driver_version = DRIVER_VERSION( i ); - break; } } - CHECK_CUSTOM_ERROR( conn->driver_version == ODBC_DRIVER_UNKNOWN, conn, SQLSRV_ERROR_CONNECT_INVALID_DRIVER, val_str){ + CHECK_CUSTOM_ERROR( conn->driver_version == ODBC_DRIVER_UNKNOWN, conn, SQLSRV_ERROR_CONNECT_INVALID_DRIVER, val_str) { throw core::CoreException(); } diff --git a/source/shared/core_sqlsrv.h b/source/shared/core_sqlsrv.h index 7e8c79c4..0c909b44 100644 --- a/source/shared/core_sqlsrv.h +++ b/source/shared/core_sqlsrv.h @@ -1642,7 +1642,7 @@ enum SQLSRV_ERROR_CODES { SQLSRV_ERROR_ODBC, SQLSRV_ERROR_DRIVER_NOT_INSTALLED, - SQLSRV_ERROR_AE_DRIVER_REQUIRED, + SQLSRV_ERROR_CE_DRIVER_REQUIRED, SQLSRV_ERROR_CONNECT_INVALID_DRIVER, SQLSRV_ERROR_SPECIFIED_DRIVER_NOT_FOUND, SQLSRV_ERROR_ZEND_HASH, diff --git a/source/sqlsrv/util.cpp b/source/sqlsrv/util.cpp index d282c9c0..b8dd765d 100644 --- a/source/sqlsrv/util.cpp +++ b/source/sqlsrv/util.cpp @@ -397,7 +397,7 @@ ss_error SS_ERRORS[] = { { IMSSP, (SQLCHAR*) "Invalid value for loading a custom keystore provider.", -104, false} }, { - SQLSRV_ERROR_AE_DRIVER_REQUIRED, + SQLSRV_ERROR_CE_DRIVER_REQUIRED, { IMSSP, (SQLCHAR*) "The Always Encrypted feature requires Microsoft ODBC Driver 17 for SQL Server.", -105, false } }, { diff --git a/test/functional/pdo_sqlsrv/pdo_connect_driver.phpt b/test/functional/pdo_sqlsrv/pdo_connect_driver.phpt index 1ab37920..6f53e50b 100644 --- a/test/functional/pdo_sqlsrv/pdo_connect_driver.phpt +++ b/test/functional/pdo_sqlsrv/pdo_connect_driver.phpt @@ -4,58 +4,51 @@ Test new connection keyword Driver with valid and invalid values --FILE-- getAttribute( PDO::ATTR_CLIENT_VERSION )['DriverVer']; - $msodbcsql_maj = explode(".", $msodbcsql_ver)[0]; -} -catch( PDOException $e ) -{ +try { + $conn = new PDO("sqlsrv:server = $server", $uid, $pwd); + $msodbcsqlVer = $conn->getAttribute(PDO::ATTR_CLIENT_VERSION)['DriverVer']; + $msodbcsqlMaj = explode(".", $msodbcsqlVer)[0]; +} catch(PDOException $e) { echo "Failed to connect\n"; - print_r( $e->getMessage() ); + print_r($e->getMessage()); echo "\n"; } $conn = null; // start test -test_valid_values(); -test_invalid_values(); -test_encrypted_with_odbc(); -test_wrong_odbc(); +testValidValues(); +testInvalidValues(); +testEncryptedWithODBC(); +testWrongODBC(); echo "Done"; // end test /////////////////////////// -function connect_verify_output( $connectionOptions, $expected = '' ) +function connectVerifyOutput($connectionOptions, $expected = '') { global $server, $uid, $pwd; - try - { - $conn = new PDO( "sqlsrv:server = $server ; $connectionOptions", $uid, $pwd ); - } - catch( PDOException $e ) - { - if ( strpos($e->getMessage(), $expected ) === false ) - { - print_r( $e->getMessage() ); + try { + $conn = new PDO("sqlsrv:server = $server ; $connectionOptions", $uid, $pwd); + } catch(PDOException $e) { + if (strpos($e->getMessage(), $expected) === false) { + print_r($e->getMessage()); echo "\n"; } } } -function test_valid_values() +function testValidValues() { - global $msodbcsql_maj; + global $msodbcsqlMaj; $value = ""; + // The major version number of ODBC 11 can be 11 or 12 // Test with {} - switch ( $msodbcsql_maj ) - { + switch ($msodbcsqlMaj) { case 17: $value = "{ODBC Driver 17 for SQL Server}"; break; @@ -70,11 +63,10 @@ function test_valid_values() $value = "invalid value"; } $connectionOptions = "Driver = $value"; - connect_verify_output( $connectionOptions ); + connectVerifyOutput($connectionOptions); // Test without {} - switch ( $msodbcsql_maj ) - { + switch ($msodbcsqlMaj) { case 17: $value = "ODBC Driver 17 for SQL Server"; break; @@ -90,47 +82,33 @@ function test_valid_values() } $connectionOptions = "Driver = $value"; - connect_verify_output( $connectionOptions ); + connectVerifyOutput($connectionOptions); } -function test_invalid_values() +function testInvalidValues() { - // test invalid value - $value = "{SQL Server Native Client 11.0}"; - $connectionOptions = "Driver = $value"; - $expected = "Invalid value $value was specified for Driver option."; - connect_verify_output( $connectionOptions, $expected ); + $values = array("{SQL Server Native Client 11.0}", + "SQL Server Native Client 11.0", + "ODBC Driver 00 for SQL Server", + 123, + false); - $value = "SQL Server Native Client 11.0"; - $connectionOptions = "Driver = $value"; - $expected = "Invalid value $value was specified for Driver option."; - connect_verify_output( $connectionOptions, $expected ); - - $value = "ODBC Driver 00 for SQL Server"; - $connectionOptions = "Driver = $value"; - $expected = "Invalid value $value was specified for Driver option."; - connect_verify_output( $connectionOptions, $expected ); - - $value = 123; - $connectionOptions = "Driver = $value"; - $expected = "Invalid value $value was specified for Driver option."; - connect_verify_output( $connectionOptions, $expected ); - - $value = false; - $connectionOptions = "Driver = $value"; - $expected = "Invalid value $value was specified for Driver option."; - connect_verify_output( $connectionOptions, $expected ); + foreach ($values as $value) { + $connectionOptions = "Driver = $value"; + $expected = "Invalid value $value was specified for Driver option."; + connectVerifyOutput($connectionOptions, $expected); + } } -function test_encrypted_with_odbc() +function testEncryptedWithODBC() { - global $msodbcsql_maj, $server, $uid, $pwd; + global $msodbcsqlMaj, $server, $uid, $pwd; $value = "ODBC Driver 13 for SQL Server"; $connectionOptions = "Driver = $value; ColumnEncryption = Enabled;"; $expected = "The Always Encrypted feature requires Microsoft ODBC Driver 17 for SQL Server."; - connect_verify_output( $connectionOptions, $expected ); + connectVerifyOutput($connectionOptions, $expected); // TODO: the following block will change once ODBC 17 is officially released $value = "ODBC Driver 17 for SQL Server"; @@ -139,46 +117,40 @@ function test_encrypted_with_odbc() $success = "Successfully connected with column encryption."; $expected = "The specified ODBC Driver is not found."; $message = $success; - try - { - $conn = new PDO( "sqlsrv:server = $server ; $connectionOptions", $uid, $pwd ); - } - catch( PDOException $e ) - { + try { + $conn = new PDO("sqlsrv:server = $server ; $connectionOptions", $uid, $pwd); + } catch(PDOException $e) { $message = $e->getMessage(); } - if ( $msodbcsql_maj == 17 ) - { + if ($msodbcsqlMaj == 17) { // this indicates that OCBC 17 is the only available driver - if ( strcmp( $message, $success ) ) - print_r( $message ); - } - else - { + if (strcmp($message, $success)) { + print_r($message); + } + } else { // OCBC 17 might or might not exist - if ( strcmp( $message, $success ) ) - { - if ( strpos( $message, $expected ) === false ) - print_r( $message ); + if (strcmp($message, $success)) { + if (strpos($message, $expected) === false) { + print_r($message); + } } } } -function test_wrong_odbc() +function testWrongODBC() { - global $msodbcsql_maj; + global $msodbcsqlMaj; // TODO: this will change once ODBC 17 is officially released $value = "ODBC Driver 17 for SQL Server"; - if ( $msodbcsql_maj == 17 || $msodbcsql_maj < 13 ) - { + if ($msodbcsqlMaj == 17 || $msodbcsqlMaj < 13) { $value = "ODBC Driver 13 for SQL Server"; } $connectionOptions = "Driver = $value;"; $expected = "The specified ODBC Driver is not found."; - connect_verify_output( $connectionOptions, $expected ); + connectVerifyOutput($connectionOptions, $expected); } ?> diff --git a/test/functional/sqlsrv/sqlsrv_connect_driver.phpt b/test/functional/sqlsrv/sqlsrv_connect_driver.phpt index 27032b07..b3c57cab 100644 --- a/test/functional/sqlsrv/sqlsrv_connect_driver.phpt +++ b/test/functional/sqlsrv/sqlsrv_connect_driver.phpt @@ -4,8 +4,8 @@ Test new connection keyword Driver with valid and invalid values --FILE-- $database, "UID"=>$userName, "PWD"=>$userPassword); $conn = sqlsrv_connect($server, $connectionOptions); @@ -13,36 +13,37 @@ if ($conn === false) { print_r(sqlsrv_errors()); } -$msodbcsql_ver = sqlsrv_client_info($conn)['DriverVer']; -$msodbcsql_maj = explode(".", $msodbcsql_ver)[0]; +$msodbcsqlVer = sqlsrv_client_info($conn)['DriverVer']; +$msodbcsqlMaj = explode(".", $msodbcsqlVer)[0]; sqlsrv_close($conn); // start test -test_valid_values( $msodbcsql_maj, $server, $connectionOptions ); -test_invalid_values( $msodbcsql_maj, $server, $connectionOptions ); -test_encrypted_with_odbc( $msodbcsql_maj, $server, $connectionOptions ); -test_wrong_odbc( $msodbcsql_maj, $server, $connectionOptions ); +testValidValues($msodbcsqlMaj, $server, $connectionOptions); +testInvalidValues($msodbcsqlMaj, $server, $connectionOptions); +testEncryptedWithODBC($msodbcsqlMaj, $server, $connectionOptions); +testWrongODBC($msodbcsqlMaj, $server, $connectionOptions); echo "Done"; // end test /////////////////////////// -function connect_verify_output( $server, $connectionOptions, $expected = '' ) +function connectVerifyOutput($server, $connectionOptions, $expected = '') { $conn = sqlsrv_connect($server, $connectionOptions); if ($conn === false) { - if( strpos(sqlsrv_errors($conn)[0]['message'], $expected) === false ) + if(strpos(sqlsrv_errors($conn)[0]['message'], $expected) === false) { print_r(sqlsrv_errors()); } } } -function test_valid_values( $msodbcsql_maj, $server, $connectionOptions ) +function testValidValues($msodbcsqlMaj, $server, $connectionOptions) { $value = ""; + // The major version number of ODBC 11 can be 11 or 12 // Test with {} - switch ( $msodbcsql_maj ) + switch ($msodbcsqlMaj) { case 17: $value = "{ODBC Driver 17 for SQL Server}"; @@ -58,10 +59,10 @@ function test_valid_values( $msodbcsql_maj, $server, $connectionOptions ) $value = "invalid value"; } $connectionOptions['Driver']=$value; - connect_verify_output( $server, $connectionOptions ); + connectVerifyOutput($server, $connectionOptions); // Test without {} - switch ( $msodbcsql_maj ) + switch ($msodbcsqlMaj) { case 17: $value = "ODBC Driver 17 for SQL Server"; @@ -78,39 +79,31 @@ function test_valid_values( $msodbcsql_maj, $server, $connectionOptions ) } $connectionOptions['Driver']=$value; - connect_verify_output( $server, $connectionOptions ); + connectVerifyOutput($server, $connectionOptions); } -function test_invalid_values( $msodbcsql_maj, $server, $connectionOptions ) +function testInvalidValues($msodbcsqlMaj, $server, $connectionOptions) { - // test invalid value - $value = "{SQL Server Native Client 11.0}"; - $connectionOptions['Driver']=$value; - $expected = "Invalid value $value was specified for Driver option."; - connect_verify_output( $server, $connectionOptions, $expected ); + $values = array("{SQL Server Native Client 11.0}", + "SQL Server Native Client 11.0", + "ODBC Driver 00 for SQL Server"); - $value = "SQL Server Native Client 11.0"; - $connectionOptions['Driver']=$value; - $expected = "Invalid value $value was specified for Driver option."; - connect_verify_output( $server, $connectionOptions, $expected ); - - $value = "ODBC Driver 00 for SQL Server"; - $connectionOptions['Driver']=$value; - $expected = "Invalid value $value was specified for Driver option."; - connect_verify_output( $server, $connectionOptions, $expected ); - - $value = 123; - $connectionOptions['Driver']=$value; - $expected = "Invalid value type for option Driver was specified. String type was expected."; - connect_verify_output( $server, $connectionOptions, $expected ); - - $value = false; - $connectionOptions['Driver']=$value; - $expected = "Invalid value type for option Driver was specified. String type was expected."; - connect_verify_output( $server, $connectionOptions, $expected ); + foreach ($values as $value) { + $connectionOptions['Driver']=$value; + $expected = "Invalid value $value was specified for Driver option."; + connectVerifyOutput($server, $connectionOptions, $expected); + } + + $values = array(123, false); + + foreach ($values as $value) { + $connectionOptions['Driver']=$value; + $expected = "Invalid value type for option Driver was specified. String type was expected."; + connectVerifyOutput($server, $connectionOptions, $expected); + } } -function test_encrypted_with_odbc( $msodbcsql_maj, $server, $connectionOptions ) +function testEncryptedWithODBC($msodbcsqlMaj, $server, $connectionOptions) { $value = "ODBC Driver 13 for SQL Server"; $connectionOptions['Driver']=$value; @@ -118,7 +111,7 @@ function test_encrypted_with_odbc( $msodbcsql_maj, $server, $connectionOptions ) $expected = "The Always Encrypted feature requires Microsoft ODBC Driver 17 for SQL Server."; - connect_verify_output( $server, $connectionOptions, $expected ); + connectVerifyOutput($server, $connectionOptions, $expected); // TODO: the following block will change once ODBC 17 is officially released $value = "ODBC Driver 17 for SQL Server"; @@ -133,29 +126,29 @@ function test_encrypted_with_odbc( $msodbcsql_maj, $server, $connectionOptions ) if ($conn === false) $message = sqlsrv_errors($conn)[0]['message']; - if ( $msodbcsql_maj == 17 ) + if ($msodbcsqlMaj == 17) { // this indicates that OCBC 17 is the only available driver - if ( strcmp( $message, $success ) ) - print_r( $message ); + if (strcmp($message, $success)) + print_r($message); } else { // OCBC 17 might or might not exist - if ( strcmp( $message, $success ) ) + if (strcmp($message, $success)) { - if ( strpos( $message, $expected ) === false ) - print_r( $message ); + if (strpos($message, $expected) === false) + print_r($message); } } } -function test_wrong_odbc( $msodbcsql_maj, $server, $connectionOptions ) +function testWrongODBC($msodbcsqlMaj, $server, $connectionOptions) { // TODO: this will change once ODBC 17 is officially released $value = "ODBC Driver 17 for SQL Server"; - if ( $msodbcsql_maj == 17 || $msodbcsql_maj < 13 ) + if ($msodbcsqlMaj == 17 || $msodbcsqlMaj < 13) { $value = "ODBC Driver 13 for SQL Server"; } @@ -163,7 +156,7 @@ function test_wrong_odbc( $msodbcsql_maj, $server, $connectionOptions ) $connectionOptions['Driver']=$value; $expected = "The specified ODBC Driver is not found."; - connect_verify_output( $server, $connectionOptions, $expected ); + connectVerifyOutput($server, $connectionOptions, $expected); } ?>