Made changes as per review comments
This commit is contained in:
parent
302f8540c8
commit
bbc2701140
|
@ -398,7 +398,7 @@ pdo_error PDO_ERRORS[] = {
|
||||||
{ IMSSP, (SQLCHAR*) "Invalid value for loading a custom keystore provider.", -77, false}
|
{ 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 }
|
{ IMSSP, (SQLCHAR*) "The Always Encrypted feature requires Microsoft ODBC Driver 17 for SQL Server.", -78, false }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -110,9 +110,9 @@ sqlsrv_conn* core_sqlsrv_connect( _In_ sqlsrv_context& henv_cp, _In_ sqlsrv_cont
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Due to the limitations on connection pooling in unixODBC 2.3.1 driver manager, we do not consider
|
// 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.
|
// 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.
|
// Instead, MSPHPSQL connection pooling is set according to the ODBCINST.INI file in [ODBC] section.
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
char pooling_string[ 128 ] = {0};
|
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;
|
is_pooled = true;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// check the connection pooling setting to determine which henv to use to allocate the connection handle
|
// 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
|
// 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.
|
// it in build_connection_string_and_set_conn_attr.
|
||||||
|
|
||||||
if( options_ht && zend_hash_num_elements( options_ht ) > 0 ) {
|
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 );
|
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 ) {
|
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 ) {
|
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();
|
throw core::CoreException();
|
||||||
}
|
}
|
||||||
|
#ifndef _WIN32
|
||||||
// check if ODBC 17 actually exists, if not, throw an exception
|
// 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 ) {
|
CHECK_CUSTOM_ERROR( ! core_search_odbc_driver_unix( ODBC_DRIVER_17 ), conn, SQLSRV_ERROR_SPECIFIED_DRIVER_NOT_FOUND ) {
|
||||||
throw core::CoreException();
|
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.
|
// 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.
|
// Thus, we will simply throw an exception.
|
||||||
if( core_search_odbc_driver_unix( ODBC_DRIVER_17 ) ) {
|
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 );
|
r = core_odbc_connect( conn, conn_str, is_pooled );
|
||||||
}
|
}
|
||||||
else {
|
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();
|
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 );
|
r = core_odbc_connect( conn, conn_str, is_pooled );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DRIVER_VERSION odbc_version = ODBC_DRIVER_UNKNOWN;
|
// skip ODBC 11 in a non-Windows environment -- only available in Red Hat / SUSE (preview)
|
||||||
for( short i = DRIVER_VERSION::FIRST; i <= DRIVER_VERSION::LAST; ++i ) {
|
// 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
|
||||||
// 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;
|
|
||||||
|
|
||||||
if( core_search_odbc_driver_unix( DRIVER_VERSION( i ) ) ) {
|
DRIVER_VERSION odbc_version = ODBC_DRIVER_UNKNOWN;
|
||||||
odbc_version = DRIVER_VERSION( i );
|
if( core_search_odbc_driver_unix( ODBC_DRIVER_13 ) ) {
|
||||||
break;
|
odbc_version = ODBC_DRIVER_13;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
CHECK_CUSTOM_ERROR( odbc_version == ODBC_DRIVER_UNKNOWN, conn, SQLSRV_ERROR_DRIVER_NOT_INSTALLED, get_processor_arch()) {
|
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() ) {
|
||||||
throw core::CoreException();
|
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 );
|
r = core_odbc_connect( conn, conn_str_driver, is_pooled );
|
||||||
} // else driver_version not unknown
|
} // else driver_version not unknown
|
||||||
} // else ce_option enabled
|
} // else ce_option enabled
|
||||||
#else
|
#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 );
|
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
|
// sql state IM002 means that the specified ODBC driver is not installed
|
||||||
CHECK_CUSTOM_ERROR( true, conn, SQLSRV_ERROR_SPECIFIED_DRIVER_NOT_FOUND ) {
|
CHECK_CUSTOM_ERROR( true, conn, SQLSRV_ERROR_SPECIFIED_DRIVER_NOT_FOUND ) {
|
||||||
throw core::CoreException();
|
throw core::CoreException();
|
||||||
|
@ -230,14 +221,12 @@ sqlsrv_conn* core_sqlsrv_connect( _In_ sqlsrv_context& henv_cp, _In_ sqlsrv_cont
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// driver not specified, so connect using ODBC 17
|
// 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 );
|
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
|
||||||
// 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() ) {
|
||||||
CHECK_CUSTOM_ERROR( core_compare_error_state( conn, r, "IM002" ) , conn, SQLSRV_ERROR_AE_DRIVER_REQUIRED, get_processor_arch() ) {
|
throw core::CoreException();
|
||||||
throw core::CoreException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -246,33 +235,35 @@ sqlsrv_conn* core_sqlsrv_connect( _In_ sqlsrv_context& henv_cp, _In_ sqlsrv_cont
|
||||||
if( conn->driver_version != ODBC_DRIVER_UNKNOWN ) {
|
if( conn->driver_version != ODBC_DRIVER_UNKNOWN ) {
|
||||||
r = core_odbc_connect( conn, conn_str, is_pooled );
|
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
|
// 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();
|
throw core::CoreException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for( short i = DRIVER_VERSION::FIRST; i <= DRIVER_VERSION::LAST; ++i ) {
|
bool done = false;
|
||||||
std::string conn_str_driver = conn_str + CONNECTION_STRING_DRIVER_NAME[ DRIVER_VERSION(i) ];
|
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 );
|
r = core_odbc_connect( conn, conn_str_driver, is_pooled );
|
||||||
|
|
||||||
if( SQL_SUCCEEDED( r ) ) {
|
if( SQL_SUCCEEDED( r ) ) {
|
||||||
// successfully connected!
|
done = true;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
else if(! core_compare_error_state( conn, r, "IM002" ) ) {
|
else if( core_compare_error_state( conn, r, "IM002" ) ) {
|
||||||
// sql state IM002 means that the specified ODBC driver is not installed
|
if(i == DRIVER_VERSION::LAST ) {
|
||||||
// something went wrong other than missing the ODBC driver
|
// sql state IM002 means that the specified ODBC driver is not installed
|
||||||
break;
|
// failed to connect even using the last valid ODBC driver
|
||||||
}
|
CHECK_CUSTOM_ERROR( true, conn, SQLSRV_ERROR_DRIVER_NOT_INSTALLED, get_processor_arch()) {
|
||||||
else if( i == DRIVER_VERSION::LAST ) {
|
throw core::CoreException();
|
||||||
// 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 {
|
||||||
|
// something else went wrong other than missing the ODBC driver, exit the loop now
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
} // for
|
} // for
|
||||||
}
|
}
|
||||||
} // else ce_option enabled
|
} // else ce_option enabled
|
||||||
|
@ -349,11 +340,7 @@ bool core_compare_error_state( _In_ sqlsrv_conn* conn, _In_ SQLRETURN rc, _In_
|
||||||
SQLSMALLINT len;
|
SQLSMALLINT len;
|
||||||
SQLRETURN sr = SQLGetDiagField( SQL_HANDLE_DBC, conn->handle(), 1, SQL_DIAG_SQLSTATE, state, SQL_SQLSTATE_BUFSIZE, &len );
|
SQLRETURN sr = SQLGetDiagField( SQL_HANDLE_DBC, conn->handle(), 1, SQL_DIAG_SQLSTATE, state, SQL_SQLSTATE_BUFSIZE, &len );
|
||||||
|
|
||||||
bool same = false;
|
return ( SQL_SUCCEEDED(sr) && ! strcmp(error_state, reinterpret_cast<char*>( state ) ) );
|
||||||
if( SQL_SUCCEEDED(sr) && ! strcmp(error_state, reinterpret_cast<char*>( state ) ) )
|
|
||||||
same = true;
|
|
||||||
|
|
||||||
return same;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// core_search_odbc_driver_unix
|
// 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 )
|
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 cbBufMax = DEFAULT_CONN_STR_LEN;
|
||||||
WORD cbBufOut;
|
WORD cbBufOut;
|
||||||
char *pszBuf = szBuf;
|
char *pszBuf = szBuf;
|
||||||
|
@ -379,7 +366,7 @@ bool core_search_odbc_driver_unix( _In_ DRIVER_VERSION driver_version )
|
||||||
}
|
}
|
||||||
|
|
||||||
// extract the ODBC driver name
|
// 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 pos1 = driver.find_first_of("{");
|
||||||
std::size_t pos2 = driver.find_first_of("}");
|
std::size_t pos2 = driver.find_first_of("}");
|
||||||
std::string driver_str = driver.substr( pos1 + 1, pos2 - pos1 - 1);
|
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 )
|
if( strstr( pszBuf, driver_name ) != 0 )
|
||||||
{
|
{
|
||||||
found_driver = true;
|
return true;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
// get the next driver
|
// get the next driver
|
||||||
pszBuf = strchr( pszBuf, '\0' ) + 1;
|
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
|
while( pszBuf[1] != '\0' ); // end when there are two consecutive null characters
|
||||||
#endif // !_WIN32
|
#endif // !_WIN32
|
||||||
|
|
||||||
return found_driver;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// core_odbc_connect
|
// core_odbc_connect
|
||||||
|
@ -429,19 +415,17 @@ SQLRETURN core_odbc_connect( _Inout_ sqlsrv_conn* conn, _Inout_ std::string& con
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
// unixODBC 2.3.1 requires a non-wide SQLDriverConnect call while pooling enabled.
|
// 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
|
// 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 );
|
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<SQLSMALLINT>( wconn_len ), NULL, 0, &output_conn_size, SQL_DRIVER_NOPROMPT );
|
r = SQLDriverConnectW( conn->handle(), NULL, wconn_string, static_cast<SQLSMALLINT>( wconn_len ), NULL, 0, &output_conn_size, SQL_DRIVER_NOPROMPT );
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
r = SQLDriverConnectW( conn->handle(), NULL, wconn_string, static_cast<SQLSMALLINT>( wconn_len ), NULL, 0, &output_conn_size, SQL_DRIVER_NOPROMPT );
|
r = SQLDriverConnectW( conn->handle(), NULL, wconn_string, static_cast<SQLSMALLINT>( wconn_len ), NULL, 0, &output_conn_size, SQL_DRIVER_NOPROMPT );
|
||||||
#endif // !_WIN32
|
#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
|
memset( wconn_string, 0, wconn_len * sizeof( SQLWCHAR )); // wconn_len is the number of characters, not bytes
|
||||||
conn_str.clear();
|
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 );
|
common_conn_str_append_func( option->odbc_name, val_str, val_len, driver_option TSRMLS_CC );
|
||||||
|
|
||||||
conn->driver_version = ODBC_DRIVER_UNKNOWN;
|
conn->driver_version = ODBC_DRIVER_UNKNOWN;
|
||||||
for ( short i = DRIVER_VERSION::FIRST; i <= DRIVER_VERSION::LAST; ++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[ DRIVER_VERSION( i ) ];
|
std::string driver_name = CONNECTION_STRING_DRIVER_NAME[i];
|
||||||
|
|
||||||
if (! driver_name.compare( driver_option ) ) {
|
if (! driver_name.compare( driver_option ) ) {
|
||||||
conn->driver_version = DRIVER_VERSION( i );
|
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();
|
throw core::CoreException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1642,7 +1642,7 @@ enum SQLSRV_ERROR_CODES {
|
||||||
|
|
||||||
SQLSRV_ERROR_ODBC,
|
SQLSRV_ERROR_ODBC,
|
||||||
SQLSRV_ERROR_DRIVER_NOT_INSTALLED,
|
SQLSRV_ERROR_DRIVER_NOT_INSTALLED,
|
||||||
SQLSRV_ERROR_AE_DRIVER_REQUIRED,
|
SQLSRV_ERROR_CE_DRIVER_REQUIRED,
|
||||||
SQLSRV_ERROR_CONNECT_INVALID_DRIVER,
|
SQLSRV_ERROR_CONNECT_INVALID_DRIVER,
|
||||||
SQLSRV_ERROR_SPECIFIED_DRIVER_NOT_FOUND,
|
SQLSRV_ERROR_SPECIFIED_DRIVER_NOT_FOUND,
|
||||||
SQLSRV_ERROR_ZEND_HASH,
|
SQLSRV_ERROR_ZEND_HASH,
|
||||||
|
|
|
@ -397,7 +397,7 @@ ss_error SS_ERRORS[] = {
|
||||||
{ IMSSP, (SQLCHAR*) "Invalid value for loading a custom keystore provider.", -104, false}
|
{ 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 }
|
{ IMSSP, (SQLCHAR*) "The Always Encrypted feature requires Microsoft ODBC Driver 17 for SQL Server.", -105, false }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,58 +4,51 @@ Test new connection keyword Driver with valid and invalid values
|
||||||
<?php require('skipif.inc'); ?>
|
<?php require('skipif.inc'); ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
require_once( 'MsSetup.inc' );
|
require_once('MsSetup.inc');
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
$conn = new PDO("sqlsrv:server = $server", $uid, $pwd);
|
||||||
$conn = new PDO( "sqlsrv:server = $server", $uid, $pwd );
|
$msodbcsqlVer = $conn->getAttribute(PDO::ATTR_CLIENT_VERSION)['DriverVer'];
|
||||||
$msodbcsql_ver = $conn->getAttribute( PDO::ATTR_CLIENT_VERSION )['DriverVer'];
|
$msodbcsqlMaj = explode(".", $msodbcsqlVer)[0];
|
||||||
$msodbcsql_maj = explode(".", $msodbcsql_ver)[0];
|
} catch(PDOException $e) {
|
||||||
}
|
|
||||||
catch( PDOException $e )
|
|
||||||
{
|
|
||||||
echo "Failed to connect\n";
|
echo "Failed to connect\n";
|
||||||
print_r( $e->getMessage() );
|
print_r($e->getMessage());
|
||||||
echo "\n";
|
echo "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
$conn = null;
|
$conn = null;
|
||||||
|
|
||||||
// start test
|
// start test
|
||||||
test_valid_values();
|
testValidValues();
|
||||||
test_invalid_values();
|
testInvalidValues();
|
||||||
test_encrypted_with_odbc();
|
testEncryptedWithODBC();
|
||||||
test_wrong_odbc();
|
testWrongODBC();
|
||||||
echo "Done";
|
echo "Done";
|
||||||
// end test
|
// end test
|
||||||
|
|
||||||
///////////////////////////
|
///////////////////////////
|
||||||
function connect_verify_output( $connectionOptions, $expected = '' )
|
function connectVerifyOutput($connectionOptions, $expected = '')
|
||||||
{
|
{
|
||||||
global $server, $uid, $pwd;
|
global $server, $uid, $pwd;
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
$conn = new PDO("sqlsrv:server = $server ; $connectionOptions", $uid, $pwd);
|
||||||
$conn = new PDO( "sqlsrv:server = $server ; $connectionOptions", $uid, $pwd );
|
} catch(PDOException $e) {
|
||||||
}
|
if (strpos($e->getMessage(), $expected) === false) {
|
||||||
catch( PDOException $e )
|
print_r($e->getMessage());
|
||||||
{
|
|
||||||
if ( strpos($e->getMessage(), $expected ) === false )
|
|
||||||
{
|
|
||||||
print_r( $e->getMessage() );
|
|
||||||
echo "\n";
|
echo "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_valid_values()
|
function testValidValues()
|
||||||
{
|
{
|
||||||
global $msodbcsql_maj;
|
global $msodbcsqlMaj;
|
||||||
|
|
||||||
$value = "";
|
$value = "";
|
||||||
|
// The major version number of ODBC 11 can be 11 or 12
|
||||||
// Test with {}
|
// Test with {}
|
||||||
switch ( $msodbcsql_maj )
|
switch ($msodbcsqlMaj) {
|
||||||
{
|
|
||||||
case 17:
|
case 17:
|
||||||
$value = "{ODBC Driver 17 for SQL Server}";
|
$value = "{ODBC Driver 17 for SQL Server}";
|
||||||
break;
|
break;
|
||||||
|
@ -70,11 +63,10 @@ function test_valid_values()
|
||||||
$value = "invalid value";
|
$value = "invalid value";
|
||||||
}
|
}
|
||||||
$connectionOptions = "Driver = $value";
|
$connectionOptions = "Driver = $value";
|
||||||
connect_verify_output( $connectionOptions );
|
connectVerifyOutput($connectionOptions);
|
||||||
|
|
||||||
// Test without {}
|
// Test without {}
|
||||||
switch ( $msodbcsql_maj )
|
switch ($msodbcsqlMaj) {
|
||||||
{
|
|
||||||
case 17:
|
case 17:
|
||||||
$value = "ODBC Driver 17 for SQL Server";
|
$value = "ODBC Driver 17 for SQL Server";
|
||||||
break;
|
break;
|
||||||
|
@ -90,47 +82,33 @@ function test_valid_values()
|
||||||
}
|
}
|
||||||
|
|
||||||
$connectionOptions = "Driver = $value";
|
$connectionOptions = "Driver = $value";
|
||||||
connect_verify_output( $connectionOptions );
|
connectVerifyOutput($connectionOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_invalid_values()
|
function testInvalidValues()
|
||||||
{
|
{
|
||||||
// test invalid value
|
$values = array("{SQL Server Native Client 11.0}",
|
||||||
$value = "{SQL Server Native Client 11.0}";
|
"SQL Server Native Client 11.0",
|
||||||
$connectionOptions = "Driver = $value";
|
"ODBC Driver 00 for SQL Server",
|
||||||
$expected = "Invalid value $value was specified for Driver option.";
|
123,
|
||||||
connect_verify_output( $connectionOptions, $expected );
|
false);
|
||||||
|
|
||||||
$value = "SQL Server Native Client 11.0";
|
foreach ($values as $value) {
|
||||||
$connectionOptions = "Driver = $value";
|
$connectionOptions = "Driver = $value";
|
||||||
$expected = "Invalid value $value was specified for Driver option.";
|
$expected = "Invalid value $value was specified for Driver option.";
|
||||||
connect_verify_output( $connectionOptions, $expected );
|
connectVerifyOutput($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 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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";
|
$value = "ODBC Driver 13 for SQL Server";
|
||||||
$connectionOptions = "Driver = $value; ColumnEncryption = Enabled;";
|
$connectionOptions = "Driver = $value; ColumnEncryption = Enabled;";
|
||||||
$expected = "The Always Encrypted feature requires Microsoft ODBC Driver 17 for SQL Server.";
|
$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
|
// TODO: the following block will change once ODBC 17 is officially released
|
||||||
$value = "ODBC Driver 17 for SQL Server";
|
$value = "ODBC Driver 17 for SQL Server";
|
||||||
|
@ -139,46 +117,40 @@ function test_encrypted_with_odbc()
|
||||||
$success = "Successfully connected with column encryption.";
|
$success = "Successfully connected with column encryption.";
|
||||||
$expected = "The specified ODBC Driver is not found.";
|
$expected = "The specified ODBC Driver is not found.";
|
||||||
$message = $success;
|
$message = $success;
|
||||||
try
|
try {
|
||||||
{
|
$conn = new PDO("sqlsrv:server = $server ; $connectionOptions", $uid, $pwd);
|
||||||
$conn = new PDO( "sqlsrv:server = $server ; $connectionOptions", $uid, $pwd );
|
} catch(PDOException $e) {
|
||||||
}
|
|
||||||
catch( PDOException $e )
|
|
||||||
{
|
|
||||||
$message = $e->getMessage();
|
$message = $e->getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $msodbcsql_maj == 17 )
|
if ($msodbcsqlMaj == 17) {
|
||||||
{
|
|
||||||
// this indicates that OCBC 17 is the only available driver
|
// this indicates that OCBC 17 is the only available driver
|
||||||
if ( strcmp( $message, $success ) )
|
if (strcmp($message, $success)) {
|
||||||
print_r( $message );
|
print_r($message);
|
||||||
}
|
}
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
// OCBC 17 might or might not exist
|
// OCBC 17 might or might not exist
|
||||||
if ( strcmp( $message, $success ) )
|
if (strcmp($message, $success)) {
|
||||||
{
|
if (strpos($message, $expected) === false) {
|
||||||
if ( strpos( $message, $expected ) === false )
|
print_r($message);
|
||||||
print_r( $message );
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_wrong_odbc()
|
function testWrongODBC()
|
||||||
{
|
{
|
||||||
global $msodbcsql_maj;
|
global $msodbcsqlMaj;
|
||||||
|
|
||||||
// TODO: this will change once ODBC 17 is officially released
|
// TODO: this will change once ODBC 17 is officially released
|
||||||
$value = "ODBC Driver 17 for SQL Server";
|
$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";
|
$value = "ODBC Driver 13 for SQL Server";
|
||||||
}
|
}
|
||||||
$connectionOptions = "Driver = $value;";
|
$connectionOptions = "Driver = $value;";
|
||||||
$expected = "The specified ODBC Driver is not found.";
|
$expected = "The specified ODBC Driver is not found.";
|
||||||
|
|
||||||
connect_verify_output( $connectionOptions, $expected );
|
connectVerifyOutput($connectionOptions, $expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -4,8 +4,8 @@ Test new connection keyword Driver with valid and invalid values
|
||||||
<?php require('skipif.inc'); ?>
|
<?php require('skipif.inc'); ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
sqlsrv_configure( 'WarningsReturnAsErrors', 0 );
|
sqlsrv_configure('WarningsReturnAsErrors', 0);
|
||||||
require( 'MsSetup.inc' );
|
require('MsSetup.inc');
|
||||||
|
|
||||||
$connectionOptions = array("Database"=>$database, "UID"=>$userName, "PWD"=>$userPassword);
|
$connectionOptions = array("Database"=>$database, "UID"=>$userName, "PWD"=>$userPassword);
|
||||||
$conn = sqlsrv_connect($server, $connectionOptions);
|
$conn = sqlsrv_connect($server, $connectionOptions);
|
||||||
|
@ -13,36 +13,37 @@ if ($conn === false)
|
||||||
{
|
{
|
||||||
print_r(sqlsrv_errors());
|
print_r(sqlsrv_errors());
|
||||||
}
|
}
|
||||||
$msodbcsql_ver = sqlsrv_client_info($conn)['DriverVer'];
|
$msodbcsqlVer = sqlsrv_client_info($conn)['DriverVer'];
|
||||||
$msodbcsql_maj = explode(".", $msodbcsql_ver)[0];
|
$msodbcsqlMaj = explode(".", $msodbcsqlVer)[0];
|
||||||
sqlsrv_close($conn);
|
sqlsrv_close($conn);
|
||||||
|
|
||||||
// start test
|
// start test
|
||||||
test_valid_values( $msodbcsql_maj, $server, $connectionOptions );
|
testValidValues($msodbcsqlMaj, $server, $connectionOptions);
|
||||||
test_invalid_values( $msodbcsql_maj, $server, $connectionOptions );
|
testInvalidValues($msodbcsqlMaj, $server, $connectionOptions);
|
||||||
test_encrypted_with_odbc( $msodbcsql_maj, $server, $connectionOptions );
|
testEncryptedWithODBC($msodbcsqlMaj, $server, $connectionOptions);
|
||||||
test_wrong_odbc( $msodbcsql_maj, $server, $connectionOptions );
|
testWrongODBC($msodbcsqlMaj, $server, $connectionOptions);
|
||||||
echo "Done";
|
echo "Done";
|
||||||
// end test
|
// end test
|
||||||
|
|
||||||
///////////////////////////
|
///////////////////////////
|
||||||
function connect_verify_output( $server, $connectionOptions, $expected = '' )
|
function connectVerifyOutput($server, $connectionOptions, $expected = '')
|
||||||
{
|
{
|
||||||
$conn = sqlsrv_connect($server, $connectionOptions);
|
$conn = sqlsrv_connect($server, $connectionOptions);
|
||||||
if ($conn === false)
|
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());
|
print_r(sqlsrv_errors());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_valid_values( $msodbcsql_maj, $server, $connectionOptions )
|
function testValidValues($msodbcsqlMaj, $server, $connectionOptions)
|
||||||
{
|
{
|
||||||
$value = "";
|
$value = "";
|
||||||
|
// The major version number of ODBC 11 can be 11 or 12
|
||||||
// Test with {}
|
// Test with {}
|
||||||
switch ( $msodbcsql_maj )
|
switch ($msodbcsqlMaj)
|
||||||
{
|
{
|
||||||
case 17:
|
case 17:
|
||||||
$value = "{ODBC Driver 17 for SQL Server}";
|
$value = "{ODBC Driver 17 for SQL Server}";
|
||||||
|
@ -58,10 +59,10 @@ function test_valid_values( $msodbcsql_maj, $server, $connectionOptions )
|
||||||
$value = "invalid value";
|
$value = "invalid value";
|
||||||
}
|
}
|
||||||
$connectionOptions['Driver']=$value;
|
$connectionOptions['Driver']=$value;
|
||||||
connect_verify_output( $server, $connectionOptions );
|
connectVerifyOutput($server, $connectionOptions);
|
||||||
|
|
||||||
// Test without {}
|
// Test without {}
|
||||||
switch ( $msodbcsql_maj )
|
switch ($msodbcsqlMaj)
|
||||||
{
|
{
|
||||||
case 17:
|
case 17:
|
||||||
$value = "ODBC Driver 17 for SQL Server";
|
$value = "ODBC Driver 17 for SQL Server";
|
||||||
|
@ -78,39 +79,31 @@ function test_valid_values( $msodbcsql_maj, $server, $connectionOptions )
|
||||||
}
|
}
|
||||||
|
|
||||||
$connectionOptions['Driver']=$value;
|
$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
|
$values = array("{SQL Server Native Client 11.0}",
|
||||||
$value = "{SQL Server Native Client 11.0}";
|
"SQL Server Native Client 11.0",
|
||||||
$connectionOptions['Driver']=$value;
|
"ODBC Driver 00 for SQL Server");
|
||||||
$expected = "Invalid value $value was specified for Driver option.";
|
|
||||||
connect_verify_output( $server, $connectionOptions, $expected );
|
|
||||||
|
|
||||||
$value = "SQL Server Native Client 11.0";
|
foreach ($values as $value) {
|
||||||
$connectionOptions['Driver']=$value;
|
$connectionOptions['Driver']=$value;
|
||||||
$expected = "Invalid value $value was specified for Driver option.";
|
$expected = "Invalid value $value was specified for Driver option.";
|
||||||
connect_verify_output( $server, $connectionOptions, $expected );
|
connectVerifyOutput($server, $connectionOptions, $expected);
|
||||||
|
}
|
||||||
|
|
||||||
$value = "ODBC Driver 00 for SQL Server";
|
$values = array(123, false);
|
||||||
$connectionOptions['Driver']=$value;
|
|
||||||
$expected = "Invalid value $value was specified for Driver option.";
|
|
||||||
connect_verify_output( $server, $connectionOptions, $expected );
|
|
||||||
|
|
||||||
$value = 123;
|
foreach ($values as $value) {
|
||||||
$connectionOptions['Driver']=$value;
|
$connectionOptions['Driver']=$value;
|
||||||
$expected = "Invalid value type for option Driver was specified. String type was expected.";
|
$expected = "Invalid value type for option Driver was specified. String type was expected.";
|
||||||
connect_verify_output( $server, $connectionOptions, $expected );
|
connectVerifyOutput($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 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_encrypted_with_odbc( $msodbcsql_maj, $server, $connectionOptions )
|
function testEncryptedWithODBC($msodbcsqlMaj, $server, $connectionOptions)
|
||||||
{
|
{
|
||||||
$value = "ODBC Driver 13 for SQL Server";
|
$value = "ODBC Driver 13 for SQL Server";
|
||||||
$connectionOptions['Driver']=$value;
|
$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.";
|
$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
|
// TODO: the following block will change once ODBC 17 is officially released
|
||||||
$value = "ODBC Driver 17 for SQL Server";
|
$value = "ODBC Driver 17 for SQL Server";
|
||||||
|
@ -133,29 +126,29 @@ function test_encrypted_with_odbc( $msodbcsql_maj, $server, $connectionOptions )
|
||||||
if ($conn === false)
|
if ($conn === false)
|
||||||
$message = sqlsrv_errors($conn)[0]['message'];
|
$message = sqlsrv_errors($conn)[0]['message'];
|
||||||
|
|
||||||
if ( $msodbcsql_maj == 17 )
|
if ($msodbcsqlMaj == 17)
|
||||||
{
|
{
|
||||||
// this indicates that OCBC 17 is the only available driver
|
// this indicates that OCBC 17 is the only available driver
|
||||||
if ( strcmp( $message, $success ) )
|
if (strcmp($message, $success))
|
||||||
print_r( $message );
|
print_r($message);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// OCBC 17 might or might not exist
|
// OCBC 17 might or might not exist
|
||||||
if ( strcmp( $message, $success ) )
|
if (strcmp($message, $success))
|
||||||
{
|
{
|
||||||
if ( strpos( $message, $expected ) === false )
|
if (strpos($message, $expected) === false)
|
||||||
print_r( $message );
|
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
|
// TODO: this will change once ODBC 17 is officially released
|
||||||
$value = "ODBC Driver 17 for SQL Server";
|
$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";
|
$value = "ODBC Driver 13 for SQL Server";
|
||||||
}
|
}
|
||||||
|
@ -163,7 +156,7 @@ function test_wrong_odbc( $msodbcsql_maj, $server, $connectionOptions )
|
||||||
$connectionOptions['Driver']=$value;
|
$connectionOptions['Driver']=$value;
|
||||||
$expected = "The specified ODBC Driver is not found.";
|
$expected = "The specified ODBC Driver is not found.";
|
||||||
|
|
||||||
connect_verify_output( $server, $connectionOptions, $expected );
|
connectVerifyOutput($server, $connectionOptions, $expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
Loading…
Reference in a new issue