Remicollet issue tsrmls (#1130)

This commit is contained in:
Jenny Tam 2020-04-20 15:17:21 -07:00 committed by GitHub
parent 14dbf79d39
commit 1aca278245
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 826 additions and 860 deletions

View file

@ -113,19 +113,18 @@ const stmt_option PDO_STMT_OPTS[] = {
// boolean connection string // boolean connection string
struct pdo_bool_conn_str_func struct pdo_bool_conn_str_func
{ {
static void func( _In_ connection_option const* option, _Inout_ zval* value, sqlsrv_conn* /*conn*/, _Out_ std::string& conn_str TSRMLS_DC ); static void func( _In_ connection_option const* option, _Inout_ zval* value, sqlsrv_conn* /*conn*/, _Out_ std::string& conn_str );
}; };
struct pdo_txn_isolation_conn_attr_func struct pdo_txn_isolation_conn_attr_func
{ {
static void func( connection_option const* /*option*/, _In_ zval* value_z, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/ TSRMLS_DC ); static void func( connection_option const* /*option*/, _In_ zval* value_z, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/ );
}; };
struct pdo_int_conn_str_func { struct pdo_int_conn_str_func {
static void func( _In_ connection_option const* option, _In_ zval* value, sqlsrv_conn* /*conn*/, _Out_ std::string& conn_str TSRMLS_DC ) static void func( _In_ connection_option const* option, _In_ zval* value, sqlsrv_conn* /*conn*/, _Out_ std::string& conn_str )
{ {
TSRMLS_C;
SQLSRV_ASSERT( Z_TYPE_P( value ) == IS_STRING, "Wrong zval type for this keyword" ) SQLSRV_ASSERT( Z_TYPE_P( value ) == IS_STRING, "Wrong zval type for this keyword" )
std::string val_str = Z_STRVAL_P( value ); std::string val_str = Z_STRVAL_P( value );
@ -140,14 +139,14 @@ struct pdo_int_conn_str_func {
template <unsigned int Attr> template <unsigned int Attr>
struct pdo_int_conn_attr_func { struct pdo_int_conn_attr_func {
static void func( connection_option const* /*option*/, _In_ zval* value, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/ TSRMLS_DC ) static void func( connection_option const* /*option*/, _In_ zval* value, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/ )
{ {
try { try {
SQLSRV_ASSERT( Z_TYPE_P( value ) == IS_STRING, "pdo_int_conn_attr_func: Unexpected zval type." ); SQLSRV_ASSERT( Z_TYPE_P( value ) == IS_STRING, "pdo_int_conn_attr_func: Unexpected zval type." );
size_t val = static_cast<size_t>( atoi( Z_STRVAL_P( value )) ); size_t val = static_cast<size_t>( atoi( Z_STRVAL_P( value )) );
core::SQLSetConnectAttr( conn, Attr, reinterpret_cast<SQLPOINTER>( val ), SQL_IS_UINTEGER TSRMLS_CC ); core::SQLSetConnectAttr( conn, Attr, reinterpret_cast<SQLPOINTER>( val ), SQL_IS_UINTEGER );
} }
catch( core::CoreException& ) { catch( core::CoreException& ) {
throw; throw;
@ -158,12 +157,12 @@ struct pdo_int_conn_attr_func {
template <unsigned int Attr> template <unsigned int Attr>
struct pdo_bool_conn_attr_func { struct pdo_bool_conn_attr_func {
static void func( connection_option const* /*option*/, _Inout_ zval* value, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/ TSRMLS_DC ) static void func( connection_option const* /*option*/, _Inout_ zval* value, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/ )
{ {
try { try {
core::SQLSetConnectAttr( conn, Attr, reinterpret_cast<SQLPOINTER>( core_str_zval_is_true( value )), core::SQLSetConnectAttr( conn, Attr, reinterpret_cast<SQLPOINTER>( core_str_zval_is_true( value )),
SQL_IS_UINTEGER TSRMLS_CC ); SQL_IS_UINTEGER );
} }
catch( core::CoreException& ) { catch( core::CoreException& ) {
throw; throw;
@ -173,8 +172,8 @@ struct pdo_bool_conn_attr_func {
// statement options related functions // statement options related functions
void add_stmt_option_key( _Inout_ sqlsrv_context& ctx, _In_ size_t key, _Inout_ HashTable* options_ht, void add_stmt_option_key( _Inout_ sqlsrv_context& ctx, _In_ size_t key, _Inout_ HashTable* options_ht,
_Inout_ zval** data TSRMLS_DC ); _Inout_ zval** data );
void validate_stmt_options( _Inout_ sqlsrv_context& ctx, _Inout_ zval* stmt_options, _Inout_ HashTable* pdo_stmt_options_ht TSRMLS_DC ); void validate_stmt_options( _Inout_ sqlsrv_context& ctx, _Inout_ zval* stmt_options, _Inout_ HashTable* pdo_stmt_options_ht );
} // namespace } // namespace
@ -438,35 +437,35 @@ const connection_option PDO_CONN_OPTS[] = {
// close the connection // close the connection
int pdo_sqlsrv_dbh_close( _Inout_ pdo_dbh_t *dbh TSRMLS_DC ); int pdo_sqlsrv_dbh_close( _Inout_ pdo_dbh_t *dbh );
// execute queries // execute queries
int pdo_sqlsrv_dbh_prepare( _Inout_ pdo_dbh_t *dbh, _In_reads_(sql_len) const char *sql, int pdo_sqlsrv_dbh_prepare( _Inout_ pdo_dbh_t *dbh, _In_reads_(sql_len) const char *sql,
_Inout_ size_t sql_len, _Inout_ pdo_stmt_t *stmt, _In_ zval *driver_options TSRMLS_DC ); _Inout_ size_t sql_len, _Inout_ pdo_stmt_t *stmt, _In_ zval *driver_options );
zend_long pdo_sqlsrv_dbh_do( _Inout_ pdo_dbh_t *dbh, _In_reads_bytes_(sql_len) const char *sql, _In_ size_t sql_len TSRMLS_DC ); zend_long pdo_sqlsrv_dbh_do( _Inout_ pdo_dbh_t *dbh, _In_reads_bytes_(sql_len) const char *sql, _In_ size_t sql_len );
// transaction support functions // transaction support functions
int pdo_sqlsrv_dbh_commit( _Inout_ pdo_dbh_t *dbh TSRMLS_DC ); int pdo_sqlsrv_dbh_commit( _Inout_ pdo_dbh_t *dbh );
int pdo_sqlsrv_dbh_begin( _Inout_ pdo_dbh_t *dbh TSRMLS_DC ); int pdo_sqlsrv_dbh_begin( _Inout_ pdo_dbh_t *dbh );
int pdo_sqlsrv_dbh_rollback( _Inout_ pdo_dbh_t *dbh TSRMLS_DC ); int pdo_sqlsrv_dbh_rollback( _Inout_ pdo_dbh_t *dbh );
// attribute functions // attribute functions
int pdo_sqlsrv_dbh_set_attr( _Inout_ pdo_dbh_t *dbh, _In_ zend_long attr, _Inout_ zval *val TSRMLS_DC ); int pdo_sqlsrv_dbh_set_attr( _Inout_ pdo_dbh_t *dbh, _In_ zend_long attr, _Inout_ zval *val );
int pdo_sqlsrv_dbh_get_attr( _Inout_ pdo_dbh_t *dbh, _In_ zend_long attr, _Inout_ zval *return_value TSRMLS_DC ); int pdo_sqlsrv_dbh_get_attr( _Inout_ pdo_dbh_t *dbh, _In_ zend_long attr, _Inout_ zval *return_value );
// return more information // return more information
int pdo_sqlsrv_dbh_return_error( _In_ pdo_dbh_t *dbh, _In_opt_ pdo_stmt_t *stmt, int pdo_sqlsrv_dbh_return_error( _In_ pdo_dbh_t *dbh, _In_opt_ pdo_stmt_t *stmt,
_Out_ zval *info TSRMLS_DC); _Out_ zval *info);
// return the last id generated by an executed SQL statement // return the last id generated by an executed SQL statement
char * pdo_sqlsrv_dbh_last_id( _Inout_ pdo_dbh_t *dbh, _In_z_ const char *name, _Out_ size_t* len TSRMLS_DC ); char * pdo_sqlsrv_dbh_last_id( _Inout_ pdo_dbh_t *dbh, _In_z_ const char *name, _Out_ size_t* len );
// additional methods are supported in this function // additional methods are supported in this function
pdo_sqlsrv_function_entry *pdo_sqlsrv_get_driver_methods( _Inout_ pdo_dbh_t *dbh, int kind TSRMLS_DC ); pdo_sqlsrv_function_entry *pdo_sqlsrv_get_driver_methods( _Inout_ pdo_dbh_t *dbh, int kind );
// quote a string, meaning put quotes around it and escape any quotes within it // quote a string, meaning put quotes around it and escape any quotes within it
int pdo_sqlsrv_dbh_quote( _Inout_ pdo_dbh_t* dbh, _In_reads_(unquotedlen) const char* unquoted, _In_ size_t unquotedlen, _Outptr_result_buffer_(*quotedlen) char **quoted, _Out_ size_t* quotedlen, int pdo_sqlsrv_dbh_quote( _Inout_ pdo_dbh_t* dbh, _In_reads_(unquotedlen) const char* unquoted, _In_ size_t unquotedlen, _Outptr_result_buffer_(*quotedlen) char **quoted, _Out_ size_t* quotedlen,
enum pdo_param_type paramtype TSRMLS_DC ); enum pdo_param_type paramtype );
struct pdo_dbh_methods pdo_sqlsrv_dbh_methods = { struct pdo_dbh_methods pdo_sqlsrv_dbh_methods = {
@ -498,8 +497,8 @@ struct pdo_dbh_methods pdo_sqlsrv_dbh_methods = {
} }
// constructor for the internal object for connections // constructor for the internal object for connections
pdo_sqlsrv_dbh::pdo_sqlsrv_dbh( _In_ SQLHANDLE h, _In_ error_callback e, _In_ void* driver TSRMLS_DC ) : pdo_sqlsrv_dbh::pdo_sqlsrv_dbh( _In_ SQLHANDLE h, _In_ error_callback e, _In_ void* driver ) :
sqlsrv_conn( h, e, driver, SQLSRV_ENCODING_UTF8 TSRMLS_CC ), sqlsrv_conn( h, e, driver, SQLSRV_ENCODING_UTF8 ),
stmts( NULL ), stmts( NULL ),
direct_query( false ), direct_query( false ),
query_timeout( QUERY_TIMEOUT_INVALID ), query_timeout( QUERY_TIMEOUT_INVALID ),
@ -532,7 +531,7 @@ pdo_sqlsrv_dbh::pdo_sqlsrv_dbh( _In_ SQLHANDLE h, _In_ error_callback e, _In_ vo
// driver_options - A HashTable (within the zval) of options to use when creating the connection. // driver_options - A HashTable (within the zval) of options to use when creating the connection.
// Return: // Return:
// 0 for failure, 1 for success. // 0 for failure, 1 for success.
int pdo_sqlsrv_db_handle_factory( _Inout_ pdo_dbh_t *dbh, _In_opt_ zval *driver_options TSRMLS_DC) int pdo_sqlsrv_db_handle_factory( _Inout_ pdo_dbh_t *dbh, _In_opt_ zval *driver_options)
{ {
PDO_LOG_DBH_ENTRY; PDO_LOG_DBH_ENTRY;
@ -570,12 +569,12 @@ int pdo_sqlsrv_db_handle_factory( _Inout_ pdo_dbh_t *dbh, _In_opt_ zval *driver_
ALLOC_HASHTABLE( pdo_conn_options_ht ); ALLOC_HASHTABLE( pdo_conn_options_ht );
core::sqlsrv_zend_hash_init( *g_pdo_henv_cp, pdo_conn_options_ht, 10 /* # of buckets */, core::sqlsrv_zend_hash_init( *g_pdo_henv_cp, pdo_conn_options_ht, 10 /* # of buckets */,
ZVAL_PTR_DTOR, 0 /*persistent*/ TSRMLS_CC ); ZVAL_PTR_DTOR, 0 /*persistent*/ );
// Either of g_pdo_henv_cp or g_pdo_henv_ncp can be used to propogate the error. // Either of g_pdo_henv_cp or g_pdo_henv_ncp can be used to propogate the error.
dsn_parser = new ( sqlsrv_malloc( sizeof( conn_string_parser ))) conn_string_parser( *g_pdo_henv_cp, dbh->data_source, dsn_parser = new ( sqlsrv_malloc( sizeof( conn_string_parser ))) conn_string_parser( *g_pdo_henv_cp, dbh->data_source,
static_cast<int>( dbh->data_source_len ), pdo_conn_options_ht ); static_cast<int>( dbh->data_source_len ), pdo_conn_options_ht );
dsn_parser->parse_conn_string( TSRMLS_C ); dsn_parser->parse_conn_string();
// Extract the server name // Extract the server name
temp_server_z = zend_hash_index_find( pdo_conn_options_ht, PDO_CONN_OPTION_SERVER ); temp_server_z = zend_hash_index_find( pdo_conn_options_ht, PDO_CONN_OPTION_SERVER );
@ -593,7 +592,7 @@ int pdo_sqlsrv_db_handle_factory( _Inout_ pdo_dbh_t *dbh, _In_opt_ zval *driver_
sqlsrv_conn* conn = core_sqlsrv_connect( *g_pdo_henv_cp, *g_pdo_henv_ncp, core::allocate_conn<pdo_sqlsrv_dbh>, Z_STRVAL( server_z ), sqlsrv_conn* conn = core_sqlsrv_connect( *g_pdo_henv_cp, *g_pdo_henv_ncp, core::allocate_conn<pdo_sqlsrv_dbh>, Z_STRVAL( server_z ),
dbh->username, dbh->password, pdo_conn_options_ht, pdo_sqlsrv_handle_dbh_error, dbh->username, dbh->password, pdo_conn_options_ht, pdo_sqlsrv_handle_dbh_error,
PDO_CONN_OPTS, dbh, "pdo_sqlsrv_db_handle_factory" TSRMLS_CC ); PDO_CONN_OPTS, dbh, "pdo_sqlsrv_db_handle_factory" );
// Free the string in server_z after being used // Free the string in server_z after being used
zend_string_release( Z_STR( server_z )); zend_string_release( Z_STR( server_z ));
@ -634,7 +633,7 @@ int pdo_sqlsrv_db_handle_factory( _Inout_ pdo_dbh_t *dbh, _In_opt_ zval *driver_
// dbh - The PDO managed connection object. // dbh - The PDO managed connection object.
// Return: // Return:
// Always returns 1 for success. // Always returns 1 for success.
int pdo_sqlsrv_dbh_close( _Inout_ pdo_dbh_t *dbh TSRMLS_DC ) int pdo_sqlsrv_dbh_close( _Inout_ pdo_dbh_t *dbh )
{ {
LOG( SEV_NOTICE, "pdo_sqlsrv_dbh_close: entering" ); LOG( SEV_NOTICE, "pdo_sqlsrv_dbh_close: entering" );
@ -647,7 +646,7 @@ int pdo_sqlsrv_dbh_close( _Inout_ pdo_dbh_t *dbh TSRMLS_DC )
PDO_RESET_DBH_ERROR; PDO_RESET_DBH_ERROR;
// call the core layer close // call the core layer close
core_sqlsrv_close( reinterpret_cast<sqlsrv_conn*>( dbh->driver_data ) TSRMLS_CC ); core_sqlsrv_close( reinterpret_cast<sqlsrv_conn*>( dbh->driver_data ) );
dbh->driver_data = NULL; dbh->driver_data = NULL;
// always return success that the connection is closed // always return success that the connection is closed
@ -666,7 +665,7 @@ int pdo_sqlsrv_dbh_close( _Inout_ pdo_dbh_t *dbh TSRMLS_DC )
// Return: // Return:
// 0 for failure, 1 for success. // 0 for failure, 1 for success.
int pdo_sqlsrv_dbh_prepare( _Inout_ pdo_dbh_t *dbh, _In_reads_(sql_len) const char *sql, int pdo_sqlsrv_dbh_prepare( _Inout_ pdo_dbh_t *dbh, _In_reads_(sql_len) const char *sql,
_Inout_ size_t sql_len, _Inout_ pdo_stmt_t *stmt, _In_ zval *driver_options TSRMLS_DC ) _Inout_ size_t sql_len, _Inout_ pdo_stmt_t *stmt, _In_ zval *driver_options )
{ {
PDO_RESET_DBH_ERROR; PDO_RESET_DBH_ERROR;
PDO_VALIDATE_CONN; PDO_VALIDATE_CONN;
@ -692,14 +691,14 @@ int pdo_sqlsrv_dbh_prepare( _Inout_ pdo_dbh_t *dbh, _In_reads_(sql_len) const ch
// Initialize the options array to be passed to the core layer // Initialize the options array to be passed to the core layer
ALLOC_HASHTABLE( pdo_stmt_options_ht ); ALLOC_HASHTABLE( pdo_stmt_options_ht );
core::sqlsrv_zend_hash_init( *driver_dbh , pdo_stmt_options_ht, 3 /* # of buckets */, core::sqlsrv_zend_hash_init( *driver_dbh , pdo_stmt_options_ht, 3 /* # of buckets */,
ZVAL_PTR_DTOR, 0 /*persistent*/ TSRMLS_CC ); ZVAL_PTR_DTOR, 0 /*persistent*/ );
// Either of g_pdo_henv_cp or g_pdo_henv_ncp can be used to propogate the error. // Either of g_pdo_henv_cp or g_pdo_henv_ncp can be used to propogate the error.
validate_stmt_options( *driver_dbh, driver_options, pdo_stmt_options_ht TSRMLS_CC ); validate_stmt_options( *driver_dbh, driver_options, pdo_stmt_options_ht );
driver_stmt = static_cast<pdo_sqlsrv_stmt*>( core_sqlsrv_create_stmt( driver_dbh, core::allocate_stmt<pdo_sqlsrv_stmt>, driver_stmt = static_cast<pdo_sqlsrv_stmt*>( core_sqlsrv_create_stmt( driver_dbh, core::allocate_stmt<pdo_sqlsrv_stmt>,
pdo_stmt_options_ht, PDO_STMT_OPTS, pdo_stmt_options_ht, PDO_STMT_OPTS,
pdo_sqlsrv_handle_stmt_error, stmt TSRMLS_CC )); pdo_sqlsrv_handle_stmt_error, stmt ));
// if the user didn't set anything in the prepare options, then set the buffer limit // if the user didn't set anything in the prepare options, then set the buffer limit
// to the value set on the connection. // to the value set on the connection.
@ -714,7 +713,7 @@ int pdo_sqlsrv_dbh_prepare( _Inout_ pdo_dbh_t *dbh, _In_reads_(sql_len) const ch
// rewrite the query to map named parameters to positional parameters. We do this rather than use the ODBC named // rewrite the query to map named parameters to positional parameters. We do this rather than use the ODBC named
// parameters for consistency with the PDO MySQL and PDO ODBC drivers. // parameters for consistency with the PDO MySQL and PDO ODBC drivers.
int zr = pdo_parse_params( stmt, const_cast<char*>( sql ), sql_len, &sql_rewrite, &sql_rewrite_len TSRMLS_CC ); int zr = pdo_parse_params( stmt, const_cast<char*>( sql ), sql_len, &sql_rewrite, &sql_rewrite_len );
CHECK_ZEND_ERROR( zr, driver_dbh, PDO_SQLSRV_ERROR_PARAM_PARSE) { CHECK_ZEND_ERROR( zr, driver_dbh, PDO_SQLSRV_ERROR_PARAM_PARSE) {
throw core::CoreException(); throw core::CoreException();
@ -728,7 +727,7 @@ int pdo_sqlsrv_dbh_prepare( _Inout_ pdo_dbh_t *dbh, _In_reads_(sql_len) const ch
if( !driver_stmt->direct_query && stmt->supports_placeholders != PDO_PLACEHOLDER_NONE ) { if( !driver_stmt->direct_query && stmt->supports_placeholders != PDO_PLACEHOLDER_NONE ) {
core_sqlsrv_prepare( driver_stmt, sql, sql_len TSRMLS_CC ); core_sqlsrv_prepare( driver_stmt, sql, sql_len );
} }
else if( driver_stmt->direct_query ) { else if( driver_stmt->direct_query ) {
@ -745,10 +744,10 @@ int pdo_sqlsrv_dbh_prepare( _Inout_ pdo_dbh_t *dbh, _In_reads_(sql_len) const ch
if ( stmt->supports_placeholders == PDO_PLACEHOLDER_NONE ) { if ( stmt->supports_placeholders == PDO_PLACEHOLDER_NONE ) {
// parse placeholders in the sql query into the placeholders ht // parse placeholders in the sql query into the placeholders ht
ALLOC_HASHTABLE( placeholders ); ALLOC_HASHTABLE( placeholders );
core::sqlsrv_zend_hash_init( *driver_dbh, placeholders, 5, ZVAL_PTR_DTOR /* dtor */, 0 /* persistent */ TSRMLS_CC ); core::sqlsrv_zend_hash_init( *driver_dbh, placeholders, 5, ZVAL_PTR_DTOR /* dtor */, 0 /* persistent */ );
sql_parser = new ( sqlsrv_malloc( sizeof( sql_string_parser ))) sql_string_parser( *driver_dbh, stmt->query_string, sql_parser = new ( sqlsrv_malloc( sizeof( sql_string_parser ))) sql_string_parser( *driver_dbh, stmt->query_string,
static_cast<int>(stmt->query_stringlen), placeholders ); static_cast<int>(stmt->query_stringlen), placeholders );
sql_parser->parse_sql_string( TSRMLS_C ); sql_parser->parse_sql_string();
driver_stmt->placeholders = placeholders; driver_stmt->placeholders = placeholders;
placeholders.transferred(); placeholders.transferred();
} }
@ -796,7 +795,7 @@ int pdo_sqlsrv_dbh_prepare( _Inout_ pdo_dbh_t *dbh, _In_reads_(sql_len) const ch
// sql_len - length of sql query // sql_len - length of sql query
// Return // Return
// # of rows affected, -1 for an error. // # of rows affected, -1 for an error.
zend_long pdo_sqlsrv_dbh_do( _Inout_ pdo_dbh_t *dbh, _In_reads_bytes_(sql_len) const char *sql, _In_ size_t sql_len TSRMLS_DC ) zend_long pdo_sqlsrv_dbh_do( _Inout_ pdo_dbh_t *dbh, _In_reads_bytes_(sql_len) const char *sql, _In_ size_t sql_len )
{ {
PDO_RESET_DBH_ERROR; PDO_RESET_DBH_ERROR;
PDO_VALIDATE_CONN; PDO_VALIDATE_CONN;
@ -821,23 +820,23 @@ zend_long pdo_sqlsrv_dbh_do( _Inout_ pdo_dbh_t *dbh, _In_reads_bytes_(sql_len) c
temp_stmt.dbh = dbh; temp_stmt.dbh = dbh;
// allocate a full driver statement to take advantage of the error handling // allocate a full driver statement to take advantage of the error handling
driver_stmt = core_sqlsrv_create_stmt( driver_dbh, core::allocate_stmt<pdo_sqlsrv_stmt>, NULL /*options_ht*/, driver_stmt = core_sqlsrv_create_stmt( driver_dbh, core::allocate_stmt<pdo_sqlsrv_stmt>, NULL /*options_ht*/,
NULL /*valid_stmt_opts*/, pdo_sqlsrv_handle_stmt_error, &temp_stmt TSRMLS_CC ); NULL /*valid_stmt_opts*/, pdo_sqlsrv_handle_stmt_error, &temp_stmt );
driver_stmt->set_func( __FUNCTION__ ); driver_stmt->set_func( __FUNCTION__ );
SQLRETURN execReturn = core_sqlsrv_execute( driver_stmt TSRMLS_CC, sql, static_cast<int>( sql_len ) ); SQLRETURN execReturn = core_sqlsrv_execute( driver_stmt, sql, static_cast<int>( sql_len ) );
// since the user can give us a compound statement, we return the row count for the last set, and since the row count // since the user can give us a compound statement, we return the row count for the last set, and since the row count
// isn't guaranteed to be valid until all the results have been fetched, we fetch them all first. // isn't guaranteed to be valid until all the results have been fetched, we fetch them all first.
if ( execReturn != SQL_NO_DATA && core_sqlsrv_has_any_result( driver_stmt TSRMLS_CC )) { if ( execReturn != SQL_NO_DATA && core_sqlsrv_has_any_result( driver_stmt )) {
SQLRETURN r = SQL_SUCCESS; SQLRETURN r = SQL_SUCCESS;
do { do {
rows = core::SQLRowCount( driver_stmt TSRMLS_CC ); rows = core::SQLRowCount( driver_stmt );
r = core::SQLMoreResults( driver_stmt TSRMLS_CC ); r = core::SQLMoreResults( driver_stmt );
} while ( r != SQL_NO_DATA ); } while ( r != SQL_NO_DATA );
} }
@ -885,7 +884,7 @@ zend_long pdo_sqlsrv_dbh_do( _Inout_ pdo_dbh_t *dbh, _In_reads_bytes_(sql_len) c
// dbh - The PDO managed connection object. // dbh - The PDO managed connection object.
// Return: // Return:
// 0 for failure and 1 for success. // 0 for failure and 1 for success.
int pdo_sqlsrv_dbh_begin( _Inout_ pdo_dbh_t *dbh TSRMLS_DC ) int pdo_sqlsrv_dbh_begin( _Inout_ pdo_dbh_t *dbh )
{ {
PDO_RESET_DBH_ERROR; PDO_RESET_DBH_ERROR;
PDO_VALIDATE_CONN; PDO_VALIDATE_CONN;
@ -901,7 +900,7 @@ int pdo_sqlsrv_dbh_begin( _Inout_ pdo_dbh_t *dbh TSRMLS_DC )
DEBUG_SQLSRV_ASSERT( !dbh->in_txn, "pdo_sqlsrv_dbh_begin: Already in transaction" ); DEBUG_SQLSRV_ASSERT( !dbh->in_txn, "pdo_sqlsrv_dbh_begin: Already in transaction" );
core_sqlsrv_begin_transaction( driver_conn TSRMLS_CC ); core_sqlsrv_begin_transaction( driver_conn );
return 1; return 1;
} }
@ -927,7 +926,7 @@ int pdo_sqlsrv_dbh_begin( _Inout_ pdo_dbh_t *dbh TSRMLS_DC )
// dbh - The PDO managed connection object. // dbh - The PDO managed connection object.
// Return: // Return:
// 0 for failure and 1 for success. // 0 for failure and 1 for success.
int pdo_sqlsrv_dbh_commit( _Inout_ pdo_dbh_t *dbh TSRMLS_DC ) int pdo_sqlsrv_dbh_commit( _Inout_ pdo_dbh_t *dbh )
{ {
PDO_RESET_DBH_ERROR; PDO_RESET_DBH_ERROR;
PDO_VALIDATE_CONN; PDO_VALIDATE_CONN;
@ -943,7 +942,7 @@ int pdo_sqlsrv_dbh_commit( _Inout_ pdo_dbh_t *dbh TSRMLS_DC )
DEBUG_SQLSRV_ASSERT( dbh->in_txn, "pdo_sqlsrv_dbh_commit: Not in transaction" ); DEBUG_SQLSRV_ASSERT( dbh->in_txn, "pdo_sqlsrv_dbh_commit: Not in transaction" );
core_sqlsrv_commit( driver_conn TSRMLS_CC ); core_sqlsrv_commit( driver_conn );
return 1; return 1;
} }
@ -967,7 +966,7 @@ int pdo_sqlsrv_dbh_commit( _Inout_ pdo_dbh_t *dbh TSRMLS_DC )
// dbh - The PDO managed connection object. // dbh - The PDO managed connection object.
// Return: // Return:
// 0 for failure and 1 for success. // 0 for failure and 1 for success.
int pdo_sqlsrv_dbh_rollback( _Inout_ pdo_dbh_t *dbh TSRMLS_DC ) int pdo_sqlsrv_dbh_rollback( _Inout_ pdo_dbh_t *dbh )
{ {
PDO_RESET_DBH_ERROR; PDO_RESET_DBH_ERROR;
PDO_VALIDATE_CONN; PDO_VALIDATE_CONN;
@ -982,7 +981,7 @@ int pdo_sqlsrv_dbh_rollback( _Inout_ pdo_dbh_t *dbh TSRMLS_DC )
DEBUG_SQLSRV_ASSERT( dbh->in_txn, "pdo_sqlsrv_dbh_rollback: Not in transaction" ); DEBUG_SQLSRV_ASSERT( dbh->in_txn, "pdo_sqlsrv_dbh_rollback: Not in transaction" );
core_sqlsrv_rollback( driver_conn TSRMLS_CC ); core_sqlsrv_rollback( driver_conn );
return 1; return 1;
} }
@ -1006,7 +1005,7 @@ int pdo_sqlsrv_dbh_rollback( _Inout_ pdo_dbh_t *dbh TSRMLS_DC )
// val - The value of the attribute to be set. // val - The value of the attribute to be set.
// Return: // Return:
// 0 for failure, 1 for success. // 0 for failure, 1 for success.
int pdo_sqlsrv_dbh_set_attr( _Inout_ pdo_dbh_t *dbh, _In_ zend_long attr, _Inout_ zval *val TSRMLS_DC ) int pdo_sqlsrv_dbh_set_attr( _Inout_ pdo_dbh_t *dbh, _In_ zend_long attr, _Inout_ zval *val )
{ {
PDO_RESET_DBH_ERROR; PDO_RESET_DBH_ERROR;
PDO_VALIDATE_CONN; PDO_VALIDATE_CONN;
@ -1169,7 +1168,7 @@ int pdo_sqlsrv_dbh_set_attr( _Inout_ pdo_dbh_t *dbh, _In_ zend_long attr, _Inout
// return_value - zval in which to return the attribute value. // return_value - zval in which to return the attribute value.
// Return: // Return:
// 0 for failure, 1 for success. // 0 for failure, 1 for success.
int pdo_sqlsrv_dbh_get_attr( _Inout_ pdo_dbh_t *dbh, _In_ zend_long attr, _Inout_ zval *return_value TSRMLS_DC ) int pdo_sqlsrv_dbh_get_attr( _Inout_ pdo_dbh_t *dbh, _In_ zend_long attr, _Inout_ zval *return_value )
{ {
PDO_RESET_DBH_ERROR; PDO_RESET_DBH_ERROR;
PDO_VALIDATE_CONN; PDO_VALIDATE_CONN;
@ -1213,26 +1212,26 @@ int pdo_sqlsrv_dbh_get_attr( _Inout_ pdo_dbh_t *dbh, _In_ zend_long attr, _Inout
case PDO_ATTR_SERVER_INFO: case PDO_ATTR_SERVER_INFO:
{ {
core_sqlsrv_get_server_info( driver_dbh, return_value TSRMLS_CC ); core_sqlsrv_get_server_info( driver_dbh, return_value );
break; break;
} }
case PDO_ATTR_SERVER_VERSION: case PDO_ATTR_SERVER_VERSION:
{ {
core_sqlsrv_get_server_version( driver_dbh, return_value TSRMLS_CC ); core_sqlsrv_get_server_version( driver_dbh, return_value );
break; break;
} }
case PDO_ATTR_CLIENT_VERSION: case PDO_ATTR_CLIENT_VERSION:
{ {
core_sqlsrv_get_client_info( driver_dbh, return_value TSRMLS_CC ); core_sqlsrv_get_client_info( driver_dbh, return_value );
//Add the PDO SQLSRV driver's file version //Add the PDO SQLSRV driver's file version
//Declarations below eliminate compiler warnings about string constant to char* conversions //Declarations below eliminate compiler warnings about string constant to char* conversions
const char* extver = "ExtensionVer"; const char* extver = "ExtensionVer";
std::string filever = VER_FILEVERSION_STR; std::string filever = VER_FILEVERSION_STR;
core::sqlsrv_add_assoc_string( *driver_dbh, return_value, extver, &filever[0], 1 /*duplicate*/ core::sqlsrv_add_assoc_string( *driver_dbh, return_value, extver, &filever[0], 1 /*duplicate*/
TSRMLS_CC ); );
break; break;
} }
@ -1315,7 +1314,7 @@ int pdo_sqlsrv_dbh_get_attr( _Inout_ pdo_dbh_t *dbh, _In_ zend_long attr, _Inout
// Return: // Return:
// 0 for failure, 1 for success. // 0 for failure, 1 for success.
int pdo_sqlsrv_dbh_return_error( _In_ pdo_dbh_t *dbh, _In_opt_ pdo_stmt_t *stmt, int pdo_sqlsrv_dbh_return_error( _In_ pdo_dbh_t *dbh, _In_opt_ pdo_stmt_t *stmt,
_Out_ zval *info TSRMLS_DC) _Out_ zval *info)
{ {
SQLSRV_ASSERT( dbh != NULL || stmt != NULL, "Either dbh or stmt must not be NULL to dereference the error." ); SQLSRV_ASSERT( dbh != NULL || stmt != NULL, "Either dbh or stmt must not be NULL to dereference the error." );
@ -1341,7 +1340,7 @@ int pdo_sqlsrv_dbh_return_error( _In_ pdo_dbh_t *dbh, _In_opt_ pdo_stmt_t *stmt,
// len - Length of the name. // len - Length of the name.
// Return: // Return:
// Returns the last insert id as a string. // Returns the last insert id as a string.
char * pdo_sqlsrv_dbh_last_id( _Inout_ pdo_dbh_t *dbh, _In_z_ const char *name, _Out_ size_t* len TSRMLS_DC ) char * pdo_sqlsrv_dbh_last_id( _Inout_ pdo_dbh_t *dbh, _In_z_ const char *name, _Out_ size_t* len )
{ {
PDO_RESET_DBH_ERROR; PDO_RESET_DBH_ERROR;
PDO_VALIDATE_CONN; PDO_VALIDATE_CONN;
@ -1368,7 +1367,7 @@ char * pdo_sqlsrv_dbh_last_id( _Inout_ pdo_dbh_t *dbh, _In_z_ const char *name,
else { else {
char* quoted_table = NULL; char* quoted_table = NULL;
size_t quoted_len = 0; size_t quoted_len = 0;
int quoted = pdo_sqlsrv_dbh_quote( dbh, name, strnlen_s( name ), &quoted_table, &quoted_len, PDO_PARAM_NULL TSRMLS_CC ); int quoted = pdo_sqlsrv_dbh_quote( dbh, name, strnlen_s( name ), &quoted_table, &quoted_len, PDO_PARAM_NULL );
SQLSRV_ASSERT( quoted, "PDO::lastInsertId failed to quote the table name."); SQLSRV_ASSERT( quoted, "PDO::lastInsertId failed to quote the table name.");
snprintf( last_insert_id_query, LAST_INSERT_ID_QUERY_MAX_LEN, SEQUENCE_CURRENT_VALUE_QUERY, quoted_table ); snprintf( last_insert_id_query, LAST_INSERT_ID_QUERY_MAX_LEN, SEQUENCE_CURRENT_VALUE_QUERY, quoted_table );
sqlsrv_free( quoted_table ); sqlsrv_free( quoted_table );
@ -1379,7 +1378,7 @@ char * pdo_sqlsrv_dbh_last_id( _Inout_ pdo_dbh_t *dbh, _In_z_ const char *name,
temp_stmt.dbh = dbh; temp_stmt.dbh = dbh;
// allocate a full driver statement to take advantage of the error handling // allocate a full driver statement to take advantage of the error handling
driver_stmt = core_sqlsrv_create_stmt( driver_dbh, core::allocate_stmt<pdo_sqlsrv_stmt>, NULL /*options_ht*/, NULL /*valid_stmt_opts*/, pdo_sqlsrv_handle_stmt_error, &temp_stmt TSRMLS_CC ); driver_stmt = core_sqlsrv_create_stmt( driver_dbh, core::allocate_stmt<pdo_sqlsrv_stmt>, NULL /*options_ht*/, NULL /*valid_stmt_opts*/, pdo_sqlsrv_handle_stmt_error, &temp_stmt );
driver_stmt->set_func( __FUNCTION__ ); driver_stmt->set_func( __FUNCTION__ );
@ -1392,11 +1391,11 @@ char * pdo_sqlsrv_dbh_last_id( _Inout_ pdo_dbh_t *dbh, _In_z_ const char *name,
} }
// execute the last insert id query // execute the last insert id query
core::SQLExecDirectW( driver_stmt, wsql_string TSRMLS_CC ); core::SQLExecDirectW( driver_stmt, wsql_string );
core::SQLFetchScroll( driver_stmt, SQL_FETCH_NEXT, 0 TSRMLS_CC ); core::SQLFetchScroll( driver_stmt, SQL_FETCH_NEXT, 0 );
SQLRETURN r = core::SQLGetData( driver_stmt, 1, SQL_C_CHAR, id_str, LAST_INSERT_ID_BUFF_LEN, SQLRETURN r = core::SQLGetData( driver_stmt, 1, SQL_C_CHAR, id_str, LAST_INSERT_ID_BUFF_LEN,
reinterpret_cast<SQLLEN*>( len ), false TSRMLS_CC ); reinterpret_cast<SQLLEN*>( len ), false );
CHECK_CUSTOM_ERROR( (!SQL_SUCCEEDED( r ) || *len == SQL_NULL_DATA || *len == SQL_NO_TOTAL), driver_stmt, CHECK_CUSTOM_ERROR( (!SQL_SUCCEEDED( r ) || *len == SQL_NULL_DATA || *len == SQL_NO_TOTAL), driver_stmt,
PDO_SQLSRV_ERROR_LAST_INSERT_ID ) { PDO_SQLSRV_ERROR_LAST_INSERT_ID ) {
@ -1442,7 +1441,7 @@ char * pdo_sqlsrv_dbh_last_id( _Inout_ pdo_dbh_t *dbh, _In_z_ const char *name,
// Return: // Return:
// 0 for failure, 1 for success. // 0 for failure, 1 for success.
int pdo_sqlsrv_dbh_quote( _Inout_ pdo_dbh_t* dbh, _In_reads_(unquoted_len) const char* unquoted, _In_ size_t unquoted_len, _Outptr_result_buffer_(*quoted_len) char **quoted, _Out_ size_t* quoted_len, int pdo_sqlsrv_dbh_quote( _Inout_ pdo_dbh_t* dbh, _In_reads_(unquoted_len) const char* unquoted, _In_ size_t unquoted_len, _Outptr_result_buffer_(*quoted_len) char **quoted, _Out_ size_t* quoted_len,
enum pdo_param_type paramtype TSRMLS_DC ) enum pdo_param_type paramtype )
{ {
PDO_RESET_DBH_ERROR; PDO_RESET_DBH_ERROR;
PDO_VALIDATE_CONN; PDO_VALIDATE_CONN;
@ -1602,7 +1601,7 @@ int pdo_sqlsrv_dbh_quote( _Inout_ pdo_dbh_t* dbh, _In_reads_(unquoted_len) const
} }
// This method is not implemented by this driver. // This method is not implemented by this driver.
pdo_sqlsrv_function_entry *pdo_sqlsrv_get_driver_methods( _Inout_ pdo_dbh_t *dbh, int kind TSRMLS_DC ) pdo_sqlsrv_function_entry *pdo_sqlsrv_get_driver_methods( _Inout_ pdo_dbh_t *dbh, int kind )
{ {
PDO_RESET_DBH_ERROR; PDO_RESET_DBH_ERROR;
PDO_VALIDATE_CONN; PDO_VALIDATE_CONN;
@ -1622,7 +1621,7 @@ namespace {
// Maps the PDO driver specific statement option/attribute constants to the core layer // Maps the PDO driver specific statement option/attribute constants to the core layer
// statement option/attribute constants. // statement option/attribute constants.
void add_stmt_option_key(_Inout_ sqlsrv_context& ctx, _In_ size_t key, _Inout_ HashTable* options_ht, void add_stmt_option_key(_Inout_ sqlsrv_context& ctx, _In_ size_t key, _Inout_ HashTable* options_ht,
_Inout_ zval* data TSRMLS_DC) _Inout_ zval* data)
{ {
zend_ulong option_key = -1; zend_ulong option_key = -1;
switch (key) { switch (key) {
@ -1689,7 +1688,7 @@ void add_stmt_option_key(_Inout_ sqlsrv_context& ctx, _In_ size_t key, _Inout_ H
// if a PDO handled option makes it through (such as PDO_ATTR_STATEMENT_CLASS, just skip it // if a PDO handled option makes it through (such as PDO_ATTR_STATEMENT_CLASS, just skip it
if (option_key != -1) { if (option_key != -1) {
zval_add_ref(data); zval_add_ref(data);
core::sqlsrv_zend_hash_index_update(ctx, options_ht, option_key, data TSRMLS_CC); core::sqlsrv_zend_hash_index_update(ctx, options_ht, option_key, data);
} }
} }
@ -1702,7 +1701,7 @@ void add_stmt_option_key(_Inout_ sqlsrv_context& ctx, _In_ size_t key, _Inout_ H
// ctx - The current context. // ctx - The current context.
// stmt_options - The user provided list of statement options. // stmt_options - The user provided list of statement options.
// pdo_stmt_options_ht - Output hashtable of statement options. // pdo_stmt_options_ht - Output hashtable of statement options.
void validate_stmt_options( _Inout_ sqlsrv_context& ctx, _Inout_ zval* stmt_options, _Inout_ HashTable* pdo_stmt_options_ht TSRMLS_DC ) void validate_stmt_options( _Inout_ sqlsrv_context& ctx, _Inout_ zval* stmt_options, _Inout_ HashTable* pdo_stmt_options_ht )
{ {
try { try {
@ -1720,7 +1719,7 @@ void validate_stmt_options( _Inout_ sqlsrv_context& ctx, _Inout_ zval* stmt_opti
throw core::CoreException(); throw core::CoreException();
} }
add_stmt_option_key( ctx, int_key, pdo_stmt_options_ht, data TSRMLS_CC ); add_stmt_option_key( ctx, int_key, pdo_stmt_options_ht, data );
} ZEND_HASH_FOREACH_END(); } ZEND_HASH_FOREACH_END();
} }
} }
@ -1731,9 +1730,8 @@ void validate_stmt_options( _Inout_ sqlsrv_context& ctx, _Inout_ zval* stmt_opti
} }
void pdo_bool_conn_str_func::func( _In_ connection_option const* option, _Inout_ zval* value, sqlsrv_conn* /*conn*/, _Out_ std::string& conn_str TSRMLS_DC ) void pdo_bool_conn_str_func::func( _In_ connection_option const* option, _Inout_ zval* value, sqlsrv_conn* /*conn*/, _Out_ std::string& conn_str )
{ {
TSRMLS_C;
char const* val_str = "no"; char const* val_str = "no";
if( core_str_zval_is_true( value ) ) { if( core_str_zval_is_true( value ) ) {
@ -1748,7 +1746,7 @@ void pdo_bool_conn_str_func::func( _In_ connection_option const* option, _Inout_
} }
void pdo_txn_isolation_conn_attr_func::func( connection_option const* /*option*/, _In_ zval* value_z, _Inout_ sqlsrv_conn* conn, void pdo_txn_isolation_conn_attr_func::func( connection_option const* /*option*/, _In_ zval* value_z, _Inout_ sqlsrv_conn* conn,
std::string& /*conn_str*/ TSRMLS_DC ) std::string& /*conn_str*/ )
{ {
try { try {
@ -1800,7 +1798,7 @@ void pdo_txn_isolation_conn_attr_func::func( connection_option const* /*option*/
} }
} }
core::SQLSetConnectAttr( conn, SQL_COPT_SS_TXN_ISOLATION, reinterpret_cast<SQLPOINTER>( out_val ), SQL_IS_UINTEGER TSRMLS_CC ); core::SQLSetConnectAttr( conn, SQL_COPT_SS_TXN_ISOLATION, reinterpret_cast<SQLPOINTER>( out_val ), SQL_IS_UINTEGER );
} }
catch( core::CoreException& ) { catch( core::CoreException& ) {

View file

@ -53,8 +53,8 @@ pdo_driver_t pdo_sqlsrv_driver = {
// functions to register SQLSRV constants with the PDO class // functions to register SQLSRV constants with the PDO class
// (It's in all CAPS so it looks like the Zend macros that do similar work) // (It's in all CAPS so it looks like the Zend macros that do similar work)
void REGISTER_PDO_SQLSRV_CLASS_CONST_LONG( _In_z_ char const* name, _In_ long value TSRMLS_DC ); void REGISTER_PDO_SQLSRV_CLASS_CONST_LONG( _In_z_ char const* name, _In_ long value );
void REGISTER_PDO_SQLSRV_CLASS_CONST_STRING( _In_z_ char const* name, _In_z_ char const* value TSRMLS_DC ); void REGISTER_PDO_SQLSRV_CLASS_CONST_STRING( _In_z_ char const* name, _In_z_ char const* value );
struct sqlsrv_attr_pdo_constant { struct sqlsrv_attr_pdo_constant {
const char *name; const char *name;
@ -154,18 +154,18 @@ PHP_MINIT_FUNCTION(pdo_sqlsrv)
// register all attributes supported by this driver. // register all attributes supported by this driver.
for( int i= 0; pdo_attr_constants[i].name != NULL; ++i ) { for( int i= 0; pdo_attr_constants[i].name != NULL; ++i ) {
REGISTER_PDO_SQLSRV_CLASS_CONST_LONG( pdo_attr_constants[i].name, pdo_attr_constants[i].value TSRMLS_CC ); REGISTER_PDO_SQLSRV_CLASS_CONST_LONG( pdo_attr_constants[i].name, pdo_attr_constants[i].value );
} }
REGISTER_PDO_SQLSRV_CLASS_CONST_STRING( "SQLSRV_TXN_READ_UNCOMMITTED", PDOTxnIsolationValues::READ_UNCOMMITTED TSRMLS_CC ); REGISTER_PDO_SQLSRV_CLASS_CONST_STRING( "SQLSRV_TXN_READ_UNCOMMITTED", PDOTxnIsolationValues::READ_UNCOMMITTED );
REGISTER_PDO_SQLSRV_CLASS_CONST_STRING( "SQLSRV_TXN_READ_COMMITTED", PDOTxnIsolationValues::READ_COMMITTED TSRMLS_CC ); REGISTER_PDO_SQLSRV_CLASS_CONST_STRING( "SQLSRV_TXN_READ_COMMITTED", PDOTxnIsolationValues::READ_COMMITTED );
REGISTER_PDO_SQLSRV_CLASS_CONST_STRING( "SQLSRV_TXN_REPEATABLE_READ", PDOTxnIsolationValues::REPEATABLE_READ TSRMLS_CC ); REGISTER_PDO_SQLSRV_CLASS_CONST_STRING( "SQLSRV_TXN_REPEATABLE_READ", PDOTxnIsolationValues::REPEATABLE_READ );
REGISTER_PDO_SQLSRV_CLASS_CONST_STRING( "SQLSRV_TXN_SERIALIZABLE", PDOTxnIsolationValues::SERIALIZABLE TSRMLS_CC ); REGISTER_PDO_SQLSRV_CLASS_CONST_STRING( "SQLSRV_TXN_SERIALIZABLE", PDOTxnIsolationValues::SERIALIZABLE );
REGISTER_PDO_SQLSRV_CLASS_CONST_STRING( "SQLSRV_TXN_SNAPSHOT", PDOTxnIsolationValues::SNAPSHOT TSRMLS_CC ); REGISTER_PDO_SQLSRV_CLASS_CONST_STRING( "SQLSRV_TXN_SNAPSHOT", PDOTxnIsolationValues::SNAPSHOT );
// retrieve the handles for the environments // retrieve the handles for the environments
core_sqlsrv_minit( &g_pdo_henv_cp, &g_pdo_henv_ncp, pdo_sqlsrv_handle_env_error, "PHP_MINIT_FUNCTION for pdo_sqlsrv" TSRMLS_CC ); core_sqlsrv_minit( &g_pdo_henv_cp, &g_pdo_henv_ncp, pdo_sqlsrv_handle_env_error, "PHP_MINIT_FUNCTION for pdo_sqlsrv" );
} }
catch( ... ) { catch( ... ) {
@ -274,23 +274,23 @@ namespace {
// mimic the functionality of the REGISTER_PDO_CLASS_CONST_LONG. We use this instead of the macro because // mimic the functionality of the REGISTER_PDO_CLASS_CONST_LONG. We use this instead of the macro because
// we dynamically link the pdo_get_dbh_class function rather than use the static php_pdo_get_dbh_ce (see MINIT) // we dynamically link the pdo_get_dbh_class function rather than use the static php_pdo_get_dbh_ce (see MINIT)
void REGISTER_PDO_SQLSRV_CLASS_CONST_LONG( _In_z_ char const* name, _In_ long value TSRMLS_DC ) void REGISTER_PDO_SQLSRV_CLASS_CONST_LONG( _In_z_ char const* name, _In_ long value )
{ {
zend_class_entry* zend_class = php_pdo_get_dbh_ce(); zend_class_entry* zend_class = php_pdo_get_dbh_ce();
SQLSRV_ASSERT( zend_class != NULL, "REGISTER_PDO_SQLSRV_CLASS_CONST_LONG: php_pdo_get_dbh_ce failed"); SQLSRV_ASSERT( zend_class != NULL, "REGISTER_PDO_SQLSRV_CLASS_CONST_LONG: php_pdo_get_dbh_ce failed");
int zr = zend_declare_class_constant_long( zend_class, const_cast<char*>( name ), strlen( name ), value TSRMLS_CC ); int zr = zend_declare_class_constant_long( zend_class, const_cast<char*>( name ), strlen( name ), value );
if( zr == FAILURE ) { if( zr == FAILURE ) {
throw core::CoreException(); throw core::CoreException();
} }
} }
void REGISTER_PDO_SQLSRV_CLASS_CONST_STRING( _In_z_ char const* name, _In_z_ char const* value TSRMLS_DC ) void REGISTER_PDO_SQLSRV_CLASS_CONST_STRING( _In_z_ char const* name, _In_z_ char const* value )
{ {
zend_class_entry* zend_class = php_pdo_get_dbh_ce(); zend_class_entry* zend_class = php_pdo_get_dbh_ce();
SQLSRV_ASSERT( zend_class != NULL, "REGISTER_PDO_SQLSRV_CLASS_CONST_STRING: php_pdo_get_dbh_ce failed"); SQLSRV_ASSERT( zend_class != NULL, "REGISTER_PDO_SQLSRV_CLASS_CONST_STRING: php_pdo_get_dbh_ce failed");
int zr = zend_declare_class_constant_string( zend_class, const_cast<char*>( name ), strlen( name ), const_cast<char*>( value ) TSRMLS_CC ); int zr = zend_declare_class_constant_string( zend_class, const_cast<char*>( name ), strlen( name ), const_cast<char*>( value ) );
if( zr == FAILURE ) { if( zr == FAILURE ) {
throw core::CoreException(); throw core::CoreException();

View file

@ -122,7 +122,7 @@ bool string_parser::discard_white_spaces()
} }
// Add a key-value pair to the hashtable // Add a key-value pair to the hashtable
void string_parser::add_key_value_pair( _In_reads_(len) const char* value, _In_ int len TSRMLS_DC ) void string_parser::add_key_value_pair( _In_reads_(len) const char* value, _In_ int len )
{ {
zval value_z; zval value_z;
ZVAL_UNDEF( &value_z ); ZVAL_UNDEF( &value_z );
@ -136,19 +136,19 @@ void string_parser::add_key_value_pair( _In_reads_(len) const char* value, _In_
ZVAL_STRINGL( &value_z, const_cast<char*>( value ), len ); ZVAL_STRINGL( &value_z, const_cast<char*>( value ), len );
} }
core::sqlsrv_zend_hash_index_update( *ctx, this->element_ht, this->current_key, &value_z TSRMLS_CC ); core::sqlsrv_zend_hash_index_update( *ctx, this->element_ht, this->current_key, &value_z );
} }
// Add a key-value pair to the hashtable with int value // Add a key-value pair to the hashtable with int value
void sql_string_parser::add_key_int_value_pair( _In_ unsigned int value TSRMLS_DC ) { void sql_string_parser::add_key_int_value_pair( _In_ unsigned int value ) {
zval value_z; zval value_z;
ZVAL_LONG( &value_z, value ); ZVAL_LONG( &value_z, value );
core::sqlsrv_zend_hash_index_update( *ctx, this->element_ht, this->current_key, &value_z TSRMLS_CC ); core::sqlsrv_zend_hash_index_update( *ctx, this->element_ht, this->current_key, &value_z );
} }
// Validate a given DSN keyword. // Validate a given DSN keyword.
void conn_string_parser::validate_key( _In_reads_(key_len) const char *key, _Inout_ int key_len TSRMLS_DC ) void conn_string_parser::validate_key( _In_reads_(key_len) const char *key, _Inout_ int key_len )
{ {
int new_len = discard_trailing_white_spaces( key, key_len ); int new_len = discard_trailing_white_spaces( key, key_len );
@ -173,7 +173,7 @@ void conn_string_parser::validate_key( _In_reads_(key_len) const char *key, _Ino
THROW_PDO_ERROR( this->ctx, PDO_SQLSRV_ERROR_INVALID_DSN_KEY, static_cast<char*>( key_name ) ); THROW_PDO_ERROR( this->ctx, PDO_SQLSRV_ERROR_INVALID_DSN_KEY, static_cast<char*>( key_name ) );
} }
void conn_string_parser::add_key_value_pair( _In_reads_(len) const char* value, _In_ int len TSRMLS_DC ) void conn_string_parser::add_key_value_pair( _In_reads_(len) const char* value, _In_ int len )
{ {
// if the keyword is 'Authentication', check whether the user specified option is supported // if the keyword is 'Authentication', check whether the user specified option is supported
bool valid = true; bool valid = true;
@ -208,7 +208,7 @@ inline bool sql_string_parser::is_placeholder_char( char c )
} }
// Primary function which parses the connection string/DSN. // Primary function which parses the connection string/DSN.
void conn_string_parser:: parse_conn_string( TSRMLS_D ) void conn_string_parser:: parse_conn_string( void )
{ {
States state = FirstKeyValuePair; // starting state States state = FirstKeyValuePair; // starting state
int start_pos = -1; int start_pos = -1;
@ -244,7 +244,7 @@ void conn_string_parser:: parse_conn_string( TSRMLS_D )
} }
} }
this->validate_key( &( this->orig_str[start_pos] ), ( pos - start_pos ) TSRMLS_CC ); this->validate_key( &( this->orig_str[start_pos] ), ( pos - start_pos ) );
state = Value; state = Value;
@ -261,7 +261,7 @@ void conn_string_parser:: parse_conn_string( TSRMLS_D )
// if EOS encountered after 0 or more spaces OR semi-colon encountered. // if EOS encountered after 0 or more spaces OR semi-colon encountered.
if( !discard_white_spaces() || this->orig_str[pos] == ';' ) { if( !discard_white_spaces() || this->orig_str[pos] == ';' ) {
add_key_value_pair( NULL, 0 TSRMLS_CC ); add_key_value_pair( NULL, 0 );
if( this->is_eos() ) { if( this->is_eos() ) {
@ -323,7 +323,7 @@ void conn_string_parser:: parse_conn_string( TSRMLS_D )
state = NextKeyValuePair; state = NextKeyValuePair;
} }
add_key_value_pair( &( this->orig_str[start_pos] ), this->pos - start_pos TSRMLS_CC ); add_key_value_pair( &( this->orig_str[start_pos] ), this->pos - start_pos );
SQLSRV_ASSERT((( state == NextKeyValuePair ) || ( this->is_eos() )), SQLSRV_ASSERT((( state == NextKeyValuePair ) || ( this->is_eos() )),
"conn_string_parser::parse_conn_string: Invalid state encountered " ); "conn_string_parser::parse_conn_string: Invalid state encountered " );
@ -338,7 +338,7 @@ void conn_string_parser:: parse_conn_string( TSRMLS_D )
if( !next() ) { if( !next() ) {
// EOS // EOS
add_key_value_pair( &( this->orig_str[start_pos] ), this->pos - start_pos TSRMLS_CC ); add_key_value_pair( &( this->orig_str[start_pos] ), this->pos - start_pos );
break; break;
} }
@ -365,7 +365,7 @@ void conn_string_parser:: parse_conn_string( TSRMLS_D )
if( ! this->discard_white_spaces() ) { if( ! this->discard_white_spaces() ) {
//EOS //EOS
add_key_value_pair( &( this->orig_str[start_pos] ), end_pos - start_pos TSRMLS_CC ); add_key_value_pair( &( this->orig_str[start_pos] ), end_pos - start_pos );
break; break;
} }
} }
@ -373,7 +373,7 @@ void conn_string_parser:: parse_conn_string( TSRMLS_D )
// if semi-colon than go to next key-value pair // if semi-colon than go to next key-value pair
if ( this->orig_str[pos] == ';' ) { if ( this->orig_str[pos] == ';' ) {
add_key_value_pair( &( this->orig_str[start_pos] ), end_pos - start_pos TSRMLS_CC ); add_key_value_pair( &( this->orig_str[start_pos] ), end_pos - start_pos );
state = NextKeyValuePair; state = NextKeyValuePair;
break; break;
} }
@ -417,7 +417,7 @@ void conn_string_parser:: parse_conn_string( TSRMLS_D )
} }
// Primary function which parses out the named placeholders from a sql string. // Primary function which parses out the named placeholders from a sql string.
void sql_string_parser::parse_sql_string( TSRMLS_D ) { void sql_string_parser::parse_sql_string( void ) {
try { try {
int start_pos = -1; int start_pos = -1;
while ( !this->is_eos() ) { while ( !this->is_eos() ) {
@ -447,7 +447,7 @@ void sql_string_parser::parse_sql_string( TSRMLS_D ) {
while ( is_placeholder_char( this->orig_str[pos] )) { while ( is_placeholder_char( this->orig_str[pos] )) {
next(); next();
} }
add_key_value_pair( &( this->orig_str[start_pos] ), this->pos - start_pos TSRMLS_CC ); add_key_value_pair( &( this->orig_str[start_pos] ), this->pos - start_pos );
discard_white_spaces(); discard_white_spaces();
// if an '=' is right after a placeholder, it means the placeholder is for output parameters // if an '=' is right after a placeholder, it means the placeholder is for output parameters
// and emulate prepare does not support output parameters // and emulate prepare does not support output parameters

View file

@ -53,7 +53,7 @@ inline SQLSMALLINT pdo_fetch_ori_to_odbc_fetch_ori ( _In_ enum pdo_fetch_orienta
// Returns SQLSRV data type for a given PDO type. See pdo_param_type // Returns SQLSRV data type for a given PDO type. See pdo_param_type
// for list of supported pdo types. // for list of supported pdo types.
SQLSRV_PHPTYPE pdo_type_to_sqlsrv_php_type( _Inout_ sqlsrv_stmt* driver_stmt, _In_ enum pdo_param_type pdo_type TSRMLS_DC ) SQLSRV_PHPTYPE pdo_type_to_sqlsrv_php_type( _Inout_ sqlsrv_stmt* driver_stmt, _In_ enum pdo_param_type pdo_type )
{ {
pdo_sqlsrv_stmt *pdo_stmt = static_cast<pdo_sqlsrv_stmt*>(driver_stmt); pdo_sqlsrv_stmt *pdo_stmt = static_cast<pdo_sqlsrv_stmt*>(driver_stmt);
SQLSRV_ASSERT(pdo_stmt != NULL, "pdo_type_to_sqlsrv_php_type: pdo_stmt object was null"); SQLSRV_ASSERT(pdo_stmt != NULL, "pdo_type_to_sqlsrv_php_type: pdo_stmt object was null");
@ -137,7 +137,7 @@ inline pdo_param_type sql_type_to_pdo_type( _In_ SQLSMALLINT sql_type )
// Calls core_sqlsrv_set_scrollable function to set cursor. // Calls core_sqlsrv_set_scrollable function to set cursor.
// PDO supports two cursor types: PDO_CURSOR_FWDONLY, PDO_CURSOR_SCROLL. // PDO supports two cursor types: PDO_CURSOR_FWDONLY, PDO_CURSOR_SCROLL.
void set_stmt_cursors( _Inout_ sqlsrv_stmt* stmt, _In_ zval* value_z TSRMLS_DC ) void set_stmt_cursors( _Inout_ sqlsrv_stmt* stmt, _In_ zval* value_z )
{ {
if( Z_TYPE_P( value_z ) != IS_LONG ) { if( Z_TYPE_P( value_z ) != IS_LONG ) {
@ -161,10 +161,10 @@ void set_stmt_cursors( _Inout_ sqlsrv_stmt* stmt, _In_ zval* value_z TSRMLS_DC )
THROW_PDO_ERROR( stmt, PDO_SQLSRV_ERROR_INVALID_CURSOR_TYPE ); THROW_PDO_ERROR( stmt, PDO_SQLSRV_ERROR_INVALID_CURSOR_TYPE );
} }
core_sqlsrv_set_scrollable( stmt, odbc_cursor_type TSRMLS_CC ); core_sqlsrv_set_scrollable( stmt, odbc_cursor_type );
} }
void set_stmt_cursor_scroll_type( _Inout_ sqlsrv_stmt* stmt, _In_ zval* value_z TSRMLS_DC ) void set_stmt_cursor_scroll_type( _Inout_ sqlsrv_stmt* stmt, _In_ zval* value_z )
{ {
if( Z_TYPE_P( value_z ) != IS_LONG ) { if( Z_TYPE_P( value_z ) != IS_LONG ) {
@ -178,14 +178,14 @@ void set_stmt_cursor_scroll_type( _Inout_ sqlsrv_stmt* stmt, _In_ zval* value_z
long odbc_cursor_type = static_cast<long>( Z_LVAL_P( value_z ) ); long odbc_cursor_type = static_cast<long>( Z_LVAL_P( value_z ) );
core_sqlsrv_set_scrollable( stmt, odbc_cursor_type TSRMLS_CC ); core_sqlsrv_set_scrollable( stmt, odbc_cursor_type );
return; return;
} }
// Sets the statement encoding. Default encoding on the statement // Sets the statement encoding. Default encoding on the statement
// implies use the connection's encoding. // implies use the connection's encoding.
void set_stmt_encoding( _Inout_ sqlsrv_stmt* stmt, _In_ zval* value_z TSRMLS_DC ) void set_stmt_encoding( _Inout_ sqlsrv_stmt* stmt, _In_ zval* value_z )
{ {
// validate the value // validate the value
if( Z_TYPE_P( value_z ) != IS_LONG ) { if( Z_TYPE_P( value_z ) != IS_LONG ) {
@ -280,20 +280,20 @@ zval convert_to_zval(_Inout_ sqlsrv_stmt* stmt, _In_ SQLSRV_PHPTYPE sqlsrv_php_t
} // namespace } // namespace
int pdo_sqlsrv_stmt_dtor( _Inout_ pdo_stmt_t *stmt TSRMLS_DC ); int pdo_sqlsrv_stmt_dtor( _Inout_ pdo_stmt_t *stmt );
int pdo_sqlsrv_stmt_execute( _Inout_ pdo_stmt_t *stmt TSRMLS_DC ); int pdo_sqlsrv_stmt_execute( _Inout_ pdo_stmt_t *stmt );
int pdo_sqlsrv_stmt_fetch( _Inout_ pdo_stmt_t *stmt, _In_ enum pdo_fetch_orientation ori, int pdo_sqlsrv_stmt_fetch( _Inout_ pdo_stmt_t *stmt, _In_ enum pdo_fetch_orientation ori,
_In_ zend_long offset TSRMLS_DC ); _In_ zend_long offset );
int pdo_sqlsrv_stmt_param_hook( _Inout_ pdo_stmt_t *stmt, int pdo_sqlsrv_stmt_param_hook( _Inout_ pdo_stmt_t *stmt,
_Inout_ struct pdo_bound_param_data *param, _In_ enum pdo_param_event event_type TSRMLS_DC ); _Inout_ struct pdo_bound_param_data *param, _In_ enum pdo_param_event event_type );
int pdo_sqlsrv_stmt_describe_col( _Inout_ pdo_stmt_t *stmt, _In_ int colno TSRMLS_DC ); int pdo_sqlsrv_stmt_describe_col( _Inout_ pdo_stmt_t *stmt, _In_ int colno );
int pdo_sqlsrv_stmt_get_col_data( _Inout_ pdo_stmt_t *stmt, _In_ int colno, int pdo_sqlsrv_stmt_get_col_data( _Inout_ pdo_stmt_t *stmt, _In_ int colno,
_Out_writes_bytes_opt_(*len) char **ptr, _Inout_ size_t *len, _Out_opt_ int *caller_frees TSRMLS_DC ); _Out_writes_bytes_opt_(*len) char **ptr, _Inout_ size_t *len, _Out_opt_ int *caller_frees );
int pdo_sqlsrv_stmt_set_attr( _Inout_ pdo_stmt_t *stmt, _In_ zend_long attr, _Inout_ zval *val TSRMLS_DC ); int pdo_sqlsrv_stmt_set_attr( _Inout_ pdo_stmt_t *stmt, _In_ zend_long attr, _Inout_ zval *val );
int pdo_sqlsrv_stmt_get_attr( _Inout_ pdo_stmt_t *stmt, _In_ zend_long attr, _Inout_ zval *return_value TSRMLS_DC ); int pdo_sqlsrv_stmt_get_attr( _Inout_ pdo_stmt_t *stmt, _In_ zend_long attr, _Inout_ zval *return_value );
int pdo_sqlsrv_stmt_get_col_meta( _Inout_ pdo_stmt_t *stmt, _In_ zend_long colno, _Inout_ zval *return_value TSRMLS_DC ); int pdo_sqlsrv_stmt_get_col_meta( _Inout_ pdo_stmt_t *stmt, _In_ zend_long colno, _Inout_ zval *return_value );
int pdo_sqlsrv_stmt_next_rowset( _Inout_ pdo_stmt_t *stmt TSRMLS_DC ); int pdo_sqlsrv_stmt_next_rowset( _Inout_ pdo_stmt_t *stmt );
int pdo_sqlsrv_stmt_close_cursor( _Inout_ pdo_stmt_t *stmt TSRMLS_DC ); int pdo_sqlsrv_stmt_close_cursor( _Inout_ pdo_stmt_t *stmt );
struct pdo_stmt_methods pdo_sqlsrv_stmt_methods = { struct pdo_stmt_methods pdo_sqlsrv_stmt_methods = {
@ -311,40 +311,40 @@ struct pdo_stmt_methods pdo_sqlsrv_stmt_methods = {
}; };
void stmt_option_pdo_scrollable:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC ) void stmt_option_pdo_scrollable:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z )
{ {
set_stmt_cursors( stmt, value_z TSRMLS_CC ); set_stmt_cursors( stmt, value_z );
} }
void stmt_option_encoding:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC ) void stmt_option_encoding:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z )
{ {
set_stmt_encoding( stmt, value_z TSRMLS_CC ); set_stmt_encoding( stmt, value_z );
} }
void stmt_option_direct_query:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC ) void stmt_option_direct_query:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z )
{ {
pdo_sqlsrv_stmt *pdo_stmt = static_cast<pdo_sqlsrv_stmt*>( stmt ); pdo_sqlsrv_stmt *pdo_stmt = static_cast<pdo_sqlsrv_stmt*>( stmt );
pdo_stmt->direct_query = ( zend_is_true( value_z )) ? true : false; pdo_stmt->direct_query = ( zend_is_true( value_z )) ? true : false;
} }
void stmt_option_cursor_scroll_type:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC ) void stmt_option_cursor_scroll_type:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z )
{ {
set_stmt_cursor_scroll_type( stmt, value_z TSRMLS_CC ); set_stmt_cursor_scroll_type( stmt, value_z );
} }
void stmt_option_emulate_prepares:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC ) void stmt_option_emulate_prepares:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z )
{ {
pdo_stmt_t *pdo_stmt = static_cast<pdo_stmt_t*>( stmt->driver() ); pdo_stmt_t *pdo_stmt = static_cast<pdo_stmt_t*>( stmt->driver() );
pdo_stmt->supports_placeholders = ( zend_is_true( value_z )) ? PDO_PLACEHOLDER_NONE : PDO_PLACEHOLDER_POSITIONAL; pdo_stmt->supports_placeholders = ( zend_is_true( value_z )) ? PDO_PLACEHOLDER_NONE : PDO_PLACEHOLDER_POSITIONAL;
} }
void stmt_option_fetch_numeric:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC ) void stmt_option_fetch_numeric:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z )
{ {
pdo_sqlsrv_stmt *pdo_stmt = static_cast<pdo_sqlsrv_stmt*>( stmt ); pdo_sqlsrv_stmt *pdo_stmt = static_cast<pdo_sqlsrv_stmt*>( stmt );
pdo_stmt->fetch_numeric = ( zend_is_true( value_z )) ? true : false; pdo_stmt->fetch_numeric = ( zend_is_true( value_z )) ? true : false;
} }
void stmt_option_fetch_datetime:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC ) void stmt_option_fetch_datetime:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z )
{ {
pdo_sqlsrv_stmt *pdo_stmt = static_cast<pdo_sqlsrv_stmt*>( stmt ); pdo_sqlsrv_stmt *pdo_stmt = static_cast<pdo_sqlsrv_stmt*>( stmt );
pdo_stmt->fetch_datetime = ( zend_is_true( value_z )) ? true : false; pdo_stmt->fetch_datetime = ( zend_is_true( value_z )) ? true : false;
@ -384,7 +384,7 @@ pdo_sqlsrv_stmt::~pdo_sqlsrv_stmt( void )
// *stmt - Pointer to current statement // *stmt - Pointer to current statement
// Return: // Return:
// Returns 0 for failure, 1 for success. // Returns 0 for failure, 1 for success.
int pdo_sqlsrv_stmt_close_cursor( _Inout_ pdo_stmt_t *stmt TSRMLS_DC ) int pdo_sqlsrv_stmt_close_cursor( _Inout_ pdo_stmt_t *stmt )
{ {
PDO_RESET_STMT_ERROR; PDO_RESET_STMT_ERROR;
PDO_VALIDATE_STMT; PDO_VALIDATE_STMT;
@ -404,7 +404,7 @@ int pdo_sqlsrv_stmt_close_cursor( _Inout_ pdo_stmt_t *stmt TSRMLS_DC )
if ( driver_stmt && driver_stmt->executed == true ) if ( driver_stmt && driver_stmt->executed == true )
{ {
while( driver_stmt && driver_stmt->past_next_result_end == false ) { while( driver_stmt && driver_stmt->past_next_result_end == false ) {
core_sqlsrv_next_result( driver_stmt TSRMLS_CC ); core_sqlsrv_next_result( driver_stmt );
} }
} }
} }
@ -428,7 +428,7 @@ int pdo_sqlsrv_stmt_close_cursor( _Inout_ pdo_stmt_t *stmt TSRMLS_DC )
// colno - Index of the column which requires description. // colno - Index of the column which requires description.
// Return: // Return:
// 0 for failure, 1 for success. // 0 for failure, 1 for success.
int pdo_sqlsrv_stmt_describe_col( _Inout_ pdo_stmt_t *stmt, _In_ int colno TSRMLS_DC) int pdo_sqlsrv_stmt_describe_col( _Inout_ pdo_stmt_t *stmt, _In_ int colno)
{ {
PDO_RESET_STMT_ERROR; PDO_RESET_STMT_ERROR;
PDO_VALIDATE_STMT; PDO_VALIDATE_STMT;
@ -441,7 +441,7 @@ int pdo_sqlsrv_stmt_describe_col( _Inout_ pdo_stmt_t *stmt, _In_ int colno TSRML
try { try {
core_meta_data = core_sqlsrv_field_metadata( reinterpret_cast<sqlsrv_stmt*>( stmt->driver_data ), colno TSRMLS_CC ); core_meta_data = core_sqlsrv_field_metadata( reinterpret_cast<sqlsrv_stmt*>( stmt->driver_data ), colno );
} }
catch( core::CoreException& ) { catch( core::CoreException& ) {
@ -485,7 +485,7 @@ int pdo_sqlsrv_stmt_describe_col( _Inout_ pdo_stmt_t *stmt, _In_ int colno TSRML
// *stmt - pointer to current statement // *stmt - pointer to current statement
// Return: // Return:
// 1 for success. // 1 for success.
int pdo_sqlsrv_stmt_dtor( _Inout_ pdo_stmt_t *stmt TSRMLS_DC ) int pdo_sqlsrv_stmt_dtor( _Inout_ pdo_stmt_t *stmt )
{ {
pdo_sqlsrv_stmt* driver_stmt = reinterpret_cast<pdo_sqlsrv_stmt*>( stmt->driver_data ); pdo_sqlsrv_stmt* driver_stmt = reinterpret_cast<pdo_sqlsrv_stmt*>( stmt->driver_data );
@ -523,7 +523,7 @@ int pdo_sqlsrv_stmt_dtor( _Inout_ pdo_stmt_t *stmt TSRMLS_DC )
// *stmt - pointer to the current statement. // *stmt - pointer to the current statement.
// Return: // Return:
// 0 for failure, 1 for success. // 0 for failure, 1 for success.
int pdo_sqlsrv_stmt_execute( _Inout_ pdo_stmt_t *stmt TSRMLS_DC ) int pdo_sqlsrv_stmt_execute( _Inout_ pdo_stmt_t *stmt )
{ {
PDO_RESET_STMT_ERROR; PDO_RESET_STMT_ERROR;
PDO_VALIDATE_STMT; PDO_VALIDATE_STMT;
@ -540,7 +540,7 @@ int pdo_sqlsrv_stmt_execute( _Inout_ pdo_stmt_t *stmt TSRMLS_DC )
while( driver_stmt->past_next_result_end == false ) { while( driver_stmt->past_next_result_end == false ) {
core_sqlsrv_next_result( driver_stmt TSRMLS_CC, false ); core_sqlsrv_next_result( driver_stmt, false );
} }
} }
@ -572,7 +572,7 @@ int pdo_sqlsrv_stmt_execute( _Inout_ pdo_stmt_t *stmt TSRMLS_DC )
// PDOStatement::setAttribute() // PDOStatement::setAttribute()
driver_stmt->set_query_timeout(); driver_stmt->set_query_timeout();
SQLRETURN execReturn = core_sqlsrv_execute( driver_stmt TSRMLS_CC, query, query_len ); SQLRETURN execReturn = core_sqlsrv_execute( driver_stmt, query, query_len );
if ( execReturn == SQL_NO_DATA ) { if ( execReturn == SQL_NO_DATA ) {
stmt->column_count = 0; stmt->column_count = 0;
@ -582,7 +582,7 @@ int pdo_sqlsrv_stmt_execute( _Inout_ pdo_stmt_t *stmt TSRMLS_DC )
} }
else { else {
if (driver_stmt->column_count == ACTIVE_NUM_COLS_INVALID) { if (driver_stmt->column_count == ACTIVE_NUM_COLS_INVALID) {
stmt->column_count = core::SQLNumResultCols( driver_stmt TSRMLS_CC ); stmt->column_count = core::SQLNumResultCols( driver_stmt );
driver_stmt->column_count = stmt->column_count; driver_stmt->column_count = stmt->column_count;
} }
else { else {
@ -591,7 +591,7 @@ int pdo_sqlsrv_stmt_execute( _Inout_ pdo_stmt_t *stmt TSRMLS_DC )
if (driver_stmt->row_count == ACTIVE_NUM_ROWS_INVALID) { if (driver_stmt->row_count == ACTIVE_NUM_ROWS_INVALID) {
// return the row count regardless if there are any rows or not // return the row count regardless if there are any rows or not
stmt->row_count = core::SQLRowCount( driver_stmt TSRMLS_CC ); stmt->row_count = core::SQLRowCount( driver_stmt );
driver_stmt->row_count = stmt->row_count; driver_stmt->row_count = stmt->row_count;
} }
else { else {
@ -642,7 +642,7 @@ int pdo_sqlsrv_stmt_execute( _Inout_ pdo_stmt_t *stmt TSRMLS_DC )
// Return: // Return:
// 0 for failure, 1 for success. // 0 for failure, 1 for success.
int pdo_sqlsrv_stmt_fetch( _Inout_ pdo_stmt_t *stmt, _In_ enum pdo_fetch_orientation ori, int pdo_sqlsrv_stmt_fetch( _Inout_ pdo_stmt_t *stmt, _In_ enum pdo_fetch_orientation ori,
_In_ zend_long offset TSRMLS_DC) _In_ zend_long offset)
{ {
PDO_RESET_STMT_ERROR; PDO_RESET_STMT_ERROR;
PDO_VALIDATE_STMT; PDO_VALIDATE_STMT;
@ -688,7 +688,7 @@ int pdo_sqlsrv_stmt_fetch( _Inout_ pdo_stmt_t *stmt, _In_ enum pdo_fetch_orienta
} }
SQLSMALLINT odbc_fetch_ori = pdo_fetch_ori_to_odbc_fetch_ori( ori ); SQLSMALLINT odbc_fetch_ori = pdo_fetch_ori_to_odbc_fetch_ori( ori );
bool data = core_sqlsrv_fetch( driver_stmt, odbc_fetch_ori, offset TSRMLS_CC ); bool data = core_sqlsrv_fetch( driver_stmt, odbc_fetch_ori, offset );
// support for the PDO rowCount method. Since rowCount doesn't call a // support for the PDO rowCount method. Since rowCount doesn't call a
// method, PDO relies on us to fill the pdo_stmt_t::row_count member // method, PDO relies on us to fill the pdo_stmt_t::row_count member
@ -698,7 +698,7 @@ int pdo_sqlsrv_stmt_fetch( _Inout_ pdo_stmt_t *stmt, _In_ enum pdo_fetch_orienta
// which is unnecessary and a performance hit // which is unnecessary and a performance hit
if( driver_stmt->past_fetch_end || driver_stmt->cursor_type == SQL_CURSOR_DYNAMIC) { if( driver_stmt->past_fetch_end || driver_stmt->cursor_type == SQL_CURSOR_DYNAMIC) {
stmt->row_count = core::SQLRowCount( driver_stmt TSRMLS_CC ); stmt->row_count = core::SQLRowCount( driver_stmt );
driver_stmt->row_count = stmt->row_count; driver_stmt->row_count = stmt->row_count;
// a row_count of -1 means no rows, but we change it to 0 // a row_count of -1 means no rows, but we change it to 0
@ -741,7 +741,7 @@ int pdo_sqlsrv_stmt_fetch( _Inout_ pdo_stmt_t *stmt, _In_ enum pdo_fetch_orienta
// Return: // Return:
// 0 for failure, 1 for success. // 0 for failure, 1 for success.
int pdo_sqlsrv_stmt_get_col_data( _Inout_ pdo_stmt_t *stmt, _In_ int colno, int pdo_sqlsrv_stmt_get_col_data( _Inout_ pdo_stmt_t *stmt, _In_ int colno,
_Out_writes_bytes_opt_(*len) char **ptr, _Inout_ size_t *len, _Out_opt_ int *caller_frees TSRMLS_DC) _Out_writes_bytes_opt_(*len) char **ptr, _Inout_ size_t *len, _Out_opt_ int *caller_frees)
{ {
PDO_RESET_STMT_ERROR; PDO_RESET_STMT_ERROR;
PDO_VALIDATE_STMT; PDO_VALIDATE_STMT;
@ -781,7 +781,7 @@ int pdo_sqlsrv_stmt_get_col_data( _Inout_ pdo_stmt_t *stmt, _In_ int colno,
sqlsrv_php_type.typeinfo.type = pdo_type_to_sqlsrv_php_type( driver_stmt, sqlsrv_php_type.typeinfo.type = pdo_type_to_sqlsrv_php_type( driver_stmt,
driver_stmt->bound_column_param_types[colno] driver_stmt->bound_column_param_types[colno]
TSRMLS_CC ); );
pdo_bound_param_data* bind_data = NULL; pdo_bound_param_data* bind_data = NULL;
bind_data = reinterpret_cast<pdo_bound_param_data*>(zend_hash_index_find_ptr(stmt->bound_columns, colno)); bind_data = reinterpret_cast<pdo_bound_param_data*>(zend_hash_index_find_ptr(stmt->bound_columns, colno));
@ -823,7 +823,7 @@ int pdo_sqlsrv_stmt_get_col_data( _Inout_ pdo_stmt_t *stmt, _In_ int colno,
SQLSRV_PHPTYPE sqlsrv_phptype_out = SQLSRV_PHPTYPE_INVALID; SQLSRV_PHPTYPE sqlsrv_phptype_out = SQLSRV_PHPTYPE_INVALID;
core_sqlsrv_get_field( driver_stmt, colno, sqlsrv_php_type, false, *(reinterpret_cast<void**>(ptr)), core_sqlsrv_get_field( driver_stmt, colno, sqlsrv_php_type, false, *(reinterpret_cast<void**>(ptr)),
reinterpret_cast<SQLLEN*>( len ), true, &sqlsrv_phptype_out TSRMLS_CC ); reinterpret_cast<SQLLEN*>( len ), true, &sqlsrv_phptype_out );
if (ptr) { if (ptr) {
zval* zval_ptr = reinterpret_cast<zval*>(sqlsrv_malloc(sizeof(zval))); zval* zval_ptr = reinterpret_cast<zval*>(sqlsrv_malloc(sizeof(zval)));
@ -851,7 +851,7 @@ int pdo_sqlsrv_stmt_get_col_data( _Inout_ pdo_stmt_t *stmt, _In_ int colno,
// val - Attribute value. // val - Attribute value.
// Return: // Return:
// 0 for failure, 1 for success. // 0 for failure, 1 for success.
int pdo_sqlsrv_stmt_set_attr( _Inout_ pdo_stmt_t *stmt, _In_ zend_long attr, _Inout_ zval *val TSRMLS_DC) int pdo_sqlsrv_stmt_set_attr( _Inout_ pdo_stmt_t *stmt, _In_ zend_long attr, _Inout_ zval *val)
{ {
PDO_RESET_STMT_ERROR; PDO_RESET_STMT_ERROR;
PDO_VALIDATE_STMT; PDO_VALIDATE_STMT;
@ -869,7 +869,7 @@ int pdo_sqlsrv_stmt_set_attr( _Inout_ pdo_stmt_t *stmt, _In_ zend_long attr, _In
break; break;
case SQLSRV_ATTR_ENCODING: case SQLSRV_ATTR_ENCODING:
set_stmt_encoding( driver_stmt, val TSRMLS_CC ); set_stmt_encoding( driver_stmt, val );
break; break;
case PDO_ATTR_CURSOR: case PDO_ATTR_CURSOR:
@ -877,7 +877,7 @@ int pdo_sqlsrv_stmt_set_attr( _Inout_ pdo_stmt_t *stmt, _In_ zend_long attr, _In
break; break;
case SQLSRV_ATTR_QUERY_TIMEOUT: case SQLSRV_ATTR_QUERY_TIMEOUT:
core_sqlsrv_set_query_timeout( driver_stmt, val TSRMLS_CC ); core_sqlsrv_set_query_timeout( driver_stmt, val );
break; break;
case SQLSRV_ATTR_CURSOR_SCROLL_TYPE: case SQLSRV_ATTR_CURSOR_SCROLL_TYPE:
@ -885,7 +885,7 @@ int pdo_sqlsrv_stmt_set_attr( _Inout_ pdo_stmt_t *stmt, _In_ zend_long attr, _In
break; break;
case SQLSRV_ATTR_CLIENT_BUFFER_MAX_KB_SIZE: case SQLSRV_ATTR_CLIENT_BUFFER_MAX_KB_SIZE:
core_sqlsrv_set_buffered_query_limit( driver_stmt, val TSRMLS_CC ); core_sqlsrv_set_buffered_query_limit( driver_stmt, val );
break; break;
case SQLSRV_ATTR_FETCHES_NUMERIC_TYPE: case SQLSRV_ATTR_FETCHES_NUMERIC_TYPE:
@ -901,7 +901,7 @@ int pdo_sqlsrv_stmt_set_attr( _Inout_ pdo_stmt_t *stmt, _In_ zend_long attr, _In
break; break;
case SQLSRV_ATTR_DECIMAL_PLACES: case SQLSRV_ATTR_DECIMAL_PLACES:
core_sqlsrv_set_decimal_places(driver_stmt, val TSRMLS_CC); core_sqlsrv_set_decimal_places(driver_stmt, val);
break; break;
case SQLSRV_ATTR_DATA_CLASSIFICATION: case SQLSRV_ATTR_DATA_CLASSIFICATION:
@ -933,7 +933,7 @@ int pdo_sqlsrv_stmt_set_attr( _Inout_ pdo_stmt_t *stmt, _In_ zend_long attr, _In
// return_value - Attribute value. // return_value - Attribute value.
// Return: // Return:
// 0 for failure, 1 for success. // 0 for failure, 1 for success.
int pdo_sqlsrv_stmt_get_attr( _Inout_ pdo_stmt_t *stmt, _In_ zend_long attr, _Inout_ zval *return_value TSRMLS_DC ) int pdo_sqlsrv_stmt_get_attr( _Inout_ pdo_stmt_t *stmt, _In_ zend_long attr, _Inout_ zval *return_value )
{ {
PDO_RESET_STMT_ERROR; PDO_RESET_STMT_ERROR;
PDO_VALIDATE_STMT; PDO_VALIDATE_STMT;
@ -1041,7 +1041,7 @@ int pdo_sqlsrv_stmt_get_attr( _Inout_ pdo_stmt_t *stmt, _In_ zend_long attr, _In
// return_value - zval* consisting of the metadata. // return_value - zval* consisting of the metadata.
// Return: // Return:
// FAILURE for failure, SUCCESS for success. // FAILURE for failure, SUCCESS for success.
int pdo_sqlsrv_stmt_get_col_meta( _Inout_ pdo_stmt_t *stmt, _In_ zend_long colno, _Inout_ zval *return_value TSRMLS_DC) int pdo_sqlsrv_stmt_get_col_meta( _Inout_ pdo_stmt_t *stmt, _In_ zend_long colno, _Inout_ zval *return_value)
{ {
PDO_RESET_STMT_ERROR; PDO_RESET_STMT_ERROR;
PDO_VALIDATE_STMT; PDO_VALIDATE_STMT;
@ -1065,7 +1065,7 @@ int pdo_sqlsrv_stmt_get_col_meta( _Inout_ pdo_stmt_t *stmt, _In_ zend_long colno
} }
// initialize the array to nothing, as PDO requires us to create it // initialize the array to nothing, as PDO requires us to create it
core::sqlsrv_array_init( *driver_stmt, return_value TSRMLS_CC ); core::sqlsrv_array_init( *driver_stmt, return_value );
field_meta_data* core_meta_data; field_meta_data* core_meta_data;
@ -1080,7 +1080,7 @@ int pdo_sqlsrv_stmt_get_col_meta( _Inout_ pdo_stmt_t *stmt, _In_ zend_long colno
// initialize the column data classification array // initialize the column data classification array
zval data_classification; zval data_classification;
ZVAL_UNDEF(&data_classification); ZVAL_UNDEF(&data_classification);
core::sqlsrv_array_init(*driver_stmt, &data_classification TSRMLS_CC ); core::sqlsrv_array_init(*driver_stmt, &data_classification );
data_classification::fill_column_sensitivity_array(driver_stmt, (SQLSMALLINT)colno, &data_classification); data_classification::fill_column_sensitivity_array(driver_stmt, (SQLSMALLINT)colno, &data_classification);
@ -1095,7 +1095,7 @@ int pdo_sqlsrv_stmt_get_col_meta( _Inout_ pdo_stmt_t *stmt, _In_ zend_long colno
SQLSMALLINT out_buff_len; SQLSMALLINT out_buff_len;
SQLLEN not_used; SQLLEN not_used;
core::SQLColAttribute( driver_stmt, (SQLUSMALLINT) colno + 1, SQL_DESC_TYPE_NAME, field_type_name, core::SQLColAttribute( driver_stmt, (SQLUSMALLINT) colno + 1, SQL_DESC_TYPE_NAME, field_type_name,
sizeof( field_type_name ), &out_buff_len, &not_used TSRMLS_CC ); sizeof( field_type_name ), &out_buff_len, &not_used );
add_assoc_string( return_value, "sqlsrv:decl_type", field_type_name ); add_assoc_string( return_value, "sqlsrv:decl_type", field_type_name );
// get the PHP type of the column. The types returned here mirror the types returned by debug_zval_dump when // get the PHP type of the column. The types returned here mirror the types returned by debug_zval_dump when
@ -1120,7 +1120,7 @@ int pdo_sqlsrv_stmt_get_col_meta( _Inout_ pdo_stmt_t *stmt, _In_ zend_long colno
char table_name[SQL_SERVER_IDENT_SIZE_MAX] = {'\0'}; char table_name[SQL_SERVER_IDENT_SIZE_MAX] = {'\0'};
SQLLEN field_type_num; SQLLEN field_type_num;
core::SQLColAttribute( driver_stmt, (SQLUSMALLINT) colno + 1, SQL_DESC_TABLE_NAME, table_name, SQL_SERVER_IDENT_SIZE_MAX, core::SQLColAttribute( driver_stmt, (SQLUSMALLINT) colno + 1, SQL_DESC_TABLE_NAME, table_name, SQL_SERVER_IDENT_SIZE_MAX,
&out_buff_len, &field_type_num TSRMLS_CC ); &out_buff_len, &field_type_num );
add_assoc_string( return_value, "table", table_name ); add_assoc_string( return_value, "table", table_name );
if( stmt->columns && stmt->columns[colno].param_type == PDO_PARAM_ZVAL ) { if( stmt->columns && stmt->columns[colno].param_type == PDO_PARAM_ZVAL ) {
@ -1150,7 +1150,7 @@ int pdo_sqlsrv_stmt_get_col_meta( _Inout_ pdo_stmt_t *stmt, _In_ zend_long colno
// stmt - PDOStatement object containing the result set. // stmt - PDOStatement object containing the result set.
// Return: // Return:
// 0 for failure, 1 for success. // 0 for failure, 1 for success.
int pdo_sqlsrv_stmt_next_rowset( _Inout_ pdo_stmt_t *stmt TSRMLS_DC ) int pdo_sqlsrv_stmt_next_rowset( _Inout_ pdo_stmt_t *stmt )
{ {
PDO_RESET_STMT_ERROR; PDO_RESET_STMT_ERROR;
PDO_VALIDATE_STMT; PDO_VALIDATE_STMT;
@ -1164,7 +1164,7 @@ int pdo_sqlsrv_stmt_next_rowset( _Inout_ pdo_stmt_t *stmt TSRMLS_DC )
SQLSRV_ASSERT( driver_stmt != NULL, "pdo_sqlsrv_stmt_next_rowset: driver_data object was null" ); SQLSRV_ASSERT( driver_stmt != NULL, "pdo_sqlsrv_stmt_next_rowset: driver_data object was null" );
core_sqlsrv_next_result( static_cast<sqlsrv_stmt*>( stmt->driver_data ) TSRMLS_CC ); core_sqlsrv_next_result( static_cast<sqlsrv_stmt*>( stmt->driver_data ) );
// clear the current meta data since the new result will generate new meta data // clear the current meta data since the new result will generate new meta data
std::for_each( driver_stmt->current_meta_data.begin(), driver_stmt->current_meta_data.end(), meta_data_free ); std::for_each( driver_stmt->current_meta_data.begin(), driver_stmt->current_meta_data.end(), meta_data_free );
@ -1175,10 +1175,10 @@ int pdo_sqlsrv_stmt_next_rowset( _Inout_ pdo_stmt_t *stmt TSRMLS_DC )
return 0; return 0;
} }
stmt->column_count = core::SQLNumResultCols( driver_stmt TSRMLS_CC ); stmt->column_count = core::SQLNumResultCols( driver_stmt );
// return the row count regardless if there are any rows or not // return the row count regardless if there are any rows or not
stmt->row_count = core::SQLRowCount( driver_stmt TSRMLS_CC ); stmt->row_count = core::SQLRowCount( driver_stmt );
driver_stmt->column_count = stmt->column_count; driver_stmt->column_count = stmt->column_count;
driver_stmt->row_count = stmt->row_count; driver_stmt->row_count = stmt->row_count;
@ -1209,7 +1209,7 @@ int pdo_sqlsrv_stmt_next_rowset( _Inout_ pdo_stmt_t *stmt TSRMLS_DC )
// Return: // Return:
// Returns 0 for failure, 1 for success. // Returns 0 for failure, 1 for success.
int pdo_sqlsrv_stmt_param_hook( _Inout_ pdo_stmt_t *stmt, int pdo_sqlsrv_stmt_param_hook( _Inout_ pdo_stmt_t *stmt,
_Inout_ struct pdo_bound_param_data *param, _In_ enum pdo_param_event event_type TSRMLS_DC) _Inout_ struct pdo_bound_param_data *param, _In_ enum pdo_param_event event_type)
{ {
PDO_RESET_STMT_ERROR; PDO_RESET_STMT_ERROR;
@ -1255,7 +1255,7 @@ int pdo_sqlsrv_stmt_param_hook( _Inout_ pdo_stmt_t *stmt,
while( driver_stmt->past_next_result_end == false ) { while( driver_stmt->past_next_result_end == false ) {
core_sqlsrv_next_result( driver_stmt TSRMLS_CC, false ); core_sqlsrv_next_result( driver_stmt, false );
} }
} }
@ -1401,7 +1401,7 @@ int pdo_sqlsrv_stmt_param_hook( _Inout_ pdo_stmt_t *stmt,
// and bind the parameter // and bind the parameter
core_sqlsrv_bind_param( driver_stmt, static_cast<SQLUSMALLINT>( param->paramno ), direction, &(param->parameter) , php_out_type, encoding, core_sqlsrv_bind_param( driver_stmt, static_cast<SQLUSMALLINT>( param->paramno ), direction, &(param->parameter) , php_out_type, encoding,
sql_type, column_size, decimal_digits TSRMLS_CC ); sql_type, column_size, decimal_digits );
} }
break; break;
// undo any work done by the core layer after the statement is executed // undo any work done by the core layer after the statement is executed
@ -1416,7 +1416,7 @@ int pdo_sqlsrv_stmt_param_hook( _Inout_ pdo_stmt_t *stmt,
} }
core_sqlsrv_post_param( reinterpret_cast<sqlsrv_stmt*>( stmt->driver_data ), param->paramno, core_sqlsrv_post_param( reinterpret_cast<sqlsrv_stmt*>( stmt->driver_data ), param->paramno,
&(param->parameter) TSRMLS_CC ); &(param->parameter) );
} }
break; break;
case PDO_PARAM_EVT_FETCH_PRE: case PDO_PARAM_EVT_FETCH_PRE:
@ -1530,5 +1530,5 @@ void pdo_sqlsrv_stmt::set_query_timeout()
return; return;
} }
core::SQLSetStmtAttr(this, SQL_ATTR_QUERY_TIMEOUT, reinterpret_cast<SQLPOINTER>((SQLLEN)query_timeout), SQL_IS_UINTEGER TSRMLS_CC); core::SQLSetStmtAttr(this, SQL_ATTR_QUERY_TIMEOUT, reinterpret_cast<SQLPOINTER>((SQLLEN)query_timeout), SQL_IS_UINTEGER);
} }

View file

@ -43,7 +43,7 @@ const int WARNING_MIN_LENGTH = static_cast<const int>( strlen( WARNING_TEMPLATE
sqlsrv_error_const* get_error_message( _In_opt_ unsigned int sqlsrv_error_code); sqlsrv_error_const* get_error_message( _In_opt_ unsigned int sqlsrv_error_code);
// build the object and throw the PDO exception // build the object and throw the PDO exception
void pdo_sqlsrv_throw_exception( _In_ sqlsrv_error_const* error TSRMLS_DC ); void pdo_sqlsrv_throw_exception( _In_ sqlsrv_error_const* error );
} }
@ -463,7 +463,7 @@ pdo_error PDO_ERRORS[] = {
}; };
// PDO error handler for the environment context. // PDO error handler for the environment context.
bool pdo_sqlsrv_handle_env_error( _Inout_ sqlsrv_context& ctx, _In_opt_ unsigned int sqlsrv_error_code, _In_opt_ bool warning TSRMLS_DC, bool pdo_sqlsrv_handle_env_error( _Inout_ sqlsrv_context& ctx, _In_opt_ unsigned int sqlsrv_error_code, _In_opt_ bool warning,
_In_opt_ va_list* print_args ) _In_opt_ va_list* print_args )
{ {
SQLSRV_ASSERT(( ctx != NULL ), "pdo_sqlsrv_handle_env_error: sqlsrv_context was null" ); SQLSRV_ASSERT(( ctx != NULL ), "pdo_sqlsrv_handle_env_error: sqlsrv_context was null" );
@ -474,11 +474,11 @@ bool pdo_sqlsrv_handle_env_error( _Inout_ sqlsrv_context& ctx, _In_opt_ unsigned
if( sqlsrv_error_code != SQLSRV_ERROR_ODBC ) { if( sqlsrv_error_code != SQLSRV_ERROR_ODBC ) {
core_sqlsrv_format_driver_error( ctx, get_error_message( sqlsrv_error_code ), error, SEV_ERROR TSRMLS_CC, print_args ); core_sqlsrv_format_driver_error( ctx, get_error_message( sqlsrv_error_code ), error, SEV_ERROR, print_args );
} }
else { else {
bool err = core_sqlsrv_get_odbc_error( ctx, 1, error, SEV_ERROR TSRMLS_CC ); bool err = core_sqlsrv_get_odbc_error( ctx, 1, error, SEV_ERROR );
SQLSRV_ASSERT( err == true, "No ODBC error was found" ); SQLSRV_ASSERT( err == true, "No ODBC error was found" );
} }
@ -489,7 +489,7 @@ bool pdo_sqlsrv_handle_env_error( _Inout_ sqlsrv_context& ctx, _In_opt_ unsigned
case PDO_ERRMODE_EXCEPTION: case PDO_ERRMODE_EXCEPTION:
if( !warning ) { if( !warning ) {
pdo_sqlsrv_throw_exception( error TSRMLS_CC ); pdo_sqlsrv_throw_exception( error );
} }
ctx.set_last_error( error ); ctx.set_last_error( error );
break; break;
@ -506,7 +506,7 @@ bool pdo_sqlsrv_handle_env_error( _Inout_ sqlsrv_context& ctx, _In_opt_ unsigned
} }
// pdo error handler for the dbh context. // pdo error handler for the dbh context.
bool pdo_sqlsrv_handle_dbh_error( _Inout_ sqlsrv_context& ctx, _In_opt_ unsigned int sqlsrv_error_code, _In_opt_ bool warning TSRMLS_DC, bool pdo_sqlsrv_handle_dbh_error( _Inout_ sqlsrv_context& ctx, _In_opt_ unsigned int sqlsrv_error_code, _In_opt_ bool warning,
_In_opt_ va_list* print_args ) _In_opt_ va_list* print_args )
{ {
pdo_dbh_t* dbh = reinterpret_cast<pdo_dbh_t*>( ctx.driver()); pdo_dbh_t* dbh = reinterpret_cast<pdo_dbh_t*>( ctx.driver());
@ -516,10 +516,10 @@ bool pdo_sqlsrv_handle_dbh_error( _Inout_ sqlsrv_context& ctx, _In_opt_ unsigned
if( sqlsrv_error_code != SQLSRV_ERROR_ODBC ) { if( sqlsrv_error_code != SQLSRV_ERROR_ODBC ) {
core_sqlsrv_format_driver_error( ctx, get_error_message( sqlsrv_error_code ), error, SEV_ERROR TSRMLS_CC, print_args ); core_sqlsrv_format_driver_error( ctx, get_error_message( sqlsrv_error_code ), error, SEV_ERROR, print_args );
} }
else { else {
bool err = core_sqlsrv_get_odbc_error( ctx, 1, error, SEV_ERROR TSRMLS_CC ); bool err = core_sqlsrv_get_odbc_error( ctx, 1, error, SEV_ERROR );
SQLSRV_ASSERT( err == true, "No ODBC error was found" ); SQLSRV_ASSERT( err == true, "No ODBC error was found" );
} }
@ -530,7 +530,7 @@ bool pdo_sqlsrv_handle_dbh_error( _Inout_ sqlsrv_context& ctx, _In_opt_ unsigned
case PDO_ERRMODE_EXCEPTION: case PDO_ERRMODE_EXCEPTION:
if( !warning ) { if( !warning ) {
pdo_sqlsrv_throw_exception( error TSRMLS_CC ); pdo_sqlsrv_throw_exception( error );
} }
ctx.set_last_error( error ); ctx.set_last_error( error );
break; break;
@ -559,7 +559,7 @@ bool pdo_sqlsrv_handle_dbh_error( _Inout_ sqlsrv_context& ctx, _In_opt_ unsigned
} }
// PDO error handler for the statement context. // PDO error handler for the statement context.
bool pdo_sqlsrv_handle_stmt_error( _Inout_ sqlsrv_context& ctx, _In_opt_ unsigned int sqlsrv_error_code, _In_opt_ bool warning TSRMLS_DC, bool pdo_sqlsrv_handle_stmt_error( _Inout_ sqlsrv_context& ctx, _In_opt_ unsigned int sqlsrv_error_code, _In_opt_ bool warning,
_In_opt_ va_list* print_args ) _In_opt_ va_list* print_args )
{ {
pdo_stmt_t* pdo_stmt = reinterpret_cast<pdo_stmt_t*>( ctx.driver()); pdo_stmt_t* pdo_stmt = reinterpret_cast<pdo_stmt_t*>( ctx.driver());
@ -568,10 +568,10 @@ bool pdo_sqlsrv_handle_stmt_error( _Inout_ sqlsrv_context& ctx, _In_opt_ unsigne
sqlsrv_error_auto_ptr error; sqlsrv_error_auto_ptr error;
if( sqlsrv_error_code != SQLSRV_ERROR_ODBC ) { if( sqlsrv_error_code != SQLSRV_ERROR_ODBC ) {
core_sqlsrv_format_driver_error( ctx, get_error_message( sqlsrv_error_code ), error, SEV_ERROR TSRMLS_CC, print_args ); core_sqlsrv_format_driver_error( ctx, get_error_message( sqlsrv_error_code ), error, SEV_ERROR, print_args );
} }
else { else {
bool err = core_sqlsrv_get_odbc_error( ctx, 1, error, SEV_ERROR TSRMLS_CC ); bool err = core_sqlsrv_get_odbc_error( ctx, 1, error, SEV_ERROR );
SQLSRV_ASSERT( err == true, "No ODBC error was found" ); SQLSRV_ASSERT( err == true, "No ODBC error was found" );
} }
@ -582,7 +582,7 @@ bool pdo_sqlsrv_handle_stmt_error( _Inout_ sqlsrv_context& ctx, _In_opt_ unsigne
case PDO_ERRMODE_EXCEPTION: case PDO_ERRMODE_EXCEPTION:
if( !warning ) { if( !warning ) {
pdo_sqlsrv_throw_exception( error TSRMLS_CC ); pdo_sqlsrv_throw_exception( error );
} }
ctx.set_last_error( error ); ctx.set_last_error( error );
break; break;
@ -617,7 +617,7 @@ void pdo_sqlsrv_retrieve_context_error( _In_ sqlsrv_error const* last_error, _Ou
} }
// check the global variable of pdo_sqlsrv severity whether the message qualifies to be logged with the LOG macro // check the global variable of pdo_sqlsrv severity whether the message qualifies to be logged with the LOG macro
bool pdo_severity_check(_In_ unsigned int severity TSRMLS_DC) bool pdo_severity_check(_In_ unsigned int severity)
{ {
return ((severity & PDO_SQLSRV_G(pdo_log_severity))); return ((severity & PDO_SQLSRV_G(pdo_log_severity)));
} }
@ -639,7 +639,7 @@ sqlsrv_error_const* get_error_message( _In_opt_ unsigned int sqlsrv_error_code)
return error_message; return error_message;
} }
void pdo_sqlsrv_throw_exception( _In_ sqlsrv_error_const* error TSRMLS_DC ) void pdo_sqlsrv_throw_exception( _In_ sqlsrv_error_const* error )
{ {
zval ex_obj; zval ex_obj;
ZVAL_UNDEF( &ex_obj ); ZVAL_UNDEF( &ex_obj );
@ -655,9 +655,9 @@ void pdo_sqlsrv_throw_exception( _In_ sqlsrv_error_const* error TSRMLS_DC )
ex_msg = reinterpret_cast<char*>( sqlsrv_malloc( ex_msg_len )); ex_msg = reinterpret_cast<char*>( sqlsrv_malloc( ex_msg_len ));
snprintf( ex_msg, ex_msg_len, EXCEPTION_MSG_TEMPLATE, error->sqlstate, error->native_message ); snprintf( ex_msg, ex_msg_len, EXCEPTION_MSG_TEMPLATE, error->sqlstate, error->native_message );
zend_update_property_string( ex_class, &ex_obj, EXCEPTION_PROPERTY_MSG, sizeof( EXCEPTION_PROPERTY_MSG ) - 1, zend_update_property_string( ex_class, &ex_obj, EXCEPTION_PROPERTY_MSG, sizeof( EXCEPTION_PROPERTY_MSG ) - 1,
ex_msg TSRMLS_CC ); ex_msg );
zend_update_property_string( ex_class, &ex_obj, EXCEPTION_PROPERTY_CODE, sizeof( EXCEPTION_PROPERTY_CODE ) - 1, zend_update_property_string( ex_class, &ex_obj, EXCEPTION_PROPERTY_CODE, sizeof( EXCEPTION_PROPERTY_CODE ) - 1,
reinterpret_cast<char*>( error->sqlstate ) TSRMLS_CC ); reinterpret_cast<char*>( error->sqlstate ) );
zval ex_error_info; zval ex_error_info;
ZVAL_UNDEF( &ex_error_info ); ZVAL_UNDEF( &ex_error_info );
@ -668,13 +668,13 @@ void pdo_sqlsrv_throw_exception( _In_ sqlsrv_error_const* error TSRMLS_DC )
//zend_update_property makes an entry in the properties_table in ex_obj point to the Z_ARRVAL( ex_error_info ) //zend_update_property makes an entry in the properties_table in ex_obj point to the Z_ARRVAL( ex_error_info )
//and the refcount of the zend_array is incremented by 1 //and the refcount of the zend_array is incremented by 1
zend_update_property( ex_class, &ex_obj, EXCEPTION_PROPERTY_ERRORINFO, sizeof( EXCEPTION_PROPERTY_ERRORINFO ) - 1, zend_update_property( ex_class, &ex_obj, EXCEPTION_PROPERTY_ERRORINFO, sizeof( EXCEPTION_PROPERTY_ERRORINFO ) - 1,
&ex_error_info TSRMLS_CC ); &ex_error_info );
//DELREF ex_error_info here to decrement the refcount of the zend_array is 1 //DELREF ex_error_info here to decrement the refcount of the zend_array is 1
//the global hashtable EG(exception) then points to the zend_object in ex_obj in zend_throw_exception_object; //the global hashtable EG(exception) then points to the zend_object in ex_obj in zend_throw_exception_object;
//this ensure when EG(exception) cleans itself at php shutdown, the zend_array allocated is properly destroyed //this ensure when EG(exception) cleans itself at php shutdown, the zend_array allocated is properly destroyed
Z_DELREF( ex_error_info ); Z_DELREF( ex_error_info );
zend_throw_exception_object( &ex_obj TSRMLS_CC ); zend_throw_exception_object( &ex_obj );
} }
} }

View file

@ -120,7 +120,7 @@ class string_parser
inline bool is_eos(void); inline bool is_eos(void);
inline bool is_white_space( _In_ char c ); inline bool is_white_space( _In_ char c );
bool discard_white_spaces(void); bool discard_white_spaces(void);
void add_key_value_pair( _In_reads_(len) const char* value, _In_ int len TSRMLS_DC ); void add_key_value_pair( _In_reads_(len) const char* value, _In_ int len );
}; };
@ -145,14 +145,14 @@ class conn_string_parser : private string_parser
private: private:
const char* current_key_name; const char* current_key_name;
int discard_trailing_white_spaces( _In_reads_(len) const char* str, _Inout_ int len ); int discard_trailing_white_spaces( _In_reads_(len) const char* str, _Inout_ int len );
void validate_key( _In_reads_(key_len) const char *key, _Inout_ int key_len TSRMLS_DC); void validate_key( _In_reads_(key_len) const char *key, _Inout_ int key_len);
protected: protected:
void add_key_value_pair( _In_reads_(len) const char* value, _In_ int len TSRMLS_DC); void add_key_value_pair( _In_reads_(len) const char* value, _In_ int len);
public: public:
conn_string_parser( _In_ sqlsrv_context& ctx, _In_ const char* dsn, _In_ int len, _In_ HashTable* conn_options_ht ); conn_string_parser( _In_ sqlsrv_context& ctx, _In_ const char* dsn, _In_ int len, _In_ HashTable* conn_options_ht );
void parse_conn_string( TSRMLS_D ); void parse_conn_string( void );
}; };
@ -166,9 +166,9 @@ class sql_string_parser : private string_parser
private: private:
bool is_placeholder_char(char); bool is_placeholder_char(char);
public: public:
void add_key_int_value_pair( _In_ unsigned int value TSRMLS_DC ); void add_key_int_value_pair( _In_ unsigned int value );
sql_string_parser(_In_ sqlsrv_context& ctx, _In_ const char* sql_str, _In_ int len, _In_ HashTable* placeholder_ht); sql_string_parser(_In_ sqlsrv_context& ctx, _In_ const char* sql_str, _In_ int len, _In_ HashTable* placeholder_ht);
void parse_sql_string(TSRMLS_D); void parse_sql_string(void);
}; };
@ -178,7 +178,7 @@ class sql_string_parser : private string_parser
extern const connection_option PDO_CONN_OPTS[]; extern const connection_option PDO_CONN_OPTS[];
int pdo_sqlsrv_db_handle_factory( _Inout_ pdo_dbh_t *dbh, _In_opt_ zval *driver_options TSRMLS_DC); int pdo_sqlsrv_db_handle_factory( _Inout_ pdo_dbh_t *dbh, _In_opt_ zval *driver_options);
// a core layer pdo dbh object. This object inherits and overrides the statement factory // a core layer pdo dbh object. This object inherits and overrides the statement factory
struct pdo_sqlsrv_dbh : public sqlsrv_conn { struct pdo_sqlsrv_dbh : public sqlsrv_conn {
@ -193,7 +193,7 @@ struct pdo_sqlsrv_dbh : public sqlsrv_conn {
short decimal_places; short decimal_places;
short use_national_characters; short use_national_characters;
pdo_sqlsrv_dbh( _In_ SQLHANDLE h, _In_ error_callback e, _In_ void* driver TSRMLS_DC ); pdo_sqlsrv_dbh( _In_ SQLHANDLE h, _In_ error_callback e, _In_ void* driver );
}; };
@ -202,45 +202,39 @@ struct pdo_sqlsrv_dbh : public sqlsrv_conn {
//********************************************************************************************************************************* //*********************************************************************************************************************************
struct stmt_option_encoding : public stmt_option_functor { struct stmt_option_encoding : public stmt_option_functor {
virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z );
virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC );
}; };
struct stmt_option_pdo_scrollable : public stmt_option_functor { struct stmt_option_pdo_scrollable : public stmt_option_functor {
virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z );
virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC );
}; };
struct stmt_option_direct_query : public stmt_option_functor { struct stmt_option_direct_query : public stmt_option_functor {
virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z );
virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC );
}; };
struct stmt_option_cursor_scroll_type : public stmt_option_functor { struct stmt_option_cursor_scroll_type : public stmt_option_functor {
virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z );
virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC );
}; };
struct stmt_option_emulate_prepares : public stmt_option_functor { struct stmt_option_emulate_prepares : public stmt_option_functor {
virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z );
virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC );
}; };
struct stmt_option_fetch_numeric : public stmt_option_functor { struct stmt_option_fetch_numeric : public stmt_option_functor {
virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC ); virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z );
}; };
struct stmt_option_fetch_datetime : public stmt_option_functor { struct stmt_option_fetch_datetime : public stmt_option_functor {
virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC ); virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z );
}; };
extern struct pdo_stmt_methods pdo_sqlsrv_stmt_methods; extern struct pdo_stmt_methods pdo_sqlsrv_stmt_methods;
// a core layer pdo stmt object. This object inherits and overrides the callbacks necessary // a core layer pdo stmt object. This object inherits and overrides the callbacks necessary
struct pdo_sqlsrv_stmt : public sqlsrv_stmt { struct pdo_sqlsrv_stmt : public sqlsrv_stmt {
pdo_sqlsrv_stmt( _In_ sqlsrv_conn* c, _In_ SQLHANDLE handle, _In_ error_callback e, _In_ void* drv ) :
pdo_sqlsrv_stmt( _In_ sqlsrv_conn* c, _In_ SQLHANDLE handle, _In_ error_callback e, _In_ void* drv TSRMLS_DC ) : sqlsrv_stmt( c, handle, e, drv ),
sqlsrv_stmt( c, handle, e, drv TSRMLS_CC ),
direct_query( false ), direct_query( false ),
direct_query_subst_string( NULL ), direct_query_subst_string( NULL ),
direct_query_subst_string_len( 0 ), direct_query_subst_string_len( 0 ),
@ -292,18 +286,18 @@ struct pdo_error {
// called when an error occurs in the core layer. These routines are set as the error_callback in a // called when an error occurs in the core layer. These routines are set as the error_callback in a
// context. The context is passed to this function since it contains the function // context. The context is passed to this function since it contains the function
bool pdo_sqlsrv_handle_env_error( _Inout_ sqlsrv_context& ctx, _In_opt_ unsigned int sqlsrv_error_code, _In_opt_ bool warning TSRMLS_DC, bool pdo_sqlsrv_handle_env_error( _Inout_ sqlsrv_context& ctx, _In_opt_ unsigned int sqlsrv_error_code, _In_opt_ bool warning,
_In_opt_ va_list* print_args ); _In_opt_ va_list* print_args );
bool pdo_sqlsrv_handle_dbh_error( _Inout_ sqlsrv_context& ctx, _In_opt_ unsigned int sqlsrv_error_code, _In_opt_ bool warning TSRMLS_DC, bool pdo_sqlsrv_handle_dbh_error( _Inout_ sqlsrv_context& ctx, _In_opt_ unsigned int sqlsrv_error_code, _In_opt_ bool warning,
_In_opt_ va_list* print_args ); _In_opt_ va_list* print_args );
bool pdo_sqlsrv_handle_stmt_error( _Inout_ sqlsrv_context& ctx, _In_opt_ unsigned int sqlsrv_error_code, _In_opt_ bool warning TSRMLS_DC, bool pdo_sqlsrv_handle_stmt_error( _Inout_ sqlsrv_context& ctx, _In_opt_ unsigned int sqlsrv_error_code, _In_opt_ bool warning,
_In_opt_ va_list* print_args ); _In_opt_ va_list* print_args );
// common routine to transfer a sqlsrv_context's error to a PDO zval // common routine to transfer a sqlsrv_context's error to a PDO zval
void pdo_sqlsrv_retrieve_context_error( _In_ sqlsrv_error const* last_error, _Out_ zval* pdo_zval ); void pdo_sqlsrv_retrieve_context_error( _In_ sqlsrv_error const* last_error, _Out_ zval* pdo_zval );
// reset the errors from the last operation // reset the errors from the last operation
inline void pdo_reset_dbh_error( _Inout_ pdo_dbh_t* dbh TSRMLS_DC ) inline void pdo_reset_dbh_error( _Inout_ pdo_dbh_t* dbh )
{ {
strcpy_s( dbh->error_code, sizeof( dbh->error_code ), "00000" ); // 00000 means no error strcpy_s( dbh->error_code, sizeof( dbh->error_code ), "00000" ); // 00000 means no error
@ -330,7 +324,7 @@ inline void pdo_reset_dbh_error( _Inout_ pdo_dbh_t* dbh TSRMLS_DC )
core_sqlsrv_register_severity_checker(pdo_severity_check); \ core_sqlsrv_register_severity_checker(pdo_severity_check); \
LOG(SEV_NOTICE, message); LOG(SEV_NOTICE, message);
#define PDO_RESET_DBH_ERROR pdo_reset_dbh_error( dbh TSRMLS_CC ); #define PDO_RESET_DBH_ERROR pdo_reset_dbh_error( dbh );
inline void pdo_reset_stmt_error( _Inout_ pdo_stmt_t* stmt ) inline void pdo_reset_stmt_error( _Inout_ pdo_stmt_t* stmt )
{ {
@ -406,7 +400,7 @@ enum PDO_ERROR_CODES {
extern pdo_error PDO_ERRORS[]; extern pdo_error PDO_ERRORS[];
#define THROW_PDO_ERROR( ctx, custom, ... ) \ #define THROW_PDO_ERROR( ctx, custom, ... ) \
call_error_handler( ctx, custom TSRMLS_CC, false, ## __VA_ARGS__ ); \ call_error_handler( ctx, custom, false, ## __VA_ARGS__ ); \
throw pdo::PDOException(); throw pdo::PDOException();
namespace pdo { namespace pdo {
@ -422,7 +416,6 @@ namespace pdo {
} // namespace pdo } // namespace pdo
// check the global variable of pdo_sqlsrv severity whether the message qualifies to be logged with the LOG macro // check the global variable of pdo_sqlsrv severity whether the message qualifies to be logged with the LOG macro
bool pdo_severity_check(_In_ unsigned int severity TSRMLS_DC); bool pdo_severity_check(_In_ unsigned int severity);
#endif /* PHP_PDO_SQLSRV_INT_H */ #endif /* PHP_PDO_SQLSRV_INT_H */

View file

@ -68,13 +68,13 @@ const char CONNECTION_OPTION_MARS_ON[] = "MARS_Connection={Yes};";
void build_connection_string_and_set_conn_attr( _Inout_ sqlsrv_conn* conn, _Inout_z_ const char* server, _Inout_opt_z_ const char* uid, _Inout_opt_z_ const char* pwd, void build_connection_string_and_set_conn_attr( _Inout_ sqlsrv_conn* conn, _Inout_z_ const char* server, _Inout_opt_z_ const char* uid, _Inout_opt_z_ const char* pwd,
_Inout_opt_ HashTable* options_ht, _In_ const connection_option valid_conn_opts[], _Inout_opt_ HashTable* options_ht, _In_ const connection_option valid_conn_opts[],
void* driver,_Inout_ std::string& connection_string TSRMLS_DC ); void* driver,_Inout_ std::string& connection_string );
void determine_server_version( _Inout_ sqlsrv_conn* conn TSRMLS_DC ); void determine_server_version( _Inout_ sqlsrv_conn* conn );
const char* get_processor_arch( void ); const char* get_processor_arch( void );
void get_server_version( _Inout_ sqlsrv_conn* conn, _Outptr_result_buffer_(len) char** server_version, _Out_ SQLSMALLINT& len TSRMLS_DC ); void get_server_version( _Inout_ sqlsrv_conn* conn, _Outptr_result_buffer_(len) char** server_version, _Out_ SQLSMALLINT& len );
connection_option const* get_connection_option( sqlsrv_conn* conn, _In_ const char* key, _In_ SQLULEN key_len TSRMLS_DC ); connection_option const* get_connection_option( sqlsrv_conn* conn, _In_ const char* key, _In_ SQLULEN key_len );
void common_conn_str_append_func( _In_z_ const char* odbc_name, _In_reads_(val_len) const char* val, _Inout_ size_t val_len, _Inout_ std::string& conn_str TSRMLS_DC ); void common_conn_str_append_func( _In_z_ const char* odbc_name, _In_reads_(val_len) const char* val, _Inout_ size_t val_len, _Inout_ std::string& conn_str );
void load_azure_key_vault( _Inout_ sqlsrv_conn* conn TSRMLS_DC ); void load_azure_key_vault( _Inout_ sqlsrv_conn* conn );
void configure_azure_key_vault( sqlsrv_conn* conn, BYTE config_attr, const DWORD config_value, size_t key_size); void configure_azure_key_vault( sqlsrv_conn* conn, BYTE config_attr, const DWORD config_value, size_t key_size);
void configure_azure_key_vault( sqlsrv_conn* conn, BYTE config_attr, const char* config_value, size_t key_size); void configure_azure_key_vault( sqlsrv_conn* conn, BYTE config_attr, const char* config_value, size_t key_size);
} }
@ -97,7 +97,7 @@ void configure_azure_key_vault( sqlsrv_conn* conn, BYTE config_attr, const char*
sqlsrv_conn* core_sqlsrv_connect( _In_ sqlsrv_context& henv_cp, _In_ sqlsrv_context& henv_ncp, _In_ driver_conn_factory conn_factory, sqlsrv_conn* core_sqlsrv_connect( _In_ sqlsrv_context& henv_cp, _In_ sqlsrv_context& henv_ncp, _In_ driver_conn_factory conn_factory,
_Inout_z_ const char* server, _Inout_opt_z_ const char* uid, _Inout_opt_z_ const char* pwd, _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[], _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 ) _In_ void* driver, _In_z_ const char* driver_func )
{ {
SQLRETURN r; SQLRETURN r;
@ -149,11 +149,11 @@ sqlsrv_conn* core_sqlsrv_connect( _In_ sqlsrv_context& henv_cp, _In_ sqlsrv_cont
#endif // !_WIN32 #endif // !_WIN32
SQLHANDLE temp_conn_h; SQLHANDLE temp_conn_h;
core::SQLAllocHandle( SQL_HANDLE_DBC, *henv, &temp_conn_h TSRMLS_CC ); core::SQLAllocHandle( SQL_HANDLE_DBC, *henv, &temp_conn_h );
conn = conn_factory( temp_conn_h, err, driver TSRMLS_CC ); conn = conn_factory( temp_conn_h, err, driver );
conn->set_func( driver_func ); 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 );
// If column encryption is enabled, must use ODBC driver 17 // If column encryption is enabled, must use ODBC driver 17
if( conn->ce_option.enabled && conn->driver_version != ODBC_DRIVER_UNKNOWN) { if( conn->ce_option.enabled && conn->driver_version != ODBC_DRIVER_UNKNOWN) {
@ -271,7 +271,7 @@ sqlsrv_conn* core_sqlsrv_connect( _In_ sqlsrv_context& henv_cp, _In_ sqlsrv_cont
#ifndef _WIN32 #ifndef _WIN32
if ( r == SQL_SUCCESS_WITH_INFO ) { if ( r == SQL_SUCCESS_WITH_INFO ) {
#endif // !_WIN32 #endif // !_WIN32
determine_server_version( conn TSRMLS_CC ); determine_server_version( conn );
#ifndef _WIN32 #ifndef _WIN32
} }
#endif // !_WIN32 #endif // !_WIN32
@ -426,14 +426,14 @@ SQLRETURN core_odbc_connect( _Inout_ sqlsrv_conn* conn, _Inout_ std::string& con
// Parameters: // Parameters:
// sqlsrv_conn*: The connection with which the transaction is associated. // sqlsrv_conn*: The connection with which the transaction is associated.
void core_sqlsrv_begin_transaction( _Inout_ sqlsrv_conn* conn TSRMLS_DC ) void core_sqlsrv_begin_transaction( _Inout_ sqlsrv_conn* conn )
{ {
try { try {
DEBUG_SQLSRV_ASSERT( conn != NULL, "core_sqlsrv_begin_transaction: connection object was null." ); DEBUG_SQLSRV_ASSERT( conn != NULL, "core_sqlsrv_begin_transaction: connection object was null." );
core::SQLSetConnectAttr( conn, SQL_ATTR_AUTOCOMMIT, reinterpret_cast<SQLPOINTER>( SQL_AUTOCOMMIT_OFF ), core::SQLSetConnectAttr( conn, SQL_ATTR_AUTOCOMMIT, reinterpret_cast<SQLPOINTER>( SQL_AUTOCOMMIT_OFF ),
SQL_IS_UINTEGER TSRMLS_CC ); SQL_IS_UINTEGER );
} }
catch ( core::CoreException& ) { catch ( core::CoreException& ) {
throw; throw;
@ -449,16 +449,16 @@ void core_sqlsrv_begin_transaction( _Inout_ sqlsrv_conn* conn TSRMLS_DC )
// Parameters: // Parameters:
// sqlsrv_conn*: The connection on which the transaction is active. // sqlsrv_conn*: The connection on which the transaction is active.
void core_sqlsrv_commit( _Inout_ sqlsrv_conn* conn TSRMLS_DC ) void core_sqlsrv_commit( _Inout_ sqlsrv_conn* conn )
{ {
try { try {
DEBUG_SQLSRV_ASSERT( conn != NULL, "core_sqlsrv_commit: connection object was null." ); DEBUG_SQLSRV_ASSERT( conn != NULL, "core_sqlsrv_commit: connection object was null." );
core::SQLEndTran( SQL_HANDLE_DBC, conn, SQL_COMMIT TSRMLS_CC ); core::SQLEndTran( SQL_HANDLE_DBC, conn, SQL_COMMIT );
core::SQLSetConnectAttr( conn, SQL_ATTR_AUTOCOMMIT, reinterpret_cast<SQLPOINTER>( SQL_AUTOCOMMIT_ON ), core::SQLSetConnectAttr( conn, SQL_ATTR_AUTOCOMMIT, reinterpret_cast<SQLPOINTER>( SQL_AUTOCOMMIT_ON ),
SQL_IS_UINTEGER TSRMLS_CC ); SQL_IS_UINTEGER );
} }
catch ( core::CoreException& ) { catch ( core::CoreException& ) {
throw; throw;
@ -474,16 +474,16 @@ void core_sqlsrv_commit( _Inout_ sqlsrv_conn* conn TSRMLS_DC )
// Parameters: // Parameters:
// sqlsrv_conn*: The connection on which the transaction is active. // sqlsrv_conn*: The connection on which the transaction is active.
void core_sqlsrv_rollback( _Inout_ sqlsrv_conn* conn TSRMLS_DC ) void core_sqlsrv_rollback( _Inout_ sqlsrv_conn* conn )
{ {
try { try {
DEBUG_SQLSRV_ASSERT( conn != NULL, "core_sqlsrv_rollback: connection object was null." ); DEBUG_SQLSRV_ASSERT( conn != NULL, "core_sqlsrv_rollback: connection object was null." );
core::SQLEndTran( SQL_HANDLE_DBC, conn, SQL_ROLLBACK TSRMLS_CC ); core::SQLEndTran( SQL_HANDLE_DBC, conn, SQL_ROLLBACK );
core::SQLSetConnectAttr( conn, SQL_ATTR_AUTOCOMMIT, reinterpret_cast<SQLPOINTER>( SQL_AUTOCOMMIT_ON ), core::SQLSetConnectAttr( conn, SQL_ATTR_AUTOCOMMIT, reinterpret_cast<SQLPOINTER>( SQL_AUTOCOMMIT_ON ),
SQL_IS_UINTEGER TSRMLS_CC ); SQL_IS_UINTEGER );
} }
catch ( core::CoreException& ) { catch ( core::CoreException& ) {
@ -495,7 +495,7 @@ void core_sqlsrv_rollback( _Inout_ sqlsrv_conn* conn TSRMLS_DC )
// Called when a connection resource is destroyed by the Zend engine. // Called when a connection resource is destroyed by the Zend engine.
// Parameters: // Parameters:
// conn - The current active connection. // conn - The current active connection.
void core_sqlsrv_close( _Inout_opt_ sqlsrv_conn* conn TSRMLS_DC ) void core_sqlsrv_close( _Inout_opt_ sqlsrv_conn* conn )
{ {
// if the connection wasn't successful, just return. // if the connection wasn't successful, just return.
if( conn == NULL ) if( conn == NULL )
@ -504,7 +504,7 @@ void core_sqlsrv_close( _Inout_opt_ sqlsrv_conn* conn TSRMLS_DC )
try { try {
// rollback any transaction in progress (we don't care about the return result) // rollback any transaction in progress (we don't care about the return result)
core::SQLEndTran( SQL_HANDLE_DBC, conn, SQL_ROLLBACK TSRMLS_CC ); core::SQLEndTran( SQL_HANDLE_DBC, conn, SQL_ROLLBACK );
} }
catch( core::CoreException& ) { catch( core::CoreException& ) {
LOG( SEV_ERROR, "Transaction rollback failed when closing the connection." ); LOG( SEV_ERROR, "Transaction rollback failed when closing the connection." );
@ -529,7 +529,7 @@ void core_sqlsrv_close( _Inout_opt_ sqlsrv_conn* conn TSRMLS_DC )
// sql - T-SQL command to prepare // sql - T-SQL command to prepare
// sql_len - length of the T-SQL string // sql_len - length of the T-SQL string
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_prepare( _Inout_ sqlsrv_stmt* stmt, _In_reads_bytes_(sql_len) const char* sql, _In_ SQLLEN sql_len )
{ {
try { try {
@ -557,7 +557,7 @@ void core_sqlsrv_prepare( _Inout_ sqlsrv_stmt* stmt, _In_reads_bytes_(sql_len) c
} }
// prepare our wide char query string // prepare our wide char query string
core::SQLPrepareW( stmt, reinterpret_cast<SQLWCHAR*>( wsql_string.get() ), wsql_len TSRMLS_CC ); core::SQLPrepareW( stmt, reinterpret_cast<SQLWCHAR*>( wsql_string.get() ), wsql_len );
stmt->param_descriptions.clear(); stmt->param_descriptions.clear();
@ -587,14 +587,14 @@ void core_sqlsrv_prepare( _Inout_ sqlsrv_stmt* stmt, _In_reads_bytes_(sql_len) c
// conn - The connection resource by which the client and server are connected. // conn - The connection resource by which the client and server are connected.
// *server_version - zval for returning results. // *server_version - zval for returning results.
void core_sqlsrv_get_server_version( _Inout_ sqlsrv_conn* conn, _Inout_ zval* server_version TSRMLS_DC ) void core_sqlsrv_get_server_version( _Inout_ sqlsrv_conn* conn, _Inout_ zval* server_version )
{ {
try { try {
sqlsrv_malloc_auto_ptr<char> buffer; sqlsrv_malloc_auto_ptr<char> buffer;
SQLSMALLINT buffer_len = 0; SQLSMALLINT buffer_len = 0;
get_server_version( conn, &buffer, buffer_len TSRMLS_CC ); get_server_version( conn, &buffer, buffer_len );
core::sqlsrv_zval_stringl( server_version, buffer, buffer_len ); core::sqlsrv_zval_stringl( server_version, buffer, buffer_len );
if ( buffer != 0 ) { if ( buffer != 0 ) {
sqlsrv_free( buffer ); sqlsrv_free( buffer );
@ -614,7 +614,7 @@ void core_sqlsrv_get_server_version( _Inout_ sqlsrv_conn* conn, _Inout_ zval* se
// conn - The connection resource by which the client and server are connected. // conn - The connection resource by which the client and server are connected.
// *server_info - zval for returning results. // *server_info - zval for returning results.
void core_sqlsrv_get_server_info( _Inout_ sqlsrv_conn* conn, _Out_ zval *server_info TSRMLS_DC ) void core_sqlsrv_get_server_info( _Inout_ sqlsrv_conn* conn, _Out_ zval *server_info )
{ {
try { try {
@ -623,23 +623,23 @@ void core_sqlsrv_get_server_info( _Inout_ sqlsrv_conn* conn, _Out_ zval *server_
// Get the database name // Get the database name
buffer = static_cast<char*>( sqlsrv_malloc( INFO_BUFFER_LEN )); buffer = static_cast<char*>( sqlsrv_malloc( INFO_BUFFER_LEN ));
core::SQLGetInfo( conn, SQL_DATABASE_NAME, buffer, INFO_BUFFER_LEN, &buffer_len TSRMLS_CC ); core::SQLGetInfo( conn, SQL_DATABASE_NAME, buffer, INFO_BUFFER_LEN, &buffer_len );
// initialize the array // initialize the array
core::sqlsrv_array_init( *conn, server_info TSRMLS_CC ); core::sqlsrv_array_init( *conn, server_info );
core::sqlsrv_add_assoc_string( *conn, server_info, "CurrentDatabase", buffer, 0 /*duplicate*/ TSRMLS_CC ); core::sqlsrv_add_assoc_string( *conn, server_info, "CurrentDatabase", buffer, 0 /*duplicate*/ );
buffer.transferred(); buffer.transferred();
// Get the server version // Get the server version
get_server_version( conn, &buffer, buffer_len TSRMLS_CC ); get_server_version( conn, &buffer, buffer_len );
core::sqlsrv_add_assoc_string( *conn, server_info, "SQLServerVersion", buffer, 0 /*duplicate*/ TSRMLS_CC ); core::sqlsrv_add_assoc_string( *conn, server_info, "SQLServerVersion", buffer, 0 /*duplicate*/ );
buffer.transferred(); buffer.transferred();
// Get the server name // Get the server name
buffer = static_cast<char*>( sqlsrv_malloc( INFO_BUFFER_LEN )); buffer = static_cast<char*>( sqlsrv_malloc( INFO_BUFFER_LEN ));
core::SQLGetInfo( conn, SQL_SERVER_NAME, buffer, INFO_BUFFER_LEN, &buffer_len TSRMLS_CC ); core::SQLGetInfo( conn, SQL_SERVER_NAME, buffer, INFO_BUFFER_LEN, &buffer_len );
core::sqlsrv_add_assoc_string( *conn, server_info, "SQLServerName", buffer, 0 /*duplicate*/ TSRMLS_CC ); core::sqlsrv_add_assoc_string( *conn, server_info, "SQLServerName", buffer, 0 /*duplicate*/ );
buffer.transferred(); buffer.transferred();
} }
@ -654,7 +654,7 @@ void core_sqlsrv_get_server_info( _Inout_ sqlsrv_conn* conn, _Out_ zval *server_
// conn - The connection resource by which the client and server are connected. // conn - The connection resource by which the client and server are connected.
// *client_info - zval for returning the results. // *client_info - zval for returning the results.
void core_sqlsrv_get_client_info( _Inout_ sqlsrv_conn* conn, _Out_ zval *client_info TSRMLS_DC ) void core_sqlsrv_get_client_info( _Inout_ sqlsrv_conn* conn, _Out_ zval *client_info )
{ {
try { try {
@ -663,28 +663,28 @@ void core_sqlsrv_get_client_info( _Inout_ sqlsrv_conn* conn, _Out_ zval *client_
// 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 );
// initialize the array // initialize the array
core::sqlsrv_array_init( *conn, client_info TSRMLS_CC ); core::sqlsrv_array_init( *conn, client_info );
#ifndef _WIN32 #ifndef _WIN32
core::sqlsrv_add_assoc_string( *conn, client_info, "DriverName", buffer, 0 /*duplicate*/ TSRMLS_CC ); core::sqlsrv_add_assoc_string( *conn, client_info, "DriverName", buffer, 0 /*duplicate*/ );
#else #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*/ );
#endif // !_WIN32 #endif // !_WIN32
buffer.transferred(); buffer.transferred();
// Get the ODBC driver's ODBC version // Get the ODBC driver's ODBC version
buffer = static_cast<char*>( sqlsrv_malloc( INFO_BUFFER_LEN )); buffer = static_cast<char*>( sqlsrv_malloc( INFO_BUFFER_LEN ));
core::SQLGetInfo( conn, SQL_DRIVER_ODBC_VER, buffer, INFO_BUFFER_LEN, &buffer_len TSRMLS_CC ); core::SQLGetInfo( conn, SQL_DRIVER_ODBC_VER, buffer, INFO_BUFFER_LEN, &buffer_len );
core::sqlsrv_add_assoc_string( *conn, client_info, "DriverODBCVer", buffer, 0 /*duplicate*/ TSRMLS_CC ); core::sqlsrv_add_assoc_string( *conn, client_info, "DriverODBCVer", buffer, 0 /*duplicate*/ );
buffer.transferred(); buffer.transferred();
// Get the OBDC driver's version // Get the OBDC driver's version
buffer = static_cast<char*>( sqlsrv_malloc( INFO_BUFFER_LEN )); buffer = static_cast<char*>( sqlsrv_malloc( INFO_BUFFER_LEN ));
core::SQLGetInfo( conn, SQL_DRIVER_VER, buffer, INFO_BUFFER_LEN, &buffer_len TSRMLS_CC ); core::SQLGetInfo( conn, SQL_DRIVER_VER, buffer, INFO_BUFFER_LEN, &buffer_len );
core::sqlsrv_add_assoc_string( *conn, client_info, "DriverVer", buffer, 0 /*duplicate*/ TSRMLS_CC ); core::sqlsrv_add_assoc_string( *conn, client_info, "DriverVer", buffer, 0 /*duplicate*/ );
buffer.transferred(); buffer.transferred();
} }
@ -753,7 +753,7 @@ bool core_is_authentication_option_valid( _In_z_ const char* value, _In_ size_t
namespace { namespace {
connection_option const* get_connection_option( sqlsrv_conn* conn, _In_ SQLULEN key, connection_option const* get_connection_option( sqlsrv_conn* conn, _In_ SQLULEN key,
_In_ const connection_option conn_opts[] TSRMLS_DC ) _In_ const connection_option conn_opts[] )
{ {
for( int opt_idx = 0; conn_opts[opt_idx].conn_option_key != SQLSRV_CONN_OPTION_INVALID; ++opt_idx ) { for( int opt_idx = 0; conn_opts[opt_idx].conn_option_key != SQLSRV_CONN_OPTION_INVALID; ++opt_idx ) {
@ -774,7 +774,7 @@ connection_option const* get_connection_option( sqlsrv_conn* conn, _In_ SQLULEN
void build_connection_string_and_set_conn_attr( _Inout_ sqlsrv_conn* conn, _Inout_z_ const char* server, _Inout_opt_z_ const char* uid, _Inout_opt_z_ const char* pwd, void build_connection_string_and_set_conn_attr( _Inout_ sqlsrv_conn* conn, _Inout_z_ const char* server, _Inout_opt_z_ const char* uid, _Inout_opt_z_ const char* pwd,
_Inout_opt_ HashTable* options, _In_ const connection_option valid_conn_opts[], _Inout_opt_ HashTable* options, _In_ const connection_option valid_conn_opts[],
void* driver, _Inout_ std::string& connection_string TSRMLS_DC ) void* driver, _Inout_ std::string& connection_string )
{ {
bool mars_mentioned = false; bool mars_mentioned = false;
connection_option const* conn_opt; connection_option const* conn_opt;
@ -834,7 +834,7 @@ void build_connection_string_and_set_conn_attr( _Inout_ sqlsrv_conn* conn, _Inou
} }
// Add the server name // Add the server name
common_conn_str_append_func( ODBCConnOptions::SERVER, server, strnlen_s( server ), connection_string TSRMLS_CC ); common_conn_str_append_func( ODBCConnOptions::SERVER, server, strnlen_s( server ), connection_string );
// If uid is not present then we use trusted connection -- but not when access token or ActiveDirectoryMSI is used, // If uid is not present then we use trusted connection -- but not when access token or ActiveDirectoryMSI is used,
// because they are incompatible // because they are incompatible
@ -848,7 +848,7 @@ void build_connection_string_and_set_conn_attr( _Inout_ sqlsrv_conn* conn, _Inou
throw core::CoreException(); throw core::CoreException();
} }
common_conn_str_append_func(ODBCConnOptions::UID, uid, strnlen_s(uid), connection_string TSRMLS_CC); common_conn_str_append_func(ODBCConnOptions::UID, uid, strnlen_s(uid), connection_string);
// if no password was given, then don't add a password to the connection string. Perhaps the UID // if no password was given, then don't add a password to the connection string. Perhaps the UID
// given doesn't have a password? // given doesn't have a password?
@ -858,7 +858,7 @@ void build_connection_string_and_set_conn_attr( _Inout_ sqlsrv_conn* conn, _Inou
throw core::CoreException(); throw core::CoreException();
} }
common_conn_str_append_func(ODBCConnOptions::PWD, pwd, strnlen_s(pwd), connection_string TSRMLS_CC); common_conn_str_append_func(ODBCConnOptions::PWD, pwd, strnlen_s(pwd), connection_string);
} }
} }
} }
@ -894,13 +894,13 @@ void build_connection_string_and_set_conn_attr( _Inout_ sqlsrv_conn* conn, _Inou
// The driver layer should ensure a valid key. // The driver layer should ensure a valid key.
DEBUG_SQLSRV_ASSERT(( type == HASH_KEY_IS_LONG ), "build_connection_string_and_set_conn_attr: invalid connection option key type." ); DEBUG_SQLSRV_ASSERT(( type == HASH_KEY_IS_LONG ), "build_connection_string_and_set_conn_attr: invalid connection option key type." );
conn_opt = get_connection_option( conn, index, valid_conn_opts TSRMLS_CC ); conn_opt = get_connection_option( conn, index, valid_conn_opts );
if( index == SQLSRV_CONN_OPTION_MARS ) { if( index == SQLSRV_CONN_OPTION_MARS ) {
mars_mentioned = true; mars_mentioned = true;
} }
conn_opt->func( conn_opt, data, conn, connection_string TSRMLS_CC ); conn_opt->func( conn_opt, data, conn, connection_string );
} ZEND_HASH_FOREACH_END(); } ZEND_HASH_FOREACH_END();
// MARS on if not explicitly turned off // MARS on if not explicitly turned off
@ -919,7 +919,7 @@ void build_connection_string_and_set_conn_attr( _Inout_ sqlsrv_conn* conn, _Inou
// get_server_version // get_server_version
// Helper function which returns the version of the SQL Server we are connected to. // Helper function which returns the version of the SQL Server we are connected to.
void get_server_version( _Inout_ sqlsrv_conn* conn, _Outptr_result_buffer_(len) char** server_version, _Out_ SQLSMALLINT& len TSRMLS_DC ) void get_server_version( _Inout_ sqlsrv_conn* conn, _Outptr_result_buffer_(len) char** server_version, _Out_ SQLSMALLINT& len )
{ {
try { try {
@ -927,7 +927,7 @@ void get_server_version( _Inout_ sqlsrv_conn* conn, _Outptr_result_buffer_(len)
SQLSMALLINT buffer_len = 0; SQLSMALLINT buffer_len = 0;
buffer = static_cast<char*>( sqlsrv_malloc( INFO_BUFFER_LEN )); buffer = static_cast<char*>( sqlsrv_malloc( INFO_BUFFER_LEN ));
core::SQLGetInfo( conn, SQL_DBMS_VER, buffer, INFO_BUFFER_LEN, &buffer_len TSRMLS_CC ); core::SQLGetInfo( conn, SQL_DBMS_VER, buffer, INFO_BUFFER_LEN, &buffer_len );
*server_version = buffer; *server_version = buffer;
len = buffer_len; len = buffer_len;
buffer.transferred(); buffer.transferred();
@ -989,11 +989,11 @@ const char* get_processor_arch( void )
// Exception is thrown when the server version is either undetermined // Exception is thrown when the server version is either undetermined
// or is invalid (< 2000). // or is invalid (< 2000).
void determine_server_version( _Inout_ sqlsrv_conn* conn TSRMLS_DC ) void determine_server_version( _Inout_ sqlsrv_conn* conn )
{ {
SQLSMALLINT info_len; SQLSMALLINT info_len;
char p[INFO_BUFFER_LEN] = {'\0'}; char p[INFO_BUFFER_LEN] = {'\0'};
core::SQLGetInfo( conn, SQL_DBMS_VER, p, INFO_BUFFER_LEN, &info_len TSRMLS_CC ); core::SQLGetInfo( conn, SQL_DBMS_VER, p, INFO_BUFFER_LEN, &info_len );
errno = 0; errno = 0;
char version_major_str[3] = {'\0'}; char version_major_str[3] = {'\0'};
@ -1013,7 +1013,7 @@ void determine_server_version( _Inout_ sqlsrv_conn* conn TSRMLS_DC )
conn->server_version = version_major; conn->server_version = version_major;
} }
void load_azure_key_vault(_Inout_ sqlsrv_conn* conn TSRMLS_DC) void load_azure_key_vault(_Inout_ sqlsrv_conn* conn)
{ {
// If column encryption is not enabled simply do nothing. Otherwise, check if Azure Key Vault // If column encryption is not enabled simply do nothing. Otherwise, check if Azure Key Vault
// is required for encryption or decryption. Note, in order to load and configure Azure Key Vault, // is required for encryption or decryption. Note, in order to load and configure Azure Key Vault,
@ -1092,11 +1092,10 @@ void configure_azure_key_vault(sqlsrv_conn* conn, BYTE config_attr, const char*
core::SQLSetConnectAttr(conn, SQL_COPT_SS_CEKEYSTOREDATA, reinterpret_cast<SQLPOINTER>(pData), SQL_IS_POINTER); core::SQLSetConnectAttr(conn, SQL_COPT_SS_CEKEYSTOREDATA, reinterpret_cast<SQLPOINTER>(pData), SQL_IS_POINTER);
} }
void common_conn_str_append_func( _In_z_ const char* odbc_name, _In_reads_(val_len) const char* val, _Inout_ size_t val_len, _Inout_ std::string& conn_str TSRMLS_DC ) void common_conn_str_append_func( _In_z_ const char* odbc_name, _In_reads_(val_len) const char* val, _Inout_ size_t val_len, _Inout_ std::string& conn_str )
{ {
// wrap a connection option in a quote. It is presumed that any character that need to be escaped will // wrap a connection option in a quote. It is presumed that any character that need to be escaped will
// be escaped, such as a closing }. // be escaped, such as a closing }.
TSRMLS_C;
if( val_len > 0 && val[0] == '{' && val[val_len - 1] == '}' ) { if( val_len > 0 && val[0] == '{' && val[val_len - 1] == '}' ) {
++val; ++val;
@ -1111,26 +1110,25 @@ void common_conn_str_append_func( _In_z_ const char* odbc_name, _In_reads_(val_l
} // namespace } // namespace
// simply add the parsed value to the connection string // simply add the parsed value to the connection string
void conn_str_append_func::func( _In_ connection_option const* option, _In_ zval* value, sqlsrv_conn* /*conn*/, _Inout_ std::string& conn_str TSRMLS_DC ) void conn_str_append_func::func( _In_ connection_option const* option, _In_ zval* value, sqlsrv_conn* /*conn*/, _Inout_ std::string& conn_str )
{ {
const char* val_str = Z_STRVAL_P( value ); const char* val_str = Z_STRVAL_P( value );
size_t val_len = Z_STRLEN_P( value ); size_t val_len = Z_STRLEN_P( value );
common_conn_str_append_func( option->odbc_name, val_str, val_len, conn_str TSRMLS_CC ); common_conn_str_append_func( option->odbc_name, val_str, val_len, conn_str );
} }
// do nothing for connection pooling since we handled it earlier when // do nothing for connection pooling since we handled it earlier when
// deciding which environment handle to use. // deciding which environment handle to use.
void conn_null_func::func( connection_option const* /*option*/, zval* /*value*/, sqlsrv_conn* /*conn*/, std::string& /*conn_str*/ TSRMLS_DC ) void conn_null_func::func( connection_option const* /*option*/, zval* /*value*/, sqlsrv_conn* /*conn*/, std::string& /*conn_str*/ )
{ {
TSRMLS_C;
} }
void driver_set_func::func( _In_ connection_option const* option, _In_ zval* value, _Inout_ sqlsrv_conn* conn, _Inout_ std::string& conn_str TSRMLS_DC ) void driver_set_func::func( _In_ connection_option const* option, _In_ zval* value, _Inout_ sqlsrv_conn* conn, _Inout_ std::string& conn_str )
{ {
const char* val_str = Z_STRVAL_P( value ); const char* val_str = Z_STRVAL_P( value );
size_t val_len = Z_STRLEN_P( value ); size_t val_len = Z_STRLEN_P( value );
std::string driver_option( "" ); std::string driver_option( "" );
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 );
conn->driver_version = ODBC_DRIVER_UNKNOWN; conn->driver_version = ODBC_DRIVER_UNKNOWN;
for ( short i = DRIVER_VERSION::FIRST; i <= DRIVER_VERSION::LAST && conn->driver_version == ODBC_DRIVER_UNKNOWN; ++i ) { for ( short i = DRIVER_VERSION::FIRST; i <= DRIVER_VERSION::LAST && conn->driver_version == ODBC_DRIVER_UNKNOWN; ++i ) {
@ -1148,7 +1146,7 @@ void driver_set_func::func( _In_ connection_option const* option, _In_ zval* val
conn_str += driver_option; conn_str += driver_option;
} }
void column_encryption_set_func::func( _In_ connection_option const* option, _In_ zval* value, _Inout_ sqlsrv_conn* conn, _Inout_ std::string& conn_str TSRMLS_DC ) void column_encryption_set_func::func( _In_ connection_option const* option, _In_ zval* value, _Inout_ sqlsrv_conn* conn, _Inout_ std::string& conn_str )
{ {
convert_to_string( value ); convert_to_string( value );
const char* value_str = Z_STRVAL_P( value ); const char* value_str = Z_STRVAL_P( value );
@ -1168,7 +1166,7 @@ void column_encryption_set_func::func( _In_ connection_option const* option, _In
conn_str += ";"; conn_str += ";";
} }
void ce_akv_str_set_func::func(_In_ connection_option const* option, _In_ zval* value, _Inout_ sqlsrv_conn* conn, _Inout_ std::string& conn_str TSRMLS_DC) void ce_akv_str_set_func::func(_In_ connection_option const* option, _In_ zval* value, _Inout_ sqlsrv_conn* conn, _Inout_ std::string& conn_str)
{ {
SQLSRV_ASSERT(Z_TYPE_P(value) == IS_STRING, "Azure Key Vault keywords accept only strings."); SQLSRV_ASSERT(Z_TYPE_P(value) == IS_STRING, "Azure Key Vault keywords accept only strings.");
@ -1254,7 +1252,7 @@ size_t core_str_zval_is_true( _Inout_ zval* value_z )
return 0; // false return 0; // false
} }
void access_token_set_func::func( _In_ connection_option const* option, _In_ zval* value, _Inout_ sqlsrv_conn* conn, _Inout_ std::string& conn_str TSRMLS_DC ) void access_token_set_func::func( _In_ connection_option const* option, _In_ zval* value, _Inout_ sqlsrv_conn* conn, _Inout_ std::string& conn_str )
{ {
SQLSRV_ASSERT(Z_TYPE_P(value) == IS_STRING, "An access token must be a byte string."); SQLSRV_ASSERT(Z_TYPE_P(value) == IS_STRING, "An access token must be a byte string.");

View file

@ -34,7 +34,7 @@ bool isVistaOrGreater;
// henv_cp - Environment handle for pooled connection. // henv_cp - Environment handle for pooled connection.
// henv_ncp - Environment handle for non-pooled connection. // henv_ncp - Environment handle for non-pooled connection.
// err - Driver specific error handler which handles any errors during initialization. // err - Driver specific error handler which handles any errors during initialization.
void core_sqlsrv_minit( _Outptr_ sqlsrv_context** henv_cp, _Inout_ sqlsrv_context** henv_ncp, _In_ error_callback err, _In_z_ const char* driver_func TSRMLS_DC ) void core_sqlsrv_minit( _Outptr_ sqlsrv_context** henv_cp, _Inout_ sqlsrv_context** henv_ncp, _In_ error_callback err, _In_z_ const char* driver_func )
{ {
SQLSRV_STATIC_ASSERT( sizeof( sqlsrv_sqltype ) == sizeof( zend_long ) ); SQLSRV_STATIC_ASSERT( sizeof( sqlsrv_sqltype ) == sizeof( zend_long ) );
SQLSRV_STATIC_ASSERT( sizeof( sqlsrv_phptype ) == sizeof( zend_long )); SQLSRV_STATIC_ASSERT( sizeof( sqlsrv_phptype ) == sizeof( zend_long ));
@ -65,11 +65,11 @@ void core_sqlsrv_minit( _Outptr_ sqlsrv_context** henv_cp, _Inout_ sqlsrv_contex
// set to ODBC 3 // set to ODBC 3
core::SQLSetEnvAttr( **henv_ncp, SQL_ATTR_ODBC_VERSION, reinterpret_cast<SQLPOINTER>( SQL_OV_ODBC3 ), SQL_IS_INTEGER core::SQLSetEnvAttr( **henv_ncp, SQL_ATTR_ODBC_VERSION, reinterpret_cast<SQLPOINTER>( SQL_OV_ODBC3 ), SQL_IS_INTEGER
TSRMLS_CC ); );
// disable connection pooling // disable connection pooling
core::SQLSetEnvAttr( **henv_ncp, SQL_ATTR_CONNECTION_POOLING, reinterpret_cast<SQLPOINTER>( SQL_CP_OFF ), core::SQLSetEnvAttr( **henv_ncp, SQL_ATTR_CONNECTION_POOLING, reinterpret_cast<SQLPOINTER>( SQL_CP_OFF ),
SQL_IS_UINTEGER TSRMLS_CC ); SQL_IS_UINTEGER );
// allocate the pooled envrionment handle // allocate the pooled envrionment handle
// we can't use the wrapper in core_sqlsrv.h since we don't have a context on which to base errors, so // we can't use the wrapper in core_sqlsrv.h since we don't have a context on which to base errors, so
@ -83,11 +83,11 @@ void core_sqlsrv_minit( _Outptr_ sqlsrv_context** henv_cp, _Inout_ sqlsrv_contex
(*henv_cp)->set_func( driver_func ); (*henv_cp)->set_func( driver_func );
// set to ODBC 3 // set to ODBC 3
core::SQLSetEnvAttr( **henv_cp, SQL_ATTR_ODBC_VERSION, reinterpret_cast<SQLPOINTER>( SQL_OV_ODBC3 ), SQL_IS_INTEGER TSRMLS_CC); core::SQLSetEnvAttr( **henv_cp, SQL_ATTR_ODBC_VERSION, reinterpret_cast<SQLPOINTER>( SQL_OV_ODBC3 ), SQL_IS_INTEGER);
// enable connection pooling // enable connection pooling
core:: SQLSetEnvAttr( **henv_cp, SQL_ATTR_CONNECTION_POOLING, reinterpret_cast<SQLPOINTER>( SQL_CP_ONE_PER_HENV ), core:: SQLSetEnvAttr( **henv_cp, SQL_ATTR_CONNECTION_POOLING, reinterpret_cast<SQLPOINTER>( SQL_CP_ONE_PER_HENV ),
SQL_IS_UINTEGER TSRMLS_CC ); SQL_IS_UINTEGER );
} }
catch( core::CoreException& e ) { catch( core::CoreException& e ) {

View file

@ -78,7 +78,7 @@ bool get_bit( _In_ void* ptr, _In_ unsigned int bit )
// read in LOB field during buffered result creation // read in LOB field during buffered result creation
SQLPOINTER read_lob_field( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _In_ sqlsrv_buffered_result_set::meta_data& meta, SQLPOINTER read_lob_field( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _In_ sqlsrv_buffered_result_set::meta_data& meta,
_In_ zend_long mem_used TSRMLS_DC ); _In_ zend_long mem_used );
// dtor for each row in the cache // dtor for each row in the cache
void cache_row_dtor( _In_ zval* data ); void cache_row_dtor( _In_ zval* data );
@ -391,27 +391,27 @@ sqlsrv_odbc_result_set::~sqlsrv_odbc_result_set( void )
{ {
} }
SQLRETURN sqlsrv_odbc_result_set::fetch( _In_ SQLSMALLINT orientation, _In_ SQLLEN offset TSRMLS_DC ) SQLRETURN sqlsrv_odbc_result_set::fetch( _In_ SQLSMALLINT orientation, _In_ SQLLEN offset )
{ {
SQLSRV_ASSERT( odbc != NULL, "Invalid statement handle" ); SQLSRV_ASSERT( odbc != NULL, "Invalid statement handle" );
return core::SQLFetchScroll( odbc, orientation, offset TSRMLS_CC ); return core::SQLFetchScroll( odbc, orientation, offset );
} }
SQLRETURN sqlsrv_odbc_result_set::get_data( _In_ SQLUSMALLINT field_index, _In_ SQLSMALLINT target_type, SQLRETURN sqlsrv_odbc_result_set::get_data( _In_ SQLUSMALLINT field_index, _In_ SQLSMALLINT target_type,
_Out_writes_opt_(buffer_length) SQLPOINTER buffer, _In_ SQLLEN buffer_length, _Inout_ SQLLEN* out_buffer_length, _Out_writes_opt_(buffer_length) SQLPOINTER buffer, _In_ SQLLEN buffer_length, _Inout_ SQLLEN* out_buffer_length,
_In_ bool handle_warning TSRMLS_DC ) _In_ bool handle_warning )
{ {
SQLSRV_ASSERT( odbc != NULL, "Invalid statement handle" ); SQLSRV_ASSERT( odbc != NULL, "Invalid statement handle" );
return core::SQLGetData( odbc, field_index, target_type, buffer, buffer_length, out_buffer_length, handle_warning TSRMLS_CC ); return core::SQLGetData( odbc, field_index, target_type, buffer, buffer_length, out_buffer_length, handle_warning );
} }
SQLRETURN sqlsrv_odbc_result_set::get_diag_field( _In_ SQLSMALLINT record_number, _In_ SQLSMALLINT diag_identifier, SQLRETURN sqlsrv_odbc_result_set::get_diag_field( _In_ SQLSMALLINT record_number, _In_ SQLSMALLINT diag_identifier,
_Inout_updates_(buffer_length) SQLPOINTER diag_info_buffer, _In_ SQLSMALLINT buffer_length, _Inout_updates_(buffer_length) SQLPOINTER diag_info_buffer, _In_ SQLSMALLINT buffer_length,
_Inout_ SQLSMALLINT* out_buffer_length TSRMLS_DC ) _Inout_ SQLSMALLINT* out_buffer_length )
{ {
SQLSRV_ASSERT( odbc != NULL, "Invalid statement handle" ); SQLSRV_ASSERT( odbc != NULL, "Invalid statement handle" );
return core::SQLGetDiagField( odbc, record_number, diag_identifier, diag_info_buffer, buffer_length, return core::SQLGetDiagField( odbc, record_number, diag_identifier, diag_info_buffer, buffer_length,
out_buffer_length TSRMLS_CC ); out_buffer_length );
} }
sqlsrv_error* sqlsrv_odbc_result_set::get_diag_rec( _In_ SQLSMALLINT record_number ) sqlsrv_error* sqlsrv_odbc_result_set::get_diag_rec( _In_ SQLSMALLINT record_number )
@ -420,17 +420,17 @@ sqlsrv_error* sqlsrv_odbc_result_set::get_diag_rec( _In_ SQLSMALLINT record_numb
return odbc_get_diag_rec( odbc, record_number ); return odbc_get_diag_rec( odbc, record_number );
} }
SQLLEN sqlsrv_odbc_result_set::row_count( TSRMLS_D ) SQLLEN sqlsrv_odbc_result_set::row_count( void )
{ {
SQLSRV_ASSERT( odbc != NULL, "Invalid statement handle" ); SQLSRV_ASSERT( odbc != NULL, "Invalid statement handle" );
return core::SQLRowCount( odbc TSRMLS_CC ); return core::SQLRowCount( odbc );
} }
// Buffered result set // Buffered result set
// This class holds a result set in memory // This class holds a result set in memory
sqlsrv_buffered_result_set::sqlsrv_buffered_result_set( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) : sqlsrv_buffered_result_set::sqlsrv_buffered_result_set( _Inout_ sqlsrv_stmt* stmt ) :
sqlsrv_result_set( stmt ), sqlsrv_result_set( stmt ),
cache(NULL), cache(NULL),
col_count(0), col_count(0),
@ -439,7 +439,7 @@ sqlsrv_buffered_result_set::sqlsrv_buffered_result_set( _Inout_ sqlsrv_stmt* stm
read_so_far(0), read_so_far(0),
temp_length(0) temp_length(0)
{ {
col_count = core::SQLNumResultCols( stmt TSRMLS_CC ); col_count = core::SQLNumResultCols( stmt );
// there is no result set to buffer // there is no result set to buffer
if( col_count == 0 ) { if( col_count == 0 ) {
return; return;
@ -456,7 +456,7 @@ sqlsrv_buffered_result_set::sqlsrv_buffered_result_set( _Inout_ sqlsrv_stmt* stm
SQLULEN offset = null_bytes; SQLULEN offset = null_bytes;
for( SQLSMALLINT i = 0; i < col_count; ++i ) { for( SQLSMALLINT i = 0; i < col_count; ++i ) {
core::SQLDescribeColW( stmt, i + 1, NULL, 0, NULL, &meta[i].type, &meta[i].length, &meta[i].scale, NULL TSRMLS_CC ); core::SQLDescribeColW( stmt, i + 1, NULL, 0, NULL, &meta[i].type, &meta[i].length, &meta[i].scale, NULL );
offset = align_to<sizeof(SQLPOINTER)>( offset ); offset = align_to<sizeof(SQLPOINTER)>( offset );
meta[i].offset = offset; meta[i].offset = offset;
@ -469,7 +469,7 @@ sqlsrv_buffered_result_set::sqlsrv_buffered_result_set( _Inout_ sqlsrv_stmt* stm
case SQL_GUID: case SQL_GUID:
case SQL_NUMERIC: case SQL_NUMERIC:
core::SQLColAttributeW( stmt, i + 1, SQL_DESC_DISPLAY_SIZE, NULL, 0, NULL, core::SQLColAttributeW( stmt, i + 1, SQL_DESC_DISPLAY_SIZE, NULL, 0, NULL,
reinterpret_cast<SQLLEN*>( &meta[i].length ) TSRMLS_CC ); reinterpret_cast<SQLLEN*>( &meta[i].length ) );
meta[i].length += sizeof( char ) + sizeof( SQLULEN ); // null terminator space meta[i].length += sizeof( char ) + sizeof( SQLULEN ); // null terminator space
offset += meta[i].length; offset += meta[i].length;
break; break;
@ -536,7 +536,7 @@ sqlsrv_buffered_result_set::sqlsrv_buffered_result_set( _Inout_ sqlsrv_stmt* stm
case SQL_SS_TIMESTAMPOFFSET: case SQL_SS_TIMESTAMPOFFSET:
case SQL_TYPE_TIMESTAMP: case SQL_TYPE_TIMESTAMP:
core::SQLColAttributeW( stmt, i + 1, SQL_DESC_DISPLAY_SIZE, NULL, 0, NULL, core::SQLColAttributeW( stmt, i + 1, SQL_DESC_DISPLAY_SIZE, NULL, 0, NULL,
reinterpret_cast<SQLLEN*>( &meta[i].length ) TSRMLS_CC ); reinterpret_cast<SQLLEN*>( &meta[i].length ) );
meta[i].length += sizeof(char) + sizeof( SQLULEN ); // null terminator space meta[i].length += sizeof(char) + sizeof( SQLULEN ); // null terminator space
offset += meta[i].length; offset += meta[i].length;
break; break;
@ -628,10 +628,10 @@ sqlsrv_buffered_result_set::sqlsrv_buffered_result_set( _Inout_ sqlsrv_stmt* stm
size_t row_count = 0; size_t row_count = 0;
// 10 is an arbitrary number for now for the initial size of the cache // 10 is an arbitrary number for now for the initial size of the cache
ALLOC_HASHTABLE( cache ); ALLOC_HASHTABLE( cache );
core::sqlsrv_zend_hash_init( *stmt, cache, 10 /* # of buckets */, cache_row_dtor /*dtor*/, 0 /*persistent*/ TSRMLS_CC ); core::sqlsrv_zend_hash_init( *stmt, cache, 10 /* # of buckets */, cache_row_dtor /*dtor*/, 0 /*persistent*/ );
try { try {
while( core::SQLFetchScroll( stmt, SQL_FETCH_NEXT, 0 TSRMLS_CC ) != SQL_NO_DATA ) { while( core::SQLFetchScroll( stmt, SQL_FETCH_NEXT, 0 ) != SQL_NO_DATA ) {
// allocate the row buffer // allocate the row buffer
sqlsrv_malloc_auto_ptr<unsigned char> rowAuto; sqlsrv_malloc_auto_ptr<unsigned char> rowAuto;
@ -655,7 +655,7 @@ sqlsrv_buffered_result_set::sqlsrv_buffered_result_set( _Inout_ sqlsrv_stmt* stm
out_buffer_length = &out_buffer_temp; out_buffer_length = &out_buffer_temp;
SQLPOINTER* lob_addr = reinterpret_cast<SQLPOINTER*>( &row[meta[i].offset] ); SQLPOINTER* lob_addr = reinterpret_cast<SQLPOINTER*>( &row[meta[i].offset] );
*lob_addr = read_lob_field( stmt, i, meta[i], mem_used TSRMLS_CC ); *lob_addr = read_lob_field( stmt, i, meta[i], mem_used );
// a NULL pointer means NULL field // a NULL pointer means NULL field
if( *lob_addr == NULL ) { if( *lob_addr == NULL ) {
*out_buffer_length = SQL_NULL_DATA; *out_buffer_length = SQL_NULL_DATA;
@ -677,7 +677,7 @@ sqlsrv_buffered_result_set::sqlsrv_buffered_result_set( _Inout_ sqlsrv_stmt* stm
buffer = row + meta[i].offset + sizeof( SQLULEN ); buffer = row + meta[i].offset + sizeof( SQLULEN );
out_buffer_length = reinterpret_cast<SQLLEN*>( row + meta[i].offset ); out_buffer_length = reinterpret_cast<SQLLEN*>( row + meta[i].offset );
core::SQLGetData( stmt, i + 1, meta[i].c_type, buffer, meta[i].length, out_buffer_length, core::SQLGetData( stmt, i + 1, meta[i].c_type, buffer, meta[i].length, out_buffer_length,
false TSRMLS_CC ); false );
} }
break; break;
@ -693,7 +693,7 @@ sqlsrv_buffered_result_set::sqlsrv_buffered_result_set( _Inout_ sqlsrv_stmt* stm
buffer = row + meta[i].offset; buffer = row + meta[i].offset;
out_buffer_length = &out_buffer_temp; out_buffer_length = &out_buffer_temp;
core::SQLGetData( stmt, i + 1, meta[i].c_type, buffer, meta[i].length, out_buffer_length, core::SQLGetData( stmt, i + 1, meta[i].c_type, buffer, meta[i].length, out_buffer_length,
false TSRMLS_CC ); false );
} }
break; break;
@ -712,7 +712,7 @@ sqlsrv_buffered_result_set::sqlsrv_buffered_result_set( _Inout_ sqlsrv_stmt* stm
// add it to the cache // add it to the cache
row_dtor_closure cl( this, row ); row_dtor_closure cl( this, row );
sqlsrv_zend_hash_next_index_insert_mem( *stmt, cache, &cl, sizeof(row_dtor_closure) TSRMLS_CC ); sqlsrv_zend_hash_next_index_insert_mem( *stmt, cache, &cl, sizeof(row_dtor_closure) );
rowAuto.transferred(); rowAuto.transferred();
} }
} }
@ -738,7 +738,7 @@ sqlsrv_buffered_result_set::~sqlsrv_buffered_result_set( void )
} }
} }
SQLRETURN sqlsrv_buffered_result_set::fetch( _Inout_ SQLSMALLINT orientation, _Inout_opt_ SQLLEN offset TSRMLS_DC ) SQLRETURN sqlsrv_buffered_result_set::fetch( _Inout_ SQLSMALLINT orientation, _Inout_opt_ SQLLEN offset )
{ {
last_error = NULL; last_error = NULL;
last_field_index = -1; last_field_index = -1;
@ -762,7 +762,7 @@ SQLRETURN sqlsrv_buffered_result_set::fetch( _Inout_ SQLSMALLINT orientation, _I
current = 1; current = 1;
break; break;
case SQL_FETCH_LAST: case SQL_FETCH_LAST:
current = row_count( TSRMLS_C ); current = row_count();
break; break;
case SQL_FETCH_ABSOLUTE: case SQL_FETCH_ABSOLUTE:
current = offset; current = offset;
@ -783,8 +783,8 @@ SQLRETURN sqlsrv_buffered_result_set::fetch( _Inout_ SQLSMALLINT orientation, _I
} }
// the cursor can never get further away than just after the last row // the cursor can never get further away than just after the last row
if( current > row_count( TSRMLS_C ) || ( current <= 0 && offset > 0 ) /*overflow condition*/ ) { if( current > row_count() || ( current <= 0 && offset > 0 ) /*overflow condition*/ ) {
current = row_count( TSRMLS_C ) + 1; current = row_count() + 1;
return SQL_NO_DATA; return SQL_NO_DATA;
} }
@ -793,7 +793,7 @@ SQLRETURN sqlsrv_buffered_result_set::fetch( _Inout_ SQLSMALLINT orientation, _I
SQLRETURN sqlsrv_buffered_result_set::get_data( _In_ SQLUSMALLINT field_index, _In_ SQLSMALLINT target_type, SQLRETURN sqlsrv_buffered_result_set::get_data( _In_ SQLUSMALLINT field_index, _In_ SQLSMALLINT target_type,
_Out_writes_bytes_opt_(buffer_length) SQLPOINTER buffer, _In_ SQLLEN buffer_length, _Inout_ SQLLEN* out_buffer_length, _Out_writes_bytes_opt_(buffer_length) SQLPOINTER buffer, _In_ SQLLEN buffer_length, _Inout_ SQLLEN* out_buffer_length,
bool handle_warning TSRMLS_DC ) bool handle_warning )
{ {
last_error = NULL; last_error = NULL;
field_index--; // convert from 1 based to 0 based field_index--; // convert from 1 based to 0 based
@ -879,7 +879,7 @@ SQLRETURN sqlsrv_buffered_result_set::get_data( _In_ SQLUSMALLINT field_index, _
SQLRETURN sqlsrv_buffered_result_set::get_diag_field( _In_ SQLSMALLINT record_number, _In_ SQLSMALLINT diag_identifier, SQLRETURN sqlsrv_buffered_result_set::get_diag_field( _In_ SQLSMALLINT record_number, _In_ SQLSMALLINT diag_identifier,
_Inout_updates_(buffer_length) SQLPOINTER diag_info_buffer, _In_ SQLSMALLINT buffer_length, _Inout_updates_(buffer_length) SQLPOINTER diag_info_buffer, _In_ SQLSMALLINT buffer_length,
_Inout_ SQLSMALLINT* out_buffer_length TSRMLS_DC ) _Inout_ SQLSMALLINT* out_buffer_length )
{ {
SQLSRV_ASSERT( record_number == 1, "Only record number 1 can be fetched by sqlsrv_buffered_result_set::get_diag_field" ); SQLSRV_ASSERT( record_number == 1, "Only record number 1 can be fetched by sqlsrv_buffered_result_set::get_diag_field" );
SQLSRV_ASSERT( diag_identifier == SQL_DIAG_SQLSTATE, SQLSRV_ASSERT( diag_identifier == SQL_DIAG_SQLSTATE,
@ -923,7 +923,7 @@ sqlsrv_error* sqlsrv_buffered_result_set::get_diag_rec( _In_ SQLSMALLINT record_
sqlsrv_error( last_error->sqlstate, last_error->native_message, last_error->native_code ); sqlsrv_error( last_error->sqlstate, last_error->native_message, last_error->native_code );
} }
SQLLEN sqlsrv_buffered_result_set::row_count( TSRMLS_D ) SQLLEN sqlsrv_buffered_result_set::row_count( void )
{ {
last_error = NULL; last_error = NULL;
@ -1518,7 +1518,7 @@ void cache_row_dtor( _In_ zval* data )
} }
SQLPOINTER read_lob_field( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _In_ sqlsrv_buffered_result_set::meta_data& meta, SQLPOINTER read_lob_field( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _In_ sqlsrv_buffered_result_set::meta_data& meta,
_In_ zend_long mem_used TSRMLS_DC ) _In_ zend_long mem_used )
{ {
SQLSMALLINT extra = 0; SQLSMALLINT extra = 0;
SQLULEN* output_buffer_len = NULL; SQLULEN* output_buffer_len = NULL;
@ -1553,7 +1553,7 @@ SQLPOINTER read_lob_field( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_in
output_buffer_len = reinterpret_cast<SQLULEN*>( buffer.get() ); output_buffer_len = reinterpret_cast<SQLULEN*>( buffer.get() );
r = core::SQLGetData( stmt, field_index + 1, meta.c_type, buffer.get() + already_read + sizeof( SQLULEN ), r = core::SQLGetData( stmt, field_index + 1, meta.c_type, buffer.get() + already_read + sizeof( SQLULEN ),
to_read - already_read + extra, &last_field_len, false /*handle_warning*/ TSRMLS_CC ); to_read - already_read + extra, &last_field_len, false /*handle_warning*/ );
// if the field is NULL, then return a NULL pointer // if the field is NULL, then return a NULL pointer
if( last_field_len == SQL_NULL_DATA ) { if( last_field_len == SQL_NULL_DATA ) {
@ -1574,7 +1574,7 @@ SQLPOINTER read_lob_field( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_in
else if( r == SQL_SUCCESS_WITH_INFO ) { else if( r == SQL_SUCCESS_WITH_INFO ) {
SQLSMALLINT len; SQLSMALLINT len;
core::SQLGetDiagField( stmt, 1, SQL_DIAG_SQLSTATE, state, SQL_SQLSTATE_BUFSIZE, &len core::SQLGetDiagField( stmt, 1, SQL_DIAG_SQLSTATE, state, SQL_SQLSTATE_BUFSIZE, &len
TSRMLS_CC ); );
if( !is_truncated_warning( state )) { if( !is_truncated_warning( state )) {
break; break;

View file

@ -289,16 +289,16 @@ struct sqlsrv_static_assert<true> { _In_ static const int value = 1; };
// log_callback // log_callback
// a driver specific callback for checking if the messages are qualified to be logged: // a driver specific callback for checking if the messages are qualified to be logged:
// severity - severity of the message: notice, warning, or error // severity - severity of the message: notice, warning, or error
typedef bool (*severity_callback)(_In_ unsigned int severity TSRMLS_DC); typedef bool (*severity_callback)(_In_ unsigned int severity);
// each driver must register a severity checker callback for logging to work according to the INI settings // each driver must register a severity checker callback for logging to work according to the INI settings
void core_sqlsrv_register_severity_checker(_In_ severity_callback driver_checker); void core_sqlsrv_register_severity_checker(_In_ severity_callback driver_checker);
// a simple wrapper around a PHP error logging function. // a simple wrapper around a PHP error logging function.
void write_to_log( _In_ unsigned int severity TSRMLS_DC, _In_ const char* msg, ... ); void write_to_log( _In_ unsigned int severity, _In_ const char* msg, ... );
// a macro to make it convenient to use the function. // a macro to make it convenient to use the function.
#define LOG( severity, msg, ...) write_to_log( severity TSRMLS_CC, msg, ## __VA_ARGS__ ) #define LOG( severity, msg, ...) write_to_log( severity, msg, ## __VA_ARGS__ )
// mask for filtering which severities are written to the log // mask for filtering which severities are written to the log
enum logging_severity { enum logging_severity {
@ -864,7 +864,7 @@ struct sqlsrv_conn;
// a driver specific callback for processing errors. // a driver specific callback for processing errors.
// ctx - the context holding the handles // ctx - the context holding the handles
// sqlsrv_error_code - specific error code to return. // sqlsrv_error_code - specific error code to return.
typedef bool (*error_callback)( _Inout_ sqlsrv_context& ctx, _In_ unsigned int sqlsrv_error_code, _In_ bool error TSRMLS_DC, _In_opt_ va_list* print_args ); typedef bool (*error_callback)( _Inout_ sqlsrv_context& ctx, _In_ unsigned int sqlsrv_error_code, _In_ bool error, _In_opt_ va_list* print_args );
// sqlsrv_context // sqlsrv_context
// a context holds relevant information to be passed with a connection and statement objects. // a context holds relevant information to be passed with a connection and statement objects.
@ -1019,7 +1019,7 @@ struct sqlsrv_encoding {
extern bool isVistaOrGreater; // used to determine if OS is Vista or Greater extern bool isVistaOrGreater; // used to determine if OS is Vista or Greater
extern HashTable* g_encodings; // encodings supported by this driver extern HashTable* g_encodings; // encodings supported by this driver
void core_sqlsrv_minit( _Outptr_ sqlsrv_context** henv_cp, _Inout_ sqlsrv_context** henv_ncp, _In_ error_callback err, _In_z_ const char* driver_func TSRMLS_DC ); void core_sqlsrv_minit( _Outptr_ sqlsrv_context** henv_cp, _Inout_ sqlsrv_context** henv_ncp, _In_ error_callback err, _In_z_ const char* driver_func );
void core_sqlsrv_mshutdown( _Inout_ sqlsrv_context& henv_cp, _Inout_ sqlsrv_context& henv_ncp ); void core_sqlsrv_mshutdown( _Inout_ sqlsrv_context& henv_cp, _Inout_ sqlsrv_context& henv_ncp );
// environment context used by sqlsrv_connect for when a connection error occurs. // environment context used by sqlsrv_connect for when a connection error occurs.
@ -1094,7 +1094,7 @@ struct sqlsrv_conn : public sqlsrv_context {
sqlsrv_malloc_auto_ptr<ACCESSTOKEN> azure_ad_access_token; sqlsrv_malloc_auto_ptr<ACCESSTOKEN> azure_ad_access_token;
// initialize with default values // initialize with default values
sqlsrv_conn( _In_ SQLHANDLE h, _In_ error_callback e, _In_opt_ void* drv, _In_ SQLSRV_ENCODING encoding TSRMLS_DC ) : sqlsrv_conn( _In_ SQLHANDLE h, _In_ error_callback e, _In_opt_ void* drv, _In_ SQLSRV_ENCODING encoding ) :
sqlsrv_context( h, SQL_HANDLE_DBC, e, drv, encoding ) sqlsrv_context( h, SQL_HANDLE_DBC, e, drv, encoding )
{ {
server_version = SERVER_VERSION_UNKNOWN; server_version = SERVER_VERSION_UNKNOWN;
@ -1225,54 +1225,54 @@ struct connection_option {
// process the connection type // process the connection type
// return whether or not the function was successful in processing the connection option // return whether or not the function was successful in processing the connection option
void (*func)( connection_option const*, zval* value, sqlsrv_conn* conn, std::string& conn_str TSRMLS_DC ); void (*func)( connection_option const*, zval* value, sqlsrv_conn* conn, std::string& conn_str );
}; };
// connection attribute functions // connection attribute functions
// simply add the parsed value to the connection string // simply add the parsed value to the connection string
struct conn_str_append_func { struct conn_str_append_func {
static void func( _In_ connection_option const* option, _In_ zval* value, sqlsrv_conn* /*conn*/, _Inout_ std::string& conn_str TSRMLS_DC ); static void func( _In_ connection_option const* option, _In_ zval* value, sqlsrv_conn* /*conn*/, _Inout_ std::string& conn_str );
}; };
struct conn_null_func { struct conn_null_func {
static void func( connection_option const* /*option*/, zval* /*value*/, sqlsrv_conn* /*conn*/, std::string& /*conn_str*/ TSRMLS_DC ); static void func( connection_option const* /*option*/, zval* /*value*/, sqlsrv_conn* /*conn*/, std::string& /*conn_str*/ );
}; };
struct column_encryption_set_func { 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 ); static void func( _In_ connection_option const* option, _In_ zval* value, _Inout_ sqlsrv_conn* conn, _Inout_ std::string& conn_str );
}; };
struct driver_set_func { struct driver_set_func {
static void func( _In_ connection_option const* option, _In_ zval* value, _Inout_ sqlsrv_conn* conn, _Inout_ std::string& conn_str TSRMLS_DC ); static void func( _In_ connection_option const* option, _In_ zval* value, _Inout_ sqlsrv_conn* conn, _Inout_ std::string& conn_str );
}; };
struct ce_akv_str_set_func { struct ce_akv_str_set_func {
static void func( _In_ connection_option const* option, _In_ zval* value, _Inout_ sqlsrv_conn* conn, _Inout_ std::string& conn_str TSRMLS_DC ); static void func( _In_ connection_option const* option, _In_ zval* value, _Inout_ sqlsrv_conn* conn, _Inout_ std::string& conn_str );
}; };
struct access_token_set_func { struct access_token_set_func {
static void func( _In_ connection_option const* option, _In_ zval* value, _Inout_ sqlsrv_conn* conn, _Inout_ std::string& conn_str TSRMLS_DC ); static void func( _In_ connection_option const* option, _In_ zval* value, _Inout_ sqlsrv_conn* conn, _Inout_ std::string& conn_str );
}; };
// factory to create a connection (since they are subclassed to instantiate statements) // factory to create a connection (since they are subclassed to instantiate statements)
typedef sqlsrv_conn* (*driver_conn_factory)( _In_ SQLHANDLE h, _In_ error_callback e, _In_ void* drv TSRMLS_DC ); typedef sqlsrv_conn* (*driver_conn_factory)( _In_ SQLHANDLE h, _In_ error_callback e, _In_ void* drv );
// *** connection functions *** // *** connection functions ***
sqlsrv_conn* core_sqlsrv_connect( _In_ sqlsrv_context& henv_cp, _In_ sqlsrv_context& henv_ncp, _In_ driver_conn_factory conn_factory, sqlsrv_conn* core_sqlsrv_connect( _In_ sqlsrv_context& henv_cp, _In_ sqlsrv_context& henv_ncp, _In_ driver_conn_factory conn_factory,
_Inout_z_ const char* server, _Inout_opt_z_ const char* uid, _Inout_opt_z_ const char* pwd, _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[], _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 ); _In_ void* driver, _In_z_ const char* driver_func );
SQLRETURN core_odbc_connect( _Inout_ sqlsrv_conn* conn, _Inout_ std::string& conn_str, _In_ bool is_pooled ); SQLRETURN core_odbc_connect( _Inout_ sqlsrv_conn* conn, _Inout_ std::string& conn_str, _In_ bool is_pooled );
void core_sqlsrv_close( _Inout_opt_ sqlsrv_conn* conn TSRMLS_DC ); void core_sqlsrv_close( _Inout_opt_ sqlsrv_conn* conn );
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_prepare( _Inout_ sqlsrv_stmt* stmt, _In_reads_bytes_(sql_len) const char* sql, _In_ SQLLEN sql_len );
void core_sqlsrv_begin_transaction( _Inout_ sqlsrv_conn* conn TSRMLS_DC ); void core_sqlsrv_begin_transaction( _Inout_ sqlsrv_conn* conn );
void core_sqlsrv_commit( _Inout_ sqlsrv_conn* conn TSRMLS_DC ); void core_sqlsrv_commit( _Inout_ sqlsrv_conn* conn );
void core_sqlsrv_rollback( _Inout_ sqlsrv_conn* conn TSRMLS_DC ); void core_sqlsrv_rollback( _Inout_ sqlsrv_conn* conn );
void core_sqlsrv_get_server_info( _Inout_ sqlsrv_conn* conn, _Out_ zval* server_info TSRMLS_DC ); void core_sqlsrv_get_server_info( _Inout_ sqlsrv_conn* conn, _Out_ zval* server_info );
void core_sqlsrv_get_server_version( _Inout_ sqlsrv_conn* conn, _Inout_ zval *server_version TSRMLS_DC ); void core_sqlsrv_get_server_version( _Inout_ sqlsrv_conn* conn, _Inout_ zval *server_version );
void core_sqlsrv_get_client_info( _Inout_ sqlsrv_conn* conn, _Out_ zval *client_info TSRMLS_DC ); void core_sqlsrv_get_client_info( _Inout_ sqlsrv_conn* conn, _Out_ zval *client_info );
bool core_is_conn_opt_value_escaped( _Inout_ const char* value, _Inout_ size_t value_len ); bool core_is_conn_opt_value_escaped( _Inout_ const char* value, _Inout_ size_t value_len );
size_t core_str_zval_is_true( _Inout_ zval* str_zval ); size_t core_str_zval_is_true( _Inout_ zval* str_zval );
bool core_is_authentication_option_valid( _In_z_ const char* value, _In_ size_t value_len ); bool core_is_authentication_option_valid( _In_z_ const char* value, _In_ size_t value_len );
@ -1285,42 +1285,42 @@ bool core_compare_error_state( _In_ sqlsrv_conn* conn, _In_ SQLRETURN r, _In_ c
struct stmt_option_functor { struct stmt_option_functor {
virtual void operator()( _Inout_ sqlsrv_stmt* /*stmt*/, stmt_option const* /*opt*/, _In_ zval* /*value_z*/ TSRMLS_DC ); virtual void operator()( _Inout_ sqlsrv_stmt* /*stmt*/, stmt_option const* /*opt*/, _In_ zval* /*value_z*/ );
}; };
struct stmt_option_query_timeout : public stmt_option_functor { struct stmt_option_query_timeout : public stmt_option_functor {
virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* opt, _In_ zval* value_z TSRMLS_DC ); virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* opt, _In_ zval* value_z );
}; };
struct stmt_option_send_at_exec : public stmt_option_functor { struct stmt_option_send_at_exec : public stmt_option_functor {
virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* opt, _In_ zval* value_z TSRMLS_DC ); virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* opt, _In_ zval* value_z );
}; };
struct stmt_option_buffered_query_limit : public stmt_option_functor { struct stmt_option_buffered_query_limit : public stmt_option_functor {
virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* opt, _In_ zval* value_z TSRMLS_DC ); virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* opt, _In_ zval* value_z );
}; };
struct stmt_option_date_as_string : public stmt_option_functor { struct stmt_option_date_as_string : public stmt_option_functor {
virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* opt, _In_ zval* value_z TSRMLS_DC ); virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* opt, _In_ zval* value_z );
}; };
struct stmt_option_format_decimals : public stmt_option_functor { struct stmt_option_format_decimals : public stmt_option_functor {
virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* opt, _In_ zval* value_z TSRMLS_DC ); virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* opt, _In_ zval* value_z );
}; };
struct stmt_option_decimal_places : public stmt_option_functor { struct stmt_option_decimal_places : public stmt_option_functor {
virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* opt, _In_ zval* value_z TSRMLS_DC ); virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* opt, _In_ zval* value_z );
}; };
struct stmt_option_data_classification : public stmt_option_functor { struct stmt_option_data_classification : public stmt_option_functor {
virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* opt, _In_ zval* value_z TSRMLS_DC ); virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* opt, _In_ zval* value_z );
}; };
// used to hold the table for statment options // used to hold the table for statment options
@ -1353,7 +1353,7 @@ struct sqlsrv_stream {
}; };
// close any active stream // close any active stream
void close_active_stream( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ); void close_active_stream( _Inout_ sqlsrv_stmt* stmt );
extern php_stream_wrapper g_sqlsrv_stream_wrapper; extern php_stream_wrapper g_sqlsrv_stream_wrapper;
@ -1432,9 +1432,9 @@ namespace data_classification {
struct sensitivity_metadata; struct sensitivity_metadata;
void name_id_pair_free(name_id_pair * pair); void name_id_pair_free(name_id_pair * pair);
void parse_sensitivity_name_id_pairs(_Inout_ sqlsrv_stmt* stmt, _Inout_ USHORT& numpairs, _Inout_ std::vector<name_id_pair*, sqlsrv_allocator<name_id_pair*>>* pairs, _Inout_ unsigned char **pptr TSRMLS_CC); void parse_sensitivity_name_id_pairs(_Inout_ sqlsrv_stmt* stmt, _Inout_ USHORT& numpairs, _Inout_ std::vector<name_id_pair*, sqlsrv_allocator<name_id_pair*>>* pairs, _Inout_ unsigned char **pptr);
void parse_column_sensitivity_props(_Inout_ sensitivity_metadata* meta, _Inout_ unsigned char **pptr); void parse_column_sensitivity_props(_Inout_ sensitivity_metadata* meta, _Inout_ unsigned char **pptr);
USHORT fill_column_sensitivity_array(_Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT colno, _Inout_ zval *column_data TSRMLS_CC); USHORT fill_column_sensitivity_array(_Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT colno, _Inout_ zval *column_data);
struct name_id_pair { struct name_id_pair {
UCHAR name_len; UCHAR name_len;
@ -1502,8 +1502,8 @@ struct field_meta_data;
// *** Statement resource structure *** // *** Statement resource structure ***
struct sqlsrv_stmt : public sqlsrv_context { struct sqlsrv_stmt : public sqlsrv_context {
void free_param_data( TSRMLS_D ); void free_param_data( void );
virtual void new_result_set( TSRMLS_D ); virtual void new_result_set( void );
// free sensitivity classification metadata // free sensitivity classification metadata
void clean_up_sensitivity_metadata(); void clean_up_sensitivity_metadata();
@ -1551,7 +1551,8 @@ struct sqlsrv_stmt : public sqlsrv_context {
// meta data for data classification // meta data for data classification
sqlsrv_malloc_auto_ptr<data_classification::sensitivity_metadata> current_sensitivity_metadata; sqlsrv_malloc_auto_ptr<data_classification::sensitivity_metadata> current_sensitivity_metadata;
sqlsrv_stmt( _In_ sqlsrv_conn* c, _In_ SQLHANDLE handle, _In_ error_callback e, _In_opt_ void* drv TSRMLS_DC ); sqlsrv_stmt( _In_ sqlsrv_conn* c, _In_ SQLHANDLE handle, _In_ error_callback e, _In_opt_ void* drv );
virtual ~sqlsrv_stmt( void ); virtual ~sqlsrv_stmt( void );
// driver specific conversion rules from a SQL Server/ODBC type to one of the SQLSRV_PHPTYPE_* constants // driver specific conversion rules from a SQL Server/ODBC type to one of the SQLSRV_PHPTYPE_* constants
@ -1607,31 +1608,31 @@ const size_t SQLSRV_CURSOR_BUFFERED = 0xfffffffeUL; // arbitrary number that doe
#endif // !_WIN32 #endif // !_WIN32
// factory to create a statement // factory to create a statement
typedef sqlsrv_stmt* (*driver_stmt_factory)( sqlsrv_conn* conn, SQLHANDLE h, error_callback e, void* drv TSRMLS_DC ); typedef sqlsrv_stmt* (*driver_stmt_factory)( sqlsrv_conn* conn, SQLHANDLE h, error_callback e, void* drv );
// *** statement functions *** // *** statement functions ***
sqlsrv_stmt* core_sqlsrv_create_stmt( _Inout_ sqlsrv_conn* conn, _In_ driver_stmt_factory stmt_factory, _In_opt_ HashTable* options_ht, sqlsrv_stmt* core_sqlsrv_create_stmt( _Inout_ sqlsrv_conn* conn, _In_ driver_stmt_factory stmt_factory, _In_opt_ HashTable* options_ht,
_In_opt_ const stmt_option valid_stmt_opts[], _In_ error_callback const err, _In_opt_ void* driver TSRMLS_DC ); _In_opt_ const stmt_option valid_stmt_opts[], _In_ error_callback const err, _In_opt_ void* driver );
void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_num, _In_ SQLSMALLINT direction, _Inout_ zval* param_z, void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_num, _In_ SQLSMALLINT direction, _Inout_ zval* param_z,
_In_ SQLSRV_PHPTYPE php_out_type, _Inout_ SQLSRV_ENCODING encoding, _Inout_ SQLSMALLINT sql_type, _Inout_ SQLULEN column_size, _In_ SQLSRV_PHPTYPE php_out_type, _Inout_ SQLSRV_ENCODING encoding, _Inout_ SQLSMALLINT sql_type, _Inout_ SQLULEN column_size,
_Inout_ SQLSMALLINT decimal_digits TSRMLS_DC ); _Inout_ SQLSMALLINT decimal_digits );
SQLRETURN core_sqlsrv_execute( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC, _In_reads_bytes_(sql_len) const char* sql = NULL, _In_ int sql_len = 0 ); SQLRETURN core_sqlsrv_execute( _Inout_ sqlsrv_stmt* stmt, _In_reads_bytes_(sql_len) const char* sql = NULL, _In_ int sql_len = 0 );
field_meta_data* core_sqlsrv_field_metadata( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT colno TSRMLS_DC ); field_meta_data* core_sqlsrv_field_metadata( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT colno );
bool core_sqlsrv_fetch( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT fetch_orientation, _In_ SQLULEN fetch_offset TSRMLS_DC ); bool core_sqlsrv_fetch( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT fetch_orientation, _In_ SQLULEN fetch_offset );
void core_sqlsrv_get_field( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _In_ sqlsrv_phptype sqlsrv_phptype, _In_ bool prefer_string, void core_sqlsrv_get_field( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _In_ sqlsrv_phptype sqlsrv_phptype, _In_ bool prefer_string,
_Outref_result_bytebuffer_maybenull_(*field_length) void*& field_value, _Inout_ SQLLEN* field_length, _In_ bool cache_field, _Outref_result_bytebuffer_maybenull_(*field_length) void*& field_value, _Inout_ SQLLEN* field_length, _In_ bool cache_field,
_Out_ SQLSRV_PHPTYPE *sqlsrv_php_type_out TSRMLS_DC); _Out_ SQLSRV_PHPTYPE *sqlsrv_php_type_out);
bool core_sqlsrv_has_any_result( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ); bool core_sqlsrv_has_any_result( _Inout_ sqlsrv_stmt* stmt );
void core_sqlsrv_next_result( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC, _In_ bool finalize_output_params = true, _In_ bool throw_on_errors = true ); void core_sqlsrv_next_result( _Inout_ sqlsrv_stmt* stmt, _In_ bool finalize_output_params = true, _In_ bool throw_on_errors = true );
void core_sqlsrv_post_param( _Inout_ sqlsrv_stmt* stmt, _In_ zend_ulong paramno, zval* param_z TSRMLS_DC ); void core_sqlsrv_post_param( _Inout_ sqlsrv_stmt* stmt, _In_ zend_ulong paramno, zval* param_z );
void core_sqlsrv_set_scrollable( _Inout_ sqlsrv_stmt* stmt, _In_ unsigned long cursor_type TSRMLS_DC ); void core_sqlsrv_set_scrollable( _Inout_ sqlsrv_stmt* stmt, _In_ unsigned long cursor_type );
void core_sqlsrv_set_query_timeout( _Inout_ sqlsrv_stmt* stmt, _Inout_ zval* value_z TSRMLS_DC ); void core_sqlsrv_set_query_timeout( _Inout_ sqlsrv_stmt* stmt, _Inout_ zval* value_z );
void core_sqlsrv_set_send_at_exec( _Inout_ sqlsrv_stmt* stmt, _In_ zval* value_z TSRMLS_DC ); void core_sqlsrv_set_send_at_exec( _Inout_ sqlsrv_stmt* stmt, _In_ zval* value_z );
bool core_sqlsrv_send_stream_packet( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ); bool core_sqlsrv_send_stream_packet( _Inout_ sqlsrv_stmt* stmt );
void core_sqlsrv_set_buffered_query_limit( _Inout_ sqlsrv_stmt* stmt, _In_ zval* value_z TSRMLS_DC ); void core_sqlsrv_set_buffered_query_limit( _Inout_ sqlsrv_stmt* stmt, _In_ zval* value_z );
void core_sqlsrv_set_buffered_query_limit( _Inout_ sqlsrv_stmt* stmt, _In_ SQLLEN limit TSRMLS_DC ); void core_sqlsrv_set_buffered_query_limit( _Inout_ sqlsrv_stmt* stmt, _In_ SQLLEN limit );
void core_sqlsrv_set_decimal_places(_Inout_ sqlsrv_stmt* stmt, _In_ zval* value_z TSRMLS_DC); void core_sqlsrv_set_decimal_places(_Inout_ sqlsrv_stmt* stmt, _In_ zval* value_z);
void core_sqlsrv_sensitivity_metadata( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ); void core_sqlsrv_sensitivity_metadata( _Inout_ sqlsrv_stmt* stmt );
//********************************************************************************************************************************* //*********************************************************************************************************************************
// Result Set // Result Set
@ -1652,15 +1653,15 @@ struct sqlsrv_result_set {
virtual ~sqlsrv_result_set( void ) { } virtual ~sqlsrv_result_set( void ) { }
virtual bool cached( int field_index ) = 0; virtual bool cached( int field_index ) = 0;
virtual SQLRETURN fetch( _Inout_ SQLSMALLINT fetch_orientation, _Inout_opt_ SQLLEN fetch_offset TSRMLS_DC ) = 0; virtual SQLRETURN fetch( _Inout_ SQLSMALLINT fetch_orientation, _Inout_opt_ SQLLEN fetch_offset ) = 0;
virtual SQLRETURN get_data( _In_ SQLUSMALLINT field_index, _In_ SQLSMALLINT target_type, virtual SQLRETURN get_data( _In_ SQLUSMALLINT field_index, _In_ SQLSMALLINT target_type,
_Out_writes_bytes_opt_(buffer_length) void* buffer, _In_ SQLLEN buffer_length, _Inout_ SQLLEN* out_buffer_length, _Out_writes_bytes_opt_(buffer_length) void* buffer, _In_ SQLLEN buffer_length, _Inout_ SQLLEN* out_buffer_length,
bool handle_warning TSRMLS_DC )= 0; bool handle_warning )= 0;
virtual SQLRETURN get_diag_field( _In_ SQLSMALLINT record_number, _In_ SQLSMALLINT diag_identifier, virtual SQLRETURN get_diag_field( _In_ SQLSMALLINT record_number, _In_ SQLSMALLINT diag_identifier,
_Inout_updates_(buffer_length) SQLPOINTER diag_info_buffer, _In_ SQLSMALLINT buffer_length, _Inout_updates_(buffer_length) SQLPOINTER diag_info_buffer, _In_ SQLSMALLINT buffer_length,
_Inout_ SQLSMALLINT* out_buffer_length TSRMLS_DC ) = 0; _Inout_ SQLSMALLINT* out_buffer_length ) = 0;
virtual sqlsrv_error* get_diag_rec( _In_ SQLSMALLINT record_number ) = 0; virtual sqlsrv_error* get_diag_rec( _In_ SQLSMALLINT record_number ) = 0;
virtual SQLLEN row_count( TSRMLS_D ) = 0; virtual SQLLEN row_count( void ) = 0;
}; };
struct sqlsrv_odbc_result_set : public sqlsrv_result_set { struct sqlsrv_odbc_result_set : public sqlsrv_result_set {
@ -1669,15 +1670,15 @@ struct sqlsrv_odbc_result_set : public sqlsrv_result_set {
virtual ~sqlsrv_odbc_result_set( void ); virtual ~sqlsrv_odbc_result_set( void );
virtual bool cached( int field_index ) { return false; } virtual bool cached( int field_index ) { return false; }
virtual SQLRETURN fetch( _In_ SQLSMALLINT fetch_orientation, _In_ SQLLEN fetch_offset TSRMLS_DC ); virtual SQLRETURN fetch( _In_ SQLSMALLINT fetch_orientation, _In_ SQLLEN fetch_offset );
virtual SQLRETURN get_data( _In_ SQLUSMALLINT field_index, _In_ SQLSMALLINT target_type, virtual SQLRETURN get_data( _In_ SQLUSMALLINT field_index, _In_ SQLSMALLINT target_type,
_Out_writes_opt_(buffer_length) void* buffer, _In_ SQLLEN buffer_length, _Inout_ SQLLEN* out_buffer_length, _Out_writes_opt_(buffer_length) void* buffer, _In_ SQLLEN buffer_length, _Inout_ SQLLEN* out_buffer_length,
_In_ bool handle_warning TSRMLS_DC ); _In_ bool handle_warning );
virtual SQLRETURN get_diag_field( _In_ SQLSMALLINT record_number, _In_ SQLSMALLINT diag_identifier, virtual SQLRETURN get_diag_field( _In_ SQLSMALLINT record_number, _In_ SQLSMALLINT diag_identifier,
_Inout_updates_(buffer_length) SQLPOINTER diag_info_buffer, _In_ SQLSMALLINT buffer_length, _Inout_updates_(buffer_length) SQLPOINTER diag_info_buffer, _In_ SQLSMALLINT buffer_length,
_Inout_ SQLSMALLINT* out_buffer_length TSRMLS_DC ); _Inout_ SQLSMALLINT* out_buffer_length );
virtual sqlsrv_error* get_diag_rec( _In_ SQLSMALLINT record_number ); virtual sqlsrv_error* get_diag_rec( _In_ SQLSMALLINT record_number );
virtual SQLLEN row_count( TSRMLS_D ); virtual SQLLEN row_count( void );
private: private:
// prevent invalid instantiations and assignments // prevent invalid instantiations and assignments
@ -1703,19 +1704,19 @@ struct sqlsrv_buffered_result_set : public sqlsrv_result_set {
static const zend_long BUFFERED_QUERY_LIMIT_DEFAULT = 10240; // measured in KB static const zend_long BUFFERED_QUERY_LIMIT_DEFAULT = 10240; // measured in KB
static const zend_long BUFFERED_QUERY_LIMIT_INVALID = 0; static const zend_long BUFFERED_QUERY_LIMIT_INVALID = 0;
explicit sqlsrv_buffered_result_set( _Inout_ sqlsrv_stmt* odbc TSRMLS_DC ); explicit sqlsrv_buffered_result_set( _Inout_ sqlsrv_stmt* odbc );
virtual ~sqlsrv_buffered_result_set( void ); virtual ~sqlsrv_buffered_result_set( void );
virtual bool cached( int field_index ) { return true; } virtual bool cached( int field_index ) { return true; }
virtual SQLRETURN fetch( _Inout_ SQLSMALLINT fetch_orientation, _Inout_opt_ SQLLEN fetch_offset TSRMLS_DC ); virtual SQLRETURN fetch( _Inout_ SQLSMALLINT fetch_orientation, _Inout_opt_ SQLLEN fetch_offset );
virtual SQLRETURN get_data( _In_ SQLUSMALLINT field_index, _In_ SQLSMALLINT target_type, virtual SQLRETURN get_data( _In_ SQLUSMALLINT field_index, _In_ SQLSMALLINT target_type,
_Out_writes_bytes_opt_(buffer_length) void* buffer, _In_ SQLLEN buffer_length, _Inout_ SQLLEN* out_buffer_length, _Out_writes_bytes_opt_(buffer_length) void* buffer, _In_ SQLLEN buffer_length, _Inout_ SQLLEN* out_buffer_length,
bool handle_warning TSRMLS_DC ); bool handle_warning );
virtual SQLRETURN get_diag_field( _In_ SQLSMALLINT record_number, _In_ SQLSMALLINT diag_identifier, virtual SQLRETURN get_diag_field( _In_ SQLSMALLINT record_number, _In_ SQLSMALLINT diag_identifier,
_Inout_updates_(buffer_length) SQLPOINTER diag_info_buffer, _In_ SQLSMALLINT buffer_length, _Inout_updates_(buffer_length) SQLPOINTER diag_info_buffer, _In_ SQLSMALLINT buffer_length,
_Inout_ SQLSMALLINT* out_buffer_length TSRMLS_DC ); _Inout_ SQLSMALLINT* out_buffer_length );
virtual sqlsrv_error* get_diag_rec( _In_ SQLSMALLINT record_number ); virtual sqlsrv_error* get_diag_rec( _In_ SQLSMALLINT record_number );
virtual SQLLEN row_count( TSRMLS_D ); virtual SQLLEN row_count( void );
// buffered result set specific // buffered result set specific
SQLSMALLINT column_count( void ) SQLSMALLINT column_count( void )
@ -1900,12 +1901,11 @@ enum error_handling_flags {
// 3/message) driver specific error message // 3/message) driver specific error message
// The fetch type determines if the indices are numeric, associative, or both. // The fetch type determines if the indices are numeric, associative, or both.
bool core_sqlsrv_get_odbc_error( _Inout_ sqlsrv_context& ctx, _In_ int record_number, _Inout_ sqlsrv_error_auto_ptr& error, bool core_sqlsrv_get_odbc_error( _Inout_ sqlsrv_context& ctx, _In_ int record_number, _Inout_ sqlsrv_error_auto_ptr& error,
_In_ logging_severity severity TSRMLS_DC ); _In_ logging_severity severity );
// format and return a driver specfic error // format and return a driver specfic error
void core_sqlsrv_format_driver_error( _In_ sqlsrv_context& ctx, _In_ sqlsrv_error_const const* custom_error, void core_sqlsrv_format_driver_error( _In_ sqlsrv_context& ctx, _In_ sqlsrv_error_const const* custom_error,
_Out_ sqlsrv_error_auto_ptr& formatted_error, _In_ logging_severity severity TSRMLS_DC, _In_opt_ va_list* args ); _Out_ sqlsrv_error_auto_ptr& formatted_error, _In_ logging_severity severity, _In_opt_ va_list* args );
// return the message for the HRESULT returned by GetLastError. Some driver errors use this to // return the message for the HRESULT returned by GetLastError. Some driver errors use this to
// return the Windows error, e.g, when a UTF-8 <-> UTF-16 conversion fails. // return the Windows error, e.g, when a UTF-8 <-> UTF-16 conversion fails.
@ -1916,20 +1916,20 @@ DWORD core_sqlsrv_format_message( _Out_ char* output_buffer, _In_ unsigned outpu
// convenience functions that overload either a reference or a pointer so we can use // convenience functions that overload either a reference or a pointer so we can use
// either in the CHECK_* functions. // either in the CHECK_* functions.
inline bool call_error_handler( _Inout_ sqlsrv_context& ctx, _In_ unsigned long sqlsrv_error_code TSRMLS_DC, _In_ bool warning, ... ) inline bool call_error_handler( _Inout_ sqlsrv_context& ctx, _In_ unsigned long sqlsrv_error_code, _In_ bool warning, ... )
{ {
va_list print_params; va_list print_params;
va_start( print_params, warning ); va_start( print_params, warning );
bool ignored = ctx.error_handler()( ctx, sqlsrv_error_code, warning TSRMLS_CC, &print_params ); bool ignored = ctx.error_handler()( ctx, sqlsrv_error_code, warning, &print_params );
va_end( print_params ); va_end( print_params );
return ignored; return ignored;
} }
inline bool call_error_handler( _Inout_ sqlsrv_context* ctx, _In_ unsigned long sqlsrv_error_code TSRMLS_DC, _In_ bool warning, ... ) inline bool call_error_handler( _Inout_ sqlsrv_context* ctx, _In_ unsigned long sqlsrv_error_code, _In_ bool warning, ... )
{ {
va_list print_params; va_list print_params;
va_start( print_params, warning ); va_start( print_params, warning );
bool ignored = ctx->error_handler()( *ctx, sqlsrv_error_code, warning TSRMLS_CC, &print_params ); bool ignored = ctx->error_handler()( *ctx, sqlsrv_error_code, warning, &print_params );
va_end( print_params ); va_end( print_params );
return ignored; return ignored;
} }
@ -1970,7 +1970,7 @@ inline bool is_truncated_warning( _In_ SQLCHAR* state )
bool flag##unique = (condition); \ bool flag##unique = (condition); \
bool ignored##unique = true; \ bool ignored##unique = true; \
if (flag##unique) { \ if (flag##unique) { \
ignored##unique = call_error_handler( context, ssphp TSRMLS_CC, /*warning*/false, ## __VA_ARGS__ ); \ ignored##unique = call_error_handler( context, ssphp, /*warning*/false, ## __VA_ARGS__ ); \
} \ } \
if( !ignored##unique ) if( !ignored##unique )
@ -1990,7 +1990,7 @@ inline bool is_truncated_warning( _In_ SQLCHAR* state )
#define CHECK_WARNING_AS_ERROR_UNIQUE( unique, condition, context, ssphp, ... ) \ #define CHECK_WARNING_AS_ERROR_UNIQUE( unique, condition, context, ssphp, ... ) \
bool ignored##unique = true; \ bool ignored##unique = true; \
if( condition ) { \ if( condition ) { \
ignored##unique = call_error_handler( context, ssphp TSRMLS_CC, /*warning*/true, ## __VA_ARGS__ ); \ ignored##unique = call_error_handler( context, ssphp, /*warning*/true, ## __VA_ARGS__ ); \
} \ } \
if( !ignored##unique ) if( !ignored##unique )
@ -1999,7 +1999,7 @@ inline bool is_truncated_warning( _In_ SQLCHAR* state )
#define CHECK_SQL_WARNING( result, context, ... ) \ #define CHECK_SQL_WARNING( result, context, ... ) \
if( result == SQL_SUCCESS_WITH_INFO ) { \ if( result == SQL_SUCCESS_WITH_INFO ) { \
(void)call_error_handler( context, 0 TSRMLS_CC, /*warning*/ true, ## __VA_ARGS__ ); \ (void)call_error_handler( context, 0, /*warning*/ true, ## __VA_ARGS__ ); \
} }
#define CHECK_CUSTOM_WARNING_AS_ERROR( condition, context, ssphp, ... ) \ #define CHECK_CUSTOM_WARNING_AS_ERROR( condition, context, ssphp, ... ) \
@ -2012,16 +2012,16 @@ inline bool is_truncated_warning( _In_ SQLCHAR* state )
SQLSRV_ASSERT( result != SQL_INVALID_HANDLE, "Invalid handle returned." ); \ SQLSRV_ASSERT( result != SQL_INVALID_HANDLE, "Invalid handle returned." ); \
bool ignored = true; \ bool ignored = true; \
if( result == SQL_ERROR ) { \ if( result == SQL_ERROR ) { \
ignored = call_error_handler( context, SQLSRV_ERROR_ODBC TSRMLS_CC, false, ##__VA_ARGS__ ); \ ignored = call_error_handler( context, SQLSRV_ERROR_ODBC, false, ##__VA_ARGS__ ); \
} \ } \
else if( result == SQL_SUCCESS_WITH_INFO ) { \ else if( result == SQL_SUCCESS_WITH_INFO ) { \
ignored = call_error_handler( context, SQLSRV_ERROR_ODBC TSRMLS_CC, true TSRMLS_CC, ##__VA_ARGS__ ); \ ignored = call_error_handler( context, SQLSRV_ERROR_ODBC, true, ##__VA_ARGS__ ); \
} \ } \
if( !ignored ) if( !ignored )
// throw an exception after it has been hooked into the custom error handler // throw an exception after it has been hooked into the custom error handler
#define THROW_CORE_ERROR( ctx, custom, ... ) \ #define THROW_CORE_ERROR( ctx, custom, ... ) \
(void)call_error_handler( ctx, custom TSRMLS_CC, /*warning*/ false, ## __VA_ARGS__ ); \ (void)call_error_handler( ctx, custom, /*warning*/ false, ## __VA_ARGS__ ); \
throw core::CoreException(); throw core::CoreException();
//********************************************************************************************************************************* //*********************************************************************************************************************************
@ -2038,7 +2038,7 @@ namespace core {
} }
}; };
inline void check_for_mars_error( _Inout_ sqlsrv_stmt* stmt, _In_ SQLRETURN r TSRMLS_DC ) inline void check_for_mars_error( _Inout_ sqlsrv_stmt* stmt, _In_ SQLRETURN r )
{ {
// Skip this if not SQL_ERROR - // Skip this if not SQL_ERROR -
// We check for the 'connection busy' error caused by having MultipleActiveResultSets off // We check for the 'connection busy' error caused by having MultipleActiveResultSets off
@ -2083,7 +2083,7 @@ namespace core {
inline SQLRETURN SQLGetDiagField( _Inout_ sqlsrv_context* ctx, _In_ SQLSMALLINT record_number, _In_ SQLSMALLINT diag_identifier, inline SQLRETURN SQLGetDiagField( _Inout_ sqlsrv_context* ctx, _In_ SQLSMALLINT record_number, _In_ SQLSMALLINT diag_identifier,
_Out_writes_opt_(buffer_length) SQLPOINTER diag_info_buffer, _In_ SQLSMALLINT buffer_length, _Out_writes_opt_(buffer_length) SQLPOINTER diag_info_buffer, _In_ SQLSMALLINT buffer_length,
_Out_opt_ SQLSMALLINT* out_buffer_length TSRMLS_DC ) _Out_opt_ SQLSMALLINT* out_buffer_length )
{ {
SQLRETURN r = ::SQLGetDiagField( ctx->handle_type(), ctx->handle(), record_number, diag_identifier, SQLRETURN r = ::SQLGetDiagField( ctx->handle_type(), ctx->handle(), record_number, diag_identifier,
diag_info_buffer, buffer_length, out_buffer_length ); diag_info_buffer, buffer_length, out_buffer_length );
@ -2096,7 +2096,7 @@ namespace core {
} }
inline void SQLAllocHandle( _In_ SQLSMALLINT HandleType, _Inout_ sqlsrv_context& InputHandle, inline void SQLAllocHandle( _In_ SQLSMALLINT HandleType, _Inout_ sqlsrv_context& InputHandle,
_Out_ SQLHANDLE* OutputHandlePtr TSRMLS_DC ) _Out_ SQLHANDLE* OutputHandlePtr )
{ {
SQLRETURN r; SQLRETURN r;
r = ::SQLAllocHandle( HandleType, InputHandle.handle(), OutputHandlePtr ); r = ::SQLAllocHandle( HandleType, InputHandle.handle(), OutputHandlePtr );
@ -2115,7 +2115,7 @@ namespace core {
_Inout_opt_ SQLPOINTER ParameterValuePtr, _Inout_opt_ SQLPOINTER ParameterValuePtr,
_Inout_ SQLLEN BufferLength, _Inout_ SQLLEN BufferLength,
_Inout_ SQLLEN * StrLen_Or_IndPtr _Inout_ SQLLEN * StrLen_Or_IndPtr
TSRMLS_DC ) )
{ {
SQLRETURN r; SQLRETURN r;
r = ::SQLBindParameter( stmt->handle(), ParameterNumber, InputOutputType, ValueType, ParameterType, ColumnSize, r = ::SQLBindParameter( stmt->handle(), ParameterNumber, InputOutputType, ValueType, ParameterType, ColumnSize,
@ -2126,7 +2126,7 @@ namespace core {
} }
} }
inline void SQLCloseCursor( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) inline void SQLCloseCursor( _Inout_ sqlsrv_stmt* stmt )
{ {
SQLRETURN r = ::SQLCloseCursor( stmt->handle() ); SQLRETURN r = ::SQLCloseCursor( stmt->handle() );
@ -2137,7 +2137,7 @@ namespace core {
inline void SQLColAttribute( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _In_ SQLUSMALLINT field_identifier, inline void SQLColAttribute( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _In_ SQLUSMALLINT field_identifier,
_Out_writes_bytes_opt_(buffer_length) SQLPOINTER field_type_char, _In_ SQLSMALLINT buffer_length, _Out_writes_bytes_opt_(buffer_length) SQLPOINTER field_type_char, _In_ SQLSMALLINT buffer_length,
_Out_opt_ SQLSMALLINT* out_buffer_length, _Out_opt_ SQLLEN* field_type_num TSRMLS_DC ) _Out_opt_ SQLSMALLINT* out_buffer_length, _Out_opt_ SQLLEN* field_type_num )
{ {
SQLRETURN r = ::SQLColAttribute( stmt->handle(), field_index, field_identifier, field_type_char, SQLRETURN r = ::SQLColAttribute( stmt->handle(), field_index, field_identifier, field_type_char,
buffer_length, out_buffer_length, field_type_num ); buffer_length, out_buffer_length, field_type_num );
@ -2149,7 +2149,7 @@ namespace core {
inline void SQLColAttributeW( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _In_ SQLUSMALLINT field_identifier, inline void SQLColAttributeW( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _In_ SQLUSMALLINT field_identifier,
_Out_writes_bytes_opt_(buffer_length) SQLPOINTER field_type_char, _In_ SQLSMALLINT buffer_length, _Out_writes_bytes_opt_(buffer_length) SQLPOINTER field_type_char, _In_ SQLSMALLINT buffer_length,
_Out_opt_ SQLSMALLINT* out_buffer_length, _Out_opt_ SQLLEN* field_type_num TSRMLS_DC ) _Out_opt_ SQLSMALLINT* out_buffer_length, _Out_opt_ SQLLEN* field_type_num )
{ {
SQLRETURN r = ::SQLColAttributeW( stmt->handle(), field_index, field_identifier, field_type_char, SQLRETURN r = ::SQLColAttributeW( stmt->handle(), field_index, field_identifier, field_type_char,
buffer_length, out_buffer_length, field_type_num ); buffer_length, out_buffer_length, field_type_num );
@ -2161,7 +2161,7 @@ namespace core {
inline void SQLDescribeCol( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT colno, _Out_writes_opt_(col_name_length) SQLCHAR* col_name, _In_ SQLSMALLINT col_name_length, inline void SQLDescribeCol( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT colno, _Out_writes_opt_(col_name_length) SQLCHAR* col_name, _In_ SQLSMALLINT col_name_length,
_Out_opt_ SQLSMALLINT* col_name_length_out, _Out_opt_ SQLSMALLINT* data_type, _Out_opt_ SQLULEN* col_size, _Out_opt_ SQLSMALLINT* col_name_length_out, _Out_opt_ SQLSMALLINT* data_type, _Out_opt_ SQLULEN* col_size,
_Out_opt_ SQLSMALLINT* decimal_digits, _Out_opt_ SQLSMALLINT* nullable TSRMLS_DC ) _Out_opt_ SQLSMALLINT* decimal_digits, _Out_opt_ SQLSMALLINT* nullable )
{ {
SQLRETURN r; SQLRETURN r;
r = ::SQLDescribeCol( stmt->handle(), colno, col_name, col_name_length, col_name_length_out, r = ::SQLDescribeCol( stmt->handle(), colno, col_name, col_name_length, col_name_length_out,
@ -2174,7 +2174,7 @@ namespace core {
inline void SQLDescribeColW( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT colno, _Out_writes_opt_(col_name_length) SQLWCHAR* col_name, _In_ SQLSMALLINT col_name_length, inline void SQLDescribeColW( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT colno, _Out_writes_opt_(col_name_length) SQLWCHAR* col_name, _In_ SQLSMALLINT col_name_length,
_Out_opt_ SQLSMALLINT* col_name_length_out, _Out_opt_ SQLSMALLINT* data_type, _Out_opt_ SQLULEN* col_size, _Out_opt_ SQLSMALLINT* col_name_length_out, _Out_opt_ SQLSMALLINT* data_type, _Out_opt_ SQLULEN* col_size,
_Out_opt_ SQLSMALLINT* decimal_digits, _Out_opt_ SQLSMALLINT* nullable TSRMLS_DC ) _Out_opt_ SQLSMALLINT* decimal_digits, _Out_opt_ SQLSMALLINT* nullable )
{ {
SQLRETURN r; SQLRETURN r;
r = ::SQLDescribeColW( stmt->handle(), colno, col_name, col_name_length, col_name_length_out, r = ::SQLDescribeColW( stmt->handle(), colno, col_name, col_name_length, col_name_length_out,
@ -2186,7 +2186,7 @@ namespace core {
} }
inline void SQLDescribeParam( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT paramno, _Out_opt_ SQLSMALLINT* data_type, _Out_opt_ SQLULEN* col_size, inline void SQLDescribeParam( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT paramno, _Out_opt_ SQLSMALLINT* data_type, _Out_opt_ SQLULEN* col_size,
_Out_opt_ SQLSMALLINT* decimal_digits, _Out_opt_ SQLSMALLINT* nullable TSRMLS_DC ) _Out_opt_ SQLSMALLINT* decimal_digits, _Out_opt_ SQLSMALLINT* nullable )
{ {
SQLRETURN r; SQLRETURN r;
r = ::SQLDescribeParam( stmt->handle(), paramno, data_type, col_size, decimal_digits, nullable ); r = ::SQLDescribeParam( stmt->handle(), paramno, data_type, col_size, decimal_digits, nullable );
@ -2206,7 +2206,7 @@ namespace core {
} }
} }
inline void SQLEndTran( _In_ SQLSMALLINT handleType, _Inout_ sqlsrv_conn* conn, _In_ SQLSMALLINT completionType TSRMLS_DC ) inline void SQLEndTran( _In_ SQLSMALLINT handleType, _Inout_ sqlsrv_conn* conn, _In_ SQLSMALLINT completionType )
{ {
SQLRETURN r = ::SQLEndTran( handleType, conn->handle(), completionType ); SQLRETURN r = ::SQLEndTran( handleType, conn->handle(), completionType );
@ -2216,11 +2216,11 @@ namespace core {
} }
// SQLExecDirect returns the status code since it returns either SQL_NEED_DATA or SQL_NO_DATA besides just errors/success // SQLExecDirect returns the status code since it returns either SQL_NEED_DATA or SQL_NO_DATA besides just errors/success
inline SQLRETURN SQLExecDirect( _Inout_ sqlsrv_stmt* stmt, _In_ char* sql TSRMLS_DC ) inline SQLRETURN SQLExecDirect( _Inout_ sqlsrv_stmt* stmt, _In_ char* sql )
{ {
SQLRETURN r = ::SQLExecDirect( stmt->handle(), reinterpret_cast<SQLCHAR*>( sql ), SQL_NTS ); SQLRETURN r = ::SQLExecDirect( stmt->handle(), reinterpret_cast<SQLCHAR*>( sql ), SQL_NTS );
check_for_mars_error( stmt, r TSRMLS_CC ); check_for_mars_error( stmt, r );
CHECK_SQL_ERROR_OR_WARNING( r, stmt ) { CHECK_SQL_ERROR_OR_WARNING( r, stmt ) {
@ -2229,12 +2229,12 @@ namespace core {
return r; return r;
} }
inline SQLRETURN SQLExecDirectW( _Inout_ sqlsrv_stmt* stmt, _In_ SQLWCHAR* wsql TSRMLS_DC ) inline SQLRETURN SQLExecDirectW( _Inout_ sqlsrv_stmt* stmt, _In_ SQLWCHAR* wsql )
{ {
SQLRETURN r; SQLRETURN r;
r = ::SQLExecDirectW( stmt->handle(), reinterpret_cast<SQLWCHAR*>( wsql ), SQL_NTS ); r = ::SQLExecDirectW( stmt->handle(), reinterpret_cast<SQLWCHAR*>( wsql ), SQL_NTS );
check_for_mars_error( stmt, r TSRMLS_CC ); check_for_mars_error( stmt, r );
CHECK_SQL_ERROR_OR_WARNING( r, stmt ) { CHECK_SQL_ERROR_OR_WARNING( r, stmt ) {
throw CoreException(); throw CoreException();
@ -2243,12 +2243,12 @@ namespace core {
} }
// SQLExecute returns the status code since it returns either SQL_NEED_DATA or SQL_NO_DATA besides just errors/success // SQLExecute returns the status code since it returns either SQL_NEED_DATA or SQL_NO_DATA besides just errors/success
inline SQLRETURN SQLExecute( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) inline SQLRETURN SQLExecute( _Inout_ sqlsrv_stmt* stmt )
{ {
SQLRETURN r; SQLRETURN r;
r = ::SQLExecute( stmt->handle() ); r = ::SQLExecute( stmt->handle() );
check_for_mars_error( stmt, r TSRMLS_CC ); check_for_mars_error( stmt, r );
CHECK_SQL_ERROR_OR_WARNING( r, stmt ) { CHECK_SQL_ERROR_OR_WARNING( r, stmt ) {
throw CoreException(); throw CoreException();
@ -2257,7 +2257,7 @@ namespace core {
return r; return r;
} }
inline SQLRETURN SQLFetchScroll( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT fetch_orientation, _In_ SQLLEN fetch_offset TSRMLS_DC ) inline SQLRETURN SQLFetchScroll( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT fetch_orientation, _In_ SQLLEN fetch_offset )
{ {
SQLRETURN r = ::SQLFetchScroll( stmt->handle(), fetch_orientation, fetch_offset ); SQLRETURN r = ::SQLFetchScroll( stmt->handle(), fetch_orientation, fetch_offset );
@ -2269,14 +2269,14 @@ namespace core {
// wrap SQLFreeHandle and report any errors, but don't actually signal an error to the calling routine // wrap SQLFreeHandle and report any errors, but don't actually signal an error to the calling routine
inline void SQLFreeHandle( _Inout_ sqlsrv_context& ctx TSRMLS_DC ) inline void SQLFreeHandle( _Inout_ sqlsrv_context& ctx )
{ {
SQLRETURN r; SQLRETURN r;
r = ::SQLFreeHandle( ctx.handle_type(), ctx.handle() ); r = ::SQLFreeHandle( ctx.handle_type(), ctx.handle() );
CHECK_SQL_ERROR_OR_WARNING( r, ctx ) {} CHECK_SQL_ERROR_OR_WARNING( r, ctx ) {}
} }
inline void SQLGetStmtAttr( _Inout_ sqlsrv_stmt* stmt, _In_ SQLINTEGER attr, _Out_writes_opt_(buf_len) void* value_ptr, _In_ SQLINTEGER buf_len, _Out_opt_ SQLINTEGER* str_len TSRMLS_DC) inline void SQLGetStmtAttr( _Inout_ sqlsrv_stmt* stmt, _In_ SQLINTEGER attr, _Out_writes_opt_(buf_len) void* value_ptr, _In_ SQLINTEGER buf_len, _Out_opt_ SQLINTEGER* str_len)
{ {
SQLRETURN r; SQLRETURN r;
r = ::SQLGetStmtAttr( stmt->handle(), attr, value_ptr, buf_len, str_len ); r = ::SQLGetStmtAttr( stmt->handle(), attr, value_ptr, buf_len, str_len );
@ -2287,7 +2287,7 @@ namespace core {
inline SQLRETURN SQLGetData( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _In_ SQLSMALLINT target_type, inline SQLRETURN SQLGetData( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _In_ SQLSMALLINT target_type,
_Out_writes_opt_(buffer_length) void* buffer, _In_ SQLLEN buffer_length, _Out_opt_ SQLLEN* out_buffer_length, _Out_writes_opt_(buffer_length) void* buffer, _In_ SQLLEN buffer_length, _Out_opt_ SQLLEN* out_buffer_length,
_In_ bool handle_warning TSRMLS_DC ) _In_ bool handle_warning )
{ {
SQLRETURN r = ::SQLGetData( stmt->handle(), field_index, target_type, buffer, buffer_length, out_buffer_length ); SQLRETURN r = ::SQLGetData( stmt->handle(), field_index, target_type, buffer, buffer_length, out_buffer_length );
@ -2309,7 +2309,7 @@ namespace core {
inline void SQLGetInfo( _Inout_ sqlsrv_conn* conn, _In_ SQLUSMALLINT info_type, _Out_writes_bytes_opt_(buffer_len) SQLPOINTER info_value, _In_ SQLSMALLINT buffer_len, inline void SQLGetInfo( _Inout_ sqlsrv_conn* conn, _In_ SQLUSMALLINT info_type, _Out_writes_bytes_opt_(buffer_len) SQLPOINTER info_value, _In_ SQLSMALLINT buffer_len,
_Out_opt_ SQLSMALLINT* str_len TSRMLS_DC ) _Out_opt_ SQLSMALLINT* str_len )
{ {
SQLRETURN r; SQLRETURN r;
r = ::SQLGetInfo( conn->handle(), info_type, info_value, buffer_len, str_len ); r = ::SQLGetInfo( conn->handle(), info_type, info_value, buffer_len, str_len );
@ -2320,7 +2320,7 @@ namespace core {
} }
inline void SQLGetTypeInfo( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT data_type TSRMLS_DC ) inline void SQLGetTypeInfo( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT data_type )
{ {
SQLRETURN r; SQLRETURN r;
r = ::SQLGetTypeInfo( stmt->handle(), data_type ); r = ::SQLGetTypeInfo( stmt->handle(), data_type );
@ -2332,7 +2332,7 @@ namespace core {
// SQLMoreResults returns the status code since it returns SQL_NO_DATA when there is no more data in a result set. // SQLMoreResults returns the status code since it returns SQL_NO_DATA when there is no more data in a result set.
inline SQLRETURN SQLMoreResults( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) inline SQLRETURN SQLMoreResults( _Inout_ sqlsrv_stmt* stmt )
{ {
SQLRETURN r = ::SQLMoreResults( stmt->handle() ); SQLRETURN r = ::SQLMoreResults( stmt->handle() );
@ -2343,7 +2343,7 @@ namespace core {
return r; return r;
} }
inline SQLSMALLINT SQLNumResultCols( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) inline SQLSMALLINT SQLNumResultCols( _Inout_ sqlsrv_stmt* stmt )
{ {
SQLRETURN r; SQLRETURN r;
SQLSMALLINT num_cols; SQLSMALLINT num_cols;
@ -2358,7 +2358,7 @@ namespace core {
// SQLParamData returns the status code since it returns either SQL_NEED_DATA or SQL_NO_DATA when there are more // SQLParamData returns the status code since it returns either SQL_NEED_DATA or SQL_NO_DATA when there are more
// parameters or when the parameters are all processed. // parameters or when the parameters are all processed.
inline SQLRETURN SQLParamData( _Inout_ sqlsrv_stmt* stmt, _Out_opt_ SQLPOINTER* value_ptr_ptr TSRMLS_DC ) inline SQLRETURN SQLParamData( _Inout_ sqlsrv_stmt* stmt, _Out_opt_ SQLPOINTER* value_ptr_ptr )
{ {
SQLRETURN r; SQLRETURN r;
r = ::SQLParamData( stmt->handle(), value_ptr_ptr ); r = ::SQLParamData( stmt->handle(), value_ptr_ptr );
@ -2368,7 +2368,7 @@ namespace core {
return r; return r;
} }
inline void SQLPrepareW( _Inout_ sqlsrv_stmt* stmt, _In_reads_(sql_len) SQLWCHAR * sql, _In_ SQLINTEGER sql_len TSRMLS_DC ) inline void SQLPrepareW( _Inout_ sqlsrv_stmt* stmt, _In_reads_(sql_len) SQLWCHAR * sql, _In_ SQLINTEGER sql_len )
{ {
SQLRETURN r; SQLRETURN r;
r = ::SQLPrepareW( stmt->handle(), sql, sql_len ); r = ::SQLPrepareW( stmt->handle(), sql, sql_len );
@ -2378,7 +2378,7 @@ namespace core {
} }
inline void SQLPutData( _Inout_ sqlsrv_stmt* stmt, _In_reads_(strlen_or_ind) SQLPOINTER data_ptr, _In_ SQLLEN strlen_or_ind TSRMLS_DC ) inline void SQLPutData( _Inout_ sqlsrv_stmt* stmt, _In_reads_(strlen_or_ind) SQLPOINTER data_ptr, _In_ SQLLEN strlen_or_ind )
{ {
SQLRETURN r; SQLRETURN r;
r = ::SQLPutData( stmt->handle(), data_ptr, strlen_or_ind ); r = ::SQLPutData( stmt->handle(), data_ptr, strlen_or_ind );
@ -2388,7 +2388,7 @@ namespace core {
} }
inline SQLLEN SQLRowCount( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) inline SQLLEN SQLRowCount( _Inout_ sqlsrv_stmt* stmt )
{ {
SQLRETURN r; SQLRETURN r;
SQLLEN rows_affected; SQLLEN rows_affected;
@ -2415,7 +2415,7 @@ namespace core {
} }
inline void SQLSetConnectAttr( _Inout_ sqlsrv_context& ctx, _In_ SQLINTEGER attr, _In_reads_bytes_opt_(str_len) SQLPOINTER value_ptr, _In_ SQLINTEGER str_len TSRMLS_DC ) inline void SQLSetConnectAttr( _Inout_ sqlsrv_context& ctx, _In_ SQLINTEGER attr, _In_reads_bytes_opt_(str_len) SQLPOINTER value_ptr, _In_ SQLINTEGER str_len )
{ {
SQLRETURN r; SQLRETURN r;
r = ::SQLSetConnectAttr( ctx.handle(), attr, value_ptr, str_len ); r = ::SQLSetConnectAttr( ctx.handle(), attr, value_ptr, str_len );
@ -2425,7 +2425,7 @@ namespace core {
} }
} }
inline void SQLSetDescField( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT rec_num, _In_ SQLSMALLINT fld_id, _In_reads_bytes_opt_( str_len ) SQLPOINTER value_ptr, _In_ SQLINTEGER str_len TSRMLS_DC ) inline void SQLSetDescField( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT rec_num, _In_ SQLSMALLINT fld_id, _In_reads_bytes_opt_( str_len ) SQLPOINTER value_ptr, _In_ SQLINTEGER str_len )
{ {
SQLRETURN r; SQLRETURN r;
SQLHDESC hIpd = NULL; SQLHDESC hIpd = NULL;
@ -2438,7 +2438,7 @@ namespace core {
} }
} }
inline void SQLSetEnvAttr( _Inout_ sqlsrv_context& ctx, _In_ SQLINTEGER attr, _In_reads_bytes_opt_(str_len) SQLPOINTER value_ptr, _In_ SQLINTEGER str_len TSRMLS_DC ) inline void SQLSetEnvAttr( _Inout_ sqlsrv_context& ctx, _In_ SQLINTEGER attr, _In_reads_bytes_opt_(str_len) SQLPOINTER value_ptr, _In_ SQLINTEGER str_len )
{ {
SQLRETURN r; SQLRETURN r;
r = ::SQLSetEnvAttr( ctx.handle(), attr, value_ptr, str_len ); r = ::SQLSetEnvAttr( ctx.handle(), attr, value_ptr, str_len );
@ -2447,7 +2447,7 @@ namespace core {
} }
} }
inline void SQLSetConnectAttr( _Inout_ sqlsrv_conn* conn, _In_ SQLINTEGER attribute, _In_reads_bytes_opt_(value_len) SQLPOINTER value_ptr, _In_ SQLINTEGER value_len TSRMLS_DC ) inline void SQLSetConnectAttr( _Inout_ sqlsrv_conn* conn, _In_ SQLINTEGER attribute, _In_reads_bytes_opt_(value_len) SQLPOINTER value_ptr, _In_ SQLINTEGER value_len )
{ {
SQLRETURN r = ::SQLSetConnectAttr( conn->handle(), attribute, value_ptr, value_len ); SQLRETURN r = ::SQLSetConnectAttr( conn->handle(), attribute, value_ptr, value_len );
@ -2456,7 +2456,7 @@ namespace core {
} }
} }
inline void SQLSetStmtAttr( _Inout_ sqlsrv_stmt* stmt, _In_ SQLINTEGER attr, _In_reads_(str_len) SQLPOINTER value_ptr, _In_ SQLINTEGER str_len TSRMLS_DC ) inline void SQLSetStmtAttr( _Inout_ sqlsrv_stmt* stmt, _In_ SQLINTEGER attr, _In_reads_(str_len) SQLPOINTER value_ptr, _In_ SQLINTEGER str_len )
{ {
SQLRETURN r; SQLRETURN r;
r = ::SQLSetStmtAttr( stmt->handle(), attr, value_ptr, str_len ); r = ::SQLSetStmtAttr( stmt->handle(), attr, value_ptr, str_len );
@ -2494,7 +2494,7 @@ namespace core {
// If there is a zend function in the source that isn't found here, it is because it returns void and there is no error // If there is a zend function in the source that isn't found here, it is because it returns void and there is no error
// that can be thrown from it. // that can be thrown from it.
inline void sqlsrv_add_index_zval( _Inout_ sqlsrv_context& ctx, _Inout_ zval* array, _In_ zend_ulong index, _In_ zval* value TSRMLS_DC) inline void sqlsrv_add_index_zval( _Inout_ sqlsrv_context& ctx, _Inout_ zval* array, _In_ zend_ulong index, _In_ zval* value)
{ {
int zr = add_index_zval( array, index, value ); int zr = add_index_zval( array, index, value );
CHECK_ZEND_ERROR( zr, ctx, SQLSRV_ERROR_ZEND_HASH ) { CHECK_ZEND_ERROR( zr, ctx, SQLSRV_ERROR_ZEND_HASH ) {
@ -2502,7 +2502,7 @@ namespace core {
} }
} }
inline void sqlsrv_add_next_index_zval( _Inout_ sqlsrv_context& ctx, _Inout_ zval* array, _In_ zval* value TSRMLS_DC) inline void sqlsrv_add_next_index_zval( _Inout_ sqlsrv_context& ctx, _Inout_ zval* array, _In_ zval* value)
{ {
int zr = add_next_index_zval( array, value ); int zr = add_next_index_zval( array, value );
CHECK_ZEND_ERROR( zr, ctx, SQLSRV_ERROR_ZEND_HASH ) { CHECK_ZEND_ERROR( zr, ctx, SQLSRV_ERROR_ZEND_HASH ) {
@ -2510,7 +2510,7 @@ namespace core {
} }
} }
inline void sqlsrv_add_assoc_null( _Inout_ sqlsrv_context& ctx, _Inout_ zval* array_z, _In_ const char* key TSRMLS_DC ) inline void sqlsrv_add_assoc_null( _Inout_ sqlsrv_context& ctx, _Inout_ zval* array_z, _In_ const char* key )
{ {
int zr = ::add_assoc_null( array_z, key ); int zr = ::add_assoc_null( array_z, key );
CHECK_ZEND_ERROR (zr, ctx, SQLSRV_ERROR_ZEND_HASH ) { CHECK_ZEND_ERROR (zr, ctx, SQLSRV_ERROR_ZEND_HASH ) {
@ -2518,7 +2518,7 @@ namespace core {
} }
} }
inline void sqlsrv_add_assoc_long( _Inout_ sqlsrv_context& ctx, _Inout_ zval* array_z, _In_ const char* key, _In_ zend_long val TSRMLS_DC ) inline void sqlsrv_add_assoc_long( _Inout_ sqlsrv_context& ctx, _Inout_ zval* array_z, _In_ const char* key, _In_ zend_long val )
{ {
int zr = ::add_assoc_long( array_z, key, val ); int zr = ::add_assoc_long( array_z, key, val );
CHECK_ZEND_ERROR (zr, ctx, SQLSRV_ERROR_ZEND_HASH ) { CHECK_ZEND_ERROR (zr, ctx, SQLSRV_ERROR_ZEND_HASH ) {
@ -2526,7 +2526,7 @@ namespace core {
} }
} }
inline void sqlsrv_add_assoc_string( _Inout_ sqlsrv_context& ctx, _Inout_ zval* array_z, _In_ const char* key, _Inout_z_ char* val, _In_ bool duplicate TSRMLS_DC ) inline void sqlsrv_add_assoc_string( _Inout_ sqlsrv_context& ctx, _Inout_ zval* array_z, _In_ const char* key, _Inout_z_ char* val, _In_ bool duplicate )
{ {
int zr = ::add_assoc_string(array_z, key, val); int zr = ::add_assoc_string(array_z, key, val);
CHECK_ZEND_ERROR (zr, ctx, SQLSRV_ERROR_ZEND_HASH ) { CHECK_ZEND_ERROR (zr, ctx, SQLSRV_ERROR_ZEND_HASH ) {
@ -2537,7 +2537,7 @@ namespace core {
} }
} }
inline void sqlsrv_add_assoc_zval( _Inout_ sqlsrv_context& ctx, _Inout_ zval* array_z, _In_ const char* key, _In_ zval* val TSRMLS_DC ) inline void sqlsrv_add_assoc_zval( _Inout_ sqlsrv_context& ctx, _Inout_ zval* array_z, _In_ const char* key, _In_ zval* val )
{ {
int zr = ::add_assoc_zval(array_z, key, val); int zr = ::add_assoc_zval(array_z, key, val);
CHECK_ZEND_ERROR (zr, ctx, SQLSRV_ERROR_ZEND_HASH ) { CHECK_ZEND_ERROR (zr, ctx, SQLSRV_ERROR_ZEND_HASH ) {
@ -2545,7 +2545,7 @@ namespace core {
} }
} }
inline void sqlsrv_array_init( _Inout_ sqlsrv_context& ctx, _Out_ zval* new_array TSRMLS_DC) inline void sqlsrv_array_init( _Inout_ sqlsrv_context& ctx, _Out_ zval* new_array)
{ {
#if PHP_VERSION_ID < 70300 #if PHP_VERSION_ID < 70300
CHECK_ZEND_ERROR(::array_init(new_array), ctx, SQLSRV_ERROR_ZEND_HASH) { CHECK_ZEND_ERROR(::array_init(new_array), ctx, SQLSRV_ERROR_ZEND_HASH) {
@ -2556,7 +2556,7 @@ namespace core {
#endif #endif
} }
inline void sqlsrv_php_stream_from_zval_no_verify( _Inout_ sqlsrv_context& ctx, _Outref_result_maybenull_ php_stream*& stream, _In_opt_ zval* stream_z TSRMLS_DC ) inline void sqlsrv_php_stream_from_zval_no_verify( _Inout_ sqlsrv_context& ctx, _Outref_result_maybenull_ php_stream*& stream, _In_opt_ zval* stream_z )
{ {
// this duplicates the macro php_stream_from_zval_no_verify, which we can't use because it has an assignment // this duplicates the macro php_stream_from_zval_no_verify, which we can't use because it has an assignment
php_stream_from_zval_no_verify( stream, stream_z ); php_stream_from_zval_no_verify( stream, stream_z );
@ -2565,7 +2565,7 @@ namespace core {
} }
} }
inline void sqlsrv_zend_hash_get_current_data( _In_ sqlsrv_context& ctx, _In_ HashTable* ht, _Outref_result_maybenull_ zval*& output_data TSRMLS_DC) inline void sqlsrv_zend_hash_get_current_data( _In_ sqlsrv_context& ctx, _In_ HashTable* ht, _Outref_result_maybenull_ zval*& output_data)
{ {
int zr = (output_data = ::zend_hash_get_current_data(ht)) != NULL ? SUCCESS : FAILURE; int zr = (output_data = ::zend_hash_get_current_data(ht)) != NULL ? SUCCESS : FAILURE;
CHECK_ZEND_ERROR( zr, ctx, SQLSRV_ERROR_ZEND_HASH ) { CHECK_ZEND_ERROR( zr, ctx, SQLSRV_ERROR_ZEND_HASH ) {
@ -2573,7 +2573,7 @@ namespace core {
} }
} }
inline void sqlsrv_zend_hash_get_current_data_ptr( _Inout_ sqlsrv_context& ctx, _In_ HashTable* ht, _Outref_result_maybenull_ void*& output_data TSRMLS_DC) inline void sqlsrv_zend_hash_get_current_data_ptr( _Inout_ sqlsrv_context& ctx, _In_ HashTable* ht, _Outref_result_maybenull_ void*& output_data)
{ {
int zr = (output_data = ::zend_hash_get_current_data_ptr(ht)) != NULL ? SUCCESS : FAILURE; int zr = (output_data = ::zend_hash_get_current_data_ptr(ht)) != NULL ? SUCCESS : FAILURE;
CHECK_ZEND_ERROR(zr, ctx, SQLSRV_ERROR_ZEND_HASH) { CHECK_ZEND_ERROR(zr, ctx, SQLSRV_ERROR_ZEND_HASH) {
@ -2581,7 +2581,7 @@ namespace core {
} }
} }
inline void sqlsrv_zend_hash_index_del( _Inout_ sqlsrv_context& ctx, _Inout_ HashTable* ht, _In_ zend_ulong index TSRMLS_DC ) inline void sqlsrv_zend_hash_index_del( _Inout_ sqlsrv_context& ctx, _Inout_ HashTable* ht, _In_ zend_ulong index )
{ {
int zr = ::zend_hash_index_del( ht, index ); int zr = ::zend_hash_index_del( ht, index );
CHECK_ZEND_ERROR( zr, ctx, SQLSRV_ERROR_ZEND_HASH ) { CHECK_ZEND_ERROR( zr, ctx, SQLSRV_ERROR_ZEND_HASH ) {
@ -2589,7 +2589,7 @@ namespace core {
} }
} }
inline void sqlsrv_zend_hash_index_update( _Inout_ sqlsrv_context& ctx, _Inout_ HashTable* ht, _In_ zend_ulong index, _In_ zval* data_z TSRMLS_DC ) inline void sqlsrv_zend_hash_index_update( _Inout_ sqlsrv_context& ctx, _Inout_ HashTable* ht, _In_ zend_ulong index, _In_ zval* data_z )
{ {
int zr = (data_z = ::zend_hash_index_update(ht, index, data_z)) != NULL ? SUCCESS : FAILURE; int zr = (data_z = ::zend_hash_index_update(ht, index, data_z)) != NULL ? SUCCESS : FAILURE;
CHECK_ZEND_ERROR( zr, ctx, SQLSRV_ERROR_ZEND_HASH ) { CHECK_ZEND_ERROR( zr, ctx, SQLSRV_ERROR_ZEND_HASH ) {
@ -2597,7 +2597,7 @@ namespace core {
} }
} }
inline void sqlsrv_zend_hash_index_update_ptr( _Inout_ sqlsrv_context& ctx, _Inout_ HashTable* ht, _In_ zend_ulong index, _In_ void* pData TSRMLS_DC) inline void sqlsrv_zend_hash_index_update_ptr( _Inout_ sqlsrv_context& ctx, _Inout_ HashTable* ht, _In_ zend_ulong index, _In_ void* pData)
{ {
int zr = (pData = ::zend_hash_index_update_ptr(ht, index, pData)) != NULL ? SUCCESS : FAILURE; int zr = (pData = ::zend_hash_index_update_ptr(ht, index, pData)) != NULL ? SUCCESS : FAILURE;
CHECK_ZEND_ERROR(zr, ctx, SQLSRV_ERROR_ZEND_HASH) { CHECK_ZEND_ERROR(zr, ctx, SQLSRV_ERROR_ZEND_HASH) {
@ -2606,7 +2606,7 @@ namespace core {
} }
inline void sqlsrv_zend_hash_index_update_mem( _Inout_ sqlsrv_context& ctx, _Inout_ HashTable* ht, _In_ zend_ulong index, _In_reads_bytes_(size) void* pData, _In_ std::size_t size TSRMLS_DC) inline void sqlsrv_zend_hash_index_update_mem( _Inout_ sqlsrv_context& ctx, _Inout_ HashTable* ht, _In_ zend_ulong index, _In_reads_bytes_(size) void* pData, _In_ std::size_t size)
{ {
int zr = (pData = ::zend_hash_index_update_mem(ht, index, pData, size)) != NULL ? SUCCESS : FAILURE; int zr = (pData = ::zend_hash_index_update_mem(ht, index, pData, size)) != NULL ? SUCCESS : FAILURE;
CHECK_ZEND_ERROR(zr, ctx, SQLSRV_ERROR_ZEND_HASH) { CHECK_ZEND_ERROR(zr, ctx, SQLSRV_ERROR_ZEND_HASH) {
@ -2614,7 +2614,7 @@ namespace core {
} }
} }
inline void sqlsrv_zend_hash_next_index_insert( _Inout_ sqlsrv_context& ctx, _Inout_ HashTable* ht, _In_ zval* data TSRMLS_DC ) inline void sqlsrv_zend_hash_next_index_insert( _Inout_ sqlsrv_context& ctx, _Inout_ HashTable* ht, _In_ zval* data )
{ {
int zr = (data = ::zend_hash_next_index_insert(ht, data)) != NULL ? SUCCESS : FAILURE; int zr = (data = ::zend_hash_next_index_insert(ht, data)) != NULL ? SUCCESS : FAILURE;
CHECK_ZEND_ERROR( zr, ctx, SQLSRV_ERROR_ZEND_HASH ) { CHECK_ZEND_ERROR( zr, ctx, SQLSRV_ERROR_ZEND_HASH ) {
@ -2622,7 +2622,7 @@ namespace core {
} }
} }
inline void sqlsrv_zend_hash_next_index_insert_mem( _Inout_ sqlsrv_context& ctx, _In_ HashTable* ht, _In_reads_bytes_(data_size) void* data, _In_ size_t data_size TSRMLS_DC) inline void sqlsrv_zend_hash_next_index_insert_mem( _Inout_ sqlsrv_context& ctx, _In_ HashTable* ht, _In_reads_bytes_(data_size) void* data, _In_ size_t data_size)
{ {
int zr = (data = ::zend_hash_next_index_insert_mem(ht, data, data_size)) != NULL ? SUCCESS : FAILURE; int zr = (data = ::zend_hash_next_index_insert_mem(ht, data, data_size)) != NULL ? SUCCESS : FAILURE;
CHECK_ZEND_ERROR(zr, ctx, SQLSRV_ERROR_ZEND_HASH) { CHECK_ZEND_ERROR(zr, ctx, SQLSRV_ERROR_ZEND_HASH) {
@ -2630,7 +2630,7 @@ namespace core {
} }
} }
inline void sqlsrv_zend_hash_next_index_insert_ptr( _Inout_ sqlsrv_context& ctx, _Inout_ HashTable* ht, _In_ void* data TSRMLS_DC) inline void sqlsrv_zend_hash_next_index_insert_ptr( _Inout_ sqlsrv_context& ctx, _Inout_ HashTable* ht, _In_ void* data)
{ {
int zr = (data = ::zend_hash_next_index_insert_ptr(ht, data)) != NULL ? SUCCESS : FAILURE; int zr = (data = ::zend_hash_next_index_insert_ptr(ht, data)) != NULL ? SUCCESS : FAILURE;
CHECK_ZEND_ERROR(zr, ctx, SQLSRV_ERROR_ZEND_HASH) { CHECK_ZEND_ERROR(zr, ctx, SQLSRV_ERROR_ZEND_HASH) {
@ -2639,21 +2639,21 @@ namespace core {
} }
inline void sqlsrv_zend_hash_init(sqlsrv_context& ctx, _Inout_ HashTable* ht, _Inout_ uint32_t initial_size, inline void sqlsrv_zend_hash_init(sqlsrv_context& ctx, _Inout_ HashTable* ht, _Inout_ uint32_t initial_size,
_In_ dtor_func_t dtor_fn, _In_ zend_bool persistent TSRMLS_DC ) _In_ dtor_func_t dtor_fn, _In_ zend_bool persistent )
{ {
::zend_hash_init(ht, initial_size, NULL, dtor_fn, persistent); ::zend_hash_init(ht, initial_size, NULL, dtor_fn, persistent);
} }
template <typename Statement> template <typename Statement>
sqlsrv_stmt* allocate_stmt( _In_ sqlsrv_conn* conn, _In_ SQLHANDLE h, _In_ error_callback e, _In_ void* driver TSRMLS_DC ) sqlsrv_stmt* allocate_stmt( _In_ sqlsrv_conn* conn, _In_ SQLHANDLE h, _In_ error_callback e, _In_ void* driver )
{ {
return new ( sqlsrv_malloc( sizeof( Statement ))) Statement( conn, h, e, driver TSRMLS_CC ); return new ( sqlsrv_malloc( sizeof( Statement ))) Statement( conn, h, e, driver );
} }
template <typename Connection> template <typename Connection>
sqlsrv_conn* allocate_conn( _In_ SQLHANDLE h, _In_ error_callback e, _In_ void* driver TSRMLS_DC ) sqlsrv_conn* allocate_conn( _In_ SQLHANDLE h, _In_ error_callback e, _In_ void* driver )
{ {
return new ( sqlsrv_malloc( sizeof( Connection ))) Connection( h, e, driver TSRMLS_CC ); return new ( sqlsrv_malloc( sizeof( Connection ))) Connection( h, e, driver );
} }
} // namespace core } // namespace core
@ -2661,10 +2661,10 @@ sqlsrv_conn* allocate_conn( _In_ SQLHANDLE h, _In_ error_callback e, _In_ void*
template <unsigned int Attr> template <unsigned int Attr>
struct str_conn_attr_func { struct str_conn_attr_func {
static void func( connection_option const* /*option*/, zval* value, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/ TSRMLS_DC ) static void func( connection_option const* /*option*/, zval* value, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/ )
{ {
try { try {
core::SQLSetConnectAttr( conn, Attr, reinterpret_cast<SQLPOINTER>( Z_STRVAL_P( value )), static_cast<SQLINTEGER>( Z_STRLEN_P( value )) TSRMLS_CC ); core::SQLSetConnectAttr( conn, Attr, reinterpret_cast<SQLPOINTER>( Z_STRVAL_P( value )), static_cast<SQLINTEGER>( Z_STRLEN_P( value )) );
} }
catch ( core::CoreException& ) { catch ( core::CoreException& ) {
throw; throw;

View file

@ -92,35 +92,35 @@ const size_t DATE_FORMAT_LEN = sizeof( DATE_FORMAT );
// *** internal functions *** // *** internal functions ***
// Only declarations are put here. Functions contain the documentation they need at their definition sites. // Only declarations are put here. Functions contain the documentation they need at their definition sites.
void calc_string_size( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _In_ SQLLEN sql_type, _Inout_ SQLLEN& size TSRMLS_DC ); void calc_string_size( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _In_ SQLLEN sql_type, _Inout_ SQLLEN& size );
size_t calc_utf8_missing( _Inout_ sqlsrv_stmt* stmt, _In_reads_(buffer_end) const char* buffer, _In_ size_t buffer_end TSRMLS_DC ); size_t calc_utf8_missing( _Inout_ sqlsrv_stmt* stmt, _In_reads_(buffer_end) const char* buffer, _In_ size_t buffer_end );
bool check_for_next_stream_parameter( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ); bool check_for_next_stream_parameter( _Inout_ sqlsrv_stmt* stmt );
bool convert_input_param_to_utf16( _In_ zval* input_param_z, _Inout_ zval* convert_param_z ); bool convert_input_param_to_utf16( _In_ zval* input_param_z, _Inout_ zval* convert_param_z );
void core_get_field_common(_Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _Inout_ sqlsrv_phptype void core_get_field_common(_Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _Inout_ sqlsrv_phptype
sqlsrv_php_type, _Inout_updates_bytes_(*field_len) void*& field_value, _Inout_ SQLLEN* field_len TSRMLS_DC); sqlsrv_php_type, _Inout_updates_bytes_(*field_len) void*& field_value, _Inout_ SQLLEN* field_len);
// returns the ODBC C type constant that matches the PHP type and encoding given // returns the ODBC C type constant that matches the PHP type and encoding given
SQLSMALLINT default_c_type( _Inout_ sqlsrv_stmt* stmt, _In_opt_ SQLULEN paramno, _In_ zval const* param_z, _In_ SQLSRV_ENCODING encoding TSRMLS_DC ); SQLSMALLINT default_c_type( _Inout_ sqlsrv_stmt* stmt, _In_opt_ SQLULEN paramno, _In_ zval const* param_z, _In_ SQLSRV_ENCODING encoding );
void default_sql_size_and_scale( _Inout_ sqlsrv_stmt* stmt, _In_opt_ unsigned int paramno, _In_ zval* param_z, _In_ SQLSRV_ENCODING encoding, void default_sql_size_and_scale( _Inout_ sqlsrv_stmt* stmt, _In_opt_ unsigned int paramno, _In_ zval* param_z, _In_ SQLSRV_ENCODING encoding,
_Out_ SQLULEN& column_size, _Out_ SQLSMALLINT& decimal_digits TSRMLS_DC ); _Out_ SQLULEN& column_size, _Out_ SQLSMALLINT& decimal_digits );
// given a zval and encoding, determine the appropriate sql type, column size, and decimal scale (if appropriate) // given a zval and encoding, determine the appropriate sql type, column size, and decimal scale (if appropriate)
void default_sql_type( _Inout_ sqlsrv_stmt* stmt, _In_opt_ SQLULEN paramno, _In_ zval* param_z, _In_ SQLSRV_ENCODING encoding, void default_sql_type( _Inout_ sqlsrv_stmt* stmt, _In_opt_ SQLULEN paramno, _In_ zval* param_z, _In_ SQLSRV_ENCODING encoding,
_Out_ SQLSMALLINT& sql_type TSRMLS_DC ); _Out_ SQLSMALLINT& sql_type );
void col_cache_dtor( _Inout_ zval* data_z ); void col_cache_dtor( _Inout_ zval* data_z );
void field_cache_dtor( _Inout_ zval* data_z ); void field_cache_dtor( _Inout_ zval* data_z );
void format_decimal_numbers(_In_ SQLSMALLINT decimals_places, _In_ SQLSMALLINT field_scale, _Inout_updates_bytes_(*field_len) char*& field_value, _Inout_ SQLLEN* field_len); void format_decimal_numbers(_In_ SQLSMALLINT decimals_places, _In_ SQLSMALLINT field_scale, _Inout_updates_bytes_(*field_len) char*& field_value, _Inout_ SQLLEN* field_len);
void finalize_output_parameters( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ); void finalize_output_parameters( _Inout_ sqlsrv_stmt* stmt );
void get_field_as_string( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _Inout_ sqlsrv_phptype sqlsrv_php_type, void get_field_as_string( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _Inout_ sqlsrv_phptype sqlsrv_php_type,
_Inout_updates_bytes_(*field_len) void*& field_value, _Inout_ SQLLEN* field_len TSRMLS_DC ); _Inout_updates_bytes_(*field_len) void*& field_value, _Inout_ SQLLEN* field_len );
stmt_option const* get_stmt_option( sqlsrv_conn const* conn, _In_ zend_ulong key, _In_ const stmt_option stmt_opts[] TSRMLS_DC ); stmt_option const* get_stmt_option( sqlsrv_conn const* conn, _In_ zend_ulong key, _In_ const stmt_option stmt_opts[] );
bool is_valid_sqlsrv_phptype( _In_ sqlsrv_phptype type ); bool is_valid_sqlsrv_phptype( _In_ sqlsrv_phptype type );
// assure there is enough space for the output parameter string // assure there is enough space for the output parameter string
void resize_output_buffer_if_necessary( _Inout_ sqlsrv_stmt* stmt, _Inout_ zval* param_z, _In_ SQLULEN paramno, SQLSRV_ENCODING encoding, void resize_output_buffer_if_necessary( _Inout_ sqlsrv_stmt* stmt, _Inout_ zval* param_z, _In_ SQLULEN paramno, SQLSRV_ENCODING encoding,
_In_ SQLSMALLINT c_type, _In_ SQLSMALLINT sql_type, _In_ SQLULEN column_size, _In_ SQLSMALLINT decimal_digits, _In_ SQLSMALLINT c_type, _In_ SQLSMALLINT sql_type, _In_ SQLULEN column_size, _In_ SQLSMALLINT decimal_digits,
_Out_writes_(buffer_len) SQLPOINTER& buffer, _Out_ SQLLEN& buffer_len TSRMLS_DC ); _Out_writes_(buffer_len) SQLPOINTER& buffer, _Out_ SQLLEN& buffer_len );
void adjustInputPrecision( _Inout_ zval* param_z, _In_ SQLSMALLINT decimal_digits ); void adjustInputPrecision( _Inout_ zval* param_z, _In_ SQLSMALLINT decimal_digits );
void save_output_param_for_later( _Inout_ sqlsrv_stmt* stmt, _Inout_ sqlsrv_output_param& param TSRMLS_DC ); void save_output_param_for_later( _Inout_ sqlsrv_stmt* stmt, _Inout_ sqlsrv_output_param& param );
// send all the stream data // send all the stream data
void send_param_streams( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ); void send_param_streams( _Inout_ sqlsrv_stmt* stmt );
// called when a bound output string parameter is to be destroyed // called when a bound output string parameter is to be destroyed
void sqlsrv_output_param_dtor( _Inout_ zval* data ); void sqlsrv_output_param_dtor( _Inout_ zval* data );
// called when a bound stream parameter is to be destroyed. // called when a bound stream parameter is to be destroyed.
@ -129,7 +129,7 @@ void sqlsrv_stream_dtor( _Inout_ zval* data );
} }
// constructor for sqlsrv_stmt. Here so that we can use functions declared earlier. // constructor for sqlsrv_stmt. Here so that we can use functions declared earlier.
sqlsrv_stmt::sqlsrv_stmt( _In_ sqlsrv_conn* c, _In_ SQLHANDLE handle, _In_ error_callback e, _In_opt_ void* drv TSRMLS_DC ) : sqlsrv_stmt::sqlsrv_stmt( _In_ sqlsrv_conn* c, _In_ SQLHANDLE handle, _In_ error_callback e, _In_opt_ void* drv ) :
sqlsrv_context( handle, SQL_HANDLE_STMT, e, drv, SQLSRV_ENCODING_DEFAULT ), sqlsrv_context( handle, SQL_HANDLE_STMT, e, drv, SQLSRV_ENCODING_DEFAULT ),
conn( c ), conn( c ),
executed( false ), executed( false ),
@ -155,34 +155,33 @@ sqlsrv_stmt::sqlsrv_stmt( _In_ sqlsrv_conn* c, _In_ SQLHANDLE handle, _In_ error
{ {
ZVAL_UNDEF( &active_stream ); ZVAL_UNDEF( &active_stream );
// initialize the input string parameters array (which holds zvals) // initialize the input string parameters array (which holds zvals)
core::sqlsrv_array_init( *conn, &param_input_strings TSRMLS_CC ); core::sqlsrv_array_init( *conn, &param_input_strings );
// initialize the (input only) stream parameters (which holds sqlsrv_stream structures) // initialize the (input only) stream parameters (which holds sqlsrv_stream structures)
ZVAL_NEW_ARR( &param_streams ); ZVAL_NEW_ARR( &param_streams );
core::sqlsrv_zend_hash_init(*conn, Z_ARRVAL( param_streams ), 5 /* # of buckets */, sqlsrv_stream_dtor, 0 /*persistent*/ TSRMLS_CC); core::sqlsrv_zend_hash_init(*conn, Z_ARRVAL( param_streams ), 5 /* # of buckets */, sqlsrv_stream_dtor, 0 /*persistent*/);
// initialize the (input only) datetime parameters of converted date time objects to strings // initialize the (input only) datetime parameters of converted date time objects to strings
array_init( &param_datetime_buffers ); array_init( &param_datetime_buffers );
// initialize the output string parameters (which holds sqlsrv_output_param structures) // initialize the output string parameters (which holds sqlsrv_output_param structures)
ZVAL_NEW_ARR( &output_params ); ZVAL_NEW_ARR( &output_params );
core::sqlsrv_zend_hash_init(*conn, Z_ARRVAL( output_params ), 5 /* # of buckets */, sqlsrv_output_param_dtor, 0 /*persistent*/ TSRMLS_CC); core::sqlsrv_zend_hash_init(*conn, Z_ARRVAL( output_params ), 5 /* # of buckets */, sqlsrv_output_param_dtor, 0 /*persistent*/);
// initialize the col cache // initialize the col cache
ZVAL_NEW_ARR( &col_cache ); ZVAL_NEW_ARR( &col_cache );
core::sqlsrv_zend_hash_init( *conn, Z_ARRVAL(col_cache), 5 /* # of buckets */, col_cache_dtor, 0 /*persistent*/ TSRMLS_CC ); core::sqlsrv_zend_hash_init( *conn, Z_ARRVAL(col_cache), 5 /* # of buckets */, col_cache_dtor, 0 /*persistent*/ );
// initialize the field cache // initialize the field cache
ZVAL_NEW_ARR( &field_cache ); ZVAL_NEW_ARR( &field_cache );
core::sqlsrv_zend_hash_init(*conn, Z_ARRVAL(field_cache), 5 /* # of buckets */, field_cache_dtor, 0 /*persistent*/ TSRMLS_CC); core::sqlsrv_zend_hash_init(*conn, Z_ARRVAL(field_cache), 5 /* # of buckets */, field_cache_dtor, 0 /*persistent*/);
} }
// desctructor for sqlsrv statement. // desctructor for sqlsrv statement.
sqlsrv_stmt::~sqlsrv_stmt( void ) sqlsrv_stmt::~sqlsrv_stmt( void )
{ {
if( Z_TYPE( active_stream ) != IS_UNDEF ) { if( Z_TYPE( active_stream ) != IS_UNDEF ) {
TSRMLS_FETCH(); close_active_stream( this );
close_active_stream( this TSRMLS_CC );
} }
// delete any current results // delete any current results
@ -208,7 +207,7 @@ sqlsrv_stmt::~sqlsrv_stmt( void )
// centralized place to release (without destroying the hash tables // centralized place to release (without destroying the hash tables
// themselves) all the parameter data that accrues during the // themselves) all the parameter data that accrues during the
// execution phase. // execution phase.
void sqlsrv_stmt::free_param_data( TSRMLS_D ) void sqlsrv_stmt::free_param_data( void )
{ {
SQLSRV_ASSERT(Z_TYPE( param_input_strings ) == IS_ARRAY && Z_TYPE( param_streams ) == IS_ARRAY, SQLSRV_ASSERT(Z_TYPE( param_input_strings ) == IS_ARRAY && Z_TYPE( param_streams ) == IS_ARRAY,
"sqlsrv_stmt::free_param_data: Param zvals aren't arrays." ); "sqlsrv_stmt::free_param_data: Param zvals aren't arrays." );
@ -224,7 +223,7 @@ void sqlsrv_stmt::free_param_data( TSRMLS_D )
// to be called whenever a new result set is created, such as after an // to be called whenever a new result set is created, such as after an
// execute or next_result. Resets the state variables. // execute or next_result. Resets the state variables.
void sqlsrv_stmt::new_result_set( TSRMLS_D ) void sqlsrv_stmt::new_result_set( void )
{ {
this->fetch_called = false; this->fetch_called = false;
this->has_rows = false; this->has_rows = false;
@ -254,7 +253,7 @@ void sqlsrv_stmt::new_result_set( TSRMLS_D )
if( cursor_type == SQLSRV_CURSOR_BUFFERED ) { if( cursor_type == SQLSRV_CURSOR_BUFFERED ) {
sqlsrv_malloc_auto_ptr<sqlsrv_buffered_result_set> result; sqlsrv_malloc_auto_ptr<sqlsrv_buffered_result_set> result;
result = reinterpret_cast<sqlsrv_buffered_result_set*> ( sqlsrv_malloc( sizeof( sqlsrv_buffered_result_set ) ) ); result = reinterpret_cast<sqlsrv_buffered_result_set*> ( sqlsrv_malloc( sizeof( sqlsrv_buffered_result_set ) ) );
new ( result.get() ) sqlsrv_buffered_result_set( this TSRMLS_CC ); new ( result.get() ) sqlsrv_buffered_result_set( this );
current_results = result.get(); current_results = result.get();
result.transferred(); result.transferred();
} }
@ -286,7 +285,7 @@ void sqlsrv_stmt::clean_up_sensitivity_metadata()
// Returns the created statement // Returns the created statement
sqlsrv_stmt* core_sqlsrv_create_stmt( _Inout_ sqlsrv_conn* conn, _In_ driver_stmt_factory stmt_factory, _In_opt_ HashTable* options_ht, sqlsrv_stmt* core_sqlsrv_create_stmt( _Inout_ sqlsrv_conn* conn, _In_ driver_stmt_factory stmt_factory, _In_opt_ HashTable* options_ht,
_In_opt_ const stmt_option valid_stmt_opts[], _In_ error_callback const err, _In_opt_ void* driver TSRMLS_DC ) _In_opt_ const stmt_option valid_stmt_opts[], _In_ error_callback const err, _In_opt_ void* driver )
{ {
sqlsrv_malloc_auto_ptr<sqlsrv_stmt> stmt; sqlsrv_malloc_auto_ptr<sqlsrv_stmt> stmt;
SQLHANDLE stmt_h = SQL_NULL_HANDLE; SQLHANDLE stmt_h = SQL_NULL_HANDLE;
@ -294,9 +293,9 @@ sqlsrv_stmt* core_sqlsrv_create_stmt( _Inout_ sqlsrv_conn* conn, _In_ driver_stm
try { try {
core::SQLAllocHandle( SQL_HANDLE_STMT, *conn, &stmt_h TSRMLS_CC ); core::SQLAllocHandle( SQL_HANDLE_STMT, *conn, &stmt_h );
stmt = stmt_factory( conn, stmt_h, err, driver TSRMLS_CC ); stmt = stmt_factory( conn, stmt_h, err, driver );
stmt->conn = conn; stmt->conn = conn;
@ -317,14 +316,14 @@ sqlsrv_stmt* core_sqlsrv_create_stmt( _Inout_ sqlsrv_conn* conn, _In_ driver_stm
// The driver layer should ensure a valid key. // The driver layer should ensure a valid key.
DEBUG_SQLSRV_ASSERT(( type == HASH_KEY_IS_LONG ), "allocate_stmt: Invalid statment option key provided." ); DEBUG_SQLSRV_ASSERT(( type == HASH_KEY_IS_LONG ), "allocate_stmt: Invalid statment option key provided." );
const stmt_option* stmt_opt = get_stmt_option( stmt->conn, index, valid_stmt_opts TSRMLS_CC ); const stmt_option* stmt_opt = get_stmt_option( stmt->conn, index, valid_stmt_opts );
// if the key didn't match, then return the error to the script. // if the key didn't match, then return the error to the script.
// The driver layer should ensure that the key is valid. // The driver layer should ensure that the key is valid.
DEBUG_SQLSRV_ASSERT( stmt_opt != NULL, "allocate_stmt: unexpected null value for statement option." ); DEBUG_SQLSRV_ASSERT( stmt_opt != NULL, "allocate_stmt: unexpected null value for statement option." );
// perform the actions the statement option needs done. // perform the actions the statement option needs done.
(*stmt_opt->func)( stmt, stmt_opt, value_z TSRMLS_CC ); (*stmt_opt->func)( stmt, stmt_opt, value_z );
} ZEND_HASH_FOREACH_END(); } ZEND_HASH_FOREACH_END();
} }
@ -377,7 +376,7 @@ sqlsrv_stmt* core_sqlsrv_create_stmt( _Inout_ sqlsrv_conn* conn, _In_ driver_stm
void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_num, _In_ SQLSMALLINT direction, _Inout_ zval* param_z, void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_num, _In_ SQLSMALLINT direction, _Inout_ zval* param_z,
_In_ SQLSRV_PHPTYPE php_out_type, _Inout_ SQLSRV_ENCODING encoding, _Inout_ SQLSMALLINT sql_type, _Inout_ SQLULEN column_size, _In_ SQLSRV_PHPTYPE php_out_type, _Inout_ SQLSRV_ENCODING encoding, _Inout_ SQLSMALLINT sql_type, _Inout_ SQLULEN column_size,
_Inout_ SQLSMALLINT decimal_digits TSRMLS_DC ) _Inout_ SQLSMALLINT decimal_digits )
{ {
SQLSMALLINT c_type; SQLSMALLINT c_type;
SQLPOINTER buffer = NULL; SQLPOINTER buffer = NULL;
@ -493,16 +492,16 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_
else{ else{
// if the sql type is unknown, then set the default based on the PHP type passed in // if the sql type is unknown, then set the default based on the PHP type passed in
if( sql_type == SQL_UNKNOWN_TYPE ){ if( sql_type == SQL_UNKNOWN_TYPE ){
default_sql_type( stmt, param_num, param_z, encoding, sql_type TSRMLS_CC ); default_sql_type( stmt, param_num, param_z, encoding, sql_type );
} }
// if the size is unknown, then set the default based on the PHP type passed in // if the size is unknown, then set the default based on the PHP type passed in
if( column_size == SQLSRV_UNKNOWN_SIZE ){ if( column_size == SQLSRV_UNKNOWN_SIZE ){
default_sql_size_and_scale( stmt, static_cast<unsigned int>(param_num), param_z, encoding, column_size, decimal_digits TSRMLS_CC ); default_sql_size_and_scale( stmt, static_cast<unsigned int>(param_num), param_z, encoding, column_size, decimal_digits );
} }
} }
// determine the ODBC C type // determine the ODBC C type
c_type = default_c_type( stmt, param_num, param_z, encoding TSRMLS_CC ); c_type = default_c_type( stmt, param_num, param_z, encoding );
// set the buffer based on the PHP parameter type // set the buffer based on the PHP parameter type
switch( Z_TYPE_P( param_z )){ switch( Z_TYPE_P( param_z )){
@ -527,7 +526,7 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_
if( direction != SQL_PARAM_INPUT ){ if( direction != SQL_PARAM_INPUT ){
// save the parameter so that 1) the buffer doesn't go away, and 2) we can set it to NULL if returned // save the parameter so that 1) the buffer doesn't go away, and 2) we can set it to NULL if returned
sqlsrv_output_param output_param( param_ref, static_cast<int>( param_num ), zval_was_bool, php_out_type); sqlsrv_output_param output_param( param_ref, static_cast<int>( param_num ), zval_was_bool, php_out_type);
save_output_param_for_later( stmt, output_param TSRMLS_CC ); save_output_param_for_later( stmt, output_param );
} }
} }
break; break;
@ -539,7 +538,7 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_
if( direction != SQL_PARAM_INPUT ){ if( direction != SQL_PARAM_INPUT ){
// save the parameter so that 1) the buffer doesn't go away, and 2) we can set it to NULL if returned // save the parameter so that 1) the buffer doesn't go away, and 2) we can set it to NULL if returned
sqlsrv_output_param output_param( param_ref, static_cast<int>( param_num ), zval_was_bool, php_out_type); sqlsrv_output_param output_param( param_ref, static_cast<int>( param_num ), zval_was_bool, php_out_type);
save_output_param_for_later( stmt, output_param TSRMLS_CC ); save_output_param_for_later( stmt, output_param );
} }
} }
break; break;
@ -565,7 +564,7 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_
} }
buffer = Z_STRVAL_P( &wbuffer_z ); buffer = Z_STRVAL_P( &wbuffer_z );
buffer_len = Z_STRLEN_P( &wbuffer_z ); buffer_len = Z_STRLEN_P( &wbuffer_z );
core::sqlsrv_add_index_zval( *stmt, &( stmt->param_input_strings ), param_num, &wbuffer_z TSRMLS_CC ); core::sqlsrv_add_index_zval( *stmt, &( stmt->param_input_strings ), param_num, &wbuffer_z );
} }
ind_ptr = buffer_len; ind_ptr = buffer_len;
if( direction != SQL_PARAM_INPUT ){ if( direction != SQL_PARAM_INPUT ){
@ -600,14 +599,14 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_
// since this is an output string, assure there is enough space to hold the requested size and // since this is an output string, assure there is enough space to hold the requested size and
// set all the variables necessary (param_z, buffer, buffer_len, and ind_ptr) // set all the variables necessary (param_z, buffer, buffer_len, and ind_ptr)
resize_output_buffer_if_necessary( stmt, param_z, param_num, encoding, c_type, sql_type, column_size, decimal_digits, resize_output_buffer_if_necessary( stmt, param_z, param_num, encoding, c_type, sql_type, column_size, decimal_digits,
buffer, buffer_len TSRMLS_CC ); buffer, buffer_len );
// save the parameter to be adjusted and/or converted after the results are processed // save the parameter to be adjusted and/or converted after the results are processed
sqlsrv_output_param output_param( param_ref, encoding, param_num, static_cast<SQLUINTEGER>( buffer_len ) ); sqlsrv_output_param output_param( param_ref, encoding, param_num, static_cast<SQLUINTEGER>( buffer_len ) );
output_param.saveMetaData(sql_type, column_size, decimal_digits); output_param.saveMetaData(sql_type, column_size, decimal_digits);
save_output_param_for_later( stmt, output_param TSRMLS_CC ); save_output_param_for_later( stmt, output_param );
// For output parameters, if we set the column_size to be same as the buffer_len, // For output parameters, if we set the column_size to be same as the buffer_len,
// then if there is a truncation due to the data coming from the server being // then if there is a truncation due to the data coming from the server being
@ -638,7 +637,7 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_
SQLSRV_ASSERT( direction == SQL_PARAM_INPUT, "Invalid output param type. The driver layer should catch this." ); SQLSRV_ASSERT( direction == SQL_PARAM_INPUT, "Invalid output param type. The driver layer should catch this." );
sqlsrv_stream stream_encoding( param_z, encoding ); sqlsrv_stream stream_encoding( param_z, encoding );
HashTable* streams_ht = Z_ARRVAL( stmt->param_streams ); HashTable* streams_ht = Z_ARRVAL( stmt->param_streams );
core::sqlsrv_zend_hash_index_update_mem( *stmt, streams_ht, param_num, &stream_encoding, sizeof(stream_encoding) TSRMLS_CC ); core::sqlsrv_zend_hash_index_update_mem( *stmt, streams_ht, param_num, &stream_encoding, sizeof(stream_encoding) );
buffer = reinterpret_cast<SQLPOINTER>( param_num ); buffer = reinterpret_cast<SQLPOINTER>( param_num );
Z_TRY_ADDREF_P( param_z ); // so that it doesn't go away while we're using it Z_TRY_ADDREF_P( param_z ); // so that it doesn't go away while we're using it
buffer_len = 0; buffer_len = 0;
@ -659,7 +658,7 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_
bool valid_class_name_found = false; bool valid_class_name_found = false;
zend_class_entry *class_entry = Z_OBJCE_P( param_z TSRMLS_CC ); zend_class_entry *class_entry = Z_OBJCE_P( param_z );
while( class_entry != NULL ){ while( class_entry != NULL ){
SQLSRV_ASSERT( class_entry->name != NULL, "core_sqlsrv_bind_param: class_entry->name is NULL." ); SQLSRV_ASSERT( class_entry->name != NULL, "core_sqlsrv_bind_param: class_entry->name is NULL." );
@ -698,7 +697,7 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_
params[0] = format_z; params[0] = format_z;
// This is equivalent to the PHP code: $param_z->format( $format_z ); where param_z is the // This is equivalent to the PHP code: $param_z->format( $format_z ); where param_z is the
// DateTime object and $format_z is the format string. // DateTime object and $format_z is the format string.
int zr = call_user_function( EG( function_table ), param_z, &function_z, &buffer_z, 1, params TSRMLS_CC ); int zr = call_user_function( EG( function_table ), param_z, &function_z, &buffer_z, 1, params );
zend_string_release( Z_STR( format_z )); zend_string_release( Z_STR( format_z ));
zend_string_release( Z_STR( function_z )); zend_string_release( Z_STR( function_z ));
CHECK_CUSTOM_ERROR( zr == FAILURE, stmt, SQLSRV_ERROR_INVALID_PARAMETER_PHPTYPE, param_num + 1 ){ CHECK_CUSTOM_ERROR( zr == FAILURE, stmt, SQLSRV_ERROR_INVALID_PARAMETER_PHPTYPE, param_num + 1 ){
@ -727,7 +726,7 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_
} }
core::SQLBindParameter( stmt, param_num + 1, direction, core::SQLBindParameter( stmt, param_num + 1, direction,
c_type, sql_type, column_size, decimal_digits, buffer, buffer_len, &ind_ptr TSRMLS_CC ); c_type, sql_type, column_size, decimal_digits, buffer, buffer_len, &ind_ptr );
if ( stmt->conn->ce_option.enabled && sql_type == SQL_TYPE_TIMESTAMP ) if ( stmt->conn->ce_option.enabled && sql_type == SQL_TYPE_TIMESTAMP )
{ {
if( decimal_digits == 3 ) if( decimal_digits == 3 )
@ -737,7 +736,7 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_
} }
} }
catch( core::CoreException& e ){ catch( core::CoreException& e ){
stmt->free_param_data( TSRMLS_C ); stmt->free_param_data();
SQLFreeStmt( stmt->handle(), SQL_RESET_PARAMS ); SQLFreeStmt( stmt->handle(), SQL_RESET_PARAMS );
throw e; throw e;
} }
@ -751,14 +750,14 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_
// Return: // Return:
// true if there is data, false if there is not // true if there is data, false if there is not
SQLRETURN core_sqlsrv_execute( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC, _In_reads_bytes_(sql_len) const char* sql, _In_ int sql_len ) SQLRETURN core_sqlsrv_execute( _Inout_ sqlsrv_stmt* stmt, _In_reads_bytes_(sql_len) const char* sql, _In_ int sql_len )
{ {
SQLRETURN r = SQL_ERROR; SQLRETURN r = SQL_ERROR;
try { try {
// close the stream to release the resource // close the stream to release the resource
close_active_stream( stmt TSRMLS_CC ); close_active_stream( stmt );
if( sql ) { if( sql ) {
@ -778,25 +777,25 @@ SQLRETURN core_sqlsrv_execute( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC, _In_reads_by
throw core::CoreException(); throw core::CoreException();
} }
} }
r = core::SQLExecDirectW( stmt, wsql_string TSRMLS_CC ); r = core::SQLExecDirectW( stmt, wsql_string );
} }
else { else {
r = core::SQLExecute( stmt TSRMLS_CC ); r = core::SQLExecute( stmt );
} }
// if data is needed (streams were bound) and they should be sent at execute time, then do so now // if data is needed (streams were bound) and they should be sent at execute time, then do so now
if( r == SQL_NEED_DATA && stmt->send_streams_at_exec ) { if( r == SQL_NEED_DATA && stmt->send_streams_at_exec ) {
send_param_streams( stmt TSRMLS_CC ); send_param_streams( stmt );
} }
stmt->new_result_set( TSRMLS_C ); stmt->new_result_set();
stmt->executed = true; stmt->executed = true;
// if all the data has been sent and no data was returned then finalize the output parameters // if all the data has been sent and no data was returned then finalize the output parameters
if( stmt->send_streams_at_exec && ( r == SQL_NO_DATA || !core_sqlsrv_has_any_result( stmt TSRMLS_CC ))) { if( stmt->send_streams_at_exec && ( r == SQL_NO_DATA || !core_sqlsrv_has_any_result( stmt ))) {
finalize_output_parameters( stmt TSRMLS_CC ); finalize_output_parameters( stmt );
} }
// stream parameters are sent, clean the Hashtable // stream parameters are sent, clean the Hashtable
if ( stmt->send_streams_at_exec ) { if ( stmt->send_streams_at_exec ) {
@ -809,7 +808,7 @@ SQLRETURN core_sqlsrv_execute( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC, _In_reads_by
// if the statement executed but failed in a subsequent operation before returning, // if the statement executed but failed in a subsequent operation before returning,
// we need to cancel the statement and deref the output and stream parameters // we need to cancel the statement and deref the output and stream parameters
if ( stmt->send_streams_at_exec ) { if ( stmt->send_streams_at_exec ) {
finalize_output_parameters( stmt TSRMLS_CC ); finalize_output_parameters( stmt );
zend_hash_clean( Z_ARRVAL( stmt->param_streams )); zend_hash_clean( Z_ARRVAL( stmt->param_streams ));
} }
if( stmt->executed ) { if( stmt->executed ) {
@ -832,7 +831,7 @@ SQLRETURN core_sqlsrv_execute( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC, _In_reads_by
// Nothing, exception thrown if an error. stmt->past_fetch_end is set to true if the // Nothing, exception thrown if an error. stmt->past_fetch_end is set to true if the
// user scrolls past a non-scrollable result set // user scrolls past a non-scrollable result set
bool core_sqlsrv_fetch( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT fetch_orientation, _In_ SQLULEN fetch_offset TSRMLS_DC ) bool core_sqlsrv_fetch( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT fetch_orientation, _In_ SQLULEN fetch_offset )
{ {
// pre-condition check // pre-condition check
SQLSRV_ASSERT( fetch_orientation >= SQL_FETCH_NEXT || fetch_orientation <= SQL_FETCH_RELATIVE, SQLSRV_ASSERT( fetch_orientation >= SQL_FETCH_NEXT || fetch_orientation <= SQL_FETCH_RELATIVE,
@ -857,7 +856,7 @@ bool core_sqlsrv_fetch( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT fetch_orient
if (stmt->column_count != ACTIVE_NUM_COLS_INVALID) { if (stmt->column_count != ACTIVE_NUM_COLS_INVALID) {
has_fields = stmt->column_count; has_fields = stmt->column_count;
} else { } else {
has_fields = core::SQLNumResultCols( stmt TSRMLS_CC ); has_fields = core::SQLNumResultCols( stmt );
stmt->column_count = has_fields; stmt->column_count = has_fields;
} }
@ -867,7 +866,7 @@ bool core_sqlsrv_fetch( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT fetch_orient
} }
// close the stream to release the resource // close the stream to release the resource
close_active_stream( stmt TSRMLS_CC ); close_active_stream( stmt );
// if the statement has rows and is not scrollable but doesn't yet have // if the statement has rows and is not scrollable but doesn't yet have
// fetch_called, this must be the first time we've called sqlsrv_fetch. // fetch_called, this must be the first time we've called sqlsrv_fetch.
@ -878,7 +877,7 @@ bool core_sqlsrv_fetch( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT fetch_orient
// move to the record requested. For absolute records, we use a 0 based offset, so +1 since // move to the record requested. For absolute records, we use a 0 based offset, so +1 since
// SQLFetchScroll uses a 1 based offset, otherwise for relative, just use the fetch_offset provided. // SQLFetchScroll uses a 1 based offset, otherwise for relative, just use the fetch_offset provided.
SQLRETURN r = stmt->current_results->fetch( fetch_orientation, ( fetch_orientation == SQL_FETCH_RELATIVE ) ? fetch_offset : fetch_offset + 1 TSRMLS_CC ); SQLRETURN r = stmt->current_results->fetch( fetch_orientation, ( fetch_orientation == SQL_FETCH_RELATIVE ) ? fetch_offset : fetch_offset + 1 );
if( r == SQL_NO_DATA ) { if( r == SQL_NO_DATA ) {
// if this is a forward only cursor, mark that we've passed the end so future calls result in an error // if this is a forward only cursor, mark that we've passed the end so future calls result in an error
@ -911,7 +910,7 @@ bool core_sqlsrv_fetch( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT fetch_orient
// Return: // Return:
// A field_meta_data* consisting of the field metadata. // A field_meta_data* consisting of the field metadata.
field_meta_data* core_sqlsrv_field_metadata( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT colno TSRMLS_DC ) field_meta_data* core_sqlsrv_field_metadata( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT colno )
{ {
// pre-condition check // pre-condition check
SQLSRV_ASSERT( colno >= 0, "core_sqlsrv_field_metadata: Invalid column number provided." ); SQLSRV_ASSERT( colno >= 0, "core_sqlsrv_field_metadata: Invalid column number provided." );
@ -927,7 +926,7 @@ field_meta_data* core_sqlsrv_field_metadata( _Inout_ sqlsrv_stmt* stmt, _In_ SQL
try{ try{
core::SQLDescribeColW( stmt, colno + 1, field_name_temp, SS_MAXCOLNAMELEN + 1, &field_len_temp, core::SQLDescribeColW( stmt, colno + 1, field_name_temp, SS_MAXCOLNAMELEN + 1, &field_len_temp,
&( meta_data->field_type ), & ( meta_data->field_size ), & ( meta_data->field_scale ), &( meta_data->field_type ), & ( meta_data->field_size ), & ( meta_data->field_scale ),
&( meta_data->field_is_nullable ) TSRMLS_CC ); &( meta_data->field_is_nullable ) );
} }
catch ( core::CoreException& e ) { catch ( core::CoreException& e ) {
throw e; throw e;
@ -971,7 +970,7 @@ field_meta_data* core_sqlsrv_field_metadata( _Inout_ sqlsrv_stmt* stmt, _In_ SQL
SQLSMALLINT out_buff_len; SQLSMALLINT out_buff_len;
SQLLEN not_used; SQLLEN not_used;
core::SQLColAttribute(stmt, colno + 1, SQL_DESC_TYPE_NAME, field_type_name, core::SQLColAttribute(stmt, colno + 1, SQL_DESC_TYPE_NAME, field_type_name,
sizeof( field_type_name ), &out_buff_len, &not_used TSRMLS_CC); sizeof( field_type_name ), &out_buff_len, &not_used);
if (!strcmp(field_type_name, "money") || !strcmp(field_type_name, "smallmoney")) { if (!strcmp(field_type_name, "money") || !strcmp(field_type_name, "smallmoney")) {
meta_data->field_is_money_type = true; meta_data->field_is_money_type = true;
@ -986,7 +985,7 @@ field_meta_data* core_sqlsrv_field_metadata( _Inout_ sqlsrv_stmt* stmt, _In_ SQL
return result_field_meta_data; return result_field_meta_data;
} }
void core_sqlsrv_sensitivity_metadata( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) void core_sqlsrv_sensitivity_metadata( _Inout_ sqlsrv_stmt* stmt )
{ {
sqlsrv_malloc_auto_ptr<unsigned char> dcbuf; sqlsrv_malloc_auto_ptr<unsigned char> dcbuf;
SQLINTEGER dclen = 0; SQLINTEGER dclen = 0;
@ -1027,7 +1026,7 @@ void core_sqlsrv_sensitivity_metadata( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC )
SQLRETURN rc; SQLRETURN rc;
SQLCHAR state[SQL_SQLSTATE_BUFSIZE] = {'\0'}; SQLCHAR state[SQL_SQLSTATE_BUFSIZE] = {'\0'};
SQLSMALLINT len; SQLSMALLINT len;
rc = ::SQLGetDiagField(SQL_HANDLE_DESC, ird, 1, SQL_DIAG_SQLSTATE, state, SQL_SQLSTATE_BUFSIZE, &len TSRMLS_CC); rc = ::SQLGetDiagField(SQL_HANDLE_DESC, ird, 1, SQL_DIAG_SQLSTATE, state, SQL_SQLSTATE_BUFSIZE, &len);
CHECK_SQL_ERROR_OR_WARNING(rc, stmt) { CHECK_SQL_ERROR_OR_WARNING(rc, stmt) {
throw core::CoreException(); throw core::CoreException();
@ -1095,12 +1094,12 @@ void core_sqlsrv_sensitivity_metadata( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC )
void core_sqlsrv_get_field( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _In_ sqlsrv_phptype sqlsrv_php_type_in, _In_ bool prefer_string, void core_sqlsrv_get_field( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _In_ sqlsrv_phptype sqlsrv_php_type_in, _In_ bool prefer_string,
_Outref_result_bytebuffer_maybenull_(*field_len) void*& field_value, _Inout_ SQLLEN* field_len, _In_ bool cache_field, _Outref_result_bytebuffer_maybenull_(*field_len) void*& field_value, _Inout_ SQLLEN* field_len, _In_ bool cache_field,
_Out_ SQLSRV_PHPTYPE *sqlsrv_php_type_out TSRMLS_DC) _Out_ SQLSRV_PHPTYPE *sqlsrv_php_type_out)
{ {
try { try {
// close the stream to release the resource // close the stream to release the resource
close_active_stream(stmt TSRMLS_CC); close_active_stream(stmt);
// if the field has been retrieved before, return the previous result // if the field has been retrieved before, return the previous result
field_cache* cached = NULL; field_cache* cached = NULL;
@ -1139,7 +1138,7 @@ void core_sqlsrv_get_field( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_i
invalid.typeinfo.type = SQLSRV_PHPTYPE_INVALID; invalid.typeinfo.type = SQLSRV_PHPTYPE_INVALID;
for( int i = stmt->last_field_index + 1; i < field_index; ++i ) { for( int i = stmt->last_field_index + 1; i < field_index; ++i ) {
SQLSRV_ASSERT( reinterpret_cast<field_cache*>( zend_hash_index_find_ptr( Z_ARRVAL( stmt->field_cache ), i )) == NULL, "Field already cached." ); SQLSRV_ASSERT( reinterpret_cast<field_cache*>( zend_hash_index_find_ptr( Z_ARRVAL( stmt->field_cache ), i )) == NULL, "Field already cached." );
core_sqlsrv_get_field( stmt, i, invalid, prefer_string, field_value, field_len, cache_field, sqlsrv_php_type_out TSRMLS_CC ); core_sqlsrv_get_field( stmt, i, invalid, prefer_string, field_value, field_len, cache_field, sqlsrv_php_type_out );
// delete the value returned since we only want it cached, not the actual value // delete the value returned since we only want it cached, not the actual value
if( field_value ) { if( field_value ) {
efree( field_value ); efree( field_value );
@ -1183,12 +1182,12 @@ void core_sqlsrv_get_field( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_i
*sqlsrv_php_type_out = static_cast<SQLSRV_PHPTYPE>( sqlsrv_php_type.typeinfo.type ); *sqlsrv_php_type_out = static_cast<SQLSRV_PHPTYPE>( sqlsrv_php_type.typeinfo.type );
// Retrieve the data // Retrieve the data
core_get_field_common( stmt, field_index, sqlsrv_php_type, field_value, field_len TSRMLS_CC ); core_get_field_common( stmt, field_index, sqlsrv_php_type, field_value, field_len );
// if the user wants us to cache the field, we'll do it // if the user wants us to cache the field, we'll do it
if( cache_field ) { if( cache_field ) {
field_cache cache( field_value, *field_len, sqlsrv_php_type ); field_cache cache( field_value, *field_len, sqlsrv_php_type );
core::sqlsrv_zend_hash_index_update_mem( *stmt, Z_ARRVAL( stmt->field_cache ), field_index, &cache, sizeof(field_cache) TSRMLS_CC ); core::sqlsrv_zend_hash_index_update_mem( *stmt, Z_ARRVAL( stmt->field_cache ), field_index, &cache, sizeof(field_cache) );
} }
} }
@ -1205,7 +1204,7 @@ void core_sqlsrv_get_field( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_i
// Return: // Return:
// true if any results are present, false otherwise. // true if any results are present, false otherwise.
bool core_sqlsrv_has_any_result( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) bool core_sqlsrv_has_any_result( _Inout_ sqlsrv_stmt* stmt )
{ {
SQLSMALLINT num_cols; SQLSMALLINT num_cols;
SQLLEN rows_affected; SQLLEN rows_affected;
@ -1215,7 +1214,7 @@ bool core_sqlsrv_has_any_result( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC )
} }
else { else {
// Use SQLNumResultCols to determine if we have rows or not // Use SQLNumResultCols to determine if we have rows or not
num_cols = core::SQLNumResultCols( stmt TSRMLS_CC ); num_cols = core::SQLNumResultCols( stmt );
stmt->column_count = num_cols; stmt->column_count = num_cols;
} }
@ -1224,7 +1223,7 @@ bool core_sqlsrv_has_any_result( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC )
} }
else { else {
// Use SQLRowCount to determine if there is a rows status waiting // Use SQLRowCount to determine if there is a rows status waiting
rows_affected = core::SQLRowCount( stmt TSRMLS_CC ); rows_affected = core::SQLRowCount( stmt );
stmt->row_count = rows_affected; stmt->row_count = rows_affected;
} }
@ -1238,7 +1237,7 @@ bool core_sqlsrv_has_any_result( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC )
// Returns // Returns
// Nothing, exception thrown if problem occurs // Nothing, exception thrown if problem occurs
void core_sqlsrv_next_result( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC, _In_ bool finalize_output_params, _In_ bool throw_on_errors ) void core_sqlsrv_next_result( _Inout_ sqlsrv_stmt* stmt, _In_ bool finalize_output_params, _In_ bool throw_on_errors )
{ {
try { try {
@ -1251,14 +1250,14 @@ void core_sqlsrv_next_result( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC, _In_ bool fin
throw core::CoreException(); throw core::CoreException();
} }
close_active_stream( stmt TSRMLS_CC ); close_active_stream( stmt );
//Clear column sql types and sql display sizes. //Clear column sql types and sql display sizes.
zend_hash_clean( Z_ARRVAL( stmt->col_cache )); zend_hash_clean( Z_ARRVAL( stmt->col_cache ));
SQLRETURN r; SQLRETURN r;
if( throw_on_errors ) { if( throw_on_errors ) {
r = core::SQLMoreResults( stmt TSRMLS_CC ); r = core::SQLMoreResults( stmt );
} }
else { else {
r = SQLMoreResults( stmt->handle() ); r = SQLMoreResults( stmt->handle() );
@ -1268,7 +1267,7 @@ void core_sqlsrv_next_result( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC, _In_ bool fin
if( finalize_output_params ) { if( finalize_output_params ) {
// if we're finished processing result sets, handle the output parameters // if we're finished processing result sets, handle the output parameters
finalize_output_parameters( stmt TSRMLS_CC ); finalize_output_parameters( stmt );
} }
// mark we are past the end of all results // mark we are past the end of all results
@ -1276,7 +1275,7 @@ void core_sqlsrv_next_result( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC, _In_ bool fin
return; return;
} }
stmt->new_result_set( TSRMLS_C ); stmt->new_result_set();
} }
catch( core::CoreException& e ) { catch( core::CoreException& e ) {
@ -1295,26 +1294,26 @@ void core_sqlsrv_next_result( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC, _In_ bool fin
// Returns: // Returns:
// Nothing, exception thrown if problem occurs // Nothing, exception thrown if problem occurs
void core_sqlsrv_post_param( _Inout_ sqlsrv_stmt* stmt, _In_ zend_ulong param_num, zval* param_z TSRMLS_DC ) void core_sqlsrv_post_param( _Inout_ sqlsrv_stmt* stmt, _In_ zend_ulong param_num, zval* param_z )
{ {
SQLSRV_ASSERT( Z_TYPE( stmt->param_input_strings ) == IS_ARRAY, "Statement input parameter UTF-16 buffers array invalid." ); SQLSRV_ASSERT( Z_TYPE( stmt->param_input_strings ) == IS_ARRAY, "Statement input parameter UTF-16 buffers array invalid." );
SQLSRV_ASSERT( Z_TYPE( stmt->param_streams ) == IS_ARRAY, "Statement input parameter streams array invalid." ); SQLSRV_ASSERT( Z_TYPE( stmt->param_streams ) == IS_ARRAY, "Statement input parameter streams array invalid." );
// if the parameter was an input string, delete it from the array holding input parameter strings // if the parameter was an input string, delete it from the array holding input parameter strings
if( zend_hash_index_exists( Z_ARRVAL( stmt->param_input_strings ), param_num )) { if( zend_hash_index_exists( Z_ARRVAL( stmt->param_input_strings ), param_num )) {
core::sqlsrv_zend_hash_index_del( *stmt, Z_ARRVAL( stmt->param_input_strings ), param_num TSRMLS_CC ); core::sqlsrv_zend_hash_index_del( *stmt, Z_ARRVAL( stmt->param_input_strings ), param_num );
} }
// if the parameter was an input stream, decrement our reference to it and delete it from the array holding input streams // if the parameter was an input stream, decrement our reference to it and delete it from the array holding input streams
// PDO doesn't need the reference count, but sqlsrv does since the stream can be live after sqlsrv_execute by sending it // PDO doesn't need the reference count, but sqlsrv does since the stream can be live after sqlsrv_execute by sending it
// with sqlsrv_send_stream_data. // with sqlsrv_send_stream_data.
if( zend_hash_index_exists( Z_ARRVAL( stmt->param_streams ), param_num )) { if( zend_hash_index_exists( Z_ARRVAL( stmt->param_streams ), param_num )) {
core::sqlsrv_zend_hash_index_del( *stmt, Z_ARRVAL( stmt->param_streams ), param_num TSRMLS_CC ); core::sqlsrv_zend_hash_index_del( *stmt, Z_ARRVAL( stmt->param_streams ), param_num );
} }
} }
//Calls SQLSetStmtAttr to set a cursor. //Calls SQLSetStmtAttr to set a cursor.
void core_sqlsrv_set_scrollable( _Inout_ sqlsrv_stmt* stmt, _In_ unsigned long cursor_type TSRMLS_DC ) void core_sqlsrv_set_scrollable( _Inout_ sqlsrv_stmt* stmt, _In_ unsigned long cursor_type )
{ {
try { try {
@ -1322,27 +1321,27 @@ void core_sqlsrv_set_scrollable( _Inout_ sqlsrv_stmt* stmt, _In_ unsigned long c
case SQL_CURSOR_STATIC: case SQL_CURSOR_STATIC:
core::SQLSetStmtAttr( stmt, SQL_ATTR_CURSOR_TYPE, core::SQLSetStmtAttr( stmt, SQL_ATTR_CURSOR_TYPE,
reinterpret_cast<SQLPOINTER>( SQL_CURSOR_STATIC ), SQL_IS_UINTEGER TSRMLS_CC ); reinterpret_cast<SQLPOINTER>( SQL_CURSOR_STATIC ), SQL_IS_UINTEGER );
break; break;
case SQL_CURSOR_DYNAMIC: case SQL_CURSOR_DYNAMIC:
core::SQLSetStmtAttr( stmt, SQL_ATTR_CURSOR_TYPE, core::SQLSetStmtAttr( stmt, SQL_ATTR_CURSOR_TYPE,
reinterpret_cast<SQLPOINTER>( SQL_CURSOR_DYNAMIC ), SQL_IS_UINTEGER TSRMLS_CC ); reinterpret_cast<SQLPOINTER>( SQL_CURSOR_DYNAMIC ), SQL_IS_UINTEGER );
break; break;
case SQL_CURSOR_KEYSET_DRIVEN: case SQL_CURSOR_KEYSET_DRIVEN:
core::SQLSetStmtAttr( stmt, SQL_ATTR_CURSOR_TYPE, core::SQLSetStmtAttr( stmt, SQL_ATTR_CURSOR_TYPE,
reinterpret_cast<SQLPOINTER>( SQL_CURSOR_KEYSET_DRIVEN ), SQL_IS_UINTEGER TSRMLS_CC ); reinterpret_cast<SQLPOINTER>( SQL_CURSOR_KEYSET_DRIVEN ), SQL_IS_UINTEGER );
break; break;
case SQL_CURSOR_FORWARD_ONLY: case SQL_CURSOR_FORWARD_ONLY:
core::SQLSetStmtAttr( stmt, SQL_ATTR_CURSOR_TYPE, core::SQLSetStmtAttr( stmt, SQL_ATTR_CURSOR_TYPE,
reinterpret_cast<SQLPOINTER>( SQL_CURSOR_FORWARD_ONLY ), SQL_IS_UINTEGER TSRMLS_CC ); reinterpret_cast<SQLPOINTER>( SQL_CURSOR_FORWARD_ONLY ), SQL_IS_UINTEGER );
break; break;
case SQLSRV_CURSOR_BUFFERED: case SQLSRV_CURSOR_BUFFERED:
core::SQLSetStmtAttr( stmt, SQL_ATTR_CURSOR_TYPE, core::SQLSetStmtAttr( stmt, SQL_ATTR_CURSOR_TYPE,
reinterpret_cast<SQLPOINTER>( SQL_CURSOR_FORWARD_ONLY ), SQL_IS_UINTEGER TSRMLS_CC ); reinterpret_cast<SQLPOINTER>( SQL_CURSOR_FORWARD_ONLY ), SQL_IS_UINTEGER );
break; break;
default: default:
@ -1358,17 +1357,17 @@ void core_sqlsrv_set_scrollable( _Inout_ sqlsrv_stmt* stmt, _In_ unsigned long c
} }
} }
void core_sqlsrv_set_buffered_query_limit( _Inout_ sqlsrv_stmt* stmt, _In_ zval* value_z TSRMLS_DC ) void core_sqlsrv_set_buffered_query_limit( _Inout_ sqlsrv_stmt* stmt, _In_ zval* value_z )
{ {
if( Z_TYPE_P( value_z ) != IS_LONG ) { if( Z_TYPE_P( value_z ) != IS_LONG ) {
THROW_CORE_ERROR( stmt, SQLSRV_ERROR_INVALID_BUFFER_LIMIT ); THROW_CORE_ERROR( stmt, SQLSRV_ERROR_INVALID_BUFFER_LIMIT );
} }
core_sqlsrv_set_buffered_query_limit( stmt, Z_LVAL_P( value_z ) TSRMLS_CC ); core_sqlsrv_set_buffered_query_limit( stmt, Z_LVAL_P( value_z ) );
} }
void core_sqlsrv_set_buffered_query_limit( _Inout_ sqlsrv_stmt* stmt, _In_ SQLLEN limit TSRMLS_DC ) void core_sqlsrv_set_buffered_query_limit( _Inout_ sqlsrv_stmt* stmt, _In_ SQLLEN limit )
{ {
if( limit <= 0 ) { if( limit <= 0 ) {
@ -1382,7 +1381,7 @@ void core_sqlsrv_set_buffered_query_limit( _Inout_ sqlsrv_stmt* stmt, _In_ SQLLE
// Extracts the long value and calls the core_sqlsrv_set_query_timeout // Extracts the long value and calls the core_sqlsrv_set_query_timeout
// which accepts timeout parameter as a long. If the zval is not of type long // which accepts timeout parameter as a long. If the zval is not of type long
// than throws error. // than throws error.
void core_sqlsrv_set_query_timeout( _Inout_ sqlsrv_stmt* stmt, _Inout_ zval* value_z TSRMLS_DC ) void core_sqlsrv_set_query_timeout( _Inout_ sqlsrv_stmt* stmt, _Inout_ zval* value_z )
{ {
try { try {
@ -1401,7 +1400,7 @@ void core_sqlsrv_set_query_timeout( _Inout_ sqlsrv_stmt* stmt, _Inout_ zval* val
} }
} }
void core_sqlsrv_set_decimal_places(_Inout_ sqlsrv_stmt* stmt, _In_ zval* value_z TSRMLS_DC) void core_sqlsrv_set_decimal_places(_Inout_ sqlsrv_stmt* stmt, _In_ zval* value_z)
{ {
try { try {
// first check if the input is an integer // first check if the input is an integer
@ -1422,10 +1421,8 @@ void core_sqlsrv_set_decimal_places(_Inout_ sqlsrv_stmt* stmt, _In_ zval* value_
} }
} }
void core_sqlsrv_set_send_at_exec( _Inout_ sqlsrv_stmt* stmt, _In_ zval* value_z TSRMLS_DC ) void core_sqlsrv_set_send_at_exec( _Inout_ sqlsrv_stmt* stmt, _In_ zval* value_z )
{ {
TSRMLS_C;
// zend_is_true does not fail. It either returns true or false. // zend_is_true does not fail. It either returns true or false.
stmt->send_streams_at_exec = ( zend_is_true( value_z )) ? true : false; stmt->send_streams_at_exec = ( zend_is_true( value_z )) ? true : false;
} }
@ -1442,13 +1439,13 @@ void core_sqlsrv_set_send_at_exec( _Inout_ sqlsrv_stmt* stmt, _In_ zval* value_z
// Returns: // Returns:
// true if more data remains to be sent, false if all data processed // true if more data remains to be sent, false if all data processed
bool core_sqlsrv_send_stream_packet( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) bool core_sqlsrv_send_stream_packet( _Inout_ sqlsrv_stmt* stmt )
{ {
// if there no current parameter to process, get the next one // if there no current parameter to process, get the next one
// (probably because this is the first call to sqlsrv_send_stream_data) // (probably because this is the first call to sqlsrv_send_stream_data)
if( stmt->current_stream.stream_z == NULL ) { if( stmt->current_stream.stream_z == NULL ) {
if( check_for_next_stream_parameter( stmt TSRMLS_CC ) == false ) { if( check_for_next_stream_parameter( stmt ) == false ) {
stmt->current_stream = sqlsrv_stream( NULL, SQLSRV_ENCODING_CHAR ); stmt->current_stream = sqlsrv_stream( NULL, SQLSRV_ENCODING_CHAR );
stmt->current_stream_read = 0; stmt->current_stream_read = 0;
@ -1460,7 +1457,7 @@ bool core_sqlsrv_send_stream_packet( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC )
// get the stream from the zval we bound // get the stream from the zval we bound
php_stream* param_stream = NULL; php_stream* param_stream = NULL;
core::sqlsrv_php_stream_from_zval_no_verify( *stmt, param_stream, stmt->current_stream.stream_z TSRMLS_CC ); core::sqlsrv_php_stream_from_zval_no_verify( *stmt, param_stream, stmt->current_stream.stream_z );
// if we're at the end, then reset both current_stream and current_stream_read // if we're at the end, then reset both current_stream and current_stream_read
if (php_stream_eof(param_stream)) { if (php_stream_eof(param_stream)) {
@ -1489,7 +1486,7 @@ bool core_sqlsrv_send_stream_packet( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC )
if (read == 0) { if (read == 0) {
// send an empty string, which is what a 0 length does. // send an empty string, which is what a 0 length does.
char buff[1]; // temp storage to hand to SQLPutData char buff[1]; // temp storage to hand to SQLPutData
core::SQLPutData(stmt, buff, 0 TSRMLS_CC); core::SQLPutData(stmt, buff, 0);
} }
else if (read > 0) { else if (read > 0) {
// if this is a UTF-8 stream, then we will use the UTF-8 encoding to determine if we're in the middle of a character // if this is a UTF-8 stream, then we will use the UTF-8 encoding to determine if we're in the middle of a character
@ -1516,7 +1513,7 @@ bool core_sqlsrv_send_stream_packet( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC )
// this will calculate how many bytes were cut off from the last UTF-8 character and read that many more // this will calculate how many bytes were cut off from the last UTF-8 character and read that many more
// in, then reattempt the conversion. If it fails the second time, then an error is returned. // in, then reattempt the conversion. If it fails the second time, then an error is returned.
size_t need_to_read = calc_utf8_missing( stmt, buffer, read TSRMLS_CC ); size_t need_to_read = calc_utf8_missing( stmt, buffer, read );
// read the missing bytes // read the missing bytes
size_t new_read = php_stream_read( param_stream, static_cast<char*>( buffer ) + read, size_t new_read = php_stream_read( param_stream, static_cast<char*>( buffer ) + read,
need_to_read ); need_to_read );
@ -1535,17 +1532,17 @@ bool core_sqlsrv_send_stream_packet( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC )
throw core::CoreException(); throw core::CoreException();
} }
} }
core::SQLPutData( stmt, wbuffer, wsize * sizeof( SQLWCHAR ) TSRMLS_CC ); core::SQLPutData( stmt, wbuffer, wsize * sizeof( SQLWCHAR ) );
} }
else { else {
core::SQLPutData( stmt, buffer, read TSRMLS_CC ); core::SQLPutData( stmt, buffer, read );
} }
} }
} }
} }
catch( core::CoreException& e ) { catch( core::CoreException& e ) {
stmt->free_param_data( TSRMLS_C ); stmt->free_param_data();
SQLFreeStmt( stmt->handle(), SQL_RESET_PARAMS ); SQLFreeStmt( stmt->handle(), SQL_RESET_PARAMS );
SQLCancel( stmt->handle() ); SQLCancel( stmt->handle() );
stmt->current_stream = sqlsrv_stream( NULL, SQLSRV_ENCODING_DEFAULT ); stmt->current_stream = sqlsrv_stream( NULL, SQLSRV_ENCODING_DEFAULT );
@ -1556,30 +1553,28 @@ bool core_sqlsrv_send_stream_packet( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC )
return true; return true;
} }
void stmt_option_functor::operator()( _Inout_ sqlsrv_stmt* /*stmt*/, stmt_option const* /*opt*/, _In_ zval* /*value_z*/ TSRMLS_DC ) void stmt_option_functor::operator()( _Inout_ sqlsrv_stmt* /*stmt*/, stmt_option const* /*opt*/, _In_ zval* /*value_z*/ )
{ {
TSRMLS_C;
// This implementation should never get called. // This implementation should never get called.
DIE( "Not implemented." ); DIE( "Not implemented." );
} }
void stmt_option_query_timeout:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /**/, _In_ zval* value_z TSRMLS_DC ) void stmt_option_query_timeout:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /**/, _In_ zval* value_z )
{ {
core_sqlsrv_set_query_timeout( stmt, value_z TSRMLS_CC ); core_sqlsrv_set_query_timeout( stmt, value_z );
} }
void stmt_option_send_at_exec:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC ) void stmt_option_send_at_exec:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z )
{ {
core_sqlsrv_set_send_at_exec( stmt, value_z TSRMLS_CC ); core_sqlsrv_set_send_at_exec( stmt, value_z );
} }
void stmt_option_buffered_query_limit:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC ) void stmt_option_buffered_query_limit:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z )
{ {
core_sqlsrv_set_buffered_query_limit( stmt, value_z TSRMLS_CC ); core_sqlsrv_set_buffered_query_limit( stmt, value_z );
} }
void stmt_option_date_as_string:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /**/, _In_ zval* value_z TSRMLS_DC ) void stmt_option_date_as_string:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /**/, _In_ zval* value_z )
{ {
if (zend_is_true(value_z)) { if (zend_is_true(value_z)) {
stmt->date_as_string = true; stmt->date_as_string = true;
@ -1589,7 +1584,7 @@ void stmt_option_date_as_string:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_op
} }
} }
void stmt_option_format_decimals:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /**/, _In_ zval* value_z TSRMLS_DC ) void stmt_option_format_decimals:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /**/, _In_ zval* value_z )
{ {
if (zend_is_true(value_z)) { if (zend_is_true(value_z)) {
stmt->format_decimals = true; stmt->format_decimals = true;
@ -1599,12 +1594,12 @@ void stmt_option_format_decimals:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_o
} }
} }
void stmt_option_decimal_places:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /**/, _In_ zval* value_z TSRMLS_DC ) void stmt_option_decimal_places:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /**/, _In_ zval* value_z )
{ {
core_sqlsrv_set_decimal_places(stmt, value_z TSRMLS_CC); core_sqlsrv_set_decimal_places(stmt, value_z);
} }
void stmt_option_data_classification:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /**/, _In_ zval* value_z TSRMLS_DC ) void stmt_option_data_classification:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /**/, _In_ zval* value_z )
{ {
if (zend_is_true(value_z)) { if (zend_is_true(value_z)) {
stmt->data_classification = true; stmt->data_classification = true;
@ -1616,7 +1611,7 @@ void stmt_option_data_classification:: operator()( _Inout_ sqlsrv_stmt* stmt, st
// internal function to release the active stream. Called by each main API function // internal function to release the active stream. Called by each main API function
// that will alter the statement and cancel any retrieval of data from a stream. // that will alter the statement and cancel any retrieval of data from a stream.
void close_active_stream( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) void close_active_stream( _Inout_ sqlsrv_stmt* stmt )
{ {
// if there is no active stream, return // if there is no active stream, return
if( Z_TYPE( stmt->active_stream ) == IS_UNDEF ) { if( Z_TYPE( stmt->active_stream ) == IS_UNDEF ) {
@ -1678,7 +1673,7 @@ bool is_a_numeric_type(_In_ SQLSMALLINT sql_type)
return false; return false;
} }
void calc_string_size( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _In_ SQLLEN sql_type, _Inout_ SQLLEN& size TSRMLS_DC ) void calc_string_size( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _In_ SQLLEN sql_type, _Inout_ SQLLEN& size )
{ {
try { try {
@ -1712,7 +1707,7 @@ void calc_string_size( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index,
case SQL_SS_VARIANT: case SQL_SS_VARIANT:
{ {
// unixODBC 2.3.1 requires wide calls to support pooling // unixODBC 2.3.1 requires wide calls to support pooling
core::SQLColAttributeW( stmt, field_index + 1, SQL_DESC_DISPLAY_SIZE, NULL, 0, NULL, &size TSRMLS_CC ); core::SQLColAttributeW( stmt, field_index + 1, SQL_DESC_DISPLAY_SIZE, NULL, 0, NULL, &size );
break; break;
} }
@ -1722,7 +1717,7 @@ void calc_string_size( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index,
case SQL_WVARCHAR: case SQL_WVARCHAR:
{ {
// unixODBC 2.3.1 requires wide calls to support pooling // unixODBC 2.3.1 requires wide calls to support pooling
core::SQLColAttributeW( stmt, field_index + 1, SQL_DESC_OCTET_LENGTH, NULL, 0, NULL, &size TSRMLS_CC ); core::SQLColAttributeW( stmt, field_index + 1, SQL_DESC_OCTET_LENGTH, NULL, 0, NULL, &size );
break; break;
} }
@ -1739,7 +1734,7 @@ void calc_string_size( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index,
// calculates how many characters were cut off from the end of a buffer when reading // calculates how many characters were cut off from the end of a buffer when reading
// in UTF-8 encoded text // in UTF-8 encoded text
size_t calc_utf8_missing( _Inout_ sqlsrv_stmt* stmt, _In_reads_(buffer_end) const char* buffer, _In_ size_t buffer_end TSRMLS_DC ) size_t calc_utf8_missing( _Inout_ sqlsrv_stmt* stmt, _In_reads_(buffer_end) const char* buffer, _In_ size_t buffer_end )
{ {
const char* last_char = buffer + buffer_end - 1; const char* last_char = buffer + buffer_end - 1;
size_t need_to_read = 0; size_t need_to_read = 0;
@ -1778,11 +1773,11 @@ size_t calc_utf8_missing( _Inout_ sqlsrv_stmt* stmt, _In_reads_(buffer_end) cons
// the driver layer would have to calculate size of the field_value // the driver layer would have to calculate size of the field_value
// to decide the amount of memory allocation. // to decide the amount of memory allocation.
void core_get_field_common( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _Inout_ sqlsrv_phptype void core_get_field_common( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _Inout_ sqlsrv_phptype
sqlsrv_php_type, _Inout_updates_bytes_(*field_len) void*& field_value, _Inout_ SQLLEN* field_len TSRMLS_DC ) sqlsrv_php_type, _Inout_updates_bytes_(*field_len) void*& field_value, _Inout_ SQLLEN* field_len )
{ {
try { try {
close_active_stream( stmt TSRMLS_CC ); close_active_stream( stmt );
// make sure that fetch is called before trying to retrieve. // make sure that fetch is called before trying to retrieve.
CHECK_CUSTOM_ERROR( !stmt->fetch_called, stmt, SQLSRV_ERROR_FETCH_NOT_CALLED ) { CHECK_CUSTOM_ERROR( !stmt->fetch_called, stmt, SQLSRV_ERROR_FETCH_NOT_CALLED ) {
@ -1804,7 +1799,7 @@ void core_get_field_common( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_i
*field_value_temp = 0; *field_value_temp = 0;
SQLRETURN r = stmt->current_results->get_data( field_index + 1, SQL_C_LONG, field_value_temp, sizeof( SQLLEN ), SQLRETURN r = stmt->current_results->get_data( field_index + 1, SQL_C_LONG, field_value_temp, sizeof( SQLLEN ),
field_len, true /*handle_warning*/ TSRMLS_CC ); field_len, true /*handle_warning*/ );
CHECK_SQL_ERROR_OR_WARNING( r, stmt ) { CHECK_SQL_ERROR_OR_WARNING( r, stmt ) {
throw core::CoreException(); throw core::CoreException();
@ -1830,7 +1825,7 @@ void core_get_field_common( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_i
field_value_temp = static_cast<double*>( sqlsrv_malloc( sizeof( double ))); field_value_temp = static_cast<double*>( sqlsrv_malloc( sizeof( double )));
SQLRETURN r = stmt->current_results->get_data( field_index + 1, SQL_C_DOUBLE, field_value_temp, sizeof( double ), SQLRETURN r = stmt->current_results->get_data( field_index + 1, SQL_C_DOUBLE, field_value_temp, sizeof( double ),
field_len, true /*handle_warning*/ TSRMLS_CC ); field_len, true /*handle_warning*/ );
CHECK_SQL_ERROR_OR_WARNING( r, stmt ) { CHECK_SQL_ERROR_OR_WARNING( r, stmt ) {
throw core::CoreException(); throw core::CoreException();
@ -1852,7 +1847,7 @@ void core_get_field_common( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_i
case SQLSRV_PHPTYPE_STRING: case SQLSRV_PHPTYPE_STRING:
{ {
get_field_as_string( stmt, field_index, sqlsrv_php_type, field_value, field_len TSRMLS_CC ); get_field_as_string( stmt, field_index, sqlsrv_php_type, field_value, field_len );
break; break;
} }
@ -1868,7 +1863,7 @@ void core_get_field_common( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_i
field_value_temp = static_cast<char*>(sqlsrv_malloc(MAX_DATETIME_STRING_LEN)); field_value_temp = static_cast<char*>(sqlsrv_malloc(MAX_DATETIME_STRING_LEN));
memset(field_value_temp, '\0', MAX_DATETIME_STRING_LEN); memset(field_value_temp, '\0', MAX_DATETIME_STRING_LEN);
SQLRETURN r = stmt->current_results->get_data(field_index + 1, SQL_C_CHAR, field_value_temp, MAX_DATETIME_STRING_LEN, &field_len_temp, true TSRMLS_CC); SQLRETURN r = stmt->current_results->get_data(field_index + 1, SQL_C_CHAR, field_value_temp, MAX_DATETIME_STRING_LEN, &field_len_temp, true);
if (r == SQL_NO_DATA || field_len_temp == SQL_NULL_DATA) { if (r == SQL_NO_DATA || field_len_temp == SQL_NULL_DATA) {
field_value_temp.reset(); field_value_temp.reset();
@ -1950,7 +1945,7 @@ void core_get_field_common( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_i
// check_for_next_stream_parameter // check_for_next_stream_parameter
// see if there is another stream to be sent. Returns true and sets the stream as current in the statement structure, otherwise // see if there is another stream to be sent. Returns true and sets the stream as current in the statement structure, otherwise
// returns false // returns false
bool check_for_next_stream_parameter( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) bool check_for_next_stream_parameter( _Inout_ sqlsrv_stmt* stmt )
{ {
zend_ulong stream_index = 0; zend_ulong stream_index = 0;
SQLRETURN r = SQL_SUCCESS; SQLRETURN r = SQL_SUCCESS;
@ -1958,7 +1953,7 @@ bool check_for_next_stream_parameter( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC )
zval* param_z = NULL; zval* param_z = NULL;
// get the index into the streams_ht from the parameter data we set in core_sqlsrv_bind_param // get the index into the streams_ht from the parameter data we set in core_sqlsrv_bind_param
r = core::SQLParamData( stmt, reinterpret_cast<SQLPOINTER*>( &stream_index ) TSRMLS_CC ); r = core::SQLParamData( stmt, reinterpret_cast<SQLPOINTER*>( &stream_index ) );
// if no more data, we've exhausted the bound parameters, so return that we're done // if no more data, we've exhausted the bound parameters, so return that we're done
if( SQL_SUCCEEDED( r ) || r == SQL_NO_DATA ) { if( SQL_SUCCEEDED( r ) || r == SQL_NO_DATA ) {
@ -2046,7 +2041,7 @@ bool convert_input_param_to_utf16( _In_ zval* input_param_z, _Inout_ zval* conve
// returns the ODBC C type constant that matches the PHP type and encoding given // returns the ODBC C type constant that matches the PHP type and encoding given
SQLSMALLINT default_c_type( _Inout_ sqlsrv_stmt* stmt, _In_opt_ SQLULEN paramno, _In_ zval const* param_z, _In_ SQLSRV_ENCODING encoding TSRMLS_DC ) SQLSMALLINT default_c_type( _Inout_ sqlsrv_stmt* stmt, _In_opt_ SQLULEN paramno, _In_ zval const* param_z, _In_ SQLSRV_ENCODING encoding )
{ {
SQLSMALLINT sql_c_type = SQL_UNKNOWN_TYPE; SQLSMALLINT sql_c_type = SQL_UNKNOWN_TYPE;
int php_type = Z_TYPE_P( param_z ); int php_type = Z_TYPE_P( param_z );
@ -2117,7 +2112,7 @@ SQLSMALLINT default_c_type( _Inout_ sqlsrv_stmt* stmt, _In_opt_ SQLULEN paramno,
// given a zval and encoding, determine the appropriate sql type // given a zval and encoding, determine the appropriate sql type
void default_sql_type( _Inout_ sqlsrv_stmt* stmt, _In_opt_ SQLULEN paramno, _In_ zval* param_z, _In_ SQLSRV_ENCODING encoding, void default_sql_type( _Inout_ sqlsrv_stmt* stmt, _In_opt_ SQLULEN paramno, _In_ zval* param_z, _In_ SQLSRV_ENCODING encoding,
_Out_ SQLSMALLINT& sql_type TSRMLS_DC ) _Out_ SQLSMALLINT& sql_type )
{ {
sql_type = SQL_UNKNOWN_TYPE; sql_type = SQL_UNKNOWN_TYPE;
int php_type = Z_TYPE_P(param_z); int php_type = Z_TYPE_P(param_z);
@ -2195,7 +2190,7 @@ void default_sql_type( _Inout_ sqlsrv_stmt* stmt, _In_opt_ SQLULEN paramno, _In_
// given a zval and encoding, determine the appropriate column size, and decimal scale (if appropriate) // given a zval and encoding, determine the appropriate column size, and decimal scale (if appropriate)
void default_sql_size_and_scale( _Inout_ sqlsrv_stmt* stmt, _In_opt_ unsigned int paramno, _In_ zval* param_z, _In_ SQLSRV_ENCODING encoding, void default_sql_size_and_scale( _Inout_ sqlsrv_stmt* stmt, _In_opt_ unsigned int paramno, _In_ zval* param_z, _In_ SQLSRV_ENCODING encoding,
_Out_ SQLULEN& column_size, _Out_ SQLSMALLINT& decimal_digits TSRMLS_DC ) _Out_ SQLULEN& column_size, _Out_ SQLSMALLINT& decimal_digits )
{ {
int php_type = Z_TYPE_P( param_z ); int php_type = Z_TYPE_P( param_z );
column_size = 0; column_size = 0;
@ -2407,7 +2402,7 @@ void format_decimal_numbers(_In_ SQLSMALLINT decimals_places, _In_ SQLSMALLINT f
// parameters passed to SQLBindParameter. It also converts output strings from UTF-16 to UTF-8 if necessary. // parameters passed to SQLBindParameter. It also converts output strings from UTF-16 to UTF-8 if necessary.
// For integer or float parameters, it sets those to NULL if a NULL was returned by SQL Server // For integer or float parameters, it sets those to NULL if a NULL was returned by SQL Server
void finalize_output_parameters( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) void finalize_output_parameters( _Inout_ sqlsrv_stmt* stmt )
{ {
if (Z_ISUNDEF(stmt->output_params)) if (Z_ISUNDEF(stmt->output_params))
return; return;
@ -2558,7 +2553,7 @@ void finalize_output_parameters( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC )
} }
void get_field_as_string( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _Inout_ sqlsrv_phptype sqlsrv_php_type, void get_field_as_string( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _Inout_ sqlsrv_phptype sqlsrv_php_type,
_Inout_updates_bytes_(*field_len) void*& field_value, _Inout_ SQLLEN* field_len TSRMLS_DC ) _Inout_updates_bytes_(*field_len) void*& field_value, _Inout_ SQLLEN* field_len )
{ {
SQLRETURN r; SQLRETURN r;
SQLSMALLINT c_type; SQLSMALLINT c_type;
@ -2584,10 +2579,10 @@ void get_field_as_string( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_ind
sql_field_type = stmt->current_meta_data[field_index]->field_type; sql_field_type = stmt->current_meta_data[field_index]->field_type;
// Calculate the field size. // Calculate the field size.
calc_string_size( stmt, field_index, sql_field_type, sql_display_size TSRMLS_CC ); calc_string_size( stmt, field_index, sql_field_type, sql_display_size );
col_cache cache( sql_field_type, sql_display_size ); col_cache cache( sql_field_type, sql_display_size );
core::sqlsrv_zend_hash_index_update_mem( *stmt, Z_ARRVAL( stmt->col_cache ), field_index, &cache, sizeof( col_cache ) TSRMLS_CC ); core::sqlsrv_zend_hash_index_update_mem( *stmt, Z_ARRVAL( stmt->col_cache ), field_index, &cache, sizeof( col_cache ) );
} }
// Determine the correct encoding // Determine the correct encoding
@ -2626,7 +2621,7 @@ void get_field_as_string( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_ind
field_value_temp = static_cast<char*>( sqlsrv_malloc( field_len_temp + extra + 1 )); field_value_temp = static_cast<char*>( sqlsrv_malloc( field_len_temp + extra + 1 ));
r = stmt->current_results->get_data( field_index + 1, c_type, field_value_temp, ( field_len_temp + extra ), r = stmt->current_results->get_data( field_index + 1, c_type, field_value_temp, ( field_len_temp + extra ),
&field_len_temp, false /*handle_warning*/ TSRMLS_CC ); &field_len_temp, false /*handle_warning*/ );
CHECK_CUSTOM_ERROR(( r == SQL_NO_DATA ), stmt, SQLSRV_ERROR_NO_DATA, field_index ) { CHECK_CUSTOM_ERROR(( r == SQL_NO_DATA ), stmt, SQLSRV_ERROR_NO_DATA, field_index ) {
throw core::CoreException(); throw core::CoreException();
@ -2643,7 +2638,7 @@ void get_field_as_string( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_ind
SQLCHAR state[SQL_SQLSTATE_BUFSIZE] = {L'\0'}; SQLCHAR state[SQL_SQLSTATE_BUFSIZE] = {L'\0'};
SQLSMALLINT len = 0; SQLSMALLINT len = 0;
stmt->current_results->get_diag_field( 1, SQL_DIAG_SQLSTATE, state, SQL_SQLSTATE_BUFSIZE, &len TSRMLS_CC ); stmt->current_results->get_diag_field( 1, SQL_DIAG_SQLSTATE, state, SQL_SQLSTATE_BUFSIZE, &len );
// with Linux connection pooling may not get a truncated warning back but the actual field_len_temp // with Linux connection pooling may not get a truncated warning back but the actual field_len_temp
// can be greater than the initallen value. // can be greater than the initallen value.
@ -2673,7 +2668,7 @@ void get_field_as_string( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_ind
// Get the rest of the data. // Get the rest of the data.
r = stmt->current_results->get_data( field_index + 1, c_type, field_value_temp + initial_field_len, r = stmt->current_results->get_data( field_index + 1, c_type, field_value_temp + initial_field_len,
field_len_temp + extra, &dummy_field_len, false /*handle_warning*/ TSRMLS_CC ); field_len_temp + extra, &dummy_field_len, false /*handle_warning*/ );
// the last packet will contain the actual amount retrieved, not SQL_NO_TOTAL // the last packet will contain the actual amount retrieved, not SQL_NO_TOTAL
// so we calculate the actual length of the string with that. // so we calculate the actual length of the string with that.
if ( dummy_field_len != SQL_NO_TOTAL ) if ( dummy_field_len != SQL_NO_TOTAL )
@ -2683,7 +2678,7 @@ void get_field_as_string( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_ind
if( r == SQL_SUCCESS_WITH_INFO ) { if( r == SQL_SUCCESS_WITH_INFO ) {
core::SQLGetDiagField( stmt, 1, SQL_DIAG_SQLSTATE, state, SQL_SQLSTATE_BUFSIZE, &len core::SQLGetDiagField( stmt, 1, SQL_DIAG_SQLSTATE, state, SQL_SQLSTATE_BUFSIZE, &len
TSRMLS_CC ); );
} }
} while( r == SQL_SUCCESS_WITH_INFO && is_truncated_warning( state )); } while( r == SQL_SUCCESS_WITH_INFO && is_truncated_warning( state ));
@ -2698,7 +2693,7 @@ void get_field_as_string( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_ind
// Get the rest of the data. // Get the rest of the data.
r = stmt->current_results->get_data( field_index + 1, c_type, field_value_temp + intial_field_len, r = stmt->current_results->get_data( field_index + 1, c_type, field_value_temp + intial_field_len,
field_len_temp + extra, &dummy_field_len, true /*handle_warning*/ TSRMLS_CC ); field_len_temp + extra, &dummy_field_len, true /*handle_warning*/ );
field_len_temp += intial_field_len; field_len_temp += intial_field_len;
if( dummy_field_len == SQL_NULL_DATA ) { if( dummy_field_len == SQL_NULL_DATA ) {
@ -2750,7 +2745,7 @@ void get_field_as_string( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_ind
// get the data // get the data
r = stmt->current_results->get_data( field_index + 1, c_type, field_value_temp, sql_display_size, r = stmt->current_results->get_data( field_index + 1, c_type, field_value_temp, sql_display_size,
&field_len_temp, true /*handle_warning*/ TSRMLS_CC ); &field_len_temp, true /*handle_warning*/ );
CHECK_SQL_ERROR( r, stmt ) { CHECK_SQL_ERROR( r, stmt ) {
throw core::CoreException(); throw core::CoreException();
} }
@ -2828,7 +2823,7 @@ field_value = field_value_temp;
// return the option from the stmt_opts array that matches the key. If no option found, // return the option from the stmt_opts array that matches the key. If no option found,
// NULL is returned. // NULL is returned.
stmt_option const* get_stmt_option( sqlsrv_conn const* conn, _In_ zend_ulong key, _In_ const stmt_option stmt_opts[] TSRMLS_DC ) stmt_option const* get_stmt_option( sqlsrv_conn const* conn, _In_ zend_ulong key, _In_ const stmt_option stmt_opts[] )
{ {
for( int i = 0; stmt_opts[i].key != SQLSRV_STMT_OPTION_INVALID; ++i ) { for( int i = 0; stmt_opts[i].key != SQLSRV_STMT_OPTION_INVALID; ++i ) {
@ -2896,7 +2891,7 @@ bool is_valid_sqlsrv_phptype( _In_ sqlsrv_phptype type )
void resize_output_buffer_if_necessary( _Inout_ sqlsrv_stmt* stmt, _Inout_ zval* param_z, _In_ SQLULEN paramno, SQLSRV_ENCODING encoding, void resize_output_buffer_if_necessary( _Inout_ sqlsrv_stmt* stmt, _Inout_ zval* param_z, _In_ SQLULEN paramno, SQLSRV_ENCODING encoding,
_In_ SQLSMALLINT c_type, _In_ SQLSMALLINT sql_type, _In_ SQLULEN column_size, _In_ SQLSMALLINT decimal_digits, _In_ SQLSMALLINT c_type, _In_ SQLSMALLINT sql_type, _In_ SQLULEN column_size, _In_ SQLSMALLINT decimal_digits,
_Out_writes_(buffer_len) SQLPOINTER& buffer, _Out_ SQLLEN& buffer_len TSRMLS_DC ) _Out_writes_(buffer_len) SQLPOINTER& buffer, _Out_ SQLLEN& buffer_len )
{ {
SQLSRV_ASSERT( column_size != SQLSRV_UNKNOWN_SIZE, "column size should be set to a known value." ); SQLSRV_ASSERT( column_size != SQLSRV_UNKNOWN_SIZE, "column size should be set to a known value." );
buffer_len = Z_STRLEN_P( param_z ); buffer_len = Z_STRLEN_P( param_z );
@ -3124,7 +3119,7 @@ void adjustInputPrecision( _Inout_ zval* param_z, _In_ SQLSMALLINT decimal_digit
// while the query is executed and processed. They are saved in the statement so that // while the query is executed and processed. They are saved in the statement so that
// their reference count may be decremented later (after results are processed) // their reference count may be decremented later (after results are processed)
void save_output_param_for_later( _Inout_ sqlsrv_stmt* stmt, _Inout_ sqlsrv_output_param& param TSRMLS_DC ) void save_output_param_for_later( _Inout_ sqlsrv_stmt* stmt, _Inout_ sqlsrv_output_param& param )
{ {
HashTable* param_ht = Z_ARRVAL( stmt->output_params ); HashTable* param_ht = Z_ARRVAL( stmt->output_params );
zend_ulong paramno = static_cast<zend_ulong>( param.param_num ); zend_ulong paramno = static_cast<zend_ulong>( param.param_num );
@ -3135,9 +3130,9 @@ void save_output_param_for_later( _Inout_ sqlsrv_stmt* stmt, _Inout_ sqlsrv_outp
// send all the stream data // send all the stream data
void send_param_streams( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) void send_param_streams( _Inout_ sqlsrv_stmt* stmt )
{ {
while( core_sqlsrv_send_stream_packet( stmt TSRMLS_CC )) { } while( core_sqlsrv_send_stream_packet( stmt )) { }
} }

View file

@ -23,7 +23,7 @@ namespace {
// close a stream and free the PHP resources used by it // close a stream and free the PHP resources used by it
int sqlsrv_stream_close( _Inout_ php_stream* stream, int /*close_handle*/ TSRMLS_DC ) int sqlsrv_stream_close( _Inout_ php_stream* stream, int /*close_handle*/ )
{ {
sqlsrv_stream* ss = static_cast<sqlsrv_stream*>( stream->abstract ); sqlsrv_stream* ss = static_cast<sqlsrv_stream*>( stream->abstract );
SQLSRV_ASSERT( ss != NULL && ss->stmt != NULL, "sqlsrv_stream_close: sqlsrv_stream* ss was null." ); SQLSRV_ASSERT( ss != NULL && ss->stmt != NULL, "sqlsrv_stream_close: sqlsrv_stream* ss was null." );
@ -45,9 +45,9 @@ int sqlsrv_stream_close( _Inout_ php_stream* stream, int /*close_handle*/ TSRMLS
// set when sqlsrv_get_field is called by the user specifying which field type they want. // set when sqlsrv_get_field is called by the user specifying which field type they want.
#if PHP_VERSION_ID >= 70400 #if PHP_VERSION_ID >= 70400
ssize_t sqlsrv_stream_read(_Inout_ php_stream* stream, _Out_writes_bytes_(count) char* buf, _Inout_ size_t count TSRMLS_DC) ssize_t sqlsrv_stream_read(_Inout_ php_stream* stream, _Out_writes_bytes_(count) char* buf, _Inout_ size_t count)
#else #else
size_t sqlsrv_stream_read(_Inout_ php_stream* stream, _Out_writes_bytes_(count) char* buf, _Inout_ size_t count TSRMLS_DC) size_t sqlsrv_stream_read(_Inout_ php_stream* stream, _Out_writes_bytes_(count) char* buf, _Inout_ size_t count)
#endif #endif
{ {
SQLLEN read = 0; SQLLEN read = 0;
@ -94,7 +94,7 @@ size_t sqlsrv_stream_read(_Inout_ php_stream* stream, _Out_writes_bytes_(count)
} }
// Warnings will be handled below // Warnings will be handled below
SQLRETURN r = ss->stmt->current_results->get_data(ss->field_index + 1, c_type, get_data_buffer, count /*BufferLength*/, &read, false /*handle_warning*/ TSRMLS_CC); SQLRETURN r = ss->stmt->current_results->get_data(ss->field_index + 1, c_type, get_data_buffer, count /*BufferLength*/, &read, false /*handle_warning*/);
CHECK_SQL_ERROR( r, ss->stmt ) { CHECK_SQL_ERROR( r, ss->stmt ) {
stream->eof = 1; stream->eof = 1;
@ -114,7 +114,7 @@ size_t sqlsrv_stream_read(_Inout_ php_stream* stream, _Out_writes_bytes_(count)
SQLCHAR state[SQL_SQLSTATE_BUFSIZE] = {L'\0'}; SQLCHAR state[SQL_SQLSTATE_BUFSIZE] = {L'\0'};
SQLSMALLINT len = 0; SQLSMALLINT len = 0;
ss->stmt->current_results->get_diag_field( 1, SQL_DIAG_SQLSTATE, state, SQL_SQLSTATE_BUFSIZE, &len TSRMLS_CC ); ss->stmt->current_results->get_diag_field( 1, SQL_DIAG_SQLSTATE, state, SQL_SQLSTATE_BUFSIZE, &len );
if( read == SQL_NO_TOTAL ) { if( read == SQL_NO_TOTAL ) {
SQLSRV_ASSERT( is_truncated_warning( state ), "sqlsrv_stream_read: truncation warning was expected but it " SQLSRV_ASSERT( is_truncated_warning( state ), "sqlsrv_stream_read: truncation warning was expected but it "
@ -222,7 +222,7 @@ php_stream_ops sqlsrv_stream_ops = {
// return value. There is only one valid way to open a stream, using sqlsrv_get_field on // return value. There is only one valid way to open a stream, using sqlsrv_get_field on
// certain field types. A sqlsrv stream may only be opened in read mode. // certain field types. A sqlsrv stream may only be opened in read mode.
static php_stream* sqlsrv_stream_opener( _In_opt_ php_stream_wrapper* wrapper, _In_ const char*, _In_ const char* mode, static php_stream* sqlsrv_stream_opener( _In_opt_ php_stream_wrapper* wrapper, _In_ const char*, _In_ const char* mode,
_In_opt_ int options, _In_ zend_string **, php_stream_context* STREAMS_DC TSRMLS_DC ) _In_opt_ int options, _In_ zend_string **, php_stream_context* STREAMS_DC )
{ {
#if ZEND_DEBUG #if ZEND_DEBUG
@ -240,7 +240,7 @@ static php_stream* sqlsrv_stream_opener( _In_opt_ php_stream_wrapper* wrapper, _
// check for valid options // check for valid options
if( options != REPORT_ERRORS ) { if( options != REPORT_ERRORS ) {
php_stream_wrapper_log_error( wrapper, options TSRMLS_CC, "Invalid option: no options except REPORT_ERRORS may be specified with a sqlsrv stream" ); php_stream_wrapper_log_error( wrapper, options, "Invalid option: no options except REPORT_ERRORS may be specified with a sqlsrv stream" );
return NULL; return NULL;
} }

View file

@ -57,7 +57,7 @@ void log_activity(_In_opt_ const char* msg, _In_opt_ va_list* print_args)
std::copy(INTERNAL_FORMAT_ERROR, INTERNAL_FORMAT_ERROR + sizeof(INTERNAL_FORMAT_ERROR), log_msg); std::copy(INTERNAL_FORMAT_ERROR, INTERNAL_FORMAT_ERROR + sizeof(INTERNAL_FORMAT_ERROR), log_msg);
} }
php_log_err(log_msg TSRMLS_CC); php_log_err(log_msg);
} }
} }
@ -70,10 +70,10 @@ SQLCHAR SSPWARN[] = "01SSP";
// write to the php log if the severity and subsystem match the filters currently set in the INI or // write to the php log if the severity and subsystem match the filters currently set in the INI or
// the script (sqlsrv_configure). // the script (sqlsrv_configure).
void write_to_log( _In_ unsigned int severity TSRMLS_DC, _In_ const char* msg, ...) void write_to_log( _In_ unsigned int severity, _In_ const char* msg, ...)
{ {
SQLSRV_ASSERT( !(g_driver_severity == NULL), "Must register a driver checker function." ); SQLSRV_ASSERT( !(g_driver_severity == NULL), "Must register a driver checker function." );
if (!g_driver_severity(severity TSRMLS_CC)) { if (!g_driver_severity(severity)) {
return; return;
} }
@ -242,7 +242,7 @@ void convert_datetime_string_to_zval(_Inout_ sqlsrv_stmt* stmt, _In_opt_ char* i
params[0] = value_temp_z; params[0] = value_temp_z;
if (call_user_function(EG(function_table), NULL, &function_z, &out_zval, 1, if (call_user_function(EG(function_table), NULL, &function_z, &out_zval, 1,
params TSRMLS_CC) == FAILURE) { params) == FAILURE) {
THROW_CORE_ERROR(stmt, SQLSRV_ERROR_DATETIME_CONVERSION_FAILED); THROW_CORE_ERROR(stmt, SQLSRV_ERROR_DATETIME_CONVERSION_FAILED);
} }
@ -258,7 +258,7 @@ void convert_datetime_string_to_zval(_Inout_ sqlsrv_stmt* stmt, _In_opt_ char* i
// The fetch type determines if the indices are numeric, associative, or both. // The fetch type determines if the indices are numeric, associative, or both.
bool core_sqlsrv_get_odbc_error( _Inout_ sqlsrv_context& ctx, _In_ int record_number, _Inout_ sqlsrv_error_auto_ptr& error, _In_ logging_severity severity bool core_sqlsrv_get_odbc_error( _Inout_ sqlsrv_context& ctx, _In_ int record_number, _Inout_ sqlsrv_error_auto_ptr& error, _In_ logging_severity severity
TSRMLS_DC ) )
{ {
SQLHANDLE h = ctx.handle(); SQLHANDLE h = ctx.handle();
SQLSMALLINT h_type = ctx.handle_type(); SQLSMALLINT h_type = ctx.handle_type();
@ -361,7 +361,7 @@ bool core_sqlsrv_get_odbc_error( _Inout_ sqlsrv_context& ctx, _In_ int record_nu
// format and return a driver specfic error // format and return a driver specfic error
void core_sqlsrv_format_driver_error( _In_ sqlsrv_context& ctx, _In_ sqlsrv_error_const const* custom_error, void core_sqlsrv_format_driver_error( _In_ sqlsrv_context& ctx, _In_ sqlsrv_error_const const* custom_error,
_Out_ sqlsrv_error_auto_ptr& formatted_error, _In_ logging_severity severity TSRMLS_DC, _In_opt_ va_list* args ) _Out_ sqlsrv_error_auto_ptr& formatted_error, _In_ logging_severity severity, _In_opt_ va_list* args )
{ {
// allocate space for the formatted message // allocate space for the formatted message
formatted_error = new (sqlsrv_malloc( sizeof( sqlsrv_error ))) sqlsrv_error(); formatted_error = new (sqlsrv_malloc( sizeof( sqlsrv_error ))) sqlsrv_error();
@ -606,7 +606,7 @@ namespace data_classification {
*pptr = ptr; *pptr = ptr;
} }
USHORT fill_column_sensitivity_array(_Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT colno, _Inout_ zval *return_array TSRMLS_CC) USHORT fill_column_sensitivity_array(_Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT colno, _Inout_ zval *return_array)
{ {
sensitivity_metadata* meta = stmt->current_sensitivity_metadata; sensitivity_metadata* meta = stmt->current_sensitivity_metadata;
if (meta == NULL) { if (meta == NULL) {
@ -617,27 +617,27 @@ namespace data_classification {
zval data_classification; zval data_classification;
ZVAL_UNDEF(&data_classification); ZVAL_UNDEF(&data_classification);
core::sqlsrv_array_init(*stmt, &data_classification TSRMLS_CC ); core::sqlsrv_array_init(*stmt, &data_classification );
USHORT num_pairs = meta->columns_sensitivity[colno].num_pairs; USHORT num_pairs = meta->columns_sensitivity[colno].num_pairs;
if (num_pairs == 0) { if (num_pairs == 0) {
core::sqlsrv_add_assoc_zval(*stmt, return_array, DATA_CLASS, &data_classification TSRMLS_CC); core::sqlsrv_add_assoc_zval(*stmt, return_array, DATA_CLASS, &data_classification);
return 0; return 0;
} }
zval sensitivity_properties; zval sensitivity_properties;
ZVAL_UNDEF(&sensitivity_properties); ZVAL_UNDEF(&sensitivity_properties);
core::sqlsrv_array_init(*stmt, &sensitivity_properties TSRMLS_CC); core::sqlsrv_array_init(*stmt, &sensitivity_properties);
for (USHORT j = 0; j < num_pairs; j++) { for (USHORT j = 0; j < num_pairs; j++) {
zval label_array, infotype_array; zval label_array, infotype_array;
ZVAL_UNDEF(&label_array); ZVAL_UNDEF(&label_array);
ZVAL_UNDEF(&infotype_array); ZVAL_UNDEF(&infotype_array);
core::sqlsrv_array_init(*stmt, &label_array TSRMLS_CC); core::sqlsrv_array_init(*stmt, &label_array);
core::sqlsrv_array_init(*stmt, &infotype_array TSRMLS_CC); core::sqlsrv_array_init(*stmt, &infotype_array);
USHORT labelidx = meta->columns_sensitivity[colno].label_info_pairs[j].label_idx; USHORT labelidx = meta->columns_sensitivity[colno].label_info_pairs[j].label_idx;
USHORT typeidx = meta->columns_sensitivity[colno].label_info_pairs[j].infotype_idx; USHORT typeidx = meta->columns_sensitivity[colno].label_info_pairs[j].infotype_idx;
@ -647,22 +647,22 @@ namespace data_classification {
char *infotype = meta->infotypes[typeidx]->name; char *infotype = meta->infotypes[typeidx]->name;
char *infotype_id = meta->infotypes[typeidx]->id; char *infotype_id = meta->infotypes[typeidx]->id;
core::sqlsrv_add_assoc_string(*stmt, &label_array, NAME, label, 1 TSRMLS_CC); core::sqlsrv_add_assoc_string(*stmt, &label_array, NAME, label, 1);
core::sqlsrv_add_assoc_string(*stmt, &label_array, ID, label_id, 1 TSRMLS_CC); core::sqlsrv_add_assoc_string(*stmt, &label_array, ID, label_id, 1);
core::sqlsrv_add_assoc_zval(*stmt, &sensitivity_properties, LABEL, &label_array TSRMLS_CC); core::sqlsrv_add_assoc_zval(*stmt, &sensitivity_properties, LABEL, &label_array);
core::sqlsrv_add_assoc_string(*stmt, &infotype_array, NAME, infotype, 1 TSRMLS_CC); core::sqlsrv_add_assoc_string(*stmt, &infotype_array, NAME, infotype, 1);
core::sqlsrv_add_assoc_string(*stmt, &infotype_array, ID, infotype_id, 1 TSRMLS_CC); core::sqlsrv_add_assoc_string(*stmt, &infotype_array, ID, infotype_id, 1);
core::sqlsrv_add_assoc_zval(*stmt, &sensitivity_properties, INFOTYPE, &infotype_array TSRMLS_CC); core::sqlsrv_add_assoc_zval(*stmt, &sensitivity_properties, INFOTYPE, &infotype_array);
// add the pair of sensitivity properties to data_classification // add the pair of sensitivity properties to data_classification
core::sqlsrv_add_next_index_zval(*stmt, &data_classification, &sensitivity_properties TSRMLS_CC ); core::sqlsrv_add_next_index_zval(*stmt, &data_classification, &sensitivity_properties );
} }
// add data classfication as associative array // add data classfication as associative array
core::sqlsrv_add_assoc_zval(*stmt, return_array, DATA_CLASS, &data_classification TSRMLS_CC); core::sqlsrv_add_assoc_zval(*stmt, return_array, DATA_CLASS, &data_classification);
return num_pairs; return num_pairs;
} }

View file

@ -35,10 +35,8 @@ unsigned int current_log_subsystem = LOG_CONN;
struct date_as_string_func { struct date_as_string_func {
static void func( connection_option const* /*option*/, _In_ zval* value, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/ TSRMLS_DC ) static void func( connection_option const* /*option*/, _In_ zval* value, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/ )
{ {
TSRMLS_C; // show as used to avoid a warning
ss_sqlsrv_conn* ss_conn = static_cast<ss_sqlsrv_conn*>( conn ); ss_sqlsrv_conn* ss_conn = static_cast<ss_sqlsrv_conn*>( conn );
if( zend_is_true( value )) { if( zend_is_true( value )) {
@ -52,10 +50,8 @@ struct date_as_string_func {
struct format_decimals_func struct format_decimals_func
{ {
static void func(connection_option const* /*option*/, _In_ zval* value, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/ TSRMLS_DC) static void func(connection_option const* /*option*/, _In_ zval* value, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/)
{ {
TSRMLS_C; // show as used to avoid a warning
ss_sqlsrv_conn* ss_conn = static_cast<ss_sqlsrv_conn*>(conn); ss_sqlsrv_conn* ss_conn = static_cast<ss_sqlsrv_conn*>(conn);
if (zend_is_true(value)) { if (zend_is_true(value)) {
@ -70,10 +66,8 @@ struct format_decimals_func
struct decimal_places_func struct decimal_places_func
{ {
static void func(connection_option const* /*option*/, _In_ zval* value, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/ TSRMLS_DC) static void func(connection_option const* /*option*/, _In_ zval* value, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/)
{ {
TSRMLS_C; // show as used to avoid a warning
// first check if the input is an integer // first check if the input is an integer
if (Z_TYPE_P(value) != IS_LONG) { if (Z_TYPE_P(value) != IS_LONG) {
THROW_SS_ERROR(conn, SQLSRV_ERROR_INVALID_DECIMAL_PLACES); THROW_SS_ERROR(conn, SQLSRV_ERROR_INVALID_DECIMAL_PLACES);
@ -91,7 +85,7 @@ struct decimal_places_func
struct conn_char_set_func { struct conn_char_set_func {
static void func( connection_option const* /*option*/, _Inout_ zval* value, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/ TSRMLS_DC ) static void func( connection_option const* /*option*/, _Inout_ zval* value, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/ )
{ {
convert_to_string( value ); convert_to_string( value );
const char* encoding = Z_STRVAL_P( value ); const char* encoding = Z_STRVAL_P( value );
@ -121,9 +115,8 @@ struct conn_char_set_func {
struct bool_conn_str_func { struct bool_conn_str_func {
static void func( _In_ connection_option const* option, _In_ zval* value, sqlsrv_conn* /*conn*/, _Out_ std::string& conn_str TSRMLS_DC ) static void func( _In_ connection_option const* option, _In_ zval* value, sqlsrv_conn* /*conn*/, _Out_ std::string& conn_str )
{ {
TSRMLS_C;
char const* val_str; char const* val_str;
if( zend_is_true( value )) { if( zend_is_true( value )) {
val_str = "yes"; val_str = "yes";
@ -140,9 +133,8 @@ struct bool_conn_str_func {
struct int_conn_str_func { struct int_conn_str_func {
static void func( _In_ connection_option const* option, _In_ zval* value, sqlsrv_conn* /*conn*/, _Out_ std::string& conn_str TSRMLS_DC ) static void func( _In_ connection_option const* option, _In_ zval* value, sqlsrv_conn* /*conn*/, _Out_ std::string& conn_str )
{ {
TSRMLS_C;
SQLSRV_ASSERT( Z_TYPE_P( value ) == IS_LONG, "An integer is expected for this keyword" ) SQLSRV_ASSERT( Z_TYPE_P( value ) == IS_LONG, "An integer is expected for this keyword" )
std::string val_str = std::to_string( Z_LVAL_P( value )); std::string val_str = std::to_string( Z_LVAL_P( value ));
@ -157,11 +149,11 @@ struct int_conn_str_func {
template <unsigned int Attr> template <unsigned int Attr>
struct int_conn_attr_func { struct int_conn_attr_func {
static void func( connection_option const* /*option*/, _In_ zval* value, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/ TSRMLS_DC ) static void func( connection_option const* /*option*/, _In_ zval* value, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/ )
{ {
try { try {
core::SQLSetConnectAttr( conn, Attr, reinterpret_cast<SQLPOINTER>( Z_LVAL_P( value )), SQL_IS_UINTEGER TSRMLS_CC ); core::SQLSetConnectAttr( conn, Attr, reinterpret_cast<SQLPOINTER>( Z_LVAL_P( value )), SQL_IS_UINTEGER );
} }
catch( core::CoreException& ) { catch( core::CoreException& ) {
throw; throw;
@ -172,10 +164,10 @@ struct int_conn_attr_func {
template <unsigned int Attr> template <unsigned int Attr>
struct bool_conn_attr_func { struct bool_conn_attr_func {
static void func( connection_option const* /*option*/, _In_ zval* value, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/ TSRMLS_DC ) static void func( connection_option const* /*option*/, _In_ zval* value, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/ )
{ {
try { try {
core::SQLSetConnectAttr(conn, Attr, reinterpret_cast<SQLPOINTER>((zend_long)zend_is_true(value)), SQL_IS_UINTEGER TSRMLS_CC); core::SQLSetConnectAttr(conn, Attr, reinterpret_cast<SQLPOINTER>((zend_long)zend_is_true(value)), SQL_IS_UINTEGER);
} }
catch( core::CoreException& ) { catch( core::CoreException& ) {
@ -187,15 +179,15 @@ struct bool_conn_attr_func {
//// *** internal functions *** //// *** internal functions ***
void sqlsrv_conn_close_stmts( _Inout_ ss_sqlsrv_conn* conn TSRMLS_DC ); void sqlsrv_conn_close_stmts( _Inout_ ss_sqlsrv_conn* conn );
void validate_conn_options( _Inout_ sqlsrv_context& ctx, _In_ zval* user_options_z, _Inout_ char** uid, _Inout_ char** pwd, void validate_conn_options( _Inout_ sqlsrv_context& ctx, _In_ zval* user_options_z, _Inout_ char** uid, _Inout_ char** pwd,
_Inout_ HashTable* ss_conn_options_ht TSRMLS_DC ); _Inout_ HashTable* ss_conn_options_ht );
void validate_stmt_options( _Inout_ sqlsrv_context& ctx, _Inout_ zval* stmt_options, _Inout_ HashTable* ss_stmt_options_ht TSRMLS_DC ); void validate_stmt_options( _Inout_ sqlsrv_context& ctx, _Inout_ zval* stmt_options, _Inout_ HashTable* ss_stmt_options_ht );
void add_conn_option_key( _Inout_ sqlsrv_context& ctx, _In_ zend_string* key, _In_ size_t key_len, void add_conn_option_key( _Inout_ sqlsrv_context& ctx, _In_ zend_string* key, _In_ size_t key_len,
_Inout_ HashTable* options_ht, _Inout_ zval* data TSRMLS_DC ); _Inout_ HashTable* options_ht, _Inout_ zval* data );
void add_stmt_option_key( _Inout_ sqlsrv_context& ctx, _In_ zend_string* key, _In_ size_t key_len, _Inout_ HashTable* options_ht, _Inout_ zval* data TSRMLS_DC ); void add_stmt_option_key( _Inout_ sqlsrv_context& ctx, _In_ zend_string* key, _In_ size_t key_len, _Inout_ HashTable* options_ht, _Inout_ zval* data );
int get_conn_option_key( _Inout_ sqlsrv_context& ctx, _In_ zend_string* key, _In_ size_t key_len, _Inout_ zval const* value_z TSRMLS_DC ); int get_conn_option_key( _Inout_ sqlsrv_context& ctx, _In_ zend_string* key, _In_ size_t key_len, _Inout_ zval const* value_z );
int get_stmt_option_key( _In_ zend_string* key, _In_ size_t key_len TSRMLS_DC ); int get_stmt_option_key( _In_ zend_string* key, _In_ size_t key_len );
} }
@ -633,7 +625,7 @@ PHP_FUNCTION ( sqlsrv_connect )
g_ss_henv_cp->set_func(_FN_); g_ss_henv_cp->set_func(_FN_);
g_ss_henv_ncp->set_func(_FN_); g_ss_henv_ncp->set_func(_FN_);
reset_errors( TSRMLS_C ); reset_errors();
const char* server = NULL; const char* server = NULL;
zval* options_z = NULL; zval* options_z = NULL;
@ -643,7 +635,7 @@ PHP_FUNCTION ( sqlsrv_connect )
zval conn_z; zval conn_z;
ZVAL_UNDEF(&conn_z); ZVAL_UNDEF(&conn_z);
// get the server name and connection options // get the server name and connection options
int result = zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "s|a", &server, &server_len, &options_z ); int result = zend_parse_parameters( ZEND_NUM_ARGS(), "s|a", &server, &server_len, &options_z );
CHECK_CUSTOM_ERROR(( result == FAILURE ), *g_ss_henv_cp, SS_SQLSRV_ERROR_INVALID_FUNCTION_PARAMETER, "sqlsrv_connect" ) { CHECK_CUSTOM_ERROR(( result == FAILURE ), *g_ss_henv_cp, SS_SQLSRV_ERROR_INVALID_FUNCTION_PARAMETER, "sqlsrv_connect" ) {
RETURN_FALSE; RETURN_FALSE;
@ -659,26 +651,26 @@ PHP_FUNCTION ( sqlsrv_connect )
ALLOC_HASHTABLE( ss_conn_options_ht ); ALLOC_HASHTABLE( ss_conn_options_ht );
core::sqlsrv_zend_hash_init( *g_ss_henv_cp, ss_conn_options_ht, 10 /* # of buckets */, core::sqlsrv_zend_hash_init( *g_ss_henv_cp, ss_conn_options_ht, 10 /* # of buckets */,
ZVAL_PTR_DTOR, 0 /*persistent*/ TSRMLS_CC ); ZVAL_PTR_DTOR, 0 /*persistent*/ );
// Either of g_ss_henv_cp or g_ss_henv_ncp can be used to propagate the error. // Either of g_ss_henv_cp or g_ss_henv_ncp can be used to propagate the error.
::validate_conn_options( *g_ss_henv_cp, options_z, &uid, &pwd, ss_conn_options_ht TSRMLS_CC ); ::validate_conn_options( *g_ss_henv_cp, options_z, &uid, &pwd, ss_conn_options_ht );
// call the core connect function // call the core connect function
conn = static_cast<ss_sqlsrv_conn*>( core_sqlsrv_connect( *g_ss_henv_cp, *g_ss_henv_ncp, &core::allocate_conn<ss_sqlsrv_conn>, conn = static_cast<ss_sqlsrv_conn*>( core_sqlsrv_connect( *g_ss_henv_cp, *g_ss_henv_ncp, &core::allocate_conn<ss_sqlsrv_conn>,
server, uid, pwd, ss_conn_options_ht, ss_error_handler, server, uid, pwd, ss_conn_options_ht, ss_error_handler,
SS_CONN_OPTS, NULL, "sqlsrv_connect" TSRMLS_CC )); SS_CONN_OPTS, NULL, "sqlsrv_connect" ));
SQLSRV_ASSERT( conn != NULL, "sqlsrv_connect: Invalid connection returned. Exception should have been thrown." ); SQLSRV_ASSERT( conn != NULL, "sqlsrv_connect: Invalid connection returned. Exception should have been thrown." );
// create a bunch of statements // create a bunch of statements
ALLOC_HASHTABLE( stmts ); ALLOC_HASHTABLE( stmts );
core::sqlsrv_zend_hash_init( *g_ss_henv_cp, stmts, 5, NULL /* dtor */, 0 /* persistent */ TSRMLS_CC ); core::sqlsrv_zend_hash_init( *g_ss_henv_cp, stmts, 5, NULL /* dtor */, 0 /* persistent */ );
// register the connection with the PHP runtime // register the connection with the PHP runtime
ss::zend_register_resource(conn_z, conn, ss_sqlsrv_conn::descriptor, ss_sqlsrv_conn::resource_name TSRMLS_CC); ss::zend_register_resource(conn_z, conn, ss_sqlsrv_conn::descriptor, ss_sqlsrv_conn::resource_name);
conn->stmts = stmts; conn->stmts = stmts;
stmts.transferred(); stmts.transferred();
@ -739,7 +731,7 @@ PHP_FUNCTION( sqlsrv_begin_transaction )
try { try {
core_sqlsrv_begin_transaction( conn TSRMLS_CC ); core_sqlsrv_begin_transaction( conn );
conn->in_transaction = true; conn->in_transaction = true;
RETURN_TRUE; RETURN_TRUE;
} }
@ -778,7 +770,7 @@ PHP_FUNCTION( sqlsrv_close )
ss_sqlsrv_conn* conn = NULL; ss_sqlsrv_conn* conn = NULL;
sqlsrv_context_auto_ptr error_ctx; sqlsrv_context_auto_ptr error_ctx;
reset_errors( TSRMLS_C ); reset_errors();
try { try {
@ -786,10 +778,10 @@ PHP_FUNCTION( sqlsrv_close )
error_ctx = new (sqlsrv_malloc( sizeof( sqlsrv_context ))) sqlsrv_context( 0, ss_error_handler, NULL ); error_ctx = new (sqlsrv_malloc( sizeof( sqlsrv_context ))) sqlsrv_context( 0, ss_error_handler, NULL );
error_ctx->set_func(_FN_); error_ctx->set_func(_FN_);
if( zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &conn_r) == FAILURE ) { if( zend_parse_parameters(ZEND_NUM_ARGS(), "r", &conn_r) == FAILURE ) {
// Check if it was a zval // Check if it was a zval
int zr = zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "z", &conn_r ); int zr = zend_parse_parameters( ZEND_NUM_ARGS(), "z", &conn_r );
CHECK_CUSTOM_ERROR(( zr == FAILURE ), error_ctx, SS_SQLSRV_ERROR_INVALID_FUNCTION_PARAMETER, _FN_ ) { CHECK_CUSTOM_ERROR(( zr == FAILURE ), error_ctx, SS_SQLSRV_ERROR_INVALID_FUNCTION_PARAMETER, _FN_ ) {
throw ss::SSException(); throw ss::SSException();
} }
@ -803,7 +795,7 @@ PHP_FUNCTION( sqlsrv_close )
} }
} }
SQLSRV_ASSERT( conn_r != NULL, "sqlsrv_close: conn_r was null" ); SQLSRV_ASSERT( conn_r != NULL, "sqlsrv_close: conn_r was null" );
conn = static_cast<ss_sqlsrv_conn*>( zend_fetch_resource( Z_RES_P( conn_r ) TSRMLS_CC, ss_sqlsrv_conn::resource_name, ss_sqlsrv_conn::descriptor )); conn = static_cast<ss_sqlsrv_conn*>( zend_fetch_resource( Z_RES_P( conn_r ), ss_sqlsrv_conn::resource_name, ss_sqlsrv_conn::descriptor ));
// if sqlsrv_close was called on an already closed connection then we just return success. // if sqlsrv_close was called on an already closed connection then we just return success.
if ( Z_RES_TYPE_P( conn_r ) == RSRC_INVALID_TYPE) { if ( Z_RES_TYPE_P( conn_r ) == RSRC_INVALID_TYPE) {
@ -842,7 +834,7 @@ PHP_FUNCTION( sqlsrv_close )
} }
} }
void __cdecl sqlsrv_conn_dtor( _Inout_ zend_resource *rsrc TSRMLS_DC ) void __cdecl sqlsrv_conn_dtor( _Inout_ zend_resource *rsrc )
{ {
// Without sqlsrv_close(), this function is invoked by php during the final clean up stage. // Without sqlsrv_close(), this function is invoked by php during the final clean up stage.
// To prevent memory/resource leaks, no more logging at this point. // To prevent memory/resource leaks, no more logging at this point.
@ -855,10 +847,10 @@ void __cdecl sqlsrv_conn_dtor( _Inout_ zend_resource *rsrc TSRMLS_DC )
conn->set_func(__func__); conn->set_func(__func__);
// close all statements associated with the connection. // close all statements associated with the connection.
sqlsrv_conn_close_stmts( conn TSRMLS_CC ); sqlsrv_conn_close_stmts( conn );
// close the connection itself. // close the connection itself.
core_sqlsrv_close( conn TSRMLS_CC ); core_sqlsrv_close( conn );
rsrc->ptr = NULL; rsrc->ptr = NULL;
} }
@ -901,7 +893,7 @@ PHP_FUNCTION( sqlsrv_commit )
try { try {
conn->in_transaction = false; conn->in_transaction = false;
core_sqlsrv_commit( conn TSRMLS_CC ); core_sqlsrv_commit( conn );
RETURN_TRUE; RETURN_TRUE;
} }
@ -955,7 +947,7 @@ PHP_FUNCTION( sqlsrv_rollback )
try { try {
conn->in_transaction = false; conn->in_transaction = false;
core_sqlsrv_rollback( conn TSRMLS_CC ); core_sqlsrv_rollback( conn );
RETURN_TRUE; RETURN_TRUE;
} }
catch( core::CoreException& ){ catch( core::CoreException& ){
@ -982,13 +974,13 @@ PHP_FUNCTION( sqlsrv_client_info )
try { try {
core_sqlsrv_get_client_info( conn, return_value TSRMLS_CC ); core_sqlsrv_get_client_info( conn, return_value );
// Add the sqlsrv driver's file version // Add the sqlsrv driver's file version
//Declarations below eliminate compiler warnings about string constant to char* conversions //Declarations below eliminate compiler warnings about string constant to char* conversions
const char* extver = "ExtensionVer"; const char* extver = "ExtensionVer";
std::string filever = VER_FILEVERSION_STR; std::string filever = VER_FILEVERSION_STR;
core::sqlsrv_add_assoc_string( *conn, return_value, extver, &filever[0], 1 /*duplicate*/ TSRMLS_CC ); core::sqlsrv_add_assoc_string( *conn, return_value, extver, &filever[0], 1 /*duplicate*/ );
} }
catch( core::CoreException& ) { catch( core::CoreException& ) {
@ -1024,7 +1016,7 @@ PHP_FUNCTION( sqlsrv_server_info )
ss_sqlsrv_conn* conn = NULL; ss_sqlsrv_conn* conn = NULL;
PROCESS_PARAMS( conn, "r", _FN_, 0 ); PROCESS_PARAMS( conn, "r", _FN_, 0 );
core_sqlsrv_get_server_info( conn, return_value TSRMLS_CC ); core_sqlsrv_get_server_info( conn, return_value );
} }
catch( core::CoreException& ) { catch( core::CoreException& ) {
@ -1093,9 +1085,9 @@ PHP_FUNCTION( sqlsrv_prepare )
// Initialize the options array to be passed to the core layer // Initialize the options array to be passed to the core layer
ALLOC_HASHTABLE( ss_stmt_options_ht ); ALLOC_HASHTABLE( ss_stmt_options_ht );
core::sqlsrv_zend_hash_init( *conn , ss_stmt_options_ht, 5 /* # of buckets */, core::sqlsrv_zend_hash_init( *conn , ss_stmt_options_ht, 5 /* # of buckets */,
ZVAL_PTR_DTOR, 0 /*persistent*/ TSRMLS_CC ); ZVAL_PTR_DTOR, 0 /*persistent*/ );
validate_stmt_options( *conn, options_z, ss_stmt_options_ht TSRMLS_CC ); validate_stmt_options( *conn, options_z, ss_stmt_options_ht );
} }
@ -1114,9 +1106,9 @@ PHP_FUNCTION( sqlsrv_prepare )
stmt = static_cast<ss_sqlsrv_stmt*>( core_sqlsrv_create_stmt( conn, core::allocate_stmt<ss_sqlsrv_stmt>, stmt = static_cast<ss_sqlsrv_stmt*>( core_sqlsrv_create_stmt( conn, core::allocate_stmt<ss_sqlsrv_stmt>,
ss_stmt_options_ht, SS_STMT_OPTS, ss_stmt_options_ht, SS_STMT_OPTS,
ss_error_handler, NULL TSRMLS_CC ) ); ss_error_handler, NULL ) );
core_sqlsrv_prepare( stmt, sql, sql_len TSRMLS_CC ); core_sqlsrv_prepare( stmt, sql, sql_len );
if (params_z) { if (params_z) {
stmt->params_z = (zval *)sqlsrv_malloc(sizeof(zval)); stmt->params_z = (zval *)sqlsrv_malloc(sizeof(zval));
@ -1126,13 +1118,13 @@ PHP_FUNCTION( sqlsrv_prepare )
stmt->prepared = true; stmt->prepared = true;
// register the statement with the PHP runtime // register the statement with the PHP runtime
ss::zend_register_resource( stmt_z, stmt, ss_sqlsrv_stmt::descriptor, ss_sqlsrv_stmt::resource_name TSRMLS_CC ); ss::zend_register_resource( stmt_z, stmt, ss_sqlsrv_stmt::descriptor, ss_sqlsrv_stmt::resource_name );
// store the resource id with the connection so the connection // store the resource id with the connection so the connection
// can release this statement when it closes. // can release this statement when it closes.
zend_long next_index = zend_hash_next_free_element( conn->stmts ); zend_long next_index = zend_hash_next_free_element( conn->stmts );
core::sqlsrv_zend_hash_index_update(*conn, conn->stmts, next_index, &stmt_z TSRMLS_CC); core::sqlsrv_zend_hash_index_update(*conn, conn->stmts, next_index, &stmt_z);
stmt->conn_index = next_index; stmt->conn_index = next_index;
@ -1150,7 +1142,7 @@ PHP_FUNCTION( sqlsrv_prepare )
stmt->~ss_sqlsrv_stmt(); stmt->~ss_sqlsrv_stmt();
} }
if (!Z_ISUNDEF(stmt_z)) { if (!Z_ISUNDEF(stmt_z)) {
free_stmt_resource(&stmt_z TSRMLS_CC); free_stmt_resource(&stmt_z);
} }
RETURN_FALSE; RETURN_FALSE;
@ -1216,9 +1208,9 @@ PHP_FUNCTION( sqlsrv_query )
// Initialize the options array to be passed to the core layer // Initialize the options array to be passed to the core layer
ALLOC_HASHTABLE( ss_stmt_options_ht ); ALLOC_HASHTABLE( ss_stmt_options_ht );
core::sqlsrv_zend_hash_init( *conn , ss_stmt_options_ht, 5 /* # of buckets */, ZVAL_PTR_DTOR, core::sqlsrv_zend_hash_init( *conn , ss_stmt_options_ht, 5 /* # of buckets */, ZVAL_PTR_DTOR,
0 /*persistent*/ TSRMLS_CC ); 0 /*persistent*/ );
validate_stmt_options( *conn, options_z, ss_stmt_options_ht TSRMLS_CC ); validate_stmt_options( *conn, options_z, ss_stmt_options_ht );
} }
if( params_z && Z_TYPE_P( params_z ) != IS_ARRAY ) { if( params_z && Z_TYPE_P( params_z ) != IS_ARRAY ) {
@ -1236,7 +1228,7 @@ PHP_FUNCTION( sqlsrv_query )
stmt = static_cast<ss_sqlsrv_stmt*>( core_sqlsrv_create_stmt( conn, core::allocate_stmt<ss_sqlsrv_stmt>, stmt = static_cast<ss_sqlsrv_stmt*>( core_sqlsrv_create_stmt( conn, core::allocate_stmt<ss_sqlsrv_stmt>,
ss_stmt_options_ht, SS_STMT_OPTS, ss_stmt_options_ht, SS_STMT_OPTS,
ss_error_handler, NULL TSRMLS_CC ) ); ss_error_handler, NULL ) );
if( params_z ) { if( params_z ) {
stmt->params_z = (zval *)sqlsrv_malloc(sizeof(zval)); stmt->params_z = (zval *)sqlsrv_malloc(sizeof(zval));
@ -1245,18 +1237,18 @@ PHP_FUNCTION( sqlsrv_query )
stmt->set_func( "sqlsrv_query" ); stmt->set_func( "sqlsrv_query" );
bind_params( stmt TSRMLS_CC ); bind_params( stmt );
// execute the statement // execute the statement
core_sqlsrv_execute( stmt TSRMLS_CC, sql, static_cast<int>( sql_len ) ); core_sqlsrv_execute( stmt, sql, static_cast<int>( sql_len ) );
// register the statement with the PHP runtime // register the statement with the PHP runtime
ss::zend_register_resource(stmt_z, stmt, ss_sqlsrv_stmt::descriptor, ss_sqlsrv_stmt::resource_name TSRMLS_CC); ss::zend_register_resource(stmt_z, stmt, ss_sqlsrv_stmt::descriptor, ss_sqlsrv_stmt::resource_name);
// store the resource id with the connection so the connection // store the resource id with the connection so the connection
// can release this statement when it closes. // can release this statement when it closes.
zend_ulong next_index = zend_hash_next_free_element( conn->stmts ); zend_ulong next_index = zend_hash_next_free_element( conn->stmts );
core::sqlsrv_zend_hash_index_update(*conn, conn->stmts, next_index, &stmt_z TSRMLS_CC); core::sqlsrv_zend_hash_index_update(*conn, conn->stmts, next_index, &stmt_z);
stmt->conn_index = next_index; stmt->conn_index = next_index;
stmt.transferred(); stmt.transferred();
@ -1271,7 +1263,7 @@ PHP_FUNCTION( sqlsrv_query )
stmt->~ss_sqlsrv_stmt(); stmt->~ss_sqlsrv_stmt();
} }
if (!Z_ISUNDEF(stmt_z)) { if (!Z_ISUNDEF(stmt_z)) {
free_stmt_resource(&stmt_z TSRMLS_CC); free_stmt_resource(&stmt_z);
} }
RETURN_FALSE; RETURN_FALSE;
@ -1282,7 +1274,7 @@ PHP_FUNCTION( sqlsrv_query )
} }
} }
void free_stmt_resource( _Inout_ zval* stmt_z TSRMLS_DC ) void free_stmt_resource( _Inout_ zval* stmt_z )
{ {
if( FAILURE == zend_list_close( Z_RES_P( stmt_z ))) { if( FAILURE == zend_list_close( Z_RES_P( stmt_z ))) {
LOG(SEV_ERROR, "Failed to remove stmt resource %1!d!", Z_RES_HANDLE_P(stmt_z)); LOG(SEV_ERROR, "Failed to remove stmt resource %1!d!", Z_RES_HANDLE_P(stmt_z));
@ -1298,7 +1290,7 @@ namespace {
// must close all statement handles opened by this connection before closing the connection // must close all statement handles opened by this connection before closing the connection
// no errors are returned, since close should always succeed // no errors are returned, since close should always succeed
void sqlsrv_conn_close_stmts( _Inout_ ss_sqlsrv_conn* conn TSRMLS_DC ) void sqlsrv_conn_close_stmts( _Inout_ ss_sqlsrv_conn* conn )
{ {
//pre-condition check //pre-condition check
SQLSRV_ASSERT(( conn->handle() != NULL ), "sqlsrv_conn_close_stmts: Connection handle is NULL. Trying to destroy an " SQLSRV_ASSERT(( conn->handle() != NULL ), "sqlsrv_conn_close_stmts: Connection handle is NULL. Trying to destroy an "
@ -1346,7 +1338,7 @@ void sqlsrv_conn_close_stmts( _Inout_ ss_sqlsrv_conn* conn TSRMLS_DC )
conn->stmts = NULL; conn->stmts = NULL;
} }
int get_conn_option_key( _Inout_ sqlsrv_context& ctx, _In_ zend_string* key, _In_ size_t key_len, _Inout_ zval const* value_z TSRMLS_DC ) int get_conn_option_key( _Inout_ sqlsrv_context& ctx, _In_ zend_string* key, _In_ size_t key_len, _Inout_ zval const* value_z )
{ {
for( int i=0; SS_CONN_OPTS[i].conn_option_key != SQLSRV_CONN_OPTION_INVALID; ++i ) for( int i=0; SS_CONN_OPTS[i].conn_option_key != SQLSRV_CONN_OPTION_INVALID; ++i )
{ {
@ -1407,7 +1399,7 @@ int get_conn_option_key( _Inout_ sqlsrv_context& ctx, _In_ zend_string* key, _In
return SQLSRV_CONN_OPTION_INVALID; return SQLSRV_CONN_OPTION_INVALID;
} }
int get_stmt_option_key( _In_ zend_string* key, _In_ size_t key_len TSRMLS_DC ) int get_stmt_option_key( _In_ zend_string* key, _In_ size_t key_len )
{ {
for( int i = 0; SS_STMT_OPTS[i].key != SQLSRV_STMT_OPTION_INVALID; ++i ) for( int i = 0; SS_STMT_OPTS[i].key != SQLSRV_STMT_OPTION_INVALID; ++i )
{ {
@ -1419,9 +1411,9 @@ int get_stmt_option_key( _In_ zend_string* key, _In_ size_t key_len TSRMLS_DC )
} }
void add_stmt_option_key( _Inout_ sqlsrv_context& ctx, _In_ zend_string* key, _In_ size_t key_len, void add_stmt_option_key( _Inout_ sqlsrv_context& ctx, _In_ zend_string* key, _In_ size_t key_len,
_Inout_ HashTable* options_ht, _Inout_ zval* data TSRMLS_DC ) _Inout_ HashTable* options_ht, _Inout_ zval* data )
{ {
int option_key = ::get_stmt_option_key( key, key_len TSRMLS_CC ); int option_key = ::get_stmt_option_key( key, key_len );
CHECK_CUSTOM_ERROR((option_key == SQLSRV_STMT_OPTION_INVALID ), ctx, SQLSRV_ERROR_INVALID_OPTION_KEY, ZSTR_VAL( key ) ) { CHECK_CUSTOM_ERROR((option_key == SQLSRV_STMT_OPTION_INVALID ), ctx, SQLSRV_ERROR_INVALID_OPTION_KEY, ZSTR_VAL( key ) ) {
@ -1429,27 +1421,27 @@ void add_stmt_option_key( _Inout_ sqlsrv_context& ctx, _In_ zend_string* key, _I
} }
Z_TRY_ADDREF_P(data); // inc the ref count since this is going into the options_ht too. Z_TRY_ADDREF_P(data); // inc the ref count since this is going into the options_ht too.
core::sqlsrv_zend_hash_index_update( ctx, options_ht, option_key, data TSRMLS_CC ); core::sqlsrv_zend_hash_index_update( ctx, options_ht, option_key, data );
} }
void add_conn_option_key( _Inout_ sqlsrv_context& ctx, _In_ zend_string* key, _In_ size_t key_len, void add_conn_option_key( _Inout_ sqlsrv_context& ctx, _In_ zend_string* key, _In_ size_t key_len,
_Inout_ HashTable* options_ht, _Inout_ zval* data TSRMLS_DC ) _Inout_ HashTable* options_ht, _Inout_ zval* data )
{ {
int option_key = ::get_conn_option_key( ctx, key, key_len, data TSRMLS_CC ); int option_key = ::get_conn_option_key( ctx, key, key_len, data );
CHECK_CUSTOM_ERROR((option_key == SQLSRV_STMT_OPTION_INVALID ), ctx, SS_SQLSRV_ERROR_INVALID_OPTION, ZSTR_VAL( key ) ) { CHECK_CUSTOM_ERROR((option_key == SQLSRV_STMT_OPTION_INVALID ), ctx, SS_SQLSRV_ERROR_INVALID_OPTION, ZSTR_VAL( key ) ) {
throw ss::SSException(); throw ss::SSException();
} }
Z_TRY_ADDREF_P(data); // inc the ref count since this is going into the options_ht too. Z_TRY_ADDREF_P(data); // inc the ref count since this is going into the options_ht too.
core::sqlsrv_zend_hash_index_update( ctx, options_ht, option_key, data TSRMLS_CC ); core::sqlsrv_zend_hash_index_update( ctx, options_ht, option_key, data );
} }
// Iterates through the list of statement options provided by the user and validates them // Iterates through the list of statement options provided by the user and validates them
// against the list of supported statement options by this driver. After validation // against the list of supported statement options by this driver. After validation
// creates a Hashtable of statement options to be sent to the core layer for processing. // creates a Hashtable of statement options to be sent to the core layer for processing.
void validate_stmt_options( _Inout_ sqlsrv_context& ctx, _Inout_ zval* stmt_options, _Inout_ HashTable* ss_stmt_options_ht TSRMLS_DC ) void validate_stmt_options( _Inout_ sqlsrv_context& ctx, _Inout_ zval* stmt_options, _Inout_ HashTable* ss_stmt_options_ht )
{ {
try { try {
if( stmt_options ) { if( stmt_options ) {
@ -1471,7 +1463,7 @@ void validate_stmt_options( _Inout_ sqlsrv_context& ctx, _Inout_ zval* stmt_opti
} }
else if ( key != NULL ) { else if ( key != NULL ) {
key_len = ZSTR_LEN( key ) + 1; key_len = ZSTR_LEN( key ) + 1;
add_stmt_option_key( ctx, key, key_len, ss_stmt_options_ht, data TSRMLS_CC ); add_stmt_option_key( ctx, key, key_len, ss_stmt_options_ht, data );
} }
else { else {
DIE( "validate_stmt_options: key was null." ); DIE( "validate_stmt_options: key was null." );
@ -1489,7 +1481,7 @@ void validate_stmt_options( _Inout_ sqlsrv_context& ctx, _Inout_ zval* stmt_opti
// against the predefined list of supported connection options by this driver. After validation // against the predefined list of supported connection options by this driver. After validation
// creates a Hashtable of connection options to be sent to the core layer for processing. // creates a Hashtable of connection options to be sent to the core layer for processing.
void validate_conn_options( _Inout_ sqlsrv_context& ctx, _In_ zval* user_options_z, _Inout_ char** uid, _Inout_ char** pwd, _Inout_ HashTable* ss_conn_options_ht TSRMLS_DC ) void validate_conn_options( _Inout_ sqlsrv_context& ctx, _In_ zval* user_options_z, _Inout_ char** uid, _Inout_ char** pwd, _Inout_ HashTable* ss_conn_options_ht )
{ {
try { try {
@ -1524,7 +1516,7 @@ void validate_conn_options( _Inout_ sqlsrv_context& ctx, _In_ zval* user_options
} }
else { else {
::add_conn_option_key( ctx, key, key_len, ss_conn_options_ht, data TSRMLS_CC ); ::add_conn_option_key( ctx, key, key_len, ss_conn_options_ht, data );
} }
} }
else { else {

View file

@ -551,14 +551,14 @@ PHP_MINIT_FUNCTION(sqlsrv)
} }
} }
if( php_register_url_stream_wrapper( SQLSRV_STREAM_WRAPPER, &g_sqlsrv_stream_wrapper TSRMLS_CC ) == FAILURE ) { if( php_register_url_stream_wrapper( SQLSRV_STREAM_WRAPPER, &g_sqlsrv_stream_wrapper ) == FAILURE ) {
LOG( SEV_ERROR, "%1!s!: stream registration failed", _FN_ ); LOG( SEV_ERROR, "%1!s!: stream registration failed", _FN_ );
return FAILURE; return FAILURE;
} }
try { try {
// retrieve the handles for the environments // retrieve the handles for the environments
core_sqlsrv_minit( &g_ss_henv_cp, &g_ss_henv_ncp, ss_error_handler, "PHP_MINIT_FUNCTION for sqlsrv" TSRMLS_CC ); core_sqlsrv_minit( &g_ss_henv_cp, &g_ss_henv_ncp, ss_error_handler, "PHP_MINIT_FUNCTION for sqlsrv" );
} }
catch( core::CoreException& ) { catch( core::CoreException& ) {
@ -610,7 +610,7 @@ PHP_MSHUTDOWN_FUNCTION(sqlsrv)
core_sqlsrv_mshutdown( *g_ss_henv_cp, *g_ss_henv_ncp ); core_sqlsrv_mshutdown( *g_ss_henv_cp, *g_ss_henv_ncp );
if( php_unregister_url_stream_wrapper( SQLSRV_STREAM_WRAPPER TSRMLS_CC ) == FAILURE ) { if( php_unregister_url_stream_wrapper( SQLSRV_STREAM_WRAPPER ) == FAILURE ) {
return FAILURE; return FAILURE;
} }
@ -692,7 +692,7 @@ PHP_RSHUTDOWN_FUNCTION(sqlsrv)
SQLSRV_UNUSED( type ); SQLSRV_UNUSED( type );
LOG_FUNCTION( "PHP_RSHUTDOWN for php_sqlsrv" ); LOG_FUNCTION( "PHP_RSHUTDOWN for php_sqlsrv" );
reset_errors( TSRMLS_C ); reset_errors();
// TODO - destruction // TODO - destruction
zval_ptr_dtor( &SQLSRV_G( errors )); zval_ptr_dtor( &SQLSRV_G( errors ));

View file

@ -91,8 +91,8 @@ struct ss_sqlsrv_conn : sqlsrv_conn
static int descriptor; static int descriptor;
// initialize with default values // initialize with default values
ss_sqlsrv_conn( _In_ SQLHANDLE h, _In_ error_callback e, _In_ void* drv TSRMLS_DC ) : ss_sqlsrv_conn( _In_ SQLHANDLE h, _In_ error_callback e, _In_ void* drv ) :
sqlsrv_conn( h, e, drv, SQLSRV_ENCODING_SYSTEM TSRMLS_CC ), sqlsrv_conn( h, e, drv, SQLSRV_ENCODING_SYSTEM ),
stmts( NULL ), stmts( NULL ),
date_as_string( false ), date_as_string( false ),
format_decimals( false ), format_decimals( false ),
@ -103,8 +103,7 @@ struct ss_sqlsrv_conn : sqlsrv_conn
}; };
// resource destructor // resource destructor
void __cdecl sqlsrv_conn_dtor( _Inout_ zend_resource *rsrc TSRMLS_DC ); void __cdecl sqlsrv_conn_dtor( _Inout_ zend_resource *rsrc );
//********************************************************************************************************************************* //*********************************************************************************************************************************
// Statement // Statement
@ -117,18 +116,16 @@ struct sqlsrv_fetch_field_name {
}; };
struct stmt_option_ss_scrollable : public stmt_option_functor { struct stmt_option_ss_scrollable : public stmt_option_functor {
virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z );
virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC );
}; };
// This object inherits and overrides the callbacks necessary // This object inherits and overrides the callbacks necessary
struct ss_sqlsrv_stmt : public sqlsrv_stmt { struct ss_sqlsrv_stmt : public sqlsrv_stmt {
ss_sqlsrv_stmt( _In_ sqlsrv_conn* c, _In_ SQLHANDLE handle, _In_ error_callback e, _In_ void* drv );
ss_sqlsrv_stmt( _In_ sqlsrv_conn* c, _In_ SQLHANDLE handle, _In_ error_callback e, _In_ void* drv TSRMLS_DC );
virtual ~ss_sqlsrv_stmt( void ); virtual ~ss_sqlsrv_stmt( void );
void new_result_set( TSRMLS_D ); void new_result_set( void );
// driver specific conversion rules from a SQL Server/ODBC type to one of the SQLSRV_PHPTYPE_* constants // driver specific conversion rules from a SQL Server/ODBC type to one of the SQLSRV_PHPTYPE_* constants
sqlsrv_phptype sql_type_to_php_type( _In_ SQLINTEGER sql_type, _In_ SQLUINTEGER size, _In_ bool prefer_string_to_stream ); sqlsrv_phptype sql_type_to_php_type( _In_ SQLINTEGER sql_type, _In_ SQLUINTEGER size, _In_ bool prefer_string_to_stream );
@ -166,14 +163,14 @@ struct sqlsrv_stream_encoding {
}; };
// resource destructor // resource destructor
void __cdecl sqlsrv_stmt_dtor( _Inout_ zend_resource *rsrc TSRMLS_DC ); void __cdecl sqlsrv_stmt_dtor( _Inout_ zend_resource *rsrc );
// "internal" statement functions shared by functions in conn.cpp and stmt.cpp // "internal" statement functions shared by functions in conn.cpp and stmt.cpp
void bind_params( _Inout_ ss_sqlsrv_stmt* stmt TSRMLS_DC ); void bind_params( _Inout_ ss_sqlsrv_stmt* stmt );
bool sqlsrv_stmt_common_execute( sqlsrv_stmt* s, const SQLCHAR* sql_string, int sql_len, bool direct, const char* function bool sqlsrv_stmt_common_execute( sqlsrv_stmt* s, const SQLCHAR* sql_string, int sql_len, bool direct, const char* function
TSRMLS_DC ); );
void free_odbc_resources( ss_sqlsrv_stmt* stmt TSRMLS_DC ); void free_odbc_resources( ss_sqlsrv_stmt* stmt );
void free_stmt_resource( _Inout_ zval* stmt_z TSRMLS_DC ); void free_stmt_resource( _Inout_ zval* stmt_z );
//********************************************************************************************************************************* //*********************************************************************************************************************************
@ -218,7 +215,7 @@ enum SS_ERROR_CODES {
extern ss_error SS_ERRORS[]; extern ss_error SS_ERRORS[];
bool ss_error_handler( _Inout_ sqlsrv_context& ctx, _In_ unsigned int sqlsrv_error_code, _In_ bool warning TSRMLS_DC, _In_opt_ va_list* print_args ); bool ss_error_handler( _Inout_ sqlsrv_context& ctx, _In_ unsigned int sqlsrv_error_code, _In_ bool warning, _In_opt_ va_list* print_args );
// convert from the default encoding specified by the "CharacterSet" // convert from the default encoding specified by the "CharacterSet"
// connection option to UTF-16. mbcs_len and utf16_len are sizes in // connection option to UTF-16. mbcs_len and utf16_len are sizes in
@ -235,13 +232,13 @@ SQLWCHAR* utf16_string_from_mbcs_string( _In_ unsigned int php_encoding, _In_rea
// *** internal error macros and functions *** // *** internal error macros and functions ***
bool handle_error( sqlsrv_context const* ctx, int log_subsystem, const char* function, bool handle_error( sqlsrv_context const* ctx, int log_subsystem, const char* function,
sqlsrv_error const* ssphp TSRMLS_DC, ... ); sqlsrv_error const* ssphp, ... );
void handle_warning( sqlsrv_context const* ctx, int log_subsystem, const char* function, void handle_warning( sqlsrv_context const* ctx, int log_subsystem, const char* function,
sqlsrv_error const* ssphp TSRMLS_DC, ... ); sqlsrv_error const* ssphp, ... );
void __cdecl sqlsrv_error_dtor( zend_resource *rsrc TSRMLS_DC ); void __cdecl sqlsrv_error_dtor( zend_resource *rsrc );
// release current error lists and set to NULL // release current error lists and set to NULL
inline void reset_errors( TSRMLS_D ) inline void reset_errors( void )
{ {
if( Z_TYPE( SQLSRV_G( errors )) != IS_ARRAY && Z_TYPE( SQLSRV_G( errors )) != IS_NULL ) { if( Z_TYPE( SQLSRV_G( errors )) != IS_ARRAY && Z_TYPE( SQLSRV_G( errors )) != IS_NULL ) {
DIE( "sqlsrv_errors contains an invalid type" ); DIE( "sqlsrv_errors contains an invalid type" );
@ -264,7 +261,7 @@ inline void reset_errors( TSRMLS_D )
} }
#define THROW_SS_ERROR( ctx, error_code, ... ) \ #define THROW_SS_ERROR( ctx, error_code, ... ) \
(void)call_error_handler( ctx, error_code TSRMLS_CC, false /*warning*/, ## __VA_ARGS__ ); \ (void)call_error_handler( ctx, error_code, false /*warning*/, ## __VA_ARGS__ ); \
throw ss::SSException(); throw ss::SSException();
@ -317,7 +314,7 @@ public:
LOG(SEV_NOTICE, "%1!s!: entering", _FN_); LOG(SEV_NOTICE, "%1!s!: entering", _FN_);
// check the global variables of sqlsrv severity whether the message qualifies to be logged with the LOG macro // check the global variables of sqlsrv severity whether the message qualifies to be logged with the LOG macro
bool ss_severity_check(_In_ unsigned int severity TSRMLS_DC); bool ss_severity_check(_In_ unsigned int severity);
// subsystems that may report log messages. These may be used to filter which systems write to the log to prevent noise. // subsystems that may report log messages. These may be used to filter which systems write to the log to prevent noise.
enum logging_subsystems { enum logging_subsystems {
@ -345,7 +342,7 @@ namespace ss {
} }
}; };
inline void zend_register_resource( _Inout_ zval& rsrc_result, _Inout_ void* rsrc_pointer, _In_ int rsrc_type, _In_opt_ const char* rsrc_name TSRMLS_DC) inline void zend_register_resource( _Inout_ zval& rsrc_result, _Inout_ void* rsrc_pointer, _In_ int rsrc_type, _In_opt_ const char* rsrc_name)
{ {
int zr = (NULL != (Z_RES(rsrc_result) = ::zend_register_resource(rsrc_pointer, rsrc_type)) ? SUCCESS : FAILURE); int zr = (NULL != (Z_RES(rsrc_result) = ::zend_register_resource(rsrc_pointer, rsrc_type)) ? SUCCESS : FAILURE);
CHECK_CUSTOM_ERROR(( zr == FAILURE ), reinterpret_cast<sqlsrv_context*>( rsrc_pointer ), SS_SQLSRV_ERROR_REGISTER_RESOURCE, CHECK_CUSTOM_ERROR(( zr == FAILURE ), reinterpret_cast<sqlsrv_context*>( rsrc_pointer ), SS_SQLSRV_ERROR_REGISTER_RESOURCE,
@ -372,7 +369,7 @@ inline H* process_params( INTERNAL_FUNCTION_PARAMETERS, _In_ char const* param_s
H* h; H* h;
// reset the errors from the previous API call // reset the errors from the previous API call
reset_errors( TSRMLS_C ); reset_errors();
if( ZEND_NUM_ARGS() > param_count + 1 ) { if( ZEND_NUM_ARGS() > param_count + 1 ) {
DIE( "Param count and argument count don't match." ); DIE( "Param count and argument count don't match." );
@ -406,35 +403,35 @@ inline H* process_params( INTERNAL_FUNCTION_PARAMETERS, _In_ char const* param_s
switch( param_count ) { switch( param_count ) {
case 0: case 0:
result = zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>( param_spec ), &rsrc ); result = zend_parse_parameters( ZEND_NUM_ARGS(), const_cast<char*>( param_spec ), &rsrc );
break; break;
case 1: case 1:
result = zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>( param_spec ), &rsrc, arr[0] ); result = zend_parse_parameters( ZEND_NUM_ARGS(), const_cast<char*>( param_spec ), &rsrc, arr[0] );
break; break;
case 2: case 2:
result = zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>( param_spec ), &rsrc, arr[0], result = zend_parse_parameters( ZEND_NUM_ARGS(), const_cast<char*>( param_spec ), &rsrc, arr[0],
arr[1] ); arr[1] );
break; break;
case 3: case 3:
result = zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>( param_spec ), &rsrc, arr[0], result = zend_parse_parameters( ZEND_NUM_ARGS(), const_cast<char*>( param_spec ), &rsrc, arr[0],
arr[1], arr[2] ); arr[1], arr[2] );
break; break;
case 4: case 4:
result = zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>( param_spec ), &rsrc, arr[0], result = zend_parse_parameters( ZEND_NUM_ARGS(), const_cast<char*>( param_spec ), &rsrc, arr[0],
arr[1], arr[2], arr[3] ); arr[1], arr[2], arr[3] );
break; break;
case 5: case 5:
result = zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>( param_spec ), &rsrc, arr[0], result = zend_parse_parameters( ZEND_NUM_ARGS(), const_cast<char*>( param_spec ), &rsrc, arr[0],
arr[1], arr[2], arr[3], arr[4] ); arr[1], arr[2], arr[3], arr[4] );
break; break;
case 6: case 6:
result = zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>( param_spec ), &rsrc, arr[0], result = zend_parse_parameters( ZEND_NUM_ARGS(), const_cast<char*>( param_spec ), &rsrc, arr[0],
arr[1], arr[2], arr[3], arr[4], arr[5] ); arr[1], arr[2], arr[3], arr[4], arr[5] );
break; break;
@ -451,7 +448,7 @@ inline H* process_params( INTERNAL_FUNCTION_PARAMETERS, _In_ char const* param_s
} }
// get the resource registered // get the resource registered
h = static_cast<H*>( zend_fetch_resource(Z_RES_P(rsrc) TSRMLS_CC, H::resource_name, H::descriptor )); h = static_cast<H*>( zend_fetch_resource(Z_RES_P(rsrc), H::resource_name, H::descriptor ));
CHECK_CUSTOM_ERROR(( h == NULL ), &error_ctx, SS_SQLSRV_ERROR_INVALID_FUNCTION_PARAMETER, calling_func ) { CHECK_CUSTOM_ERROR(( h == NULL ), &error_ctx, SS_SQLSRV_ERROR_INVALID_FUNCTION_PARAMETER, calling_func ) {

View file

@ -89,21 +89,20 @@ const char* NULLABLE = "Nullable";
void convert_to_zval( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSRV_PHPTYPE sqlsrv_php_type, _In_opt_ void* in_val, _In_ SQLLEN field_len, _Inout_ zval& out_zval ); void convert_to_zval( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSRV_PHPTYPE sqlsrv_php_type, _In_opt_ void* in_val, _In_ SQLLEN field_len, _Inout_ zval& out_zval );
SQLSMALLINT get_resultset_meta_data(_Inout_ sqlsrv_stmt* stmt); SQLSMALLINT get_resultset_meta_data(_Inout_ sqlsrv_stmt* stmt);
void fetch_fields_common( _Inout_ ss_sqlsrv_stmt* stmt, _In_ zend_long fetch_type, _Out_ zval& fields, _In_ bool allow_empty_field_names void fetch_fields_common( _Inout_ ss_sqlsrv_stmt* stmt, _In_ zend_long fetch_type, _Out_ zval& fields, _In_ bool allow_empty_field_names );
TSRMLS_DC );
bool determine_column_size_or_precision( sqlsrv_stmt const* stmt, _In_ sqlsrv_sqltype sqlsrv_type, _Inout_ SQLULEN* column_size, bool determine_column_size_or_precision( sqlsrv_stmt const* stmt, _In_ sqlsrv_sqltype sqlsrv_type, _Inout_ SQLULEN* column_size,
_Out_ SQLSMALLINT* decimal_digits ); _Out_ SQLSMALLINT* decimal_digits );
sqlsrv_phptype determine_sqlsrv_php_type( sqlsrv_stmt const* stmt, SQLINTEGER sql_type, SQLUINTEGER size, bool prefer_string ); sqlsrv_phptype determine_sqlsrv_php_type( sqlsrv_stmt const* stmt, SQLINTEGER sql_type, SQLUINTEGER size, bool prefer_string );
void determine_stmt_has_rows( _Inout_ ss_sqlsrv_stmt* stmt TSRMLS_DC ); void determine_stmt_has_rows( _Inout_ ss_sqlsrv_stmt* stmt );
bool is_valid_sqlsrv_phptype( _In_ sqlsrv_phptype type ); bool is_valid_sqlsrv_phptype( _In_ sqlsrv_phptype type );
bool is_valid_sqlsrv_sqltype( _In_ sqlsrv_sqltype type ); bool is_valid_sqlsrv_sqltype( _In_ sqlsrv_sqltype type );
void parse_param_array( _Inout_ ss_sqlsrv_stmt* stmt, _Inout_ zval* param_array, zend_ulong index, _Out_ SQLSMALLINT& direction, void parse_param_array( _Inout_ ss_sqlsrv_stmt* stmt, _Inout_ zval* param_array, zend_ulong index, _Out_ SQLSMALLINT& direction,
_Out_ SQLSRV_PHPTYPE& php_out_type, _Out_ SQLSRV_ENCODING& encoding, _Out_ SQLSMALLINT& sql_type, _Out_ SQLSRV_PHPTYPE& php_out_type, _Out_ SQLSRV_ENCODING& encoding, _Out_ SQLSMALLINT& sql_type,
_Out_ SQLULEN& column_size, _Out_ SQLSMALLINT& decimal_digits TSRMLS_DC ); _Out_ SQLULEN& column_size, _Out_ SQLSMALLINT& decimal_digits );
void type_and_encoding( INTERNAL_FUNCTION_PARAMETERS, _In_ int type ); void type_and_encoding( INTERNAL_FUNCTION_PARAMETERS, _In_ int type );
void type_and_size_calc( INTERNAL_FUNCTION_PARAMETERS, _In_ int type ); void type_and_size_calc( INTERNAL_FUNCTION_PARAMETERS, _In_ int type );
void type_and_precision_calc( INTERNAL_FUNCTION_PARAMETERS, _In_ int type ); void type_and_precision_calc( INTERNAL_FUNCTION_PARAMETERS, _In_ int type );
bool verify_and_set_encoding( _In_ const char* encoding_string, _Inout_ sqlsrv_phptype& phptype_encoding TSRMLS_DC ); bool verify_and_set_encoding( _In_ const char* encoding_string, _Inout_ sqlsrv_phptype& phptype_encoding );
} }
@ -126,15 +125,15 @@ namespace SSCursorTypes {
const char QUERY_OPTION_SCROLLABLE_BUFFERED[] = "buffered"; const char QUERY_OPTION_SCROLLABLE_BUFFERED[] = "buffered";
} }
ss_sqlsrv_stmt::ss_sqlsrv_stmt( _In_ sqlsrv_conn* c, _In_ SQLHANDLE handle, _In_ error_callback e, _In_ void* drv TSRMLS_DC ) : ss_sqlsrv_stmt::ss_sqlsrv_stmt( _In_ sqlsrv_conn* c, _In_ SQLHANDLE handle, _In_ error_callback e, _In_ void* drv ) :
sqlsrv_stmt( c, handle, e, drv TSRMLS_CC ), sqlsrv_stmt( c, handle, e, drv ),
prepared( false ), prepared( false ),
conn_index( -1 ), conn_index( -1 ),
params_z( NULL ), params_z( NULL ),
fetch_field_names( NULL ), fetch_field_names( NULL ),
fetch_fields_count ( 0 ) fetch_fields_count ( 0 )
{ {
core_sqlsrv_set_buffered_query_limit( this, SQLSRV_G( buffered_query_limit ) TSRMLS_CC ); core_sqlsrv_set_buffered_query_limit( this, SQLSRV_G( buffered_query_limit ) );
// inherit other values based on the corresponding connection options // inherit other values based on the corresponding connection options
ss_sqlsrv_conn* ss_conn = static_cast<ss_sqlsrv_conn*>(conn); ss_sqlsrv_conn* ss_conn = static_cast<ss_sqlsrv_conn*>(conn);
@ -164,7 +163,7 @@ ss_sqlsrv_stmt::~ss_sqlsrv_stmt( void )
// to be called whenever a new result set is created, such as after an // to be called whenever a new result set is created, such as after an
// execute or next_result. Resets the state variables and calls the subclass. // execute or next_result. Resets the state variables and calls the subclass.
void ss_sqlsrv_stmt::new_result_set( TSRMLS_D ) void ss_sqlsrv_stmt::new_result_set( void )
{ {
if( fetch_field_names != NULL ) { if( fetch_field_names != NULL ) {
@ -177,7 +176,7 @@ void ss_sqlsrv_stmt::new_result_set( TSRMLS_D )
fetch_field_names = NULL; fetch_field_names = NULL;
fetch_fields_count = 0; fetch_fields_count = 0;
sqlsrv_stmt::new_result_set( TSRMLS_C ); sqlsrv_stmt::new_result_set();
} }
// Returns a php type for a given sql type. Also sets the encoding wherever applicable. // Returns a php type for a given sql type. Also sets the encoding wherever applicable.
@ -269,7 +268,7 @@ void ss_sqlsrv_stmt::set_query_timeout()
} }
// set the statement attribute // set the statement attribute
core::SQLSetStmtAttr(this, SQL_ATTR_QUERY_TIMEOUT, reinterpret_cast<SQLPOINTER>( (SQLLEN)query_timeout ), SQL_IS_UINTEGER TSRMLS_CC ); core::SQLSetStmtAttr(this, SQL_ATTR_QUERY_TIMEOUT, reinterpret_cast<SQLPOINTER>( (SQLLEN)query_timeout ), SQL_IS_UINTEGER );
// a query timeout of 0 indicates "no timeout", which means that lock_timeout should also be set to "no timeout" which // a query timeout of 0 indicates "no timeout", which means that lock_timeout should also be set to "no timeout" which
// is represented by -1. // is represented by -1.
@ -282,7 +281,7 @@ void ss_sqlsrv_stmt::set_query_timeout()
SQLSRV_ASSERT( (written != -1 && written != sizeof( lock_timeout_sql )), SQLSRV_ASSERT( (written != -1 && written != sizeof( lock_timeout_sql )),
"stmt_option_query_timeout: snprintf failed. Shouldn't ever fail." ); "stmt_option_query_timeout: snprintf failed. Shouldn't ever fail." );
core::SQLExecDirect(this, lock_timeout_sql TSRMLS_CC ); core::SQLExecDirect(this, lock_timeout_sql );
} }
// statement specific parameter proccessing. Uses the generic function specialised to return a statement // statement specific parameter proccessing. Uses the generic function specialised to return a statement
@ -327,14 +326,14 @@ PHP_FUNCTION( sqlsrv_execute )
// to prepare to execute the next statement, we skip any remaining results (and skip parameter finalization too) // to prepare to execute the next statement, we skip any remaining results (and skip parameter finalization too)
while( stmt->past_next_result_end == false ) { while( stmt->past_next_result_end == false ) {
core_sqlsrv_next_result( stmt TSRMLS_CC, false, false ); core_sqlsrv_next_result( stmt, false, false );
} }
} }
// bind parameters before executing // bind parameters before executing
bind_params( stmt TSRMLS_CC ); bind_params( stmt );
core_sqlsrv_execute( stmt TSRMLS_CC ); core_sqlsrv_execute( stmt );
RETURN_TRUE; RETURN_TRUE;
} }
@ -383,7 +382,7 @@ PHP_FUNCTION( sqlsrv_fetch )
throw ss::SSException(); throw ss::SSException();
} }
bool result = core_sqlsrv_fetch( stmt, static_cast<SQLSMALLINT>(fetch_style), fetch_offset TSRMLS_CC ); bool result = core_sqlsrv_fetch( stmt, static_cast<SQLSMALLINT>(fetch_style), fetch_offset );
if( !result ) { if( !result ) {
RETURN_NULL(); RETURN_NULL();
} }
@ -442,13 +441,13 @@ PHP_FUNCTION( sqlsrv_fetch_array )
throw ss::SSException(); throw ss::SSException();
} }
bool result = core_sqlsrv_fetch( stmt, static_cast<SQLSMALLINT>(fetch_style), fetch_offset TSRMLS_CC ); bool result = core_sqlsrv_fetch( stmt, static_cast<SQLSMALLINT>(fetch_style), fetch_offset );
if( !result ) { if( !result ) {
RETURN_NULL(); RETURN_NULL();
} }
zval fields; zval fields;
ZVAL_UNDEF( &fields ); ZVAL_UNDEF( &fields );
fetch_fields_common( stmt, fetch_type, fields, true /*allow_empty_field_names*/ TSRMLS_CC ); fetch_fields_common( stmt, fetch_type, fields, true /*allow_empty_field_names*/ );
RETURN_ARR( Z_ARRVAL( fields )); RETURN_ARR( Z_ARRVAL( fields ));
} }
@ -501,7 +500,7 @@ PHP_FUNCTION( sqlsrv_field_metadata )
zval result_meta_data; zval result_meta_data;
ZVAL_UNDEF( &result_meta_data ); ZVAL_UNDEF( &result_meta_data );
core::sqlsrv_array_init( *stmt, &result_meta_data TSRMLS_CC ); core::sqlsrv_array_init( *stmt, &result_meta_data );
for( SQLSMALLINT f = 0; f < num_cols; ++f ) { for( SQLSMALLINT f = 0; f < num_cols; ++f ) {
field_meta_data* core_meta_data = stmt->current_meta_data[f]; field_meta_data* core_meta_data = stmt->current_meta_data[f];
@ -509,13 +508,13 @@ PHP_FUNCTION( sqlsrv_field_metadata )
// initialize the array // initialize the array
zval field_array; zval field_array;
ZVAL_UNDEF( &field_array ); ZVAL_UNDEF( &field_array );
core::sqlsrv_array_init( *stmt, &field_array TSRMLS_CC ); core::sqlsrv_array_init( *stmt, &field_array );
// add the field name to the associative array but keep a copy // add the field name to the associative array but keep a copy
core::sqlsrv_add_assoc_string(*stmt, &field_array, FieldMetaData::NAME, core::sqlsrv_add_assoc_string(*stmt, &field_array, FieldMetaData::NAME,
reinterpret_cast<char*>(core_meta_data->field_name.get()), 1 TSRMLS_CC); reinterpret_cast<char*>(core_meta_data->field_name.get()), 1);
core::sqlsrv_add_assoc_long( *stmt, &field_array, FieldMetaData::TYPE, core_meta_data->field_type TSRMLS_CC ); core::sqlsrv_add_assoc_long( *stmt, &field_array, FieldMetaData::TYPE, core_meta_data->field_type );
switch( core_meta_data->field_type ) { switch( core_meta_data->field_type ) {
case SQL_DECIMAL: case SQL_DECIMAL:
@ -524,9 +523,9 @@ PHP_FUNCTION( sqlsrv_field_metadata )
case SQL_TYPE_DATE: case SQL_TYPE_DATE:
case SQL_SS_TIME2: case SQL_SS_TIME2:
case SQL_SS_TIMESTAMPOFFSET: case SQL_SS_TIMESTAMPOFFSET:
core::sqlsrv_add_assoc_null( *stmt, &field_array, FieldMetaData::SIZE TSRMLS_CC ); core::sqlsrv_add_assoc_null( *stmt, &field_array, FieldMetaData::SIZE );
core::sqlsrv_add_assoc_long( *stmt, &field_array, FieldMetaData::PREC, core_meta_data->field_precision TSRMLS_CC ); core::sqlsrv_add_assoc_long( *stmt, &field_array, FieldMetaData::PREC, core_meta_data->field_precision );
core::sqlsrv_add_assoc_long( *stmt, &field_array, FieldMetaData::SCALE, core_meta_data->field_scale TSRMLS_CC ); core::sqlsrv_add_assoc_long( *stmt, &field_array, FieldMetaData::SCALE, core_meta_data->field_scale );
break; break;
case SQL_BIT: case SQL_BIT:
case SQL_TINYINT: case SQL_TINYINT:
@ -536,27 +535,26 @@ PHP_FUNCTION( sqlsrv_field_metadata )
case SQL_REAL: case SQL_REAL:
case SQL_FLOAT: case SQL_FLOAT:
case SQL_DOUBLE: case SQL_DOUBLE:
core::sqlsrv_add_assoc_null( *stmt, &field_array, FieldMetaData::SIZE TSRMLS_CC ); core::sqlsrv_add_assoc_null( *stmt, &field_array, FieldMetaData::SIZE );
core::sqlsrv_add_assoc_long( *stmt, &field_array, FieldMetaData::PREC, core_meta_data->field_precision TSRMLS_CC ); core::sqlsrv_add_assoc_long( *stmt, &field_array, FieldMetaData::PREC, core_meta_data->field_precision );
core::sqlsrv_add_assoc_null( *stmt, &field_array, FieldMetaData::SCALE TSRMLS_CC ); core::sqlsrv_add_assoc_null( *stmt, &field_array, FieldMetaData::SCALE );
break; break;
default: default:
core::sqlsrv_add_assoc_long( *stmt, &field_array, FieldMetaData::SIZE, core_meta_data->field_size TSRMLS_CC ); core::sqlsrv_add_assoc_long( *stmt, &field_array, FieldMetaData::SIZE, core_meta_data->field_size );
core::sqlsrv_add_assoc_null( *stmt, &field_array, FieldMetaData::PREC TSRMLS_CC ); core::sqlsrv_add_assoc_null( *stmt, &field_array, FieldMetaData::PREC );
core::sqlsrv_add_assoc_null( *stmt, &field_array, FieldMetaData::SCALE TSRMLS_CC ); core::sqlsrv_add_assoc_null( *stmt, &field_array, FieldMetaData::SCALE );
break; break;
} }
// add the nullability to the array // add the nullability to the array
core::sqlsrv_add_assoc_long( *stmt, &field_array, FieldMetaData::NULLABLE, core_meta_data->field_is_nullable core::sqlsrv_add_assoc_long(*stmt, &field_array, FieldMetaData::NULLABLE, core_meta_data->field_is_nullable);
TSRMLS_CC );
if (stmt->data_classification) { if (stmt->data_classification) {
data_classification::fill_column_sensitivity_array(stmt, f, &field_array TSRMLS_CC); data_classification::fill_column_sensitivity_array(stmt, f, &field_array);
} }
// add this field's meta data to the result set meta data // add this field's meta data to the result set meta data
core::sqlsrv_add_next_index_zval( *stmt, &result_meta_data, &field_array TSRMLS_CC ); core::sqlsrv_add_next_index_zval( *stmt, &result_meta_data, &field_array );
} }
// return our built collection and transfer ownership // return our built collection and transfer ownership
@ -600,7 +598,7 @@ PHP_FUNCTION( sqlsrv_next_result )
try { try {
core_sqlsrv_next_result( stmt TSRMLS_CC, true ); core_sqlsrv_next_result( stmt, true );
// clear the current meta data since the new result will generate new meta data // clear the current meta data since the new result will generate new meta data
std::for_each(stmt->current_meta_data.begin(), stmt->current_meta_data.end(), meta_data_free); std::for_each(stmt->current_meta_data.begin(), stmt->current_meta_data.end(), meta_data_free);
@ -659,7 +657,7 @@ PHP_FUNCTION( sqlsrv_rows_affected )
throw ss::SSException(); throw ss::SSException();
} }
rows = stmt->current_results->row_count( TSRMLS_C ); rows = stmt->current_results->row_count();
RETURN_LONG( rows ); RETURN_LONG( rows );
} }
@ -708,7 +706,7 @@ PHP_FUNCTION( sqlsrv_num_rows )
throw ss::SSException(); throw ss::SSException();
} }
rows = stmt->current_results->row_count( TSRMLS_C ); rows = stmt->current_results->row_count();
RETURN_LONG( rows ); RETURN_LONG( rows );
} }
@ -747,7 +745,7 @@ PHP_FUNCTION( sqlsrv_num_fields )
try { try {
// retrieve the number of columns from ODBC // retrieve the number of columns from ODBC
fields = core::SQLNumResultCols( stmt TSRMLS_CC ); fields = core::SQLNumResultCols( stmt );
RETURN_LONG( fields ); RETURN_LONG( fields );
} }
@ -844,18 +842,18 @@ PHP_FUNCTION( sqlsrv_fetch_object )
} }
// fetch the data // fetch the data
bool result = core_sqlsrv_fetch( stmt, static_cast<SQLSMALLINT>(fetch_style), fetch_offset TSRMLS_CC ); bool result = core_sqlsrv_fetch( stmt, static_cast<SQLSMALLINT>(fetch_style), fetch_offset );
if( !result ) { if( !result ) {
RETURN_NULL(); RETURN_NULL();
} }
fetch_fields_common( stmt, SQLSRV_FETCH_ASSOC, retval_z, false /*allow_empty_field_names*/ TSRMLS_CC ); fetch_fields_common( stmt, SQLSRV_FETCH_ASSOC, retval_z, false /*allow_empty_field_names*/ );
properties_ht = Z_ARRVAL( retval_z ); properties_ht = Z_ARRVAL( retval_z );
// find the zend_class_entry of the class the user requested (stdClass by default) for use below // find the zend_class_entry of the class the user requested (stdClass by default) for use below
zend_class_entry* class_entry = NULL; zend_class_entry* class_entry = NULL;
zend_string* class_name_str_z = zend_string_init( class_name, class_name_len, 0 ); zend_string* class_name_str_z = zend_string_init( class_name, class_name_len, 0 );
int zr = ( NULL != ( class_entry = zend_lookup_class( class_name_str_z TSRMLS_CC ))) ? SUCCESS : FAILURE; int zr = ( NULL != ( class_entry = zend_lookup_class( class_name_str_z ))) ? SUCCESS : FAILURE;
zend_string_release( class_name_str_z ); zend_string_release( class_name_str_z );
CHECK_ZEND_ERROR( zr, stmt, SS_SQLSRV_ERROR_ZEND_BAD_CLASS, class_name ) { CHECK_ZEND_ERROR( zr, stmt, SS_SQLSRV_ERROR_ZEND_BAD_CLASS, class_name ) {
throw ss::SSException(); throw ss::SSException();
@ -873,7 +871,7 @@ PHP_FUNCTION( sqlsrv_fetch_object )
// causes duplicate properties when the visibilities are different and also references the // causes duplicate properties when the visibilities are different and also references the
// default parameters directly in the object, meaning the default property value is changed when // default parameters directly in the object, meaning the default property value is changed when
// the object's property is changed. // the object's property is changed.
zend_merge_properties( &retval_z, properties_ht TSRMLS_CC ); zend_merge_properties( &retval_z, properties_ht );
zend_hash_destroy( properties_ht ); zend_hash_destroy( properties_ht );
FREE_HASHTABLE( properties_ht ); FREE_HASHTABLE( properties_ht );
@ -940,7 +938,7 @@ PHP_FUNCTION( sqlsrv_fetch_object )
fcic.object = Z_OBJ_P( &retval_z ); fcic.object = Z_OBJ_P( &retval_z );
zr = zend_call_function( &fci, &fcic TSRMLS_CC ); zr = zend_call_function( &fci, &fcic );
CHECK_ZEND_ERROR( zr, stmt, SS_SQLSRV_ERROR_ZEND_OBJECT_FAILED, class_name ) { CHECK_ZEND_ERROR( zr, stmt, SS_SQLSRV_ERROR_ZEND_OBJECT_FAILED, class_name ) {
throw ss::SSException(); throw ss::SSException();
} }
@ -1004,7 +1002,7 @@ PHP_FUNCTION( sqlsrv_has_rows )
if( !stmt->has_rows && !stmt->fetch_called ) { if( !stmt->has_rows && !stmt->fetch_called ) {
determine_stmt_has_rows( stmt TSRMLS_CC ); determine_stmt_has_rows( stmt );
} }
if( stmt->has_rows ) { if( stmt->has_rows ) {
@ -1057,7 +1055,7 @@ PHP_FUNCTION( sqlsrv_send_stream_data )
} }
// send the next packet // send the next packet
bool more = core_sqlsrv_send_stream_packet( stmt TSRMLS_CC ); bool more = core_sqlsrv_send_stream_packet( stmt );
// if more to send, return true // if more to send, return true
if( more ) { if( more ) {
@ -1130,7 +1128,7 @@ PHP_FUNCTION( sqlsrv_get_field )
} }
core_sqlsrv_get_field( stmt, static_cast<SQLUSMALLINT>( field_index ), sqlsrv_php_type, false, field_value, &field_len, false/*cache_field*/, core_sqlsrv_get_field( stmt, static_cast<SQLUSMALLINT>( field_index ), sqlsrv_php_type, false, field_value, &field_len, false/*cache_field*/,
&sqlsrv_php_type_out TSRMLS_CC ); &sqlsrv_php_type_out );
convert_to_zval( stmt, sqlsrv_php_type_out, field_value, field_len, retval_z ); convert_to_zval( stmt, sqlsrv_php_type_out, field_value, field_len, retval_z );
sqlsrv_free( field_value ); sqlsrv_free( field_value );
RETURN_ZVAL( &retval_z, 1, 1 ); RETURN_ZVAL( &retval_z, 1, 1 );
@ -1213,7 +1211,7 @@ PHP_FUNCTION(SQLSRV_SQLTYPE_VARCHAR)
type_and_size_calc( INTERNAL_FUNCTION_PARAM_PASSTHRU, SQL_VARCHAR ); type_and_size_calc( INTERNAL_FUNCTION_PARAM_PASSTHRU, SQL_VARCHAR );
} }
void bind_params( _Inout_ ss_sqlsrv_stmt* stmt TSRMLS_DC ) void bind_params( _Inout_ ss_sqlsrv_stmt* stmt )
{ {
// if there's nothing to do, just return // if there's nothing to do, just return
if( stmt->params_z == NULL ) { if( stmt->params_z == NULL ) {
@ -1222,7 +1220,7 @@ void bind_params( _Inout_ ss_sqlsrv_stmt* stmt TSRMLS_DC )
try { try {
stmt->free_param_data( TSRMLS_C ); stmt->free_param_data();
stmt->executed = false; stmt->executed = false;
@ -1263,7 +1261,7 @@ void bind_params( _Inout_ ss_sqlsrv_stmt* stmt TSRMLS_DC )
// parse the parameter array that the user gave // parse the parameter array that the user gave
parse_param_array( stmt, param_z, index, direction, php_out_type, encoding, sql_type, column_size, parse_param_array( stmt, param_z, index, direction, php_out_type, encoding, sql_type, column_size,
decimal_digits TSRMLS_CC ); decimal_digits );
value_z = var; value_z = var;
} }
else { else {
@ -1275,7 +1273,7 @@ void bind_params( _Inout_ ss_sqlsrv_stmt* stmt TSRMLS_DC )
// bind the parameter // bind the parameter
SQLSRV_ASSERT( value_z != NULL, "bind_params: value_z is null." ); SQLSRV_ASSERT( value_z != NULL, "bind_params: value_z is null." );
core_sqlsrv_bind_param( stmt, static_cast<SQLUSMALLINT>( index ), direction, value_z, php_out_type, encoding, sql_type, column_size, core_sqlsrv_bind_param( stmt, static_cast<SQLUSMALLINT>( index ), direction, value_z, php_out_type, encoding, sql_type, column_size,
decimal_digits TSRMLS_CC ); decimal_digits );
} ZEND_HASH_FOREACH_END(); } ZEND_HASH_FOREACH_END();
} }
@ -1312,7 +1310,7 @@ PHP_FUNCTION( sqlsrv_cancel )
try { try {
// close the stream to release the resource // close the stream to release the resource
close_active_stream( stmt TSRMLS_CC ); close_active_stream( stmt );
SQLRETURN r = SQLCancel( stmt->handle() ); SQLRETURN r = SQLCancel( stmt->handle() );
CHECK_SQL_ERROR_OR_WARNING( r, stmt ) { CHECK_SQL_ERROR_OR_WARNING( r, stmt ) {
@ -1331,7 +1329,7 @@ PHP_FUNCTION( sqlsrv_cancel )
} }
} }
void __cdecl sqlsrv_stmt_dtor( _Inout_ zend_resource *rsrc TSRMLS_DC ) void __cdecl sqlsrv_stmt_dtor( _Inout_ zend_resource *rsrc )
{ {
LOG_FUNCTION( "sqlsrv_stmt_dtor" ); LOG_FUNCTION( "sqlsrv_stmt_dtor" );
@ -1377,7 +1375,7 @@ PHP_FUNCTION( sqlsrv_free_stmt )
ss_sqlsrv_stmt* stmt = NULL; ss_sqlsrv_stmt* stmt = NULL;
sqlsrv_context_auto_ptr error_ctx; sqlsrv_context_auto_ptr error_ctx;
reset_errors( TSRMLS_C ); reset_errors();
try { try {
@ -1386,10 +1384,10 @@ PHP_FUNCTION( sqlsrv_free_stmt )
error_ctx->set_func(_FN_); error_ctx->set_func(_FN_);
// take only the statement resource // take only the statement resource
if( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "r", &stmt_r ) == FAILURE ) { if( zend_parse_parameters( ZEND_NUM_ARGS(), "r", &stmt_r ) == FAILURE ) {
// Check if it was a zval // Check if it was a zval
int zr = zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "z", &stmt_r ); int zr = zend_parse_parameters( ZEND_NUM_ARGS(), "z", &stmt_r );
CHECK_CUSTOM_ERROR(( zr == FAILURE ), error_ctx, SS_SQLSRV_ERROR_INVALID_FUNCTION_PARAMETER, _FN_ ) { CHECK_CUSTOM_ERROR(( zr == FAILURE ), error_ctx, SS_SQLSRV_ERROR_INVALID_FUNCTION_PARAMETER, _FN_ ) {
throw ss::SSException(); throw ss::SSException();
@ -1406,7 +1404,7 @@ PHP_FUNCTION( sqlsrv_free_stmt )
} }
// verify the resource so we know we're deleting a statement // verify the resource so we know we're deleting a statement
stmt = static_cast<ss_sqlsrv_stmt*>(zend_fetch_resource_ex(stmt_r TSRMLS_CC, ss_sqlsrv_stmt::resource_name, ss_sqlsrv_stmt::descriptor)); stmt = static_cast<ss_sqlsrv_stmt*>(zend_fetch_resource_ex(stmt_r, ss_sqlsrv_stmt::resource_name, ss_sqlsrv_stmt::descriptor));
// if sqlsrv_free_stmt was called on an already closed statment then we just return success. // if sqlsrv_free_stmt was called on an already closed statment then we just return success.
// zend_list_close sets the type of the closed statment to -1. // zend_list_close sets the type of the closed statment to -1.
@ -1445,7 +1443,7 @@ PHP_FUNCTION( sqlsrv_free_stmt )
} }
} }
void stmt_option_ss_scrollable:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC ) void stmt_option_ss_scrollable:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z )
{ {
CHECK_CUSTOM_ERROR(( Z_TYPE_P( value_z ) != IS_STRING ), stmt, SQLSRV_ERROR_INVALID_OPTION_SCROLLABLE ) { CHECK_CUSTOM_ERROR(( Z_TYPE_P( value_z ) != IS_STRING ), stmt, SQLSRV_ERROR_INVALID_OPTION_SCROLLABLE ) {
throw ss::SSException(); throw ss::SSException();
@ -1485,7 +1483,7 @@ void stmt_option_ss_scrollable:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_opt
THROW_SS_ERROR( stmt, SQLSRV_ERROR_INVALID_OPTION_SCROLLABLE ); THROW_SS_ERROR( stmt, SQLSRV_ERROR_INVALID_OPTION_SCROLLABLE );
} }
core_sqlsrv_set_scrollable( stmt, cursor_type TSRMLS_CC ); core_sqlsrv_set_scrollable( stmt, cursor_type );
} }
@ -1753,7 +1751,7 @@ sqlsrv_phptype determine_sqlsrv_php_type( _In_ ss_sqlsrv_stmt const* stmt, _In_
// The return value simply states whether or not if an error occurred during the determination. // The return value simply states whether or not if an error occurred during the determination.
// (All errors are posted here before returning.) // (All errors are posted here before returning.)
void determine_stmt_has_rows( _Inout_ ss_sqlsrv_stmt* stmt TSRMLS_DC ) void determine_stmt_has_rows( _Inout_ ss_sqlsrv_stmt* stmt )
{ {
SQLRETURN r = SQL_SUCCESS; SQLRETURN r = SQL_SUCCESS;
@ -1766,7 +1764,7 @@ void determine_stmt_has_rows( _Inout_ ss_sqlsrv_stmt* stmt TSRMLS_DC )
stmt->has_rows = false; stmt->has_rows = false;
// if there are no columns then there are no rows // if there are no columns then there are no rows
if( core::SQLNumResultCols( stmt TSRMLS_CC ) == 0 ) { if( core::SQLNumResultCols( stmt ) == 0 ) {
return; return;
} }
@ -1775,13 +1773,13 @@ void determine_stmt_has_rows( _Inout_ ss_sqlsrv_stmt* stmt TSRMLS_DC )
// fetch the first row, and then roll the cursor back to be prior to the first row // fetch the first row, and then roll the cursor back to be prior to the first row
if( stmt->cursor_type != SQL_CURSOR_FORWARD_ONLY ) { if( stmt->cursor_type != SQL_CURSOR_FORWARD_ONLY ) {
r = stmt->current_results->fetch( SQL_FETCH_FIRST, 0 TSRMLS_CC ); r = stmt->current_results->fetch( SQL_FETCH_FIRST, 0 );
if( SQL_SUCCEEDED( r )) { if( SQL_SUCCEEDED( r )) {
stmt->has_rows = true; stmt->has_rows = true;
CHECK_SQL_WARNING( r, stmt ); CHECK_SQL_WARNING( r, stmt );
// restore the cursor to its original position. // restore the cursor to its original position.
r = stmt->current_results->fetch( SQL_FETCH_ABSOLUTE, 0 TSRMLS_CC ); r = stmt->current_results->fetch( SQL_FETCH_ABSOLUTE, 0 );
SQLSRV_ASSERT(( r == SQL_NO_DATA ), "core_sqlsrv_has_rows: Should have scrolled the cursor to the beginning " SQLSRV_ASSERT(( r == SQL_NO_DATA ), "core_sqlsrv_has_rows: Should have scrolled the cursor to the beginning "
"of the result set." ); "of the result set." );
} }
@ -1792,7 +1790,7 @@ void determine_stmt_has_rows( _Inout_ ss_sqlsrv_stmt* stmt TSRMLS_DC )
// flag and simply skips the first fetch, knowing it was already done. It records its own // flag and simply skips the first fetch, knowing it was already done. It records its own
// flags to know if it should fetch on subsequent calls. // flags to know if it should fetch on subsequent calls.
r = core::SQLFetchScroll( stmt, SQL_FETCH_NEXT, 0 TSRMLS_CC ); r = core::SQLFetchScroll( stmt, SQL_FETCH_NEXT, 0 );
if( SQL_SUCCEEDED( r )) { if( SQL_SUCCEEDED( r )) {
stmt->has_rows = true; stmt->has_rows = true;
@ -1813,7 +1811,7 @@ SQLSMALLINT get_resultset_meta_data(_Inout_ sqlsrv_stmt * stmt)
if (num_cols == 0) { if (num_cols == 0) {
getMetaData = true; getMetaData = true;
if (stmt->column_count == ACTIVE_NUM_COLS_INVALID) { if (stmt->column_count == ACTIVE_NUM_COLS_INVALID) {
num_cols = core::SQLNumResultCols(stmt TSRMLS_CC); num_cols = core::SQLNumResultCols(stmt);
stmt->column_count = num_cols; stmt->column_count = num_cols;
} else { } else {
num_cols = stmt->column_count; num_cols = stmt->column_count;
@ -1824,7 +1822,7 @@ SQLSMALLINT get_resultset_meta_data(_Inout_ sqlsrv_stmt * stmt)
if (getMetaData) { if (getMetaData) {
for (int i = 0; i < num_cols; i++) { for (int i = 0; i < num_cols; i++) {
sqlsrv_malloc_auto_ptr<field_meta_data> core_meta_data; sqlsrv_malloc_auto_ptr<field_meta_data> core_meta_data;
core_meta_data = core_sqlsrv_field_metadata(stmt, i TSRMLS_CC); core_meta_data = core_sqlsrv_field_metadata(stmt, i);
stmt->current_meta_data.push_back(core_meta_data.get()); stmt->current_meta_data.push_back(core_meta_data.get());
core_meta_data.transferred(); core_meta_data.transferred();
} }
@ -1838,8 +1836,7 @@ SQLSMALLINT get_resultset_meta_data(_Inout_ sqlsrv_stmt * stmt)
return num_cols; return num_cols;
} }
void fetch_fields_common( _Inout_ ss_sqlsrv_stmt* stmt, _In_ zend_long fetch_type, _Out_ zval& fields, _In_ bool allow_empty_field_names void fetch_fields_common( _Inout_ ss_sqlsrv_stmt* stmt, _In_ zend_long fetch_type, _Out_ zval& fields, _In_ bool allow_empty_field_names )
TSRMLS_DC )
{ {
void* field_value = NULL; void* field_value = NULL;
sqlsrv_phptype sqlsrv_php_type; sqlsrv_phptype sqlsrv_php_type;
@ -1888,7 +1885,7 @@ void fetch_fields_common( _Inout_ ss_sqlsrv_stmt* stmt, _In_ zend_long fetch_typ
SQLLEN field_len = -1; SQLLEN field_len = -1;
core_sqlsrv_get_field( stmt, i, sqlsrv_php_type, true /*prefer string*/, core_sqlsrv_get_field( stmt, i, sqlsrv_php_type, true /*prefer string*/,
field_value, &field_len, false /*cache_field*/, &sqlsrv_php_type_out TSRMLS_CC ); field_value, &field_len, false /*cache_field*/, &sqlsrv_php_type_out );
zval field; zval field;
ZVAL_UNDEF( &field ); ZVAL_UNDEF( &field );
@ -1929,8 +1926,7 @@ void fetch_fields_common( _Inout_ ss_sqlsrv_stmt* stmt, _In_ zend_long fetch_typ
void parse_param_array( _Inout_ ss_sqlsrv_stmt* stmt, _Inout_ zval* param_array, zend_ulong index, _Out_ SQLSMALLINT& direction, void parse_param_array( _Inout_ ss_sqlsrv_stmt* stmt, _Inout_ zval* param_array, zend_ulong index, _Out_ SQLSMALLINT& direction,
_Out_ SQLSRV_PHPTYPE& php_out_type, _Out_ SQLSRV_ENCODING& encoding, _Out_ SQLSMALLINT& sql_type, _Out_ SQLSRV_PHPTYPE& php_out_type, _Out_ SQLSRV_ENCODING& encoding, _Out_ SQLSMALLINT& sql_type,
_Out_ SQLULEN& column_size, _Out_ SQLSMALLINT& decimal_digits TSRMLS_DC ) _Out_ SQLULEN& column_size, _Out_ SQLSMALLINT& decimal_digits )
{ {
zval* var_or_val = NULL; zval* var_or_val = NULL;
zval* temp = NULL; zval* temp = NULL;
@ -2165,7 +2161,7 @@ bool is_valid_sqlsrv_sqltype( _In_ sqlsrv_sqltype sql_type )
// verify an encoding given to type_and_encoding by looking through the list // verify an encoding given to type_and_encoding by looking through the list
// of standard encodings created at module initialization time // of standard encodings created at module initialization time
bool verify_and_set_encoding( _In_ const char* encoding_string, _Inout_ sqlsrv_phptype& phptype_encoding TSRMLS_DC ) bool verify_and_set_encoding( _In_ const char* encoding_string, _Inout_ sqlsrv_phptype& phptype_encoding )
{ {
void* encoding_temp = NULL; void* encoding_temp = NULL;
zend_ulong index = -1; zend_ulong index = -1;
@ -2195,8 +2191,7 @@ void type_and_size_calc( INTERNAL_FUNCTION_PARAMETERS, _In_ int type )
size_t size_len = 0; size_t size_len = 0;
int size = 0; int size = 0;
if( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "s", &size_p, &size_len ) == FAILURE ) { if( zend_parse_parameters( ZEND_NUM_ARGS(), "s", &size_p, &size_len ) == FAILURE ) {
return; return;
} }
if (size_p) { if (size_p) {
@ -2246,8 +2241,7 @@ void type_and_precision_calc( INTERNAL_FUNCTION_PARAMETERS, _In_ int type )
zend_long prec = SQLSRV_INVALID_PRECISION; zend_long prec = SQLSRV_INVALID_PRECISION;
zend_long scale = SQLSRV_INVALID_SCALE; zend_long scale = SQLSRV_INVALID_SCALE;
if( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "|ll", &prec, &scale ) == FAILURE ) { if( zend_parse_parameters( ZEND_NUM_ARGS(), "|ll", &prec, &scale ) == FAILURE ) {
return; return;
} }
@ -2290,12 +2284,11 @@ void type_and_encoding( INTERNAL_FUNCTION_PARAMETERS, _In_ int type )
sqlsrv_php_type.typeinfo.type = type; sqlsrv_php_type.typeinfo.type = type;
sqlsrv_php_type.typeinfo.encoding = SQLSRV_ENCODING_INVALID; sqlsrv_php_type.typeinfo.encoding = SQLSRV_ENCODING_INVALID;
if( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "s", &encoding_param, &encoding_param_len ) == FAILURE ) { if( zend_parse_parameters( ZEND_NUM_ARGS(), "s", &encoding_param, &encoding_param_len ) == FAILURE ) {
ZVAL_LONG( return_value, sqlsrv_php_type.value ); ZVAL_LONG( return_value, sqlsrv_php_type.value );
} }
if( !verify_and_set_encoding( encoding_param, sqlsrv_php_type TSRMLS_CC )) { if( !verify_and_set_encoding( encoding_param, sqlsrv_php_type )) {
LOG( SEV_ERROR, "Invalid encoding for php type." ); LOG( SEV_ERROR, "Invalid encoding for php type." );
} }

View file

@ -34,13 +34,13 @@ unsigned int current_log_subsystem = LOG_UTIL;
sqlsrv_error_const* get_error_message( _In_ unsigned int sqlsrv_error_code ); sqlsrv_error_const* get_error_message( _In_ unsigned int sqlsrv_error_code );
void copy_error_to_zval( _Inout_ zval* error_z, _In_ sqlsrv_error_const* error, _Inout_ zval* reported_chain, _Inout_ zval* ignored_chain, void copy_error_to_zval( _Inout_ zval* error_z, _In_ sqlsrv_error_const* error, _Inout_ zval* reported_chain, _Inout_ zval* ignored_chain,
_In_ bool warning TSRMLS_DC ); _In_ bool warning );
bool ignore_warning( _In_ char* sql_state, _In_ int native_code TSRMLS_DC ); bool ignore_warning( _In_ char* sql_state, _In_ int native_code );
bool handle_errors_and_warnings( _Inout_ sqlsrv_context& ctx, _Inout_ zval* reported_chain, _Inout_ zval* ignored_chain, _In_ logging_severity log_severity, bool handle_errors_and_warnings( _Inout_ sqlsrv_context& ctx, _Inout_ zval* reported_chain, _Inout_ zval* ignored_chain, _In_ logging_severity log_severity,
_In_ unsigned int sqlsrv_error_code, _In_ bool warning, _In_opt_ va_list* print_args TSRMLS_DC ); _In_ unsigned int sqlsrv_error_code, _In_ bool warning, _In_opt_ va_list* print_args );
int sqlsrv_merge_zend_hash_dtor( _Inout_ zval* dest TSRMLS_DC ); int sqlsrv_merge_zend_hash_dtor( _Inout_ zval* dest );
bool sqlsrv_merge_zend_hash( _Inout_ zval* dest_z, zval const* src_z TSRMLS_DC ); bool sqlsrv_merge_zend_hash( _Inout_ zval* dest_z, zval const* src_z );
} }
@ -451,12 +451,12 @@ ss_error SS_ERRORS[] = {
}; };
// check the global variables of sqlsrv severity whether the message qualifies to be logged with the LOG macro // check the global variables of sqlsrv severity whether the message qualifies to be logged with the LOG macro
bool ss_severity_check(_In_ unsigned int severity TSRMLS_DC) bool ss_severity_check(_In_ unsigned int severity)
{ {
return ((severity & SQLSRV_G(log_severity)) && (SQLSRV_G(current_subsystem) & SQLSRV_G(log_subsystems))); return ((severity & SQLSRV_G(log_severity)) && (SQLSRV_G(current_subsystem) & SQLSRV_G(log_subsystems)));
} }
bool ss_error_handler( _Inout_ sqlsrv_context& ctx, _In_ unsigned int sqlsrv_error_code, _In_ bool warning TSRMLS_DC, _In_opt_ va_list* print_args ) bool ss_error_handler( _Inout_ sqlsrv_context& ctx, _In_ unsigned int sqlsrv_error_code, _In_ bool warning, _In_opt_ va_list* print_args )
{ {
logging_severity severity = SEV_ERROR; logging_severity severity = SEV_ERROR;
if( warning && !SQLSRV_G( warnings_return_as_errors )) { if( warning && !SQLSRV_G( warnings_return_as_errors )) {
@ -464,7 +464,7 @@ bool ss_error_handler( _Inout_ sqlsrv_context& ctx, _In_ unsigned int sqlsrv_err
} }
return handle_errors_and_warnings( ctx, &SQLSRV_G( errors ), &SQLSRV_G( warnings ), severity, sqlsrv_error_code, warning, return handle_errors_and_warnings( ctx, &SQLSRV_G( errors ), &SQLSRV_G( warnings ), severity, sqlsrv_error_code, warning,
print_args TSRMLS_CC ); print_args );
} }
// sqlsrv_errors( [int $errorsAndOrWarnings] ) // sqlsrv_errors( [int $errorsAndOrWarnings] )
@ -512,7 +512,7 @@ PHP_FUNCTION( sqlsrv_errors )
LOG_FUNCTION( "sqlsrv_errors" ); LOG_FUNCTION( "sqlsrv_errors" );
if(( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "|l", &flags ) == FAILURE ) || if(( zend_parse_parameters( ZEND_NUM_ARGS(), "|l", &flags ) == FAILURE ) ||
( flags != SQLSRV_ERR_ALL && flags != SQLSRV_ERR_ERRORS && flags != SQLSRV_ERR_WARNINGS )) { ( flags != SQLSRV_ERR_ALL && flags != SQLSRV_ERR_ERRORS && flags != SQLSRV_ERR_WARNINGS )) {
LOG( SEV_ERROR, "An invalid parameter was passed to %1!s!.", _FN_ ); LOG( SEV_ERROR, "An invalid parameter was passed to %1!s!.", _FN_ );
RETURN_FALSE; RETURN_FALSE;
@ -528,13 +528,13 @@ PHP_FUNCTION( sqlsrv_errors )
#endif #endif
if( flags == SQLSRV_ERR_ALL || flags == SQLSRV_ERR_ERRORS ) { if( flags == SQLSRV_ERR_ALL || flags == SQLSRV_ERR_ERRORS ) {
if( Z_TYPE( SQLSRV_G( errors )) == IS_ARRAY && !sqlsrv_merge_zend_hash( &err_z, &SQLSRV_G( errors ) TSRMLS_CC )) { if( Z_TYPE( SQLSRV_G( errors )) == IS_ARRAY && !sqlsrv_merge_zend_hash( &err_z, &SQLSRV_G( errors ) )) {
zval_ptr_dtor(&err_z); zval_ptr_dtor(&err_z);
RETURN_FALSE; RETURN_FALSE;
} }
} }
if( flags == SQLSRV_ERR_ALL || flags == SQLSRV_ERR_WARNINGS ) { if( flags == SQLSRV_ERR_ALL || flags == SQLSRV_ERR_WARNINGS ) {
if( Z_TYPE( SQLSRV_G( warnings )) == IS_ARRAY && !sqlsrv_merge_zend_hash( &err_z, &SQLSRV_G( warnings ) TSRMLS_CC )) { if( Z_TYPE( SQLSRV_G( warnings )) == IS_ARRAY && !sqlsrv_merge_zend_hash( &err_z, &SQLSRV_G( warnings ) )) {
zval_ptr_dtor(&err_z); zval_ptr_dtor(&err_z);
RETURN_FALSE; RETURN_FALSE;
} }
@ -574,7 +574,7 @@ PHP_FUNCTION( sqlsrv_configure )
RETVAL_FALSE; RETVAL_FALSE;
reset_errors( TSRMLS_C ); reset_errors();
try { try {
@ -582,7 +582,7 @@ PHP_FUNCTION( sqlsrv_configure )
error_ctx = new ( sqlsrv_malloc( sizeof( sqlsrv_context ))) sqlsrv_context( 0, ss_error_handler, NULL ); error_ctx = new ( sqlsrv_malloc( sizeof( sqlsrv_context ))) sqlsrv_context( 0, ss_error_handler, NULL );
error_ctx->set_func(_FN_); error_ctx->set_func(_FN_);
int zr = zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "sz", &option, &option_len, &value_z ); int zr = zend_parse_parameters( ZEND_NUM_ARGS(), "sz", &option, &option_len, &value_z );
CHECK_CUSTOM_ERROR(( zr == FAILURE ), error_ctx, SS_SQLSRV_ERROR_INVALID_FUNCTION_PARAMETER, _FN_ ) { CHECK_CUSTOM_ERROR(( zr == FAILURE ), error_ctx, SS_SQLSRV_ERROR_INVALID_FUNCTION_PARAMETER, _FN_ ) {
throw ss::SSException(); throw ss::SSException();
@ -694,7 +694,7 @@ PHP_FUNCTION( sqlsrv_get_config )
LOG_FUNCTION( "sqlsrv_get_config" ); LOG_FUNCTION( "sqlsrv_get_config" );
reset_errors( TSRMLS_C ); reset_errors();
try { try {
@ -702,7 +702,7 @@ PHP_FUNCTION( sqlsrv_get_config )
error_ctx = new ( sqlsrv_malloc( sizeof( sqlsrv_context ))) sqlsrv_context( 0, ss_error_handler, NULL ); error_ctx = new ( sqlsrv_malloc( sizeof( sqlsrv_context ))) sqlsrv_context( 0, ss_error_handler, NULL );
error_ctx->set_func(_FN_); error_ctx->set_func(_FN_);
int zr = zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "s", &option, &option_len ); int zr = zend_parse_parameters( ZEND_NUM_ARGS(), "s", &option, &option_len );
CHECK_CUSTOM_ERROR(( zr == FAILURE ), error_ctx, SS_SQLSRV_ERROR_INVALID_FUNCTION_PARAMETER, _FN_ ) { CHECK_CUSTOM_ERROR(( zr == FAILURE ), error_ctx, SS_SQLSRV_ERROR_INVALID_FUNCTION_PARAMETER, _FN_ ) {
throw ss::SSException(); throw ss::SSException();
@ -761,7 +761,7 @@ sqlsrv_error_const* get_error_message( _In_ unsigned int sqlsrv_error_code ) {
} }
void copy_error_to_zval( _Inout_ zval* error_z, _In_ sqlsrv_error_const* error, _Inout_ zval* reported_chain, _Inout_ zval* ignored_chain, void copy_error_to_zval( _Inout_ zval* error_z, _In_ sqlsrv_error_const* error, _Inout_ zval* reported_chain, _Inout_ zval* ignored_chain,
_In_ bool warning TSRMLS_DC ) _In_ bool warning )
{ {
#if PHP_VERSION_ID < 70300 #if PHP_VERSION_ID < 70300
if (array_init(error_z) == FAILURE) { if (array_init(error_z) == FAILURE) {
@ -813,7 +813,7 @@ void copy_error_to_zval( _Inout_ zval* error_z, _In_ sqlsrv_error_const* error,
{ {
// if the warning is part of the ignored warning list than // if the warning is part of the ignored warning list than
// add to the ignored chain if the ignored chain is not null. // add to the ignored chain if the ignored chain is not null.
if( warning && ignore_warning( reinterpret_cast<char*>(error->sqlstate), error->native_code TSRMLS_CC ) && if( warning && ignore_warning( reinterpret_cast<char*>(error->sqlstate), error->native_code ) &&
ignored_chain != NULL ) { ignored_chain != NULL ) {
if( add_next_index_zval( ignored_chain, error_z ) == FAILURE ) { if( add_next_index_zval( ignored_chain, error_z ) == FAILURE ) {
@ -841,7 +841,7 @@ void copy_error_to_zval( _Inout_ zval* error_z, _In_ sqlsrv_error_const* error,
} }
bool handle_errors_and_warnings( _Inout_ sqlsrv_context& ctx, _Inout_ zval* reported_chain, _Inout_ zval* ignored_chain, _In_ logging_severity log_severity, bool handle_errors_and_warnings( _Inout_ sqlsrv_context& ctx, _Inout_ zval* reported_chain, _Inout_ zval* ignored_chain, _In_ logging_severity log_severity,
_In_ unsigned int sqlsrv_error_code, _In_ bool warning, _In_opt_ va_list* print_args TSRMLS_DC ) _In_ unsigned int sqlsrv_error_code, _In_ bool warning, _In_opt_ va_list* print_args )
{ {
bool result = true; bool result = true;
bool errors_ignored = false; bool errors_ignored = false;
@ -886,16 +886,16 @@ bool handle_errors_and_warnings( _Inout_ sqlsrv_context& ctx, _Inout_ zval* repo
if( sqlsrv_error_code != SQLSRV_ERROR_ODBC ) { if( sqlsrv_error_code != SQLSRV_ERROR_ODBC ) {
core_sqlsrv_format_driver_error( ctx, get_error_message( sqlsrv_error_code ), error, log_severity TSRMLS_CC, print_args ); core_sqlsrv_format_driver_error( ctx, get_error_message( sqlsrv_error_code ), error, log_severity, print_args );
copy_error_to_zval( &error_z, error, reported_chain, ignored_chain, warning TSRMLS_CC ); copy_error_to_zval( &error_z, error, reported_chain, ignored_chain, warning );
} }
SQLSMALLINT record_number = 0; SQLSMALLINT record_number = 0;
do { do {
result = core_sqlsrv_get_odbc_error( ctx, ++record_number, error, log_severity TSRMLS_CC ); result = core_sqlsrv_get_odbc_error( ctx, ++record_number, error, log_severity );
if( result ) { if( result ) {
copy_error_to_zval( &error_z, error, reported_chain, ignored_chain, warning TSRMLS_CC ); copy_error_to_zval( &error_z, error, reported_chain, ignored_chain, warning );
} }
} while( result ); } while( result );
@ -933,7 +933,7 @@ bool handle_errors_and_warnings( _Inout_ sqlsrv_context& ctx, _Inout_ zval* repo
// return whether or not a warning should be ignored or returned as an error if WarningsReturnAsErrors is true // return whether or not a warning should be ignored or returned as an error if WarningsReturnAsErrors is true
// see RINIT in init.cpp for information about which errors are ignored. // see RINIT in init.cpp for information about which errors are ignored.
bool ignore_warning( _In_ char* sql_state, _In_ int native_code TSRMLS_DC ) bool ignore_warning( _In_ char* sql_state, _In_ int native_code )
{ {
zend_ulong index = -1; zend_ulong index = -1;
zend_string* key = NULL; zend_string* key = NULL;
@ -954,7 +954,7 @@ bool ignore_warning( _In_ char* sql_state, _In_ int native_code TSRMLS_DC )
return false; return false;
} }
int sqlsrv_merge_zend_hash_dtor( _Inout_ zval* dest TSRMLS_DC ) int sqlsrv_merge_zend_hash_dtor( _Inout_ zval* dest )
{ {
zval_ptr_dtor( dest ); zval_ptr_dtor( dest );
return ZEND_HASH_APPLY_REMOVE; return ZEND_HASH_APPLY_REMOVE;
@ -962,7 +962,7 @@ int sqlsrv_merge_zend_hash_dtor( _Inout_ zval* dest TSRMLS_DC )
// sqlsrv_merge_zend_hash // sqlsrv_merge_zend_hash
// merge a source hash into a dest hash table and return any errors. // merge a source hash into a dest hash table and return any errors.
bool sqlsrv_merge_zend_hash( _Inout_ zval* dest_z, zval const* src_z TSRMLS_DC ) bool sqlsrv_merge_zend_hash( _Inout_ zval* dest_z, zval const* src_z )
{ {
if( Z_TYPE_P( dest_z ) != IS_ARRAY && Z_TYPE_P( dest_z ) != IS_NULL ) DIE( "dest_z must be an array or null" ); if( Z_TYPE_P( dest_z ) != IS_ARRAY && Z_TYPE_P( dest_z ) != IS_NULL ) DIE( "dest_z must be an array or null" );
if( Z_TYPE_P( src_z ) != IS_ARRAY && Z_TYPE_P( src_z ) != IS_NULL ) DIE( "src_z must be an array or null" ); if( Z_TYPE_P( src_z ) != IS_ARRAY && Z_TYPE_P( src_z ) != IS_NULL ) DIE( "src_z must be an array or null" );
@ -978,14 +978,14 @@ bool sqlsrv_merge_zend_hash( _Inout_ zval* dest_z, zval const* src_z TSRMLS_DC )
ZEND_HASH_FOREACH_KEY_VAL( src_ht, index, key, value_z ) { ZEND_HASH_FOREACH_KEY_VAL( src_ht, index, key, value_z ) {
if ( !value_z ) { if ( !value_z ) {
zend_hash_apply( Z_ARRVAL_P(dest_z), sqlsrv_merge_zend_hash_dtor TSRMLS_CC ); zend_hash_apply( Z_ARRVAL_P(dest_z), sqlsrv_merge_zend_hash_dtor );
return false; return false;
} }
int result = add_next_index_zval( dest_z, value_z ); int result = add_next_index_zval( dest_z, value_z );
if( result == FAILURE ) { if( result == FAILURE ) {
zend_hash_apply( Z_ARRVAL_P( dest_z ), sqlsrv_merge_zend_hash_dtor TSRMLS_CC ); zend_hash_apply( Z_ARRVAL_P( dest_z ), sqlsrv_merge_zend_hash_dtor );
return false; return false;
} }
Z_TRY_ADDREF_P( value_z ); Z_TRY_ADDREF_P( value_z );