PHP 8.1 dev (#1282)
This commit is contained in:
parent
277872619e
commit
5e607a802c
|
@ -34,7 +34,7 @@ namespace {
|
|||
|
||||
const char LAST_INSERT_ID_QUERY[] = "SELECT @@IDENTITY;";
|
||||
const size_t LAST_INSERT_ID_BUFF_LEN = 50; // size of the buffer to hold the string value of the last inserted id, which may be an int, bigint, decimal(p,0) or numeric(p,0)
|
||||
const char SEQUENCE_CURRENT_VALUE_QUERY[] = "SELECT current_value FROM sys.sequences WHERE name=N'%s'";
|
||||
const char SEQUENCE_CURRENT_VALUE_QUERY[] = "SELECT current_value FROM sys.sequences WHERE name=N'%s'";
|
||||
const int LAST_INSERT_ID_QUERY_MAX_LEN = sizeof( SEQUENCE_CURRENT_VALUE_QUERY ) + SQL_MAX_SQLSERVERNAME + 2; // include the quotes
|
||||
|
||||
// List of PDO supported connection options.
|
||||
|
@ -436,36 +436,66 @@ const connection_option PDO_CONN_OPTS[] = {
|
|||
};
|
||||
|
||||
|
||||
#if PHP_VERSION_ID < 80100
|
||||
// close the connection
|
||||
int pdo_sqlsrv_dbh_close( _Inout_ pdo_dbh_t *dbh );
|
||||
int pdo_sqlsrv_dbh_close(_Inout_ pdo_dbh_t *dbh);
|
||||
|
||||
// execute queries
|
||||
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 );
|
||||
zend_long pdo_sqlsrv_dbh_do( _Inout_ pdo_dbh_t *dbh, _In_reads_bytes_(sql_len) const char *sql, _In_ size_t sql_len );
|
||||
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);
|
||||
zend_long pdo_sqlsrv_dbh_do(_Inout_ pdo_dbh_t *dbh, _In_reads_bytes_(sql_len) const char *sql, _In_ size_t sql_len);
|
||||
|
||||
// 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,
|
||||
enum pdo_param_type paramtype);
|
||||
|
||||
// transaction support functions
|
||||
int pdo_sqlsrv_dbh_commit( _Inout_ pdo_dbh_t *dbh );
|
||||
int pdo_sqlsrv_dbh_begin( _Inout_ pdo_dbh_t *dbh );
|
||||
int pdo_sqlsrv_dbh_rollback( _Inout_ pdo_dbh_t *dbh );
|
||||
int pdo_sqlsrv_dbh_commit(_Inout_ pdo_dbh_t *dbh);
|
||||
int pdo_sqlsrv_dbh_begin(_Inout_ pdo_dbh_t *dbh);
|
||||
int pdo_sqlsrv_dbh_rollback(_Inout_ pdo_dbh_t *dbh);
|
||||
|
||||
// attribute functions
|
||||
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 );
|
||||
|
||||
// return more information
|
||||
int pdo_sqlsrv_dbh_return_error( _In_ pdo_dbh_t *dbh, _In_opt_ pdo_stmt_t *stmt,
|
||||
_Out_ zval *info);
|
||||
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);
|
||||
|
||||
// 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 );
|
||||
char * pdo_sqlsrv_dbh_last_id(_Inout_ pdo_dbh_t *dbh, _In_z_ const char *name, _Out_ size_t* len);
|
||||
|
||||
// return more information
|
||||
int pdo_sqlsrv_dbh_return_error(_In_ pdo_dbh_t *dbh, _In_opt_ pdo_stmt_t *stmt, _Out_ zval *info);
|
||||
|
||||
#else
|
||||
// close the connection
|
||||
void pdo_sqlsrv_dbh_close(_Inout_ pdo_dbh_t *dbh);
|
||||
|
||||
// execute queries
|
||||
bool pdo_sqlsrv_dbh_prepare(_Inout_ pdo_dbh_t *dbh, _In_ zend_string *sql,
|
||||
_Inout_ pdo_stmt_t *stmt, _In_ zval *driver_options);
|
||||
zend_long pdo_sqlsrv_dbh_do(_Inout_ pdo_dbh_t *dbh, _In_ const zend_string *sql);
|
||||
|
||||
// quote a string, meaning put quotes around it and escape any quotes within it
|
||||
zend_string* pdo_sqlsrv_dbh_quote(_Inout_ pdo_dbh_t* dbh, _In_ const zend_string *unquoted, _In_ enum pdo_param_type paramtype);
|
||||
|
||||
// transaction support functions
|
||||
bool pdo_sqlsrv_dbh_commit(_Inout_ pdo_dbh_t *dbh);
|
||||
bool pdo_sqlsrv_dbh_begin(_Inout_ pdo_dbh_t *dbh);
|
||||
bool pdo_sqlsrv_dbh_rollback(_Inout_ pdo_dbh_t *dbh);
|
||||
|
||||
// attribute functions
|
||||
bool 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);
|
||||
|
||||
// return the last id generated by an executed SQL statement
|
||||
zend_string * pdo_sqlsrv_dbh_last_id(_Inout_ pdo_dbh_t *dbh, _In_ const zend_string *name);
|
||||
|
||||
// return more information
|
||||
void pdo_sqlsrv_dbh_return_error(_In_ pdo_dbh_t *dbh, _In_opt_ pdo_stmt_t *stmt, _Out_ zval *info);
|
||||
|
||||
#endif
|
||||
|
||||
// additional methods are supported in this function
|
||||
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
|
||||
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 );
|
||||
|
||||
struct pdo_dbh_methods pdo_sqlsrv_dbh_methods = {
|
||||
|
||||
|
@ -632,15 +662,22 @@ int pdo_sqlsrv_db_handle_factory( _Inout_ pdo_dbh_t *dbh, _In_opt_ zval *driver_
|
|||
// Parameters:
|
||||
// dbh - The PDO managed connection object.
|
||||
// Return:
|
||||
// Always returns 1 for success.
|
||||
// Always returns 1 for success. (for PHP_VERSION_ID < 80100)
|
||||
#if PHP_VERSION_ID < 80100
|
||||
int pdo_sqlsrv_dbh_close( _Inout_ pdo_dbh_t *dbh )
|
||||
#else
|
||||
void pdo_sqlsrv_dbh_close(_Inout_ pdo_dbh_t *dbh)
|
||||
#endif
|
||||
{
|
||||
LOG( SEV_NOTICE, "pdo_sqlsrv_dbh_close: entering" );
|
||||
|
||||
// if the connection didn't complete properly, driver_data isn't initialized.
|
||||
if( dbh->driver_data == NULL ) {
|
||||
|
||||
#if PHP_VERSION_ID < 80100
|
||||
return 1;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
PDO_RESET_DBH_ERROR;
|
||||
|
@ -649,8 +686,10 @@ int pdo_sqlsrv_dbh_close( _Inout_ pdo_dbh_t *dbh )
|
|||
core_sqlsrv_close( reinterpret_cast<sqlsrv_conn*>( dbh->driver_data ) );
|
||||
dbh->driver_data = NULL;
|
||||
|
||||
#if PHP_VERSION_ID < 80100
|
||||
// always return success that the connection is closed
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
// pdo_sqlsrv_dbh_prepare
|
||||
|
@ -664,8 +703,12 @@ int pdo_sqlsrv_dbh_close( _Inout_ pdo_dbh_t *dbh )
|
|||
// driver_options - User provided list of statement options.
|
||||
// Return:
|
||||
// 0 for failure, 1 for success.
|
||||
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 )
|
||||
#if PHP_VERSION_ID < 80100
|
||||
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)
|
||||
#else
|
||||
bool pdo_sqlsrv_dbh_prepare(_Inout_ pdo_dbh_t *dbh, _In_ zend_string *sql_zstr, _Inout_ pdo_stmt_t *stmt, _In_ zval *driver_options)
|
||||
#endif
|
||||
{
|
||||
PDO_RESET_DBH_ERROR;
|
||||
PDO_VALIDATE_CONN;
|
||||
|
@ -707,27 +750,44 @@ int pdo_sqlsrv_dbh_prepare( _Inout_ pdo_dbh_t *dbh, _In_reads_(sql_len) const ch
|
|||
driver_stmt->buffered_query_limit = driver_dbh->client_buffer_max_size;
|
||||
}
|
||||
|
||||
#if PHP_VERSION_ID >= 80100
|
||||
zend_string* sql_rewrite_zstr = NULL;
|
||||
const char* sql = ZSTR_VAL(sql_zstr);
|
||||
size_t sql_len = ZSTR_LEN(sql_zstr);
|
||||
#endif
|
||||
|
||||
// rewrite named parameters in the query to positional parameters if we aren't letting PDO do the
|
||||
// parameter substitution for us
|
||||
if( stmt->supports_placeholders != PDO_PLACEHOLDER_NONE ) {
|
||||
|
||||
// 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.
|
||||
#if PHP_VERSION_ID < 80100
|
||||
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();
|
||||
}
|
||||
// if parameter substitution happened, use that query instead of the original
|
||||
if( sql_rewrite != 0) {
|
||||
if (sql_rewrite != 0) {
|
||||
sql = sql_rewrite;
|
||||
sql_len = sql_rewrite_len;
|
||||
}
|
||||
#else
|
||||
int zr = pdo_parse_params(stmt, sql_zstr, &sql_rewrite_zstr);
|
||||
CHECK_ZEND_ERROR(zr, driver_dbh, PDO_SQLSRV_ERROR_PARAM_PARSE) {
|
||||
throw core::CoreException();
|
||||
}
|
||||
|
||||
// if parameter substitution happened, use that query instead of the original
|
||||
if (sql_rewrite_zstr != NULL) {
|
||||
sql = ZSTR_VAL(sql_rewrite_zstr);
|
||||
sql_len = ZSTR_LEN(sql_rewrite_zstr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if( !driver_stmt->direct_query && stmt->supports_placeholders != PDO_PLACEHOLDER_NONE ) {
|
||||
|
||||
core_sqlsrv_prepare( driver_stmt, sql, sql_len );
|
||||
core_sqlsrv_prepare(driver_stmt, sql, sql_len);
|
||||
}
|
||||
else if( driver_stmt->direct_query ) {
|
||||
|
||||
|
@ -739,14 +799,26 @@ int pdo_sqlsrv_dbh_prepare( _Inout_ pdo_dbh_t *dbh, _In_reads_(sql_len) const ch
|
|||
driver_stmt->direct_query_subst_string = estrdup( sql );
|
||||
driver_stmt->direct_query_subst_string_len = sql_len;
|
||||
}
|
||||
|
||||
#if PHP_VERSION_ID >= 80100
|
||||
if (sql_rewrite_zstr != NULL) {
|
||||
zend_string_release(sql_rewrite_zstr);
|
||||
}
|
||||
#endif
|
||||
|
||||
// else if stmt->support_placeholders == PDO_PLACEHOLDER_NONE means that stmt->active_query_string will be
|
||||
// set to the substituted query
|
||||
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 );
|
||||
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,
|
||||
static_cast<int>(stmt->query_stringlen), placeholders );
|
||||
core::sqlsrv_zend_hash_init(*driver_dbh, placeholders, 5, ZVAL_PTR_DTOR /* dtor */, 0 /* persistent */);
|
||||
#if PHP_VERSION_ID < 80100
|
||||
sql_parser = new (sqlsrv_malloc(sizeof(sql_string_parser))) sql_string_parser(*driver_dbh, stmt->query_string,
|
||||
static_cast<int>(stmt->query_stringlen), placeholders);
|
||||
#else
|
||||
sql_parser = new (sqlsrv_malloc(sizeof(sql_string_parser))) sql_string_parser(*driver_dbh, ZSTR_VAL(stmt->query_string),
|
||||
ZSTR_LEN(stmt->query_string), placeholders);
|
||||
#endif
|
||||
sql_parser->parse_sql_string();
|
||||
driver_stmt->placeholders = placeholders;
|
||||
placeholders.transferred();
|
||||
|
@ -772,7 +844,11 @@ int pdo_sqlsrv_dbh_prepare( _Inout_ pdo_dbh_t *dbh, _In_reads_(sql_len) const ch
|
|||
reinterpret_cast<const char*>( driver_dbh->last_error()->sqlstate ));
|
||||
}
|
||||
|
||||
#if PHP_VERSION_ID < 80100
|
||||
return 0;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
// catch any errant exception and die
|
||||
|
@ -781,7 +857,11 @@ int pdo_sqlsrv_dbh_prepare( _Inout_ pdo_dbh_t *dbh, _In_reads_(sql_len) const ch
|
|||
DIE( "pdo_sqlsrv_dbh_prepare: Unknown exception caught." );
|
||||
}
|
||||
|
||||
#if PHP_VERSION_ID < 80100
|
||||
return 1;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -795,7 +875,11 @@ int pdo_sqlsrv_dbh_prepare( _Inout_ pdo_dbh_t *dbh, _In_reads_(sql_len) const ch
|
|||
// sql_len - length of sql query
|
||||
// Return
|
||||
// # of rows affected, -1 for an error.
|
||||
#if PHP_VERSION_ID < 80100
|
||||
zend_long pdo_sqlsrv_dbh_do( _Inout_ pdo_dbh_t *dbh, _In_reads_bytes_(sql_len) const char *sql, _In_ size_t sql_len )
|
||||
#else
|
||||
zend_long pdo_sqlsrv_dbh_do(_Inout_ pdo_dbh_t *dbh, _In_ const zend_string *sql)
|
||||
#endif
|
||||
{
|
||||
PDO_RESET_DBH_ERROR;
|
||||
PDO_VALIDATE_CONN;
|
||||
|
@ -823,8 +907,11 @@ zend_long pdo_sqlsrv_dbh_do( _Inout_ pdo_dbh_t *dbh, _In_reads_bytes_(sql_len) c
|
|||
NULL /*valid_stmt_opts*/, pdo_sqlsrv_handle_stmt_error, &temp_stmt );
|
||||
driver_stmt->set_func( __FUNCTION__ );
|
||||
|
||||
SQLRETURN execReturn = core_sqlsrv_execute( driver_stmt, sql, static_cast<int>( sql_len ) );
|
||||
|
||||
#if PHP_VERSION_ID < 80100
|
||||
SQLRETURN execReturn = core_sqlsrv_execute(driver_stmt, sql, static_cast<int>(sql_len));
|
||||
#else
|
||||
SQLRETURN execReturn = core_sqlsrv_execute(driver_stmt, ZSTR_VAL(sql), ZSTR_LEN(sql));
|
||||
#endif
|
||||
// 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.
|
||||
|
||||
|
@ -883,8 +970,13 @@ zend_long pdo_sqlsrv_dbh_do( _Inout_ pdo_dbh_t *dbh, _In_reads_bytes_(sql_len) c
|
|||
// Parameters:
|
||||
// dbh - The PDO managed connection object.
|
||||
// Return:
|
||||
// 0 for failure and 1 for success.
|
||||
int pdo_sqlsrv_dbh_begin( _Inout_ pdo_dbh_t *dbh )
|
||||
// 0 for failure and 1 for success. (if PHP_VERSION_ID < 80100)
|
||||
// Return true if currently inside a transaction, false otherwise
|
||||
#if PHP_VERSION_ID < 80100
|
||||
int pdo_sqlsrv_dbh_begin(_Inout_ pdo_dbh_t *dbh)
|
||||
#else
|
||||
bool pdo_sqlsrv_dbh_begin(_Inout_ pdo_dbh_t *dbh)
|
||||
#endif
|
||||
{
|
||||
PDO_RESET_DBH_ERROR;
|
||||
PDO_VALIDATE_CONN;
|
||||
|
@ -902,18 +994,29 @@ int pdo_sqlsrv_dbh_begin( _Inout_ pdo_dbh_t *dbh )
|
|||
|
||||
core_sqlsrv_begin_transaction( driver_conn );
|
||||
|
||||
#if PHP_VERSION_ID < 80100
|
||||
return 1;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
catch( core::CoreException& ) {
|
||||
|
||||
#if PHP_VERSION_ID < 80100
|
||||
return 0;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
catch( ... ) {
|
||||
|
||||
DIE ("pdo_sqlsrv_dbh_begin: Uncaught exception occurred.");
|
||||
}
|
||||
// Should not have reached here but adding this due to compilation warnings
|
||||
#if PHP_VERSION_ID < 80100
|
||||
return 0;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -927,8 +1030,13 @@ int pdo_sqlsrv_dbh_begin( _Inout_ pdo_dbh_t *dbh )
|
|||
// Parameters:
|
||||
// dbh - The PDO managed connection object.
|
||||
// Return:
|
||||
// 0 for failure and 1 for success.
|
||||
int pdo_sqlsrv_dbh_commit( _Inout_ pdo_dbh_t *dbh )
|
||||
// 0 for failure and 1 for success. (if PHP_VERSION_ID < 80100)
|
||||
// Return true for success and false otherwise
|
||||
#if PHP_VERSION_ID < 80100
|
||||
int pdo_sqlsrv_dbh_commit(_Inout_ pdo_dbh_t *dbh)
|
||||
#else
|
||||
bool pdo_sqlsrv_dbh_commit(_Inout_ pdo_dbh_t *dbh)
|
||||
#endif
|
||||
{
|
||||
PDO_RESET_DBH_ERROR;
|
||||
PDO_VALIDATE_CONN;
|
||||
|
@ -946,18 +1054,30 @@ int pdo_sqlsrv_dbh_commit( _Inout_ pdo_dbh_t *dbh )
|
|||
|
||||
core_sqlsrv_commit( driver_conn );
|
||||
|
||||
#if PHP_VERSION_ID < 80100
|
||||
return 1;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
catch( core::CoreException& ) {
|
||||
|
||||
#if PHP_VERSION_ID < 80100
|
||||
return 0;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
catch( ... ) {
|
||||
|
||||
DIE ("pdo_sqlsrv_dbh_commit: Uncaught exception occurred.");
|
||||
}
|
||||
|
||||
// Should not have reached here but adding this due to compilation warnings
|
||||
#if PHP_VERSION_ID < 80100
|
||||
return 0;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
// pdo_sqlsrv_dbh_rollback
|
||||
|
@ -969,8 +1089,13 @@ int pdo_sqlsrv_dbh_commit( _Inout_ pdo_dbh_t *dbh )
|
|||
// Parameters:
|
||||
// dbh - The PDO managed connection object.
|
||||
// Return:
|
||||
// 0 for failure and 1 for success.
|
||||
int pdo_sqlsrv_dbh_rollback( _Inout_ pdo_dbh_t *dbh )
|
||||
// 0 for failure and 1 for success. (if PHP_VERSION_ID < 80100)
|
||||
// Return true for success and false otherwise
|
||||
#if PHP_VERSION_ID < 80100
|
||||
int pdo_sqlsrv_dbh_rollback(_Inout_ pdo_dbh_t *dbh)
|
||||
#else
|
||||
bool pdo_sqlsrv_dbh_rollback(_Inout_ pdo_dbh_t *dbh)
|
||||
#endif
|
||||
{
|
||||
PDO_RESET_DBH_ERROR;
|
||||
PDO_VALIDATE_CONN;
|
||||
|
@ -987,18 +1112,30 @@ int pdo_sqlsrv_dbh_rollback( _Inout_ pdo_dbh_t *dbh )
|
|||
|
||||
core_sqlsrv_rollback( driver_conn );
|
||||
|
||||
#if PHP_VERSION_ID < 80100
|
||||
return 1;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
catch( core::CoreException& ) {
|
||||
|
||||
#if PHP_VERSION_ID < 80100
|
||||
return 0;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
catch( ... ) {
|
||||
|
||||
DIE ("pdo_sqlsrv_dbh_rollback: Uncaught exception occurred.");
|
||||
}
|
||||
// Should not have reached here but adding this due to compilation warnings
|
||||
#if PHP_VERSION_ID < 80100
|
||||
return 0;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
// pdo_sqlsrv_dbh_set_attr
|
||||
|
@ -1010,8 +1147,13 @@ int pdo_sqlsrv_dbh_rollback( _Inout_ pdo_dbh_t *dbh )
|
|||
// attr - The attribute to be set.
|
||||
// val - The value of the attribute to be set.
|
||||
// Return:
|
||||
// 0 for failure, 1 for success.
|
||||
int pdo_sqlsrv_dbh_set_attr( _Inout_ pdo_dbh_t *dbh, _In_ zend_long attr, _Inout_ zval *val )
|
||||
// 0 for failure, 1 for success. (if PHP_VERSION_ID < 80100)
|
||||
// Return true on success and false in case of failure
|
||||
#if PHP_VERSION_ID < 80100
|
||||
int pdo_sqlsrv_dbh_set_attr(_Inout_ pdo_dbh_t *dbh, _In_ zend_long attr, _Inout_ zval *val)
|
||||
#else
|
||||
bool pdo_sqlsrv_dbh_set_attr(_Inout_ pdo_dbh_t *dbh, _In_ zend_long attr, _Inout_ zval *val)
|
||||
#endif
|
||||
{
|
||||
PDO_RESET_DBH_ERROR;
|
||||
PDO_VALIDATE_CONN;
|
||||
|
@ -1158,11 +1300,18 @@ int pdo_sqlsrv_dbh_set_attr( _Inout_ pdo_dbh_t *dbh, _In_ zend_long attr, _Inout
|
|||
}
|
||||
}
|
||||
catch( pdo::PDOException& ) {
|
||||
|
||||
#if PHP_VERSION_ID < 80100
|
||||
return 0;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if PHP_VERSION_ID < 80100
|
||||
return 1;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -1173,8 +1322,12 @@ int pdo_sqlsrv_dbh_set_attr( _Inout_ pdo_dbh_t *dbh, _In_ zend_long attr, _Inout
|
|||
// attr - The attribute to get.
|
||||
// return_value - zval in which to return the attribute value.
|
||||
// Return:
|
||||
// 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 )
|
||||
// 0 for failure, 1 for success. (if PHP_VERSION_ID < 80100)
|
||||
// There are 3 return states:
|
||||
// -1 for errors while retrieving a valid attribute
|
||||
// 0 for attempting to retrieve an attribute which is not supported by the driver
|
||||
// any other value for success, *return_value must be set to the attribute value
|
||||
int pdo_sqlsrv_dbh_get_attr(_Inout_ pdo_dbh_t *dbh, _In_ zend_long attr, _Inout_ zval *return_value)
|
||||
{
|
||||
PDO_RESET_DBH_ERROR;
|
||||
PDO_VALIDATE_CONN;
|
||||
|
@ -1196,8 +1349,12 @@ int pdo_sqlsrv_dbh_get_attr( _Inout_ pdo_dbh_t *dbh, _In_ zend_long attr, _Inout
|
|||
case PDO_ATTR_AUTOCOMMIT:
|
||||
case PDO_ATTR_TIMEOUT:
|
||||
{
|
||||
#if PHP_VERSION_ID < 80100
|
||||
// PDO does not throw "not supported" error message for these attributes.
|
||||
THROW_PDO_ERROR( driver_dbh, PDO_SQLSRV_ERROR_UNSUPPORTED_DBH_ATTR );
|
||||
THROW_PDO_ERROR(driver_dbh, PDO_SQLSRV_ERROR_UNSUPPORTED_DBH_ATTR);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Statement level only
|
||||
|
@ -1303,10 +1460,18 @@ int pdo_sqlsrv_dbh_get_attr( _Inout_ pdo_dbh_t *dbh, _In_ zend_long attr, _Inout
|
|||
}
|
||||
}
|
||||
|
||||
#if PHP_VERSION_ID < 80100
|
||||
return 1;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
catch( core::CoreException& ) {
|
||||
#if PHP_VERSION_ID < 80100
|
||||
return 0;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1318,8 +1483,11 @@ int pdo_sqlsrv_dbh_get_attr( _Inout_ pdo_dbh_t *dbh, _In_ zend_long attr, _Inout
|
|||
// info - zval in which to return the error info.
|
||||
// Return:
|
||||
// 0 for failure, 1 for success.
|
||||
int pdo_sqlsrv_dbh_return_error( _In_ pdo_dbh_t *dbh, _In_opt_ pdo_stmt_t *stmt,
|
||||
_Out_ zval *info)
|
||||
#if PHP_VERSION_ID < 80100
|
||||
int pdo_sqlsrv_dbh_return_error(_In_ pdo_dbh_t *dbh, _In_opt_ pdo_stmt_t *stmt, _Out_ zval *info)
|
||||
#else
|
||||
void pdo_sqlsrv_dbh_return_error(_In_ pdo_dbh_t *dbh, _In_opt_ pdo_stmt_t *stmt, _Out_ zval *info)
|
||||
#endif
|
||||
{
|
||||
SQLSRV_ASSERT( dbh != NULL || stmt != NULL, "Either dbh or stmt must not be NULL to dereference the error." );
|
||||
|
||||
|
@ -1333,7 +1501,9 @@ int pdo_sqlsrv_dbh_return_error( _In_ pdo_dbh_t *dbh, _In_opt_ pdo_stmt_t *stmt,
|
|||
|
||||
pdo_sqlsrv_retrieve_context_error( ctx_error, info );
|
||||
|
||||
#if PHP_VERSION_ID < 80100
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
// pdo_sqlsrv_dbh_last_id
|
||||
|
@ -1344,8 +1514,13 @@ int pdo_sqlsrv_dbh_return_error( _In_ pdo_dbh_t *dbh, _In_opt_ pdo_stmt_t *stmt,
|
|||
// name - Table name.
|
||||
// len - Length of the name.
|
||||
// Return:
|
||||
// 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 )
|
||||
// Returns the last insert id as a string. (if PHP_VERSION_ID < 80100)
|
||||
// Returning NULL indicates an error condition. The input "name" MIGHT be NULL
|
||||
#if PHP_VERSION_ID < 80100
|
||||
char * pdo_sqlsrv_dbh_last_id(_Inout_ pdo_dbh_t *dbh, _In_z_ const char *name, _Out_ size_t* len)
|
||||
#else
|
||||
zend_string * pdo_sqlsrv_dbh_last_id(_Inout_ pdo_dbh_t *dbh, _In_ const zend_string *name)
|
||||
#endif
|
||||
{
|
||||
PDO_RESET_DBH_ERROR;
|
||||
PDO_VALIDATE_CONN;
|
||||
|
@ -1372,7 +1547,12 @@ char * pdo_sqlsrv_dbh_last_id( _Inout_ pdo_dbh_t *dbh, _In_z_ const char *name,
|
|||
wsql_string = utf16_string_from_mbcs_string(SQLSRV_ENCODING_CHAR, LAST_INSERT_ID_QUERY, sizeof(LAST_INSERT_ID_QUERY), &wsql_len);
|
||||
} else {
|
||||
char buffer[LAST_INSERT_ID_QUERY_MAX_LEN] = { '\0' };
|
||||
#if PHP_VERSION_ID < 80100
|
||||
snprintf(buffer, LAST_INSERT_ID_QUERY_MAX_LEN, SEQUENCE_CURRENT_VALUE_QUERY, name);
|
||||
#else
|
||||
const char *name_str = ZSTR_VAL(name);
|
||||
snprintf(buffer, LAST_INSERT_ID_QUERY_MAX_LEN, SEQUENCE_CURRENT_VALUE_QUERY, ZSTR_VAL(name));
|
||||
#endif
|
||||
wsql_string = utf16_string_from_mbcs_string(SQLSRV_ENCODING_CHAR, buffer, sizeof(buffer), &wsql_len);
|
||||
}
|
||||
CHECK_CUSTOM_ERROR(wsql_string == 0, driver_stmt, SQLSRV_ERROR_QUERY_STRING_ENCODING_TRANSLATE, get_last_error_message()) {
|
||||
|
@ -1390,7 +1570,7 @@ char * pdo_sqlsrv_dbh_last_id( _Inout_ pdo_dbh_t *dbh, _In_z_ const char *name,
|
|||
// execute the last insert id query
|
||||
core::SQLExecDirectW( driver_stmt, wsql_string );
|
||||
core::SQLFetchScroll( driver_stmt, SQL_FETCH_NEXT, 0 );
|
||||
|
||||
|
||||
SQLRETURN r = core::SQLGetData(driver_stmt, 1, SQL_C_CHAR, idSTR, LAST_INSERT_ID_BUFF_LEN, &cbID, false);
|
||||
CHECK_CUSTOM_ERROR((!SQL_SUCCEEDED(r) || cbID == SQL_NULL_DATA || cbID == SQL_NO_TOTAL), driver_stmt,
|
||||
PDO_SQLSRV_ERROR_LAST_INSERT_ID) {
|
||||
|
@ -1408,20 +1588,31 @@ char * pdo_sqlsrv_dbh_last_id( _Inout_ pdo_dbh_t *dbh, _In_z_ const char *name,
|
|||
if( driver_stmt ) {
|
||||
driver_stmt->~sqlsrv_stmt();
|
||||
}
|
||||
#if PHP_VERSION_ID < 80100
|
||||
*len = 0;
|
||||
str = reinterpret_cast<char*>(sqlsrv_malloc(0, sizeof(char), 1)); // return an empty string with a null terminator
|
||||
str[0] = '\0';
|
||||
return str;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
// restore error handling to its previous mode
|
||||
dbh->error_mode = prev_err_mode;
|
||||
|
||||
// copy the last ID string and return it
|
||||
*len = static_cast<size_t>(cbID);
|
||||
// copy the last ID string and return it
|
||||
str = reinterpret_cast<char*>(sqlsrv_malloc(cbID, sizeof(char), 1)); // include space for null terminator
|
||||
strcpy_s(str, cbID + 1, idSTR);
|
||||
|
||||
#if PHP_VERSION_ID < 80100
|
||||
*len = static_cast<size_t>(cbID);
|
||||
return str;
|
||||
#else
|
||||
zend_string *zstr = zend_string_init(str, cbID, 0);
|
||||
sqlsrv_free(str);
|
||||
return zstr;
|
||||
#endif
|
||||
}
|
||||
|
||||
// pdo_sqlsrv_dbh_quote
|
||||
|
@ -1435,8 +1626,12 @@ char * pdo_sqlsrv_dbh_last_id( _Inout_ pdo_dbh_t *dbh, _In_z_ const char *name,
|
|||
// quoted_len - Length of the output string.
|
||||
// Return:
|
||||
// 0 for failure, 1 for success.
|
||||
#if PHP_VERSION_ID < 80100
|
||||
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 )
|
||||
#else
|
||||
zend_string* pdo_sqlsrv_dbh_quote(_Inout_ pdo_dbh_t* dbh, _In_ const zend_string *unquoted, _In_ enum pdo_param_type paramtype)
|
||||
#endif
|
||||
{
|
||||
PDO_RESET_DBH_ERROR;
|
||||
PDO_VALIDATE_CONN;
|
||||
|
@ -1513,28 +1708,60 @@ int pdo_sqlsrv_dbh_quote( _Inout_ pdo_dbh_t* dbh, _In_reads_(unquoted_len) const
|
|||
}
|
||||
#endif
|
||||
|
||||
if ( encoding == SQLSRV_ENCODING_BINARY ) {
|
||||
*quoted_len = (unquoted_len * 2) + 2; // each character will be converted to 2 hex digits and prepend '0x' to the result
|
||||
*quoted = reinterpret_cast<char*>(sqlsrv_malloc(*quoted_len, sizeof(char), 1)); // include space for null terminator
|
||||
memset(*quoted, '\0', *quoted_len + 1);
|
||||
|
||||
unsigned int pos = 0;
|
||||
(*quoted)[pos++] = '0';
|
||||
(*quoted)[pos++] = 'x';
|
||||
|
||||
for (size_t index = 0; index < unquoted_len && unquoted[index] != '\0'; ++index) {
|
||||
// On success, snprintf returns the total number of characters written
|
||||
// On failure, a negative number is returned
|
||||
// The generated string has a length of at most len - 1, so
|
||||
if (encoding == SQLSRV_ENCODING_BINARY) {
|
||||
#if PHP_VERSION_ID < 80100
|
||||
*quoted_len = (unquoted_len * 2) + 2; // each character will be converted to 2 hex digits and prepend '0x' to the result
|
||||
*quoted = reinterpret_cast<char*>(sqlsrv_malloc(*quoted_len, sizeof(char), 1)); // include space for null terminator
|
||||
memset(*quoted, '\0', *quoted_len + 1);
|
||||
|
||||
unsigned int pos = 0;
|
||||
(*quoted)[pos++] = '0';
|
||||
(*quoted)[pos++] = 'x';
|
||||
|
||||
for (size_t index = 0; index < unquoted_len && unquoted[index] != '\0'; ++index) {
|
||||
// On success, snprintf returns the total number of characters written
|
||||
// On failure, a negative number is returned
|
||||
// The generated string has a length of at most len - 1, so
|
||||
// len is 3 (2 hex digits + 1)
|
||||
int n = snprintf((char*)(*quoted + pos), 3, "%02X", unquoted[index]);
|
||||
if (n < 0) {
|
||||
// Something went wrong, simply return 0 (failure)
|
||||
return 0;
|
||||
}
|
||||
pos += 2;
|
||||
}
|
||||
return 1;
|
||||
if (n < 0) {
|
||||
// Something went wrong, simply return 0 (failure)
|
||||
return 0;
|
||||
}
|
||||
pos += 2;
|
||||
}
|
||||
|
||||
return 1;
|
||||
#else
|
||||
size_t unquoted_len = ZSTR_LEN(unquoted);
|
||||
const char *unquoted_str = ZSTR_VAL(unquoted);
|
||||
|
||||
sqlsrv_malloc_auto_ptr<char> quoted;
|
||||
size_t quoted_len = (unquoted_len * 2) + 2; // each character will be converted to 2 hex digits and prepend '0x' to the result
|
||||
quoted = reinterpret_cast<char*>(sqlsrv_malloc(quoted_len, sizeof(char), 1)); // include space for null terminator
|
||||
memset(quoted, '\0', quoted_len + 1);
|
||||
|
||||
unsigned int pos = 0;
|
||||
quoted[pos++] = '0';
|
||||
quoted[pos++] = 'x';
|
||||
|
||||
char *p = quoted;
|
||||
for (size_t index = 0; index < unquoted_len && unquoted_str[index] != '\0'; ++index) {
|
||||
// On success, snprintf returns the total number of characters written
|
||||
// On failure, a negative number is returned
|
||||
// The generated string has a length of at most len - 1, so
|
||||
// len is 3 (2 hex digits + 1)
|
||||
int n = snprintf((char*)(p + pos), 3, "%02X", unquoted_str[index]);
|
||||
if (n < 0) {
|
||||
// Something went wrong, simply return NULL (failure)
|
||||
return NULL;
|
||||
}
|
||||
pos += 2;
|
||||
}
|
||||
|
||||
zend_string* zstr = zend_string_init(quoted, quoted_len, 0);
|
||||
return zstr;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
// The minimum number of single quotes needed is 2 -- the initial start and end quotes
|
||||
|
@ -1542,18 +1769,35 @@ int pdo_sqlsrv_dbh_quote( _Inout_ pdo_dbh_t* dbh, _In_reads_(unquoted_len) const
|
|||
int quotes_needed = (use_national_char_set) ? 3 : 2;
|
||||
char c = '\'';
|
||||
|
||||
#if PHP_VERSION_ID < 80100
|
||||
std::string tmp_str(unquoted, unquoted_len); // Copy all unquoted_len characters from unquoted
|
||||
#else
|
||||
size_t unquoted_len = ZSTR_LEN(unquoted);
|
||||
const char *unquoted_str = ZSTR_VAL(unquoted);
|
||||
std::string tmp_str(unquoted_str, unquoted_len); // Copy all unquoted_len characters from unquoted
|
||||
#endif
|
||||
|
||||
std::size_t found = tmp_str.find(c); // Find the first single quote
|
||||
while (found != std::string::npos) {
|
||||
tmp_str.insert(found + 1, 1, c); // Insert an additional single quote
|
||||
found = tmp_str.find(c, found + 2); // Find the next single quote
|
||||
}
|
||||
size_t len = tmp_str.length();
|
||||
|
||||
#if PHP_VERSION_ID < 80100
|
||||
*quoted_len = quotes_needed + len; // The new length should be number of quotes plus the length of tmp_str
|
||||
*quoted = reinterpret_cast<char*>(sqlsrv_malloc(*quoted_len, sizeof(char), 1)); // include space for null terminator
|
||||
memset(*quoted, '\0', *quoted_len + 1);
|
||||
memset(*quoted, '\0', *quoted_len + 1);
|
||||
|
||||
char *p = *quoted;
|
||||
#else
|
||||
sqlsrv_malloc_auto_ptr<char> quoted;
|
||||
size_t quoted_len = quotes_needed + len; // length returned to the caller should not account for null terminator
|
||||
quoted = reinterpret_cast<char*>(sqlsrv_malloc(quoted_len, sizeof(char), 1)); // include space for null terminator
|
||||
memset(quoted, '\0', quoted_len + 1);
|
||||
|
||||
char *p = quoted;
|
||||
#endif
|
||||
size_t pos = 0;
|
||||
if (use_national_char_set) { // Insert the letter N if the encoding is UTF8
|
||||
*(p + (pos++)) = 'N';
|
||||
|
@ -1562,7 +1806,13 @@ int pdo_sqlsrv_dbh_quote( _Inout_ pdo_dbh_t* dbh, _In_reads_(unquoted_len) const
|
|||
tmp_str.copy(p + pos, len, 0); // Copy tmp_str to *quoted
|
||||
pos += len;
|
||||
*(p + pos) = c; // Add the end quote
|
||||
|
||||
#if PHP_VERSION_ID < 80100
|
||||
return 1;
|
||||
#else
|
||||
zend_string* zstr = zend_string_init(quoted, quoted_len, 0);
|
||||
return zstr;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -278,8 +278,13 @@ int pdo_sqlsrv_stmt_fetch( _Inout_ pdo_stmt_t *stmt, _In_ enum pdo_fetch_orienta
|
|||
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 );
|
||||
int pdo_sqlsrv_stmt_describe_col( _Inout_ pdo_stmt_t *stmt, _In_ int colno );
|
||||
#if PHP_VERSION_ID < 80100
|
||||
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 );
|
||||
#else
|
||||
int pdo_sqlsrv_stmt_get_col_data(_Inout_ pdo_stmt_t *stmt, _In_ int colno, _Inout_ zval *result, _Inout_ enum pdo_param_type *type);
|
||||
#endif
|
||||
|
||||
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 );
|
||||
int pdo_sqlsrv_stmt_get_col_meta( _Inout_ pdo_stmt_t *stmt, _In_ zend_long colno, _Inout_ zval *return_value );
|
||||
|
@ -453,9 +458,10 @@ int pdo_sqlsrv_stmt_describe_col( _Inout_ pdo_stmt_t *stmt, _In_ int colno)
|
|||
// Set the precision
|
||||
column_data->precision = core_meta_data->field_scale;
|
||||
|
||||
#if PHP_VERSION_ID < 80100
|
||||
// Set the param_type
|
||||
column_data->param_type = PDO_PARAM_ZVAL;
|
||||
|
||||
#endif
|
||||
// store the field data for use by pdo_sqlsrv_stmt_get_col_data
|
||||
pdo_sqlsrv_stmt* driver_stmt = reinterpret_cast<pdo_sqlsrv_stmt*>( stmt->driver_data );
|
||||
SQLSRV_ASSERT( driver_stmt != NULL, "Invalid driver statement in pdo_sqlsrv_stmt_describe_col" );
|
||||
|
@ -551,8 +557,13 @@ int pdo_sqlsrv_stmt_execute( _Inout_ pdo_stmt_t *stmt )
|
|||
|
||||
zend_hash_internal_pointer_reset(driver_stmt->placeholders);
|
||||
|
||||
#if PHP_VERSION_ID < 80100
|
||||
query = stmt->active_query_string;
|
||||
query_len = static_cast<unsigned int>(stmt->active_query_stringlen);
|
||||
#else
|
||||
query = ZSTR_VAL(stmt->active_query_string);
|
||||
query_len = ZSTR_LEN(stmt->active_query_string);
|
||||
#endif
|
||||
}
|
||||
|
||||
// The query timeout setting is inherited from the corresponding connection attribute, but
|
||||
|
@ -652,14 +663,23 @@ int pdo_sqlsrv_stmt_fetch( _Inout_ pdo_stmt_t *stmt, _In_ enum pdo_fetch_orienta
|
|||
pdo_bound_param_data* bind_data = NULL;
|
||||
|
||||
if( !driver_stmt->bound_column_param_types ) {
|
||||
driver_stmt->bound_column_param_types =
|
||||
#if PHP_VERSION_ID < 80100
|
||||
driver_stmt->bound_column_param_types =
|
||||
reinterpret_cast<pdo_param_type*>( sqlsrv_malloc( stmt->column_count, sizeof( pdo_param_type ), 0 ));
|
||||
std::fill( driver_stmt->bound_column_param_types, driver_stmt->bound_column_param_types + stmt->column_count,
|
||||
PDO_PARAM_ZVAL );
|
||||
#else
|
||||
// TODO: possibly no longer need bound_column_param_types?? default to PDO_PARAM_STR???
|
||||
driver_stmt->bound_column_param_types =
|
||||
reinterpret_cast<pdo_param_type*>(sqlsrv_malloc(stmt->column_count, sizeof(pdo_param_type), 0));
|
||||
std::fill(driver_stmt->bound_column_param_types, driver_stmt->bound_column_param_types + stmt->column_count,
|
||||
PDO_PARAM_STR);
|
||||
#endif
|
||||
}
|
||||
|
||||
for( long i = 0; i < stmt->column_count; ++i ) {
|
||||
|
||||
#if PHP_VERSION_ID < 80100
|
||||
if (NULL== (bind_data = reinterpret_cast<pdo_bound_param_data*>(zend_hash_index_find_ptr(stmt->bound_columns, i))) &&
|
||||
(NULL == (bind_data = reinterpret_cast<pdo_bound_param_data*>(zend_hash_find_ptr(stmt->bound_columns, stmt->columns[i].name))))) {
|
||||
|
||||
|
@ -672,6 +692,15 @@ int pdo_sqlsrv_stmt_fetch( _Inout_ pdo_stmt_t *stmt, _In_ enum pdo_fetch_orienta
|
|||
driver_stmt->bound_column_param_types[i] = bind_data->param_type;
|
||||
bind_data->param_type = PDO_PARAM_ZVAL;
|
||||
}
|
||||
#else
|
||||
if (NULL == (bind_data = reinterpret_cast<pdo_bound_param_data*>(zend_hash_index_find_ptr(stmt->bound_columns, i))) &&
|
||||
(NULL == (bind_data = reinterpret_cast<pdo_bound_param_data*>(zend_hash_find_ptr(stmt->bound_columns, stmt->columns[i].name))))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO: possibly no longer need bound_column_param_types??
|
||||
driver_stmt->bound_column_param_types[i] = bind_data->param_type;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -730,8 +759,13 @@ int pdo_sqlsrv_stmt_fetch( _Inout_ pdo_stmt_t *stmt, _In_ enum pdo_fetch_orienta
|
|||
// freeing the memory.
|
||||
// Return:
|
||||
// 0 for failure, 1 for success.
|
||||
#if PHP_VERSION_ID < 80100
|
||||
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)
|
||||
#else
|
||||
int pdo_sqlsrv_stmt_get_col_data(_Inout_ pdo_stmt_t *stmt, _In_ int colno, _Inout_ zval *result_z, _Inout_ enum pdo_param_type *type)
|
||||
#endif
|
||||
|
||||
{
|
||||
PDO_RESET_STMT_ERROR;
|
||||
PDO_VALIDATE_STMT;
|
||||
|
@ -739,39 +773,44 @@ int pdo_sqlsrv_stmt_get_col_data( _Inout_ pdo_stmt_t *stmt, _In_ int colno,
|
|||
|
||||
try {
|
||||
|
||||
SQLSRV_ASSERT( stmt != NULL, "pdo_sqlsrv_stmt_get_col_data: pdo_stmt object was null" );
|
||||
SQLSRV_ASSERT(stmt != NULL, "pdo_sqlsrv_stmt_get_col_data: pdo_stmt object was null");
|
||||
|
||||
pdo_sqlsrv_stmt* driver_stmt = reinterpret_cast<pdo_sqlsrv_stmt*>( stmt->driver_data );
|
||||
|
||||
SQLSRV_ASSERT( driver_stmt != NULL, "pdo_sqlsrv_stmt_get_col_data: driver_data object was null" );
|
||||
pdo_sqlsrv_stmt* driver_stmt = reinterpret_cast<pdo_sqlsrv_stmt*>(stmt->driver_data);
|
||||
|
||||
CHECK_CUSTOM_ERROR((colno < 0), driver_stmt, PDO_SQLSRV_ERROR_INVALID_COLUMN_INDEX ) {
|
||||
SQLSRV_ASSERT(driver_stmt != NULL, "pdo_sqlsrv_stmt_get_col_data: driver_data object was null");
|
||||
|
||||
CHECK_CUSTOM_ERROR((colno < 0), driver_stmt, PDO_SQLSRV_ERROR_INVALID_COLUMN_INDEX) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if PHP_VERSION_ID < 80100
|
||||
// Let PDO free the memory after use.
|
||||
*caller_frees = 1;
|
||||
|
||||
* caller_frees = 1;
|
||||
#endif
|
||||
|
||||
// translate the pdo type to a type the core layer understands
|
||||
sqlsrv_phptype sqlsrv_php_type;
|
||||
SQLSRV_ASSERT( colno >= 0 && colno < static_cast<int>( driver_stmt->current_meta_data.size()),
|
||||
"Invalid column number in pdo_sqlsrv_stmt_get_col_data" );
|
||||
SQLSRV_ASSERT(colno >= 0 && colno < static_cast<int>(driver_stmt->current_meta_data.size()),
|
||||
"Invalid column number in pdo_sqlsrv_stmt_get_col_data");
|
||||
|
||||
// set the encoding if the user specified one via bindColumn, otherwise use the statement's encoding
|
||||
// save the php type for next use
|
||||
sqlsrv_php_type = driver_stmt->sql_type_to_php_type(
|
||||
static_cast<SQLINTEGER>(driver_stmt->current_meta_data[colno]->field_type),
|
||||
static_cast<SQLUINTEGER>(driver_stmt->current_meta_data[colno]->field_size),
|
||||
true);
|
||||
static_cast<SQLINTEGER>(driver_stmt->current_meta_data[colno]->field_type),
|
||||
static_cast<SQLUINTEGER>(driver_stmt->current_meta_data[colno]->field_size),
|
||||
true);
|
||||
driver_stmt->current_meta_data[colno]->sqlsrv_php_type = sqlsrv_php_type;
|
||||
|
||||
// if a column is bound to a type different than the column type, figure out a way to convert it to the
|
||||
// type they want
|
||||
if( stmt->bound_columns && driver_stmt->bound_column_param_types[colno] != PDO_PARAM_ZVAL ) {
|
||||
|
||||
sqlsrv_php_type.typeinfo.type = pdo_type_to_sqlsrv_php_type( driver_stmt,
|
||||
driver_stmt->bound_column_param_types[colno]
|
||||
);
|
||||
#if PHP_VERSION_ID < 80100
|
||||
if (stmt->bound_columns && driver_stmt->bound_column_param_types[colno] != PDO_PARAM_ZVAL) {
|
||||
#else
|
||||
if (stmt->bound_columns) {
|
||||
#endif
|
||||
sqlsrv_php_type.typeinfo.type = pdo_type_to_sqlsrv_php_type(driver_stmt,
|
||||
driver_stmt->bound_column_param_types[colno]
|
||||
);
|
||||
|
||||
pdo_bound_param_data* bind_data = NULL;
|
||||
bind_data = reinterpret_cast<pdo_bound_param_data*>(zend_hash_index_find_ptr(stmt->bound_columns, colno));
|
||||
|
@ -780,40 +819,41 @@ int pdo_sqlsrv_stmt_get_col_data( _Inout_ pdo_stmt_t *stmt, _In_ int colno,
|
|||
bind_data = reinterpret_cast<pdo_bound_param_data*>(zend_hash_find_ptr(stmt->bound_columns, stmt->columns[colno].name));
|
||||
}
|
||||
|
||||
if( bind_data != NULL && !Z_ISUNDEF(bind_data->driver_params) ) {
|
||||
if (bind_data != NULL && !Z_ISUNDEF(bind_data->driver_params)) {
|
||||
|
||||
CHECK_CUSTOM_ERROR( Z_TYPE( bind_data->driver_params ) != IS_LONG, driver_stmt,
|
||||
PDO_SQLSRV_ERROR_INVALID_COLUMN_DRIVER_DATA, colno + 1 ) {
|
||||
CHECK_CUSTOM_ERROR(Z_TYPE(bind_data->driver_params) != IS_LONG, driver_stmt,
|
||||
PDO_SQLSRV_ERROR_INVALID_COLUMN_DRIVER_DATA, colno + 1) {
|
||||
throw pdo::PDOException();
|
||||
}
|
||||
|
||||
CHECK_CUSTOM_ERROR( driver_stmt->bound_column_param_types[colno] != PDO_PARAM_STR
|
||||
&& driver_stmt->bound_column_param_types[colno] != PDO_PARAM_LOB, driver_stmt,
|
||||
PDO_SQLSRV_ERROR_COLUMN_TYPE_DOES_NOT_SUPPORT_ENCODING, colno + 1 ) {
|
||||
CHECK_CUSTOM_ERROR(driver_stmt->bound_column_param_types[colno] != PDO_PARAM_STR
|
||||
&& driver_stmt->bound_column_param_types[colno] != PDO_PARAM_LOB, driver_stmt,
|
||||
PDO_SQLSRV_ERROR_COLUMN_TYPE_DOES_NOT_SUPPORT_ENCODING, colno + 1) {
|
||||
|
||||
throw pdo::PDOException();
|
||||
throw pdo::PDOException();
|
||||
}
|
||||
|
||||
sqlsrv_php_type.typeinfo.encoding = Z_LVAL( bind_data->driver_params );
|
||||
sqlsrv_php_type.typeinfo.encoding = Z_LVAL(bind_data->driver_params);
|
||||
|
||||
switch( sqlsrv_php_type.typeinfo.encoding ) {
|
||||
case SQLSRV_ENCODING_SYSTEM:
|
||||
case SQLSRV_ENCODING_BINARY:
|
||||
case SQLSRV_ENCODING_UTF8:
|
||||
break;
|
||||
default:
|
||||
THROW_PDO_ERROR( driver_stmt, PDO_SQLSRV_ERROR_INVALID_DRIVER_COLUMN_ENCODING, colno );
|
||||
break;
|
||||
switch (sqlsrv_php_type.typeinfo.encoding) {
|
||||
case SQLSRV_ENCODING_SYSTEM:
|
||||
case SQLSRV_ENCODING_BINARY:
|
||||
case SQLSRV_ENCODING_UTF8:
|
||||
break;
|
||||
default:
|
||||
THROW_PDO_ERROR(driver_stmt, PDO_SQLSRV_ERROR_INVALID_DRIVER_COLUMN_ENCODING, colno);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// save the php type for the bound column
|
||||
driver_stmt->current_meta_data[colno]->sqlsrv_php_type = sqlsrv_php_type;
|
||||
}
|
||||
|
||||
|
||||
SQLSRV_PHPTYPE sqlsrv_phptype_out = SQLSRV_PHPTYPE_INVALID;
|
||||
core_sqlsrv_get_field( driver_stmt, colno, sqlsrv_php_type, false, *(reinterpret_cast<void**>(ptr)),
|
||||
reinterpret_cast<SQLLEN*>( len ), true, &sqlsrv_phptype_out );
|
||||
#if PHP_VERSION_ID < 80100
|
||||
core_sqlsrv_get_field(driver_stmt, colno, sqlsrv_php_type, false, *(reinterpret_cast<void**>(ptr)),
|
||||
reinterpret_cast<SQLLEN*>(len), true, &sqlsrv_phptype_out);
|
||||
|
||||
if (ptr) {
|
||||
zval* zval_ptr = reinterpret_cast<zval*>(sqlsrv_malloc(sizeof(zval)));
|
||||
|
@ -821,7 +861,14 @@ int pdo_sqlsrv_stmt_get_col_data( _Inout_ pdo_stmt_t *stmt, _In_ int colno,
|
|||
*ptr = reinterpret_cast<char*>(zval_ptr);
|
||||
*len = sizeof(zval);
|
||||
}
|
||||
|
||||
#else
|
||||
SQLLEN len = 0;
|
||||
void *ptr = NULL;
|
||||
core_sqlsrv_get_field(driver_stmt, colno, sqlsrv_php_type, false, ptr, &len, true, &sqlsrv_phptype_out);
|
||||
if (ptr) {
|
||||
*result_z = convert_to_zval(driver_stmt, sqlsrv_phptype_out, &ptr, len);
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
catch ( core::CoreException& ) {
|
||||
|
@ -1114,9 +1161,15 @@ int pdo_sqlsrv_stmt_get_col_meta( _Inout_ pdo_stmt_t *stmt, _In_ zend_long colno
|
|||
&out_buff_len, &field_type_num );
|
||||
add_assoc_string( return_value, "table", table_name );
|
||||
|
||||
#if PHP_VERSION_ID < 80100
|
||||
if( stmt->columns && stmt->columns[colno].param_type == PDO_PARAM_ZVAL ) {
|
||||
add_assoc_long( return_value, "pdo_type", pdo_type );
|
||||
}
|
||||
#else
|
||||
if (stmt->columns) {
|
||||
add_assoc_long(return_value, "pdo_type", pdo_type);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
catch( core::CoreException& ) {
|
||||
zval_ptr_dtor(return_value);
|
||||
|
|
|
@ -23,20 +23,20 @@ $stmt->debugDumpParams();
|
|||
$stmt=null;
|
||||
$conn=null;
|
||||
?>
|
||||
--EXPECT--
|
||||
SQL: [52] select * from Person.ContactType where name = :param
|
||||
--EXPECTREGEX--
|
||||
SQL: \[52\] select \* from Person.ContactType where name = \:param
|
||||
Params: 1
|
||||
Key: Name: [6] :param
|
||||
Key: Name: \[6\] :param
|
||||
paramno=0
|
||||
name=[6] ":param"
|
||||
name=\[6\] ":param"
|
||||
is_param=1
|
||||
param_type=2
|
||||
param_type=(2|3)
|
||||
|
||||
|
||||
SQL: [47] select * from Person.ContactType where name = ?
|
||||
SQL: \[47\] select \* from Person.ContactType where name = \?
|
||||
Params: 1
|
||||
Key: Position #0:
|
||||
paramno=0
|
||||
name=[0] ""
|
||||
name=\[0\] ""
|
||||
is_param=1
|
||||
param_type=2
|
||||
param_type=(2|3)
|
|
@ -19,24 +19,24 @@ print $metadata['name'];
|
|||
$stmt = null;
|
||||
$conn = null;
|
||||
?>
|
||||
--EXPECT--
|
||||
array(8) {
|
||||
["flags"]=>
|
||||
int(0)
|
||||
["sqlsrv:decl_type"]=>
|
||||
string(8) "datetime"
|
||||
["native_type"]=>
|
||||
string(6) "string"
|
||||
["table"]=>
|
||||
string(0) ""
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
["name"]=>
|
||||
string(12) "ModifiedDate"
|
||||
["len"]=>
|
||||
int(23)
|
||||
["precision"]=>
|
||||
int(3)
|
||||
--EXPECTREGEX--
|
||||
array\(8\) {
|
||||
\["flags"\]=>
|
||||
int\(0\)
|
||||
\["sqlsrv:decl_type"\]=>
|
||||
string\(8\) "datetime"
|
||||
\["native_type"\]=>
|
||||
string\(6\) "string"
|
||||
\["table"\]=>
|
||||
string\(0\) ""
|
||||
\["pdo_type"\]=>
|
||||
int\((2|3)\)
|
||||
\["name"\]=>
|
||||
string\(12\) "ModifiedDate"
|
||||
\["len"\]=>
|
||||
int\(23\)
|
||||
\["precision"\]=>
|
||||
int\(3\)
|
||||
}
|
||||
datetime
|
||||
string
|
||||
|
|
|
@ -306,7 +306,7 @@ class BindParamOp
|
|||
}
|
||||
|
||||
if ($length >= 0 || is_null($length)) {
|
||||
$this->length = $length;
|
||||
$this->length = is_null($length) ? 0 : $length;
|
||||
} else {
|
||||
printf("BindParamOp construct: The length provided must be greater or equal to 0.\n");
|
||||
exit;
|
||||
|
@ -531,14 +531,11 @@ function fetchAll($conn, $tbname)
|
|||
* @param string $fetchStyle : fetch_style argument passed to PDOStatement::fetchAll
|
||||
* @return array rows in a result set
|
||||
*/
|
||||
function selectAll($conn, $tbname, $fetchStyle = null)
|
||||
function selectAll($conn, $tbname, $fetchStyle = PDO::FETCH_BOTH)
|
||||
{
|
||||
try {
|
||||
$sql = "SELECT * FROM $tbname";
|
||||
$stmt = $conn->query($sql);
|
||||
if ($fetchStyle) {
|
||||
$fetchStyle = constant($fetchStyle);
|
||||
}
|
||||
$data = $stmt->fetchAll($fetchStyle);
|
||||
return $data;
|
||||
} catch (PDOException $e) {
|
||||
|
@ -1806,3 +1803,22 @@ function getTodayDateAsString($conn)
|
|||
$row = $stmt->fetch(PDO::FETCH_NUM);
|
||||
return $row[0];
|
||||
}
|
||||
|
||||
function compareResourceToInput($actual, $expected)
|
||||
{
|
||||
$size = 8192;
|
||||
$pos = 0;
|
||||
$matched = true;
|
||||
while (!feof($actual)) {
|
||||
$original = fread($actual, $size);
|
||||
$str = substr($expected, $pos, $size);
|
||||
|
||||
if ($original !== $str) {
|
||||
$matched = false;
|
||||
break;
|
||||
}
|
||||
$pos += $size;
|
||||
}
|
||||
|
||||
return $matched;
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ function insertNullsTest($bindType)
|
|||
$stmt2->setAttribute(PDO::SQLSRV_ATTR_ENCODING, PDO::SQLSRV_ENCODING_BINARY);
|
||||
$stmt2->bindValue(":p1", null, $bindType);
|
||||
} elseif ($bindType == PDO::PARAM_STR) {
|
||||
$stmt2->bindParam(":p1", $outvar, $bindType, null, PDO::SQLSRV_ENCODING_BINARY);
|
||||
$stmt2->bindParam(":p1", $outvar, $bindType, 0, PDO::SQLSRV_ENCODING_BINARY);
|
||||
}
|
||||
} else {
|
||||
$stmt2->bindParam(":p1", $outvar);
|
||||
|
|
|
@ -10,7 +10,7 @@ PHPT_EXEC=true
|
|||
<?php
|
||||
include 'MsCommon.inc';
|
||||
|
||||
function ReadOnly()
|
||||
function testReadOnly()
|
||||
{
|
||||
include 'MsSetup.inc';
|
||||
|
||||
|
@ -62,7 +62,7 @@ function Repro()
|
|||
|
||||
try
|
||||
{
|
||||
ReadOnly();
|
||||
testReadOnly();
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
|
|
|
@ -81,7 +81,7 @@ function Repro()
|
|||
Repro();
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
array(8) {
|
||||
["flags"]=>
|
||||
int(0)
|
||||
|
@ -92,7 +92,7 @@ array(8) {
|
|||
["table"]=>
|
||||
string(0) ""
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
int(%d)
|
||||
["name"]=>
|
||||
string(2) "id"
|
||||
["len"]=>
|
||||
|
@ -110,7 +110,7 @@ array(8) {
|
|||
["table"]=>
|
||||
string(0) ""
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
int(%d)
|
||||
["name"]=>
|
||||
string(3) "val"
|
||||
["len"]=>
|
||||
|
@ -128,7 +128,7 @@ array(8) {
|
|||
["table"]=>
|
||||
string(0) ""
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
int(%d)
|
||||
["name"]=>
|
||||
string(4) "val2"
|
||||
["len"]=>
|
||||
|
@ -146,7 +146,7 @@ array(8) {
|
|||
["table"]=>
|
||||
string(0) ""
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
int(%d)
|
||||
["name"]=>
|
||||
string(0) ""
|
||||
["len"]=>
|
||||
|
|
|
@ -61,8 +61,14 @@ function fetchLob($offset, $conn, $table, $sqlType, $data1, $data2)
|
|||
if ($id != $data1) {
|
||||
logInfo($offset, "ID data corruption: [$id] instead of [$data1]");
|
||||
}
|
||||
if ($label != $data2) {
|
||||
logInfo($offset, "Label data corruption: [$label] instead of [$data2]");
|
||||
if (PHP_VERSION_ID < 80100) {
|
||||
if ($label != $data2) {
|
||||
logInfo($offset, "Label data corruption: [$label] instead of [$data2]");
|
||||
}
|
||||
} else {
|
||||
if (!compareResourceToInput($label, $data2)) {
|
||||
logInfo($offset, "Label data corruption");
|
||||
}
|
||||
}
|
||||
unset($stmt);
|
||||
unset($label);
|
||||
|
|
|
@ -42,7 +42,7 @@ try {
|
|||
}
|
||||
|
||||
// Get data
|
||||
$row = selectAll($conn, $tableName, "PDO::FETCH_ASSOC");
|
||||
$row = selectAll($conn, $tableName, PDO::FETCH_ASSOC);
|
||||
var_dump($row);
|
||||
|
||||
// Close connection
|
||||
|
|
|
@ -28,9 +28,18 @@ try {
|
|||
$stmt = $conn->prepare("SELECT Value FROM $tableName");
|
||||
$stmt->bindColumn('Value', $val1, PDO::PARAM_LOB, 0, PDO::SQLSRV_ENCODING_BINARY);
|
||||
$stmt->execute();
|
||||
$stmt->fetch(PDO::FETCH_BOUND);
|
||||
var_dump($val1 === $value);
|
||||
|
||||
$stmt->fetch(PDO::FETCH_BOUND);
|
||||
|
||||
if (PHP_VERSION_ID < 80100) {
|
||||
var_dump($val1 === $value);
|
||||
} else {
|
||||
// $val1 is a stream object
|
||||
if (!feof($val1)) {
|
||||
$str = fread($val1, 8192);
|
||||
var_dump($str === $value);
|
||||
}
|
||||
}
|
||||
|
||||
// Close connection
|
||||
dropTable($conn, $tableName);
|
||||
unset($stmt);
|
||||
|
|
|
@ -148,7 +148,16 @@ try {
|
|||
$stmt->bindColumn('Value', $val1, PDO::PARAM_LOB, 0, PDO::SQLSRV_ENCODING_BINARY);
|
||||
$stmt->execute();
|
||||
$stmt->fetch(PDO::FETCH_BOUND);
|
||||
var_dump($val1 === $value);
|
||||
|
||||
if (PHP_VERSION_ID < 80100) {
|
||||
var_dump($val1 === $value);
|
||||
} else {
|
||||
// $val1 is a stream object
|
||||
if (!feof($val1)) {
|
||||
$str = fread($val1, 8192);
|
||||
var_dump($str === $value);
|
||||
}
|
||||
}
|
||||
|
||||
// Close connection
|
||||
dropTable($conn, $tableName);
|
||||
|
|
|
@ -57,7 +57,12 @@ try {
|
|||
// Start testing quote function
|
||||
$conn->setAttribute(PDO::ATTR_DEFAULT_STR_PARAM, PDO::PARAM_STR_CHAR);
|
||||
|
||||
var_dump($conn->quote(null, PDO::PARAM_NULL));
|
||||
// Deprecated: PDO::quote(): Passing null to parameter #1 ($string) of type string is being deprecated
|
||||
if (PHP_VERSION_ID < 80100) {
|
||||
var_dump($conn->quote(null, PDO::PARAM_NULL));
|
||||
} else {
|
||||
var_dump($conn->quote('', PDO::PARAM_NULL));
|
||||
}
|
||||
var_dump($conn->quote('\'', PDO::PARAM_STR));
|
||||
var_dump($conn->quote('foo', PDO::PARAM_STR));
|
||||
var_dump($conn->quote('foo', PDO::PARAM_STR | PDO::PARAM_STR_CHAR));
|
||||
|
|
|
@ -38,7 +38,7 @@ try {
|
|||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
array(8) {
|
||||
["flags"]=>
|
||||
int(0)
|
||||
|
@ -49,7 +49,7 @@ array(8) {
|
|||
["table"]=>
|
||||
string(0) ""
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
int(%d)
|
||||
["name"]=>
|
||||
string(6) "RESULT"
|
||||
["len"]=>
|
||||
|
|
|
@ -50,7 +50,23 @@ try {
|
|||
var_dump($e->errorInfo);
|
||||
}
|
||||
|
||||
//calls various fetch methods
|
||||
function verifyBinaryResult($result, $input, $len, $message)
|
||||
{
|
||||
if (PHP_VERSION_ID < 80100) {
|
||||
if (strncmp($result, $input, $len) !== 0) {
|
||||
print_r($message);
|
||||
}
|
||||
} else {
|
||||
if (!feof($result)) {
|
||||
$str = fread($result, $len);
|
||||
if (strncmp($str, $input, $len) !== 0) {
|
||||
print_r($message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//calls various fetch methods
|
||||
function testFetch($conn, $tableName, $columnName, $input)
|
||||
{
|
||||
$len = strlen($input);
|
||||
|
@ -60,17 +76,13 @@ function testFetch($conn, $tableName, $columnName, $input)
|
|||
$stmt->bindColumn(1, $result, PDO::PARAM_LOB);
|
||||
$stmt->fetch(PDO::FETCH_BOUND);
|
||||
//binary is fixed size, to evaluate output, compare it using strncmp
|
||||
if (strncmp($result, $input, $len) !== 0) {
|
||||
print_r("\nRetrieving using bindColumn failed");
|
||||
}
|
||||
verifyBinaryResult($result, $input, $len, "\nRetrieving using bindColumn failed");
|
||||
|
||||
$result = "";
|
||||
$stmt = $conn->query($sql);
|
||||
$stmt->bindColumn(1, $result, PDO::PARAM_LOB, 0, PDO::SQLSRV_ENCODING_BINARY);
|
||||
$stmt->fetch(PDO::FETCH_BOUND);
|
||||
if (strncmp($result, $input, $len) !== 0) {
|
||||
print_r("\nRetrieving using bindColumn with encoding set failed");
|
||||
}
|
||||
verifyBinaryResult($result, $input, $len, "\nRetrieving using bindColumn with encoding set failed");
|
||||
|
||||
$result = "";
|
||||
$stmt = $conn->query($sql);
|
||||
|
|
|
@ -45,9 +45,23 @@ try {
|
|||
|
||||
$stmt->bindColumn(2, $value, PDO::PARAM_LOB, 0, PDO::SQLSRV_ENCODING_SYSTEM);
|
||||
$result = $stmt->fetch(PDO::FETCH_BOUND);
|
||||
if (!$result || $value !== $input[1]) {
|
||||
echo "Expected $input[1] but got: ";
|
||||
var_dump($result);
|
||||
if (PHP_VERSION_ID < 80100) {
|
||||
if (!$result || $value !== $input[1]) {
|
||||
echo "Expected $input[1] but got: ";
|
||||
var_dump($value);
|
||||
}
|
||||
} else {
|
||||
if (!$result || !is_resource($value)) {
|
||||
echo "Expected a stream resource but got: ";
|
||||
var_dump($value);
|
||||
}
|
||||
if (!feof($value)) {
|
||||
$str = fread($value, strlen($input[1]));
|
||||
if ($str !== $input[1]) {
|
||||
echo "Expected $input[1] but got: ";
|
||||
var_dump($str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$stmt->bindColumn(2, $value, PDO::PARAM_STR);
|
||||
|
|
|
@ -79,7 +79,7 @@ unset($stmt);
|
|||
unset($conn);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
Number of columns after UPDATE: 0
|
||||
array(8) {
|
||||
["flags"]=>
|
||||
|
@ -91,7 +91,7 @@ array(8) {
|
|||
["table"]=>
|
||||
string(0) ""
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
int(%d)
|
||||
["name"]=>
|
||||
string(2) "id"
|
||||
["len"]=>
|
||||
|
@ -109,7 +109,7 @@ array(8) {
|
|||
["table"]=>
|
||||
string(0) ""
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
int(%d)
|
||||
["name"]=>
|
||||
string(4) "name"
|
||||
["len"]=>
|
||||
|
|
|
@ -52,9 +52,15 @@ try {
|
|||
if (!is_null($det) || !is_null($rand)) {
|
||||
echo "Retrieving $typeFull data as $pdoParamType should not be supported\n";
|
||||
}
|
||||
// check the case when fetching as PDO::PARAM_STR or PDO::PARAM_LOB
|
||||
// check the case when fetching as PDO::PARAM_STR
|
||||
// with or without AE: should work
|
||||
} else {
|
||||
if (PHP_VERSION_ID >= 80100 && $pdoParamType == "PDO::PARAM_LOB") {
|
||||
// Starting with PHP 8.1 fetching as PDO::PARAM_LOB will return a resource obj
|
||||
$det = fread($det, 8192);
|
||||
$rand = fread($rand, 8192);
|
||||
}
|
||||
|
||||
if (trim($det) == $inputValues[0] && trim($rand) == $inputValues[1]) {
|
||||
echo "****Retrieving $typeFull data as $pdoParamType is supported****\n";
|
||||
} else {
|
||||
|
|
|
@ -53,6 +53,10 @@ try {
|
|||
// check the case when fetching as PDO::PARAM_STR or PDO::PARAM_LOB
|
||||
// with or without AE: should work
|
||||
} else {
|
||||
if (PHP_VERSION_ID >= 80100 && is_resource($c1)) {
|
||||
// Starting with PHP 8.1 fetching as PDO::PARAM_LOB will return a resource obj
|
||||
$c1 = fread($c1, 8192);
|
||||
}
|
||||
if (strlen($c1) == $m) {
|
||||
echo "****Retrieving $typeFull as $pdoParamType is supported****\n";
|
||||
} else {
|
||||
|
|
|
@ -47,6 +47,11 @@ try {
|
|||
// only check if input values are part of fetched values because some input values do not contain any deicmal places, the value retrieved however has 3 decimal places if the type is a datetime
|
||||
// with or without AE: should work
|
||||
} else {
|
||||
if (PHP_VERSION_ID >= 80100 && $pdoParamType == "PDO::PARAM_LOB") {
|
||||
// Starting with PHP 8.1 fetching as PDO::PARAM_LOB will return a resource obj
|
||||
$det = fread($det, 8192);
|
||||
$rand = fread($rand, 8192);
|
||||
}
|
||||
if (strpos($det, $inputValues[0]) !== false && strpos($rand, $inputValues[1]) !== false) {
|
||||
echo "****Retrieving $dataType as $pdoParamType is supported****\n";
|
||||
} else {
|
||||
|
|
|
@ -83,6 +83,11 @@ try {
|
|||
// check the case when fetching as PDO::PARAM_STR or PDO::PARAM_LOB
|
||||
// with or without AE: should work
|
||||
} else {
|
||||
if (PHP_VERSION_ID >= 80100 && $pdoParamType == "PDO::PARAM_LOB") {
|
||||
// Starting with PHP 8.1 fetching as PDO::PARAM_LOB will return a resource obj
|
||||
$det = fread($det, 8192);
|
||||
$rand = fread($rand, 8192);
|
||||
}
|
||||
if (compareDate($det, $inputValues[0], $dataType) && compareDate($rand, $inputValues[1], $dataType)) {
|
||||
echo "****Retrieving $typeFull as $pdoParamType is supported****\n";
|
||||
} else {
|
||||
|
|
|
@ -114,6 +114,11 @@ try {
|
|||
$succeeded = compareIntegers($pdoParamType, $det, $rand, $inputValues, $m1, $m2);
|
||||
}
|
||||
} else {
|
||||
if (PHP_VERSION_ID >= 80100 && $pdoParamType == "PDO::PARAM_LOB") {
|
||||
// Starting with PHP 8.1 fetching as PDO::PARAM_LOB will return a resource obj
|
||||
$det = fread($det, 8192);
|
||||
$rand = fread($rand, 8192);
|
||||
}
|
||||
if (abs($det - $inputValues[0]) < $epsilon &&
|
||||
abs($rand - $inputValues[1]) < $epsilon) {
|
||||
$succeeded = true;
|
||||
|
|
|
@ -57,6 +57,12 @@ try {
|
|||
echo "Retriving $typeFull data as $pdoParamType should return NULL\n";
|
||||
}
|
||||
} else {
|
||||
if (PHP_VERSION_ID >= 80100 && $pdoParamType == "PDO::PARAM_LOB") {
|
||||
// Starting with PHP 8.1 fetching as PDO::PARAM_LOB will return a resource obj
|
||||
$det = fread($det, 8192);
|
||||
$rand = fread($rand, 8192);
|
||||
}
|
||||
|
||||
if (abs($det - $inputValues[0]) < $epsilon && abs($rand - $inputValues[1]) < $epsilon) {
|
||||
echo "****Retrieving $typeFull as $pdoParamType is supported****\n";
|
||||
} else {
|
||||
|
|
|
@ -53,6 +53,10 @@ try {
|
|||
// check the case when fetching as PDO::PARAM_STR or PDO::PARAM_LOB
|
||||
// with or without AE: should work
|
||||
} else {
|
||||
if (PHP_VERSION_ID >= 80100 && is_resource($c1)) {
|
||||
// Starting with PHP 8.1 fetching as PDO::PARAM_LOB will return a resource obj
|
||||
$c1 = fread($c1, 8192);
|
||||
}
|
||||
if (strlen($c1) == $m) {
|
||||
echo "****Retrieving $typeFull as $pdoParamType is supported****\n";
|
||||
} else {
|
||||
|
|
|
@ -48,27 +48,41 @@ try {
|
|||
}
|
||||
// check the case when fetching as PDO::PARAM_BOOL or PDO::PARAM_INT
|
||||
// with or without AE: should only not work with bigint
|
||||
} else if ($pdoParamType == "PDO::PARAM_BOOL" || $pdoParamType == "PDO::PARAM_INT") {
|
||||
} elseif ($pdoParamType == "PDO::PARAM_BOOL" || $pdoParamType == "PDO::PARAM_INT") {
|
||||
if ($dataType == "bigint") {
|
||||
if (!is_null($det) || !is_null($rand)) {
|
||||
echo "Retrieving $dataType data as $pdoParamType should not be supported\n";
|
||||
}
|
||||
} else if ($dataType == "real") {
|
||||
if (abs($det - $inputValues[0]) < $epsilon && abs($rand - $inputValues[1]) < $epsilon) {
|
||||
} elseif (PHP_VERSION_ID >= 80100 && $pdoParamType == "PDO::PARAM_BOOL") {
|
||||
if ($det == boolval($inputValues[0]) && $rand == boolval($inputValues[1])) {
|
||||
echo "****Retrieving $dataType as $pdoParamType is supported****\n";
|
||||
} else {
|
||||
echo "Retrieving $dataType as $pdoParamType fails\n";
|
||||
}
|
||||
} else {
|
||||
if ($det == $inputValues[0] && $rand == $inputValues[1]) {
|
||||
echo "****Retrieving $dataType as $pdoParamType is supported****\n";
|
||||
if ($dataType == "real") {
|
||||
if (abs($det - $inputValues[0]) < $epsilon && abs($rand - $inputValues[1]) < $epsilon) {
|
||||
echo "****Retrieving $dataType as $pdoParamType is supported****\n";
|
||||
} else {
|
||||
echo "Retrieving $dataType as $pdoParamType fails\n";
|
||||
}
|
||||
} else {
|
||||
echo "Retrieving $dataType as $pdoParamType fails\n";
|
||||
if ($det == $inputValues[0] && $rand == $inputValues[1]) {
|
||||
echo "****Retrieving $dataType as $pdoParamType is supported****\n";
|
||||
} else {
|
||||
echo "Retrieving $dataType as $pdoParamType fails\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
// check the case when fetching as PDO::PARAM_BOOL, PDO::PARAM_INT, PDO::PARAM_STR or PDO::PARAM_LOB
|
||||
// with or without AE: should work
|
||||
} else {
|
||||
if ($pdoParamType == "PDO::PARAM_LOB") {
|
||||
if (PHP_VERSION_ID >= 80100) {
|
||||
$det = fread($det, 8192);
|
||||
$rand = fread($rand, 8192);
|
||||
}
|
||||
}
|
||||
if ($dataType == "real") {
|
||||
if (abs($det - $inputValues[0]) < $epsilon && abs($rand - $inputValues[1]) < $epsilon) {
|
||||
echo "****Retrieving $dataType as $pdoParamType is supported****\n";
|
||||
|
|
|
@ -129,8 +129,14 @@ function fetchBinaryAsBinary($conn, $tableName, $inputs)
|
|||
$stmt->bindColumn('c1', $binaryValue, PDO::PARAM_LOB, 0, PDO::SQLSRV_ENCODING_BINARY);
|
||||
$row = $stmt->fetch(PDO::FETCH_BOUND);
|
||||
|
||||
if ($binaryValue !== $inputs[0]) {
|
||||
echo "Fetched binary value unexpected: $binaryValue\n";
|
||||
if (PHP_VERSION_ID < 80100) {
|
||||
if ($binaryValue !== $inputs[0]) {
|
||||
echo "Fetched binary value unexpected: $binaryValue\n";
|
||||
}
|
||||
} else {
|
||||
if (!compareResourceToInput($binaryValue, $inputs[0])) {
|
||||
echo "Fetched binary value unexpected\n";
|
||||
}
|
||||
}
|
||||
} catch (PdoException $e) {
|
||||
echo "Caught exception in fetchBinaryAsBinary:\n";
|
||||
|
|
|
@ -50,7 +50,8 @@ function testConnAttrCases()
|
|||
$conn = new PDO($dsn, $uid, $pwd, $attr);
|
||||
$conn->getAttribute(PDO::SQLSRV_ATTR_DATA_CLASSIFICATION);
|
||||
} catch (PDOException $e) {
|
||||
if (!fnmatch($noSupportErr, $e->getMessage())) {
|
||||
$expected = (PHP_VERSION_ID < 80100) ? $noSupportErr : $stmtErr;
|
||||
if (!fnmatch($expected, $e->getMessage())) {
|
||||
echo "Connection attribute test (3) unexpected\n";
|
||||
var_dump($e->getMessage());
|
||||
}
|
||||
|
|
|
@ -52,7 +52,8 @@ function testConnAttrCases()
|
|||
$conn = new PDO($dsn, $uid, $pwd, $attr);
|
||||
$conn->getAttribute(PDO::SQLSRV_ATTR_DATA_CLASSIFICATION);
|
||||
} catch (PDOException $e) {
|
||||
if (!fnmatch($noSupportErr, $e->getMessage())) {
|
||||
$expected = (PHP_VERSION_ID < 80100) ? $noSupportErr : $stmtErr;
|
||||
if (!fnmatch($expected, $e->getMessage())) {
|
||||
echo "Connection attribute test (3) unexpected\n";
|
||||
var_dump($e->getMessage());
|
||||
}
|
||||
|
|
|
@ -30,6 +30,9 @@ try {
|
|||
$stmt->execute();
|
||||
$stmt->bindColumn('exist', $float_col, PDO::PARAM_LOB);
|
||||
$value = $stmt->fetch();
|
||||
if (PHP_VERSION_ID >= 80100) {
|
||||
$float_col = fread($float_col, 8192);
|
||||
}
|
||||
var_dump($float_col);
|
||||
|
||||
print "\nno buffered cursor, stringify off, fetch_numeric on\n";
|
||||
|
@ -38,6 +41,9 @@ try {
|
|||
$stmt->execute();
|
||||
$stmt->bindColumn('exist', $float_col, PDO::PARAM_LOB);
|
||||
$value = $stmt->fetch();
|
||||
if (PHP_VERSION_ID >= 80100) {
|
||||
$float_col = fread($float_col, 8192);
|
||||
}
|
||||
var_dump($float_col);
|
||||
|
||||
print "\nno buffered cursor, stringify on, fetch_numeric on\n";
|
||||
|
@ -63,6 +69,9 @@ try {
|
|||
$stmt->execute();
|
||||
$stmt->bindColumn('exist', $float_col, PDO::PARAM_LOB);
|
||||
$value = $stmt->fetch();
|
||||
if (PHP_VERSION_ID >= 80100) {
|
||||
$float_col = fread($float_col, 8192);
|
||||
}
|
||||
var_dump($float_col);
|
||||
|
||||
print "\nbuffered cursor, stringify off, fetch_numeric on\n";
|
||||
|
@ -71,6 +80,9 @@ try {
|
|||
$stmt->execute();
|
||||
$stmt->bindColumn('exist', $float_col, PDO::PARAM_LOB);
|
||||
$value = $stmt->fetch();
|
||||
if (PHP_VERSION_ID >= 80100) {
|
||||
$float_col = fread($float_col, 8192);
|
||||
}
|
||||
var_dump($float_col);
|
||||
|
||||
print "\nbuffered cursor, stringify on, fetch_numeric on\n";
|
||||
|
|
|
@ -135,7 +135,12 @@ function runTest($conn, $query, $columns, $values, $useBuffer = false)
|
|||
// Setting it to true only converts numeric values to strings when fetching
|
||||
// See http://www.php.net/manual/en/pdo.setattribute.php for details
|
||||
// stringify on, fetch_numeric off, fetch_datetime on
|
||||
$conn->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true);
|
||||
if (PHP_VERSION_ID < 80100) {
|
||||
// TODO: starting in PHP 8.1 with ATTR_STRINGIFY_FETCHES set to true
|
||||
// this fails with this error from PHP:
|
||||
// Fatal error: Uncaught Error: Object of class DateTime could not be converted to string
|
||||
$conn->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true);
|
||||
}
|
||||
$conn->setAttribute(PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, false);
|
||||
$conn->setAttribute(PDO::SQLSRV_ATTR_FETCHES_DATETIME_TYPE, true);
|
||||
$stmt = $conn->prepare($query, $options);
|
||||
|
@ -253,11 +258,7 @@ try {
|
|||
|
||||
$query = "INSERT INTO $tableName VALUES(?, ?, ?, ?, ?, ?)";
|
||||
$stmt = $conn->prepare($query);
|
||||
|
||||
// Bind the first param using the PHP DateTime object
|
||||
$today = date_create($values[0]);
|
||||
$stmt->bindParam(1, $today, PDO::PARAM_LOB);
|
||||
for ($i = 1; $i < count($columns); $i++) {
|
||||
for ($i = 0; $i < count($columns); $i++) {
|
||||
$stmt->bindParam($i+1, $values[$i], PDO::PARAM_LOB);
|
||||
}
|
||||
$stmt->execute();
|
||||
|
|
|
@ -23,6 +23,9 @@ $nstrValue = str_repeat("ÃÜðßZZýA©", 200);
|
|||
|
||||
function checkData($actual, $expected)
|
||||
{
|
||||
if (PHP_VERSION_ID >= 80100 && is_resource($actual)) {
|
||||
$actual = fread($actual, 8192);
|
||||
}
|
||||
trace("Actual:\n$actual\n");
|
||||
|
||||
$success = true;
|
||||
|
|
|
@ -7,12 +7,33 @@ Test getting invalid attributes
|
|||
|
||||
require_once("MsCommon_mid-refactor.inc");
|
||||
|
||||
// When testing with PHP 8.1-dev, pdo_sqlsrv handles unsupported attribute differently.
|
||||
// Implement a custom warning handler such that this test works with previous PHP versions as well.
|
||||
function warningHandler($errno, $errstr)
|
||||
{
|
||||
$warning = "Driver does not support this function: driver does not support that attribute";
|
||||
$str = strstr($errstr, $warning);
|
||||
if ($str == false) {
|
||||
echo "Unexpected warning message:";
|
||||
var_dump($errstr);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$conn = connect("", array(), PDO::ERRMODE_SILENT);
|
||||
|
||||
set_error_handler("warningHandler", E_WARNING);
|
||||
@$conn->getAttribute(PDO::ATTR_FETCH_TABLE_NAMES);
|
||||
print_r(($conn->errorInfo())[2]);
|
||||
echo "\n";
|
||||
|
||||
// Starting with PHP 8.1-dev getting an unsupported attribute pdo_sqlsrv will no longer
|
||||
// throw an exception. PHP PDO will handle the warning instead.
|
||||
if (PHP_VERSION_ID < 80100) {
|
||||
$errmsg = ($conn->errorInfo())[2];
|
||||
if ($errmsg !== "An unsupported attribute was designated on the PDO object.") {
|
||||
var_dump($conn->errorInfo());
|
||||
}
|
||||
}
|
||||
restore_error_handler();
|
||||
|
||||
@$conn->getAttribute(PDO::ATTR_CURSOR);
|
||||
print_r(($conn->errorInfo())[2]);
|
||||
|
@ -26,6 +47,5 @@ try {
|
|||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
An unsupported attribute was designated on the PDO object.
|
||||
The given attribute is only supported on the PDOStatement object.
|
||||
An invalid attribute was designated on the PDO object.
|
||||
|
|
|
@ -26,7 +26,7 @@ try {
|
|||
|
||||
$insertSql = "INSERT INTO $tableName (c1) VALUES (?)";
|
||||
$stmt = $conn->prepare($insertSql);
|
||||
$stmt->bindParam(1, $invalidUTF16, PDO::PARAM_STR, null, PDO::SQLSRV_ENCODING_BINARY);
|
||||
$stmt->bindParam(1, $invalidUTF16, PDO::PARAM_STR, 0, PDO::SQLSRV_ENCODING_BINARY);
|
||||
$stmt->execute();
|
||||
|
||||
try {
|
||||
|
|
|
@ -40,7 +40,7 @@ try {
|
|||
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
string(3) "200"
|
||||
string(3) "102"
|
||||
string(0) ""
|
||||
--EXPECTREGEX--
|
||||
string\(3\) "200"
|
||||
string\(3\) "102"
|
||||
(string\(0\) ""|bool\(false\))
|
||||
|
|
|
@ -6,7 +6,7 @@ prepare with emulate prepare and binding uft8 characters
|
|||
<?php
|
||||
require_once('MsCommon_mid-refactor.inc');
|
||||
|
||||
function prepareStmt($conn, $query, $prepareOptions = array(), $dataType = null, $length = null, $driverOptions = null)
|
||||
function prepareStmt($conn, $query, $prepareOptions = array(), $dataType = PDO::PARAM_STR, $length = 0, $driverOptions = null)
|
||||
{
|
||||
$name = "가각";
|
||||
if (!isColEncrypted()) {
|
||||
|
|
|
@ -4,12 +4,38 @@ Test warnings on connection and statement levels
|
|||
<?php require('skipif_mid-refactor.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$counter = 0;
|
||||
|
||||
// When testing with PHP 8.1-dev it throws different warning messages. Implement a custom
|
||||
// warning handler such that when testing with previous PHP versions, the warnings are
|
||||
// handled and verified differently.
|
||||
function warningHandler($errno, $errstr)
|
||||
{
|
||||
global $counter;
|
||||
|
||||
$warnings = array("An unsupported attribute was designated on the PDO object.",
|
||||
"Driver does not support this function: driver does not support that attribute");
|
||||
|
||||
if (PHP_VERSION_ID < 80100) {
|
||||
$str = strstr($errstr, $warnings[$counter++]);
|
||||
} else {
|
||||
$str = strstr($errstr, $warnings[1]);
|
||||
}
|
||||
if ($str == false) {
|
||||
echo "Unexpected warning message ($counter):";
|
||||
var_dump($errstr);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
require_once("MsCommon_mid-refactor.inc");
|
||||
|
||||
set_error_handler("warningHandler", E_WARNING);
|
||||
$conn = connect("", array(), PDO::ERRMODE_WARNING);
|
||||
// raise a warning in connection
|
||||
$conn->getAttribute(PDO::ATTR_TIMEOUT);
|
||||
restore_error_handler();
|
||||
|
||||
$tbname = "table1";
|
||||
dropTable($conn, $tbname);
|
||||
|
@ -22,15 +48,7 @@ try {
|
|||
unset($conn);
|
||||
} catch (PDOException $e) {
|
||||
var_dump($e->errorInfo);
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
--EXPECTREGEX--
|
||||
Warning: SQLSTATE: IMSSP
|
||||
Error Code: -38
|
||||
Error Message: An unsupported attribute was designated on the PDO object\.
|
||||
in .+(\/|\\)pdo_warnings\.php on line [0-9]+
|
||||
|
||||
Warning: PDO::getAttribute\(\): SQLSTATE\[IM001\]: Driver does not support this function: driver does not support that attribute in .+(\/|\\)pdo_warnings\.php on line [0-9]+
|
||||
|
||||
Warning: PDOStatement::execute\(\): SQLSTATE\[42000\]: Syntax error or access violation: 156 \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]\[SQL Server\]Incorrect syntax near the keyword 'TABLE'\. in .+(\/|\\)pdo_warnings\.php on line [0-9]+
|
||||
|
|
|
@ -111,8 +111,10 @@ function bindPARAM_NULL($db, $tbname)
|
|||
$query = "UPDATE PDO_AllTypes SET [BitCol]=:Name WHERE [VarcharCol]=:value";
|
||||
|
||||
$stmt = $db->prepare($query, array(PDO::ATTR_CURSOR=>PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE=>PDO::SQLSRV_CURSOR_BUFFERED));
|
||||
fwrite($noteID, null);
|
||||
rewind($noteID);
|
||||
// PHP Deprecated: fwrite(): Passing null to parameter #2 ($data) of type string is deprecated
|
||||
// Also, it is not necessary for this test
|
||||
// fwrite($noteID, null);
|
||||
// rewind($noteID);
|
||||
$stmt->bindParam(':Name', $noteID, PDO::PARAM_NULL);
|
||||
$stmt->bindParam(':value', $data);
|
||||
$stmt->execute();
|
||||
|
|
|
@ -28,16 +28,16 @@ try {
|
|||
var_dump($e);
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
SQL: [79] SELECT IntCol FROM PDO_AllTypes WHERE BigIntCol = :bigint AND CharCol = :string
|
||||
Params: 2
|
||||
Key: Name: [7] :bigint
|
||||
paramno=0
|
||||
name=[7] ":bigint"
|
||||
is_param=1
|
||||
param_type=1
|
||||
param_type=%d
|
||||
Key: Name: [7] :string
|
||||
paramno=1
|
||||
name=[7] ":string"
|
||||
is_param=1
|
||||
param_type=2
|
||||
param_type=%d
|
||||
|
|
|
@ -185,7 +185,7 @@ try {
|
|||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
SQLSTATE[IMSSP]: The given attribute is only supported on the PDOStatement object.
|
||||
SQLSTATE[IMSSP]: An invalid attribute was designated on the PDOStatement object.
|
||||
Start inserting data...
|
||||
|
@ -271,7 +271,7 @@ array(8) {
|
|||
["table"]=>
|
||||
string(0) ""
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
int(%d)
|
||||
["name"]=>
|
||||
string(6) "Budget"
|
||||
["len"]=>
|
||||
|
|
|
@ -94,7 +94,7 @@ try {
|
|||
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
|
||||
array(8) {
|
||||
["flags"]=>
|
||||
|
@ -106,7 +106,7 @@ array(8) {
|
|||
["table"]=>
|
||||
string(0) ""
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
int(%d)
|
||||
["name"]=>
|
||||
string(6) "IntCol"
|
||||
["len"]=>
|
||||
|
@ -124,7 +124,7 @@ array(8) {
|
|||
["table"]=>
|
||||
string(0) ""
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
int(%d)
|
||||
["name"]=>
|
||||
string(7) "CharCol"
|
||||
["len"]=>
|
||||
|
@ -142,7 +142,7 @@ array(8) {
|
|||
["table"]=>
|
||||
string(0) ""
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
int(%d)
|
||||
["name"]=>
|
||||
string(8) "NCharCol"
|
||||
["len"]=>
|
||||
|
@ -160,7 +160,7 @@ array(8) {
|
|||
["table"]=>
|
||||
string(0) ""
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
int(%d)
|
||||
["name"]=>
|
||||
string(11) "DateTimeCol"
|
||||
["len"]=>
|
||||
|
@ -178,7 +178,7 @@ array(8) {
|
|||
["table"]=>
|
||||
string(0) ""
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
int(%d)
|
||||
["name"]=>
|
||||
string(10) "VarcharCol"
|
||||
["len"]=>
|
||||
|
@ -196,7 +196,7 @@ array(8) {
|
|||
["table"]=>
|
||||
string(0) ""
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
int(%d)
|
||||
["name"]=>
|
||||
string(11) "NVarCharCol"
|
||||
["len"]=>
|
||||
|
@ -214,7 +214,7 @@ array(8) {
|
|||
["table"]=>
|
||||
string(0) ""
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
int(%d)
|
||||
["name"]=>
|
||||
string(8) "FloatCol"
|
||||
["len"]=>
|
||||
|
@ -230,7 +230,7 @@ array(7) {
|
|||
["table"]=>
|
||||
string(0) ""
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
int(%d)
|
||||
["name"]=>
|
||||
string(6) "XmlCol"
|
||||
["len"]=>
|
||||
|
|
|
@ -133,7 +133,7 @@ try {
|
|||
exit;
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
|
||||
array(8) {
|
||||
["flags"]=>
|
||||
|
@ -145,7 +145,7 @@ array(8) {
|
|||
["table"]=>
|
||||
string(0) ""
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
int(%d)
|
||||
["name"]=>
|
||||
string(12) "此是後話"
|
||||
["len"]=>
|
||||
|
@ -163,7 +163,7 @@ array(8) {
|
|||
["table"]=>
|
||||
string(0) ""
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
int(%d)
|
||||
["name"]=>
|
||||
string(29) "Κοντάוְאַתָּה第"
|
||||
["len"]=>
|
||||
|
@ -181,7 +181,7 @@ array(8) {
|
|||
["table"]=>
|
||||
string(0) ""
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
int(%d)
|
||||
["name"]=>
|
||||
string(30) "NΚοντάוְאַתָּה第"
|
||||
["len"]=>
|
||||
|
@ -199,7 +199,7 @@ array(8) {
|
|||
["table"]=>
|
||||
string(0) ""
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
int(%d)
|
||||
["name"]=>
|
||||
string(38) "ნომინავიiałopioБун"
|
||||
["len"]=>
|
||||
|
@ -217,7 +217,7 @@ array(8) {
|
|||
["table"]=>
|
||||
string(0) ""
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
int(%d)
|
||||
["name"]=>
|
||||
string(10) "VarcharCol"
|
||||
["len"]=>
|
||||
|
@ -235,7 +235,7 @@ array(8) {
|
|||
["table"]=>
|
||||
string(0) ""
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
int(%d)
|
||||
["name"]=>
|
||||
string(33) "NVarΚοντάוְאַתָּה第"
|
||||
["len"]=>
|
||||
|
@ -253,7 +253,7 @@ array(8) {
|
|||
["table"]=>
|
||||
string(0) ""
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
int(%d)
|
||||
["name"]=>
|
||||
string(8) "FloatCol"
|
||||
["len"]=>
|
||||
|
@ -269,7 +269,7 @@ array(7) {
|
|||
["table"]=>
|
||||
string(0) ""
|
||||
["pdo_type"]=>
|
||||
int(2)
|
||||
int(%d)
|
||||
["name"]=>
|
||||
string(6) "XmlCol"
|
||||
["len"]=>
|
||||
|
|
|
@ -74,7 +74,7 @@ class ColumnMeta
|
|||
|
||||
$unsupported = array("xml", "timestamp", "image", "ntext", "text", "sql_variant", "hierarchyid", "geography", "geometry", "alias");
|
||||
|
||||
if (stripos($this->options, "identity") !== false) {
|
||||
if (!is_null($this->options) && stripos($this->options, "identity") !== false) {
|
||||
$this->encryptable = false;
|
||||
} elseif (in_array(strtolower($this->dataType), $unsupported)) {
|
||||
$this->encryptable = false;
|
||||
|
@ -180,7 +180,7 @@ class BindParamOption
|
|||
$scal = $prec_scal[1];
|
||||
$size = null;
|
||||
}
|
||||
if (strpos($size, "max") !== false) {
|
||||
if (!is_null($size) && strpos($size, "max") !== false) {
|
||||
$size = trim($size, "'");
|
||||
}
|
||||
}
|
||||
|
@ -794,15 +794,14 @@ function getInsertData($rowIndex, $colIndex)
|
|||
if (empty($inputArray)) {
|
||||
fatalError("getInsertData: failed to retrieve data at row $rowIndex.\n");
|
||||
}
|
||||
$count = 0;
|
||||
foreach ($inputArray as $key => $value) {
|
||||
if (++$count == $colIndex) {
|
||||
if (is_array($value)) {
|
||||
return $value[0];
|
||||
} else {
|
||||
return $value;
|
||||
}
|
||||
break;
|
||||
|
||||
$key = getColName($colIndex);
|
||||
if (!empty($key)) {
|
||||
$value = $inputArray[$key];
|
||||
if (is_array($value)) {
|
||||
return $value[0];
|
||||
} else {
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -988,11 +987,7 @@ function isUnicode($k)
|
|||
|
||||
function isUpdatable($k)
|
||||
{
|
||||
switch ($k) {
|
||||
case 27: return (false); // timestamp
|
||||
default: break;
|
||||
}
|
||||
return (true);
|
||||
return ($k != 27); // timestamp
|
||||
}
|
||||
|
||||
function isLiteral($k)
|
||||
|
|
|
@ -37,7 +37,7 @@ function deleteQuery()
|
|||
|
||||
trace("Deleting rows from $tableName ...");
|
||||
$delRows = 1;
|
||||
if (strlen($keyValue) == 0) {
|
||||
if (empty($keyValue)) {
|
||||
$stmt2 = AE\executeQuery($conn1, "DELETE TOP(1) FROM [$tableName]");
|
||||
$cond = "(top row)";
|
||||
} else {
|
||||
|
|
|
@ -23,7 +23,7 @@ function fetchFields()
|
|||
AE\createTestTable($conn1, $tableName);
|
||||
|
||||
$startRow = 1;
|
||||
$noRows = 20;
|
||||
$noRows = 14; // 20;
|
||||
AE\insertTestRowsByRange($conn1, $tableName, $startRow, $startRow + $noRows - 1);
|
||||
|
||||
$query = "SELECT * FROM [$tableName] ORDER BY c27_timestamp";
|
||||
|
@ -49,8 +49,12 @@ function fetchFields()
|
|||
if (isUpdatable($col)) {
|
||||
// should check data even if $fld is null
|
||||
$data = AE\getInsertData($startRow + $i, $col);
|
||||
if (!checkData($col, $fld, $data)) {
|
||||
echo("\nData error\nExpected:\n$data\nActual:\n$fld\n");
|
||||
if (!checkData($col, $fld, $data, isBinary($col))) {
|
||||
// echo("\nData error\nExpected:\n$data\nActual:\n$fld\n");
|
||||
echo("\nData error\nExpected:\n");
|
||||
var_dump($data);
|
||||
echo("\nActual:\n");
|
||||
var_dump($fld);
|
||||
|
||||
setUTF8Data(false);
|
||||
die("Data corruption on row ".($startRow + $i)." column $col");
|
||||
|
@ -66,10 +70,23 @@ function fetchFields()
|
|||
sqlsrv_close($conn1);
|
||||
}
|
||||
|
||||
function checkData($col, $actual, $expected)
|
||||
function checkData($col, $actual, $expected, $isBinary)
|
||||
{
|
||||
$success = true;
|
||||
|
||||
|
||||
// First check for nulls
|
||||
if (is_null($expected)) {
|
||||
$success = ($isBinary) ? empty($actual) : is_null($actual);
|
||||
if (!$success) {
|
||||
trace("\nData error\nExpected null but Actual:\n$actual\n");
|
||||
}
|
||||
return $success;
|
||||
} elseif (is_null($actual)) {
|
||||
trace("\nData error\nExpected:\n$expected\nbut Actual is null\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Neither is null, so keep checking
|
||||
if (isNumeric($col)) {
|
||||
if (floatval($actual) != floatval($expected)) {
|
||||
$success = false;
|
||||
|
|
|
@ -126,9 +126,17 @@ function checkData($row, $stmt, $index, $mode)
|
|||
}
|
||||
} elseif (isBinary($col)) {
|
||||
$expected = sqlsrv_get_field($stmt, $index, SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR));
|
||||
$actual = bin2hex($actual);
|
||||
if (strcasecmp($actual, $expected) != 0) {
|
||||
$success = false;
|
||||
if (is_null($expected)) {
|
||||
$success = is_null($actual);
|
||||
} else {
|
||||
if (is_null($actual)) {
|
||||
$success = false;
|
||||
} else {
|
||||
$actual = bin2hex($actual);
|
||||
if (strcasecmp($actual, $expected) != 0) {
|
||||
$success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { // if (isChar($col))
|
||||
if (useUTF8Data()) {
|
||||
|
@ -136,7 +144,9 @@ function checkData($row, $stmt, $index, $mode)
|
|||
} else {
|
||||
$expected = sqlsrv_get_field($stmt, $index, SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR));
|
||||
}
|
||||
if (strcmp($actual, $expected) != 0) {
|
||||
if (is_null($expected)) {
|
||||
$success = is_null($actual);
|
||||
} elseif (strcmp($actual, $expected) != 0) {
|
||||
$success = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,15 +86,24 @@ function verifyStream($stmt, $row, $colIndex)
|
|||
|
||||
function checkData($col, $actual, $expected)
|
||||
{
|
||||
if (is_null($expected)) {
|
||||
return empty($actual);
|
||||
}
|
||||
|
||||
$success = true;
|
||||
|
||||
|
||||
if (isBinary($col)) {
|
||||
$actual = bin2hex($actual);
|
||||
if (strncasecmp($actual, $expected, strlen($expected)) != 0) {
|
||||
if (is_null($actual)) {
|
||||
$success = false;
|
||||
} else {
|
||||
$actual = bin2hex($actual);
|
||||
if (strncasecmp($actual, $expected, strlen($expected)) != 0) {
|
||||
$success = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (strncasecmp($actual, $expected, strlen($expected)) != 0) {
|
||||
$len = (empty($expected)) ? 0 : strlen($expected);
|
||||
if (strncasecmp($actual, $expected, $len) != 0) {
|
||||
if ($col != 19) { // skip ntext
|
||||
$pos = strpos($actual, $expected);
|
||||
if (($pos === false) || ($pos > 1)) {
|
||||
|
@ -120,7 +129,8 @@ startTest($testName);
|
|||
if (isLocaleSupported()) {
|
||||
try {
|
||||
setUTF8Data(false);
|
||||
streamRead(20, 1);
|
||||
// streamRead(20, 1);
|
||||
streamRead(14, 1);
|
||||
} catch (Exception $e) {
|
||||
echo $e->getMessage();
|
||||
}
|
||||
|
@ -132,7 +142,8 @@ startTest($testName);
|
|||
try {
|
||||
setUTF8Data(true);
|
||||
resetLocaleToDefault();
|
||||
streamRead(20, 1);
|
||||
// streamRead(20, 1);
|
||||
streamRead(14, 1);
|
||||
} catch (Exception $e) {
|
||||
echo $e->getMessage();
|
||||
}
|
||||
|
|
|
@ -105,15 +105,24 @@ function verifyStream($stmt, $row, $colIndex)
|
|||
|
||||
function checkData($col, $actual, $expected)
|
||||
{
|
||||
if (is_null($expected)) {
|
||||
return empty($actual);
|
||||
}
|
||||
|
||||
$success = true;
|
||||
|
||||
if (isBinary($col)) {
|
||||
$actual = bin2hex($actual);
|
||||
if (strncasecmp($actual, $expected, strlen($expected)) != 0) {
|
||||
if (is_null($actual)) {
|
||||
$success = false;
|
||||
} else {
|
||||
$actual = bin2hex($actual);
|
||||
if (strncasecmp($actual, $expected, strlen($expected)) != 0) {
|
||||
$success = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (strncasecmp($actual, $expected, strlen($expected)) != 0) {
|
||||
$len = (empty($expected)) ? 0 : strlen($expected);
|
||||
if (strncasecmp($actual, $expected, $len) != 0) {
|
||||
if ($col != 19) {
|
||||
// skip ntext
|
||||
$pos = strpos($actual, $expected);
|
||||
|
@ -143,7 +152,8 @@ startTest($testName);
|
|||
if (isLocaleSupported()) {
|
||||
try {
|
||||
setUTF8Data(false);
|
||||
streamScroll(20, 1);
|
||||
// streamScroll(20, 1);
|
||||
streamScroll(14, 1);
|
||||
} catch (Exception $e) {
|
||||
echo $e->getMessage();
|
||||
}
|
||||
|
@ -155,7 +165,8 @@ startTest($testName);
|
|||
try {
|
||||
setUTF8Data(true);
|
||||
resetLocaleToDefault();
|
||||
streamScroll(20, 1);
|
||||
// streamScroll(20, 1);
|
||||
streamScroll(14, 1);
|
||||
} catch (Exception $e) {
|
||||
echo $e->getMessage();
|
||||
}
|
||||
|
|
|
@ -25,13 +25,14 @@ if (!$stmt) {
|
|||
}
|
||||
|
||||
// insert new date time types as strings (this works now)
|
||||
$d1 = date_create();
|
||||
$insertSql = "INSERT INTO [$tableName] (id, [c1_date], [c2_time], [c3_datetimeoffset], [c4_datetime2]) VALUES (?, ?, ?, ?, ?)";
|
||||
$stmt = AE\executeQueryParams(
|
||||
$conn,
|
||||
$insertSql,
|
||||
array(rand(0, 99999),
|
||||
array(strftime('%Y-%m-%d'), SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STRING('utf-8'), SQLSRV_SQLTYPE_DATE),
|
||||
array(strftime('%H:%M:%S'), SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STRING('utf-8'), SQLSRV_SQLTYPE_TIME),
|
||||
array(date_format($d1, 'Y-m-d'), SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STRING('utf-8'), SQLSRV_SQLTYPE_DATE),
|
||||
array(date_format($d1, 'H:i:s'), SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STRING('utf-8'), SQLSRV_SQLTYPE_TIME),
|
||||
array(date_format(date_create(), 'Y-m-d H:i:s.u P'), SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STRING('utf-8'), SQLSRV_SQLTYPE_DATETIMEOFFSET),
|
||||
array(date_format(date_create(), 'Y-m-d H:i:s.u'), SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STRING('utf-8'), SQLSRV_SQLTYPE_DATETIME2)),
|
||||
false,
|
||||
|
@ -61,10 +62,11 @@ $stmt = AE\executeQueryParams(
|
|||
);
|
||||
|
||||
// insert new date time types as strings with no type information (this works)
|
||||
$d2 = date_create();
|
||||
$stmt = AE\executeQueryParams(
|
||||
$conn,
|
||||
$insertSql,
|
||||
array(rand(0, 99999), strftime('%Y-%m-%d'), strftime('%H:%M:%S'), date_format(date_create(), 'Y-m-d H:i:s.u P'), date_format(date_create(), 'Y-m-d H:i:s.u P')),
|
||||
array(rand(0, 99999), date_format($d2, 'Y-m-d'), date_format($d2, 'H:i:s'), date_format(date_create(), 'Y-m-d H:i:s.u P'), date_format(date_create(), 'Y-m-d H:i:s.u P')),
|
||||
false,
|
||||
"Insert 4 failed"
|
||||
);
|
||||
|
|
|
@ -60,7 +60,12 @@ function FetchAsStream_Binary()
|
|||
|
||||
function CompareValues($actual, $expected)
|
||||
{
|
||||
return (strncasecmp($actual, $expected, strlen($expected)) === 0);
|
||||
if (is_null($expected)) {
|
||||
return (is_null($actual));
|
||||
}
|
||||
|
||||
$len = (empty($expected)) ? 0 : strlen($expected);
|
||||
return (strncasecmp($actual, $expected, $len) === 0);
|
||||
}
|
||||
|
||||
function GetQuery($tableName, $index)
|
||||
|
|
|
@ -218,7 +218,7 @@ function compareDataStream($colType, $rowIndex, $colName, $stream, $expected)
|
|||
function compareBinaryData($actual, $expected)
|
||||
{
|
||||
// this function assumes $actual is a stream of hex
|
||||
$len = strlen($expected);
|
||||
$len = (empty($expected)) ? 0 : strlen($expected);
|
||||
$pos = 0;
|
||||
|
||||
$matched = true;
|
||||
|
|
Loading…
Reference in a new issue