removed driver_version from conn struct

This commit is contained in:
Hadis-Fard 2017-09-11 16:17:24 -07:00
parent 16c5556340
commit a0e959a6e9
2 changed files with 49 additions and 54 deletions

View file

@ -26,11 +26,8 @@
#include <windows.h>
#include <winver.h>
#endif // _WIN32
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
#ifndef _WIN32
#include <sys/utsname.h>
@ -136,7 +133,7 @@ sqlsrv_conn* core_sqlsrv_connect( _In_ sqlsrv_context& henv_cp, _In_ sqlsrv_cont
if( options_ht && zend_hash_num_elements( options_ht ) > 0 ) {
zval* option_z = NULL;
option_z = zend_hash_index_find(options_ht, SQLSRV_CONN_OPTION_CONN_POOLING);
option_z = zend_hash_index_find( options_ht, SQLSRV_CONN_OPTION_CONN_POOLING );
if ( option_z ) {
// if the option was found and it's not true, then use the non pooled environment handle
if(( Z_TYPE_P( option_z ) == IS_STRING && !core_str_zval_is_true( option_z )) || !zend_is_true( option_z ) ) {
@ -152,28 +149,28 @@ sqlsrv_conn* core_sqlsrv_connect( _In_ sqlsrv_context& henv_cp, _In_ sqlsrv_cont
conn = conn_factory( temp_conn_h, err, driver TSRMLS_CC );
conn->set_func( driver_func );
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 );
bool missing_driver_error = false;
if (conn->is_driver_set) {
if ( conn->is_driver_set ) {
r = core_odbc_connect( conn, conn_str, wconn_string, wconn_len, missing_driver_error, is_pooled);
}
else if (conn->ce_option.enabled) {
conn_str = conn_str + CONNECTION_STRING_DRIVER_NAME[DRIVER_VERSION::ODBC_DRIVER_17];
else if ( conn->ce_option.enabled ) {
conn_str = conn_str + CONNECTION_STRING_DRIVER_NAME[ DRIVER_VERSION::ODBC_DRIVER_17 ];
r = core_odbc_connect( conn, conn_str, wconn_string, wconn_len, missing_driver_error, is_pooled);
CHECK_CUSTOM_ERROR(missing_driver_error, conn, SQLSRV_AE_ERROR_DRIVER_NOT_INSTALLED, get_processor_arch()) {
CHECK_CUSTOM_ERROR( missing_driver_error, conn, SQLSRV_AE_ERROR_DRIVER_NOT_INSTALLED, get_processor_arch()) {
throw core::CoreException();
}
}
else {
for ( std::size_t i = DRIVER_VERSION::ODBC_DRIVER_13; i <= DRIVER_VERSION::LAST; ++i ) {
conn_str = conn_str + CONNECTION_STRING_DRIVER_NAME[DRIVER_VERSION(i)];
r = core_odbc_connect(conn, conn_str, wconn_string, wconn_len, missing_driver_error, is_pooled);
conn_str = conn_str + CONNECTION_STRING_DRIVER_NAME[ DRIVER_VERSION(i) ];
r = core_odbc_connect( conn, conn_str, wconn_string, wconn_len, missing_driver_error, is_pooled );
// if it's a IM002, meaning that the correct ODBC driver is not installed
CHECK_CUSTOM_ERROR(missing_driver_error && (i == DRIVER_VERSION::LAST), conn, SQLSRV_ERROR_DRIVER_NOT_INSTALLED, get_processor_arch()) {
CHECK_CUSTOM_ERROR( missing_driver_error && ( i == DRIVER_VERSION::LAST ), conn, SQLSRV_ERROR_DRIVER_NOT_INSTALLED, get_processor_arch()) {
throw core::CoreException();
}
if ( !missing_driver_error ) {
@ -214,21 +211,21 @@ sqlsrv_conn* core_sqlsrv_connect( _In_ sqlsrv_context& henv_cp, _In_ sqlsrv_cont
DIE( "C++ memory allocation failure building the connection string." );
}
catch( std::out_of_range const& ex ) {
memset( const_cast<char*>(conn_str.c_str()), 0, conn_str.size() );
memset( const_cast<char*>( conn_str.c_str()), 0, conn_str.size() );
memset( wconn_string, 0, wconn_len * sizeof( SQLWCHAR )); // wconn_len is the number of characters, not bytes
LOG( SEV_ERROR, "C++ exception returned: %1!s!", ex.what() );
conn->invalidate();
throw;
}
catch( std::length_error const& ex ) {
memset( const_cast<char*>(conn_str.c_str()), 0, conn_str.size() );
memset( const_cast<char*>( conn_str.c_str()), 0, conn_str.size() );
memset( wconn_string, 0, wconn_len * sizeof( SQLWCHAR )); // wconn_len is the number of characters, not bytes
LOG( SEV_ERROR, "C++ exception returned: %1!s!", ex.what() );
conn->invalidate();
throw;
}
catch( core::CoreException& ) {
memset( const_cast<char*>(conn_str.c_str()), 0, conn_str.size() );
memset( const_cast<char*>( conn_str.c_str()), 0, conn_str.size() );
memset( wconn_string, 0, wconn_len * sizeof( SQLWCHAR )); // wconn_len is the number of characters, not bytes
conn->invalidate();
throw;
@ -247,11 +244,11 @@ SQLRETURN core_odbc_connect(_Inout_ sqlsrv_conn* conn, _Inout_ std::string& conn
// We only support UTF-8 encoding for connection string.
// Convert our UTF-8 connection string to UTF-16 before connecting with SQLDriverConnnectW
wconn_len = static_cast<unsigned int>(conn_str.length() + 1) * sizeof(SQLWCHAR);
wconn_len = static_cast<unsigned int>( conn_str.length() + 1 ) * sizeof( SQLWCHAR );
wconn_string = utf16_string_from_mbcs_string(SQLSRV_ENCODING_UTF8, conn_str.c_str(), static_cast<unsigned int>(conn_str.length()), &wconn_len);
wconn_string = utf16_string_from_mbcs_string( SQLSRV_ENCODING_UTF8, conn_str.c_str(), static_cast<unsigned int>( conn_str.length()), &wconn_len );
CHECK_CUSTOM_ERROR(wconn_string == 0, conn, SQLSRV_ERROR_CONNECT_STRING_ENCODING_TRANSLATE, get_last_error_message())
CHECK_CUSTOM_ERROR( wconn_string == 0, conn, SQLSRV_ERROR_CONNECT_STRING_ENCODING_TRANSLATE, get_last_error_message())
{
throw core::CoreException();
}
@ -269,24 +266,21 @@ SQLRETURN core_odbc_connect(_Inout_ sqlsrv_conn* conn, _Inout_ std::string& conn
r = SQLDriverConnectW(conn->handle(), NULL, wconn_string, static_cast<SQLSMALLINT>(wconn_len), NULL, 0, &output_conn_size, SQL_DRIVER_NOPROMPT);
}
#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
// clear the connection string from memory to remove sensitive data (such as a password).
memset(const_cast<char*>(conn_str.c_str()), 0, conn_str.size());
memset(wconn_string, 0, wconn_len * sizeof(SQLWCHAR)); // wconn_len is the number of characters, not bytes
memset( const_cast<char*>( conn_str.c_str() ), 0, conn_str.size() );
memset( wconn_string, 0, wconn_len * sizeof( SQLWCHAR )); // wconn_len is the number of characters, not bytes
wconn_len = 0;
conn_str.clear();
if (SQL_SUCCEEDED(r)) {
//conn->driver_version = static_cast<DRIVER_VERSION>(odbc_version);
}
else {
SQLCHAR state[SQL_SQLSTATE_BUFSIZE];
if (!SQL_SUCCEEDED(r)) {
SQLCHAR state[ SQL_SQLSTATE_BUFSIZE ];
SQLSMALLINT len;
SQLRETURN sr = SQLGetDiagField(SQL_HANDLE_DBC, conn->handle(), 1, SQL_DIAG_SQLSTATE, state, SQL_SQLSTATE_BUFSIZE, &len);
missing_driver_error = (SQL_SUCCEEDED(sr) && state[0] == 'I' && state[1] == 'M' && state[2] == '0' && state[3] == '0' && state[4] == '2');
}
SQLRETURN sr = SQLGetDiagField( SQL_HANDLE_DBC, conn->handle(), 1, SQL_DIAG_SQLSTATE, state, SQL_SQLSTATE_BUFSIZE, &len );
missing_driver_error = ( SQL_SUCCEEDED(sr) && state[0] == 'I' && state[1] == 'M' && state[2] == '0' && state[3] == '0' && state[4] == '2' );
}
return r;
}

View file

@ -151,6 +151,7 @@ OACR_WARNING_POP
#include <deque>
#include <map>
#include <string>
#include <algorithm>
#include <limits>
#include <cassert>
@ -1067,8 +1068,6 @@ struct sqlsrv_conn : public sqlsrv_context {
// instance variables
SERVER_VERSION server_version; // version of the server that we're connected to
DRIVER_VERSION driver_version;
col_encryption_option ce_option; // holds the details of what are required to enable column encryption
bool is_driver_set;
@ -1077,7 +1076,6 @@ struct sqlsrv_conn : public sqlsrv_context {
sqlsrv_context( h, SQL_HANDLE_DBC, e, drv, encoding )
{
server_version = SERVER_VERSION_UNKNOWN;
driver_version = ODBC_DRIVER_UNKNOWN;
is_driver_set = false;
}
@ -1201,6 +1199,8 @@ struct connection_option {
void (*func)( connection_option const*, zval* value, sqlsrv_conn* conn, std::string& conn_str TSRMLS_DC );
};
// connection attribute functions
// simply add the parsed value to the connection string
struct conn_str_append_func {
@ -1212,6 +1212,21 @@ struct conn_null_func {
static void func( connection_option const* /*option*/, zval* /*value*/, sqlsrv_conn* /*conn*/, std::string& /*conn_str*/ TSRMLS_DC );
};
template <unsigned int Attr>
struct str_conn_attr_func {
static void func(connection_option const* /*option*/, zval* value, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/ TSRMLS_DC)
{
try {
core::SQLSetConnectAttr(conn, Attr, reinterpret_cast<SQLPOINTER>(Z_STRVAL_P(value)),
static_cast<SQLINTEGER>(Z_STRLEN_P(value)) TSRMLS_CC);
}
catch (core::CoreException&) {
throw;
}
}
};
struct column_encryption_set_func {
static void func( _In_ connection_option const* option, _In_ zval* value, _Inout_ sqlsrv_conn* conn, _Inout_ std::string& conn_str TSRMLS_DC);
@ -1239,7 +1254,8 @@ sqlsrv_conn* core_sqlsrv_connect( _In_ sqlsrv_context& henv_cp, _In_ sqlsrv_cont
_Inout_z_ const char* server, _Inout_opt_z_ const char* uid, _Inout_opt_z_ const char* pwd,
_Inout_opt_ HashTable* options_ht, _In_ error_callback err, _In_ const connection_option valid_conn_opts[],
_In_ void* driver, _In_z_ const char* driver_func TSRMLS_DC );
SQLRETURN core_odbc_connect( _Inout_ sqlsrv_conn* conn, _Inout_ std::string& conn_str, _Inout_ SQLWCHAR* wconn_string, _Inout_ unsigned int& wconn_len, _Inout_ bool& missing_driver_error);
SQLRETURN core_odbc_connect( _Inout_ sqlsrv_conn* conn, _Inout_ std::string& conn_str, _Inout_ SQLWCHAR* wconn_string,
_Inout_ unsigned int& wconn_len, _Inout_ bool& missing_driver_error, _In_ bool is_pooled);
void core_sqlsrv_close( _Inout_opt_ sqlsrv_conn* conn TSRMLS_DC );
void core_sqlsrv_prepare( _Inout_ sqlsrv_stmt* stmt, _In_reads_bytes_(sql_len) const char* sql, _In_ SQLLEN sql_len TSRMLS_DC );
void core_sqlsrv_begin_transaction( _Inout_ sqlsrv_conn* conn TSRMLS_DC );
@ -1692,10 +1708,6 @@ enum SQLSRV_ERROR_CODES {
};
// the message returned by ODBC Driver 11 for SQL Server
static const char* CONNECTION_BUSY_ODBC_ERROR[] = { "[Microsoft][ODBC Driver 13 for SQL Server]Connection is busy with results for another command",
"[Microsoft][ODBC Driver 11 for SQL Server]Connection is busy with results for another command" };
// SQLSTATE for all internal errors
extern SQLCHAR IMSSP[];
@ -1871,8 +1883,12 @@ namespace core {
throw CoreException();
}
std::size_t driver_version = stmt->conn->driver_version;
if( !strcmp( reinterpret_cast<const char*>( err_msg ), CONNECTION_BUSY_ODBC_ERROR[driver_version] )) {
// the message returned by ODBC Driver for SQL Server
const std::string connection_busy_error( "Connection is busy with results for another command" );
const std::string returned_error( reinterpret_cast<char*>( err_msg ));
if(( returned_error.find( connection_busy_error ) == std::string::npos )) {
THROW_CORE_ERROR( stmt, SQLSRV_ERROR_MARS_OFF );
}
@ -2420,20 +2436,5 @@ sqlsrv_conn* allocate_conn( _In_ SQLHANDLE h, _In_ error_callback e, _In_ void*
} // namespace core
// connection attribute functions
template <unsigned int Attr>
struct str_conn_attr_func {
static void func( connection_option const* /*option*/, zval* value, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/ TSRMLS_DC )
{
try {
core::SQLSetConnectAttr( conn, Attr, reinterpret_cast<SQLPOINTER>( Z_STRVAL_P( value )),
static_cast<SQLINTEGER>(Z_STRLEN_P( value )) TSRMLS_CC );
}
catch( core::CoreException& ) {
throw;
}
}
};
#endif // CORE_SQLSRV_H