modified core_sqlsrv_connect based on review comments

This commit is contained in:
Jenny Tam 2017-10-02 16:13:32 -07:00
parent f9cc00791a
commit afb8167995

View file

@ -150,38 +150,16 @@ 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 );
if( conn->ce_option.enabled ) { // If column encryption is enabled, must use ODBC driver 17
// when column encryption is enabled, must use ODBC driver 17 if( conn->ce_option.enabled && 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_CE_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_CUSTOM_ERROR( ! core_search_odbc_driver_unix( ODBC_DRIVER_17 ), conn, SQLSRV_ERROR_SPECIFIED_DRIVER_NOT_FOUND ) {
throw core::CoreException();
} }
r = core_odbc_connect( conn, conn_str, is_pooled ); // In non-Windows environment, unixODBC 2.3.4 and unixODBC 2.3.1 return different error states when an ODBC driver exists or not
} // Therefore, it is unreliable to check for a certain sql state error
else { #ifndef _WIN32
// driver not specified, so connect using ODBC 17
// In non-Windows environment, unixODBC 2.3.4 and unixODBC 2.3.1 return different error states
// 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[ODBC_DRIVER_17];
r = core_odbc_connect( conn, conn_str, is_pooled );
}
else {
CHECK_CUSTOM_ERROR( true, conn, SQLSRV_ERROR_CE_DRIVER_REQUIRED, get_processor_arch()) {
throw core::CoreException();
}
}
} // else driver_version not unknown
}
else {
// column encryption NOT enabled
if( conn->driver_version != ODBC_DRIVER_UNKNOWN ) { if( conn->driver_version != ODBC_DRIVER_UNKNOWN ) {
// check if the ODBC driver actually exists, if not, throw an exception // check if the ODBC driver actually exists, if not, throw an exception
CHECK_CUSTOM_ERROR( ! core_search_odbc_driver_unix( conn->driver_version ), conn, SQLSRV_ERROR_SPECIFIED_DRIVER_NOT_FOUND ) { CHECK_CUSTOM_ERROR( ! core_search_odbc_driver_unix( conn->driver_version ), conn, SQLSRV_ERROR_SPECIFIED_DRIVER_NOT_FOUND ) {
@ -190,6 +168,16 @@ 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 {
if( conn->ce_option.enabled ) {
// driver not specified, so check if ODBC 17 exists
CHECK_CUSTOM_ERROR( ! core_search_odbc_driver_unix( ODBC_DRIVER_17 ), conn, SQLSRV_ERROR_CE_DRIVER_REQUIRED, get_processor_arch()) {
throw core::CoreException();
}
conn_str = conn_str + CONNECTION_STRING_DRIVER_NAME[ODBC_DRIVER_17];
r = core_odbc_connect( conn, conn_str, is_pooled );
}
else { else {
// skip ODBC 11 in a non-Windows environment -- only available in Red Hat / SUSE (preview) // 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 // 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
@ -207,66 +195,48 @@ sqlsrv_conn* core_sqlsrv_connect( _In_ sqlsrv_context& henv_cp, _In_ sqlsrv_cont
} }
std::string conn_str_driver = conn_str + CONNECTION_STRING_DRIVER_NAME[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 ce_option enabled } // else ce_option enabled
} // else driver_version not unknown
#else #else
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( core_compare_error_state( conn, r, "IM002" ) ) { // sql state IM002 means that the specified ODBC driver is not found
// 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_SPECIFIED_DRIVER_NOT_FOUND ) {
CHECK_CUSTOM_ERROR( true, conn, SQLSRV_ERROR_SPECIFIED_DRIVER_NOT_FOUND ) {
throw core::CoreException(); throw core::CoreException();
} }
} }
}
else { else {
if( conn->ce_option.enabled ) {
// driver not specified, so connect using ODBC 17 // driver not specified, so connect using ODBC 17
conn_str = conn_str + CONNECTION_STRING_DRIVER_NAME[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 );
// sql state IM002 means that the specified ODBC driver is not installed // sql state IM002 means that the specified ODBC driver is not found
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_CE_DRIVER_REQUIRED, get_processor_arch() ) {
throw core::CoreException(); throw core::CoreException();
} }
} }
}
else {
// column encryption NOT enabled
if( conn->driver_version != ODBC_DRIVER_UNKNOWN ) {
r = core_odbc_connect( conn, conn_str, is_pooled );
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() ) {
throw core::CoreException();
}
}
}
else { else {
bool done = false; bool done = false;
for( short i = DRIVER_VERSION::FIRST; i <= DRIVER_VERSION::LAST && ! done; ++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]; 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 ) || ! core_compare_error_state( conn, r, "IM002" ) ) {
// sql state IM002 means that the specified ODBC driver is not found
// something else went wrong, exit the loop now
done = true; done = true;
} }
else if( core_compare_error_state( conn, r, "IM002" ) ) { else {
if(i == DRIVER_VERSION::LAST ) { // did it fail to find the last valid ODBC driver?
// sql state IM002 means that the specified ODBC driver is not installed CHECK_CUSTOM_ERROR( ( i == DRIVER_VERSION::LAST ), conn, SQLSRV_ERROR_DRIVER_NOT_INSTALLED, get_processor_arch()) {
// 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(); 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
} // else driver_version not unknown
#endif // !_WIN32 #endif // !_WIN32
CHECK_SQL_ERROR( r, conn ) { CHECK_SQL_ERROR( r, conn ) {