merged core_conn from linux to Windows
This commit is contained in:
parent
dcc4ff2d11
commit
0d3b475277
|
@ -20,13 +20,20 @@
|
||||||
#include "core_sqlsrv.h"
|
#include "core_sqlsrv.h"
|
||||||
|
|
||||||
#include <php.h>
|
#include <php.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
#include <psapi.h>
|
#include <psapi.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <winver.h>
|
#include <winver.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
// *** internal variables and constants ***
|
// *** internal variables and constants ***
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -91,7 +98,7 @@ sqlsrv_conn* core_sqlsrv_connect( sqlsrv_context& henv_cp, sqlsrv_context& henv_
|
||||||
std::string conn_str;
|
std::string conn_str;
|
||||||
conn_str.reserve( DEFAULT_CONN_STR_LEN );
|
conn_str.reserve( DEFAULT_CONN_STR_LEN );
|
||||||
sqlsrv_malloc_auto_ptr<sqlsrv_conn> conn;
|
sqlsrv_malloc_auto_ptr<sqlsrv_conn> conn;
|
||||||
sqlsrv_malloc_auto_ptr<wchar_t> wconn_string;
|
sqlsrv_malloc_auto_ptr<SQLWCHAR> wconn_string;
|
||||||
unsigned int wconn_len = 0;
|
unsigned int wconn_len = 0;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -105,7 +112,6 @@ sqlsrv_conn* core_sqlsrv_connect( sqlsrv_context& henv_cp, sqlsrv_context& henv_
|
||||||
if( options_ht && zend_hash_num_elements( options_ht ) > 0 ) {
|
if( options_ht && zend_hash_num_elements( options_ht ) > 0 ) {
|
||||||
|
|
||||||
zval* option_z = NULL;
|
zval* option_z = NULL;
|
||||||
int zr = SUCCESS;
|
|
||||||
|
|
||||||
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 (option_z) {
|
||||||
|
@ -126,28 +132,27 @@ sqlsrv_conn* core_sqlsrv_connect( sqlsrv_context& henv_cp, sqlsrv_context& henv_
|
||||||
|
|
||||||
for ( std::size_t i = DRIVER_VERSION::MIN; i <= DRIVER_VERSION::MAX; ++i ) {
|
for ( std::size_t i = DRIVER_VERSION::MIN; i <= DRIVER_VERSION::MAX; ++i ) {
|
||||||
conn_str = CONNECTION_STRING_DRIVER_NAME[i];
|
conn_str = CONNECTION_STRING_DRIVER_NAME[i];
|
||||||
build_connection_string_and_set_conn_attr( conn, server, uid, pwd, options_ht, valid_conn_opts, driver,
|
build_connection_string_and_set_conn_attr( conn, server, uid, pwd, options_ht, valid_conn_opts, driver, conn_str TSRMLS_CC );
|
||||||
conn_str TSRMLS_CC );
|
|
||||||
|
|
||||||
// We only support UTF-8 encoding for connection string.
|
// We only support UTF-8 encoding for connection string.
|
||||||
// Convert our UTF-8 connection string to UTF-16 before connecting with SQLDriverConnnectW
|
// Convert our UTF-8 connection string to UTF-16 before connecting with SQLDriverConnnectW
|
||||||
wconn_len = static_cast<unsigned int>( conn_str.length() + 1 ) * sizeof( wchar_t );
|
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 == NULL, conn, SQLSRV_ERROR_CONNECT_STRING_ENCODING_TRANSLATE, get_last_error_message())
|
|
||||||
{
|
|
||||||
throw core::CoreException();
|
|
||||||
}
|
|
||||||
|
|
||||||
SQLSMALLINT output_conn_size;
|
CHECK_CUSTOM_ERROR( wconn_string == 0, conn, SQLSRV_ERROR_CONNECT_STRING_ENCODING_TRANSLATE, get_last_error_message() )
|
||||||
r = SQLDriverConnectW( conn->handle(), NULL, reinterpret_cast<SQLWCHAR*>( wconn_string.get()),
|
{
|
||||||
static_cast<SQLSMALLINT>( wconn_len ), NULL,
|
throw core::CoreException();
|
||||||
0, &output_conn_size, SQL_DRIVER_NOPROMPT );
|
}
|
||||||
// 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( wchar_t )); // wconn_len is the number of characters, not bytes
|
|
||||||
conn_str.clear();
|
|
||||||
|
|
||||||
|
SQLSMALLINT output_conn_size;
|
||||||
|
r = SQLDriverConnectW( conn->handle(), NULL, reinterpret_cast<SQLWCHAR*>( wconn_string.get() ),
|
||||||
|
static_cast<SQLSMALLINT>( wconn_len ), NULL, 0, &output_conn_size, SQL_DRIVER_NOPROMPT );
|
||||||
|
|
||||||
|
// 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
|
||||||
|
conn_str.clear();
|
||||||
if( !SQL_SUCCEEDED( r )) {
|
if( !SQL_SUCCEEDED( r )) {
|
||||||
SQLCHAR state[SQL_SQLSTATE_BUFSIZE];
|
SQLCHAR state[SQL_SQLSTATE_BUFSIZE];
|
||||||
SQLSMALLINT len;
|
SQLSMALLINT len;
|
||||||
|
@ -182,27 +187,27 @@ sqlsrv_conn* core_sqlsrv_connect( sqlsrv_context& henv_cp, sqlsrv_context& henv_
|
||||||
}
|
}
|
||||||
catch( std::bad_alloc& ) {
|
catch( std::bad_alloc& ) {
|
||||||
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( wchar_t )); // 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->invalidate();
|
conn->invalidate();
|
||||||
DIE( "C++ memory allocation failure building the connection string." );
|
DIE( "C++ memory allocation failure building the connection string." );
|
||||||
}
|
}
|
||||||
catch( std::out_of_range const& ex ) {
|
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( wchar_t )); // 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
|
||||||
LOG( SEV_ERROR, "C++ exception returned: %1!s!", ex.what() );
|
LOG( SEV_ERROR, "C++ exception returned: %1!s!", ex.what() );
|
||||||
conn->invalidate();
|
conn->invalidate();
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
catch( std::length_error const& ex ) {
|
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( wchar_t )); // 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
|
||||||
LOG( SEV_ERROR, "C++ exception returned: %1!s!", ex.what() );
|
LOG( SEV_ERROR, "C++ exception returned: %1!s!", ex.what() );
|
||||||
conn->invalidate();
|
conn->invalidate();
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
catch( core::CoreException& ) {
|
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( wchar_t )); // 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->invalidate();
|
conn->invalidate();
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
@ -336,10 +341,10 @@ void core_sqlsrv_prepare( sqlsrv_stmt* stmt, const char* sql, SQLLEN sql_len TSR
|
||||||
// convert the string from its encoding to UTf-16
|
// convert the string from its encoding to UTf-16
|
||||||
// if the string is empty, we initialize the fields and skip since an empty string is a
|
// if the string is empty, we initialize the fields and skip since an empty string is a
|
||||||
// failure case for utf16_string_from_mbcs_string
|
// failure case for utf16_string_from_mbcs_string
|
||||||
sqlsrv_malloc_auto_ptr<wchar_t> wsql_string;
|
sqlsrv_malloc_auto_ptr<SQLWCHAR> wsql_string;
|
||||||
unsigned int wsql_len = 0;
|
unsigned int wsql_len = 0;
|
||||||
if( sql_len == 0 || ( sql[0] == '\0' && sql_len == 1 )) {
|
if( sql_len == 0 || ( sql[0] == '\0' && sql_len == 1 )) {
|
||||||
wsql_string = reinterpret_cast<wchar_t*>( sqlsrv_malloc( sizeof( wchar_t )));
|
wsql_string = reinterpret_cast<SQLWCHAR*>( sqlsrv_malloc( sizeof( SQLWCHAR )));
|
||||||
wsql_string[0] = L'\0';
|
wsql_string[0] = L'\0';
|
||||||
wsql_len = 0;
|
wsql_len = 0;
|
||||||
}
|
}
|
||||||
|
@ -355,7 +360,7 @@ void core_sqlsrv_prepare( sqlsrv_stmt* stmt, const char* sql, SQLLEN sql_len TSR
|
||||||
stmt->encoding() );
|
stmt->encoding() );
|
||||||
wsql_string = utf16_string_from_mbcs_string( encoding, reinterpret_cast<const char*>( sql ),
|
wsql_string = utf16_string_from_mbcs_string( encoding, reinterpret_cast<const char*>( sql ),
|
||||||
static_cast<int>( sql_len ), &wsql_len );
|
static_cast<int>( sql_len ), &wsql_len );
|
||||||
CHECK_CUSTOM_ERROR( wsql_string == NULL, stmt, SQLSRV_ERROR_QUERY_STRING_ENCODING_TRANSLATE,
|
CHECK_CUSTOM_ERROR( wsql_string == 0, stmt, SQLSRV_ERROR_QUERY_STRING_ENCODING_TRANSLATE,
|
||||||
get_last_error_message() ) {
|
get_last_error_message() ) {
|
||||||
throw core::CoreException();
|
throw core::CoreException();
|
||||||
}
|
}
|
||||||
|
@ -385,10 +390,10 @@ void core_sqlsrv_get_server_version( sqlsrv_conn* conn, _Out_ zval *server_versi
|
||||||
SQLSMALLINT buffer_len = 0;
|
SQLSMALLINT buffer_len = 0;
|
||||||
|
|
||||||
get_server_version( conn, &buffer, buffer_len TSRMLS_CC );
|
get_server_version( conn, &buffer, buffer_len TSRMLS_CC );
|
||||||
core::sqlsrv_zval_stringl( server_version, buffer, buffer_len );
|
core::sqlsrv_zval_stringl( server_version, buffer, buffer_len );
|
||||||
if (NULL != buffer) {
|
if ( buffer != 0 ) {
|
||||||
sqlsrv_free( buffer );
|
sqlsrv_free( buffer );
|
||||||
}
|
}
|
||||||
buffer.transferred();
|
buffer.transferred();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -456,7 +461,11 @@ void core_sqlsrv_get_client_info( sqlsrv_conn* conn, _Out_ zval *client_info TSR
|
||||||
// Get the ODBC driver's dll name
|
// Get the ODBC driver's dll name
|
||||||
buffer = static_cast<char*>( sqlsrv_malloc( INFO_BUFFER_LEN ));
|
buffer = static_cast<char*>( sqlsrv_malloc( INFO_BUFFER_LEN ));
|
||||||
core::SQLGetInfo( conn, SQL_DRIVER_NAME, buffer, INFO_BUFFER_LEN, &buffer_len TSRMLS_CC );
|
core::SQLGetInfo( conn, SQL_DRIVER_NAME, buffer, INFO_BUFFER_LEN, &buffer_len TSRMLS_CC );
|
||||||
|
#if defined (__linux__) || defined(__MACH__)
|
||||||
|
core::sqlsrv_add_assoc_string( *conn, client_info, "DriverName", buffer, 0 /*duplicate*/ TSRMLS_CC );
|
||||||
|
#else
|
||||||
core::sqlsrv_add_assoc_string( *conn, client_info, "DriverDllName", buffer, 0 /*duplicate*/ TSRMLS_CC );
|
core::sqlsrv_add_assoc_string( *conn, client_info, "DriverDllName", buffer, 0 /*duplicate*/ TSRMLS_CC );
|
||||||
|
#endif
|
||||||
buffer.transferred();
|
buffer.transferred();
|
||||||
|
|
||||||
// Get the ODBC driver's ODBC version
|
// Get the ODBC driver's ODBC version
|
||||||
|
@ -536,10 +545,8 @@ void build_connection_string_and_set_conn_attr( sqlsrv_conn* conn, const char* s
|
||||||
HashTable* options, const connection_option valid_conn_opts[],
|
HashTable* options, const connection_option valid_conn_opts[],
|
||||||
void* driver,_Inout_ std::string& connection_string TSRMLS_DC )
|
void* driver,_Inout_ std::string& connection_string TSRMLS_DC )
|
||||||
{
|
{
|
||||||
bool credentials_mentioned = false;
|
|
||||||
bool mars_mentioned = false;
|
bool mars_mentioned = false;
|
||||||
connection_option const* conn_opt;
|
connection_option const* conn_opt;
|
||||||
int zr = SUCCESS;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
@ -654,6 +661,23 @@ void get_server_version( sqlsrv_conn* conn, char** server_version, SQLSMALLINT&
|
||||||
// and return the string of the processor name.
|
// and return the string of the processor name.
|
||||||
const char* get_processor_arch( void )
|
const char* get_processor_arch( void )
|
||||||
{
|
{
|
||||||
|
#ifdef __linux__
|
||||||
|
struct utsname sys_info;
|
||||||
|
if ( uname(&sys_info) == -1 )
|
||||||
|
{
|
||||||
|
DIE( "Error retrieving system info" );
|
||||||
|
}
|
||||||
|
if( strcmp(sys_info.machine, "x86") ) {
|
||||||
|
return PROCESSOR_ARCH[0];
|
||||||
|
} else if ( strcmp(sys_info.machine, "x86_64") ) {
|
||||||
|
return PROCESSOR_ARCH[1];
|
||||||
|
} else if ( strcmp(sys_info.machine, "ia64") ) {
|
||||||
|
return PROCESSOR_ARCH[2];
|
||||||
|
} else {
|
||||||
|
DIE( "Unknown processor architecture." );
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
#else
|
||||||
SYSTEM_INFO sys_info;
|
SYSTEM_INFO sys_info;
|
||||||
GetSystemInfo( &sys_info);
|
GetSystemInfo( &sys_info);
|
||||||
switch( sys_info.wProcessorArchitecture ) {
|
switch( sys_info.wProcessorArchitecture ) {
|
||||||
|
@ -671,6 +695,8 @@ const char* get_processor_arch( void )
|
||||||
DIE( "Unknown Windows processor architecture." );
|
DIE( "Unknown Windows processor architecture." );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -690,6 +716,7 @@ void determine_server_version( sqlsrv_conn* conn TSRMLS_DC )
|
||||||
char version_major_str[ 3 ];
|
char version_major_str[ 3 ];
|
||||||
SERVER_VERSION version_major;
|
SERVER_VERSION version_major;
|
||||||
memcpy_s( version_major_str, sizeof( version_major_str ), p, 2 );
|
memcpy_s( version_major_str, sizeof( version_major_str ), p, 2 );
|
||||||
|
|
||||||
version_major_str[ 2 ] = '\0';
|
version_major_str[ 2 ] = '\0';
|
||||||
version_major = static_cast<SERVER_VERSION>( atoi( version_major_str ));
|
version_major = static_cast<SERVER_VERSION>( atoi( version_major_str ));
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue