Microsoft Drivers 3.0 for PHP for SQL Server
This commit is contained in:
parent
9c37a48e57
commit
c727ada07e
|
@ -1 +1 @@
|
||||||
Microsoft Drivers for PHP for SQL Server 2.0 Cumulative Update 1
|
Microsoft Drivers 3.0 for PHP for SQL Server (PDO driver)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
* Copyright and License Information *
|
* Copyright and License Information *
|
||||||
|
|
||||||
Copyright 2010 Microsoft Corporation
|
Copyright Microsoft Corporation
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License"); you
|
Licensed under the Apache License, Version 2.0 (the "License"); you
|
||||||
may not use this file except in compliance with the License.
|
may not use this file except in compliance with the License.
|
||||||
|
@ -14,33 +14,25 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
implied. See the License for the specific language governing
|
implied. See the License for the specific language governing
|
||||||
permissions and limitations under the License.
|
permissions and limitations under the License.
|
||||||
|
|
||||||
* Notes about changes to the Microsoft Drivers for PHP for SQL Server
|
* Notes about changes to the Microsoft Drivers 3.0 for PHP for SQL Server *
|
||||||
Driver 2.0 *
|
|
||||||
|
|
||||||
For details about the changes included in this release, please see our blog at
|
For details about the changes included in this release, please see our blog at
|
||||||
http://blogs.msdn.com/sqlphp or see the SQLSRV20_Readme.htm
|
http://blogs.msdn.com/sqlphp or see the SQLSRV_Readme.htm
|
||||||
file that is part of the download package.
|
file that is part of the download package.
|
||||||
|
|
||||||
* Notes about compiling the Microsoft Drivers for PHP for SQL Server 2.0 *
|
* Notes about compiling the Microsoft Drivers 3.0 for PHP for SQL Server *
|
||||||
|
|
||||||
Prerequisites:
|
Prerequisites:
|
||||||
|
|
||||||
* You must first be able to build PHP without including these
|
* You must first be able to build PHP without including these
|
||||||
extensions. For help with doing this, see xthe official PHP website,
|
extensions. For help with doing this, see the official PHP website,
|
||||||
http://php.net.
|
http://php.net.
|
||||||
|
|
||||||
* The header file sqlncli.h is required to build these extensions. It
|
To compile the SQLSRV30 and PDO_SQLSRV30:
|
||||||
may be installed with the Microsoft SQL Server® 2008 R2 Native Client
|
|
||||||
(found at Microsoft.com)
|
|
||||||
|
|
||||||
To compile the SQLSRV20 and PDO_SQLSRV20:
|
|
||||||
|
|
||||||
1) Copy the source code directories from this repository into the ext
|
1) Copy the source code directories from this repository into the ext
|
||||||
subdirectory.
|
subdirectory.
|
||||||
|
|
||||||
1a) Make sure that sqlncli.h is either on the INCLUDE file path or
|
|
||||||
copied locally to the extension directories.
|
|
||||||
|
|
||||||
2) run buildconf.bat to rebuild the configure.js script to include the
|
2) run buildconf.bat to rebuild the configure.js script to include the
|
||||||
new drivers.
|
new drivers.
|
||||||
|
|
||||||
|
@ -61,8 +53,8 @@ wish to do so, run "nmake clean" first.
|
||||||
php_sqlsrv.dll and php_pdo_sqlsrv.dll to your PHP extension directory.
|
php_sqlsrv.dll and php_pdo_sqlsrv.dll to your PHP extension directory.
|
||||||
Also enable them within your PHP installation's php.ini file.
|
Also enable them within your PHP installation's php.ini file.
|
||||||
|
|
||||||
This software has been compiled and tested under PHP 5.2.10 and PHP 5.3.0
|
This software has been compiled and tested under PHP 5.3.6 and later
|
||||||
using the Visual C++ 2008 Express and Standard compilers.
|
using the Visual C++ 2008 and 2010, Express and Standard compilers.
|
||||||
|
|
||||||
* Note about version.h *
|
* Note about version.h *
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
//
|
//
|
||||||
// Contents: JScript build configuration used by buildconf.bat
|
// Contents: JScript build configuration used by buildconf.bat
|
||||||
//
|
//
|
||||||
// Copyright 2010 Microsoft Corporation
|
// Copyright Microsoft Corporation
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -18,20 +18,21 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//----------------------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
ARG_WITH("pdo-sqlsrv", "MS SQL Server support for PDO", "no");
|
ARG_WITH("pdo-sqlsrv", "enable Microsoft Drivers for PHP for SQL Server (PDO driver)", "no");
|
||||||
|
|
||||||
|
|
||||||
if( PHP_PDO_SQLSRV != "no" ) {
|
if( PHP_PDO_SQLSRV != "no" ) {
|
||||||
|
|
||||||
if (CHECK_LIB("odbc32.lib", "pdo_sqlsrv") && CHECK_LIB("odbccp32.lib", "pdo_sqlsrv") &&
|
if (CHECK_LIB("odbc32.lib", "pdo_sqlsrv") && CHECK_LIB("odbccp32.lib", "pdo_sqlsrv") &&
|
||||||
CHECK_LIB("version.lib", "pdo_sqlsrv") && CHECK_LIB("psapi.lib", "pdo_sqlsrv")) {
|
CHECK_LIB("version.lib", "pdo_sqlsrv") && CHECK_LIB("psapi.lib", "pdo_sqlsrv")) {
|
||||||
|
|
||||||
EXTENSION("pdo_sqlsrv", "pdo_dbh.cpp pdo_init.cpp pdo_stmt.cpp pdo_util.cpp pdo_parser.cpp core_init.cpp core_conn.cpp core_stmt.cpp core_util.cpp core_stream.cpp" )
|
EXTENSION("pdo_sqlsrv", "pdo_dbh.cpp pdo_init.cpp pdo_stmt.cpp pdo_util.cpp pdo_parser.cpp core_init.cpp core_conn.cpp core_stmt.cpp core_util.cpp core_stream.cpp core_results.cpp" )
|
||||||
CHECK_HEADER_ADD_INCLUDE('sql.h', 'CFLAGS_PDO_SQLSRV_ODBC');
|
CHECK_HEADER_ADD_INCLUDE('sql.h', 'CFLAGS_PDO_SQLSRV_ODBC');
|
||||||
CHECK_HEADER_ADD_INCLUDE('sqlext.h', 'CFLAGS_PDO_SQLSRV_ODBC');
|
CHECK_HEADER_ADD_INCLUDE('sqlext.h', 'CFLAGS_PDO_SQLSRV_ODBC');
|
||||||
ADD_FLAG( 'LDFLAGS_PDO_SQLSRV', '/NXCOMPAT /DYNAMICBASE' );
|
ADD_FLAG( 'LDFLAGS_PDO_SQLSRV', '/NXCOMPAT /DYNAMICBASE' );
|
||||||
ADD_FLAG( 'CFLAGS_PDO_SQLSRV', '/EHsc' );
|
ADD_FLAG( 'CFLAGS_PDO_SQLSRV', '/EHsc' );
|
||||||
ADD_FLAG( 'CFLAGS_PDO_SQLSRV', '/GS' );
|
ADD_FLAG( 'CFLAGS_PDO_SQLSRV', '/GS' );
|
||||||
|
ADD_FLAG( 'CFLAGS_PDO_SQLSRV', '/D ZEND_WIN32_FORCE_INLINE' );
|
||||||
|
ADD_FLAG( 'CFLAGS_PDO_SQLSRV', '/D _HAS_CPP0X=0' );
|
||||||
ADD_EXTENSION_DEP('pdo_sqlsrv', 'pdo');
|
ADD_EXTENSION_DEP('pdo_sqlsrv', 'pdo');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
//
|
//
|
||||||
// Contents: Core routines that use connection handles shared between sqlsrv and pdo_sqlsrv
|
// Contents: Core routines that use connection handles shared between sqlsrv and pdo_sqlsrv
|
||||||
//
|
//
|
||||||
// Copyright 2010 Microsoft Corporation
|
// Copyright Microsoft Corporation
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -43,7 +43,7 @@ const int INFO_BUFFER_LEN = 256;
|
||||||
const char* PROCESSOR_ARCH[] = { "x86", "x64", "ia64" };
|
const char* PROCESSOR_ARCH[] = { "x86", "x64", "ia64" };
|
||||||
|
|
||||||
// ODBC driver name.
|
// ODBC driver name.
|
||||||
const char CONNECTION_STRING_DRIVER_NAME[] = "Driver={SQL Server Native Client 10.0};";
|
const char CONNECTION_STRING_DRIVER_NAME[] = "Driver={SQL Server Native Client 11.0};";
|
||||||
|
|
||||||
// default options if only the server is specified
|
// default options if only the server is specified
|
||||||
const char CONNECTION_STRING_DEFAULT_OPTIONS[] = "Mars_Connection={Yes}";
|
const char CONNECTION_STRING_DEFAULT_OPTIONS[] = "Mars_Connection={Yes}";
|
||||||
|
@ -562,6 +562,20 @@ void build_connection_string_and_set_conn_attr( sqlsrv_conn* conn, const char* s
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// workaround for a bug in ODBC Driver Manager wherein the Driver Manager creates a 0 KB file
|
||||||
|
// if the TraceFile option is set, even if the "TraceOn" is not present or the "TraceOn"
|
||||||
|
// flag is set to false.
|
||||||
|
if( zend_hash_index_exists( options, SQLSRV_CONN_OPTION_TRACE_FILE )) {
|
||||||
|
|
||||||
|
zval** trace_value = NULL;
|
||||||
|
int zr = zend_hash_index_find( options, SQLSRV_CONN_OPTION_TRACE_ON, (void**)&trace_value );
|
||||||
|
|
||||||
|
if( zr == FAILURE || !zend_is_true( *trace_value )) {
|
||||||
|
|
||||||
|
zend_hash_index_del( options, SQLSRV_CONN_OPTION_TRACE_FILE );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for( zend_hash_internal_pointer_reset( options );
|
for( zend_hash_internal_pointer_reset( options );
|
||||||
zend_hash_has_more_elements( options ) == SUCCESS;
|
zend_hash_has_more_elements( options ) == SUCCESS;
|
||||||
zend_hash_move_forward( options )) {
|
zend_hash_move_forward( options )) {
|
||||||
|
@ -573,9 +587,9 @@ void build_connection_string_and_set_conn_attr( sqlsrv_conn* conn, const char* s
|
||||||
zval** data = NULL;
|
zval** data = NULL;
|
||||||
|
|
||||||
type = zend_hash_get_current_key_ex( options, &key, &key_len, &index, 0, NULL );
|
type = zend_hash_get_current_key_ex( options, &key, &key_len, &index, 0, NULL );
|
||||||
CHECK_CUSTOM_ERROR(( type != HASH_KEY_IS_LONG ), conn, SQLSRV_ERROR_INVALID_OPTION_KEY ) {
|
|
||||||
throw core::CoreException();
|
// 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." );
|
||||||
|
|
||||||
core::sqlsrv_zend_hash_get_current_data( *conn, options, (void**) &data TSRMLS_CC );
|
core::sqlsrv_zend_hash_get_current_data( *conn, options, (void**) &data TSRMLS_CC );
|
||||||
|
|
||||||
|
@ -660,13 +674,14 @@ void determine_server_version( sqlsrv_conn* conn TSRMLS_DC )
|
||||||
char p[ INFO_BUFFER_LEN ];
|
char p[ INFO_BUFFER_LEN ];
|
||||||
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 TSRMLS_CC );
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
char version_major_str[ 3 ];
|
char version_major_str[ 3 ];
|
||||||
SERVER_VERSION version_major;
|
SERVER_VERSION version_major;
|
||||||
memcpy( version_major_str, p, 2 );
|
memcpy( version_major_str, p, 2 );
|
||||||
version_major_str[ 2 ] = '\0';
|
version_major_str[ 2 ] = '\0';
|
||||||
version_major = static_cast<SERVER_VERSION>( atoi( version_major_str ));
|
version_major = static_cast<SERVER_VERSION>( atoi( version_major_str ));
|
||||||
|
|
||||||
CHECK_CUSTOM_ERROR( version_major == 0 || errno == ERANGE || errno == EINVAL, conn, SQLSRV_ERROR_UNKNOWN_SERVER_VERSION )
|
CHECK_CUSTOM_ERROR( version_major == 0 && ( errno == ERANGE || errno == EINVAL ), conn, SQLSRV_ERROR_UNKNOWN_SERVER_VERSION )
|
||||||
{
|
{
|
||||||
throw core::CoreException();
|
throw core::CoreException();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
//
|
//
|
||||||
// Contents: common initialization routines shared by PDO and sqlsrv
|
// Contents: common initialization routines shared by PDO and sqlsrv
|
||||||
//
|
//
|
||||||
// Copyright 2010 Microsoft Corporation
|
// Copyright Microsoft Corporation
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
|
1338
pdo_sqlsrv/core_results.cpp
Normal file
1338
pdo_sqlsrv/core_results.cpp
Normal file
|
@ -0,0 +1,1338 @@
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
// File: core_results.cpp
|
||||||
|
//
|
||||||
|
// Contents: Result sets
|
||||||
|
//
|
||||||
|
// Copyright Microsoft Corporation
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
//
|
||||||
|
// You may obtain a copy of the License at:
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "core_sqlsrv.h"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
using namespace core;
|
||||||
|
|
||||||
|
// conversion matrix
|
||||||
|
// each entry holds a function that can perform the conversion or NULL which means the conversion isn't supported
|
||||||
|
// this is initialized the first time the buffered result set is created.
|
||||||
|
sqlsrv_buffered_result_set::conv_matrix_t sqlsrv_buffered_result_set::conv_matrix;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// *** internal types ***
|
||||||
|
|
||||||
|
#pragma warning(disable:4200)
|
||||||
|
|
||||||
|
// *** internal constants ***
|
||||||
|
|
||||||
|
const int INITIAL_FIELD_STRING_LEN = 256; // base allocation size when retrieving a string field
|
||||||
|
|
||||||
|
// *** internal functions ***
|
||||||
|
|
||||||
|
// return an integral type rounded up to a certain number
|
||||||
|
template <int align, typename T>
|
||||||
|
T align_to( T number )
|
||||||
|
{
|
||||||
|
DEBUG_SQLSRV_ASSERT( (number + align) > number, "Number to align overflowed" );
|
||||||
|
return ((number % align) == 0) ? number : (number + align - (number % align));
|
||||||
|
}
|
||||||
|
|
||||||
|
// return a pointer address aligned to a certain address boundary
|
||||||
|
template <int align, typename T>
|
||||||
|
T* align_to( T* ptr )
|
||||||
|
{
|
||||||
|
size_t p_value = (size_t) ptr;
|
||||||
|
return align_to<align, size_t>( p_value );
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the nth bit of the bitstream starting at ptr
|
||||||
|
void set_bit( void* ptr, unsigned int bit )
|
||||||
|
{
|
||||||
|
unsigned char* null_bits = reinterpret_cast<unsigned char*>( ptr );
|
||||||
|
null_bits += bit >> 3;
|
||||||
|
*null_bits |= 1 << ( 7 - ( bit & 0x7 ));
|
||||||
|
}
|
||||||
|
|
||||||
|
// retrieve the nth bit from the bitstream starting at ptr
|
||||||
|
bool get_bit( void* ptr, unsigned int bit )
|
||||||
|
{
|
||||||
|
unsigned char* null_bits = reinterpret_cast<unsigned char*>( ptr );
|
||||||
|
null_bits += bit >> 3;
|
||||||
|
return ((*null_bits & (1 << ( 7 - ( bit & 0x07 )))) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// read in LOB field during buffered result creation
|
||||||
|
SQLPOINTER read_lob_field( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_buffered_result_set::meta_data& meta,
|
||||||
|
unsigned long mem_used TSRMLS_DC );
|
||||||
|
|
||||||
|
// dtor for each row in the cache
|
||||||
|
void cache_row_dtor( void* data );
|
||||||
|
|
||||||
|
// convert a number to a string using locales
|
||||||
|
// There is an extra copy here, but given the size is short (usually <20 bytes) and the complications of
|
||||||
|
// subclassing a new streambuf just to avoid the copy, it's easier to do the copy
|
||||||
|
template <typename Char, typename Number>
|
||||||
|
SQLRETURN number_to_string( Number* number_data, __out void* buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length,
|
||||||
|
sqlsrv_error_auto_ptr& last_error )
|
||||||
|
{
|
||||||
|
std::basic_ostringstream<Char> os;
|
||||||
|
std::locale loc;
|
||||||
|
os.imbue( loc );
|
||||||
|
std::use_facet< std::num_put< Char > >( loc ).put( std::basic_ostream<Char>::_Iter( os.rdbuf() ), os, ' ', *number_data );
|
||||||
|
std::basic_string<Char>& str_num = os.str();
|
||||||
|
|
||||||
|
if( os.fail() ) {
|
||||||
|
last_error = new ( sqlsrv_malloc( sizeof( sqlsrv_error ))) sqlsrv_error(
|
||||||
|
(SQLCHAR*) "IMSSP", (SQLCHAR*) "Failed to convert number to string", -1 );
|
||||||
|
return SQL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( str_num.size() * sizeof(Char) + sizeof(Char) > (size_t) buffer_length ) {
|
||||||
|
last_error = new ( sqlsrv_malloc( sizeof( sqlsrv_error ))) sqlsrv_error(
|
||||||
|
(SQLCHAR*) "HY090", (SQLCHAR*) "Buffer length too small to hold number as string", -1 );
|
||||||
|
return SQL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_buffer_length = str_num.size() * sizeof(Char) + sizeof(Char); // include NULL terminator
|
||||||
|
memcpy( buffer, str_num.c_str(), *out_buffer_length );
|
||||||
|
|
||||||
|
return SQL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Number, typename Char>
|
||||||
|
SQLRETURN string_to_number( Char* string_data, SQLLEN str_len, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length, sqlsrv_error_auto_ptr& last_error )
|
||||||
|
{
|
||||||
|
Number* number_data = reinterpret_cast<Number*>( buffer );
|
||||||
|
std::locale loc; // default locale should match system
|
||||||
|
std::basic_istringstream<Char> is;
|
||||||
|
is.str( string_data );
|
||||||
|
is.imbue( loc );
|
||||||
|
std::ios_base::iostate st = 0;
|
||||||
|
|
||||||
|
std::use_facet< std::num_get< Char > >( loc ).get( std::basic_istream<Char>::_Iter( is.rdbuf( ) ),
|
||||||
|
std::basic_istream<Char>::_Iter(0), is, st, *number_data );
|
||||||
|
|
||||||
|
if( st & std::ios_base::failbit ) {
|
||||||
|
last_error = new ( sqlsrv_malloc( sizeof( sqlsrv_error ))) sqlsrv_error(
|
||||||
|
(SQLCHAR*) "22003", (SQLCHAR*) "Numeric value out of range", 103 );
|
||||||
|
return SQL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_buffer_length = sizeof( Number );
|
||||||
|
|
||||||
|
return SQL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// "closure" for the hash table destructor
|
||||||
|
struct row_dtor_closure {
|
||||||
|
|
||||||
|
sqlsrv_buffered_result_set* results;
|
||||||
|
BYTE* row_data;
|
||||||
|
|
||||||
|
row_dtor_closure( sqlsrv_buffered_result_set* st, BYTE* row ) :
|
||||||
|
results( st ), row_data( row )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
sqlsrv_error* odbc_get_diag_rec( sqlsrv_stmt* odbc, SQLSMALLINT record_number )
|
||||||
|
{
|
||||||
|
SQLWCHAR wsql_state[ SQL_SQLSTATE_BUFSIZE ];
|
||||||
|
SQLCHAR* sql_state = reinterpret_cast<SQLCHAR*>( wsql_state );
|
||||||
|
SQLWCHAR wnative_message[ SQL_MAX_MESSAGE_LENGTH + 1 ];
|
||||||
|
sqlsrv_malloc_auto_ptr<SQLCHAR> native_message;
|
||||||
|
SQLINTEGER native_code;
|
||||||
|
SQLINTEGER message_len;
|
||||||
|
|
||||||
|
SQLRETURN r = SQLGetDiagRecW( SQL_HANDLE_STMT, odbc->handle(), record_number, wsql_state, &native_code, wnative_message,
|
||||||
|
SQL_MAX_MESSAGE_LENGTH + 1, NULL );
|
||||||
|
if( !SQL_SUCCEEDED( r ) || r == SQL_NO_DATA ) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert the error into the encoding of the context
|
||||||
|
SQLSRV_ENCODING enc = odbc->encoding();
|
||||||
|
if( enc == SQLSRV_ENCODING_DEFAULT ) {
|
||||||
|
enc = odbc->conn->encoding();
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert the error into the encoding of the context
|
||||||
|
message_len = SQL_SQLSTATE_BUFSIZE * sizeof(WCHAR);
|
||||||
|
convert_string_from_utf16( enc, reinterpret_cast<char**>( &sql_state ), message_len,
|
||||||
|
false /*no free*/ );
|
||||||
|
message_len = (SQL_MAX_MESSAGE_LENGTH + 1) * sizeof( WCHAR );
|
||||||
|
native_message = reinterpret_cast<SQLCHAR*>( wnative_message );
|
||||||
|
convert_string_from_utf16( enc, reinterpret_cast<char**>( &native_message ), message_len,
|
||||||
|
false /*no free*/ );
|
||||||
|
|
||||||
|
return new (sqlsrv_malloc( sizeof( sqlsrv_error ))) sqlsrv_error( (SQLCHAR*) sql_state, (SQLCHAR*) native_message,
|
||||||
|
native_code );
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// base class result set
|
||||||
|
|
||||||
|
sqlsrv_result_set::sqlsrv_result_set( sqlsrv_stmt* stmt ) :
|
||||||
|
odbc( stmt )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ODBC result set
|
||||||
|
// This object simply wraps ODBC function calls
|
||||||
|
|
||||||
|
sqlsrv_odbc_result_set::sqlsrv_odbc_result_set( sqlsrv_stmt* stmt ) :
|
||||||
|
sqlsrv_result_set( stmt )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlsrv_odbc_result_set::~sqlsrv_odbc_result_set( void )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_odbc_result_set::fetch( SQLSMALLINT orientation, SQLLEN offset TSRMLS_DC )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( odbc != NULL, "Invalid statement handle" );
|
||||||
|
return core::SQLFetchScroll( odbc, orientation, offset TSRMLS_CC );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_odbc_result_set::get_data( SQLUSMALLINT field_index, SQLSMALLINT target_type,
|
||||||
|
__out SQLPOINTER buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length,
|
||||||
|
bool handle_warning TSRMLS_DC )
|
||||||
|
{
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_odbc_result_set::get_diag_field( SQLSMALLINT record_number, SQLSMALLINT diag_identifier,
|
||||||
|
__out SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
|
||||||
|
__out SQLSMALLINT* out_buffer_length TSRMLS_DC )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( odbc != NULL, "Invalid statement handle" );
|
||||||
|
return core::SQLGetDiagField( odbc, record_number, diag_identifier, diag_info_buffer, buffer_length,
|
||||||
|
out_buffer_length TSRMLS_CC );
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlsrv_error* sqlsrv_odbc_result_set::get_diag_rec( SQLSMALLINT record_number )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( odbc != NULL, "Invalid statement handle" );
|
||||||
|
return odbc_get_diag_rec( odbc, record_number );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLLEN sqlsrv_odbc_result_set::row_count( TSRMLS_D )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( odbc != NULL, "Invalid statement handle" );
|
||||||
|
return core::SQLRowCount( odbc TSRMLS_CC );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Buffered result set
|
||||||
|
// This class holds a result set in memory
|
||||||
|
|
||||||
|
sqlsrv_buffered_result_set::sqlsrv_buffered_result_set( sqlsrv_stmt* stmt TSRMLS_DC ) :
|
||||||
|
sqlsrv_result_set( stmt ),
|
||||||
|
cache(NULL),
|
||||||
|
col_count(0),
|
||||||
|
meta(NULL),
|
||||||
|
current(0),
|
||||||
|
last_field_index(-1),
|
||||||
|
read_so_far(0)
|
||||||
|
{
|
||||||
|
// 10 is an arbitrary number for now for the initial size of the cache
|
||||||
|
ALLOC_HASHTABLE( cache );
|
||||||
|
|
||||||
|
core::sqlsrv_zend_hash_init( *stmt, cache, 10 /* # of buckets */, NULL /* hashfn */, cache_row_dtor /*dtor*/, 0 /*persistent*/
|
||||||
|
TSRMLS_CC );
|
||||||
|
col_count = core::SQLNumResultCols( stmt TSRMLS_CC );
|
||||||
|
// there is no result set to buffer
|
||||||
|
if( col_count == 0 ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLULEN null_bytes = ( col_count / 8 ) + 1; // number of bits to reserve at the beginning of each row for NULL flags
|
||||||
|
meta = static_cast<sqlsrv_buffered_result_set::meta_data*>( sqlsrv_malloc( col_count *
|
||||||
|
sizeof( sqlsrv_buffered_result_set::meta_data )));
|
||||||
|
|
||||||
|
// set up the conversion matrix if this is the first time we're called
|
||||||
|
if( conv_matrix.size() == 0 ) {
|
||||||
|
|
||||||
|
conv_matrix[ SQL_C_CHAR ][ SQL_C_CHAR ] = &sqlsrv_buffered_result_set::to_same_string;
|
||||||
|
conv_matrix[ SQL_C_CHAR ][ SQL_C_WCHAR ] = &sqlsrv_buffered_result_set::system_to_wide_string;
|
||||||
|
conv_matrix[ SQL_C_CHAR ][ SQL_C_BINARY ] = &sqlsrv_buffered_result_set::to_binary_string;
|
||||||
|
conv_matrix[ SQL_C_CHAR ][ SQL_C_DOUBLE ] = &sqlsrv_buffered_result_set::string_to_double;
|
||||||
|
conv_matrix[ SQL_C_CHAR ][ SQL_C_LONG ] = &sqlsrv_buffered_result_set::string_to_long;
|
||||||
|
conv_matrix[ SQL_C_WCHAR ][ SQL_C_WCHAR ] = &sqlsrv_buffered_result_set::to_same_string;
|
||||||
|
conv_matrix[ SQL_C_WCHAR ][ SQL_C_BINARY ] = &sqlsrv_buffered_result_set::to_binary_string;
|
||||||
|
conv_matrix[ SQL_C_WCHAR ][ SQL_C_CHAR ] = &sqlsrv_buffered_result_set::wide_to_system_string;
|
||||||
|
conv_matrix[ SQL_C_WCHAR ][ SQL_C_DOUBLE ] = &sqlsrv_buffered_result_set::wstring_to_double;
|
||||||
|
conv_matrix[ SQL_C_WCHAR ][ SQL_C_LONG ] = &sqlsrv_buffered_result_set::wstring_to_long;
|
||||||
|
conv_matrix[ SQL_C_BINARY ][ SQL_C_BINARY ] = &sqlsrv_buffered_result_set::to_same_string;
|
||||||
|
conv_matrix[ SQL_C_BINARY ][ SQL_C_CHAR ] = &sqlsrv_buffered_result_set::binary_to_system_string;
|
||||||
|
conv_matrix[ SQL_C_BINARY ][ SQL_C_WCHAR ] = &sqlsrv_buffered_result_set::binary_to_wide_string;
|
||||||
|
conv_matrix[ SQL_C_LONG ][ SQL_C_DOUBLE ] = &sqlsrv_buffered_result_set::long_to_double;
|
||||||
|
conv_matrix[ SQL_C_LONG ][ SQL_C_LONG ] = &sqlsrv_buffered_result_set::to_long;
|
||||||
|
conv_matrix[ SQL_C_LONG ][ SQL_C_BINARY ] = &sqlsrv_buffered_result_set::to_long;
|
||||||
|
conv_matrix[ SQL_C_LONG ][ SQL_C_CHAR ] = &sqlsrv_buffered_result_set::long_to_system_string;
|
||||||
|
conv_matrix[ SQL_C_LONG ][ SQL_C_WCHAR ] = &sqlsrv_buffered_result_set::long_to_wide_string;
|
||||||
|
conv_matrix[ SQL_C_DOUBLE ][ SQL_C_DOUBLE ] = &sqlsrv_buffered_result_set::to_double;
|
||||||
|
conv_matrix[ SQL_C_DOUBLE ][ SQL_C_BINARY ] = &sqlsrv_buffered_result_set::to_double;
|
||||||
|
conv_matrix[ SQL_C_DOUBLE ][ SQL_C_CHAR ] = &sqlsrv_buffered_result_set::double_to_system_string;
|
||||||
|
conv_matrix[ SQL_C_DOUBLE ][ SQL_C_LONG ] = &sqlsrv_buffered_result_set::double_to_long;
|
||||||
|
conv_matrix[ SQL_C_DOUBLE ][ SQL_C_WCHAR ] = &sqlsrv_buffered_result_set::double_to_wide_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the meta data and calculate the size of a row buffer
|
||||||
|
SQLULEN offset = null_bytes;
|
||||||
|
for( SQLSMALLINT i = 0; i < col_count; ++i ) {
|
||||||
|
|
||||||
|
core::SQLDescribeCol( stmt, i + 1, NULL, 0, NULL, &meta[i].type, &meta[i].length, &meta[i].scale, NULL TSRMLS_CC );
|
||||||
|
|
||||||
|
offset = align_to<4>( offset );
|
||||||
|
meta[i].offset = offset;
|
||||||
|
|
||||||
|
switch( meta[i].type ) {
|
||||||
|
|
||||||
|
// these types are the display size
|
||||||
|
case SQL_BIGINT:
|
||||||
|
case SQL_DECIMAL:
|
||||||
|
case SQL_GUID:
|
||||||
|
case SQL_NUMERIC:
|
||||||
|
core::SQLColAttribute( stmt, i + 1, SQL_DESC_DISPLAY_SIZE, NULL, 0, NULL,
|
||||||
|
reinterpret_cast<SQLLEN*>( &meta[i].length ) TSRMLS_CC );
|
||||||
|
meta[i].length += sizeof( char ) + sizeof( SQLULEN ); // null terminator space
|
||||||
|
offset += meta[i].length;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// these types are the column size
|
||||||
|
case SQL_BINARY:
|
||||||
|
case SQL_CHAR:
|
||||||
|
case SQL_SS_UDT:
|
||||||
|
case SQL_VARBINARY:
|
||||||
|
case SQL_VARCHAR:
|
||||||
|
// var* field types are length prefixed
|
||||||
|
if( meta[i].length == sqlsrv_buffered_result_set::meta_data::SIZE_UNKNOWN ) {
|
||||||
|
offset += sizeof( void* );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
meta[i].length += sizeof( SQLULEN ) + sizeof( char ); // length plus null terminator space
|
||||||
|
offset += meta[i].length;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SQL_WCHAR:
|
||||||
|
case SQL_WVARCHAR:
|
||||||
|
if( meta[i].length == sqlsrv_buffered_result_set::meta_data::SIZE_UNKNOWN ) {
|
||||||
|
offset += sizeof( void* );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
meta[i].length *= sizeof( WCHAR );
|
||||||
|
meta[i].length += sizeof( SQLULEN ) + sizeof( WCHAR ); // length plus null terminator space
|
||||||
|
offset += meta[i].length;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// these types are LOBs
|
||||||
|
case SQL_LONGVARBINARY:
|
||||||
|
case SQL_LONGVARCHAR:
|
||||||
|
case SQL_WLONGVARCHAR:
|
||||||
|
case SQL_SS_XML:
|
||||||
|
meta[i].length = sqlsrv_buffered_result_set::meta_data::SIZE_UNKNOWN;
|
||||||
|
offset += sizeof( void* );
|
||||||
|
break;
|
||||||
|
|
||||||
|
// these types are the ISO date size
|
||||||
|
case SQL_DATETIME:
|
||||||
|
case SQL_TYPE_DATE:
|
||||||
|
case SQL_SS_TIME2:
|
||||||
|
case SQL_SS_TIMESTAMPOFFSET:
|
||||||
|
case SQL_TYPE_TIMESTAMP:
|
||||||
|
core::SQLColAttribute( stmt, i + 1, SQL_DESC_DISPLAY_SIZE, NULL, 0, NULL,
|
||||||
|
reinterpret_cast<SQLLEN*>( &meta[i].length ) TSRMLS_CC );
|
||||||
|
meta[i].length += sizeof(char) + sizeof( SQLULEN ); // null terminator space
|
||||||
|
offset += meta[i].length;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// these types are the native size
|
||||||
|
case SQL_BIT:
|
||||||
|
case SQL_INTEGER:
|
||||||
|
case SQL_SMALLINT:
|
||||||
|
case SQL_TINYINT:
|
||||||
|
meta[i].length = sizeof( long );
|
||||||
|
offset += meta[i].length;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SQL_REAL:
|
||||||
|
case SQL_FLOAT:
|
||||||
|
meta[i].length = sizeof( double );
|
||||||
|
offset += meta[i].length;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
SQLSRV_ASSERT( false, "Unknown type in sqlsrv_buffered_query::sqlsrv_buffered_query" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( meta[i].type ) {
|
||||||
|
|
||||||
|
case SQL_BIGINT:
|
||||||
|
case SQL_CHAR:
|
||||||
|
case SQL_DATETIME:
|
||||||
|
case SQL_DECIMAL:
|
||||||
|
case SQL_GUID:
|
||||||
|
case SQL_NUMERIC:
|
||||||
|
case SQL_LONGVARCHAR:
|
||||||
|
case SQL_TYPE_DATE:
|
||||||
|
case SQL_SS_TIME2:
|
||||||
|
case SQL_SS_TIMESTAMPOFFSET:
|
||||||
|
case SQL_SS_XML:
|
||||||
|
case SQL_TYPE_TIMESTAMP:
|
||||||
|
case SQL_VARCHAR:
|
||||||
|
meta[i].c_type = SQL_C_CHAR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SQL_SS_UDT:
|
||||||
|
case SQL_LONGVARBINARY:
|
||||||
|
case SQL_BINARY:
|
||||||
|
case SQL_VARBINARY:
|
||||||
|
meta[i].c_type = SQL_C_BINARY;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SQL_WLONGVARCHAR:
|
||||||
|
case SQL_WCHAR:
|
||||||
|
case SQL_WVARCHAR:
|
||||||
|
meta[i].c_type = SQL_C_WCHAR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SQL_BIT:
|
||||||
|
case SQL_INTEGER:
|
||||||
|
case SQL_SMALLINT:
|
||||||
|
case SQL_TINYINT:
|
||||||
|
meta[i].c_type = SQL_C_LONG;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SQL_REAL:
|
||||||
|
case SQL_FLOAT:
|
||||||
|
meta[i].c_type = SQL_C_DOUBLE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
SQLSRV_ASSERT( false, "Unknown type in sqlsrv_buffered_query::sqlsrv_buffered_query" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// read the data into the cache
|
||||||
|
// (offset from the above loop has the size of the row buffer necessary)
|
||||||
|
unsigned long mem_used = 0;
|
||||||
|
unsigned long row_count = 0;
|
||||||
|
|
||||||
|
while( core::SQLFetchScroll( stmt, SQL_FETCH_NEXT, 0 TSRMLS_CC ) != SQL_NO_DATA ) {
|
||||||
|
|
||||||
|
// allocate the row buffer
|
||||||
|
unsigned char* row = static_cast<unsigned char*>( sqlsrv_malloc( offset ));
|
||||||
|
memset( row, 0, offset );
|
||||||
|
|
||||||
|
// read the fields into the row buffer
|
||||||
|
for( SQLSMALLINT i = 0; i < col_count; ++i ) {
|
||||||
|
|
||||||
|
SQLLEN out_buffer_temp = SQL_NULL_DATA;
|
||||||
|
SQLPOINTER buffer;
|
||||||
|
SQLLEN* out_buffer_length = &out_buffer_temp;
|
||||||
|
|
||||||
|
switch( meta[i].c_type ) {
|
||||||
|
|
||||||
|
case SQL_C_CHAR:
|
||||||
|
case SQL_C_WCHAR:
|
||||||
|
case SQL_C_BINARY:
|
||||||
|
if( meta[i].length == sqlsrv_buffered_result_set::meta_data::SIZE_UNKNOWN ) {
|
||||||
|
|
||||||
|
out_buffer_length = &out_buffer_temp;
|
||||||
|
SQLPOINTER* lob_addr = reinterpret_cast<SQLPOINTER*>( &row[ meta[i].offset ] );
|
||||||
|
*lob_addr = read_lob_field( stmt, i, meta[i], mem_used TSRMLS_CC );
|
||||||
|
// a NULL pointer means NULL field
|
||||||
|
if( *lob_addr == NULL ) {
|
||||||
|
*out_buffer_length = SQL_NULL_DATA;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*out_buffer_length = **reinterpret_cast<SQLLEN**>( lob_addr );
|
||||||
|
mem_used += *out_buffer_length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
mem_used += meta[i].length;
|
||||||
|
CHECK_CUSTOM_ERROR( mem_used > stmt->buffered_query_limit * 1024, stmt,
|
||||||
|
SQLSRV_ERROR_BUFFER_LIMIT_EXCEEDED, stmt->buffered_query_limit ) {
|
||||||
|
|
||||||
|
throw core::CoreException();
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = row + meta[i].offset + sizeof( SQLULEN );
|
||||||
|
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,
|
||||||
|
false TSRMLS_CC );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SQL_C_LONG:
|
||||||
|
case SQL_C_DOUBLE:
|
||||||
|
{
|
||||||
|
mem_used += meta[i].length;
|
||||||
|
CHECK_CUSTOM_ERROR( mem_used > stmt->buffered_query_limit * 1024, stmt,
|
||||||
|
SQLSRV_ERROR_BUFFER_LIMIT_EXCEEDED, stmt->buffered_query_limit ) {
|
||||||
|
|
||||||
|
throw core::CoreException();
|
||||||
|
}
|
||||||
|
buffer = row + meta[i].offset;
|
||||||
|
out_buffer_length = &out_buffer_temp;
|
||||||
|
core::SQLGetData( stmt, i + 1, meta[i].c_type, buffer, meta[i].length, out_buffer_length,
|
||||||
|
false TSRMLS_CC );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
SQLSRV_ASSERT( false, "Unknown C type" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( *out_buffer_length == SQL_NULL_DATA ) {
|
||||||
|
unsigned char* null_bits = reinterpret_cast<unsigned char*>( row );
|
||||||
|
set_bit( row, i );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLSRV_ASSERT( row_count < LONG_MAX, "Hard maximum of 2 billion rows exceeded in a buffered query" );
|
||||||
|
|
||||||
|
// add it to the cache
|
||||||
|
row_dtor_closure cl( this, row );
|
||||||
|
sqlsrv_zend_hash_next_index_insert( *stmt, cache, &cl, sizeof( cl ) TSRMLS_CC );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlsrv_buffered_result_set::~sqlsrv_buffered_result_set( void )
|
||||||
|
{
|
||||||
|
// free the rows
|
||||||
|
if( cache ) {
|
||||||
|
zend_hash_destroy( cache );
|
||||||
|
FREE_HASHTABLE( cache );
|
||||||
|
cache = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// free the meta data
|
||||||
|
if( meta ) {
|
||||||
|
efree( meta );
|
||||||
|
meta = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::fetch( SQLSMALLINT orientation, SQLLEN offset TSRMLS_DC )
|
||||||
|
{
|
||||||
|
last_error = NULL;
|
||||||
|
last_field_index = -1;
|
||||||
|
read_so_far = 0;
|
||||||
|
|
||||||
|
switch( orientation ) {
|
||||||
|
|
||||||
|
case SQL_FETCH_NEXT:
|
||||||
|
offset = 1;
|
||||||
|
orientation = SQL_FETCH_RELATIVE;
|
||||||
|
break;
|
||||||
|
case SQL_FETCH_PRIOR:
|
||||||
|
offset = -1;
|
||||||
|
orientation = SQL_FETCH_RELATIVE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( orientation ) {
|
||||||
|
|
||||||
|
case SQL_FETCH_FIRST:
|
||||||
|
current = 1;
|
||||||
|
break;
|
||||||
|
case SQL_FETCH_LAST:
|
||||||
|
current = row_count( TSRMLS_C );
|
||||||
|
break;
|
||||||
|
case SQL_FETCH_ABSOLUTE:
|
||||||
|
current = offset;
|
||||||
|
break;
|
||||||
|
case SQL_FETCH_RELATIVE:
|
||||||
|
current += offset;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SQLSRV_ASSERT( false, "Invalid fetch orientation. Should have been caught before here." );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check validity of current row
|
||||||
|
// the cursor can never get further away than just before the first row
|
||||||
|
if( current <= 0 && ( offset < 0 || orientation != SQL_FETCH_RELATIVE )) {
|
||||||
|
current = 0;
|
||||||
|
return SQL_NO_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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*/ ) {
|
||||||
|
current = row_count( TSRMLS_C ) + 1;
|
||||||
|
return SQL_NO_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SQL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::get_data( SQLUSMALLINT field_index, SQLSMALLINT target_type,
|
||||||
|
__out SQLPOINTER buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length,
|
||||||
|
bool handle_warning TSRMLS_DC )
|
||||||
|
{
|
||||||
|
last_error = NULL;
|
||||||
|
field_index--; // convert from 1 based to 0 based
|
||||||
|
SQLSRV_ASSERT( field_index < column_count(), "Invalid field index requested" );
|
||||||
|
|
||||||
|
if( field_index != last_field_index ) {
|
||||||
|
last_field_index = field_index;
|
||||||
|
read_so_far = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
|
||||||
|
// if the field is null, then return SQL_NULL_DATA
|
||||||
|
if( get_bit( row, field_index )) {
|
||||||
|
*out_buffer_length = SQL_NULL_DATA;
|
||||||
|
return SQL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check to make sure the conversion type is valid
|
||||||
|
if( conv_matrix.find( meta[ field_index ].c_type ) == conv_matrix.end() ||
|
||||||
|
conv_matrix.find( meta[ field_index ].c_type )->second.find( target_type ) ==
|
||||||
|
conv_matrix.find( meta[ field_index ].c_type )->second.end() ) {
|
||||||
|
|
||||||
|
last_error = new (sqlsrv_malloc( sizeof( sqlsrv_error )))
|
||||||
|
sqlsrv_error( (SQLCHAR*) "07006",
|
||||||
|
(SQLCHAR*) "Restricted data type attribute violation", 0 );
|
||||||
|
return SQL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (( this )->*( conv_matrix[ meta[ field_index ].c_type ][ target_type ] ))( field_index, buffer, buffer_length,
|
||||||
|
out_buffer_length );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::get_diag_field( SQLSMALLINT record_number, SQLSMALLINT diag_identifier,
|
||||||
|
__out SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
|
||||||
|
__out SQLSMALLINT* out_buffer_length TSRMLS_DC )
|
||||||
|
{
|
||||||
|
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,
|
||||||
|
"Only SQL_DIAG_SQLSTATE can be fetched by sqlsrv_buffered_result_set::get_diag_field" );
|
||||||
|
SQLSRV_ASSERT( buffer_length >= SQL_SQLSTATE_BUFSIZE,
|
||||||
|
"Buffer not big enough to return SQLSTATE in sqlsrv_buffered_result_set::get_diag_field" );
|
||||||
|
|
||||||
|
if( last_error == NULL ) {
|
||||||
|
return SQL_NO_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLSRV_ASSERT( last_error->sqlstate != NULL,
|
||||||
|
"Must have a SQLSTATE in a valid last_error in sqlsrv_buffered_result_set::get_diag_field" );
|
||||||
|
|
||||||
|
memcpy( diag_info_buffer, last_error->sqlstate, min( buffer_length, SQL_SQLSTATE_BUFSIZE ));
|
||||||
|
|
||||||
|
return SQL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char* sqlsrv_buffered_result_set::get_row( void )
|
||||||
|
{
|
||||||
|
row_dtor_closure* cl_ptr;
|
||||||
|
int zr = zend_hash_index_find( cache, current - 1, (void**) &cl_ptr );
|
||||||
|
SQLSRV_ASSERT( zr == SUCCESS, "Failed to find row %1!d! in the cache", current );
|
||||||
|
return cl_ptr->row_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlsrv_error* sqlsrv_buffered_result_set::get_diag_rec( SQLSMALLINT record_number )
|
||||||
|
{
|
||||||
|
// we only hold a single error if there is one, otherwise return the ODBC error(s)
|
||||||
|
if( last_error == NULL ) {
|
||||||
|
return odbc_get_diag_rec( odbc, record_number );
|
||||||
|
}
|
||||||
|
if( record_number > 1 ) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new (sqlsrv_malloc( sizeof( sqlsrv_error )))
|
||||||
|
sqlsrv_error( last_error->sqlstate, last_error->native_message, last_error->native_code );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLLEN sqlsrv_buffered_result_set::row_count( TSRMLS_D )
|
||||||
|
{
|
||||||
|
last_error = NULL;
|
||||||
|
|
||||||
|
return zend_hash_num_elements( cache );
|
||||||
|
}
|
||||||
|
|
||||||
|
// private functions
|
||||||
|
template <typename Char>
|
||||||
|
SQLRETURN binary_to_string( SQLCHAR* field_data, SQLLEN& read_so_far, __out void* buffer,
|
||||||
|
SQLLEN buffer_length, __out SQLLEN* out_buffer_length,
|
||||||
|
sqlsrv_error_auto_ptr& out_error )
|
||||||
|
{
|
||||||
|
// hex characters for the conversion loop below
|
||||||
|
static char hex_chars[] = "0123456789ABCDEF";
|
||||||
|
|
||||||
|
SQLSRV_ASSERT( out_error == NULL, "Pending error for sqlsrv_buffered_results_set::binary_to_string" );
|
||||||
|
|
||||||
|
SQLRETURN r = SQL_ERROR;
|
||||||
|
|
||||||
|
// Set the amount of space necessary for null characters at the end of the data.
|
||||||
|
SQLSMALLINT extra = sizeof(Char);
|
||||||
|
|
||||||
|
SQLSRV_ASSERT( ((buffer_length - extra) % (extra * 2)) == 0, "Must be multiple of 2 for binary to system string or "
|
||||||
|
"multiple of 4 for binary to wide string" );
|
||||||
|
|
||||||
|
// all fields will be treated as ODBC returns varchar(max) fields:
|
||||||
|
// the entire length of the string is returned the first
|
||||||
|
// call in out_buffer_len. Successive calls return how much is
|
||||||
|
// left minus how much has already been read by previous reads
|
||||||
|
// *2 is for each byte to hex conversion and * extra is for either system or wide string allocation
|
||||||
|
*out_buffer_length = (*reinterpret_cast<SQLLEN*>( field_data - sizeof( SQLULEN )) - read_so_far) * 2 * extra;
|
||||||
|
|
||||||
|
// copy as much as we can into the buffer
|
||||||
|
SQLLEN to_copy;
|
||||||
|
if( buffer_length < *out_buffer_length + extra ) {
|
||||||
|
to_copy = (buffer_length - extra);
|
||||||
|
out_error = new ( sqlsrv_malloc( sizeof( sqlsrv_error )))
|
||||||
|
sqlsrv_error( (SQLCHAR*) "01004", (SQLCHAR*) "String data, right truncated", -1 );
|
||||||
|
r = SQL_SUCCESS_WITH_INFO;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
r = SQL_SUCCESS;
|
||||||
|
to_copy = *out_buffer_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if there are bytes to copy as hex
|
||||||
|
if( to_copy > 0 ) {
|
||||||
|
// quick hex conversion routine
|
||||||
|
Char* h = reinterpret_cast<Char*>( buffer );
|
||||||
|
BYTE* b = reinterpret_cast<BYTE*>( field_data );
|
||||||
|
// to_copy contains the number of bytes to copy, so we divide the number in half (or quarter)
|
||||||
|
// to get the number of hex digits we can copy
|
||||||
|
SQLLEN to_copy_hex = to_copy / (2 * extra);
|
||||||
|
for( int i = 0; i < to_copy_hex; ++i ) {
|
||||||
|
*h = hex_chars[ (*b & 0xf0) >> 4 ];
|
||||||
|
h++;
|
||||||
|
*h = hex_chars[ (*b++ & 0x0f) ];
|
||||||
|
h++;
|
||||||
|
}
|
||||||
|
read_so_far += to_copy_hex;
|
||||||
|
*h = static_cast<Char>( 0 );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
reinterpret_cast<char*>( buffer )[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::binary_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLCHAR* row = get_row();
|
||||||
|
SQLCHAR* field_data = NULL;
|
||||||
|
|
||||||
|
if( meta[ field_index ].length == sqlsrv_buffered_result_set::meta_data::SIZE_UNKNOWN ) {
|
||||||
|
|
||||||
|
field_data = *reinterpret_cast<SQLCHAR**>( &row[ meta[ field_index ].offset ] ) + sizeof( SQLULEN );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
field_data = &row[ meta[ field_index ].offset ] + sizeof( SQLULEN );
|
||||||
|
}
|
||||||
|
|
||||||
|
return binary_to_string<char>( field_data, read_so_far, buffer, buffer_length, out_buffer_length, last_error );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::binary_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLCHAR* row = get_row();
|
||||||
|
SQLCHAR* field_data = NULL;
|
||||||
|
|
||||||
|
if( meta[ field_index ].length == sqlsrv_buffered_result_set::meta_data::SIZE_UNKNOWN ) {
|
||||||
|
|
||||||
|
field_data = *reinterpret_cast<SQLCHAR**>( &row[ meta[ field_index ].offset ] ) + sizeof( SQLULEN );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
field_data = &row[ meta[ field_index ].offset ] + sizeof( SQLULEN );
|
||||||
|
}
|
||||||
|
|
||||||
|
return binary_to_string<WCHAR>( field_data, read_so_far, buffer, buffer_length, out_buffer_length, last_error );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::double_to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_DOUBLE, "Invalid conversion to long" );
|
||||||
|
SQLSRV_ASSERT( buffer_length >= sizeof(LONG), "Buffer length must be able to find a long in "
|
||||||
|
"sqlsrv_buffered_result_set::double_to_long" );
|
||||||
|
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
double* double_data = reinterpret_cast<double*>( &row[ meta[ field_index ].offset ] );
|
||||||
|
LONG* long_data = reinterpret_cast<LONG*>( buffer );
|
||||||
|
|
||||||
|
if( *double_data < double( LONG_MIN ) || *double_data > double( LONG_MAX )) {
|
||||||
|
last_error = new (sqlsrv_malloc( sizeof( sqlsrv_error ))) sqlsrv_error( (SQLCHAR*) "22003",
|
||||||
|
(SQLCHAR*) "Numeric value out of range", 0 );
|
||||||
|
return SQL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( *double_data != floor( *double_data )) {
|
||||||
|
last_error = new (sqlsrv_malloc( sizeof( sqlsrv_error ))) sqlsrv_error( (SQLCHAR*) "01S07",
|
||||||
|
(SQLCHAR*) "Fractional truncation", 0 );
|
||||||
|
return SQL_SUCCESS_WITH_INFO;
|
||||||
|
}
|
||||||
|
|
||||||
|
*long_data = static_cast<LONG>( *double_data );
|
||||||
|
*out_buffer_length = sizeof( LONG );
|
||||||
|
|
||||||
|
return SQL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::double_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_DOUBLE, "Invalid conversion to system string" );
|
||||||
|
SQLSRV_ASSERT( buffer_length > 0, "Buffer length must be > 0 in sqlsrv_buffered_result_set::double_to_system_string" );
|
||||||
|
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
double* double_data = reinterpret_cast<double*>( &row[ meta[ field_index ].offset ] );
|
||||||
|
|
||||||
|
return number_to_string<char>( double_data, buffer, buffer_length, out_buffer_length, last_error );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::double_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_DOUBLE, "Invalid conversion to wide string" );
|
||||||
|
SQLSRV_ASSERT( buffer_length > 0, "Buffer length must be > 0 in sqlsrv_buffered_result_set::double_to_wide_string" );
|
||||||
|
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
double* double_data = reinterpret_cast<double*>( &row[ meta[ field_index ].offset ] );
|
||||||
|
|
||||||
|
return number_to_string<WCHAR>( double_data, buffer, buffer_length, out_buffer_length, last_error );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::long_to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_LONG, "Invalid conversion to long" );
|
||||||
|
SQLSRV_ASSERT( buffer_length >= sizeof(double), "Buffer length must be able to find a long in sqlsrv_buffered_result_set::double_to_long" );
|
||||||
|
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
double* double_data = reinterpret_cast<double*>( buffer );
|
||||||
|
LONG* long_data = reinterpret_cast<LONG*>( &row[ meta[ field_index ].offset ] );
|
||||||
|
|
||||||
|
*double_data = static_cast<LONG>( *long_data );
|
||||||
|
*out_buffer_length = sizeof( double );
|
||||||
|
|
||||||
|
return SQL_SUCCESS;
|
||||||
|
}
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::long_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_LONG, "Invalid conversion to system string" );
|
||||||
|
SQLSRV_ASSERT( buffer_length > 0, "Buffer length must be > 0 in sqlsrv_buffered_result_set::long_to_system_string" );
|
||||||
|
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
LONG* long_data = reinterpret_cast<LONG*>( &row[ meta[ field_index ].offset ] );
|
||||||
|
|
||||||
|
return number_to_string<char>( long_data, buffer, buffer_length, out_buffer_length, last_error );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::long_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_LONG, "Invalid conversion to wide string" );
|
||||||
|
SQLSRV_ASSERT( buffer_length > 0, "Buffer length must be > 0 in sqlsrv_buffered_result_set::long_to_wide_string" );
|
||||||
|
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
LONG* long_data = reinterpret_cast<LONG*>( &row[ meta[ field_index ].offset ] );
|
||||||
|
|
||||||
|
return number_to_string<WCHAR>( long_data, buffer, buffer_length, out_buffer_length, last_error );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::string_to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_CHAR, "Invalid conversion from string to double" );
|
||||||
|
SQLSRV_ASSERT( buffer_length >= sizeof( double ), "Buffer needs to be big enough to hold a double" );
|
||||||
|
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
char* string_data = reinterpret_cast<char*>( &row[ meta[ field_index ].offset ] ) + sizeof( SQLULEN );
|
||||||
|
|
||||||
|
return string_to_number<double>( string_data, meta[ field_index ].length, buffer, buffer_length, out_buffer_length, last_error );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::wstring_to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_WCHAR, "Invalid conversion from wide string to double" );
|
||||||
|
SQLSRV_ASSERT( buffer_length >= sizeof( double ), "Buffer needs to be big enough to hold a double" );
|
||||||
|
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
SQLWCHAR* string_data = reinterpret_cast<SQLWCHAR*>( &row[ meta[ field_index ].offset ] ) + sizeof( SQLULEN ) / sizeof( SQLWCHAR );
|
||||||
|
|
||||||
|
return string_to_number<double>( string_data, meta[ field_index ].length, buffer, buffer_length, out_buffer_length, last_error );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::string_to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_CHAR, "Invalid conversion from string to long" );
|
||||||
|
SQLSRV_ASSERT( buffer_length >= sizeof( LONG ), "Buffer needs to be big enough to hold a long" );
|
||||||
|
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
char* string_data = reinterpret_cast<char*>( &row[ meta[ field_index ].offset ] ) + sizeof( SQLULEN );
|
||||||
|
|
||||||
|
return string_to_number<LONG>( string_data, meta[ field_index ].length, buffer, buffer_length, out_buffer_length, last_error );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::wstring_to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_WCHAR, "Invalid conversion from wide string to long" );
|
||||||
|
SQLSRV_ASSERT( buffer_length >= sizeof( LONG ), "Buffer needs to be big enough to hold a long" );
|
||||||
|
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
SQLWCHAR* string_data = reinterpret_cast<SQLWCHAR*>( &row[ meta[ field_index ].offset ] ) + sizeof( SQLULEN ) / sizeof( SQLWCHAR );
|
||||||
|
|
||||||
|
return string_to_number<LONG>( string_data, meta[ field_index ].length, buffer, buffer_length, out_buffer_length, last_error );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::system_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( last_error == NULL, "Pending error for sqlsrv_buffered_results_set::system_to_wide_string" );
|
||||||
|
SQLSRV_ASSERT( buffer_length % 2 == 0, "Odd buffer length passed to sqlsrv_buffered_result_set::system_to_wide_string" );
|
||||||
|
|
||||||
|
SQLRETURN r = SQL_ERROR;
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
|
||||||
|
SQLCHAR* field_data = NULL;
|
||||||
|
SQLULEN field_len = NULL;
|
||||||
|
|
||||||
|
if( meta[ field_index ].length == sqlsrv_buffered_result_set::meta_data::SIZE_UNKNOWN ) {
|
||||||
|
|
||||||
|
field_len = **reinterpret_cast<SQLLEN**>( &row[ meta[ field_index ].offset ] );
|
||||||
|
field_data = *reinterpret_cast<SQLCHAR**>( &row[ meta[ field_index ].offset ] ) + sizeof( SQLULEN ) + read_so_far;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
field_len = *reinterpret_cast<SQLLEN*>( &row[ meta[ field_index ].offset ] );
|
||||||
|
field_data = &row[ meta[ field_index ].offset ] + sizeof( SQLULEN ) + read_so_far;
|
||||||
|
}
|
||||||
|
|
||||||
|
// all fields will be treated as ODBC returns varchar(max) fields:
|
||||||
|
// the entire length of the string is returned the first
|
||||||
|
// call in out_buffer_len. Successive calls return how much is
|
||||||
|
// left minus how much has already been read by previous reads
|
||||||
|
*out_buffer_length = (*reinterpret_cast<SQLLEN*>( field_data - sizeof( SQLULEN )) - read_so_far) * sizeof(WCHAR);
|
||||||
|
|
||||||
|
// to_copy is the number of characters to copy, not including the null terminator
|
||||||
|
// supposedly it will never happen that a Windows MBCS will explode to UTF-16 surrogate pair.
|
||||||
|
SQLLEN to_copy;
|
||||||
|
|
||||||
|
if( (size_t) buffer_length < (field_len - read_so_far + sizeof(char)) * sizeof(WCHAR)) {
|
||||||
|
|
||||||
|
to_copy = (buffer_length - sizeof(WCHAR)) / sizeof(WCHAR); // to_copy is the number of characters
|
||||||
|
last_error = new ( sqlsrv_malloc( sizeof( sqlsrv_error )))
|
||||||
|
sqlsrv_error( (SQLCHAR*) "01004", (SQLCHAR*) "String data, right truncated", -1 );
|
||||||
|
r = SQL_SUCCESS_WITH_INFO;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
r = SQL_SUCCESS;
|
||||||
|
to_copy = field_len - read_so_far;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( to_copy > 0 ) {
|
||||||
|
|
||||||
|
bool tried_again = false;
|
||||||
|
do {
|
||||||
|
int ch_space = MultiByteToWideChar( CP_ACP, MB_ERR_INVALID_CHARS, (LPCSTR) field_data, to_copy,
|
||||||
|
(LPWSTR) buffer, to_copy );
|
||||||
|
if( ch_space == 0 ) {
|
||||||
|
|
||||||
|
switch( GetLastError() ) {
|
||||||
|
|
||||||
|
case ERROR_NO_UNICODE_TRANSLATION:
|
||||||
|
// the theory here is the conversion failed because the end of the buffer we provided contained only
|
||||||
|
// half a character at the end
|
||||||
|
if( !tried_again ) {
|
||||||
|
to_copy--;
|
||||||
|
tried_again = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
last_error = new ( sqlsrv_malloc( sizeof( sqlsrv_error )))
|
||||||
|
sqlsrv_error( (SQLCHAR*) "IMSSP", (SQLCHAR*) "Invalid Unicode translation", -1 );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SQLSRV_ASSERT( false, "Severe error translating Unicode" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SQL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
((WCHAR*)buffer)[ to_copy ] = L'\0';
|
||||||
|
read_so_far += to_copy;
|
||||||
|
break;
|
||||||
|
|
||||||
|
} while( true );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
reinterpret_cast<WCHAR*>( buffer )[0] = L'\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::to_same_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( last_error == NULL, "Pending error for sqlsrv_buffered_results_set::to_same_string" );
|
||||||
|
|
||||||
|
SQLRETURN r = SQL_ERROR;
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
|
||||||
|
// Set the amount of space necessary for null characters at the end of the data.
|
||||||
|
SQLSMALLINT extra = 0;
|
||||||
|
|
||||||
|
switch( meta[ field_index ].c_type ) {
|
||||||
|
case SQL_C_WCHAR:
|
||||||
|
extra = sizeof( SQLWCHAR );
|
||||||
|
break;
|
||||||
|
case SQL_C_BINARY:
|
||||||
|
extra = 0;
|
||||||
|
break;
|
||||||
|
case SQL_C_CHAR:
|
||||||
|
extra = sizeof( SQLCHAR );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SQLSRV_ASSERT( false, "Invalid type in get_string_data" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLCHAR* field_data = NULL;
|
||||||
|
|
||||||
|
if( meta[ field_index ].length == sqlsrv_buffered_result_set::meta_data::SIZE_UNKNOWN ) {
|
||||||
|
|
||||||
|
field_data = *reinterpret_cast<SQLCHAR**>( &row[ meta[ field_index ].offset ] ) + sizeof( SQLULEN );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
field_data = &row[ meta[ field_index ].offset ] + sizeof( SQLULEN );
|
||||||
|
}
|
||||||
|
|
||||||
|
// all fields will be treated as ODBC returns varchar(max) fields:
|
||||||
|
// the entire length of the string is returned the first
|
||||||
|
// call in out_buffer_len. Successive calls return how much is
|
||||||
|
// left minus how much has already been read by previous reads
|
||||||
|
*out_buffer_length = *reinterpret_cast<SQLLEN*>( field_data - sizeof( SQLULEN )) - read_so_far;
|
||||||
|
|
||||||
|
// copy as much as we can into the buffer
|
||||||
|
SQLLEN to_copy;
|
||||||
|
if( buffer_length < *out_buffer_length + extra ) {
|
||||||
|
to_copy = buffer_length - extra;
|
||||||
|
last_error = new ( sqlsrv_malloc( sizeof( sqlsrv_error )))
|
||||||
|
sqlsrv_error( (SQLCHAR*) "01004", (SQLCHAR*) "String data, right truncated", -1 );
|
||||||
|
r = SQL_SUCCESS_WITH_INFO;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
r = SQL_SUCCESS;
|
||||||
|
to_copy = *out_buffer_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLSRV_ASSERT( to_copy >= 0, "Negative field length calculated in buffered result set" );
|
||||||
|
|
||||||
|
if( to_copy > 0 ) {
|
||||||
|
memcpy( buffer, field_data + read_so_far, to_copy );
|
||||||
|
read_so_far += to_copy;
|
||||||
|
}
|
||||||
|
if( extra ) {
|
||||||
|
OACR_WARNING_SUPPRESS( 26001, "Buffer length verified above" );
|
||||||
|
memcpy( reinterpret_cast<SQLCHAR*>( buffer ) + to_copy, L"\0", extra );
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::wide_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( last_error == NULL, "Pending error for sqlsrv_buffered_results_set::wide_to_system_string" );
|
||||||
|
|
||||||
|
SQLRETURN r = SQL_ERROR;
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
|
||||||
|
SQLCHAR* field_data = NULL;
|
||||||
|
SQLULEN field_len = NULL;
|
||||||
|
|
||||||
|
// if this is the first time called for this field, just convert the entire string to system first then
|
||||||
|
// use that to read from instead of converting chunk by chunk. This is because it's impossible to know
|
||||||
|
// the total length of the string for output_buffer_length without doing the conversion and returning
|
||||||
|
// SQL_NO_TOTAL is not consistent with what our other conversion functions do (system_to_wide_string and
|
||||||
|
// to_same_string).
|
||||||
|
|
||||||
|
if( read_so_far == 0 ) {
|
||||||
|
|
||||||
|
if( meta[ field_index ].length == sqlsrv_buffered_result_set::meta_data::SIZE_UNKNOWN ) {
|
||||||
|
|
||||||
|
field_len = **reinterpret_cast<SQLLEN**>( &row[ meta[ field_index ].offset ] );
|
||||||
|
field_data = *reinterpret_cast<SQLCHAR**>( &row[ meta[ field_index ].offset ] ) + sizeof( SQLULEN ) + read_so_far;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
field_len = *reinterpret_cast<SQLLEN*>( &row[ meta[ field_index ].offset ] );
|
||||||
|
field_data = &row[ meta[ field_index ].offset ] + sizeof( SQLULEN ) + read_so_far;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL default_char_used = FALSE;
|
||||||
|
char default_char = '?';
|
||||||
|
|
||||||
|
// allocate enough to handle WC -> DBCS conversion if it happens
|
||||||
|
temp_string = reinterpret_cast<SQLCHAR*>( sqlsrv_malloc( field_len, sizeof( char ), sizeof(char)));
|
||||||
|
temp_length = WideCharToMultiByte( CP_ACP, 0, (LPCWSTR) field_data, field_len / sizeof(WCHAR),
|
||||||
|
(LPSTR) temp_string.get(), field_len, &default_char, &default_char_used );
|
||||||
|
|
||||||
|
if( temp_length == 0 ) {
|
||||||
|
|
||||||
|
switch( GetLastError() ) {
|
||||||
|
|
||||||
|
case ERROR_NO_UNICODE_TRANSLATION:
|
||||||
|
last_error = new ( sqlsrv_malloc( sizeof( sqlsrv_error )))
|
||||||
|
sqlsrv_error( (SQLCHAR*) "IMSSP", (SQLCHAR*) "Invalid Unicode translation", -1 );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SQLSRV_ASSERT( false, "Severe error translating Unicode" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SQL_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_buffer_length = (temp_length - read_so_far);
|
||||||
|
|
||||||
|
SQLLEN to_copy = 0;
|
||||||
|
|
||||||
|
if( (size_t) buffer_length < (temp_length - read_so_far + sizeof(char))) {
|
||||||
|
|
||||||
|
to_copy = buffer_length - sizeof(char);
|
||||||
|
last_error = new ( sqlsrv_malloc( sizeof( sqlsrv_error )))
|
||||||
|
sqlsrv_error( (SQLCHAR*) "01004", (SQLCHAR*) "String data, right truncated", -1 );
|
||||||
|
r = SQL_SUCCESS_WITH_INFO;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
to_copy = (temp_length - read_so_far);
|
||||||
|
r = SQL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( to_copy > 0 ) {
|
||||||
|
|
||||||
|
memcpy( buffer, temp_string.get() + read_so_far, to_copy );
|
||||||
|
}
|
||||||
|
SQLSRV_ASSERT( to_copy >= 0, "Invalid field copy length" );
|
||||||
|
OACR_WARNING_SUPPRESS( BUFFER_UNDERFLOW, "Buffer length verified above" );
|
||||||
|
((SQLCHAR*) buffer)[ to_copy ] = '\0';
|
||||||
|
read_so_far += to_copy;
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::to_binary_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
return to_same_string( field_index, buffer, buffer_length, out_buffer_length );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_LONG, "Invlid conversion to long" );
|
||||||
|
SQLSRV_ASSERT( buffer_length >= sizeof( LONG ), "Buffer too small for SQL_C_LONG" ); // technically should ignore this
|
||||||
|
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
LONG* long_data = reinterpret_cast<LONG*>( &row[ meta[ field_index ].offset ] );
|
||||||
|
|
||||||
|
memcpy( buffer, long_data, sizeof( LONG ));
|
||||||
|
*out_buffer_length = sizeof( LONG );
|
||||||
|
|
||||||
|
return SQL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_DOUBLE, "Invlid conversion to double" );
|
||||||
|
SQLSRV_ASSERT( buffer_length >= sizeof( double ), "Buffer too small for SQL_C_DOUBLE" ); // technically should ignore this
|
||||||
|
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
double* double_data = reinterpret_cast<double*>( &row[ meta[ field_index ].offset ] );
|
||||||
|
|
||||||
|
memcpy( buffer, double_data, sizeof( double ));
|
||||||
|
*out_buffer_length = sizeof( double );
|
||||||
|
|
||||||
|
return SQL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// called for each row in the cache when the cache is destroyed in the destructor
|
||||||
|
void cache_row_dtor( void* data )
|
||||||
|
{
|
||||||
|
row_dtor_closure* cl = reinterpret_cast<row_dtor_closure*>( data );
|
||||||
|
BYTE* row = cl->row_data;
|
||||||
|
// don't release this here, since this is called from the destructor of the result_set
|
||||||
|
sqlsrv_buffered_result_set* result_set = cl->results;
|
||||||
|
|
||||||
|
for( SQLSMALLINT i = 0; i < result_set->column_count(); ++i ) {
|
||||||
|
|
||||||
|
if( result_set->col_meta_data(i).length == sqlsrv_buffered_result_set::meta_data::SIZE_UNKNOWN ) {
|
||||||
|
|
||||||
|
void* out_of_row_data = *reinterpret_cast<void**>( &row[ result_set->col_meta_data(i).offset ] );
|
||||||
|
sqlsrv_free( out_of_row_data );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlsrv_free( row );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLPOINTER read_lob_field( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_buffered_result_set::meta_data& meta,
|
||||||
|
unsigned long mem_used TSRMLS_DC )
|
||||||
|
{
|
||||||
|
SQLSMALLINT extra = 0;
|
||||||
|
SQLLEN* output_buffer_len = NULL;
|
||||||
|
|
||||||
|
// Set the amount of space necessary for null characters at the end of the data.
|
||||||
|
switch( meta.c_type ) {
|
||||||
|
case SQL_C_WCHAR:
|
||||||
|
extra = sizeof( SQLWCHAR );
|
||||||
|
break;
|
||||||
|
case SQL_C_BINARY:
|
||||||
|
extra = 0;
|
||||||
|
break;
|
||||||
|
case SQL_C_CHAR:
|
||||||
|
extra = sizeof( SQLCHAR );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SQLSRV_ASSERT( false, "Invalid type in read_lob_field" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLLEN already_read = 0;
|
||||||
|
SQLLEN to_read = INITIAL_FIELD_STRING_LEN;
|
||||||
|
sqlsrv_malloc_auto_ptr<char> buffer;
|
||||||
|
buffer = static_cast<char*>( sqlsrv_malloc( INITIAL_FIELD_STRING_LEN + extra + sizeof( SQLULEN )));
|
||||||
|
SQLRETURN r = SQL_SUCCESS;
|
||||||
|
SQLCHAR state[ SQL_SQLSTATE_BUFSIZE ];
|
||||||
|
SQLLEN last_field_len = 0;
|
||||||
|
bool full_length_returned = false;
|
||||||
|
|
||||||
|
do {
|
||||||
|
|
||||||
|
|
||||||
|
output_buffer_len = reinterpret_cast<SQLLEN*>( buffer.get() );
|
||||||
|
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 );
|
||||||
|
|
||||||
|
// if the field is NULL, then return a NULL pointer
|
||||||
|
if( last_field_len == SQL_NULL_DATA ) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the last read was successful, we're done
|
||||||
|
if( r == SQL_SUCCESS ) {
|
||||||
|
// check to make sure we haven't overflown our memory limit
|
||||||
|
CHECK_CUSTOM_ERROR( mem_used + last_field_len > stmt->buffered_query_limit * 1024, stmt,
|
||||||
|
SQLSRV_ERROR_BUFFER_LIMIT_EXCEEDED, stmt->buffered_query_limit ) {
|
||||||
|
|
||||||
|
throw core::CoreException();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// else if it wasn't the truncated warning (01004) then we're done
|
||||||
|
else if( r == SQL_SUCCESS_WITH_INFO ) {
|
||||||
|
SQLSMALLINT len;
|
||||||
|
core::SQLGetDiagField( stmt, 1, SQL_DIAG_SQLSTATE, state, SQL_SQLSTATE_BUFSIZE, &len
|
||||||
|
TSRMLS_CC );
|
||||||
|
|
||||||
|
if( !is_truncated_warning( state )) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLSRV_ASSERT( SQL_SUCCEEDED( r ), "Unknown SQL error not triggered" );
|
||||||
|
|
||||||
|
// if the type of the field returns the total to be read, we use that and preallocate the buffer
|
||||||
|
if( last_field_len != SQL_NO_TOTAL ) {
|
||||||
|
|
||||||
|
CHECK_CUSTOM_ERROR( mem_used + last_field_len > stmt->buffered_query_limit * 1024, stmt,
|
||||||
|
SQLSRV_ERROR_BUFFER_LIMIT_EXCEEDED, stmt->buffered_query_limit ) {
|
||||||
|
|
||||||
|
throw core::CoreException();
|
||||||
|
}
|
||||||
|
|
||||||
|
already_read += to_read - already_read;
|
||||||
|
to_read = last_field_len;
|
||||||
|
buffer.resize( to_read + extra + sizeof( SQLULEN ));
|
||||||
|
output_buffer_len = reinterpret_cast<SQLLEN*>( buffer.get() );
|
||||||
|
// record the size of the field since we have it available
|
||||||
|
*output_buffer_len = last_field_len;
|
||||||
|
full_length_returned = true;
|
||||||
|
}
|
||||||
|
// otherwise allocate another chunk of memory to read in
|
||||||
|
else {
|
||||||
|
already_read += to_read - already_read;
|
||||||
|
to_read *= 2;
|
||||||
|
CHECK_CUSTOM_ERROR( mem_used + to_read > stmt->buffered_query_limit * 1024, stmt,
|
||||||
|
SQLSRV_ERROR_BUFFER_LIMIT_EXCEEDED, stmt->buffered_query_limit ) {
|
||||||
|
|
||||||
|
throw core::CoreException();
|
||||||
|
}
|
||||||
|
buffer.resize( to_read + extra + sizeof( SQLULEN ));
|
||||||
|
output_buffer_len = reinterpret_cast<SQLLEN*>( buffer.get() );
|
||||||
|
}
|
||||||
|
|
||||||
|
} while( true );
|
||||||
|
|
||||||
|
SQLSRV_ASSERT( output_buffer_len != NULL, "Output buffer not allocated properly" );
|
||||||
|
|
||||||
|
// most LOB field types return the total length in the last_field_len, but some field types such as XML
|
||||||
|
// only return the amount read on the last read
|
||||||
|
if( !full_length_returned ) {
|
||||||
|
*output_buffer_len = already_read + last_field_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* return_buffer = buffer;
|
||||||
|
buffer.transferred();
|
||||||
|
return return_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -6,7 +6,7 @@
|
||||||
//
|
//
|
||||||
// Contents: Core routines and constants shared by the Microsoft Drivers for PHP for SQL Server
|
// Contents: Core routines and constants shared by the Microsoft Drivers for PHP for SQL Server
|
||||||
//
|
//
|
||||||
// Copyright 2010 Microsoft Corporation
|
// Copyright Microsoft Corporation
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -45,6 +45,10 @@ OACR_WARNING_DISABLE( INDEX_NEGATIVE, "Third party code." )
|
||||||
OACR_WARNING_DISABLE( UNANNOTATED_BUFFER, "Third party code." )
|
OACR_WARNING_DISABLE( UNANNOTATED_BUFFER, "Third party code." )
|
||||||
OACR_WARNING_DISABLE( INDEX_UNDERFLOW, "Third party code." )
|
OACR_WARNING_DISABLE( INDEX_UNDERFLOW, "Third party code." )
|
||||||
OACR_WARNING_DISABLE( REALLOCLEAK, "Third party code." )
|
OACR_WARNING_DISABLE( REALLOCLEAK, "Third party code." )
|
||||||
|
OACR_WARNING_DISABLE( ALLOC_SIZE_OVERFLOW_WITH_ACCESS, "Third party code." )
|
||||||
|
#else
|
||||||
|
// define to eliminate static analysis hints in the code
|
||||||
|
#define OACR_WARNING_SUPPRESS( warning, msg )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -88,8 +92,6 @@ OACR_WARNING_POP
|
||||||
#include <sql.h>
|
#include <sql.h>
|
||||||
#include <sqlext.h>
|
#include <sqlext.h>
|
||||||
|
|
||||||
#include <deque>
|
|
||||||
|
|
||||||
#if !defined(WC_ERR_INVALID_CHARS)
|
#if !defined(WC_ERR_INVALID_CHARS)
|
||||||
// imported from winnls.h as it isn't included by 5.3.0
|
// imported from winnls.h as it isn't included by 5.3.0
|
||||||
#define WC_ERR_INVALID_CHARS 0x00000080 // error for invalid chars
|
#define WC_ERR_INVALID_CHARS 0x00000080 // error for invalid chars
|
||||||
|
@ -101,8 +103,10 @@ OACR_WARNING_POP
|
||||||
#undef inline
|
#undef inline
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <deque>
|
||||||
|
#include <map>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <limits>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <strsafe.h>
|
#include <strsafe.h>
|
||||||
|
|
||||||
|
@ -216,10 +220,46 @@ struct sqlsrv_static_assert<true> { static const int value = 1; };
|
||||||
#define SQLSRV_STATIC_ASSERT( c ) (sqlsrv_static_assert<(c) != 0>() )
|
#define SQLSRV_STATIC_ASSERT( c ) (sqlsrv_static_assert<(c) != 0>() )
|
||||||
|
|
||||||
|
|
||||||
|
//*********************************************************************************************************************************
|
||||||
|
// Logging
|
||||||
|
//*********************************************************************************************************************************
|
||||||
|
// log_callback
|
||||||
|
// a driver specific callback for logging messages
|
||||||
|
// severity - severity of the message: notice, warning, or error
|
||||||
|
// msg - the message to log in a FormatMessage style formatting
|
||||||
|
// print_args - args to the message
|
||||||
|
typedef void (*log_callback)( unsigned int severity TSRMLS_DC, const char* msg, va_list* print_args );
|
||||||
|
|
||||||
|
// each driver must register a log callback. This should be the first thing a driver does.
|
||||||
|
void core_sqlsrv_register_logger( log_callback );
|
||||||
|
|
||||||
|
// a simple wrapper around a PHP error logging function.
|
||||||
|
void write_to_log( unsigned int severity TSRMLS_DC, const char* msg, ... );
|
||||||
|
|
||||||
|
// a macro to make it convenient to use the function.
|
||||||
|
#define LOG( severity, msg, ...) write_to_log( severity TSRMLS_CC, msg, __VA_ARGS__ )
|
||||||
|
|
||||||
|
// mask for filtering which severities are written to the log
|
||||||
|
enum logging_severity {
|
||||||
|
SEV_ERROR = 0x01,
|
||||||
|
SEV_WARNING = 0x02,
|
||||||
|
SEV_NOTICE = 0x04,
|
||||||
|
SEV_ALL = -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Kill the PHP process and log the message to PHP
|
||||||
|
void die( const char* msg, ... );
|
||||||
|
#define DIE( msg, ... ) { die( msg, __VA_ARGS__ ); }
|
||||||
|
|
||||||
|
|
||||||
//*********************************************************************************************************************************
|
//*********************************************************************************************************************************
|
||||||
// Resource/Memory Management
|
// Resource/Memory Management
|
||||||
//*********************************************************************************************************************************
|
//*********************************************************************************************************************************
|
||||||
|
|
||||||
|
// the macro max is defined and overrides the call to max in the allocator class
|
||||||
|
#pragma push_macro( "max" )
|
||||||
|
#undef max
|
||||||
|
|
||||||
// new memory allocation/free debugging facilities to help us verify that all allocations are being
|
// new memory allocation/free debugging facilities to help us verify that all allocations are being
|
||||||
// released in a timely manner and not just at the end of the script.
|
// released in a timely manner and not just at the end of the script.
|
||||||
// Zend has memory logging and checking, but it can generate a lot of noise for just one extension.
|
// Zend has memory logging and checking, but it can generate a lot of noise for just one extension.
|
||||||
|
@ -229,36 +269,89 @@ struct sqlsrv_static_assert<true> { static const int value = 1; };
|
||||||
// #define SQLSRV_MEM_DEBUG 1
|
// #define SQLSRV_MEM_DEBUG 1
|
||||||
#if defined( PHP_DEBUG ) && !defined( ZTS ) && defined( SQLSRV_MEM_DEBUG )
|
#if defined( PHP_DEBUG ) && !defined( ZTS ) && defined( SQLSRV_MEM_DEBUG )
|
||||||
|
|
||||||
// macro to log memory allocation and frees locations and their sizes
|
inline void* sqlsrv_malloc_trace( size_t size, const char* file, int line )
|
||||||
inline void* emalloc_trace( size_t size, const char* file, int line )
|
|
||||||
{
|
{
|
||||||
void* ptr = emalloc( size );
|
void* ptr = emalloc( size );
|
||||||
LOG( SEV_NOTICE, "emalloc returned %4!08x!: %1!d! bytes at %2!s!:%3!d!", size, file, line, ptr );
|
LOG( SEV_NOTICE, "emalloc returned %4!08x!: %1!d! bytes at %2!s!:%3!d!", size, file, line, ptr );
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void* erealloc_trace( void* original, size_t size, const char* file, int line )
|
inline void* sqlsrv_malloc_trace( size_t element_count, size_t element_size, size_t extra, const char* file, int line )
|
||||||
|
{
|
||||||
|
OACR_WARNING_SUPPRESS( ALLOC_SIZE_OVERFLOW_IN_ALLOC_WRAPPER, "Overflow verified below" );
|
||||||
|
|
||||||
|
if(( element_count > 0 && element_size > 0 ) &&
|
||||||
|
( element_count > element_size * element_count || element_size > element_size * element_count )) {
|
||||||
|
DIE( "Integer overflow in sqlsrv_malloc" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( element_size * element_count > element_size * element_count + extra ) {
|
||||||
|
DIE( "Integer overflow in sqlsrv_malloc" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( element_size * element_count + extra == 0 ) {
|
||||||
|
DIE( "Allocation size must be more than 0" );
|
||||||
|
}
|
||||||
|
|
||||||
|
void* ptr = emalloc( element_size * element_count + extra );
|
||||||
|
LOG( SEV_NOTICE, "emalloc returned %4!08x!: %1!d! bytes at %2!s!:%3!d!", size, file, line, ptr );
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void* sqlsrv_realloc_trace( void* buffer, size_t size, const char* file, int line )
|
||||||
{
|
{
|
||||||
void* ptr = erealloc( original, size );
|
void* ptr = erealloc( original, size );
|
||||||
LOG( SEV_NOTICE, "erealloc returned %5!08x! from %4!08x!: %1!d! bytes at %2!s!:%3!d!", size, file, line, ptr, original );
|
LOG( SEV_NOTICE, "erealloc returned %5!08x! from %4!08x!: %1!d! bytes at %2!s!:%3!d!", size, file, line, ptr, original );
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void efree_trace( void* ptr, const char* file, int line )
|
inline void sqlsrv_free_trace( void* ptr, const char* file, int line )
|
||||||
{
|
{
|
||||||
LOG( SEV_NOTICE, "efree %1!08x! at %2!s!:%3!d!", ptr, file, line );
|
LOG( SEV_NOTICE, "efree %1!08x! at %2!s!:%3!d!", ptr, file, line );
|
||||||
efree( ptr );
|
efree( ptr );
|
||||||
}
|
}
|
||||||
|
|
||||||
#define sqlsrv_malloc( size ) emalloc_trace( size, __FILE__, __LINE__ )
|
#define sqlsrv_malloc( size ) sqlsrv_malloc_trace( size, __FILE__, __LINE__ )
|
||||||
#define sqlsrv_realloc( buffer, size ) erealloc_trace( buffer, size, __FILE__, __LINE__ )
|
#define sqlsrv_malloc( count, size, extra ) sqlsrv_malloc_trace( count, size, extra, __FILE__, __LINE__ )
|
||||||
#define sqlsrv_free( ptr ) efree_trace( ptr, __FILE__, __LINE__ )
|
#define sqlsrv_realloc( buffer, size ) sqlsrv_realloc_trace( buffer, size, __FILE__, __LINE__ )
|
||||||
|
#define sqlsrv_free( ptr ) sqlsrv_free_trace( ptr, __FILE__, __LINE__ )
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define sqlsrv_malloc( size ) emalloc( size )
|
inline void* sqlsrv_malloc( size_t size )
|
||||||
#define sqlsrv_realloc( buffer, size ) erealloc( buffer, size )
|
{
|
||||||
#define sqlsrv_free( ptr ) efree( ptr )
|
return emalloc( size );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void* sqlsrv_malloc( size_t element_count, size_t element_size, size_t extra )
|
||||||
|
{
|
||||||
|
OACR_WARNING_SUPPRESS( ALLOC_SIZE_OVERFLOW_IN_ALLOC_WRAPPER, "Overflow verified below" );
|
||||||
|
|
||||||
|
if(( element_count > 0 && element_size > 0 ) &&
|
||||||
|
( element_count > element_size * element_count || element_size > element_size * element_count )) {
|
||||||
|
DIE( "Integer overflow in sqlsrv_malloc" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( element_size * element_count > element_size * element_count + extra ) {
|
||||||
|
DIE( "Integer overflow in sqlsrv_malloc" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( element_size * element_count + extra == 0 ) {
|
||||||
|
DIE( "Allocation size must be more than 0" );
|
||||||
|
}
|
||||||
|
|
||||||
|
return emalloc( element_size * element_count + extra );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void* sqlsrv_realloc( void* buffer, size_t size )
|
||||||
|
{
|
||||||
|
return erealloc( buffer, size );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void sqlsrv_free( void* ptr )
|
||||||
|
{
|
||||||
|
efree( ptr );
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -273,6 +366,84 @@ struct remove_const<const T*> {
|
||||||
typedef T* type;
|
typedef T* type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// allocator that uses the zend memory manager to manage memory
|
||||||
|
// this allows us to use STL classes that still work with Zend objects
|
||||||
|
template<typename T>
|
||||||
|
struct sqlsrv_allocator {
|
||||||
|
|
||||||
|
// typedefs used by the STL classes
|
||||||
|
typedef T value_type;
|
||||||
|
typedef value_type* pointer;
|
||||||
|
typedef const value_type* const_pointer;
|
||||||
|
typedef value_type& reference;
|
||||||
|
typedef const value_type& const_reference;
|
||||||
|
typedef std::size_t size_type;
|
||||||
|
typedef std::ptrdiff_t difference_type;
|
||||||
|
|
||||||
|
// conversion typedef (used by list and other STL classes)
|
||||||
|
template<typename U>
|
||||||
|
struct rebind {
|
||||||
|
typedef sqlsrv_allocator<U> other;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline sqlsrv_allocator() {}
|
||||||
|
inline ~sqlsrv_allocator() {}
|
||||||
|
inline sqlsrv_allocator( sqlsrv_allocator const& ) {}
|
||||||
|
template<typename U>
|
||||||
|
inline sqlsrv_allocator( sqlsrv_allocator<U> const& ) {}
|
||||||
|
|
||||||
|
// address (doesn't work if the class defines operator&)
|
||||||
|
inline pointer address( reference r )
|
||||||
|
{
|
||||||
|
return &r;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const_pointer address( const_reference r )
|
||||||
|
{
|
||||||
|
return &r;
|
||||||
|
}
|
||||||
|
|
||||||
|
// memory allocation/deallocation
|
||||||
|
inline pointer allocate( size_type cnt,
|
||||||
|
typename std::allocator<void>::const_pointer = 0 )
|
||||||
|
{
|
||||||
|
return reinterpret_cast<pointer>( sqlsrv_malloc(cnt, sizeof (T), 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void deallocate( pointer p, size_type )
|
||||||
|
{
|
||||||
|
sqlsrv_free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
// size
|
||||||
|
inline size_type max_size( void ) const
|
||||||
|
{
|
||||||
|
return std::numeric_limits<size_type>::max() / sizeof(T);
|
||||||
|
}
|
||||||
|
|
||||||
|
// object construction/destruction
|
||||||
|
inline void construct( pointer p, const T& t )
|
||||||
|
{
|
||||||
|
new(p) T(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void destroy(pointer p)
|
||||||
|
{
|
||||||
|
p->~T();
|
||||||
|
}
|
||||||
|
|
||||||
|
// equality operators
|
||||||
|
inline bool operator==( sqlsrv_allocator const& )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator!=( sqlsrv_allocator const& a )
|
||||||
|
{
|
||||||
|
return !operator==(a);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// base class for auto_ptrs that we define below. It provides common operators and functions
|
// base class for auto_ptrs that we define below. It provides common operators and functions
|
||||||
// used by all the classes.
|
// used by all the classes.
|
||||||
|
@ -398,6 +569,8 @@ protected:
|
||||||
// in a variable of sqlsrv_malloc_auto_ptr. sqlsrv_malloc_auto_ptr will "own" that block and assure that it is
|
// in a variable of sqlsrv_malloc_auto_ptr. sqlsrv_malloc_auto_ptr will "own" that block and assure that it is
|
||||||
// freed until the variable is destroyed (out of scope) or ownership is transferred using the function
|
// freed until the variable is destroyed (out of scope) or ownership is transferred using the function
|
||||||
// "transferred".
|
// "transferred".
|
||||||
|
// DO NOT CALL sqlsrv_realloc with a sqlsrv_malloc_auto_ptr. Use the resize member function.
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class sqlsrv_malloc_auto_ptr : public sqlsrv_auto_ptr<T, sqlsrv_malloc_auto_ptr<T> > {
|
class sqlsrv_malloc_auto_ptr : public sqlsrv_auto_ptr<T, sqlsrv_malloc_auto_ptr<T> > {
|
||||||
|
|
||||||
|
@ -432,6 +605,13 @@ public:
|
||||||
src.transferred();
|
src.transferred();
|
||||||
this->_ptr = p;
|
this->_ptr = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DO NOT CALL sqlsrv_realloc with a sqlsrv_malloc_auto_ptr. Use the resize member function.
|
||||||
|
// has the same parameter list as sqlsrv_realloc: new_size is the size in bytes of the newly allocated buffer
|
||||||
|
void resize( size_t new_size )
|
||||||
|
{
|
||||||
|
_ptr = reinterpret_cast<T*>( sqlsrv_realloc( _ptr, new_size ));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -507,6 +687,9 @@ private:
|
||||||
zval_auto_ptr( const zval_auto_ptr& src );
|
zval_auto_ptr( const zval_auto_ptr& src );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#pragma pop_macro( "max" )
|
||||||
|
|
||||||
|
|
||||||
//*********************************************************************************************************************************
|
//*********************************************************************************************************************************
|
||||||
// sqlsrv_error
|
// sqlsrv_error
|
||||||
//*********************************************************************************************************************************
|
//*********************************************************************************************************************************
|
||||||
|
@ -546,6 +729,11 @@ struct sqlsrv_error : public sqlsrv_error_const {
|
||||||
format = printf_format;
|
format = printf_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sqlsrv_error( sqlsrv_error_const const& prototype )
|
||||||
|
{
|
||||||
|
sqlsrv_error( prototype.sqlstate, prototype.native_message, prototype.native_code, prototype.format );
|
||||||
|
}
|
||||||
|
|
||||||
~sqlsrv_error( void )
|
~sqlsrv_error( void )
|
||||||
{
|
{
|
||||||
if( sqlstate != NULL ) {
|
if( sqlstate != NULL ) {
|
||||||
|
@ -816,6 +1004,7 @@ enum SQLSRV_STMT_OPTIONS {
|
||||||
SQLSRV_STMT_OPTION_QUERY_TIMEOUT,
|
SQLSRV_STMT_OPTION_QUERY_TIMEOUT,
|
||||||
SQLSRV_STMT_OPTION_SEND_STREAMS_AT_EXEC,
|
SQLSRV_STMT_OPTION_SEND_STREAMS_AT_EXEC,
|
||||||
SQLSRV_STMT_OPTION_SCROLLABLE,
|
SQLSRV_STMT_OPTION_SCROLLABLE,
|
||||||
|
SQLSRV_STMT_OPTION_CLIENT_BUFFER_MAX_SIZE,
|
||||||
|
|
||||||
// Driver specific connection options
|
// Driver specific connection options
|
||||||
SQLSRV_STMT_OPTION_DRIVER_SPECIFIC = 1000,
|
SQLSRV_STMT_OPTION_DRIVER_SPECIFIC = 1000,
|
||||||
|
@ -825,6 +1014,8 @@ enum SQLSRV_STMT_OPTIONS {
|
||||||
namespace ODBCConnOptions {
|
namespace ODBCConnOptions {
|
||||||
|
|
||||||
const char APP[] = "APP";
|
const char APP[] = "APP";
|
||||||
|
const char ApplicationIntent[] = "ApplicationIntent";
|
||||||
|
const char AttachDBFileName[] = "AttachDbFileName";
|
||||||
const char CharacterSet[] = "CharacterSet";
|
const char CharacterSet[] = "CharacterSet";
|
||||||
const char ConnectionPooling[] = "ConnectionPooling";
|
const char ConnectionPooling[] = "ConnectionPooling";
|
||||||
const char Database[] = "Database";
|
const char Database[] = "Database";
|
||||||
|
@ -832,6 +1023,7 @@ const char Encrypt[] = "Encrypt";
|
||||||
const char Failover_Partner[] = "Failover_Partner";
|
const char Failover_Partner[] = "Failover_Partner";
|
||||||
const char LoginTimeout[] = "LoginTimggeout";
|
const char LoginTimeout[] = "LoginTimggeout";
|
||||||
const char MARS_ODBC[] = "MARS_Connection";
|
const char MARS_ODBC[] = "MARS_Connection";
|
||||||
|
const char MultiSubnetFailover[] = "MultiSubnetFailover";
|
||||||
const char QuotedId[] = "QuotedId";
|
const char QuotedId[] = "QuotedId";
|
||||||
const char TraceFile[] = "TraceFile";
|
const char TraceFile[] = "TraceFile";
|
||||||
const char TraceOn[] = "TraceOn";
|
const char TraceOn[] = "TraceOn";
|
||||||
|
@ -861,6 +1053,9 @@ enum SQLSRV_CONN_OPTIONS {
|
||||||
SQLSRV_CONN_OPTION_TRANS_ISOLATION,
|
SQLSRV_CONN_OPTION_TRANS_ISOLATION,
|
||||||
SQLSRV_CONN_OPTION_TRUST_SERVER_CERT,
|
SQLSRV_CONN_OPTION_TRUST_SERVER_CERT,
|
||||||
SQLSRV_CONN_OPTION_WSID,
|
SQLSRV_CONN_OPTION_WSID,
|
||||||
|
SQLSRV_CONN_OPTION_ATTACHDBFILENAME,
|
||||||
|
SQLSRV_CONN_OPTION_APPLICATION_INTENT,
|
||||||
|
SQLSRV_CONN_OPTION_MULTI_SUBNET_FAILOVER,
|
||||||
|
|
||||||
// Driver specific connection options
|
// Driver specific connection options
|
||||||
SQLSRV_CONN_OPTION_DRIVER_SPECIFIC = 1000,
|
SQLSRV_CONN_OPTION_DRIVER_SPECIFIC = 1000,
|
||||||
|
@ -963,6 +1158,11 @@ struct stmt_option_send_at_exec : public stmt_option_functor {
|
||||||
virtual void operator()( sqlsrv_stmt* stmt, stmt_option const* opt, zval* value_z TSRMLS_DC );
|
virtual void operator()( sqlsrv_stmt* stmt, stmt_option const* opt, zval* value_z TSRMLS_DC );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct stmt_option_buffered_query_limit : public stmt_option_functor {
|
||||||
|
|
||||||
|
virtual void operator()( sqlsrv_stmt* stmt, stmt_option const* opt, zval* value_z TSRMLS_DC );
|
||||||
|
};
|
||||||
|
|
||||||
// used to hold the table for statment options
|
// used to hold the table for statment options
|
||||||
struct stmt_option {
|
struct stmt_option {
|
||||||
|
|
||||||
|
@ -1029,25 +1229,28 @@ struct sqlsrv_output_param {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// forward decls
|
||||||
|
struct sqlsrv_result_set;
|
||||||
|
|
||||||
// *** 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( TSRMLS_D );
|
||||||
virtual void new_result_set( void );
|
virtual void new_result_set( TSRMLS_D );
|
||||||
|
|
||||||
sqlsrv_conn* conn; // Connection that created this statement
|
sqlsrv_conn* conn; // Connection that created this statement
|
||||||
|
|
||||||
bool executed; // Whether the statement has been executed yet (used for error messages)
|
bool executed; // Whether the statement has been executed yet (used for error messages)
|
||||||
bool past_fetch_end; // Core_sqlsrv_fetch sets this field when the statement goes beyond the last row
|
bool past_fetch_end; // Core_sqlsrv_fetch sets this field when the statement goes beyond the last row
|
||||||
bool scrollable; // Determines if the statement was created with the Scrollable query attribute
|
sqlsrv_result_set* current_results; // Current result set
|
||||||
// (don't have to use ODBC to find out)
|
SQLULEN cursor_type; // Type of cursor for the current result set
|
||||||
bool scroll_is_dynamic; // if scrollable, is it a dynamic cursor.
|
|
||||||
bool has_rows; // Has_rows is set if there are actual rows in the row set
|
bool has_rows; // Has_rows is set if there are actual rows in the row set
|
||||||
bool fetch_called; // Used by core_sqlsrv_get_field to return an informative error if fetch not yet called
|
bool fetch_called; // Used by core_sqlsrv_get_field to return an informative error if fetch not yet called
|
||||||
int last_field_index; // last field retrieved by core_sqlsrv_get_field
|
int last_field_index; // last field retrieved by core_sqlsrv_get_field
|
||||||
bool past_next_result_end; // core_sqlsrv_next_result sets this to true when the statement goes beyond the
|
bool past_next_result_end; // core_sqlsrv_next_result sets this to true when the statement goes beyond the
|
||||||
// last results
|
// last results
|
||||||
unsigned long query_timeout; // maximum allowed statement execution time
|
unsigned long query_timeout; // maximum allowed statement execution time
|
||||||
|
unsigned long buffered_query_limit; // maximum allowed memory for a buffered query (measured in KB)
|
||||||
|
|
||||||
// holds output pointers for SQLBindParameter
|
// holds output pointers for SQLBindParameter
|
||||||
// We use a deque because it 1) provides the at/[] access in constant time, and 2) grows dynamically without moving
|
// We use a deque because it 1) provides the at/[] access in constant time, and 2) grows dynamically without moving
|
||||||
|
@ -1101,6 +1304,9 @@ const int SQLSRV_DEFAULT_SIZE = -1; // size given for an output parameter th
|
||||||
// uninitialized query timeout value
|
// uninitialized query timeout value
|
||||||
const unsigned int QUERY_TIMEOUT_INVALID = 0xffffffff;
|
const unsigned int QUERY_TIMEOUT_INVALID = 0xffffffff;
|
||||||
|
|
||||||
|
// special buffered query constant
|
||||||
|
const size_t SQLSRV_CURSOR_BUFFERED = 0xfffffffeUL; // arbitrary number that doesn't map to any other SQL_CURSOR_* constant
|
||||||
|
|
||||||
// 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 TSRMLS_DC );
|
||||||
|
|
||||||
|
@ -1117,42 +1323,181 @@ void core_sqlsrv_get_field( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_
|
||||||
__out void** field_value, __out SQLLEN* field_length, bool cache_field,
|
__out void** field_value, __out SQLLEN* field_length, bool cache_field,
|
||||||
__out SQLSRV_PHPTYPE *sqlsrv_php_type_out TSRMLS_DC );
|
__out SQLSRV_PHPTYPE *sqlsrv_php_type_out TSRMLS_DC );
|
||||||
bool core_sqlsrv_has_any_result( sqlsrv_stmt* stmt TSRMLS_DC );
|
bool core_sqlsrv_has_any_result( sqlsrv_stmt* stmt TSRMLS_DC );
|
||||||
void core_sqlsrv_next_result( sqlsrv_stmt* stmt TSRMLS_DC, bool finalize_output_params = true );
|
void core_sqlsrv_next_result( sqlsrv_stmt* stmt TSRMLS_DC, bool finalize_output_params = true, bool throw_on_errors = true );
|
||||||
void core_sqlsrv_post_param( sqlsrv_stmt* stmt, unsigned int paramno, zval* param_z TSRMLS_DC );
|
void core_sqlsrv_post_param( sqlsrv_stmt* stmt, unsigned int paramno, zval* param_z TSRMLS_DC );
|
||||||
void core_sqlsrv_set_scrollable( sqlsrv_stmt* stmt, unsigned int cursor_type TSRMLS_DC );
|
void core_sqlsrv_set_scrollable( sqlsrv_stmt* stmt, unsigned int cursor_type TSRMLS_DC );
|
||||||
void core_sqlsrv_set_query_timeout( sqlsrv_stmt* stmt, long timeout TSRMLS_DC );
|
void core_sqlsrv_set_query_timeout( sqlsrv_stmt* stmt, long timeout TSRMLS_DC );
|
||||||
void core_sqlsrv_set_query_timeout( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC );
|
void core_sqlsrv_set_query_timeout( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC );
|
||||||
void core_sqlsrv_set_send_at_exec( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC );
|
void core_sqlsrv_set_send_at_exec( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC );
|
||||||
bool core_sqlsrv_send_stream_packet( sqlsrv_stmt* stmt TSRMLS_DC );
|
bool core_sqlsrv_send_stream_packet( sqlsrv_stmt* stmt TSRMLS_DC );
|
||||||
|
void core_sqlsrv_set_buffered_query_limit( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC );
|
||||||
|
void core_sqlsrv_set_buffered_query_limit( sqlsrv_stmt* stmt, long limit TSRMLS_DC );
|
||||||
|
|
||||||
|
|
||||||
//*********************************************************************************************************************************
|
//*********************************************************************************************************************************
|
||||||
// Logging
|
// Result Set
|
||||||
//*********************************************************************************************************************************
|
//*********************************************************************************************************************************
|
||||||
// log_callback
|
|
||||||
// a driver specific callback for logging messages
|
|
||||||
// severity - severity of the message: notice, warning, or error
|
|
||||||
// msg - the message to log in a FormatMessage style formatting
|
|
||||||
// print_args - args to the message
|
|
||||||
typedef void (*log_callback)( unsigned int severity TSRMLS_DC, const char* msg, va_list* print_args );
|
|
||||||
|
|
||||||
// each driver must register a log callback. This should be the first thing a driver does.
|
// Abstract the result set so that a result set can either be used as is from ODBC or buffered.
|
||||||
void core_sqlsrv_register_logger( log_callback );
|
// This is not a complete abstraction of a result set. Only enough is abstracted to allow for
|
||||||
|
// information and capabilities normally not available when a result set is not buffered
|
||||||
|
// (e.g., forward only vs buffered means row count is available and cursor movement is possible).
|
||||||
|
// Otherwise, normal ODBC calls are still valid and should be used to get information about the
|
||||||
|
// result set (e.g., SQLNumResultCols).
|
||||||
|
|
||||||
// a simple wrapper around a PHP error logging function.
|
struct sqlsrv_result_set {
|
||||||
void write_to_log( unsigned int severity TSRMLS_DC, const char* msg, ... );
|
|
||||||
|
|
||||||
// a macro to make it convenient to use the function.
|
sqlsrv_stmt* odbc;
|
||||||
#define LOG( severity, msg, ...) write_to_log( severity TSRMLS_CC, msg, __VA_ARGS__ )
|
|
||||||
|
|
||||||
// mask for filtering which severities are written to the log
|
explicit sqlsrv_result_set( sqlsrv_stmt* );
|
||||||
enum logging_severity {
|
virtual ~sqlsrv_result_set( void ) { }
|
||||||
SEV_ERROR = 0x01,
|
|
||||||
SEV_WARNING = 0x02,
|
virtual bool cached( int field_index ) = 0;
|
||||||
SEV_NOTICE = 0x04,
|
virtual SQLRETURN fetch( SQLSMALLINT fetch_orientation, SQLLEN fetch_offset TSRMLS_DC ) = 0;
|
||||||
SEV_ALL = -1,
|
virtual SQLRETURN get_data( SQLUSMALLINT field_index, SQLSMALLINT target_type,
|
||||||
|
__out void* buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length,
|
||||||
|
bool handle_warning TSRMLS_DC )= 0;
|
||||||
|
virtual SQLRETURN get_diag_field( SQLSMALLINT record_number, SQLSMALLINT diag_identifier,
|
||||||
|
__out SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
|
||||||
|
__out SQLSMALLINT* out_buffer_length TSRMLS_DC ) = 0;
|
||||||
|
virtual sqlsrv_error* get_diag_rec( SQLSMALLINT record_number ) = 0;
|
||||||
|
virtual SQLLEN row_count( TSRMLS_D ) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct sqlsrv_odbc_result_set : public sqlsrv_result_set {
|
||||||
|
|
||||||
|
explicit sqlsrv_odbc_result_set( sqlsrv_stmt* );
|
||||||
|
virtual ~sqlsrv_odbc_result_set( void );
|
||||||
|
|
||||||
|
virtual bool cached( int field_index ) { return false; }
|
||||||
|
virtual SQLRETURN fetch( SQLSMALLINT fetch_orientation, SQLLEN fetch_offset TSRMLS_DC );
|
||||||
|
virtual SQLRETURN get_data( SQLUSMALLINT field_index, SQLSMALLINT target_type,
|
||||||
|
__out void* buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length,
|
||||||
|
bool handle_warning TSRMLS_DC );
|
||||||
|
virtual SQLRETURN get_diag_field( SQLSMALLINT record_number, SQLSMALLINT diag_identifier,
|
||||||
|
__out SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
|
||||||
|
__out SQLSMALLINT* out_buffer_length TSRMLS_DC );
|
||||||
|
virtual sqlsrv_error* get_diag_rec( SQLSMALLINT record_number );
|
||||||
|
virtual SQLLEN row_count( TSRMLS_D );
|
||||||
|
|
||||||
|
private:
|
||||||
|
// prevent invalid instantiations and assignments
|
||||||
|
sqlsrv_odbc_result_set( void );
|
||||||
|
sqlsrv_odbc_result_set( sqlsrv_odbc_result_set& );
|
||||||
|
sqlsrv_odbc_result_set& operator=( sqlsrv_odbc_result_set& );
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sqlsrv_buffered_result_set : public sqlsrv_result_set {
|
||||||
|
|
||||||
|
struct meta_data {
|
||||||
|
SQLSMALLINT type;
|
||||||
|
SQLSMALLINT c_type; // convenience
|
||||||
|
SQLULEN offset; // in bytes
|
||||||
|
SQLULEN length; // in bytes
|
||||||
|
SQLSMALLINT scale;
|
||||||
|
|
||||||
|
static const SQLULEN SIZE_UNKNOWN = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// default maximum amount of memory that a buffered query can consume
|
||||||
|
#define INI_BUFFERED_QUERY_LIMIT_DEFAULT "10240" // default used by the php.ini settings
|
||||||
|
static const unsigned long BUFFERED_QUERY_LIMIT_DEFAULT = 10240; // measured in KB
|
||||||
|
static const long BUFFERED_QUERY_LIMIT_INVALID = 0;
|
||||||
|
|
||||||
|
explicit sqlsrv_buffered_result_set( sqlsrv_stmt* odbc TSRMLS_DC );
|
||||||
|
virtual ~sqlsrv_buffered_result_set( void );
|
||||||
|
|
||||||
|
virtual bool cached( int field_index ) { return true; }
|
||||||
|
virtual SQLRETURN fetch( SQLSMALLINT fetch_orientation, SQLLEN fetch_offset TSRMLS_DC );
|
||||||
|
virtual SQLRETURN get_data( SQLUSMALLINT field_index, SQLSMALLINT target_type,
|
||||||
|
__out void* buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length,
|
||||||
|
bool handle_warning TSRMLS_DC );
|
||||||
|
virtual SQLRETURN get_diag_field( SQLSMALLINT record_number, SQLSMALLINT diag_identifier,
|
||||||
|
__out SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
|
||||||
|
__out SQLSMALLINT* out_buffer_length TSRMLS_DC );
|
||||||
|
virtual sqlsrv_error* get_diag_rec( SQLSMALLINT record_number );
|
||||||
|
virtual SQLLEN row_count( TSRMLS_D );
|
||||||
|
|
||||||
|
// buffered result set specific
|
||||||
|
SQLSMALLINT column_count( void )
|
||||||
|
{
|
||||||
|
return col_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct meta_data& col_meta_data( SQLSMALLINT i )
|
||||||
|
{
|
||||||
|
return meta[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// prevent invalid instantiations and assignments
|
||||||
|
sqlsrv_buffered_result_set( void );
|
||||||
|
sqlsrv_buffered_result_set( sqlsrv_buffered_result_set& );
|
||||||
|
sqlsrv_buffered_result_set& operator=( sqlsrv_buffered_result_set& );
|
||||||
|
|
||||||
|
HashTable* cache; // rows of data kept in index based hash table
|
||||||
|
SQLSMALLINT col_count; // number of columns in the current result set
|
||||||
|
meta_data* meta; // metadata for fields in the cache
|
||||||
|
SQLLEN current; // 1 based, 0 means before first row
|
||||||
|
sqlsrv_error_auto_ptr last_error; // if an error occurred, it is kept here
|
||||||
|
SQLUSMALLINT last_field_index; // the last field data retrieved from
|
||||||
|
SQLLEN read_so_far; // position within string to read from (for partial reads of strings)
|
||||||
|
sqlsrv_malloc_auto_ptr<SQLCHAR> temp_string; // temp buffer to hold a converted field while in use
|
||||||
|
SQLLEN temp_length; // number of bytes in the temp conversion buffer
|
||||||
|
|
||||||
|
typedef SQLRETURN (sqlsrv_buffered_result_set::*conv_fn)( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
typedef std::map< SQLINTEGER, std::map< SQLINTEGER, conv_fn > > conv_matrix_t;
|
||||||
|
|
||||||
|
// two dimentional sparse matrix that holds the [from][to] functions that do conversions
|
||||||
|
static conv_matrix_t conv_matrix;
|
||||||
|
|
||||||
|
// string conversion functions
|
||||||
|
SQLRETURN binary_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
SQLRETURN binary_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
SQLRETURN system_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
SQLRETURN to_binary_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
SQLRETURN to_same_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
SQLRETURN wide_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
|
||||||
|
// long conversion functions
|
||||||
|
SQLRETURN to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length );
|
||||||
|
SQLRETURN long_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
SQLRETURN long_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
SQLRETURN long_to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
|
||||||
|
// double conversion functions
|
||||||
|
SQLRETURN to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length );
|
||||||
|
SQLRETURN double_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
SQLRETURN double_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
SQLRETURN double_to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
|
||||||
|
// string to number conversion functions
|
||||||
|
// Future: See if these can be converted directly to template member functions
|
||||||
|
SQLRETURN string_to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
SQLRETURN string_to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
SQLRETURN wstring_to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
SQLRETURN wstring_to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
|
||||||
|
// utility functions for conversions
|
||||||
|
unsigned char* get_row( void );
|
||||||
|
};
|
||||||
|
|
||||||
//*********************************************************************************************************************************
|
//*********************************************************************************************************************************
|
||||||
// Utility
|
// Utility
|
||||||
|
@ -1205,7 +1550,7 @@ enum SQLSRV_ERROR_CODES {
|
||||||
SQLSRV_ERROR_INVALID_CONNECTION_KEY,
|
SQLSRV_ERROR_INVALID_CONNECTION_KEY,
|
||||||
SQLSRV_ERROR_MAX_PARAMS_EXCEEDED,
|
SQLSRV_ERROR_MAX_PARAMS_EXCEEDED,
|
||||||
SQLSRV_ERROR_INVALID_OPTION_KEY,
|
SQLSRV_ERROR_INVALID_OPTION_KEY,
|
||||||
SQLSRV_ERROR_INVALID_OPTION_VALUE,
|
SQLSRV_ERROR_INVALID_QUERY_TIMEOUT_VALUE,
|
||||||
SQLSRV_ERROR_INVALID_OPTION_SCROLLABLE,
|
SQLSRV_ERROR_INVALID_OPTION_SCROLLABLE,
|
||||||
SQLSRV_ERROR_QUERY_STRING_ENCODING_TRANSLATE,
|
SQLSRV_ERROR_QUERY_STRING_ENCODING_TRANSLATE,
|
||||||
SQLSRV_ERROR_OUTPUT_PARAM_TRUNCATED,
|
SQLSRV_ERROR_OUTPUT_PARAM_TRUNCATED,
|
||||||
|
@ -1215,6 +1560,8 @@ enum SQLSRV_ERROR_CODES {
|
||||||
SQLSRV_ERROR_STREAM_CREATE,
|
SQLSRV_ERROR_STREAM_CREATE,
|
||||||
SQLSRV_ERROR_MARS_OFF,
|
SQLSRV_ERROR_MARS_OFF,
|
||||||
SQLSRV_ERROR_FIELD_INDEX_ERROR,
|
SQLSRV_ERROR_FIELD_INDEX_ERROR,
|
||||||
|
SQLSRV_ERROR_BUFFER_LIMIT_EXCEEDED,
|
||||||
|
SQLSRV_ERROR_INVALID_BUFFER_LIMIT,
|
||||||
|
|
||||||
// Driver specific error codes starts from here.
|
// Driver specific error codes starts from here.
|
||||||
SQLSRV_ERROR_DRIVER_SPECIFIC = 1000,
|
SQLSRV_ERROR_DRIVER_SPECIFIC = 1000,
|
||||||
|
@ -1222,7 +1569,8 @@ enum SQLSRV_ERROR_CODES {
|
||||||
};
|
};
|
||||||
|
|
||||||
// the message returned by SQL Native Client
|
// the message returned by SQL Native Client
|
||||||
const char CONNECTION_BUSY_ODBC_ERROR[] = "[Microsoft][SQL Server Native Client 10.0]Connection is busy with results for another command";
|
const char CONNECTION_BUSY_ODBC_ERROR[] = "[Microsoft][SQL Server Native Client 11.0]Connection is busy with results for "
|
||||||
|
"another command";
|
||||||
|
|
||||||
// SQLSTATE for all internal errors
|
// SQLSTATE for all internal errors
|
||||||
extern SQLCHAR IMSSP[];
|
extern SQLCHAR IMSSP[];
|
||||||
|
@ -1244,11 +1592,12 @@ enum error_handling_flags {
|
||||||
// 2/code) driver specific error code
|
// 2/code) driver specific error code
|
||||||
// 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( sqlsrv_context& ctx, int record_number, sqlsrv_error* error, logging_severity severity TSRMLS_DC );
|
bool core_sqlsrv_get_odbc_error( sqlsrv_context& ctx, int record_number, __out sqlsrv_error_auto_ptr& error,
|
||||||
|
logging_severity severity TSRMLS_DC );
|
||||||
|
|
||||||
// format and return a driver specfic error
|
// format and return a driver specfic error
|
||||||
void core_sqlsrv_format_driver_error( sqlsrv_context& ctx, sqlsrv_error_const const* custom_error,
|
void core_sqlsrv_format_driver_error( sqlsrv_context& ctx, sqlsrv_error_const const* custom_error,
|
||||||
sqlsrv_error* formatted_error, logging_severity severity TSRMLS_DC, va_list* args );
|
sqlsrv_error_auto_ptr& formatted_error, logging_severity severity TSRMLS_DC, 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
|
||||||
|
@ -1278,10 +1627,6 @@ inline bool call_error_handler( sqlsrv_context* ctx, unsigned int sqlsrv_error_c
|
||||||
return ignored;
|
return ignored;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kill the PHP process and log the message to PHP
|
|
||||||
void die( const char* msg, ... );
|
|
||||||
#define DIE( msg, ... ) { die( msg, __VA_ARGS__ ); }
|
|
||||||
|
|
||||||
// PHP equivalent of ASSERT. C asserts cause a dialog to show and halt the process which
|
// PHP equivalent of ASSERT. C asserts cause a dialog to show and halt the process which
|
||||||
// we don't want on a web server
|
// we don't want on a web server
|
||||||
|
|
||||||
|
@ -1300,7 +1645,6 @@ void die( const char* msg, ... );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// check to see if the sqlstate is 01004, truncated field retrieved. Used for retrieving large fields.
|
// check to see if the sqlstate is 01004, truncated field retrieved. Used for retrieving large fields.
|
||||||
inline bool is_truncated_warning( SQLCHAR* state )
|
inline bool is_truncated_warning( SQLCHAR* state )
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
//
|
//
|
||||||
// Contents: Core routines that use statement handles shared between sqlsrv and pdo_sqlsrv
|
// Contents: Core routines that use statement handles shared between sqlsrv and pdo_sqlsrv
|
||||||
//
|
//
|
||||||
// Copyright 2010 Microsoft Corporation
|
// Copyright Microsoft Corporation
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -28,8 +28,10 @@ struct field_cache {
|
||||||
|
|
||||||
void* value;
|
void* value;
|
||||||
SQLLEN len;
|
SQLLEN len;
|
||||||
|
sqlsrv_phptype type;
|
||||||
|
|
||||||
field_cache( void* field_value, SQLLEN field_len )
|
field_cache( void* field_value, SQLLEN field_len, sqlsrv_phptype t )
|
||||||
|
: type( t )
|
||||||
{
|
{
|
||||||
// if the value is NULL, then just record a NULL pointer
|
// if the value is NULL, then just record a NULL pointer
|
||||||
if( field_value != NULL ) {
|
if( field_value != NULL ) {
|
||||||
|
@ -105,7 +107,6 @@ void send_param_streams( sqlsrv_stmt* stmt TSRMLS_DC );
|
||||||
void sqlsrv_output_param_dtor( void* data );
|
void sqlsrv_output_param_dtor( void* data );
|
||||||
// called when a bound stream parameter is to be destroyed.
|
// called when a bound stream parameter is to be destroyed.
|
||||||
void sqlsrv_stream_dtor( void* data );
|
void sqlsrv_stream_dtor( void* data );
|
||||||
sqlsrv_phptype sql_type_to_php_type( sqlsrv_stmt const* stmt, SQLINTEGER sql_type, SQLUINTEGER size, bool prefer_string );
|
|
||||||
bool is_streamable_type( SQLINTEGER sql_type );
|
bool is_streamable_type( SQLINTEGER sql_type );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -116,7 +117,8 @@ sqlsrv_stmt::sqlsrv_stmt( sqlsrv_conn* c, SQLHANDLE handle, error_callback e, vo
|
||||||
conn( c ),
|
conn( c ),
|
||||||
executed( false ),
|
executed( false ),
|
||||||
past_fetch_end( false ),
|
past_fetch_end( false ),
|
||||||
scrollable( false ),
|
current_results( NULL ),
|
||||||
|
cursor_type( SQL_CURSOR_FORWARD_ONLY ),
|
||||||
has_rows( false ),
|
has_rows( false ),
|
||||||
fetch_called( false ),
|
fetch_called( false ),
|
||||||
last_field_index( -1 ),
|
last_field_index( -1 ),
|
||||||
|
@ -126,6 +128,7 @@ sqlsrv_stmt::sqlsrv_stmt( sqlsrv_conn* c, SQLHANDLE handle, error_callback e, vo
|
||||||
current_stream( NULL, SQLSRV_ENCODING_DEFAULT ),
|
current_stream( NULL, SQLSRV_ENCODING_DEFAULT ),
|
||||||
current_stream_read( 0 ),
|
current_stream_read( 0 ),
|
||||||
query_timeout( QUERY_TIMEOUT_INVALID ),
|
query_timeout( QUERY_TIMEOUT_INVALID ),
|
||||||
|
buffered_query_limit( sqlsrv_buffered_result_set::BUFFERED_QUERY_LIMIT_INVALID ),
|
||||||
active_stream( NULL )
|
active_stream( NULL )
|
||||||
{
|
{
|
||||||
// initialize the input string parameters array (which holds zvals)
|
// initialize the input string parameters array (which holds zvals)
|
||||||
|
@ -165,6 +168,14 @@ sqlsrv_stmt::~sqlsrv_stmt( void )
|
||||||
TSRMLS_FETCH();
|
TSRMLS_FETCH();
|
||||||
close_active_stream( this TSRMLS_CC );
|
close_active_stream( this TSRMLS_CC );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// delete any current results
|
||||||
|
if( current_results ) {
|
||||||
|
current_results->~sqlsrv_result_set();
|
||||||
|
efree( current_results );
|
||||||
|
current_results = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
invalidate();
|
invalidate();
|
||||||
zval_ptr_dtor( ¶m_input_strings );
|
zval_ptr_dtor( ¶m_input_strings );
|
||||||
zval_ptr_dtor( &output_params );
|
zval_ptr_dtor( &output_params );
|
||||||
|
@ -192,13 +203,28 @@ 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( void )
|
void sqlsrv_stmt::new_result_set( TSRMLS_D )
|
||||||
{
|
{
|
||||||
this->fetch_called = false;
|
this->fetch_called = false;
|
||||||
this->has_rows = false;
|
this->has_rows = false;
|
||||||
this->past_next_result_end = false;
|
this->past_next_result_end = false;
|
||||||
this->past_fetch_end = false;
|
this->past_fetch_end = false;
|
||||||
this->last_field_index = -1;
|
this->last_field_index = -1;
|
||||||
|
|
||||||
|
// delete any current results
|
||||||
|
if( current_results ) {
|
||||||
|
current_results->~sqlsrv_result_set();
|
||||||
|
efree( current_results );
|
||||||
|
current_results = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a new result set
|
||||||
|
if( cursor_type == SQLSRV_CURSOR_BUFFERED ) {
|
||||||
|
current_results = new (sqlsrv_malloc( sizeof( sqlsrv_buffered_result_set ))) sqlsrv_buffered_result_set( this TSRMLS_CC );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
current_results = new (sqlsrv_malloc( sizeof( sqlsrv_odbc_result_set ))) sqlsrv_odbc_result_set( this );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// core_sqlsrv_create_stmt
|
// core_sqlsrv_create_stmt
|
||||||
|
@ -247,16 +273,15 @@ sqlsrv_stmt* core_sqlsrv_create_stmt( sqlsrv_conn* conn, driver_stmt_factory stm
|
||||||
int type = zend_hash_get_current_key_ex( options_ht, &key, &key_len, &index, 0, NULL );
|
int type = zend_hash_get_current_key_ex( options_ht, &key, &key_len, &index, 0, NULL );
|
||||||
|
|
||||||
// The driver layer should ensure a valid key.
|
// The driver layer should ensure a valid key.
|
||||||
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." );
|
||||||
|
|
||||||
core::sqlsrv_zend_hash_get_current_data( *(stmt->conn), options_ht, (void**) &value_z TSRMLS_CC );
|
core::sqlsrv_zend_hash_get_current_data( *(stmt->conn), options_ht, (void**) &value_z TSRMLS_CC );
|
||||||
|
|
||||||
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 TSRMLS_CC );
|
||||||
|
|
||||||
// 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.
|
||||||
if( !stmt_opt ) {
|
// The driver layer should ensure that the key is valid.
|
||||||
THROW_CORE_ERROR( stmt->conn, SQLSRV_ERROR_INVALID_OPTION_KEY );
|
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 TSRMLS_CC );
|
||||||
|
@ -273,6 +298,8 @@ sqlsrv_stmt* core_sqlsrv_create_stmt( sqlsrv_conn* conn, driver_stmt_factory stm
|
||||||
catch( core::CoreException& )
|
catch( core::CoreException& )
|
||||||
{
|
{
|
||||||
if( stmt ) {
|
if( stmt ) {
|
||||||
|
|
||||||
|
conn->set_last_error( stmt->last_error() );
|
||||||
stmt->~sqlsrv_stmt();
|
stmt->~sqlsrv_stmt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,7 +348,7 @@ void core_sqlsrv_bind_param( sqlsrv_stmt* stmt, unsigned int param_num, int dire
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// check is only < because params are 0 based
|
// check is only < because params are 0 based
|
||||||
CHECK_CUSTOM_ERROR( param_num >= SQL_SERVER_MAX_PARAMS, stmt, SQLSRV_ERROR_MAX_PARAMS_EXCEEDED, param_num ) {
|
CHECK_CUSTOM_ERROR( param_num >= SQL_SERVER_MAX_PARAMS, stmt, SQLSRV_ERROR_MAX_PARAMS_EXCEEDED, param_num + 1 ) {
|
||||||
throw core::CoreException();
|
throw core::CoreException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -498,6 +525,27 @@ void core_sqlsrv_bind_param( sqlsrv_stmt* stmt, unsigned int param_num, int dire
|
||||||
// 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_z, encoding, param_num, buffer_len );
|
sqlsrv_output_param output_param( param_z, encoding, param_num, buffer_len );
|
||||||
save_output_param_for_later( stmt, output_param TSRMLS_CC );
|
save_output_param_for_later( stmt, output_param TSRMLS_CC );
|
||||||
|
|
||||||
|
// For output parameters, if we set the column_size to be same as the buffer_len,
|
||||||
|
// than if there is a truncation due to the data coming from the server being
|
||||||
|
// greater than the column_size, we don't get any truncation error. In order to
|
||||||
|
// avoid this silent truncation, we set the column_size to be "MAX" size for
|
||||||
|
// string types. This will guarantee that there is no silent truncation for
|
||||||
|
// output parameters.
|
||||||
|
if( direction == SQL_PARAM_OUTPUT ) {
|
||||||
|
|
||||||
|
switch( sql_type ) {
|
||||||
|
|
||||||
|
case SQL_VARBINARY:
|
||||||
|
case SQL_VARCHAR:
|
||||||
|
case SQL_WVARCHAR:
|
||||||
|
column_size = SQL_SS_LENGTH_UNLIMITED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IS_RESOURCE:
|
case IS_RESOURCE:
|
||||||
|
@ -516,22 +564,33 @@ void core_sqlsrv_bind_param( sqlsrv_stmt* stmt, unsigned int param_num, int dire
|
||||||
case IS_OBJECT:
|
case IS_OBJECT:
|
||||||
{
|
{
|
||||||
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_malloc_auto_ptr<char> class_name;
|
|
||||||
zend_uint class_name_len;
|
|
||||||
zval_auto_ptr function_z;
|
zval_auto_ptr function_z;
|
||||||
zval_auto_ptr buffer_z;
|
zval_auto_ptr buffer_z;
|
||||||
zval_auto_ptr format_z;
|
zval_auto_ptr format_z;
|
||||||
zval* params[1];
|
zval* params[1];
|
||||||
|
bool valid_class_name_found = false;
|
||||||
|
|
||||||
int zr = zend_get_object_classname( param_z, &class_name, &class_name_len TSRMLS_CC );
|
zend_class_entry *class_entry = zend_get_class_entry( param_z TSRMLS_CC );
|
||||||
CHECK_CUSTOM_ERROR( zr == FAILURE, stmt, SQLSRV_ERROR_INVALID_PARAMETER_PHPTYPE, param_num + 1 ) {
|
|
||||||
throw core::CoreException();
|
while( class_entry != NULL ) {
|
||||||
}
|
|
||||||
CHECK_CUSTOM_ERROR( class_name_len != DateTime::DATETIME_CLASS_NAME_LEN ||
|
if( class_entry->name_length == DateTime::DATETIME_CLASS_NAME_LEN && class_entry->name != NULL &&
|
||||||
stricmp( class_name, DateTime::DATETIME_CLASS_NAME ),
|
stricmp( class_entry->name, DateTime::DATETIME_CLASS_NAME ) == 0 ) {
|
||||||
stmt, SQLSRV_ERROR_INVALID_PARAMETER_PHPTYPE, param_num + 1 ) {
|
valid_class_name_found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
|
||||||
|
// Check the parent
|
||||||
|
class_entry = class_entry->parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK_CUSTOM_ERROR( !valid_class_name_found, stmt, SQLSRV_ERROR_INVALID_PARAMETER_PHPTYPE, param_num + 1 ) {
|
||||||
throw core::CoreException();
|
throw core::CoreException();
|
||||||
}
|
}
|
||||||
|
|
||||||
ALLOC_INIT_ZVAL( buffer_z );
|
ALLOC_INIT_ZVAL( buffer_z );
|
||||||
ALLOC_INIT_ZVAL( function_z );
|
ALLOC_INIT_ZVAL( function_z );
|
||||||
ALLOC_INIT_ZVAL( format_z );
|
ALLOC_INIT_ZVAL( format_z );
|
||||||
|
@ -554,7 +613,7 @@ void core_sqlsrv_bind_param( sqlsrv_stmt* stmt, unsigned int param_num, int dire
|
||||||
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.
|
||||||
zr = call_user_function( EG( function_table ), ¶m_z, function_z, buffer_z, 1, params TSRMLS_CC );
|
int zr = call_user_function( EG( function_table ), ¶m_z, function_z, buffer_z, 1, params TSRMLS_CC );
|
||||||
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 ) {
|
||||||
throw core::CoreException();
|
throw core::CoreException();
|
||||||
}
|
}
|
||||||
|
@ -602,6 +661,8 @@ void core_sqlsrv_bind_param( sqlsrv_stmt* stmt, unsigned int param_num, int dire
|
||||||
|
|
||||||
void core_sqlsrv_execute( sqlsrv_stmt* stmt TSRMLS_DC, const char* sql, int sql_len )
|
void core_sqlsrv_execute( sqlsrv_stmt* stmt TSRMLS_DC, const char* sql, int sql_len )
|
||||||
{
|
{
|
||||||
|
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 TSRMLS_CC );
|
||||||
|
|
||||||
|
@ -632,7 +693,7 @@ void core_sqlsrv_execute( sqlsrv_stmt* stmt TSRMLS_DC, const char* sql, int sql_
|
||||||
r = core::SQLExecute( stmt TSRMLS_CC );
|
r = core::SQLExecute( stmt TSRMLS_CC );
|
||||||
}
|
}
|
||||||
|
|
||||||
stmt->new_result_set();
|
stmt->new_result_set( TSRMLS_C );
|
||||||
stmt->executed = true;
|
stmt->executed = true;
|
||||||
|
|
||||||
// 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
|
||||||
|
@ -646,6 +707,19 @@ void core_sqlsrv_execute( sqlsrv_stmt* stmt TSRMLS_DC, const char* sql, int sql_
|
||||||
|
|
||||||
finalize_output_parameters( stmt TSRMLS_CC );
|
finalize_output_parameters( stmt TSRMLS_CC );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch( core::CoreException& e ) {
|
||||||
|
|
||||||
|
// if the statement executed but failed in a subsequent operation before returning,
|
||||||
|
// we need to cancel the statement
|
||||||
|
if( stmt->executed ) {
|
||||||
|
SQLCancel( stmt->handle() );
|
||||||
|
// stmt->executed = false; should this be reset if something fails?
|
||||||
|
}
|
||||||
|
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -689,20 +763,19 @@ bool core_sqlsrv_fetch( sqlsrv_stmt* stmt, SQLSMALLINT fetch_orientation, SQLLEN
|
||||||
|
|
||||||
// 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.
|
||||||
if( !stmt->scrollable && stmt->has_rows && !stmt->fetch_called ) {
|
if( stmt->cursor_type == SQL_CURSOR_FORWARD_ONLY && stmt->has_rows && !stmt->fetch_called ) {
|
||||||
stmt->fetch_called = true;
|
stmt->fetch_called = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 = core::SQLFetchScroll( stmt, fetch_orientation,
|
SQLRETURN r = stmt->current_results->fetch( fetch_orientation,
|
||||||
( fetch_orientation == SQL_FETCH_RELATIVE ) ? fetch_offset : fetch_offset + 1
|
( fetch_orientation == SQL_FETCH_RELATIVE ) ? fetch_offset : fetch_offset + 1
|
||||||
TSRMLS_CC );
|
TSRMLS_CC );
|
||||||
|
|
||||||
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
|
||||||
if( !stmt->scrollable ) {
|
if( stmt->cursor_type == SQL_CURSOR_FORWARD_ONLY ) {
|
||||||
stmt->past_fetch_end = true;
|
stmt->past_fetch_end = true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -812,13 +885,18 @@ void core_sqlsrv_get_field( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_
|
||||||
if( cached->value == NULL ) {
|
if( cached->value == NULL ) {
|
||||||
*field_value = NULL;
|
*field_value = NULL;
|
||||||
*field_len = 0;
|
*field_len = 0;
|
||||||
|
if( sqlsrv_php_type_out ) { *sqlsrv_php_type_out = SQLSRV_PHPTYPE_NULL; }
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
*field_value = sqlsrv_malloc( cached->len + 1 );
|
*field_value = sqlsrv_malloc( cached->len, sizeof( char ), 1 );
|
||||||
memcpy( *field_value, cached->value, cached->len );
|
memcpy( *field_value, cached->value, cached->len );
|
||||||
reinterpret_cast<char*>( *field_value )[ cached->len ] = '\0'; // prevent the 'string not null terminated' warning
|
if( cached->type.typeinfo.type == SQLSRV_PHPTYPE_STRING ) {
|
||||||
|
// prevent the 'string not null terminated' warning
|
||||||
|
reinterpret_cast<char*>( *field_value )[ cached->len ] = '\0';
|
||||||
|
}
|
||||||
*field_len = cached->len;
|
*field_len = cached->len;
|
||||||
|
if( sqlsrv_php_type_out ) { *sqlsrv_php_type_out = static_cast<SQLSRV_PHPTYPE>( cached->type.typeinfo.type ); }
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -878,7 +956,7 @@ void core_sqlsrv_get_field( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_
|
||||||
|
|
||||||
// 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 );
|
field_cache cache( *field_value, *field_len, sqlsrv_php_type );
|
||||||
core::sqlsrv_zend_hash_index_update( *stmt, Z_ARRVAL_P( stmt->field_cache ), field_index, &cache,
|
core::sqlsrv_zend_hash_index_update( *stmt, Z_ARRVAL_P( stmt->field_cache ), field_index, &cache,
|
||||||
sizeof( field_cache ) TSRMLS_CC );
|
sizeof( field_cache ) TSRMLS_CC );
|
||||||
}
|
}
|
||||||
|
@ -913,7 +991,7 @@ bool core_sqlsrv_has_any_result( sqlsrv_stmt* stmt TSRMLS_DC )
|
||||||
// Returns
|
// Returns
|
||||||
// Nothing, exception thrown if problem occurs
|
// Nothing, exception thrown if problem occurs
|
||||||
|
|
||||||
void core_sqlsrv_next_result( sqlsrv_stmt* stmt TSRMLS_DC, bool finalize_output_params )
|
void core_sqlsrv_next_result( sqlsrv_stmt* stmt TSRMLS_DC, bool finalize_output_params, bool throw_on_errors )
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
@ -928,7 +1006,13 @@ void core_sqlsrv_next_result( sqlsrv_stmt* stmt TSRMLS_DC, bool finalize_output_
|
||||||
|
|
||||||
close_active_stream( stmt TSRMLS_CC );
|
close_active_stream( stmt TSRMLS_CC );
|
||||||
|
|
||||||
SQLRETURN r = core::SQLMoreResults( stmt TSRMLS_CC );
|
SQLRETURN r;
|
||||||
|
if( throw_on_errors ) {
|
||||||
|
r = core::SQLMoreResults( stmt TSRMLS_CC );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
r = SQLMoreResults( stmt->handle() );
|
||||||
|
}
|
||||||
|
|
||||||
if( r == SQL_NO_DATA ) {
|
if( r == SQL_NO_DATA ) {
|
||||||
|
|
||||||
|
@ -942,7 +1026,7 @@ void core_sqlsrv_next_result( sqlsrv_stmt* stmt TSRMLS_DC, bool finalize_output_
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
stmt->new_result_set();
|
stmt->new_result_set( TSRMLS_C );
|
||||||
}
|
}
|
||||||
catch( core::CoreException& e ) {
|
catch( core::CoreException& e ) {
|
||||||
|
|
||||||
|
@ -991,42 +1075,62 @@ void core_sqlsrv_set_scrollable( sqlsrv_stmt* stmt, unsigned int cursor_type TSR
|
||||||
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 TSRMLS_CC );
|
||||||
stmt->scrollable = true;
|
|
||||||
stmt->scroll_is_dynamic = false;
|
|
||||||
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 TSRMLS_CC );
|
||||||
stmt->scrollable = true;
|
|
||||||
stmt->scroll_is_dynamic = true; // this cursor is dynamic
|
|
||||||
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 TSRMLS_CC );
|
||||||
stmt->scrollable = true;
|
|
||||||
stmt->scroll_is_dynamic = false;
|
|
||||||
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 TSRMLS_CC );
|
||||||
stmt->scrollable = false; // reset since forward isn't scrollable
|
break;
|
||||||
stmt->scroll_is_dynamic = false;
|
|
||||||
|
case SQLSRV_CURSOR_BUFFERED:
|
||||||
|
core::SQLSetStmtAttr( stmt, SQL_ATTR_CURSOR_TYPE,
|
||||||
|
reinterpret_cast<SQLPOINTER>( SQL_CURSOR_FORWARD_ONLY ), SQL_IS_UINTEGER TSRMLS_CC );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
THROW_CORE_ERROR( stmt, SQLSRV_ERROR_INVALID_OPTION_SCROLLABLE );
|
THROW_CORE_ERROR( stmt, SQLSRV_ERROR_INVALID_OPTION_SCROLLABLE );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
stmt->cursor_type = cursor_type;
|
||||||
|
|
||||||
|
}
|
||||||
catch( core::CoreException& ) {
|
catch( core::CoreException& ) {
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void core_sqlsrv_set_buffered_query_limit( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC )
|
||||||
|
{
|
||||||
|
if( Z_TYPE_P( value_z ) != IS_LONG ) {
|
||||||
|
|
||||||
|
THROW_CORE_ERROR( stmt, SQLSRV_ERROR_INVALID_BUFFER_LIMIT );
|
||||||
|
}
|
||||||
|
|
||||||
|
core_sqlsrv_set_buffered_query_limit( stmt, Z_LVAL_P( value_z ) TSRMLS_CC );
|
||||||
|
}
|
||||||
|
|
||||||
|
void core_sqlsrv_set_buffered_query_limit( sqlsrv_stmt* stmt, long limit TSRMLS_DC )
|
||||||
|
{
|
||||||
|
if( limit <= 0 ) {
|
||||||
|
|
||||||
|
THROW_CORE_ERROR( stmt, SQLSRV_ERROR_INVALID_BUFFER_LIMIT );
|
||||||
|
}
|
||||||
|
|
||||||
|
stmt->buffered_query_limit = limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Overloaded. Extracts the long value and calls the core_sqlsrv_set_query_timeout
|
// Overloaded. 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.
|
||||||
|
@ -1038,7 +1142,7 @@ void core_sqlsrv_set_query_timeout( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC )
|
||||||
if( Z_TYPE_P( value_z ) != IS_LONG || Z_LVAL_P( value_z ) < 0 ) {
|
if( Z_TYPE_P( value_z ) != IS_LONG || Z_LVAL_P( value_z ) < 0 ) {
|
||||||
|
|
||||||
convert_to_string( value_z );
|
convert_to_string( value_z );
|
||||||
THROW_CORE_ERROR( stmt, SQLSRV_ERROR_INVALID_OPTION_VALUE, Z_STRVAL_P( value_z ) );
|
THROW_CORE_ERROR( stmt, SQLSRV_ERROR_INVALID_QUERY_TIMEOUT_VALUE, Z_STRVAL_P( value_z ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
core_sqlsrv_set_query_timeout( stmt, Z_LVAL_P( value_z ) TSRMLS_CC );
|
core_sqlsrv_set_query_timeout( stmt, Z_LVAL_P( value_z ) TSRMLS_CC );
|
||||||
|
@ -1214,6 +1318,11 @@ void stmt_option_send_at_exec:: operator()( sqlsrv_stmt* stmt, stmt_option const
|
||||||
core_sqlsrv_set_send_at_exec( stmt, value_z TSRMLS_CC );
|
core_sqlsrv_set_send_at_exec( stmt, value_z TSRMLS_CC );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void stmt_option_buffered_query_limit:: operator()( sqlsrv_stmt* stmt, stmt_option const* /*opt*/, zval* value_z TSRMLS_DC )
|
||||||
|
{
|
||||||
|
core_sqlsrv_set_buffered_query_limit( stmt, value_z TSRMLS_CC );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 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.
|
||||||
|
@ -1382,9 +1491,13 @@ void core_get_field_common( __inout sqlsrv_stmt* stmt, SQLUSMALLINT field_index,
|
||||||
sqlsrv_malloc_auto_ptr<long> field_value_temp;
|
sqlsrv_malloc_auto_ptr<long> field_value_temp;
|
||||||
field_value_temp = static_cast<long*>( sqlsrv_malloc( sizeof( long )));
|
field_value_temp = static_cast<long*>( sqlsrv_malloc( sizeof( long )));
|
||||||
|
|
||||||
SQLRETURN r = core::SQLGetData( stmt, field_index + 1, SQL_C_LONG, field_value_temp, 0,
|
SQLRETURN r = stmt->current_results->get_data(field_index + 1, SQL_C_LONG, field_value_temp, sizeof( long ),
|
||||||
field_len, true /*handle_warning*/ TSRMLS_CC );
|
field_len, true /*handle_warning*/ TSRMLS_CC );
|
||||||
|
|
||||||
|
CHECK_SQL_ERROR_OR_WARNING( r, stmt ) {
|
||||||
|
throw core::CoreException();
|
||||||
|
}
|
||||||
|
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
@ -1404,9 +1517,13 @@ void core_get_field_common( __inout sqlsrv_stmt* stmt, SQLUSMALLINT field_index,
|
||||||
sqlsrv_malloc_auto_ptr<double> field_value_temp;
|
sqlsrv_malloc_auto_ptr<double> field_value_temp;
|
||||||
field_value_temp = static_cast<double*>( sqlsrv_malloc( sizeof( double )));
|
field_value_temp = static_cast<double*>( sqlsrv_malloc( sizeof( double )));
|
||||||
|
|
||||||
SQLRETURN r = core::SQLGetData( stmt, field_index + 1, SQL_C_DOUBLE, field_value_temp, 0,
|
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*/ TSRMLS_CC );
|
||||||
|
|
||||||
|
CHECK_SQL_ERROR_OR_WARNING( r, stmt ) {
|
||||||
|
throw core::CoreException();
|
||||||
|
}
|
||||||
|
|
||||||
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 ();
|
||||||
}
|
}
|
||||||
|
@ -1440,8 +1557,8 @@ void core_get_field_common( __inout sqlsrv_stmt* stmt, SQLUSMALLINT field_index,
|
||||||
ALLOC_INIT_ZVAL( function_z );
|
ALLOC_INIT_ZVAL( function_z );
|
||||||
ALLOC_INIT_ZVAL( return_value_z );
|
ALLOC_INIT_ZVAL( return_value_z );
|
||||||
|
|
||||||
SQLRETURN r = core::SQLGetData( stmt, field_index + 1, SQL_C_CHAR, field_value_temp, MAX_DATETIME_STRING_LEN,
|
SQLRETURN r = stmt->current_results->get_data( field_index + 1, SQL_C_CHAR, field_value_temp,
|
||||||
field_len, true TSRMLS_CC );
|
MAX_DATETIME_STRING_LEN, field_len, true TSRMLS_CC );
|
||||||
|
|
||||||
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 ();
|
||||||
|
@ -1512,6 +1629,11 @@ void core_get_field_common( __inout sqlsrv_stmt* stmt, SQLUSMALLINT field_index,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SQLSRV_PHPTYPE_NULL:
|
||||||
|
*field_value = NULL;
|
||||||
|
*field_len = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DIE( "core_get_field_common: Unexpected sqlsrv_phptype provided" );
|
DIE( "core_get_field_common: Unexpected sqlsrv_phptype provided" );
|
||||||
break;
|
break;
|
||||||
|
@ -1951,7 +2073,7 @@ void get_field_as_string( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_ph
|
||||||
|
|
||||||
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 = core::SQLGetData( stmt, 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*/ TSRMLS_CC );
|
||||||
|
|
||||||
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 ) {
|
||||||
|
@ -1969,7 +2091,7 @@ void get_field_as_string( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_ph
|
||||||
SQLCHAR state[ SQL_SQLSTATE_BUFSIZE ];
|
SQLCHAR state[ SQL_SQLSTATE_BUFSIZE ];
|
||||||
SQLSMALLINT len;
|
SQLSMALLINT len;
|
||||||
|
|
||||||
core::SQLGetDiagField( stmt, 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 TSRMLS_CC );
|
||||||
|
|
||||||
if( is_truncated_warning( state ) ) {
|
if( is_truncated_warning( state ) ) {
|
||||||
|
|
||||||
|
@ -1993,8 +2115,9 @@ void get_field_as_string( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_ph
|
||||||
field_len_temp -= initial_field_len;
|
field_len_temp -= initial_field_len;
|
||||||
|
|
||||||
// Get the rest of the data.
|
// Get the rest of the data.
|
||||||
r = core::SQLGetData( stmt, 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*/ TSRMLS_CC );
|
||||||
|
|
||||||
// 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.
|
||||||
|
@ -2019,8 +2142,9 @@ void get_field_as_string( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_ph
|
||||||
field_len_temp -= INITIAL_FIELD_STRING_LEN;
|
field_len_temp -= INITIAL_FIELD_STRING_LEN;
|
||||||
|
|
||||||
// Get the rest of the data.
|
// Get the rest of the data.
|
||||||
r = core::SQLGetData( stmt, field_index + 1, c_type, field_value_temp + INITIAL_FIELD_STRING_LEN,
|
r = stmt->current_results->get_data( field_index + 1, c_type, field_value_temp + INITIAL_FIELD_STRING_LEN,
|
||||||
field_len_temp + extra, &dummy_field_len, true /*handle_warning*/ TSRMLS_CC );
|
field_len_temp + extra, &dummy_field_len,
|
||||||
|
true /*handle_warning*/ TSRMLS_CC );
|
||||||
|
|
||||||
if( dummy_field_len == SQL_NULL_DATA ) {
|
if( dummy_field_len == SQL_NULL_DATA ) {
|
||||||
*field_value = NULL;
|
*field_value = NULL;
|
||||||
|
@ -2072,9 +2196,11 @@ void get_field_as_string( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_ph
|
||||||
field_value_temp = static_cast<char*>( sqlsrv_malloc( sql_display_size + extra + 1 ));
|
field_value_temp = static_cast<char*>( sqlsrv_malloc( sql_display_size + extra + 1 ));
|
||||||
|
|
||||||
// get the data
|
// get the data
|
||||||
r = core::SQLGetData( stmt, 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*/ TSRMLS_CC );
|
||||||
|
CHECK_SQL_ERROR( r, stmt ) {
|
||||||
|
throw core::CoreException();
|
||||||
|
}
|
||||||
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 ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
//
|
//
|
||||||
// Contents: Implementation of PHP streams for reading SQL Server data
|
// Contents: Implementation of PHP streams for reading SQL Server data
|
||||||
//
|
//
|
||||||
// Copyright 2010 Microsoft Corporation
|
// Copyright Microsoft Corporation
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -113,7 +113,8 @@ size_t sqlsrv_stream_read( php_stream* stream, __out_bcount(count) char* buf, si
|
||||||
|
|
||||||
SQLCHAR state[ SQL_SQLSTATE_BUFSIZE ];
|
SQLCHAR state[ SQL_SQLSTATE_BUFSIZE ];
|
||||||
SQLSMALLINT len;
|
SQLSMALLINT len;
|
||||||
core::SQLGetDiagField( ss->stmt, 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 TSRMLS_CC );
|
||||||
|
|
||||||
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 "
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
//
|
//
|
||||||
// Comments: Mostly error handling and some type handling
|
// Comments: Mostly error handling and some type handling
|
||||||
//
|
//
|
||||||
// Copyright 2010 Microsoft Corporation
|
// Copyright Microsoft Corporation
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -147,7 +147,8 @@ wchar_t* utf16_string_from_mbcs_string( SQLSRV_ENCODING php_encoding, const char
|
||||||
// 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( sqlsrv_context& ctx, int record_number, sqlsrv_error* error, logging_severity severity TSRMLS_DC )
|
bool core_sqlsrv_get_odbc_error( sqlsrv_context& ctx, int record_number, sqlsrv_error_auto_ptr& error, 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();
|
||||||
|
@ -165,7 +166,33 @@ bool core_sqlsrv_get_odbc_error( sqlsrv_context& ctx, int record_number, sqlsrv_
|
||||||
SQLINTEGER message_len = 0;
|
SQLINTEGER message_len = 0;
|
||||||
SQLWCHAR wsqlstate[ SQL_SQLSTATE_BUFSIZE ];
|
SQLWCHAR wsqlstate[ SQL_SQLSTATE_BUFSIZE ];
|
||||||
SQLWCHAR wnative_message[ SQL_MAX_MESSAGE_LENGTH + 1 ];
|
SQLWCHAR wnative_message[ SQL_MAX_MESSAGE_LENGTH + 1 ];
|
||||||
|
SQLSRV_ENCODING enc = ctx.encoding();
|
||||||
|
|
||||||
|
switch( h_type ) {
|
||||||
|
|
||||||
|
case SQL_HANDLE_STMT:
|
||||||
|
{
|
||||||
|
sqlsrv_stmt* stmt = static_cast<sqlsrv_stmt*>( &ctx );
|
||||||
|
if( stmt->current_results != NULL ) {
|
||||||
|
|
||||||
|
error = stmt->current_results->get_diag_rec( record_number );
|
||||||
|
// don't use the CHECK* macros here since it will trigger reentry into the error handling system
|
||||||
|
if( error == NULL ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert the error into the encoding of the context
|
||||||
|
if( enc == SQLSRV_ENCODING_DEFAULT ) {
|
||||||
|
enc = stmt->conn->encoding();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
error = new ( sqlsrv_malloc( sizeof( sqlsrv_error ))) sqlsrv_error();
|
||||||
r = SQLGetDiagRecW( h_type, h, record_number, wsqlstate, &error->native_code, wnative_message,
|
r = SQLGetDiagRecW( h_type, h, record_number, wsqlstate, &error->native_code, wnative_message,
|
||||||
SQL_MAX_MESSAGE_LENGTH + 1, &wmessage_len );
|
SQL_MAX_MESSAGE_LENGTH + 1, &wmessage_len );
|
||||||
// don't use the CHECK* macros here since it will trigger reentry into the error handling system
|
// don't use the CHECK* macros here since it will trigger reentry into the error handling system
|
||||||
|
@ -173,14 +200,16 @@ bool core_sqlsrv_get_odbc_error( sqlsrv_context& ctx, int record_number, sqlsrv_
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert the error into the encoding of the context
|
|
||||||
error->sqlstate = reinterpret_cast<SQLCHAR*>( wsqlstate );
|
error->sqlstate = reinterpret_cast<SQLCHAR*>( wsqlstate );
|
||||||
convert_string_from_utf16( ctx.encoding(), reinterpret_cast<char**>( &error->sqlstate ), sqlstate_len,
|
convert_string_from_utf16( enc, reinterpret_cast<char**>( &error->sqlstate ), sqlstate_len,
|
||||||
false /*no free*/ );
|
false /*no free*/ );
|
||||||
error->native_message = reinterpret_cast<SQLCHAR*>( wnative_message );
|
error->native_message = reinterpret_cast<SQLCHAR*>( wnative_message );
|
||||||
message_len = wmessage_len * sizeof( wchar_t );
|
message_len = wmessage_len * sizeof( wchar_t );
|
||||||
convert_string_from_utf16( ctx.encoding(), reinterpret_cast<char**>( &error->native_message ), message_len,
|
convert_string_from_utf16( enc, reinterpret_cast<char**>( &error->native_message ), message_len,
|
||||||
false /*no free*/ );
|
false /*no free*/ );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// log the error first
|
// log the error first
|
||||||
LOG( severity, "%1!s!: SQLSTATE = %2!s!", ctx.func(), error->sqlstate );
|
LOG( severity, "%1!s!: SQLSTATE = %2!s!", ctx.func(), error->sqlstate );
|
||||||
|
@ -194,9 +223,10 @@ bool core_sqlsrv_get_odbc_error( sqlsrv_context& ctx, int record_number, sqlsrv_
|
||||||
|
|
||||||
// format and return a driver specfic error
|
// format and return a driver specfic error
|
||||||
void core_sqlsrv_format_driver_error( sqlsrv_context& ctx, sqlsrv_error_const const* custom_error,
|
void core_sqlsrv_format_driver_error( sqlsrv_context& ctx, sqlsrv_error_const const* custom_error,
|
||||||
sqlsrv_error* formatted_error, logging_severity severity TSRMLS_DC, va_list* args )
|
sqlsrv_error_auto_ptr& formatted_error, logging_severity severity TSRMLS_DC, 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->sqlstate = reinterpret_cast<SQLCHAR*>( sqlsrv_malloc( SQL_SQLSTATE_BUFSIZE ));
|
formatted_error->sqlstate = reinterpret_cast<SQLCHAR*>( sqlsrv_malloc( SQL_SQLSTATE_BUFSIZE ));
|
||||||
formatted_error->native_message = reinterpret_cast<SQLCHAR*>( sqlsrv_malloc( SQL_MAX_MESSAGE_LENGTH + 1 ));
|
formatted_error->native_message = reinterpret_cast<SQLCHAR*>( sqlsrv_malloc( SQL_MAX_MESSAGE_LENGTH + 1 ));
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
//
|
//
|
||||||
// Contents: Implements the PDO object for PDO_SQLSRV
|
// Contents: Implements the PDO object for PDO_SQLSRV
|
||||||
//
|
//
|
||||||
// Copyright 2010 Microsoft Corporation
|
// Copyright Microsoft Corporation
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -52,12 +52,15 @@ namespace PDOConnOptionNames {
|
||||||
|
|
||||||
const char Server[] = "Server";
|
const char Server[] = "Server";
|
||||||
const char APP[] = "APP";
|
const char APP[] = "APP";
|
||||||
|
const char ApplicationIntent[] = "ApplicationIntent";
|
||||||
|
const char AttachDBFileName[] = "AttachDbFileName";
|
||||||
const char ConnectionPooling[] = "ConnectionPooling";
|
const char ConnectionPooling[] = "ConnectionPooling";
|
||||||
const char Database[] = "Database";
|
const char Database[] = "Database";
|
||||||
const char Encrypt[] = "Encrypt";
|
const char Encrypt[] = "Encrypt";
|
||||||
const char Failover_Partner[] = "Failover_Partner";
|
const char Failover_Partner[] = "Failover_Partner";
|
||||||
const char LoginTimeout[] = "LoginTimeout";
|
const char LoginTimeout[] = "LoginTimeout";
|
||||||
const char MARS_Option[] = "MultipleActiveResultSets";
|
const char MARS_Option[] = "MultipleActiveResultSets";
|
||||||
|
const char MultiSubnetFailover[] = "MultiSubnetFailover";
|
||||||
const char QuotedId[] = "QuotedId";
|
const char QuotedId[] = "QuotedId";
|
||||||
const char TraceFile[] = "TraceFile";
|
const char TraceFile[] = "TraceFile";
|
||||||
const char TraceOn[] = "TraceOn";
|
const char TraceOn[] = "TraceOn";
|
||||||
|
@ -77,6 +80,9 @@ enum PDO_STMT_OPTIONS {
|
||||||
|
|
||||||
PDO_STMT_OPTION_ENCODING = SQLSRV_STMT_OPTION_DRIVER_SPECIFIC,
|
PDO_STMT_OPTION_ENCODING = SQLSRV_STMT_OPTION_DRIVER_SPECIFIC,
|
||||||
PDO_STMT_OPTION_DIRECT_QUERY,
|
PDO_STMT_OPTION_DIRECT_QUERY,
|
||||||
|
PDO_STMT_OPTION_CURSOR_SCROLL_TYPE,
|
||||||
|
PDO_STMT_OPTION_CLIENT_BUFFER_MAX_KB_SIZE,
|
||||||
|
PDO_STMT_OPTION_EMULATE_PREPARES,
|
||||||
};
|
};
|
||||||
|
|
||||||
// List of all the statement options supported by this driver.
|
// List of all the statement options supported by this driver.
|
||||||
|
@ -86,6 +92,9 @@ const stmt_option PDO_STMT_OPTS[] = {
|
||||||
{ NULL, 0, SQLSRV_STMT_OPTION_SCROLLABLE, new stmt_option_scrollable },
|
{ NULL, 0, SQLSRV_STMT_OPTION_SCROLLABLE, new stmt_option_scrollable },
|
||||||
{ NULL, 0, PDO_STMT_OPTION_ENCODING, new stmt_option_encoding },
|
{ NULL, 0, PDO_STMT_OPTION_ENCODING, new stmt_option_encoding },
|
||||||
{ NULL, 0, PDO_STMT_OPTION_DIRECT_QUERY, new stmt_option_direct_query },
|
{ NULL, 0, PDO_STMT_OPTION_DIRECT_QUERY, new stmt_option_direct_query },
|
||||||
|
{ NULL, 0, PDO_STMT_OPTION_CURSOR_SCROLL_TYPE, new stmt_option_cursor_scroll_type },
|
||||||
|
{ NULL, 0, PDO_STMT_OPTION_CLIENT_BUFFER_MAX_KB_SIZE, new stmt_option_buffered_query_limit },
|
||||||
|
{ NULL, 0, PDO_STMT_OPTION_EMULATE_PREPARES, new stmt_option_emulate_prepares },
|
||||||
|
|
||||||
{ NULL, 0, SQLSRV_STMT_OPTION_INVALID, NULL},
|
{ NULL, 0, SQLSRV_STMT_OPTION_INVALID, NULL},
|
||||||
};
|
};
|
||||||
|
@ -163,6 +172,24 @@ const connection_option PDO_CONN_OPTS[] = {
|
||||||
CONN_ATTR_STRING,
|
CONN_ATTR_STRING,
|
||||||
conn_str_append_func::func
|
conn_str_append_func::func
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
PDOConnOptionNames::ApplicationIntent,
|
||||||
|
sizeof( PDOConnOptionNames::ApplicationIntent ),
|
||||||
|
SQLSRV_CONN_OPTION_APPLICATION_INTENT,
|
||||||
|
ODBCConnOptions::ApplicationIntent,
|
||||||
|
sizeof( ODBCConnOptions::ApplicationIntent ),
|
||||||
|
CONN_ATTR_STRING,
|
||||||
|
conn_str_append_func::func
|
||||||
|
},
|
||||||
|
{
|
||||||
|
PDOConnOptionNames::AttachDBFileName,
|
||||||
|
sizeof( PDOConnOptionNames::AttachDBFileName ),
|
||||||
|
SQLSRV_CONN_OPTION_ATTACHDBFILENAME,
|
||||||
|
ODBCConnOptions::AttachDBFileName,
|
||||||
|
sizeof( ODBCConnOptions::AttachDBFileName ),
|
||||||
|
CONN_ATTR_STRING,
|
||||||
|
conn_str_append_func::func
|
||||||
|
},
|
||||||
{
|
{
|
||||||
PDOConnOptionNames::ConnectionPooling,
|
PDOConnOptionNames::ConnectionPooling,
|
||||||
sizeof( PDOConnOptionNames::ConnectionPooling ),
|
sizeof( PDOConnOptionNames::ConnectionPooling ),
|
||||||
|
@ -217,6 +244,15 @@ const connection_option PDO_CONN_OPTS[] = {
|
||||||
CONN_ATTR_BOOL,
|
CONN_ATTR_BOOL,
|
||||||
pdo_bool_conn_str_func::func
|
pdo_bool_conn_str_func::func
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
PDOConnOptionNames::MultiSubnetFailover,
|
||||||
|
sizeof( PDOConnOptionNames::MultiSubnetFailover ),
|
||||||
|
SQLSRV_CONN_OPTION_MULTI_SUBNET_FAILOVER,
|
||||||
|
ODBCConnOptions::MultiSubnetFailover,
|
||||||
|
sizeof( ODBCConnOptions::MultiSubnetFailover ),
|
||||||
|
CONN_ATTR_BOOL,
|
||||||
|
pdo_bool_conn_str_func::func
|
||||||
|
},
|
||||||
{
|
{
|
||||||
PDOConnOptionNames::QuotedId,
|
PDOConnOptionNames::QuotedId,
|
||||||
sizeof( PDOConnOptionNames::QuotedId ),
|
sizeof( PDOConnOptionNames::QuotedId ),
|
||||||
|
@ -333,6 +369,20 @@ struct pdo_dbh_methods pdo_sqlsrv_dbh_methods = {
|
||||||
LOG( SEV_NOTICE, __FUNCTION__ ## ": entering" ); \
|
LOG( SEV_NOTICE, __FUNCTION__ ## ": entering" ); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// constructor for the internal object for connections
|
||||||
|
pdo_sqlsrv_dbh::pdo_sqlsrv_dbh( SQLHANDLE h, error_callback e, void* driver TSRMLS_DC ) :
|
||||||
|
sqlsrv_conn( h, e, driver, SQLSRV_ENCODING_UTF8 TSRMLS_CC ),
|
||||||
|
stmts( NULL ),
|
||||||
|
direct_query( false ),
|
||||||
|
query_timeout( QUERY_TIMEOUT_INVALID ),
|
||||||
|
client_buffer_max_size( PDO_SQLSRV_G( client_buffer_max_size ) )
|
||||||
|
{
|
||||||
|
if( client_buffer_max_size < 0 ) {
|
||||||
|
client_buffer_max_size = sqlsrv_buffered_result_set::BUFFERED_QUERY_LIMIT_DEFAULT;
|
||||||
|
LOG( SEV_WARNING, INI_PDO_SQLSRV_CLIENT_BUFFER_MAX_SIZE " set to a invalid value. Resetting to default value." );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// pdo_sqlsrv_db_handle_factory
|
// pdo_sqlsrv_db_handle_factory
|
||||||
// Maps to PDO::__construct.
|
// Maps to PDO::__construct.
|
||||||
// Factory method called by the PDO driver manager to create a SQLSRV PDO connection.
|
// Factory method called by the PDO driver manager to create a SQLSRV PDO connection.
|
||||||
|
@ -481,29 +531,16 @@ int pdo_sqlsrv_dbh_prepare( pdo_dbh_t *dbh, const char *sql,
|
||||||
int sql_rewrite_len = 0;
|
int sql_rewrite_len = 0;
|
||||||
sqlsrv_malloc_auto_ptr<pdo_sqlsrv_stmt> driver_stmt;
|
sqlsrv_malloc_auto_ptr<pdo_sqlsrv_stmt> driver_stmt;
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
pdo_sqlsrv_dbh* driver_dbh = reinterpret_cast<pdo_sqlsrv_dbh*>( dbh->driver_data );
|
pdo_sqlsrv_dbh* driver_dbh = reinterpret_cast<pdo_sqlsrv_dbh*>( dbh->driver_data );
|
||||||
SQLSRV_ASSERT(( driver_dbh != NULL ), "pdo_sqlsrv_dbh_prepare: dbh->driver_data was null");
|
SQLSRV_ASSERT(( driver_dbh != NULL ), "pdo_sqlsrv_dbh_prepare: dbh->driver_data was null");
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
// assign the methods for the statement object. This is necessary even if the
|
// assign the methods for the statement object. This is necessary even if the
|
||||||
// statement fails so the user can retrieve the error information.
|
// statement fails so the user can retrieve the error information.
|
||||||
stmt->methods = &pdo_sqlsrv_stmt_methods;
|
stmt->methods = &pdo_sqlsrv_stmt_methods;
|
||||||
stmt->supports_placeholders = PDO_PLACEHOLDER_POSITIONAL; // we support parameterized queries with ?, not names
|
stmt->supports_placeholders = PDO_PLACEHOLDER_POSITIONAL; // we support parameterized queries with ?, not names
|
||||||
|
|
||||||
// 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.
|
|
||||||
int zr = pdo_subst_params_named_to_positional( stmt, const_cast<char*>( sql ), sql_len,
|
|
||||||
&sql_rewrite, &sql_rewrite_len TSRMLS_CC );
|
|
||||||
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 != NULL ) {
|
|
||||||
sql = sql_rewrite;
|
|
||||||
sql_len = sql_rewrite_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 */, NULL /*hashfn*/,
|
core::sqlsrv_zend_hash_init( *driver_dbh , pdo_stmt_options_ht, 3 /* # of buckets */, NULL /*hashfn*/,
|
||||||
|
@ -516,6 +553,13 @@ int pdo_sqlsrv_dbh_prepare( pdo_dbh_t *dbh, const char *sql,
|
||||||
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 TSRMLS_CC ));
|
||||||
|
|
||||||
|
// if the user didn't set anything in the prepare options, then set the buffer limit
|
||||||
|
// to the value set on the connection.
|
||||||
|
if( driver_stmt->buffered_query_limit== sqlsrv_buffered_result_set::BUFFERED_QUERY_LIMIT_INVALID ) {
|
||||||
|
|
||||||
|
driver_stmt->buffered_query_limit = driver_dbh->client_buffer_max_size;
|
||||||
|
}
|
||||||
|
|
||||||
// if the user didn't set anything in the prepare options, then set the query timeout
|
// if the user didn't set anything in the prepare options, then set the query timeout
|
||||||
// to the value set on the connection.
|
// to the value set on the connection.
|
||||||
if(( driver_stmt->query_timeout == QUERY_TIMEOUT_INVALID ) && ( driver_dbh->query_timeout != QUERY_TIMEOUT_INVALID )) {
|
if(( driver_stmt->query_timeout == QUERY_TIMEOUT_INVALID ) && ( driver_dbh->query_timeout != QUERY_TIMEOUT_INVALID )) {
|
||||||
|
@ -523,12 +567,24 @@ int pdo_sqlsrv_dbh_prepare( pdo_dbh_t *dbh, const char *sql,
|
||||||
core_sqlsrv_set_query_timeout( driver_stmt, driver_dbh->query_timeout TSRMLS_CC );
|
core_sqlsrv_set_query_timeout( driver_stmt, driver_dbh->query_timeout TSRMLS_CC );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( driver_stmt->direct_query ) {
|
// 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 ) {
|
||||||
|
|
||||||
driver_stmt->query = estrndup( sql, sql_len );
|
// rewrite the query to map named parameters to positional parameters. We do this rather than use the ODBC named
|
||||||
driver_stmt->query_len = sql_len;
|
// parameters for consistency with the PDO MySQL and PDO ODBC drivers.
|
||||||
|
int zr = pdo_subst_named_params( stmt, const_cast<char*>( sql ), sql_len, &sql_rewrite, &sql_rewrite_len TSRMLS_CC );
|
||||||
|
CHECK_ZEND_ERROR( zr, driver_dbh, PDO_SQLSRV_ERROR_PARAM_PARSE ) {
|
||||||
|
throw core::CoreException();
|
||||||
}
|
}
|
||||||
else {
|
// if parameter substitution happened, use that query instead of the original
|
||||||
|
if( sql_rewrite != NULL ) {
|
||||||
|
sql = sql_rewrite;
|
||||||
|
sql_len = sql_rewrite_len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 TSRMLS_CC );
|
||||||
}
|
}
|
||||||
|
@ -545,6 +601,14 @@ int pdo_sqlsrv_dbh_prepare( pdo_dbh_t *dbh, const char *sql,
|
||||||
driver_stmt->~pdo_sqlsrv_stmt();
|
driver_stmt->~pdo_sqlsrv_stmt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// in the event that the statement caused an error that was copied to the connection, update the
|
||||||
|
// connection with the error's SQLSTATE.
|
||||||
|
if( driver_dbh->last_error() ) {
|
||||||
|
|
||||||
|
strcpy_s( dbh->error_code, sizeof( dbh->error_code ),
|
||||||
|
reinterpret_cast<const char*>( driver_dbh->last_error()->sqlstate ));
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -819,17 +883,24 @@ int pdo_sqlsrv_dbh_set_attr( pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC )
|
||||||
case SQLSRV_ATTR_QUERY_TIMEOUT:
|
case SQLSRV_ATTR_QUERY_TIMEOUT:
|
||||||
if( Z_TYPE_P( val ) != IS_LONG || Z_LVAL_P( val ) < 0 ) {
|
if( Z_TYPE_P( val ) != IS_LONG || Z_LVAL_P( val ) < 0 ) {
|
||||||
convert_to_string( val );
|
convert_to_string( val );
|
||||||
THROW_PDO_ERROR( driver_dbh, SQLSRV_ERROR_INVALID_OPTION_VALUE, Z_STRVAL_P( val ));
|
THROW_PDO_ERROR( driver_dbh, SQLSRV_ERROR_INVALID_QUERY_TIMEOUT_VALUE, Z_STRVAL_P( val ));
|
||||||
}
|
}
|
||||||
driver_dbh->query_timeout = Z_LVAL_P( val );
|
driver_dbh->query_timeout = Z_LVAL_P( val );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SQLSRV_ATTR_CLIENT_BUFFER_MAX_KB_SIZE:
|
||||||
|
if( Z_TYPE_P( val ) != IS_LONG || Z_LVAL_P( val ) <= 0 ) {
|
||||||
|
convert_to_string( val );
|
||||||
|
THROW_PDO_ERROR( driver_dbh, SQLSRV_ERROR_INVALID_BUFFER_LIMIT, Z_STRVAL_P( val ));
|
||||||
|
}
|
||||||
|
driver_dbh->client_buffer_max_size = Z_LVAL_P( val );
|
||||||
|
break;
|
||||||
|
|
||||||
// Not supported
|
// Not supported
|
||||||
case PDO_ATTR_FETCH_TABLE_NAMES:
|
case PDO_ATTR_FETCH_TABLE_NAMES:
|
||||||
case PDO_ATTR_FETCH_CATALOG_NAMES:
|
case PDO_ATTR_FETCH_CATALOG_NAMES:
|
||||||
case PDO_ATTR_PREFETCH:
|
case PDO_ATTR_PREFETCH:
|
||||||
case PDO_ATTR_MAX_COLUMN_LEN:
|
case PDO_ATTR_MAX_COLUMN_LEN:
|
||||||
case PDO_ATTR_EMULATE_PREPARES:
|
|
||||||
case PDO_ATTR_CURSOR_NAME:
|
case PDO_ATTR_CURSOR_NAME:
|
||||||
case PDO_ATTR_AUTOCOMMIT:
|
case PDO_ATTR_AUTOCOMMIT:
|
||||||
case PDO_ATTR_PERSISTENT:
|
case PDO_ATTR_PERSISTENT:
|
||||||
|
@ -849,7 +920,9 @@ int pdo_sqlsrv_dbh_set_attr( pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC )
|
||||||
}
|
}
|
||||||
|
|
||||||
// Statement level only
|
// Statement level only
|
||||||
|
case PDO_ATTR_EMULATE_PREPARES:
|
||||||
case PDO_ATTR_CURSOR:
|
case PDO_ATTR_CURSOR:
|
||||||
|
case SQLSRV_ATTR_CURSOR_SCROLL_TYPE:
|
||||||
{
|
{
|
||||||
THROW_PDO_ERROR( driver_dbh, PDO_SQLSRV_ERROR_STMT_LEVEL_ATTR );
|
THROW_PDO_ERROR( driver_dbh, PDO_SQLSRV_ERROR_STMT_LEVEL_ATTR );
|
||||||
}
|
}
|
||||||
|
@ -895,7 +968,6 @@ int pdo_sqlsrv_dbh_get_attr( pdo_dbh_t *dbh, long attr, zval *return_value TSRML
|
||||||
case PDO_ATTR_FETCH_CATALOG_NAMES:
|
case PDO_ATTR_FETCH_CATALOG_NAMES:
|
||||||
case PDO_ATTR_PREFETCH:
|
case PDO_ATTR_PREFETCH:
|
||||||
case PDO_ATTR_MAX_COLUMN_LEN:
|
case PDO_ATTR_MAX_COLUMN_LEN:
|
||||||
case PDO_ATTR_EMULATE_PREPARES:
|
|
||||||
case PDO_ATTR_CURSOR_NAME:
|
case PDO_ATTR_CURSOR_NAME:
|
||||||
case PDO_ATTR_AUTOCOMMIT:
|
case PDO_ATTR_AUTOCOMMIT:
|
||||||
case PDO_ATTR_TIMEOUT:
|
case PDO_ATTR_TIMEOUT:
|
||||||
|
@ -905,7 +977,9 @@ int pdo_sqlsrv_dbh_get_attr( pdo_dbh_t *dbh, long attr, zval *return_value TSRML
|
||||||
}
|
}
|
||||||
|
|
||||||
// Statement level only
|
// Statement level only
|
||||||
|
case PDO_ATTR_EMULATE_PREPARES:
|
||||||
case PDO_ATTR_CURSOR:
|
case PDO_ATTR_CURSOR:
|
||||||
|
case SQLSRV_ATTR_CURSOR_SCROLL_TYPE:
|
||||||
{
|
{
|
||||||
THROW_PDO_ERROR( driver_dbh, PDO_SQLSRV_ERROR_STMT_LEVEL_ATTR );
|
THROW_PDO_ERROR( driver_dbh, PDO_SQLSRV_ERROR_STMT_LEVEL_ATTR );
|
||||||
}
|
}
|
||||||
|
@ -957,6 +1031,12 @@ int pdo_sqlsrv_dbh_get_attr( pdo_dbh_t *dbh, long attr, zval *return_value TSRML
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SQLSRV_ATTR_CLIENT_BUFFER_MAX_KB_SIZE:
|
||||||
|
{
|
||||||
|
ZVAL_LONG( return_value, driver_dbh->client_buffer_max_size );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
THROW_PDO_ERROR( driver_dbh, PDO_SQLSRV_ERROR_INVALID_DBH_ATTR );
|
THROW_PDO_ERROR( driver_dbh, PDO_SQLSRV_ERROR_INVALID_DBH_ATTR );
|
||||||
|
@ -1114,7 +1194,7 @@ int pdo_sqlsrv_dbh_quote( pdo_dbh_t* dbh, const char* unquoted, int unquoted_len
|
||||||
}
|
}
|
||||||
|
|
||||||
*quoted_len = unquoted_len + quotes_needed; // length returned to the caller should not account for null terminator.
|
*quoted_len = unquoted_len + quotes_needed; // length returned to the caller should not account for null terminator.
|
||||||
*quoted = reinterpret_cast<char*>( sqlsrv_malloc( *quoted_len + 1 )); // include space for null terminator.
|
*quoted = reinterpret_cast<char*>( sqlsrv_malloc( *quoted_len, sizeof( char ), 1 )); // include space for null terminator.
|
||||||
unsigned int out_current = 0;
|
unsigned int out_current = 0;
|
||||||
|
|
||||||
// insert initial quote
|
// insert initial quote
|
||||||
|
@ -1182,10 +1262,23 @@ void add_stmt_option_key( sqlsrv_context& ctx, unsigned long key, HashTable* opt
|
||||||
option_key = PDO_STMT_OPTION_DIRECT_QUERY;
|
option_key = PDO_STMT_OPTION_DIRECT_QUERY;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SQLSRV_ATTR_CURSOR_SCROLL_TYPE:
|
||||||
|
option_key = PDO_STMT_OPTION_CURSOR_SCROLL_TYPE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SQLSRV_ATTR_CLIENT_BUFFER_MAX_KB_SIZE:
|
||||||
|
option_key = PDO_STMT_OPTION_CLIENT_BUFFER_MAX_KB_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PDO_ATTR_EMULATE_PREPARES:
|
||||||
|
option_key = PDO_STMT_OPTION_EMULATE_PREPARES;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
CHECK_CUSTOM_ERROR( true, ctx, PDO_SQLSRV_ERROR_INVALID_STMT_OPTION ) {
|
CHECK_CUSTOM_ERROR( true, ctx, PDO_SQLSRV_ERROR_INVALID_STMT_OPTION ) {
|
||||||
throw core::CoreException();
|
throw core::CoreException();
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
//
|
//
|
||||||
// Contents: initialization routines for PDO_SQLSRV
|
// Contents: initialization routines for PDO_SQLSRV
|
||||||
//
|
//
|
||||||
// Copyright 2010 Microsoft Corporation
|
// Copyright Microsoft Corporation
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -134,7 +134,7 @@ zend_module_entry g_pdo_sqlsrv_module_entry =
|
||||||
|
|
||||||
// functions dynamically linked from the PDO (or PHP) dll and called by other parts of the driver
|
// functions dynamically linked from the PDO (or PHP) dll and called by other parts of the driver
|
||||||
zend_class_entry* (*pdo_get_exception_class)( void );
|
zend_class_entry* (*pdo_get_exception_class)( void );
|
||||||
int (*pdo_subst_params_named_to_positional)(pdo_stmt_t *stmt, char *inquery, int inquery_len,
|
int (*pdo_subst_named_params)(pdo_stmt_t *stmt, char *inquery, int inquery_len,
|
||||||
char **outquery, int *outquery_len TSRMLS_DC);
|
char **outquery, int *outquery_len TSRMLS_DC);
|
||||||
|
|
||||||
// Module initialization
|
// Module initialization
|
||||||
|
@ -206,11 +206,11 @@ PHP_MINIT_FUNCTION(pdo_sqlsrv)
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
pdo_subst_params_named_to_positional =
|
pdo_subst_named_params =
|
||||||
reinterpret_cast<int (*)(pdo_stmt_t *stmt, char *inquery, int inquery_len,
|
reinterpret_cast<int (*)(pdo_stmt_t *stmt, char *inquery, int inquery_len,
|
||||||
char **outquery, int *outquery_len TSRMLS_DC)>(
|
char **outquery, int *outquery_len TSRMLS_DC)>(
|
||||||
GetProcAddress( pdo_hmodule, "pdo_parse_params" ));
|
GetProcAddress( pdo_hmodule, "pdo_parse_params" ));
|
||||||
if( pdo_subst_params_named_to_positional == NULL ) {
|
if( pdo_subst_named_params == NULL ) {
|
||||||
LOG( SEV_ERROR, "Failed to register driver." );
|
LOG( SEV_ERROR, "Failed to register driver." );
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
@ -243,16 +243,6 @@ PHP_MINIT_FUNCTION(pdo_sqlsrv)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// used for the size for output parameters: PDO::PARAM_INT and PDO::PARAM_BOOL use the default size of int,
|
|
||||||
// PDO::PARAM_STR uses the size of the string in the variable
|
|
||||||
REGISTER_PDO_SQLSRV_CLASS_CONST_LONG( "SQLSRV_PARAM_OUT_DEFAULT_SIZE", -1 TSRMLS_CC );
|
|
||||||
|
|
||||||
// encoding attributes
|
|
||||||
REGISTER_PDO_SQLSRV_CLASS_CONST_LONG( "SQLSRV_ENCODING_DEFAULT", SQLSRV_ENCODING_DEFAULT TSRMLS_CC );
|
|
||||||
REGISTER_PDO_SQLSRV_CLASS_CONST_LONG( "SQLSRV_ENCODING_SYSTEM", SQLSRV_ENCODING_SYSTEM TSRMLS_CC );
|
|
||||||
REGISTER_PDO_SQLSRV_CLASS_CONST_LONG( "SQLSRV_ENCODING_BINARY", SQLSRV_ENCODING_BINARY TSRMLS_CC );
|
|
||||||
REGISTER_PDO_SQLSRV_CLASS_CONST_LONG( "SQLSRV_ENCODING_UTF8", SQLSRV_ENCODING_UTF8 TSRMLS_CC );
|
|
||||||
|
|
||||||
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 TSRMLS_CC );
|
||||||
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 TSRMLS_CC );
|
||||||
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 TSRMLS_CC );
|
||||||
|
@ -384,9 +374,29 @@ namespace {
|
||||||
// array of pdo constants.
|
// array of pdo constants.
|
||||||
sqlsrv_attr_pdo_constant pdo_attr_constants[] = {
|
sqlsrv_attr_pdo_constant pdo_attr_constants[] = {
|
||||||
|
|
||||||
|
// driver specific attributes
|
||||||
{ "SQLSRV_ATTR_ENCODING" , SQLSRV_ATTR_ENCODING },
|
{ "SQLSRV_ATTR_ENCODING" , SQLSRV_ATTR_ENCODING },
|
||||||
{ "SQLSRV_ATTR_QUERY_TIMEOUT" , SQLSRV_ATTR_QUERY_TIMEOUT },
|
{ "SQLSRV_ATTR_QUERY_TIMEOUT" , SQLSRV_ATTR_QUERY_TIMEOUT },
|
||||||
{ "SQLSRV_ATTR_DIRECT_QUERY" , SQLSRV_ATTR_DIRECT_QUERY },
|
{ "SQLSRV_ATTR_DIRECT_QUERY" , SQLSRV_ATTR_DIRECT_QUERY },
|
||||||
|
{ "SQLSRV_ATTR_CURSOR_SCROLL_TYPE" , SQLSRV_ATTR_CURSOR_SCROLL_TYPE },
|
||||||
|
{ "SQLSRV_ATTR_CLIENT_BUFFER_MAX_KB_SIZE", SQLSRV_ATTR_CLIENT_BUFFER_MAX_KB_SIZE },
|
||||||
|
|
||||||
|
// used for the size for output parameters: PDO::PARAM_INT and PDO::PARAM_BOOL use the default size of int,
|
||||||
|
// PDO::PARAM_STR uses the size of the string in the variable
|
||||||
|
{ "SQLSRV_PARAM_OUT_DEFAULT_SIZE" , -1 },
|
||||||
|
|
||||||
|
// encoding attributes
|
||||||
|
{ "SQLSRV_ENCODING_DEFAULT" , SQLSRV_ENCODING_DEFAULT },
|
||||||
|
{ "SQLSRV_ENCODING_SYSTEM" , SQLSRV_ENCODING_SYSTEM },
|
||||||
|
{ "SQLSRV_ENCODING_BINARY" , SQLSRV_ENCODING_BINARY },
|
||||||
|
{ "SQLSRV_ENCODING_UTF8" , SQLSRV_ENCODING_UTF8 },
|
||||||
|
|
||||||
|
// cursor types (can be assigned to SQLSRV_ATTR_CURSOR_SCROLL_TYPE
|
||||||
|
{ "SQLSRV_CURSOR_STATIC" , SQL_CURSOR_STATIC },
|
||||||
|
{ "SQLSRV_CURSOR_DYNAMIC" , SQL_CURSOR_DYNAMIC },
|
||||||
|
{ "SQLSRV_CURSOR_KEYSET" , SQL_CURSOR_KEYSET_DRIVEN },
|
||||||
|
{ "SQLSRV_CURSOR_BUFFERED" , SQLSRV_CURSOR_BUFFERED },
|
||||||
|
|
||||||
{ NULL , 0 } // terminate the table
|
{ NULL , 0 } // terminate the table
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
//
|
//
|
||||||
// Contents: Implements a parser to parse the PDO DSN.
|
// Contents: Implements a parser to parse the PDO DSN.
|
||||||
//
|
//
|
||||||
// Copyright 2010 Microsoft Corporation
|
// Copyright Microsoft Corporation
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
//
|
//
|
||||||
// Contents: Declarations for the extension
|
// Contents: Declarations for the extension
|
||||||
//
|
//
|
||||||
// Copyright 2010 Microsoft Corporation
|
// Copyright Microsoft Corporation
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -32,6 +32,10 @@ extern "C" {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
|
||||||
//*********************************************************************************************************************************
|
//*********************************************************************************************************************************
|
||||||
// Constants and Types
|
// Constants and Types
|
||||||
//*********************************************************************************************************************************
|
//*********************************************************************************************************************************
|
||||||
|
@ -43,6 +47,8 @@ enum PDO_SQLSRV_ATTR {
|
||||||
SQLSRV_ATTR_ENCODING = PDO_ATTR_DRIVER_SPECIFIC,
|
SQLSRV_ATTR_ENCODING = PDO_ATTR_DRIVER_SPECIFIC,
|
||||||
SQLSRV_ATTR_QUERY_TIMEOUT,
|
SQLSRV_ATTR_QUERY_TIMEOUT,
|
||||||
SQLSRV_ATTR_DIRECT_QUERY,
|
SQLSRV_ATTR_DIRECT_QUERY,
|
||||||
|
SQLSRV_ATTR_CURSOR_SCROLL_TYPE,
|
||||||
|
SQLSRV_ATTR_CLIENT_BUFFER_MAX_KB_SIZE,
|
||||||
};
|
};
|
||||||
|
|
||||||
// valid set of values for TransactionIsolation connection option
|
// valid set of values for TransactionIsolation connection option
|
||||||
|
@ -65,6 +71,7 @@ extern "C" {
|
||||||
ZEND_BEGIN_MODULE_GLOBALS(pdo_sqlsrv)
|
ZEND_BEGIN_MODULE_GLOBALS(pdo_sqlsrv)
|
||||||
|
|
||||||
unsigned int log_severity;
|
unsigned int log_severity;
|
||||||
|
long client_buffer_max_size;
|
||||||
|
|
||||||
ZEND_END_MODULE_GLOBALS(pdo_sqlsrv)
|
ZEND_END_MODULE_GLOBALS(pdo_sqlsrv)
|
||||||
|
|
||||||
|
@ -81,12 +88,15 @@ ZEND_EXTERN_MODULE_GLOBALS(pdo_sqlsrv);
|
||||||
|
|
||||||
// INI settings and constants
|
// INI settings and constants
|
||||||
// (these are defined as macros to allow concatenation as we do below)
|
// (these are defined as macros to allow concatenation as we do below)
|
||||||
|
#define INI_PDO_SQLSRV_CLIENT_BUFFER_MAX_SIZE "client_buffer_max_kb_size"
|
||||||
#define INI_PDO_SQLSRV_LOG "log_severity"
|
#define INI_PDO_SQLSRV_LOG "log_severity"
|
||||||
#define INI_PREFIX "pdo_sqlsrv."
|
#define INI_PREFIX "pdo_sqlsrv."
|
||||||
|
|
||||||
PHP_INI_BEGIN()
|
PHP_INI_BEGIN()
|
||||||
STD_PHP_INI_ENTRY( INI_PREFIX INI_PDO_SQLSRV_LOG , "0", PHP_INI_ALL, OnUpdateLong, log_severity,
|
STD_PHP_INI_ENTRY( INI_PREFIX INI_PDO_SQLSRV_LOG , "0", PHP_INI_ALL, OnUpdateLong, log_severity,
|
||||||
zend_pdo_sqlsrv_globals, pdo_sqlsrv_globals )
|
zend_pdo_sqlsrv_globals, pdo_sqlsrv_globals )
|
||||||
|
STD_PHP_INI_ENTRY( INI_PREFIX INI_PDO_SQLSRV_CLIENT_BUFFER_MAX_SIZE , INI_BUFFERED_QUERY_LIMIT_DEFAULT, PHP_INI_ALL, OnUpdateLong,
|
||||||
|
client_buffer_max_size, zend_pdo_sqlsrv_globals, pdo_sqlsrv_globals )
|
||||||
PHP_INI_END()
|
PHP_INI_END()
|
||||||
|
|
||||||
// henv context for creating connections
|
// henv context for creating connections
|
||||||
|
@ -166,14 +176,9 @@ struct pdo_sqlsrv_dbh : public sqlsrv_conn {
|
||||||
zval* stmts;
|
zval* stmts;
|
||||||
bool direct_query;
|
bool direct_query;
|
||||||
long query_timeout;
|
long query_timeout;
|
||||||
|
long client_buffer_max_size;
|
||||||
|
|
||||||
pdo_sqlsrv_dbh( SQLHANDLE h, error_callback e, void* driver TSRMLS_DC ) :
|
pdo_sqlsrv_dbh( SQLHANDLE h, error_callback e, void* driver TSRMLS_DC );
|
||||||
sqlsrv_conn( h, e, driver, SQLSRV_ENCODING_UTF8 TSRMLS_CC ),
|
|
||||||
stmts( NULL ),
|
|
||||||
direct_query( false ),
|
|
||||||
query_timeout( QUERY_TIMEOUT_INVALID )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -196,6 +201,16 @@ struct stmt_option_direct_query : public stmt_option_functor {
|
||||||
virtual void operator()( sqlsrv_stmt* stmt, stmt_option const* /*opt*/, zval* value_z TSRMLS_DC );
|
virtual void operator()( sqlsrv_stmt* stmt, stmt_option const* /*opt*/, zval* value_z TSRMLS_DC );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct stmt_option_cursor_scroll_type : public stmt_option_functor {
|
||||||
|
|
||||||
|
virtual void operator()( sqlsrv_stmt* stmt, stmt_option const* /*opt*/, zval* value_z TSRMLS_DC );
|
||||||
|
};
|
||||||
|
|
||||||
|
struct stmt_option_emulate_prepares : public stmt_option_functor {
|
||||||
|
|
||||||
|
virtual void operator()( sqlsrv_stmt* stmt, stmt_option const* /*opt*/, zval* value_z TSRMLS_DC );
|
||||||
|
};
|
||||||
|
|
||||||
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
|
||||||
|
@ -204,28 +219,22 @@ struct pdo_sqlsrv_stmt : public sqlsrv_stmt {
|
||||||
pdo_sqlsrv_stmt( sqlsrv_conn* c, SQLHANDLE handle, error_callback e, void* drv TSRMLS_DC ) :
|
pdo_sqlsrv_stmt( sqlsrv_conn* c, SQLHANDLE handle, error_callback e, void* drv TSRMLS_DC ) :
|
||||||
sqlsrv_stmt( c, handle, e, drv TSRMLS_CC ),
|
sqlsrv_stmt( c, handle, e, drv TSRMLS_CC ),
|
||||||
direct_query( false ),
|
direct_query( false ),
|
||||||
query( NULL ),
|
bound_column_param_types( NULL )
|
||||||
query_len( 0 )
|
|
||||||
{
|
{
|
||||||
pdo_sqlsrv_dbh* db = static_cast<pdo_sqlsrv_dbh*>( c );
|
pdo_sqlsrv_dbh* db = static_cast<pdo_sqlsrv_dbh*>( c );
|
||||||
direct_query = db->direct_query;
|
direct_query = db->direct_query;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~pdo_sqlsrv_stmt( void )
|
virtual ~pdo_sqlsrv_stmt( void );
|
||||||
{
|
|
||||||
if( query ) {
|
|
||||||
sqlsrv_free( query );
|
|
||||||
query = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
||||||
// for PDO, everything is a string, so we return SQLSRV_PHPTYPE_STRING for all SQL types
|
// for PDO, everything is a string, so we return SQLSRV_PHPTYPE_STRING for all SQL types
|
||||||
virtual sqlsrv_phptype sql_type_to_php_type( SQLINTEGER sql_type, SQLUINTEGER size, bool prefer_string_to_stream );
|
virtual sqlsrv_phptype sql_type_to_php_type( SQLINTEGER sql_type, SQLUINTEGER size, bool prefer_string_to_stream );
|
||||||
|
|
||||||
bool direct_query; // flag set if the query should be executed directly or prepared
|
bool direct_query; // flag set if the query should be executed directly or prepared
|
||||||
char* query; // if the query should be executed directly, this holds the query to execute
|
// meta data for current result set
|
||||||
unsigned int query_len; // length of the query string.
|
std::vector<field_meta_data*, sqlsrv_allocator< field_meta_data* > > current_meta_data;
|
||||||
|
pdo_param_type* bound_column_param_types;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -345,6 +354,8 @@ enum PDO_ERROR_CODES {
|
||||||
PDO_SQLSRV_ERROR_DQ_ATTR_AT_PREPARE_ONLY,
|
PDO_SQLSRV_ERROR_DQ_ATTR_AT_PREPARE_ONLY,
|
||||||
PDO_SQLSRV_ERROR_INVALID_COLUMN_INDEX,
|
PDO_SQLSRV_ERROR_INVALID_COLUMN_INDEX,
|
||||||
PDO_SQLSRV_ERROR_INVALID_OUTPUT_PARAM_TYPE,
|
PDO_SQLSRV_ERROR_INVALID_OUTPUT_PARAM_TYPE,
|
||||||
|
PDO_SQLSRV_ERROR_INVALID_CURSOR_WITH_SCROLL_TYPE,
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern pdo_error PDO_ERRORS[];
|
extern pdo_error PDO_ERRORS[];
|
||||||
|
@ -368,7 +379,7 @@ namespace pdo {
|
||||||
// called pdo_parse_params in php_pdo_driver.h
|
// called pdo_parse_params in php_pdo_driver.h
|
||||||
// we renamed it for 2 reasons: 1) we can't have the same name since it would conflict with our dynamic linking, and
|
// we renamed it for 2 reasons: 1) we can't have the same name since it would conflict with our dynamic linking, and
|
||||||
// 2) this is a more precise name
|
// 2) this is a more precise name
|
||||||
extern int (*pdo_subst_params_named_to_positional)(pdo_stmt_t *stmt, char *inquery, int inquery_len,
|
extern int (*pdo_subst_named_params)(pdo_stmt_t *stmt, char *inquery, int inquery_len,
|
||||||
char **outquery, int *outquery_len TSRMLS_DC);
|
char **outquery, int *outquery_len TSRMLS_DC);
|
||||||
|
|
||||||
// logger for pdo_sqlsrv called by the core layer when it wants to log something with the LOG macro
|
// logger for pdo_sqlsrv called by the core layer when it wants to log something with the LOG macro
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
//
|
//
|
||||||
// Contents: Implements the PDOStatement object for the PDO_SQLSRV
|
// Contents: Implements the PDOStatement object for the PDO_SQLSRV
|
||||||
//
|
//
|
||||||
// Copyright 2010 Microsoft Corporation
|
// Copyright Microsoft Corporation
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -40,6 +40,9 @@ const int SQL_SERVER_IDENT_SIZE_MAX = 128;
|
||||||
|
|
||||||
inline SQLSMALLINT pdo_fetch_ori_to_odbc_fetch_ori (enum pdo_fetch_orientation ori)
|
inline SQLSMALLINT pdo_fetch_ori_to_odbc_fetch_ori (enum pdo_fetch_orientation ori)
|
||||||
{
|
{
|
||||||
|
SQLSRV_ASSERT( ori >= PDO_FETCH_ORI_NEXT && ori <= PDO_FETCH_ORI_REL, "Fetch orientation out of range." );
|
||||||
|
OACR_WARNING_SUPPRESS( 26001, "Buffer length verified above" );
|
||||||
|
OACR_WARNING_SUPPRESS( 26000, "Buffer length verified above" );
|
||||||
return odbc_fetch_orientation[ori];
|
return odbc_fetch_orientation[ori];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +63,8 @@ SQLSRV_PHPTYPE pdo_type_to_sqlsrv_php_type( sqlsrv_stmt* driver_stmt, enum pdo_p
|
||||||
return SQLSRV_PHPTYPE_NULL;
|
return SQLSRV_PHPTYPE_NULL;
|
||||||
|
|
||||||
case PDO_PARAM_LOB:
|
case PDO_PARAM_LOB:
|
||||||
return SQLSRV_PHPTYPE_STREAM;
|
// TODO: This will eventually be changed to SQLSRV_PHPTYPE_STREAM when output streaming is implemented.
|
||||||
|
return SQLSRV_PHPTYPE_STRING;
|
||||||
|
|
||||||
case PDO_PARAM_STMT:
|
case PDO_PARAM_STMT:
|
||||||
THROW_PDO_ERROR( driver_stmt, PDO_SQLSRV_ERROR_PDO_STMT_UNSUPPORTED );
|
THROW_PDO_ERROR( driver_stmt, PDO_SQLSRV_ERROR_PDO_STMT_UNSUPPORTED );
|
||||||
|
@ -73,31 +77,6 @@ SQLSRV_PHPTYPE pdo_type_to_sqlsrv_php_type( sqlsrv_stmt* driver_stmt, enum pdo_p
|
||||||
return SQLSRV_PHPTYPE_INVALID; // to prevent compiler warning
|
return SQLSRV_PHPTYPE_INVALID; // to prevent compiler warning
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns PDO type for a given SQLSRV type. See pdo_param_type
|
|
||||||
// for list of supported pdo types.
|
|
||||||
inline pdo_param_type sqlsrv_php_type_to_pdo_type( enum SQLSRV_PHPTYPE sqlsrv_php_type )
|
|
||||||
{
|
|
||||||
switch( sqlsrv_php_type ) {
|
|
||||||
|
|
||||||
case SQLSRV_PHPTYPE_INT:
|
|
||||||
case SQLSRV_PHPTYPE_FLOAT:
|
|
||||||
return PDO_PARAM_INT;
|
|
||||||
|
|
||||||
case SQLSRV_PHPTYPE_DATETIME:
|
|
||||||
case SQLSRV_PHPTYPE_STRING:
|
|
||||||
return PDO_PARAM_STR;
|
|
||||||
|
|
||||||
case SQLSRV_PHPTYPE_STREAM:
|
|
||||||
return PDO_PARAM_LOB;
|
|
||||||
|
|
||||||
case SQLSRV_PHPTYPE_NULL:
|
|
||||||
return PDO_PARAM_NULL;
|
|
||||||
|
|
||||||
default:
|
|
||||||
DIE( "sqlsrv_php_type_to_pdo_type: Unexpected sqlsrv_php_type encountered." );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns a pdo type for a given SQL type. See pdo_param_type
|
// Returns a pdo type for a given SQL type. See pdo_param_type
|
||||||
// for list of supported pdo types.
|
// for list of supported pdo types.
|
||||||
inline pdo_param_type sql_type_to_pdo_type( SQLSMALLINT sql_type )
|
inline pdo_param_type sql_type_to_pdo_type( SQLSMALLINT sql_type )
|
||||||
|
@ -124,6 +103,7 @@ inline pdo_param_type sql_type_to_pdo_type( SQLSMALLINT sql_type )
|
||||||
case SQL_SS_TIME2:
|
case SQL_SS_TIME2:
|
||||||
case SQL_SS_TIMESTAMPOFFSET:
|
case SQL_SS_TIMESTAMPOFFSET:
|
||||||
case SQL_SS_UDT:
|
case SQL_SS_UDT:
|
||||||
|
case SQL_SS_VARIANT:
|
||||||
case SQL_SS_XML:
|
case SQL_SS_XML:
|
||||||
case SQL_TYPE_DATE:
|
case SQL_TYPE_DATE:
|
||||||
case SQL_TYPE_TIMESTAMP:
|
case SQL_TYPE_TIMESTAMP:
|
||||||
|
@ -173,6 +153,25 @@ void set_stmt_cursors( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC )
|
||||||
core_sqlsrv_set_scrollable( stmt, odbc_cursor_type TSRMLS_CC );
|
core_sqlsrv_set_scrollable( stmt, odbc_cursor_type TSRMLS_CC );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_stmt_cursor_scroll_type( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC )
|
||||||
|
{
|
||||||
|
if( Z_TYPE_P( value_z ) != IS_LONG ) {
|
||||||
|
|
||||||
|
THROW_PDO_ERROR( stmt, PDO_SQLSRV_ERROR_INVALID_CURSOR_TYPE );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( stmt->cursor_type == SQL_CURSOR_FORWARD_ONLY ) {
|
||||||
|
|
||||||
|
THROW_PDO_ERROR( stmt, PDO_SQLSRV_ERROR_INVALID_CURSOR_WITH_SCROLL_TYPE );
|
||||||
|
}
|
||||||
|
|
||||||
|
long odbc_cursor_type = Z_LVAL_P( value_z );
|
||||||
|
|
||||||
|
core_sqlsrv_set_scrollable( stmt, odbc_cursor_type TSRMLS_CC );
|
||||||
|
|
||||||
|
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( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC )
|
void set_stmt_encoding( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC )
|
||||||
|
@ -201,6 +200,76 @@ void set_stmt_encoding( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// internal helper function to free meta data structures allocated
|
||||||
|
void meta_data_free( field_meta_data* meta )
|
||||||
|
{
|
||||||
|
sqlsrv_free( meta );
|
||||||
|
}
|
||||||
|
|
||||||
|
zval* convert_to_zval( SQLSRV_PHPTYPE sqlsrv_php_type, void** in_val, SQLLEN field_len )
|
||||||
|
{
|
||||||
|
zval* out_zval = NULL;
|
||||||
|
|
||||||
|
switch( sqlsrv_php_type ) {
|
||||||
|
|
||||||
|
case SQLSRV_PHPTYPE_INT:
|
||||||
|
case SQLSRV_PHPTYPE_FLOAT:
|
||||||
|
{
|
||||||
|
ALLOC_INIT_ZVAL( out_zval );
|
||||||
|
if( *in_val == NULL ) {
|
||||||
|
ZVAL_NULL( out_zval );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
if( sqlsrv_php_type == SQLSRV_PHPTYPE_INT ) {
|
||||||
|
ZVAL_LONG( out_zval, **( reinterpret_cast<long**>( in_val )));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ZVAL_DOUBLE( out_zval, **( reinterpret_cast<double**>( in_val )));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( *in_val ) {
|
||||||
|
sqlsrv_free( *in_val );
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SQLSRV_PHPTYPE_STRING:
|
||||||
|
case SQLSRV_PHPTYPE_STREAM: // TODO: this will be moved when output streaming is implemented
|
||||||
|
{
|
||||||
|
ALLOC_INIT_ZVAL( out_zval );
|
||||||
|
|
||||||
|
if( *in_val == NULL ) {
|
||||||
|
|
||||||
|
ZVAL_NULL( out_zval );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
ZVAL_STRINGL( out_zval, reinterpret_cast<char*>( *in_val ), field_len, 0 /*duplicate*/ );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SQLSRV_PHPTYPE_DATETIME:
|
||||||
|
DIE( "Unsupported php type" );
|
||||||
|
out_zval = ( reinterpret_cast<zval*>( *in_val ));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SQLSRV_PHPTYPE_NULL:
|
||||||
|
ALLOC_INIT_ZVAL( out_zval );
|
||||||
|
ZVAL_NULL( out_zval );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
DIE( "Unknown php type" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return out_zval;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
int pdo_sqlsrv_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC);
|
int pdo_sqlsrv_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC);
|
||||||
|
@ -243,12 +312,25 @@ void stmt_option_encoding:: operator()( sqlsrv_stmt* stmt, stmt_option const* /*
|
||||||
{
|
{
|
||||||
set_stmt_encoding( stmt, value_z TSRMLS_CC );
|
set_stmt_encoding( stmt, value_z TSRMLS_CC );
|
||||||
}
|
}
|
||||||
|
|
||||||
void stmt_option_direct_query:: operator()( sqlsrv_stmt* stmt, stmt_option const* /*opt*/, zval* value_z TSRMLS_DC )
|
void stmt_option_direct_query:: operator()( sqlsrv_stmt* stmt, stmt_option const* /*opt*/, zval* value_z TSRMLS_DC )
|
||||||
{
|
{
|
||||||
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()( sqlsrv_stmt* stmt, stmt_option const* /*opt*/, zval* value_z TSRMLS_DC )
|
||||||
|
{
|
||||||
|
set_stmt_cursor_scroll_type( stmt, value_z TSRMLS_CC );
|
||||||
|
}
|
||||||
|
|
||||||
|
void stmt_option_emulate_prepares:: operator()( sqlsrv_stmt* stmt, stmt_option const* /*opt*/, zval* value_z TSRMLS_DC )
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// log a function entry point
|
// log a function entry point
|
||||||
#define PDO_LOG_STMT_ENTRY \
|
#define PDO_LOG_STMT_ENTRY \
|
||||||
{ \
|
{ \
|
||||||
|
@ -257,6 +339,19 @@ void stmt_option_direct_query:: operator()( sqlsrv_stmt* stmt, stmt_option const
|
||||||
LOG( SEV_NOTICE, __FUNCTION__ ## ": entering" ); \
|
LOG( SEV_NOTICE, __FUNCTION__ ## ": entering" ); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PDO SQLSRV statement destructor
|
||||||
|
pdo_sqlsrv_stmt::~pdo_sqlsrv_stmt( void )
|
||||||
|
{
|
||||||
|
std::for_each( current_meta_data.begin(), current_meta_data.end(), meta_data_free );
|
||||||
|
current_meta_data.clear();
|
||||||
|
|
||||||
|
if( bound_column_param_types ) {
|
||||||
|
sqlsrv_free( bound_column_param_types );
|
||||||
|
bound_column_param_types = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// pdo_sqlsrv_stmt_close_cursor
|
// pdo_sqlsrv_stmt_close_cursor
|
||||||
// Close any open cursors on the statement. Maps to PDO function PDOStatement::closeCursor.
|
// Close any open cursors on the statement. Maps to PDO function PDOStatement::closeCursor.
|
||||||
// Parameters:
|
// Parameters:
|
||||||
|
@ -345,10 +440,14 @@ int pdo_sqlsrv_stmt_describe_col(pdo_stmt_t *stmt, int colno TSRMLS_DC)
|
||||||
column_data->precision = core_meta_data->field_scale;
|
column_data->precision = core_meta_data->field_scale;
|
||||||
|
|
||||||
// Set the param_type
|
// Set the param_type
|
||||||
column_data->param_type = sql_type_to_pdo_type( core_meta_data->field_type );
|
column_data->param_type = PDO_PARAM_ZVAL;
|
||||||
|
|
||||||
// always good to call destructor for allocations done through placement new operator.
|
// store the field data for use by pdo_sqlsrv_stmt_get_col_data
|
||||||
core_meta_data->~field_meta_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" );
|
||||||
|
driver_stmt->current_meta_data.push_back( core_meta_data.get() );
|
||||||
|
SQLSRV_ASSERT( driver_stmt->current_meta_data.size() == colno + 1, "Meta data vector out of sync with column numbers" );
|
||||||
|
core_meta_data.transferred();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -408,7 +507,23 @@ int pdo_sqlsrv_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
core_sqlsrv_execute( driver_stmt TSRMLS_CC, driver_stmt->query, driver_stmt->query_len );
|
const char* query = NULL;
|
||||||
|
unsigned int query_len = 0;
|
||||||
|
|
||||||
|
// if the user is doing a direct query (PDO::SQLSRV_ATTR_DIRECT_QUERY), set the query here
|
||||||
|
if( driver_stmt->direct_query ) {
|
||||||
|
query = stmt->query_string;
|
||||||
|
query_len = stmt->query_stringlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the user is using prepare emulation (PDO::ATTR_EMULATE_PREPARES), set the query to the
|
||||||
|
// subtituted query provided by PDO
|
||||||
|
if( stmt->supports_placeholders == PDO_PLACEHOLDER_NONE ) {
|
||||||
|
query = stmt->active_query_string;
|
||||||
|
query_len = stmt->active_query_stringlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
core_sqlsrv_execute( driver_stmt TSRMLS_CC, query, query_len );
|
||||||
|
|
||||||
stmt->column_count = core::SQLNumResultCols( driver_stmt TSRMLS_CC );
|
stmt->column_count = core::SQLNumResultCols( driver_stmt TSRMLS_CC );
|
||||||
|
|
||||||
|
@ -468,16 +583,48 @@ int pdo_sqlsrv_stmt_fetch(pdo_stmt_t *stmt, enum pdo_fetch_orientation ori,
|
||||||
|
|
||||||
SQLSRV_ASSERT( stmt != NULL, "pdo_sqlsrv_stmt_fetch: pdo_stmt object was null" );
|
SQLSRV_ASSERT( stmt != NULL, "pdo_sqlsrv_stmt_fetch: pdo_stmt object was null" );
|
||||||
|
|
||||||
sqlsrv_stmt* driver_stmt = reinterpret_cast<sqlsrv_stmt*>( stmt->driver_data );
|
pdo_sqlsrv_stmt* driver_stmt = reinterpret_cast<pdo_sqlsrv_stmt*>( stmt->driver_data );
|
||||||
|
|
||||||
SQLSRV_ASSERT( driver_stmt != NULL, "pdo_sqlsrv_stmt_fetch: driver_data object was null" );
|
SQLSRV_ASSERT( driver_stmt != NULL, "pdo_sqlsrv_stmt_fetch: driver_data object was null" );
|
||||||
|
|
||||||
|
// set the types for bound columns to zval so that PDO does no conversion when the value
|
||||||
|
// is returned by pdo_sqlsrv_get_col_data. Remember the types that were bound by the user
|
||||||
|
// and use it to manually convert data types
|
||||||
|
if( stmt->bound_columns ) {
|
||||||
|
|
||||||
|
pdo_bound_param_data* bind_data = NULL;
|
||||||
|
|
||||||
|
if( !driver_stmt->bound_column_param_types ) {
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
for( long i = 0; i < stmt->column_count; ++i ) {
|
||||||
|
|
||||||
|
if( zend_hash_index_find( stmt->bound_columns, i, (void**) &bind_data ) == FAILURE &&
|
||||||
|
zend_hash_find( stmt->bound_columns, stmt->columns[ i ].name, stmt->columns[ i ].namelen,
|
||||||
|
(void**) &bind_data ) == FAILURE ) {
|
||||||
|
|
||||||
|
driver_stmt->bound_column_param_types[ i ] = PDO_PARAM_ZVAL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( bind_data->param_type != PDO_PARAM_ZVAL ) {
|
||||||
|
|
||||||
|
driver_stmt->bound_column_param_types[ i ] = bind_data->param_type;
|
||||||
|
bind_data->param_type = PDO_PARAM_ZVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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 TSRMLS_CC );
|
||||||
|
|
||||||
// support for the PDO rowCount method. Since rowCount doesn't call a method, PDO relies on us to fill the
|
// 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
|
// pdo_stmt_t::row_count member
|
||||||
if( driver_stmt->past_fetch_end || driver_stmt->scrollable ) {
|
if( driver_stmt->past_fetch_end || driver_stmt->cursor_type != SQL_CURSOR_FORWARD_ONLY ) {
|
||||||
|
|
||||||
stmt->row_count = core::SQLRowCount( driver_stmt TSRMLS_CC );
|
stmt->row_count = core::SQLRowCount( driver_stmt TSRMLS_CC );
|
||||||
|
|
||||||
|
@ -531,7 +678,7 @@ int pdo_sqlsrv_stmt_get_col_data(pdo_stmt_t *stmt, int colno,
|
||||||
|
|
||||||
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" );
|
||||||
|
|
||||||
sqlsrv_stmt* driver_stmt = reinterpret_cast<sqlsrv_stmt*>( stmt->driver_data );
|
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" );
|
SQLSRV_ASSERT( driver_stmt != NULL, "pdo_sqlsrv_stmt_get_col_data: driver_data object was null" );
|
||||||
|
|
||||||
|
@ -547,12 +694,21 @@ int pdo_sqlsrv_stmt_get_col_data(pdo_stmt_t *stmt, int colno,
|
||||||
|
|
||||||
// translate the pdo type to a type the core layer understands
|
// translate the pdo type to a type the core layer understands
|
||||||
sqlsrv_phptype sqlsrv_php_type;
|
sqlsrv_phptype sqlsrv_php_type;
|
||||||
sqlsrv_php_type.typeinfo.type = pdo_type_to_sqlsrv_php_type( driver_stmt, column_data->param_type TSRMLS_CC );
|
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_php_type = driver_stmt->sql_type_to_php_type( driver_stmt->current_meta_data[ colno ]->field_type,
|
||||||
|
driver_stmt->current_meta_data[ colno ]->field_size, true );
|
||||||
|
|
||||||
// set the encoding if the user specified one via bindColumn, otherwise use the statement's encoding
|
// set the encoding if the user specified one via bindColumn, otherwise use the statement's encoding
|
||||||
sqlsrv_php_type.typeinfo.encoding = driver_stmt->encoding();
|
sqlsrv_php_type.typeinfo.encoding = driver_stmt->encoding();
|
||||||
|
|
||||||
if( stmt->bound_columns ) {
|
// 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 ]
|
||||||
|
TSRMLS_CC );
|
||||||
|
|
||||||
pdo_bound_param_data* bind_data = NULL;
|
pdo_bound_param_data* bind_data = NULL;
|
||||||
int zr = zend_hash_index_find( stmt->bound_columns, colno, (void**) &bind_data );
|
int zr = zend_hash_index_find( stmt->bound_columns, colno, (void**) &bind_data );
|
||||||
|
@ -560,12 +716,14 @@ int pdo_sqlsrv_stmt_get_col_data(pdo_stmt_t *stmt, int colno,
|
||||||
if( bind_data != NULL && bind_data->driver_params != NULL ) {
|
if( bind_data != NULL && bind_data->driver_params != NULL ) {
|
||||||
|
|
||||||
CHECK_CUSTOM_ERROR( Z_TYPE_P( bind_data->driver_params ) != IS_LONG, driver_stmt,
|
CHECK_CUSTOM_ERROR( Z_TYPE_P( bind_data->driver_params ) != IS_LONG, driver_stmt,
|
||||||
PDO_SQLSRV_ERROR_INVALID_COLUMN_DRIVER_DATA, colno ) {
|
PDO_SQLSRV_ERROR_INVALID_COLUMN_DRIVER_DATA, colno + 1 ) {
|
||||||
throw pdo::PDOException();
|
throw pdo::PDOException();
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECK_CUSTOM_ERROR( bind_data->param_type != PDO_PARAM_STR && bind_data->param_type != PDO_PARAM_LOB,
|
CHECK_CUSTOM_ERROR( driver_stmt->bound_column_param_types[ colno ] != PDO_PARAM_STR
|
||||||
driver_stmt, PDO_SQLSRV_ERROR_COLUMN_TYPE_DOES_NOT_SUPPORT_ENCODING, colno ) {
|
&& 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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -583,8 +741,14 @@ int pdo_sqlsrv_stmt_get_col_data(pdo_stmt_t *stmt, int colno,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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, NULL TSRMLS_CC );
|
reinterpret_cast<SQLLEN*>( len ), true, &sqlsrv_phptype_out TSRMLS_CC );
|
||||||
|
zval** zval_ptr = reinterpret_cast<zval**>( sqlsrv_malloc( sizeof( zval* )));
|
||||||
|
*zval_ptr = reinterpret_cast<zval*>( convert_to_zval( sqlsrv_phptype_out, reinterpret_cast<void**>( ptr ), *len ));
|
||||||
|
*ptr = reinterpret_cast<char*>( zval_ptr );
|
||||||
|
|
||||||
|
*len = sizeof( zval );
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -633,6 +797,14 @@ int pdo_sqlsrv_stmt_set_attr(pdo_stmt_t *stmt, long attr, zval *val TSRMLS_DC)
|
||||||
core_sqlsrv_set_query_timeout( driver_stmt, val TSRMLS_CC );
|
core_sqlsrv_set_query_timeout( driver_stmt, val TSRMLS_CC );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SQLSRV_ATTR_CURSOR_SCROLL_TYPE:
|
||||||
|
THROW_PDO_ERROR( driver_stmt, PDO_SQLSRV_ERROR_CURSOR_ATTR_AT_PREPARE_ONLY );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SQLSRV_ATTR_CLIENT_BUFFER_MAX_KB_SIZE:
|
||||||
|
core_sqlsrv_set_buffered_query_limit( driver_stmt, val TSRMLS_CC );
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
THROW_PDO_ERROR( driver_stmt, PDO_SQLSRV_ERROR_INVALID_STMT_ATTR );
|
THROW_PDO_ERROR( driver_stmt, PDO_SQLSRV_ERROR_INVALID_STMT_ATTR );
|
||||||
break;
|
break;
|
||||||
|
@ -685,9 +857,23 @@ int pdo_sqlsrv_stmt_get_attr( pdo_stmt_t *stmt, long attr, zval *return_value TS
|
||||||
|
|
||||||
case PDO_ATTR_CURSOR:
|
case PDO_ATTR_CURSOR:
|
||||||
{
|
{
|
||||||
ZVAL_LONG( return_value, ( driver_stmt->scrollable ? PDO_CURSOR_SCROLL : PDO_CURSOR_FWDONLY ));
|
ZVAL_LONG( return_value, ( driver_stmt->cursor_type != SQL_CURSOR_FORWARD_ONLY ?
|
||||||
|
PDO_CURSOR_SCROLL : PDO_CURSOR_FWDONLY ));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SQLSRV_ATTR_CURSOR_SCROLL_TYPE:
|
||||||
|
{
|
||||||
|
ZVAL_LONG( return_value, driver_stmt->cursor_type );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SQLSRV_ATTR_CLIENT_BUFFER_MAX_KB_SIZE:
|
||||||
|
{
|
||||||
|
ZVAL_LONG( return_value, driver_stmt->buffered_query_limit );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case SQLSRV_ATTR_QUERY_TIMEOUT:
|
case SQLSRV_ATTR_QUERY_TIMEOUT:
|
||||||
{
|
{
|
||||||
ZVAL_LONG( return_value, ( driver_stmt->query_timeout == QUERY_TIMEOUT_INVALID ? 0 : driver_stmt->query_timeout ));
|
ZVAL_LONG( return_value, ( driver_stmt->query_timeout == QUERY_TIMEOUT_INVALID ? 0 : driver_stmt->query_timeout ));
|
||||||
|
@ -755,7 +941,8 @@ int pdo_sqlsrv_stmt_get_col_meta(pdo_stmt_t *stmt, long colno, zval *return_valu
|
||||||
// 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
|
||||||
// given a variable of the same type. However, debug_zval_dump also gives the length of a string, and we only
|
// given a variable of the same type. However, debug_zval_dump also gives the length of a string, and we only
|
||||||
// say string, since the length is given in another field of the metadata array.
|
// say string, since the length is given in another field of the metadata array.
|
||||||
switch( sql_type_to_pdo_type( core_meta_data->field_type )) {
|
long pdo_type = sql_type_to_pdo_type( core_meta_data->field_type );
|
||||||
|
switch( pdo_type ) {
|
||||||
case PDO_PARAM_STR:
|
case PDO_PARAM_STR:
|
||||||
add_assoc_string( return_value, "native_type", "string", 1 );
|
add_assoc_string( return_value, "native_type", "string", 1 );
|
||||||
break;
|
break;
|
||||||
|
@ -771,6 +958,10 @@ int pdo_sqlsrv_stmt_get_col_meta(pdo_stmt_t *stmt, long colno, zval *return_valu
|
||||||
&out_buff_len, &field_type_num TSRMLS_CC );
|
&out_buff_len, &field_type_num TSRMLS_CC );
|
||||||
add_assoc_string( return_value, "table", table_name, 1 );
|
add_assoc_string( return_value, "table", table_name, 1 );
|
||||||
|
|
||||||
|
if( stmt->columns[ colno ].param_type == PDO_PARAM_ZVAL ) {
|
||||||
|
add_assoc_long( return_value, "pdo_type", pdo_type );
|
||||||
|
}
|
||||||
|
|
||||||
// this will ensure that the field_name field, which is an auto pointer gets freed.
|
// this will ensure that the field_name field, which is an auto pointer gets freed.
|
||||||
(*core_meta_data).~field_meta_data();
|
(*core_meta_data).~field_meta_data();
|
||||||
}
|
}
|
||||||
|
@ -807,12 +998,16 @@ int pdo_sqlsrv_stmt_next_rowset(pdo_stmt_t *stmt TSRMLS_DC)
|
||||||
|
|
||||||
SQLSRV_ASSERT( stmt != NULL, "pdo_sqlsrv_stmt_next_rowset: pdo_stmt object was null" );
|
SQLSRV_ASSERT( stmt != NULL, "pdo_sqlsrv_stmt_next_rowset: pdo_stmt object was null" );
|
||||||
|
|
||||||
sqlsrv_stmt* driver_stmt = reinterpret_cast<sqlsrv_stmt*>( stmt->driver_data );
|
pdo_sqlsrv_stmt* driver_stmt = reinterpret_cast<pdo_sqlsrv_stmt*>( stmt->driver_data );
|
||||||
|
|
||||||
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 ) TSRMLS_CC );
|
||||||
|
|
||||||
|
// 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 );
|
||||||
|
driver_stmt->current_meta_data.clear();
|
||||||
|
|
||||||
// if there are no more result sets, return that it failed.
|
// if there are no more result sets, return that it failed.
|
||||||
if( driver_stmt->past_next_result_end == true ) {
|
if( driver_stmt->past_next_result_end == true ) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -822,7 +1017,6 @@ int pdo_sqlsrv_stmt_next_rowset(pdo_stmt_t *stmt TSRMLS_DC)
|
||||||
|
|
||||||
// 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 TSRMLS_CC );
|
||||||
|
|
||||||
}
|
}
|
||||||
catch( core::CoreException& ) {
|
catch( core::CoreException& ) {
|
||||||
|
|
||||||
|
@ -971,7 +1165,7 @@ int pdo_sqlsrv_stmt_param_hook(pdo_stmt_t *stmt,
|
||||||
// 2.0 driver. To be consistent and avoid surprises of one object type working and others
|
// 2.0 driver. To be consistent and avoid surprises of one object type working and others
|
||||||
// not, we block all objects here.
|
// not, we block all objects here.
|
||||||
CHECK_CUSTOM_ERROR( direction != SQL_PARAM_OUTPUT && Z_TYPE_P( param->parameter ) == IS_OBJECT,
|
CHECK_CUSTOM_ERROR( direction != SQL_PARAM_OUTPUT && Z_TYPE_P( param->parameter ) == IS_OBJECT,
|
||||||
driver_stmt, SQLSRV_ERROR_INVALID_PARAMETER_PHPTYPE ) {
|
driver_stmt, SQLSRV_ERROR_INVALID_PARAMETER_PHPTYPE, param->paramno + 1 ) {
|
||||||
throw pdo::PDOException();
|
throw pdo::PDOException();
|
||||||
}
|
}
|
||||||
// the encoding by default is that set on the statement
|
// the encoding by default is that set on the statement
|
||||||
|
@ -987,7 +1181,7 @@ int pdo_sqlsrv_stmt_param_hook(pdo_stmt_t *stmt,
|
||||||
throw pdo::PDOException();
|
throw pdo::PDOException();
|
||||||
}
|
}
|
||||||
CHECK_CUSTOM_ERROR( pdo_type != PDO_PARAM_STR && pdo_type != PDO_PARAM_LOB, driver_stmt,
|
CHECK_CUSTOM_ERROR( pdo_type != PDO_PARAM_STR && pdo_type != PDO_PARAM_LOB, driver_stmt,
|
||||||
PDO_SQLSRV_ERROR_INVALID_DRIVER_PARAM_TYPE, param->paramno ) {
|
PDO_SQLSRV_ERROR_INVALID_DRIVER_PARAM_TYPE, param->paramno + 1 ) {
|
||||||
throw pdo::PDOException();
|
throw pdo::PDOException();
|
||||||
}
|
}
|
||||||
encoding = static_cast<SQLSRV_ENCODING>( Z_LVAL_P( param->driver_params ));
|
encoding = static_cast<SQLSRV_ENCODING>( Z_LVAL_P( param->driver_params ));
|
||||||
|
@ -999,7 +1193,7 @@ int pdo_sqlsrv_stmt_param_hook(pdo_stmt_t *stmt,
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
THROW_PDO_ERROR( driver_stmt, PDO_SQLSRV_ERROR_INVALID_DRIVER_PARAM_ENCODING,
|
THROW_PDO_ERROR( driver_stmt, PDO_SQLSRV_ERROR_INVALID_DRIVER_PARAM_ENCODING,
|
||||||
param->paramno );
|
param->paramno + 1 );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
//
|
//
|
||||||
// Contents: Utility functions used by both connection or statement functions
|
// Contents: Utility functions used by both connection or statement functions
|
||||||
//
|
//
|
||||||
// Copyright 2010 Microsoft Corporation
|
// Copyright Microsoft Corporation
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -144,8 +144,8 @@ pdo_error PDO_ERRORS[] = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
SQLSRV_ERROR_UNESCAPED_RIGHT_BRACE_IN_DSN,
|
SQLSRV_ERROR_UNESCAPED_RIGHT_BRACE_IN_DSN,
|
||||||
{ IMSSP, (SQLCHAR*) "An unescaped right brace (}) was found in the DSN string for keyword '%1!s!'. All right braces must be escaped "
|
{ IMSSP, (SQLCHAR*) "An unescaped right brace (}) was found in the DSN string for keyword '%1!s!'. All right braces "
|
||||||
"with another right brace (}}).", -22, true }
|
"must be escaped with another right brace (}}).", -22, true }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
SQLSRV_ERROR_INVALID_OPTION_TYPE_INT,
|
SQLSRV_ERROR_INVALID_OPTION_TYPE_INT,
|
||||||
|
@ -184,8 +184,8 @@ pdo_error PDO_ERRORS[] = {
|
||||||
{ IMSSP, (SQLCHAR*) "Invalid option key %1!s! specified.", -30, true }
|
{ IMSSP, (SQLCHAR*) "Invalid option key %1!s! specified.", -30, true }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
SQLSRV_ERROR_INVALID_OPTION_VALUE,
|
SQLSRV_ERROR_INVALID_QUERY_TIMEOUT_VALUE,
|
||||||
{ IMSSP, (SQLCHAR*) "Invalid value specified for option %1!s!.", -31, true }
|
{ IMSSP, (SQLCHAR*) "Invalid value %1!s! specified for option PDO::SQLSRV_ATTR_QUERY_TIMEOUT.", -31, true }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
SQLSRV_ERROR_INVALID_OPTION_SCROLLABLE,
|
SQLSRV_ERROR_INVALID_OPTION_SCROLLABLE,
|
||||||
|
@ -238,7 +238,8 @@ pdo_error PDO_ERRORS[] = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
PDO_SQLSRV_ERROR_INVALID_CURSOR_TYPE,
|
PDO_SQLSRV_ERROR_INVALID_CURSOR_TYPE,
|
||||||
{ IMSSP, (SQLCHAR*) "An invalid cursor type was specified for the PDO cursor attribute", -44, false }
|
{ IMSSP, (SQLCHAR*) "An invalid cursor type was specified for either PDO::ATTR_CURSOR or "
|
||||||
|
"PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE", -44, false }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
PDO_SQLSRV_ERROR_PARAM_PARSE,
|
PDO_SQLSRV_ERROR_PARAM_PARSE,
|
||||||
|
@ -277,8 +278,8 @@ pdo_error PDO_ERRORS[] = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
PDO_SQLSRV_ERROR_CURSOR_ATTR_AT_PREPARE_ONLY,
|
PDO_SQLSRV_ERROR_CURSOR_ATTR_AT_PREPARE_ONLY,
|
||||||
{ IMSSP, (SQLCHAR*) "The PDO::ATTR_CURSOR attribute may only be set in the $driver_options array of PDO::prepare.",
|
{ IMSSP, (SQLCHAR*) "The PDO::ATTR_CURSOR and PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE attributes may only be set in the "
|
||||||
-53, false }
|
"$driver_options array of PDO::prepare.", -53, false }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
SQLSRV_ERROR_OUTPUT_PARAM_TRUNCATED,
|
SQLSRV_ERROR_OUTPUT_PARAM_TRUNCATED,
|
||||||
|
@ -340,17 +341,33 @@ pdo_error PDO_ERRORS[] = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
PDO_SQLSRV_ERROR_EXTRA_SEMI_COLON_IN_DSN_STRING,
|
PDO_SQLSRV_ERROR_EXTRA_SEMI_COLON_IN_DSN_STRING,
|
||||||
{ IMSSP, (SQLCHAR*) "An extra semi-colon was encountered in the DSN string at character (byte-count) position '%1!d!' .", -66, true }
|
{ IMSSP, (SQLCHAR*) "An extra semi-colon was encountered in the DSN string at character (byte-count) position '%1!d!' .",
|
||||||
|
-66, true }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
PDO_SQLSRV_ERROR_RCB_MISSING_IN_DSN_VALUE,
|
PDO_SQLSRV_ERROR_RCB_MISSING_IN_DSN_VALUE,
|
||||||
{ IMSSP, (SQLCHAR*) "An expected right brace (}) was not found in the DSN string for the value of the keyword '%1!s!'.", -67, true }
|
{ IMSSP, (SQLCHAR*) "An expected right brace (}) was not found in the DSN string for the value of the keyword '%1!s!'.",
|
||||||
|
-67, true }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
PDO_SQLSRV_ERROR_DQ_ATTR_AT_PREPARE_ONLY,
|
PDO_SQLSRV_ERROR_DQ_ATTR_AT_PREPARE_ONLY,
|
||||||
{ IMSSP, (SQLCHAR*) "The PDO::SQLSRV_ATTR_DIRECT_QUERY attribute may only be set in the $driver_options array of "
|
{ IMSSP, (SQLCHAR*) "The PDO::SQLSRV_ATTR_DIRECT_QUERY attribute may only be set in the $driver_options array of "
|
||||||
"PDO::prepare.", -68, false }
|
"PDO::prepare.", -68, false }
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
PDO_SQLSRV_ERROR_INVALID_CURSOR_WITH_SCROLL_TYPE,
|
||||||
|
{ IMSSP, (SQLCHAR*) "The PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE attribute may only be set when PDO::ATTR_CURSOR is set to "
|
||||||
|
"PDO::CURSOR_SCROLL in the $driver_options array of PDO::prepare.", -69, false }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
SQLSRV_ERROR_INVALID_BUFFER_LIMIT,
|
||||||
|
{ IMSSP, (SQLCHAR*) "The PDO::SQLSRV_ATTR_CLIENT_BUFFER_MAX_KB_SIZE attribute is not a number or the number is not "
|
||||||
|
"positive. Only positive numbers are valid for this attribute.", -70, false }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
SQLSRV_ERROR_BUFFER_LIMIT_EXCEEDED,
|
||||||
|
{ IMSSP, (SQLCHAR*) "Memory limit of %1!d! KB exceeded for buffered query", -71, true }
|
||||||
|
},
|
||||||
|
|
||||||
{ -1, {} }
|
{ -1, {} }
|
||||||
};
|
};
|
||||||
|
@ -378,7 +395,6 @@ bool pdo_sqlsrv_handle_env_error( sqlsrv_context& ctx, unsigned int sqlsrv_error
|
||||||
SQLSRV_ASSERT(( dbh != NULL ), "pdo_sqlsrv_handle_env_error: pdo_dbh_t was null" );
|
SQLSRV_ASSERT(( dbh != NULL ), "pdo_sqlsrv_handle_env_error: pdo_dbh_t was null" );
|
||||||
|
|
||||||
sqlsrv_error_auto_ptr error;
|
sqlsrv_error_auto_ptr error;
|
||||||
error = new ( sqlsrv_malloc( sizeof( sqlsrv_error ))) sqlsrv_error;
|
|
||||||
|
|
||||||
if( sqlsrv_error_code != SQLSRV_ERROR_ODBC ) {
|
if( sqlsrv_error_code != SQLSRV_ERROR_ODBC ) {
|
||||||
|
|
||||||
|
@ -386,7 +402,8 @@ bool pdo_sqlsrv_handle_env_error( sqlsrv_context& ctx, unsigned int sqlsrv_error
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
core_sqlsrv_get_odbc_error( ctx, 1, error, SEV_ERROR TSRMLS_CC );
|
bool err = core_sqlsrv_get_odbc_error( ctx, 1, error, SEV_ERROR TSRMLS_CC );
|
||||||
|
SQLSRV_ASSERT( err == true, "No ODBC error was found" );
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy_s( dbh->error_code, sizeof( pdo_error_type ), reinterpret_cast<const char*>( error->sqlstate ));
|
strcpy_s( dbh->error_code, sizeof( pdo_error_type ), reinterpret_cast<const char*>( error->sqlstate ));
|
||||||
|
@ -420,14 +437,14 @@ bool pdo_sqlsrv_handle_dbh_error( sqlsrv_context& ctx, unsigned int sqlsrv_error
|
||||||
SQLSRV_ASSERT( dbh != NULL, "pdo_sqlsrv_handle_dbh_error: Null dbh passed" );
|
SQLSRV_ASSERT( dbh != NULL, "pdo_sqlsrv_handle_dbh_error: Null dbh passed" );
|
||||||
|
|
||||||
sqlsrv_error_auto_ptr error;
|
sqlsrv_error_auto_ptr error;
|
||||||
error = new ( sqlsrv_malloc( sizeof( sqlsrv_error ))) sqlsrv_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 TSRMLS_CC, print_args );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
core_sqlsrv_get_odbc_error( ctx, 1, error, SEV_ERROR TSRMLS_CC );
|
bool err = core_sqlsrv_get_odbc_error( ctx, 1, error, SEV_ERROR TSRMLS_CC );
|
||||||
|
SQLSRV_ASSERT( err == true, "No ODBC error was found" );
|
||||||
}
|
}
|
||||||
|
|
||||||
SQLSRV_STATIC_ASSERT( sizeof( error->sqlstate ) <= sizeof( dbh->error_code ));
|
SQLSRV_STATIC_ASSERT( sizeof( error->sqlstate ) <= sizeof( dbh->error_code ));
|
||||||
|
@ -474,13 +491,13 @@ bool pdo_sqlsrv_handle_stmt_error( sqlsrv_context& ctx, unsigned int sqlsrv_erro
|
||||||
SQLSRV_ASSERT( pdo_stmt != NULL && pdo_stmt->dbh != NULL, "pdo_sqlsrv_handle_stmt_error: Null statement or dbh passed" );
|
SQLSRV_ASSERT( pdo_stmt != NULL && pdo_stmt->dbh != NULL, "pdo_sqlsrv_handle_stmt_error: Null statement or dbh passed" );
|
||||||
|
|
||||||
sqlsrv_error_auto_ptr error;
|
sqlsrv_error_auto_ptr error;
|
||||||
error = new ( sqlsrv_malloc( sizeof( sqlsrv_error ))) sqlsrv_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 TSRMLS_CC, print_args );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
core_sqlsrv_get_odbc_error( ctx, 1, error, SEV_ERROR TSRMLS_CC );
|
bool err = core_sqlsrv_get_odbc_error( ctx, 1, error, SEV_ERROR TSRMLS_CC );
|
||||||
|
SQLSRV_ASSERT( err == true, "No ODBC error was found" );
|
||||||
}
|
}
|
||||||
|
|
||||||
SQLSRV_STATIC_ASSERT( sizeof( error->sqlstate ) <= sizeof( pdo_stmt->error_code ));
|
SQLSRV_STATIC_ASSERT( sizeof( error->sqlstate ) <= sizeof( pdo_stmt->error_code ));
|
||||||
|
|
3043
pdo_sqlsrv/sqlncli.h
Normal file
3043
pdo_sqlsrv/sqlncli.h
Normal file
|
@ -0,0 +1,3043 @@
|
||||||
|
|
||||||
|
|
||||||
|
/* this ALWAYS GENERATED file contains the definitions for the interfaces */
|
||||||
|
|
||||||
|
|
||||||
|
/* File created by MIDL compiler version 7.00.0474 */
|
||||||
|
/* Compiler settings for sqlncli.idl:
|
||||||
|
Oicf, W1, Zp8, env=Win32 (32b run)
|
||||||
|
protocol : dce , ms_ext, c_ext, robust
|
||||||
|
error checks: allocation ref bounds_check enum stub_data
|
||||||
|
VC __declspec() decoration level:
|
||||||
|
__declspec(uuid()), __declspec(selectany), __declspec(novtable)
|
||||||
|
DECLSPEC_UUID(), MIDL_INTERFACE()
|
||||||
|
*/
|
||||||
|
//@@MIDL_FILE_HEADING( )
|
||||||
|
|
||||||
|
#pragma warning( disable: 4049 ) /* more than 64k source lines */
|
||||||
|
|
||||||
|
|
||||||
|
/* verify that the <rpcndr.h> version is high enough to compile this file*/
|
||||||
|
#ifndef __REQUIRED_RPCNDR_H_VERSION__
|
||||||
|
#define __REQUIRED_RPCNDR_H_VERSION__ 475
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "rpc.h"
|
||||||
|
#include "rpcndr.h"
|
||||||
|
|
||||||
|
#ifndef __RPCNDR_H_VERSION__
|
||||||
|
#error this stub requires an updated version of <rpcndr.h>
|
||||||
|
#endif // __RPCNDR_H_VERSION__
|
||||||
|
|
||||||
|
#ifndef COM_NO_WINDOWS_H
|
||||||
|
#include "windows.h"
|
||||||
|
#include "ole2.h"
|
||||||
|
#endif /*COM_NO_WINDOWS_H*/
|
||||||
|
|
||||||
|
#ifndef __sqlncli_h__
|
||||||
|
#define __sqlncli_h__
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Forward Declarations */
|
||||||
|
|
||||||
|
#ifndef __ICommandWithParameters_FWD_DEFINED__
|
||||||
|
#define __ICommandWithParameters_FWD_DEFINED__
|
||||||
|
typedef interface ICommandWithParameters ICommandWithParameters;
|
||||||
|
#endif /* __ICommandWithParameters_FWD_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __IUMSInitialize_FWD_DEFINED__
|
||||||
|
#define __IUMSInitialize_FWD_DEFINED__
|
||||||
|
typedef interface IUMSInitialize IUMSInitialize;
|
||||||
|
#endif /* __IUMSInitialize_FWD_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __ISQLServerErrorInfo_FWD_DEFINED__
|
||||||
|
#define __ISQLServerErrorInfo_FWD_DEFINED__
|
||||||
|
typedef interface ISQLServerErrorInfo ISQLServerErrorInfo;
|
||||||
|
#endif /* __ISQLServerErrorInfo_FWD_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __IRowsetFastLoad_FWD_DEFINED__
|
||||||
|
#define __IRowsetFastLoad_FWD_DEFINED__
|
||||||
|
typedef interface IRowsetFastLoad IRowsetFastLoad;
|
||||||
|
#endif /* __IRowsetFastLoad_FWD_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __ISchemaLock_FWD_DEFINED__
|
||||||
|
#define __ISchemaLock_FWD_DEFINED__
|
||||||
|
typedef interface ISchemaLock ISchemaLock;
|
||||||
|
#endif /* __ISchemaLock_FWD_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __IBCPSession_FWD_DEFINED__
|
||||||
|
#define __IBCPSession_FWD_DEFINED__
|
||||||
|
typedef interface IBCPSession IBCPSession;
|
||||||
|
#endif /* __IBCPSession_FWD_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __ISSAbort_FWD_DEFINED__
|
||||||
|
#define __ISSAbort_FWD_DEFINED__
|
||||||
|
typedef interface ISSAbort ISSAbort;
|
||||||
|
#endif /* __ISSAbort_FWD_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __ISSCommandWithParameters_FWD_DEFINED__
|
||||||
|
#define __ISSCommandWithParameters_FWD_DEFINED__
|
||||||
|
typedef interface ISSCommandWithParameters ISSCommandWithParameters;
|
||||||
|
#endif /* __ISSCommandWithParameters_FWD_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __IDBAsynchStatus_FWD_DEFINED__
|
||||||
|
#define __IDBAsynchStatus_FWD_DEFINED__
|
||||||
|
typedef interface IDBAsynchStatus IDBAsynchStatus;
|
||||||
|
#endif /* __IDBAsynchStatus_FWD_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __ISSAsynchStatus_FWD_DEFINED__
|
||||||
|
#define __ISSAsynchStatus_FWD_DEFINED__
|
||||||
|
typedef interface ISSAsynchStatus ISSAsynchStatus;
|
||||||
|
#endif /* __ISSAsynchStatus_FWD_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
/* header files for imported files */
|
||||||
|
#include "unknwn.h"
|
||||||
|
#include "oaidl.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* interface __MIDL_itf_sqlncli_0000_0000 */
|
||||||
|
/* [local] */
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// File: sqlncli.h
|
||||||
|
//
|
||||||
|
// Copyright: Copyright (c) Microsoft Corporation
|
||||||
|
//
|
||||||
|
// Contents: SQL Server Native Client OLEDB provider and ODBC driver specific
|
||||||
|
// definitions.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if !defined(SQLNCLI_VER)
|
||||||
|
#define SQLNCLI_VER 1000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SQLNCLI_VER >= 1000
|
||||||
|
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_FULL_VER_ANSI "Microsoft SQL Server Native Client 10.0"
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_FULL_ANSI "Microsoft SQL Server Native Client"
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_SHORT_VER_ANSI "SQL Server Native Client 10.0"
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_SHORT_ANSI "SQL Server Native Client"
|
||||||
|
|
||||||
|
#define SQLNCLI_FILE_NAME_ANSI "sqlncli"
|
||||||
|
#define SQLNCLI_FILE_NAME_VER_ANSI "sqlncli10"
|
||||||
|
#define SQLNCLI_FILE_NAME_FULL_ANSI "sqlncli10.dll"
|
||||||
|
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_FULL_VER_UNICODE L"Microsoft SQL Server Native Client 10.0"
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_FULL_UNICODE L"Microsoft SQL Server Native Client"
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_SHORT_VER_UNICODE L"SQL Server Native Client 10.0"
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_SHORT_UNICODE L"SQL Server Native Client"
|
||||||
|
|
||||||
|
#define SQLNCLI_FILE_NAME_UNICODE L"sqlncli"
|
||||||
|
#define SQLNCLI_FILE_NAME_VER_UNICODE L"sqlncli10"
|
||||||
|
#define SQLNCLI_FILE_NAME_FULL_UNICODE L"sqlncli10.dll"
|
||||||
|
|
||||||
|
#if defined(_SQLNCLI_OLEDB_) || !defined(_SQLNCLI_ODBC_)
|
||||||
|
|
||||||
|
#define SQLNCLI_VI_PROG_ID_ANSI "SQLNCLI10"
|
||||||
|
#define SQLNCLI_VI_ERROR_LOOKUP_PROG_ID_ANSI "SQLNCLI10 ErrorLookup"
|
||||||
|
#define SQLNCLI_VI_ENUMERATOR_PROG_ID_ANSI "SQLNCLI10 Enumerator"
|
||||||
|
|
||||||
|
#define SQLNCLI_PROG_ID_ANSI "SQLNCLI10.1"
|
||||||
|
#define SQLNCLI_ERROR_LOOKUP_PROG_ID_ANSI "SQLNCLI10 ErrorLookup.1"
|
||||||
|
#define SQLNCLI_ENUMERATOR_PROG_ID_ANSI "SQLNCLI10 Enumerator.1"
|
||||||
|
|
||||||
|
#define SQLNCLI_VI_PROG_ID_UNICODE L"SQLNCLI10"
|
||||||
|
#define SQLNCLI_VI_ERROR_LOOKUP_PROG_ID_UNICODE L"SQLNCLI10 ErrorLookup"
|
||||||
|
#define SQLNCLI_VI_ENUMERATOR_PROG_ID_UNICODE L"SQLNCLI10 Enumerator"
|
||||||
|
|
||||||
|
#define SQLNCLI_PROG_ID_UNICODE L"SQLNCLI10.1"
|
||||||
|
#define SQLNCLI_ERROR_LOOKUP_PROG_ID_UNICODE L"SQLNCLI10 ErrorLookup.1"
|
||||||
|
#define SQLNCLI_ENUMERATOR_PROG_ID_UNICODE L"SQLNCLI10 Enumerator.1"
|
||||||
|
|
||||||
|
#define SQLNCLI_CLSID CLSID_SQLNCLI10
|
||||||
|
#define SQLNCLI_ERROR_CLSID CLSID_SQLNCLI10_ERROR
|
||||||
|
#define SQLNCLI_ENUMERATOR_CLSID CLSID_SQLNCLI10_ENUMERATOR
|
||||||
|
|
||||||
|
#endif // defined(_SQLNCLI_OLEDB_) || !defined(_SQLNCLI_ODBC_)
|
||||||
|
|
||||||
|
#else // SQLNCLI_VER >= 1000
|
||||||
|
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_FULL_VER_ANSI "Microsoft SQL Server Native Client"
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_FULL_ANSI "Microsoft SQL Server Native Client"
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_SHORT_VER_ANSI "SQL Native Client"
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_SHORT_ANSI "SQL Native Client"
|
||||||
|
|
||||||
|
#define SQLNCLI_FILE_NAME_ANSI "sqlncli"
|
||||||
|
#define SQLNCLI_FILE_NAME_VER_ANSI "sqlncli"
|
||||||
|
#define SQLNCLI_FILE_NAME_FULL_ANSI "sqlncli.dll"
|
||||||
|
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_FULL_VER_UNICODE L"Microsoft SQL Server Native Client"
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_FULL_UNICODE L"Microsoft SQL Server Native Client"
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_SHORT_VER_UNICODE L"SQL Native Client"
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_SHORT_UNICODE L"SQL Native Client"
|
||||||
|
|
||||||
|
#define SQLNCLI_FILE_NAME_UNICODE L"sqlncli"
|
||||||
|
#define SQLNCLI_FILE_NAME_VER_UNICODE L"sqlncli"
|
||||||
|
#define SQLNCLI_FILE_NAME_FULL_UNICODE L"sqlncli.dll"
|
||||||
|
|
||||||
|
#if defined(_SQLNCLI_OLEDB_) || !defined(_SQLNCLI_ODBC_)
|
||||||
|
|
||||||
|
#define SQLNCLI_VI_PROG_ID_ANSI "SQLNCLI"
|
||||||
|
#define SQLNCLI_VI_ERROR_LOOKUP_PROG_ID_ANSI "SQLNCLI ErrorLookup"
|
||||||
|
#define SQLNCLI_VI_ENUMERATOR_PROG_ID_ANSI "SQLNCLI Enumerator"
|
||||||
|
|
||||||
|
#define SQLNCLI_PROG_ID_ANSI "SQLNCLI.1"
|
||||||
|
#define SQLNCLI_ERROR_LOOKUP_PROG_ID_ANSI "SQLNCLI ErrorLookup.1"
|
||||||
|
#define SQLNCLI_ENUMERATOR_PROG_ID_ANSI "SQLNCLI Enumerator.1"
|
||||||
|
|
||||||
|
#define SQLNCLI_VI_PROG_ID_UNICODE L"SQLNCLI"
|
||||||
|
#define SQLNCLI_VI_ERROR_LOOKUP_PROG_ID_UNICODE L"SQLNCLI ErrorLookup"
|
||||||
|
#define SQLNCLI_VI_ENUMERATOR_PROG_ID_UNICODE L"SQLNCLI Enumerator"
|
||||||
|
|
||||||
|
#define SQLNCLI_PROG_ID_UNICODE L"SQLNCLI.1"
|
||||||
|
#define SQLNCLI_ERROR_LOOKUP_PROG_ID_UNICODE L"SQLNCLI ErrorLookup.1"
|
||||||
|
#define SQLNCLI_ENUMERATOR_PROG_ID_UNICODE L"SQLNCLI Enumerator.1"
|
||||||
|
|
||||||
|
#define SQLNCLI_CLSID CLSID_SQLNCLI
|
||||||
|
#define SQLNCLI_ERROR_CLSID CLSID_SQLNCLI_ERROR
|
||||||
|
#define SQLNCLI_ENUMERATOR_CLSID CLSID_SQLNCLI_ENUMERATOR
|
||||||
|
|
||||||
|
#endif // defined(_SQLNCLI_OLEDB_) || !defined(_SQLNCLI_ODBC_)
|
||||||
|
|
||||||
|
#endif // SQLNCLI_VER >= 1000
|
||||||
|
|
||||||
|
// define the character type agnostic constants
|
||||||
|
#if defined(_UNICODE) || defined(UNICODE)
|
||||||
|
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_FULL_VER SQLNCLI_PRODUCT_NAME_FULL_VER_UNICODE
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_FULL SQLNCLI_PRODUCT_NAME_FULL_UNICODE
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_SHORT_VER SQLNCLI_PRODUCT_NAME_SHORT_VER_UNICODE
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_SHORT SQLNCLI_PRODUCT_NAME_SHORT_UNICODE
|
||||||
|
|
||||||
|
#define SQLNCLI_FILE_NAME SQLNCLI_FILE_NAME_UNICODE
|
||||||
|
#define SQLNCLI_FILE_NAME_VER SQLNCLI_FILE_NAME_VER_UNICODE
|
||||||
|
#define SQLNCLI_FILE_NAME_FULL SQLNCLI_FILE_NAME_FULL_UNICODE
|
||||||
|
|
||||||
|
#if defined(_SQLNCLI_OLEDB_) || !defined(_SQLNCLI_ODBC_)
|
||||||
|
|
||||||
|
#define SQLNCLI_VI_PROG_ID SQLNCLI_VI_PROG_ID_UNICODE
|
||||||
|
#define SQLNCLI_VI_ERROR_LOOKUP_PROG_ID SQLNCLI_VI_ERROR_LOOKUP_PROG_ID_UNICODE
|
||||||
|
#define SQLNCLI_VI_ENUMERATOR_PROG_ID SQLNCLI_VI_ENUMERATOR_PROG_ID_UNICODE
|
||||||
|
|
||||||
|
#define SQLNCLI_PROG_ID SQLNCLI_PROG_ID_UNICODE
|
||||||
|
#define SQLNCLI_ERROR_LOOKUP_PROG_ID SQLNCLI_ERROR_LOOKUP_PROG_ID_UNICODE
|
||||||
|
#define SQLNCLI_ENUMERATOR_PROG_ID SQLNCLI_ENUMERATOR_PROG_ID_UNICODE
|
||||||
|
|
||||||
|
#endif // defined(_SQLNCLI_OLEDB_) || !defined(_SQLNCLI_ODBC_)
|
||||||
|
|
||||||
|
#else // _UNICODE || UNICODE
|
||||||
|
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_FULL_VER SQLNCLI_PRODUCT_NAME_FULL_VER_ANSI
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_FULL SQLNCLI_PRODUCT_NAME_FULL_ANSI
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_SHORT_VER SQLNCLI_PRODUCT_NAME_SHORT_VER_ANSI
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_SHORT SQLNCLI_PRODUCT_NAME_SHORT_ANSI
|
||||||
|
|
||||||
|
#define SQLNCLI_FILE_NAME SQLNCLI_FILE_NAME_ANSI
|
||||||
|
#define SQLNCLI_FILE_NAME_VER SQLNCLI_FILE_NAME_VER_ANSI
|
||||||
|
#define SQLNCLI_FILE_NAME_FULL SQLNCLI_FILE_NAME_FULL_ANSI
|
||||||
|
|
||||||
|
#if defined(_SQLNCLI_OLEDB_) || !defined(_SQLNCLI_ODBC_)
|
||||||
|
|
||||||
|
#define SQLNCLI_VI_PROG_ID SQLNCLI_VI_PROG_ID_ANSI
|
||||||
|
#define SQLNCLI_VI_ERROR_LOOKUP_PROG_ID SQLNCLI_VI_ERROR_LOOKUP_PROG_ID_ANSI
|
||||||
|
#define SQLNCLI_VI_ENUMERATOR_PROG_ID SQLNCLI_VI_ENUMERATOR_PROG_ID_ANSI
|
||||||
|
|
||||||
|
#define SQLNCLI_PROG_ID SQLNCLI_PROG_ID_ANSI
|
||||||
|
#define SQLNCLI_ERROR_LOOKUP_PROG_ID SQLNCLI_ERROR_LOOKUP_PROG_ID_ANSI
|
||||||
|
#define SQLNCLI_ENUMERATOR_PROG_ID SQLNCLI_ENUMERATOR_PROG_ID_ANSI
|
||||||
|
|
||||||
|
#endif // defined(_SQLNCLI_OLEDB_) || !defined(_SQLNCLI_ODBC_)
|
||||||
|
|
||||||
|
#endif // _UNICODE || UNICODE
|
||||||
|
|
||||||
|
#if defined(_SQLNCLI_ODBC_) || !defined(_SQLNCLI_OLEDB_)
|
||||||
|
|
||||||
|
#define SQLNCLI_DRIVER_NAME SQLNCLI_PRODUCT_NAME_SHORT_VER
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// OLEDB part of SQL Server Native Client header - begin here
|
||||||
|
#if defined(_SQLNCLI_OLEDB_) || !defined(_SQLNCLI_ODBC_)
|
||||||
|
#ifndef __oledb_h__
|
||||||
|
#include <oledb.h>
|
||||||
|
#endif /*__oledb_h__*/
|
||||||
|
|
||||||
|
#if 0 // This is already defined in oledb.h
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
|
||||||
|
// Length of a non-character object, size
|
||||||
|
typedef ULONGLONG DBLENGTH;
|
||||||
|
|
||||||
|
// Offset within a rowset
|
||||||
|
typedef LONGLONG DBROWOFFSET;
|
||||||
|
|
||||||
|
// Number of rows
|
||||||
|
typedef LONGLONG DBROWCOUNT;
|
||||||
|
|
||||||
|
typedef ULONGLONG DBCOUNTITEM;
|
||||||
|
|
||||||
|
// Ordinal (column number, etc.)
|
||||||
|
typedef ULONGLONG DBORDINAL;
|
||||||
|
|
||||||
|
typedef LONGLONG DB_LORDINAL;
|
||||||
|
|
||||||
|
// Bookmarks
|
||||||
|
typedef ULONGLONG DBBKMARK;
|
||||||
|
// Offset in the buffer
|
||||||
|
|
||||||
|
typedef ULONGLONG DBBYTEOFFSET;
|
||||||
|
// Reference count of each row/accessor handle
|
||||||
|
|
||||||
|
typedef ULONG DBREFCOUNT;
|
||||||
|
|
||||||
|
// Parameters
|
||||||
|
typedef ULONGLONG DB_UPARAMS;
|
||||||
|
|
||||||
|
typedef LONGLONG DB_LPARAMS;
|
||||||
|
|
||||||
|
// hash values corresponding to the elements (bookmarks)
|
||||||
|
typedef DWORDLONG DBHASHVALUE;
|
||||||
|
|
||||||
|
// For reserve
|
||||||
|
typedef DWORDLONG DB_DWRESERVE;
|
||||||
|
|
||||||
|
typedef LONGLONG DB_LRESERVE;
|
||||||
|
|
||||||
|
typedef ULONGLONG DB_URESERVE;
|
||||||
|
|
||||||
|
#else //_WIN64
|
||||||
|
|
||||||
|
// Length of a non-character object, size
|
||||||
|
typedef ULONG DBLENGTH;
|
||||||
|
|
||||||
|
// Offset within a rowset
|
||||||
|
typedef LONG DBROWOFFSET;
|
||||||
|
|
||||||
|
// Number of rows
|
||||||
|
typedef LONG DBROWCOUNT;
|
||||||
|
|
||||||
|
typedef ULONG DBCOUNTITEM;
|
||||||
|
|
||||||
|
// Ordinal (column number, etc.)
|
||||||
|
typedef ULONG DBORDINAL;
|
||||||
|
|
||||||
|
typedef LONG DB_LORDINAL;
|
||||||
|
|
||||||
|
// Bookmarks
|
||||||
|
typedef ULONG DBBKMARK;
|
||||||
|
|
||||||
|
// Offset in the buffer
|
||||||
|
typedef ULONG DBBYTEOFFSET;
|
||||||
|
|
||||||
|
// Reference count of each row handle
|
||||||
|
typedef ULONG DBREFCOUNT;
|
||||||
|
|
||||||
|
// Parameters
|
||||||
|
typedef ULONG DB_UPARAMS;
|
||||||
|
|
||||||
|
typedef LONG DB_LPARAMS;
|
||||||
|
|
||||||
|
// hash values corresponding to the elements (bookmarks)
|
||||||
|
typedef DWORD DBHASHVALUE;
|
||||||
|
|
||||||
|
// For reserve
|
||||||
|
typedef DWORD DB_DWRESERVE;
|
||||||
|
|
||||||
|
typedef LONG DB_LRESERVE;
|
||||||
|
|
||||||
|
typedef ULONG DB_URESERVE;
|
||||||
|
|
||||||
|
#endif // _WIN64
|
||||||
|
typedef DWORD DBKIND;
|
||||||
|
|
||||||
|
|
||||||
|
enum DBKINDENUM
|
||||||
|
{ DBKIND_GUID_NAME = 0,
|
||||||
|
DBKIND_GUID_PROPID = ( DBKIND_GUID_NAME + 1 ) ,
|
||||||
|
DBKIND_NAME = ( DBKIND_GUID_PROPID + 1 ) ,
|
||||||
|
DBKIND_PGUID_NAME = ( DBKIND_NAME + 1 ) ,
|
||||||
|
DBKIND_PGUID_PROPID = ( DBKIND_PGUID_NAME + 1 ) ,
|
||||||
|
DBKIND_PROPID = ( DBKIND_PGUID_PROPID + 1 ) ,
|
||||||
|
DBKIND_GUID = ( DBKIND_PROPID + 1 )
|
||||||
|
} ;
|
||||||
|
typedef struct tagDBID
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
GUID guid;
|
||||||
|
GUID *pguid;
|
||||||
|
/* Empty union arm */
|
||||||
|
} uGuid;
|
||||||
|
DBKIND eKind;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
LPOLESTR pwszName;
|
||||||
|
ULONG ulPropid;
|
||||||
|
/* Empty union arm */
|
||||||
|
} uName;
|
||||||
|
} DBID;
|
||||||
|
|
||||||
|
typedef struct tagDB_NUMERIC
|
||||||
|
{
|
||||||
|
BYTE precision;
|
||||||
|
BYTE scale;
|
||||||
|
BYTE sign;
|
||||||
|
BYTE val[ 16 ];
|
||||||
|
} DB_NUMERIC;
|
||||||
|
|
||||||
|
typedef struct tagDBDATE
|
||||||
|
{
|
||||||
|
SHORT year;
|
||||||
|
USHORT month;
|
||||||
|
USHORT day;
|
||||||
|
} DBDATE;
|
||||||
|
|
||||||
|
typedef struct tagDBTIME
|
||||||
|
{
|
||||||
|
USHORT hour;
|
||||||
|
USHORT minute;
|
||||||
|
USHORT second;
|
||||||
|
} DBTIME;
|
||||||
|
|
||||||
|
typedef struct tagDBTIMESTAMP
|
||||||
|
{
|
||||||
|
SHORT year;
|
||||||
|
USHORT month;
|
||||||
|
USHORT day;
|
||||||
|
USHORT hour;
|
||||||
|
USHORT minute;
|
||||||
|
USHORT second;
|
||||||
|
ULONG fraction;
|
||||||
|
} DBTIMESTAMP;
|
||||||
|
|
||||||
|
typedef struct tagDBOBJECT
|
||||||
|
{
|
||||||
|
DWORD dwFlags;
|
||||||
|
IID iid;
|
||||||
|
} DBOBJECT;
|
||||||
|
|
||||||
|
typedef WORD DBTYPE;
|
||||||
|
|
||||||
|
typedef ULONG_PTR HACCESSOR;
|
||||||
|
|
||||||
|
typedef ULONG_PTR HCHAPTER;
|
||||||
|
|
||||||
|
typedef DWORD DBPARAMFLAGS;
|
||||||
|
|
||||||
|
typedef struct tagDBPARAMINFO
|
||||||
|
{
|
||||||
|
DBPARAMFLAGS dwFlags;
|
||||||
|
DBORDINAL iOrdinal;
|
||||||
|
LPOLESTR pwszName;
|
||||||
|
ITypeInfo *pTypeInfo;
|
||||||
|
DBLENGTH ulParamSize;
|
||||||
|
DBTYPE wType;
|
||||||
|
BYTE bPrecision;
|
||||||
|
BYTE bScale;
|
||||||
|
} DBPARAMINFO;
|
||||||
|
|
||||||
|
typedef DWORD DBPROPID;
|
||||||
|
|
||||||
|
typedef struct tagDBPROPIDSET
|
||||||
|
{
|
||||||
|
DBPROPID *rgPropertyIDs;
|
||||||
|
ULONG cPropertyIDs;
|
||||||
|
GUID guidPropertySet;
|
||||||
|
} DBPROPIDSET;
|
||||||
|
|
||||||
|
typedef DWORD DBPROPFLAGS;
|
||||||
|
|
||||||
|
typedef DWORD DBPROPOPTIONS;
|
||||||
|
|
||||||
|
typedef DWORD DBPROPSTATUS;
|
||||||
|
|
||||||
|
typedef struct tagDBPROP
|
||||||
|
{
|
||||||
|
DBPROPID dwPropertyID;
|
||||||
|
DBPROPOPTIONS dwOptions;
|
||||||
|
DBPROPSTATUS dwStatus;
|
||||||
|
DBID colid;
|
||||||
|
VARIANT vValue;
|
||||||
|
} DBPROP;
|
||||||
|
|
||||||
|
typedef struct tagDBPROPSET
|
||||||
|
{
|
||||||
|
DBPROP *rgProperties;
|
||||||
|
ULONG cProperties;
|
||||||
|
GUID guidPropertySet;
|
||||||
|
} DBPROPSET;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern RPC_IF_HANDLE __MIDL_itf_sqlncli_0000_0000_v0_0_c_ifspec;
|
||||||
|
extern RPC_IF_HANDLE __MIDL_itf_sqlncli_0000_0000_v0_0_s_ifspec;
|
||||||
|
|
||||||
|
#ifndef __ICommandWithParameters_INTERFACE_DEFINED__
|
||||||
|
#define __ICommandWithParameters_INTERFACE_DEFINED__
|
||||||
|
|
||||||
|
/* interface ICommandWithParameters */
|
||||||
|
/* [unique][uuid][object][local] */
|
||||||
|
|
||||||
|
typedef struct tagDBPARAMBINDINFO
|
||||||
|
{
|
||||||
|
LPOLESTR pwszDataSourceType;
|
||||||
|
LPOLESTR pwszName;
|
||||||
|
DBLENGTH ulParamSize;
|
||||||
|
DBPARAMFLAGS dwFlags;
|
||||||
|
BYTE bPrecision;
|
||||||
|
BYTE bScale;
|
||||||
|
} DBPARAMBINDINFO;
|
||||||
|
|
||||||
|
|
||||||
|
EXTERN_C const IID IID_ICommandWithParameters;
|
||||||
|
|
||||||
|
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||||
|
|
||||||
|
MIDL_INTERFACE("0c733a64-2a1c-11ce-ade5-00aa0044773d")
|
||||||
|
ICommandWithParameters : public IUnknown
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetParameterInfo(
|
||||||
|
/* [out][in] */ DB_UPARAMS *pcParams,
|
||||||
|
/* [size_is][size_is][out] */ DBPARAMINFO **prgParamInfo,
|
||||||
|
/* [out] */ OLECHAR **ppNamesBuffer) = 0;
|
||||||
|
|
||||||
|
virtual /* [local] */ HRESULT STDMETHODCALLTYPE MapParameterNames(
|
||||||
|
/* [in] */ DB_UPARAMS cParamNames,
|
||||||
|
/* [size_is][in] */ const OLECHAR *rgParamNames[ ],
|
||||||
|
/* [size_is][out] */ DB_LPARAMS rgParamOrdinals[ ]) = 0;
|
||||||
|
|
||||||
|
virtual /* [local] */ HRESULT STDMETHODCALLTYPE SetParameterInfo(
|
||||||
|
/* [in] */ DB_UPARAMS cParams,
|
||||||
|
/* [size_is][unique][in] */ const DB_UPARAMS rgParamOrdinals[ ],
|
||||||
|
/* [size_is][unique][in] */ const DBPARAMBINDINFO rgParamBindInfo[ ]) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#else /* C style interface */
|
||||||
|
|
||||||
|
typedef struct ICommandWithParametersVtbl
|
||||||
|
{
|
||||||
|
BEGIN_INTERFACE
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||||
|
ICommandWithParameters * This,
|
||||||
|
/* [in] */ REFIID riid,
|
||||||
|
/* [iid_is][out] */
|
||||||
|
__RPC__deref_out void **ppvObject);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||||
|
ICommandWithParameters * This);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||||
|
ICommandWithParameters * This);
|
||||||
|
|
||||||
|
/* [local] */ HRESULT ( STDMETHODCALLTYPE *GetParameterInfo )(
|
||||||
|
ICommandWithParameters * This,
|
||||||
|
/* [out][in] */ DB_UPARAMS *pcParams,
|
||||||
|
/* [size_is][size_is][out] */ DBPARAMINFO **prgParamInfo,
|
||||||
|
/* [out] */ OLECHAR **ppNamesBuffer);
|
||||||
|
|
||||||
|
/* [local] */ HRESULT ( STDMETHODCALLTYPE *MapParameterNames )(
|
||||||
|
ICommandWithParameters * This,
|
||||||
|
/* [in] */ DB_UPARAMS cParamNames,
|
||||||
|
/* [size_is][in] */ const OLECHAR *rgParamNames[ ],
|
||||||
|
/* [size_is][out] */ DB_LPARAMS rgParamOrdinals[ ]);
|
||||||
|
|
||||||
|
/* [local] */ HRESULT ( STDMETHODCALLTYPE *SetParameterInfo )(
|
||||||
|
ICommandWithParameters * This,
|
||||||
|
/* [in] */ DB_UPARAMS cParams,
|
||||||
|
/* [size_is][unique][in] */ const DB_UPARAMS rgParamOrdinals[ ],
|
||||||
|
/* [size_is][unique][in] */ const DBPARAMBINDINFO rgParamBindInfo[ ]);
|
||||||
|
|
||||||
|
END_INTERFACE
|
||||||
|
} ICommandWithParametersVtbl;
|
||||||
|
|
||||||
|
interface ICommandWithParameters
|
||||||
|
{
|
||||||
|
CONST_VTBL struct ICommandWithParametersVtbl *lpVtbl;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef COBJMACROS
|
||||||
|
|
||||||
|
|
||||||
|
#define ICommandWithParameters_QueryInterface(This,riid,ppvObject) \
|
||||||
|
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
|
||||||
|
|
||||||
|
#define ICommandWithParameters_AddRef(This) \
|
||||||
|
( (This)->lpVtbl -> AddRef(This) )
|
||||||
|
|
||||||
|
#define ICommandWithParameters_Release(This) \
|
||||||
|
( (This)->lpVtbl -> Release(This) )
|
||||||
|
|
||||||
|
|
||||||
|
#define ICommandWithParameters_GetParameterInfo(This,pcParams,prgParamInfo,ppNamesBuffer) \
|
||||||
|
( (This)->lpVtbl -> GetParameterInfo(This,pcParams,prgParamInfo,ppNamesBuffer) )
|
||||||
|
|
||||||
|
#define ICommandWithParameters_MapParameterNames(This,cParamNames,rgParamNames,rgParamOrdinals) \
|
||||||
|
( (This)->lpVtbl -> MapParameterNames(This,cParamNames,rgParamNames,rgParamOrdinals) )
|
||||||
|
|
||||||
|
#define ICommandWithParameters_SetParameterInfo(This,cParams,rgParamOrdinals,rgParamBindInfo) \
|
||||||
|
( (This)->lpVtbl -> SetParameterInfo(This,cParams,rgParamOrdinals,rgParamBindInfo) )
|
||||||
|
|
||||||
|
#endif /* COBJMACROS */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* C style interface */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* [call_as] */ HRESULT STDMETHODCALLTYPE ICommandWithParameters_RemoteGetParameterInfo_Proxy(
|
||||||
|
ICommandWithParameters * This,
|
||||||
|
/* [out][in] */ DB_UPARAMS *pcParams,
|
||||||
|
/* [size_is][size_is][out] */ DBPARAMINFO **prgParamInfo,
|
||||||
|
/* [size_is][size_is][out] */ DBBYTEOFFSET **prgNameOffsets,
|
||||||
|
/* [out][in] */ DBLENGTH *pcbNamesBuffer,
|
||||||
|
/* [size_is][size_is][unique][out][in] */ OLECHAR **ppNamesBuffer,
|
||||||
|
/* [out] */ IErrorInfo **ppErrorInfoRem);
|
||||||
|
|
||||||
|
|
||||||
|
void __RPC_STUB ICommandWithParameters_RemoteGetParameterInfo_Stub(
|
||||||
|
IRpcStubBuffer *This,
|
||||||
|
IRpcChannelBuffer *_pRpcChannelBuffer,
|
||||||
|
PRPC_MESSAGE _pRpcMessage,
|
||||||
|
DWORD *_pdwStubPhase);
|
||||||
|
|
||||||
|
|
||||||
|
/* [call_as] */ HRESULT STDMETHODCALLTYPE ICommandWithParameters_RemoteMapParameterNames_Proxy(
|
||||||
|
ICommandWithParameters * This,
|
||||||
|
/* [in] */ DB_UPARAMS cParamNames,
|
||||||
|
/* [size_is][in] */ LPCOLESTR *rgParamNames,
|
||||||
|
/* [size_is][out] */ DB_LPARAMS *rgParamOrdinals,
|
||||||
|
/* [out] */ IErrorInfo **ppErrorInfoRem);
|
||||||
|
|
||||||
|
|
||||||
|
void __RPC_STUB ICommandWithParameters_RemoteMapParameterNames_Stub(
|
||||||
|
IRpcStubBuffer *This,
|
||||||
|
IRpcChannelBuffer *_pRpcChannelBuffer,
|
||||||
|
PRPC_MESSAGE _pRpcMessage,
|
||||||
|
DWORD *_pdwStubPhase);
|
||||||
|
|
||||||
|
|
||||||
|
/* [call_as] */ HRESULT STDMETHODCALLTYPE ICommandWithParameters_RemoteSetParameterInfo_Proxy(
|
||||||
|
ICommandWithParameters * This,
|
||||||
|
/* [in] */ DB_UPARAMS cParams,
|
||||||
|
/* [size_is][unique][in] */ const DB_UPARAMS *rgParamOrdinals,
|
||||||
|
/* [size_is][unique][in] */ const DBPARAMBINDINFO *rgParamBindInfo,
|
||||||
|
/* [out] */ IErrorInfo **ppErrorInfoRem);
|
||||||
|
|
||||||
|
|
||||||
|
void __RPC_STUB ICommandWithParameters_RemoteSetParameterInfo_Stub(
|
||||||
|
IRpcStubBuffer *This,
|
||||||
|
IRpcChannelBuffer *_pRpcChannelBuffer,
|
||||||
|
PRPC_MESSAGE _pRpcMessage,
|
||||||
|
DWORD *_pdwStubPhase);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __ICommandWithParameters_INTERFACE_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
/* interface __MIDL_itf_sqlncli_0000_0001 */
|
||||||
|
/* [local] */
|
||||||
|
|
||||||
|
typedef DWORD DBASYNCHOP;
|
||||||
|
|
||||||
|
typedef DWORD DBASYNCHPHASE;
|
||||||
|
|
||||||
|
#endif // This is already defined in oledb.h
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Variant Access macros, similar to ole automation.
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
#define V_SS_VT(X) ((X)->vt)
|
||||||
|
#define V_SS_UNION(X, Y) ((X)->Y)
|
||||||
|
|
||||||
|
#define V_SS_UI1(X) V_SS_UNION(X, bTinyIntVal)
|
||||||
|
#define V_SS_I2(X) V_SS_UNION(X, sShortIntVal)
|
||||||
|
#define V_SS_I4(X) V_SS_UNION(X, lIntVal)
|
||||||
|
#define V_SS_I8(X) V_SS_UNION(X, llBigIntVal)
|
||||||
|
|
||||||
|
#define V_SS_R4(X) V_SS_UNION(X, fltRealVal)
|
||||||
|
#define V_SS_R8(X) V_SS_UNION(X, dblFloatVal)
|
||||||
|
#define V_SS_UI4(X) V_SS_UNION(X, ulVal)
|
||||||
|
|
||||||
|
#define V_SS_MONEY(X) V_SS_UNION(X, cyMoneyVal)
|
||||||
|
#define V_SS_SMALLMONEY(X) V_SS_UNION(X, cyMoneyVal)
|
||||||
|
|
||||||
|
#define V_SS_WSTRING(X) V_SS_UNION(X, NCharVal)
|
||||||
|
#define V_SS_WVARSTRING(X) V_SS_UNION(X, NCharVal)
|
||||||
|
|
||||||
|
#define V_SS_STRING(X) V_SS_UNION(X, CharVal)
|
||||||
|
#define V_SS_VARSTRING(X) V_SS_UNION(X, CharVal)
|
||||||
|
|
||||||
|
#define V_SS_BIT(X) V_SS_UNION(X, fBitVal)
|
||||||
|
#define V_SS_GUID(X) V_SS_UNION(X, rgbGuidVal)
|
||||||
|
|
||||||
|
#define V_SS_NUMERIC(X) V_SS_UNION(X, numNumericVal)
|
||||||
|
#define V_SS_DECIMAL(X) V_SS_UNION(X, numNumericVal)
|
||||||
|
|
||||||
|
#define V_SS_BINARY(X) V_SS_UNION(X, BinaryVal)
|
||||||
|
#define V_SS_VARBINARY(X) V_SS_UNION(X, BinaryVal)
|
||||||
|
|
||||||
|
#define V_SS_DATETIME(X) V_SS_UNION(X, tsDateTimeVal)
|
||||||
|
#define V_SS_SMALLDATETIME(X) V_SS_UNION(X, tsDateTimeVal)
|
||||||
|
|
||||||
|
#define V_SS_UNKNOWN(X) V_SS_UNION(X, UnknownType)
|
||||||
|
|
||||||
|
//Text and image types.
|
||||||
|
#define V_SS_IMAGE(X) V_SS_UNION(X, ImageVal)
|
||||||
|
#define V_SS_TEXT(X) V_SS_UNION(X, TextVal)
|
||||||
|
#define V_SS_NTEXT(X) V_SS_UNION(X, NTextVal)
|
||||||
|
|
||||||
|
//Microsoft SQL Server 2008 datetime.
|
||||||
|
#define V_SS_DATE(X) V_SS_UNION(X, dDateVal)
|
||||||
|
#define V_SS_TIME2(X) V_SS_UNION(X, Time2Val)
|
||||||
|
#define V_SS_DATETIME2(X) V_SS_UNION(X, DateTimeVal)
|
||||||
|
#define V_SS_DATETIMEOFFSET(X) V_SS_UNION(X, DateTimeOffsetVal)
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// define SQL Server specific types.
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
typedef enum DBTYPEENUM EOledbTypes;
|
||||||
|
#define DBTYPE_XML ((EOledbTypes) 141) // introduced in SQL 2005
|
||||||
|
#define DBTYPE_TABLE ((EOledbTypes) 143) // introduced in SQL 2008
|
||||||
|
#define DBTYPE_DBTIME2 ((EOledbTypes) 145) // introduced in SQL 2008
|
||||||
|
#define DBTYPE_DBTIMESTAMPOFFSET ((EOledbTypes) 146) // introduced in SQL 2008
|
||||||
|
#ifdef _SQLOLEDB_H_
|
||||||
|
#undef DBTYPE_SQLVARIANT
|
||||||
|
#endif //_SQLOLEDB_H_
|
||||||
|
#define DBTYPE_SQLVARIANT ((EOledbTypes) 144) // introduced in MDAC 2.5
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _SQLOLEDB_H_
|
||||||
|
enum SQLVARENUM
|
||||||
|
{
|
||||||
|
VT_SS_EMPTY = DBTYPE_EMPTY,
|
||||||
|
VT_SS_NULL = DBTYPE_NULL,
|
||||||
|
VT_SS_UI1 = DBTYPE_UI1,
|
||||||
|
VT_SS_I2 = DBTYPE_I2,
|
||||||
|
VT_SS_I4 = DBTYPE_I4,
|
||||||
|
VT_SS_I8 = DBTYPE_I8,
|
||||||
|
|
||||||
|
//Floats
|
||||||
|
VT_SS_R4 = DBTYPE_R4,
|
||||||
|
VT_SS_R8 = DBTYPE_R8,
|
||||||
|
|
||||||
|
//Money
|
||||||
|
VT_SS_MONEY = DBTYPE_CY,
|
||||||
|
VT_SS_SMALLMONEY = 200,
|
||||||
|
|
||||||
|
//Strings
|
||||||
|
VT_SS_WSTRING = 201,
|
||||||
|
VT_SS_WVARSTRING = 202,
|
||||||
|
|
||||||
|
VT_SS_STRING = 203,
|
||||||
|
VT_SS_VARSTRING = 204,
|
||||||
|
|
||||||
|
//Bit
|
||||||
|
VT_SS_BIT = DBTYPE_BOOL,
|
||||||
|
|
||||||
|
//Guid
|
||||||
|
VT_SS_GUID = DBTYPE_GUID,
|
||||||
|
|
||||||
|
//Exact precision
|
||||||
|
VT_SS_NUMERIC = DBTYPE_NUMERIC,
|
||||||
|
VT_SS_DECIMAL = 205,
|
||||||
|
|
||||||
|
//Datetime
|
||||||
|
VT_SS_DATETIME = DBTYPE_DBTIMESTAMP,
|
||||||
|
VT_SS_SMALLDATETIME =206,
|
||||||
|
|
||||||
|
//Binary
|
||||||
|
VT_SS_BINARY =207,
|
||||||
|
VT_SS_VARBINARY = 208,
|
||||||
|
//Future
|
||||||
|
VT_SS_UNKNOWN = 209,
|
||||||
|
|
||||||
|
//Additional datetime
|
||||||
|
VT_SS_DATE = DBTYPE_DBDATE,
|
||||||
|
VT_SS_TIME2 = DBTYPE_DBTIME2,
|
||||||
|
VT_SS_DATETIME2 = 212,
|
||||||
|
VT_SS_DATETIMEOFFSET = DBTYPE_DBTIMESTAMPOFFSET,
|
||||||
|
};
|
||||||
|
typedef unsigned short SSVARTYPE;
|
||||||
|
|
||||||
|
|
||||||
|
enum DBPARAMFLAGSENUM_SS_100
|
||||||
|
{ DBPARAMFLAGS_SS_ISVARIABLESCALE = 0x40000000
|
||||||
|
} ;
|
||||||
|
enum DBCOLUMNFLAGSENUM_SS_100
|
||||||
|
{ DBCOLUMNFLAGS_SS_ISVARIABLESCALE = 0x40000000,
|
||||||
|
DBCOLUMNFLAGS_SS_ISCOLUMNSET = 0x80000000
|
||||||
|
} ;
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Class Factory Interface used to initialize pointer to UMS.
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
extern RPC_IF_HANDLE __MIDL_itf_sqlncli_0000_0001_v0_0_c_ifspec;
|
||||||
|
extern RPC_IF_HANDLE __MIDL_itf_sqlncli_0000_0001_v0_0_s_ifspec;
|
||||||
|
|
||||||
|
#ifndef __IUMSInitialize_INTERFACE_DEFINED__
|
||||||
|
#define __IUMSInitialize_INTERFACE_DEFINED__
|
||||||
|
|
||||||
|
/* interface IUMSInitialize */
|
||||||
|
/* [unique][uuid][object][local] */
|
||||||
|
|
||||||
|
|
||||||
|
EXTERN_C const IID IID_IUMSInitialize;
|
||||||
|
|
||||||
|
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||||
|
|
||||||
|
MIDL_INTERFACE("5cf4ca14-ef21-11d0-97e7-00c04fc2ad98")
|
||||||
|
IUMSInitialize : public IUnknown
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE Initialize(
|
||||||
|
/* [in] */ void *pUMS) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#else /* C style interface */
|
||||||
|
|
||||||
|
typedef struct IUMSInitializeVtbl
|
||||||
|
{
|
||||||
|
BEGIN_INTERFACE
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||||
|
IUMSInitialize * This,
|
||||||
|
/* [in] */ REFIID riid,
|
||||||
|
/* [iid_is][out] */
|
||||||
|
__RPC__deref_out void **ppvObject);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||||
|
IUMSInitialize * This);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||||
|
IUMSInitialize * This);
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *Initialize )(
|
||||||
|
IUMSInitialize * This,
|
||||||
|
/* [in] */ void *pUMS);
|
||||||
|
|
||||||
|
END_INTERFACE
|
||||||
|
} IUMSInitializeVtbl;
|
||||||
|
|
||||||
|
interface IUMSInitialize
|
||||||
|
{
|
||||||
|
CONST_VTBL struct IUMSInitializeVtbl *lpVtbl;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef COBJMACROS
|
||||||
|
|
||||||
|
|
||||||
|
#define IUMSInitialize_QueryInterface(This,riid,ppvObject) \
|
||||||
|
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
|
||||||
|
|
||||||
|
#define IUMSInitialize_AddRef(This) \
|
||||||
|
( (This)->lpVtbl -> AddRef(This) )
|
||||||
|
|
||||||
|
#define IUMSInitialize_Release(This) \
|
||||||
|
( (This)->lpVtbl -> Release(This) )
|
||||||
|
|
||||||
|
|
||||||
|
#define IUMSInitialize_Initialize(This,pUMS) \
|
||||||
|
( (This)->lpVtbl -> Initialize(This,pUMS) )
|
||||||
|
|
||||||
|
#endif /* COBJMACROS */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* C style interface */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __IUMSInitialize_INTERFACE_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
/* interface __MIDL_itf_sqlncli_0000_0002 */
|
||||||
|
/* [local] */
|
||||||
|
|
||||||
|
|
||||||
|
// the structure returned by ISQLServerErrorInfo::GetSQLServerInfo
|
||||||
|
typedef struct tagSSErrorInfo
|
||||||
|
{
|
||||||
|
LPOLESTR pwszMessage;
|
||||||
|
LPOLESTR pwszServer;
|
||||||
|
LPOLESTR pwszProcedure;
|
||||||
|
LONG lNative;
|
||||||
|
BYTE bState;
|
||||||
|
BYTE bClass;
|
||||||
|
WORD wLineNumber;
|
||||||
|
} SSERRORINFO;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern RPC_IF_HANDLE __MIDL_itf_sqlncli_0000_0002_v0_0_c_ifspec;
|
||||||
|
extern RPC_IF_HANDLE __MIDL_itf_sqlncli_0000_0002_v0_0_s_ifspec;
|
||||||
|
|
||||||
|
#ifndef __ISQLServerErrorInfo_INTERFACE_DEFINED__
|
||||||
|
#define __ISQLServerErrorInfo_INTERFACE_DEFINED__
|
||||||
|
|
||||||
|
/* interface ISQLServerErrorInfo */
|
||||||
|
/* [unique][uuid][object][local] */
|
||||||
|
|
||||||
|
|
||||||
|
EXTERN_C const IID IID_ISQLServerErrorInfo;
|
||||||
|
|
||||||
|
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||||
|
|
||||||
|
MIDL_INTERFACE("5CF4CA12-EF21-11d0-97E7-00C04FC2AD98")
|
||||||
|
ISQLServerErrorInfo : public IUnknown
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE GetErrorInfo(
|
||||||
|
/* [out] */ SSERRORINFO **ppErrorInfo,
|
||||||
|
/* [out] */ OLECHAR **ppStringsBuffer) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#else /* C style interface */
|
||||||
|
|
||||||
|
typedef struct ISQLServerErrorInfoVtbl
|
||||||
|
{
|
||||||
|
BEGIN_INTERFACE
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||||
|
ISQLServerErrorInfo * This,
|
||||||
|
/* [in] */ REFIID riid,
|
||||||
|
/* [iid_is][out] */
|
||||||
|
__RPC__deref_out void **ppvObject);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||||
|
ISQLServerErrorInfo * This);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||||
|
ISQLServerErrorInfo * This);
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *GetErrorInfo )(
|
||||||
|
ISQLServerErrorInfo * This,
|
||||||
|
/* [out] */ SSERRORINFO **ppErrorInfo,
|
||||||
|
/* [out] */ OLECHAR **ppStringsBuffer);
|
||||||
|
|
||||||
|
END_INTERFACE
|
||||||
|
} ISQLServerErrorInfoVtbl;
|
||||||
|
|
||||||
|
interface ISQLServerErrorInfo
|
||||||
|
{
|
||||||
|
CONST_VTBL struct ISQLServerErrorInfoVtbl *lpVtbl;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef COBJMACROS
|
||||||
|
|
||||||
|
|
||||||
|
#define ISQLServerErrorInfo_QueryInterface(This,riid,ppvObject) \
|
||||||
|
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
|
||||||
|
|
||||||
|
#define ISQLServerErrorInfo_AddRef(This) \
|
||||||
|
( (This)->lpVtbl -> AddRef(This) )
|
||||||
|
|
||||||
|
#define ISQLServerErrorInfo_Release(This) \
|
||||||
|
( (This)->lpVtbl -> Release(This) )
|
||||||
|
|
||||||
|
|
||||||
|
#define ISQLServerErrorInfo_GetErrorInfo(This,ppErrorInfo,ppStringsBuffer) \
|
||||||
|
( (This)->lpVtbl -> GetErrorInfo(This,ppErrorInfo,ppStringsBuffer) )
|
||||||
|
|
||||||
|
#endif /* COBJMACROS */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* C style interface */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __ISQLServerErrorInfo_INTERFACE_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __IRowsetFastLoad_INTERFACE_DEFINED__
|
||||||
|
#define __IRowsetFastLoad_INTERFACE_DEFINED__
|
||||||
|
|
||||||
|
/* interface IRowsetFastLoad */
|
||||||
|
/* [unique][uuid][object][local] */
|
||||||
|
|
||||||
|
|
||||||
|
EXTERN_C const IID IID_IRowsetFastLoad;
|
||||||
|
|
||||||
|
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||||
|
|
||||||
|
MIDL_INTERFACE("5CF4CA13-EF21-11d0-97E7-00C04FC2AD98")
|
||||||
|
IRowsetFastLoad : public IUnknown
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE InsertRow(
|
||||||
|
/* [in] */ HACCESSOR hAccessor,
|
||||||
|
/* [in] */ void *pData) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE Commit(
|
||||||
|
/* [in] */ BOOL fDone) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#else /* C style interface */
|
||||||
|
|
||||||
|
typedef struct IRowsetFastLoadVtbl
|
||||||
|
{
|
||||||
|
BEGIN_INTERFACE
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||||
|
IRowsetFastLoad * This,
|
||||||
|
/* [in] */ REFIID riid,
|
||||||
|
/* [iid_is][out] */
|
||||||
|
__RPC__deref_out void **ppvObject);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||||
|
IRowsetFastLoad * This);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||||
|
IRowsetFastLoad * This);
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *InsertRow )(
|
||||||
|
IRowsetFastLoad * This,
|
||||||
|
/* [in] */ HACCESSOR hAccessor,
|
||||||
|
/* [in] */ void *pData);
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *Commit )(
|
||||||
|
IRowsetFastLoad * This,
|
||||||
|
/* [in] */ BOOL fDone);
|
||||||
|
|
||||||
|
END_INTERFACE
|
||||||
|
} IRowsetFastLoadVtbl;
|
||||||
|
|
||||||
|
interface IRowsetFastLoad
|
||||||
|
{
|
||||||
|
CONST_VTBL struct IRowsetFastLoadVtbl *lpVtbl;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef COBJMACROS
|
||||||
|
|
||||||
|
|
||||||
|
#define IRowsetFastLoad_QueryInterface(This,riid,ppvObject) \
|
||||||
|
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
|
||||||
|
|
||||||
|
#define IRowsetFastLoad_AddRef(This) \
|
||||||
|
( (This)->lpVtbl -> AddRef(This) )
|
||||||
|
|
||||||
|
#define IRowsetFastLoad_Release(This) \
|
||||||
|
( (This)->lpVtbl -> Release(This) )
|
||||||
|
|
||||||
|
|
||||||
|
#define IRowsetFastLoad_InsertRow(This,hAccessor,pData) \
|
||||||
|
( (This)->lpVtbl -> InsertRow(This,hAccessor,pData) )
|
||||||
|
|
||||||
|
#define IRowsetFastLoad_Commit(This,fDone) \
|
||||||
|
( (This)->lpVtbl -> Commit(This,fDone) )
|
||||||
|
|
||||||
|
#endif /* COBJMACROS */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* C style interface */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __IRowsetFastLoad_INTERFACE_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
/* interface __MIDL_itf_sqlncli_0000_0004 */
|
||||||
|
/* [local] */
|
||||||
|
|
||||||
|
#include <pshpack8.h> // 8-byte structure packing
|
||||||
|
|
||||||
|
typedef struct tagDBTIME2
|
||||||
|
{
|
||||||
|
USHORT hour;
|
||||||
|
USHORT minute;
|
||||||
|
USHORT second;
|
||||||
|
ULONG fraction;
|
||||||
|
} DBTIME2;
|
||||||
|
|
||||||
|
typedef struct tagDBTIMESTAMPOFFSET
|
||||||
|
{
|
||||||
|
SHORT year;
|
||||||
|
USHORT month;
|
||||||
|
USHORT day;
|
||||||
|
USHORT hour;
|
||||||
|
USHORT minute;
|
||||||
|
USHORT second;
|
||||||
|
ULONG fraction;
|
||||||
|
SHORT timezone_hour;
|
||||||
|
SHORT timezone_minute;
|
||||||
|
} DBTIMESTAMPOFFSET;
|
||||||
|
|
||||||
|
#include <poppack.h> // restore original structure packing
|
||||||
|
|
||||||
|
struct SSVARIANT
|
||||||
|
{
|
||||||
|
SSVARTYPE vt;
|
||||||
|
DWORD dwReserved1;
|
||||||
|
DWORD dwReserved2;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
BYTE bTinyIntVal;
|
||||||
|
SHORT sShortIntVal;
|
||||||
|
LONG lIntVal;
|
||||||
|
LONGLONG llBigIntVal;
|
||||||
|
FLOAT fltRealVal;
|
||||||
|
DOUBLE dblFloatVal;
|
||||||
|
CY cyMoneyVal;
|
||||||
|
VARIANT_BOOL fBitVal;
|
||||||
|
BYTE rgbGuidVal[ 16 ];
|
||||||
|
DB_NUMERIC numNumericVal;
|
||||||
|
DBDATE dDateVal;
|
||||||
|
DBTIMESTAMP tsDateTimeVal;
|
||||||
|
struct _Time2Val
|
||||||
|
{
|
||||||
|
DBTIME2 tTime2Val;
|
||||||
|
BYTE bScale;
|
||||||
|
} Time2Val;
|
||||||
|
struct _DateTimeVal
|
||||||
|
{
|
||||||
|
DBTIMESTAMP tsDateTimeVal;
|
||||||
|
BYTE bScale;
|
||||||
|
} DateTimeVal;
|
||||||
|
struct _DateTimeOffsetVal
|
||||||
|
{
|
||||||
|
DBTIMESTAMPOFFSET tsoDateTimeOffsetVal;
|
||||||
|
BYTE bScale;
|
||||||
|
} DateTimeOffsetVal;
|
||||||
|
struct _NCharVal
|
||||||
|
{
|
||||||
|
SHORT sActualLength;
|
||||||
|
SHORT sMaxLength;
|
||||||
|
WCHAR *pwchNCharVal;
|
||||||
|
BYTE rgbReserved[ 5 ];
|
||||||
|
DWORD dwReserved;
|
||||||
|
WCHAR *pwchReserved;
|
||||||
|
} NCharVal;
|
||||||
|
struct _CharVal
|
||||||
|
{
|
||||||
|
SHORT sActualLength;
|
||||||
|
SHORT sMaxLength;
|
||||||
|
CHAR *pchCharVal;
|
||||||
|
BYTE rgbReserved[ 5 ];
|
||||||
|
DWORD dwReserved;
|
||||||
|
WCHAR *pwchReserved;
|
||||||
|
} CharVal;
|
||||||
|
struct _BinaryVal
|
||||||
|
{
|
||||||
|
SHORT sActualLength;
|
||||||
|
SHORT sMaxLength;
|
||||||
|
BYTE *prgbBinaryVal;
|
||||||
|
DWORD dwReserved;
|
||||||
|
} BinaryVal;
|
||||||
|
struct _UnknownType
|
||||||
|
{
|
||||||
|
DWORD dwActualLength;
|
||||||
|
BYTE rgMetadata[ 16 ];
|
||||||
|
BYTE *pUnknownData;
|
||||||
|
} UnknownType;
|
||||||
|
struct _BLOBType
|
||||||
|
{
|
||||||
|
DBOBJECT dbobj;
|
||||||
|
IUnknown *pUnk;
|
||||||
|
} BLOBType;
|
||||||
|
} ;
|
||||||
|
} ;
|
||||||
|
typedef DWORD LOCKMODE;
|
||||||
|
|
||||||
|
|
||||||
|
enum LOCKMODEENUM
|
||||||
|
{ LOCKMODE_INVALID = 0,
|
||||||
|
LOCKMODE_EXCLUSIVE = ( LOCKMODE_INVALID + 1 ) ,
|
||||||
|
LOCKMODE_SHARED = ( LOCKMODE_EXCLUSIVE + 1 )
|
||||||
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
extern RPC_IF_HANDLE __MIDL_itf_sqlncli_0000_0004_v0_0_c_ifspec;
|
||||||
|
extern RPC_IF_HANDLE __MIDL_itf_sqlncli_0000_0004_v0_0_s_ifspec;
|
||||||
|
|
||||||
|
#ifndef __ISchemaLock_INTERFACE_DEFINED__
|
||||||
|
#define __ISchemaLock_INTERFACE_DEFINED__
|
||||||
|
|
||||||
|
/* interface ISchemaLock */
|
||||||
|
/* [unique][uuid][object][local] */
|
||||||
|
|
||||||
|
|
||||||
|
EXTERN_C const IID IID_ISchemaLock;
|
||||||
|
|
||||||
|
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||||
|
|
||||||
|
MIDL_INTERFACE("4C2389FB-2511-11d4-B258-00C04F7971CE")
|
||||||
|
ISchemaLock : public IUnknown
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE GetSchemaLock(
|
||||||
|
/* [in] */ DBID *pTableID,
|
||||||
|
/* [in] */ LOCKMODE lmMode,
|
||||||
|
/* [out] */ HANDLE *phLockHandle,
|
||||||
|
/* [out] */ ULONGLONG *pTableVersion) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE ReleaseSchemaLock(
|
||||||
|
/* [in] */ HANDLE hLockHandle) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#else /* C style interface */
|
||||||
|
|
||||||
|
typedef struct ISchemaLockVtbl
|
||||||
|
{
|
||||||
|
BEGIN_INTERFACE
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||||
|
ISchemaLock * This,
|
||||||
|
/* [in] */ REFIID riid,
|
||||||
|
/* [iid_is][out] */
|
||||||
|
__RPC__deref_out void **ppvObject);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||||
|
ISchemaLock * This);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||||
|
ISchemaLock * This);
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *GetSchemaLock )(
|
||||||
|
ISchemaLock * This,
|
||||||
|
/* [in] */ DBID *pTableID,
|
||||||
|
/* [in] */ LOCKMODE lmMode,
|
||||||
|
/* [out] */ HANDLE *phLockHandle,
|
||||||
|
/* [out] */ ULONGLONG *pTableVersion);
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *ReleaseSchemaLock )(
|
||||||
|
ISchemaLock * This,
|
||||||
|
/* [in] */ HANDLE hLockHandle);
|
||||||
|
|
||||||
|
END_INTERFACE
|
||||||
|
} ISchemaLockVtbl;
|
||||||
|
|
||||||
|
interface ISchemaLock
|
||||||
|
{
|
||||||
|
CONST_VTBL struct ISchemaLockVtbl *lpVtbl;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef COBJMACROS
|
||||||
|
|
||||||
|
|
||||||
|
#define ISchemaLock_QueryInterface(This,riid,ppvObject) \
|
||||||
|
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
|
||||||
|
|
||||||
|
#define ISchemaLock_AddRef(This) \
|
||||||
|
( (This)->lpVtbl -> AddRef(This) )
|
||||||
|
|
||||||
|
#define ISchemaLock_Release(This) \
|
||||||
|
( (This)->lpVtbl -> Release(This) )
|
||||||
|
|
||||||
|
|
||||||
|
#define ISchemaLock_GetSchemaLock(This,pTableID,lmMode,phLockHandle,pTableVersion) \
|
||||||
|
( (This)->lpVtbl -> GetSchemaLock(This,pTableID,lmMode,phLockHandle,pTableVersion) )
|
||||||
|
|
||||||
|
#define ISchemaLock_ReleaseSchemaLock(This,hLockHandle) \
|
||||||
|
( (This)->lpVtbl -> ReleaseSchemaLock(This,hLockHandle) )
|
||||||
|
|
||||||
|
#endif /* COBJMACROS */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* C style interface */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __ISchemaLock_INTERFACE_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __IBCPSession_INTERFACE_DEFINED__
|
||||||
|
#define __IBCPSession_INTERFACE_DEFINED__
|
||||||
|
|
||||||
|
/* interface IBCPSession */
|
||||||
|
/* [unique][uuid][object][local] */
|
||||||
|
|
||||||
|
|
||||||
|
EXTERN_C const IID IID_IBCPSession;
|
||||||
|
|
||||||
|
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||||
|
|
||||||
|
MIDL_INTERFACE("88352D80-42D1-42f0-A170-AB0F8B45B939")
|
||||||
|
IBCPSession : public IUnknown
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE BCPColFmt(
|
||||||
|
/* [in] */ DBORDINAL idxUserDataCol,
|
||||||
|
/* [in] */ int eUserDataType,
|
||||||
|
/* [in] */ int cbIndicator,
|
||||||
|
/* [in] */ int cbUserData,
|
||||||
|
/* [size_is][in] */ BYTE *pbUserDataTerm,
|
||||||
|
/* [in] */ int cbUserDataTerm,
|
||||||
|
/* [in] */ DBORDINAL idxServerCol) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE BCPColumns(
|
||||||
|
/* [in] */ DBCOUNTITEM nColumns) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE BCPControl(
|
||||||
|
/* [in] */ int eOption,
|
||||||
|
/* [in] */ void *iValue) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE BCPDone( void) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE BCPExec(
|
||||||
|
/* [out] */ DBROWCOUNT *pRowsCopied) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE BCPInit(
|
||||||
|
/* [string][in] */ const wchar_t *pwszTable,
|
||||||
|
/* [string][in] */ const wchar_t *pwszDataFile,
|
||||||
|
/* [string][in] */ const wchar_t *pwszErrorFile,
|
||||||
|
/* [in] */ int eDirection) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE BCPReadFmt(
|
||||||
|
/* [string][in] */ const wchar_t *pwszFormatFile) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE BCPWriteFmt(
|
||||||
|
/* [string][in] */ const wchar_t *pwszFormatFile) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#else /* C style interface */
|
||||||
|
|
||||||
|
typedef struct IBCPSessionVtbl
|
||||||
|
{
|
||||||
|
BEGIN_INTERFACE
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||||
|
IBCPSession * This,
|
||||||
|
/* [in] */ REFIID riid,
|
||||||
|
/* [iid_is][out] */
|
||||||
|
__RPC__deref_out void **ppvObject);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||||
|
IBCPSession * This);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||||
|
IBCPSession * This);
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *BCPColFmt )(
|
||||||
|
IBCPSession * This,
|
||||||
|
/* [in] */ DBORDINAL idxUserDataCol,
|
||||||
|
/* [in] */ int eUserDataType,
|
||||||
|
/* [in] */ int cbIndicator,
|
||||||
|
/* [in] */ int cbUserData,
|
||||||
|
/* [size_is][in] */ BYTE *pbUserDataTerm,
|
||||||
|
/* [in] */ int cbUserDataTerm,
|
||||||
|
/* [in] */ DBORDINAL idxServerCol);
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *BCPColumns )(
|
||||||
|
IBCPSession * This,
|
||||||
|
/* [in] */ DBCOUNTITEM nColumns);
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *BCPControl )(
|
||||||
|
IBCPSession * This,
|
||||||
|
/* [in] */ int eOption,
|
||||||
|
/* [in] */ void *iValue);
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *BCPDone )(
|
||||||
|
IBCPSession * This);
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *BCPExec )(
|
||||||
|
IBCPSession * This,
|
||||||
|
/* [out] */ DBROWCOUNT *pRowsCopied);
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *BCPInit )(
|
||||||
|
IBCPSession * This,
|
||||||
|
/* [string][in] */ const wchar_t *pwszTable,
|
||||||
|
/* [string][in] */ const wchar_t *pwszDataFile,
|
||||||
|
/* [string][in] */ const wchar_t *pwszErrorFile,
|
||||||
|
/* [in] */ int eDirection);
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *BCPReadFmt )(
|
||||||
|
IBCPSession * This,
|
||||||
|
/* [string][in] */ const wchar_t *pwszFormatFile);
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *BCPWriteFmt )(
|
||||||
|
IBCPSession * This,
|
||||||
|
/* [string][in] */ const wchar_t *pwszFormatFile);
|
||||||
|
|
||||||
|
END_INTERFACE
|
||||||
|
} IBCPSessionVtbl;
|
||||||
|
|
||||||
|
interface IBCPSession
|
||||||
|
{
|
||||||
|
CONST_VTBL struct IBCPSessionVtbl *lpVtbl;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef COBJMACROS
|
||||||
|
|
||||||
|
|
||||||
|
#define IBCPSession_QueryInterface(This,riid,ppvObject) \
|
||||||
|
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
|
||||||
|
|
||||||
|
#define IBCPSession_AddRef(This) \
|
||||||
|
( (This)->lpVtbl -> AddRef(This) )
|
||||||
|
|
||||||
|
#define IBCPSession_Release(This) \
|
||||||
|
( (This)->lpVtbl -> Release(This) )
|
||||||
|
|
||||||
|
|
||||||
|
#define IBCPSession_BCPColFmt(This,idxUserDataCol,eUserDataType,cbIndicator,cbUserData,pbUserDataTerm,cbUserDataTerm,idxServerCol) \
|
||||||
|
( (This)->lpVtbl -> BCPColFmt(This,idxUserDataCol,eUserDataType,cbIndicator,cbUserData,pbUserDataTerm,cbUserDataTerm,idxServerCol) )
|
||||||
|
|
||||||
|
#define IBCPSession_BCPColumns(This,nColumns) \
|
||||||
|
( (This)->lpVtbl -> BCPColumns(This,nColumns) )
|
||||||
|
|
||||||
|
#define IBCPSession_BCPControl(This,eOption,iValue) \
|
||||||
|
( (This)->lpVtbl -> BCPControl(This,eOption,iValue) )
|
||||||
|
|
||||||
|
#define IBCPSession_BCPDone(This) \
|
||||||
|
( (This)->lpVtbl -> BCPDone(This) )
|
||||||
|
|
||||||
|
#define IBCPSession_BCPExec(This,pRowsCopied) \
|
||||||
|
( (This)->lpVtbl -> BCPExec(This,pRowsCopied) )
|
||||||
|
|
||||||
|
#define IBCPSession_BCPInit(This,pwszTable,pwszDataFile,pwszErrorFile,eDirection) \
|
||||||
|
( (This)->lpVtbl -> BCPInit(This,pwszTable,pwszDataFile,pwszErrorFile,eDirection) )
|
||||||
|
|
||||||
|
#define IBCPSession_BCPReadFmt(This,pwszFormatFile) \
|
||||||
|
( (This)->lpVtbl -> BCPReadFmt(This,pwszFormatFile) )
|
||||||
|
|
||||||
|
#define IBCPSession_BCPWriteFmt(This,pwszFormatFile) \
|
||||||
|
( (This)->lpVtbl -> BCPWriteFmt(This,pwszFormatFile) )
|
||||||
|
|
||||||
|
#endif /* COBJMACROS */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* C style interface */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __IBCPSession_INTERFACE_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
/* interface __MIDL_itf_sqlncli_0000_0006 */
|
||||||
|
/* [local] */
|
||||||
|
|
||||||
|
|
||||||
|
#endif //_SQLOLEDB_H_
|
||||||
|
|
||||||
|
#define ISOLATIONLEVEL_SNAPSHOT ((ISOLATIONLEVEL)(0x01000000)) // Changes made in other transactions can not be seen.
|
||||||
|
|
||||||
|
#define DBPROPVAL_TI_SNAPSHOT 0x01000000L
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern RPC_IF_HANDLE __MIDL_itf_sqlncli_0000_0006_v0_0_c_ifspec;
|
||||||
|
extern RPC_IF_HANDLE __MIDL_itf_sqlncli_0000_0006_v0_0_s_ifspec;
|
||||||
|
|
||||||
|
#ifndef __ISSAbort_INTERFACE_DEFINED__
|
||||||
|
#define __ISSAbort_INTERFACE_DEFINED__
|
||||||
|
|
||||||
|
/* interface ISSAbort */
|
||||||
|
/* [unique][uuid][object][local] */
|
||||||
|
|
||||||
|
|
||||||
|
EXTERN_C const IID IID_ISSAbort;
|
||||||
|
|
||||||
|
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||||
|
|
||||||
|
MIDL_INTERFACE("5CF4CA15-EF21-11d0-97E7-00C04FC2AD98")
|
||||||
|
ISSAbort : public IUnknown
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE Abort( void) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#else /* C style interface */
|
||||||
|
|
||||||
|
typedef struct ISSAbortVtbl
|
||||||
|
{
|
||||||
|
BEGIN_INTERFACE
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||||
|
ISSAbort * This,
|
||||||
|
/* [in] */ REFIID riid,
|
||||||
|
/* [iid_is][out] */
|
||||||
|
__RPC__deref_out void **ppvObject);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||||
|
ISSAbort * This);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||||
|
ISSAbort * This);
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *Abort )(
|
||||||
|
ISSAbort * This);
|
||||||
|
|
||||||
|
END_INTERFACE
|
||||||
|
} ISSAbortVtbl;
|
||||||
|
|
||||||
|
interface ISSAbort
|
||||||
|
{
|
||||||
|
CONST_VTBL struct ISSAbortVtbl *lpVtbl;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef COBJMACROS
|
||||||
|
|
||||||
|
|
||||||
|
#define ISSAbort_QueryInterface(This,riid,ppvObject) \
|
||||||
|
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
|
||||||
|
|
||||||
|
#define ISSAbort_AddRef(This) \
|
||||||
|
( (This)->lpVtbl -> AddRef(This) )
|
||||||
|
|
||||||
|
#define ISSAbort_Release(This) \
|
||||||
|
( (This)->lpVtbl -> Release(This) )
|
||||||
|
|
||||||
|
|
||||||
|
#define ISSAbort_Abort(This) \
|
||||||
|
( (This)->lpVtbl -> Abort(This) )
|
||||||
|
|
||||||
|
#endif /* COBJMACROS */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* C style interface */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __ISSAbort_INTERFACE_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
/* interface __MIDL_itf_sqlncli_0000_0007 */
|
||||||
|
/* [local] */
|
||||||
|
|
||||||
|
|
||||||
|
enum DBBINDFLAGENUM90
|
||||||
|
{ DBBINDFLAG_OBJECT = 0x2
|
||||||
|
} ;
|
||||||
|
|
||||||
|
enum SSACCESSORFLAGS
|
||||||
|
{ SSACCESSOR_ROWDATA = 0x100
|
||||||
|
} ;
|
||||||
|
|
||||||
|
enum DBPROPFLAGSENUM90
|
||||||
|
{ DBPROPFLAGS_PARAMETER = 0x10000
|
||||||
|
} ;
|
||||||
|
typedef struct tagSSPARAMPROPS
|
||||||
|
{
|
||||||
|
DBORDINAL iOrdinal;
|
||||||
|
ULONG cPropertySets;
|
||||||
|
DBPROPSET *rgPropertySets;
|
||||||
|
} SSPARAMPROPS;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern RPC_IF_HANDLE __MIDL_itf_sqlncli_0000_0007_v0_0_c_ifspec;
|
||||||
|
extern RPC_IF_HANDLE __MIDL_itf_sqlncli_0000_0007_v0_0_s_ifspec;
|
||||||
|
|
||||||
|
#ifndef __ISSCommandWithParameters_INTERFACE_DEFINED__
|
||||||
|
#define __ISSCommandWithParameters_INTERFACE_DEFINED__
|
||||||
|
|
||||||
|
/* interface ISSCommandWithParameters */
|
||||||
|
/* [unique][uuid][object][local] */
|
||||||
|
|
||||||
|
|
||||||
|
EXTERN_C const IID IID_ISSCommandWithParameters;
|
||||||
|
|
||||||
|
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||||
|
|
||||||
|
MIDL_INTERFACE("eec30162-6087-467c-b995-7c523ce96561")
|
||||||
|
ISSCommandWithParameters : public ICommandWithParameters
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetParameterProperties(
|
||||||
|
/* [out][in] */ DB_UPARAMS *pcParams,
|
||||||
|
/* [size_is][size_is][out] */ SSPARAMPROPS **prgParamProperties) = 0;
|
||||||
|
|
||||||
|
virtual /* [local] */ HRESULT STDMETHODCALLTYPE SetParameterProperties(
|
||||||
|
/* [in] */ DB_UPARAMS cParams,
|
||||||
|
/* [size_is][unique][in] */ SSPARAMPROPS rgParamProperties[ ]) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#else /* C style interface */
|
||||||
|
|
||||||
|
typedef struct ISSCommandWithParametersVtbl
|
||||||
|
{
|
||||||
|
BEGIN_INTERFACE
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||||
|
ISSCommandWithParameters * This,
|
||||||
|
/* [in] */ REFIID riid,
|
||||||
|
/* [iid_is][out] */
|
||||||
|
__RPC__deref_out void **ppvObject);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||||
|
ISSCommandWithParameters * This);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||||
|
ISSCommandWithParameters * This);
|
||||||
|
|
||||||
|
/* [local] */ HRESULT ( STDMETHODCALLTYPE *GetParameterInfo )(
|
||||||
|
ISSCommandWithParameters * This,
|
||||||
|
/* [out][in] */ DB_UPARAMS *pcParams,
|
||||||
|
/* [size_is][size_is][out] */ DBPARAMINFO **prgParamInfo,
|
||||||
|
/* [out] */ OLECHAR **ppNamesBuffer);
|
||||||
|
|
||||||
|
/* [local] */ HRESULT ( STDMETHODCALLTYPE *MapParameterNames )(
|
||||||
|
ISSCommandWithParameters * This,
|
||||||
|
/* [in] */ DB_UPARAMS cParamNames,
|
||||||
|
/* [size_is][in] */ const OLECHAR *rgParamNames[ ],
|
||||||
|
/* [size_is][out] */ DB_LPARAMS rgParamOrdinals[ ]);
|
||||||
|
|
||||||
|
/* [local] */ HRESULT ( STDMETHODCALLTYPE *SetParameterInfo )(
|
||||||
|
ISSCommandWithParameters * This,
|
||||||
|
/* [in] */ DB_UPARAMS cParams,
|
||||||
|
/* [size_is][unique][in] */ const DB_UPARAMS rgParamOrdinals[ ],
|
||||||
|
/* [size_is][unique][in] */ const DBPARAMBINDINFO rgParamBindInfo[ ]);
|
||||||
|
|
||||||
|
/* [local] */ HRESULT ( STDMETHODCALLTYPE *GetParameterProperties )(
|
||||||
|
ISSCommandWithParameters * This,
|
||||||
|
/* [out][in] */ DB_UPARAMS *pcParams,
|
||||||
|
/* [size_is][size_is][out] */ SSPARAMPROPS **prgParamProperties);
|
||||||
|
|
||||||
|
/* [local] */ HRESULT ( STDMETHODCALLTYPE *SetParameterProperties )(
|
||||||
|
ISSCommandWithParameters * This,
|
||||||
|
/* [in] */ DB_UPARAMS cParams,
|
||||||
|
/* [size_is][unique][in] */ SSPARAMPROPS rgParamProperties[ ]);
|
||||||
|
|
||||||
|
END_INTERFACE
|
||||||
|
} ISSCommandWithParametersVtbl;
|
||||||
|
|
||||||
|
interface ISSCommandWithParameters
|
||||||
|
{
|
||||||
|
CONST_VTBL struct ISSCommandWithParametersVtbl *lpVtbl;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef COBJMACROS
|
||||||
|
|
||||||
|
|
||||||
|
#define ISSCommandWithParameters_QueryInterface(This,riid,ppvObject) \
|
||||||
|
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
|
||||||
|
|
||||||
|
#define ISSCommandWithParameters_AddRef(This) \
|
||||||
|
( (This)->lpVtbl -> AddRef(This) )
|
||||||
|
|
||||||
|
#define ISSCommandWithParameters_Release(This) \
|
||||||
|
( (This)->lpVtbl -> Release(This) )
|
||||||
|
|
||||||
|
|
||||||
|
#define ISSCommandWithParameters_GetParameterInfo(This,pcParams,prgParamInfo,ppNamesBuffer) \
|
||||||
|
( (This)->lpVtbl -> GetParameterInfo(This,pcParams,prgParamInfo,ppNamesBuffer) )
|
||||||
|
|
||||||
|
#define ISSCommandWithParameters_MapParameterNames(This,cParamNames,rgParamNames,rgParamOrdinals) \
|
||||||
|
( (This)->lpVtbl -> MapParameterNames(This,cParamNames,rgParamNames,rgParamOrdinals) )
|
||||||
|
|
||||||
|
#define ISSCommandWithParameters_SetParameterInfo(This,cParams,rgParamOrdinals,rgParamBindInfo) \
|
||||||
|
( (This)->lpVtbl -> SetParameterInfo(This,cParams,rgParamOrdinals,rgParamBindInfo) )
|
||||||
|
|
||||||
|
|
||||||
|
#define ISSCommandWithParameters_GetParameterProperties(This,pcParams,prgParamProperties) \
|
||||||
|
( (This)->lpVtbl -> GetParameterProperties(This,pcParams,prgParamProperties) )
|
||||||
|
|
||||||
|
#define ISSCommandWithParameters_SetParameterProperties(This,cParams,rgParamProperties) \
|
||||||
|
( (This)->lpVtbl -> SetParameterProperties(This,cParams,rgParamProperties) )
|
||||||
|
|
||||||
|
#endif /* COBJMACROS */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* C style interface */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __ISSCommandWithParameters_INTERFACE_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __IDBAsynchStatus_INTERFACE_DEFINED__
|
||||||
|
#define __IDBAsynchStatus_INTERFACE_DEFINED__
|
||||||
|
|
||||||
|
/* interface IDBAsynchStatus */
|
||||||
|
/* [unique][uuid][object][local] */
|
||||||
|
|
||||||
|
|
||||||
|
EXTERN_C const IID IID_IDBAsynchStatus;
|
||||||
|
|
||||||
|
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||||
|
|
||||||
|
MIDL_INTERFACE("0c733a95-2a1c-11ce-ade5-00aa0044773d")
|
||||||
|
IDBAsynchStatus : public IUnknown
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual /* [local] */ HRESULT STDMETHODCALLTYPE Abort(
|
||||||
|
/* [in] */ HCHAPTER hChapter,
|
||||||
|
/* [in] */ DBASYNCHOP eOperation) = 0;
|
||||||
|
|
||||||
|
virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetStatus(
|
||||||
|
/* [in] */ HCHAPTER hChapter,
|
||||||
|
/* [in] */ DBASYNCHOP eOperation,
|
||||||
|
/* [out] */ DBCOUNTITEM *pulProgress,
|
||||||
|
/* [out] */ DBCOUNTITEM *pulProgressMax,
|
||||||
|
/* [out] */ DBASYNCHPHASE *peAsynchPhase,
|
||||||
|
/* [out] */ LPOLESTR *ppwszStatusText) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#else /* C style interface */
|
||||||
|
|
||||||
|
typedef struct IDBAsynchStatusVtbl
|
||||||
|
{
|
||||||
|
BEGIN_INTERFACE
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||||
|
IDBAsynchStatus * This,
|
||||||
|
/* [in] */ REFIID riid,
|
||||||
|
/* [iid_is][out] */
|
||||||
|
__RPC__deref_out void **ppvObject);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||||
|
IDBAsynchStatus * This);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||||
|
IDBAsynchStatus * This);
|
||||||
|
|
||||||
|
/* [local] */ HRESULT ( STDMETHODCALLTYPE *Abort )(
|
||||||
|
IDBAsynchStatus * This,
|
||||||
|
/* [in] */ HCHAPTER hChapter,
|
||||||
|
/* [in] */ DBASYNCHOP eOperation);
|
||||||
|
|
||||||
|
/* [local] */ HRESULT ( STDMETHODCALLTYPE *GetStatus )(
|
||||||
|
IDBAsynchStatus * This,
|
||||||
|
/* [in] */ HCHAPTER hChapter,
|
||||||
|
/* [in] */ DBASYNCHOP eOperation,
|
||||||
|
/* [out] */ DBCOUNTITEM *pulProgress,
|
||||||
|
/* [out] */ DBCOUNTITEM *pulProgressMax,
|
||||||
|
/* [out] */ DBASYNCHPHASE *peAsynchPhase,
|
||||||
|
/* [out] */ LPOLESTR *ppwszStatusText);
|
||||||
|
|
||||||
|
END_INTERFACE
|
||||||
|
} IDBAsynchStatusVtbl;
|
||||||
|
|
||||||
|
interface IDBAsynchStatus
|
||||||
|
{
|
||||||
|
CONST_VTBL struct IDBAsynchStatusVtbl *lpVtbl;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef COBJMACROS
|
||||||
|
|
||||||
|
|
||||||
|
#define IDBAsynchStatus_QueryInterface(This,riid,ppvObject) \
|
||||||
|
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
|
||||||
|
|
||||||
|
#define IDBAsynchStatus_AddRef(This) \
|
||||||
|
( (This)->lpVtbl -> AddRef(This) )
|
||||||
|
|
||||||
|
#define IDBAsynchStatus_Release(This) \
|
||||||
|
( (This)->lpVtbl -> Release(This) )
|
||||||
|
|
||||||
|
|
||||||
|
#define IDBAsynchStatus_Abort(This,hChapter,eOperation) \
|
||||||
|
( (This)->lpVtbl -> Abort(This,hChapter,eOperation) )
|
||||||
|
|
||||||
|
#define IDBAsynchStatus_GetStatus(This,hChapter,eOperation,pulProgress,pulProgressMax,peAsynchPhase,ppwszStatusText) \
|
||||||
|
( (This)->lpVtbl -> GetStatus(This,hChapter,eOperation,pulProgress,pulProgressMax,peAsynchPhase,ppwszStatusText) )
|
||||||
|
|
||||||
|
#endif /* COBJMACROS */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* C style interface */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* [call_as] */ HRESULT STDMETHODCALLTYPE IDBAsynchStatus_RemoteAbort_Proxy(
|
||||||
|
IDBAsynchStatus * This,
|
||||||
|
/* [in] */ HCHAPTER hChapter,
|
||||||
|
/* [in] */ DBASYNCHOP eOperation,
|
||||||
|
/* [out] */ IErrorInfo **ppErrorInfoRem);
|
||||||
|
|
||||||
|
|
||||||
|
void __RPC_STUB IDBAsynchStatus_RemoteAbort_Stub(
|
||||||
|
IRpcStubBuffer *This,
|
||||||
|
IRpcChannelBuffer *_pRpcChannelBuffer,
|
||||||
|
PRPC_MESSAGE _pRpcMessage,
|
||||||
|
DWORD *_pdwStubPhase);
|
||||||
|
|
||||||
|
|
||||||
|
/* [call_as] */ HRESULT STDMETHODCALLTYPE IDBAsynchStatus_RemoteGetStatus_Proxy(
|
||||||
|
IDBAsynchStatus * This,
|
||||||
|
/* [in] */ HCHAPTER hChapter,
|
||||||
|
/* [in] */ DBASYNCHOP eOperation,
|
||||||
|
/* [unique][out][in] */ DBCOUNTITEM *pulProgress,
|
||||||
|
/* [unique][out][in] */ DBCOUNTITEM *pulProgressMax,
|
||||||
|
/* [unique][out][in] */ DBASYNCHPHASE *peAsynchPhase,
|
||||||
|
/* [unique][out][in] */ LPOLESTR *ppwszStatusText,
|
||||||
|
/* [out] */ IErrorInfo **ppErrorInfoRem);
|
||||||
|
|
||||||
|
|
||||||
|
void __RPC_STUB IDBAsynchStatus_RemoteGetStatus_Stub(
|
||||||
|
IRpcStubBuffer *This,
|
||||||
|
IRpcChannelBuffer *_pRpcChannelBuffer,
|
||||||
|
PRPC_MESSAGE _pRpcMessage,
|
||||||
|
DWORD *_pdwStubPhase);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __IDBAsynchStatus_INTERFACE_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __ISSAsynchStatus_INTERFACE_DEFINED__
|
||||||
|
#define __ISSAsynchStatus_INTERFACE_DEFINED__
|
||||||
|
|
||||||
|
/* interface ISSAsynchStatus */
|
||||||
|
/* [unique][uuid][object][local] */
|
||||||
|
|
||||||
|
|
||||||
|
EXTERN_C const IID IID_ISSAsynchStatus;
|
||||||
|
|
||||||
|
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||||
|
|
||||||
|
MIDL_INTERFACE("1FF1F743-8BB0-4c00-ACC4-C10E43B08FC1")
|
||||||
|
ISSAsynchStatus : public IDBAsynchStatus
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual /* [local] */ HRESULT STDMETHODCALLTYPE WaitForAsynchCompletion(
|
||||||
|
/* [in] */ DWORD dwMillisecTimeOut) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#else /* C style interface */
|
||||||
|
|
||||||
|
typedef struct ISSAsynchStatusVtbl
|
||||||
|
{
|
||||||
|
BEGIN_INTERFACE
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||||
|
ISSAsynchStatus * This,
|
||||||
|
/* [in] */ REFIID riid,
|
||||||
|
/* [iid_is][out] */
|
||||||
|
__RPC__deref_out void **ppvObject);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||||
|
ISSAsynchStatus * This);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||||
|
ISSAsynchStatus * This);
|
||||||
|
|
||||||
|
/* [local] */ HRESULT ( STDMETHODCALLTYPE *Abort )(
|
||||||
|
ISSAsynchStatus * This,
|
||||||
|
/* [in] */ HCHAPTER hChapter,
|
||||||
|
/* [in] */ DBASYNCHOP eOperation);
|
||||||
|
|
||||||
|
/* [local] */ HRESULT ( STDMETHODCALLTYPE *GetStatus )(
|
||||||
|
ISSAsynchStatus * This,
|
||||||
|
/* [in] */ HCHAPTER hChapter,
|
||||||
|
/* [in] */ DBASYNCHOP eOperation,
|
||||||
|
/* [out] */ DBCOUNTITEM *pulProgress,
|
||||||
|
/* [out] */ DBCOUNTITEM *pulProgressMax,
|
||||||
|
/* [out] */ DBASYNCHPHASE *peAsynchPhase,
|
||||||
|
/* [out] */ LPOLESTR *ppwszStatusText);
|
||||||
|
|
||||||
|
/* [local] */ HRESULT ( STDMETHODCALLTYPE *WaitForAsynchCompletion )(
|
||||||
|
ISSAsynchStatus * This,
|
||||||
|
/* [in] */ DWORD dwMillisecTimeOut);
|
||||||
|
|
||||||
|
END_INTERFACE
|
||||||
|
} ISSAsynchStatusVtbl;
|
||||||
|
|
||||||
|
interface ISSAsynchStatus
|
||||||
|
{
|
||||||
|
CONST_VTBL struct ISSAsynchStatusVtbl *lpVtbl;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef COBJMACROS
|
||||||
|
|
||||||
|
|
||||||
|
#define ISSAsynchStatus_QueryInterface(This,riid,ppvObject) \
|
||||||
|
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
|
||||||
|
|
||||||
|
#define ISSAsynchStatus_AddRef(This) \
|
||||||
|
( (This)->lpVtbl -> AddRef(This) )
|
||||||
|
|
||||||
|
#define ISSAsynchStatus_Release(This) \
|
||||||
|
( (This)->lpVtbl -> Release(This) )
|
||||||
|
|
||||||
|
|
||||||
|
#define ISSAsynchStatus_Abort(This,hChapter,eOperation) \
|
||||||
|
( (This)->lpVtbl -> Abort(This,hChapter,eOperation) )
|
||||||
|
|
||||||
|
#define ISSAsynchStatus_GetStatus(This,hChapter,eOperation,pulProgress,pulProgressMax,peAsynchPhase,ppwszStatusText) \
|
||||||
|
( (This)->lpVtbl -> GetStatus(This,hChapter,eOperation,pulProgress,pulProgressMax,peAsynchPhase,ppwszStatusText) )
|
||||||
|
|
||||||
|
|
||||||
|
#define ISSAsynchStatus_WaitForAsynchCompletion(This,dwMillisecTimeOut) \
|
||||||
|
( (This)->lpVtbl -> WaitForAsynchCompletion(This,dwMillisecTimeOut) )
|
||||||
|
|
||||||
|
#endif /* COBJMACROS */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* C style interface */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __ISSAsynchStatus_INTERFACE_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
/* interface __MIDL_itf_sqlncli_0000_0010 */
|
||||||
|
/* [local] */
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Values for STATUS bitmask for DBSCHEMA_TABLES & DBSCHEMA_TABLES_INFO
|
||||||
|
#define TABLE_HAS_UPDATE_INSTEAD_OF_TRIGGER 0x00000001 //table has IOT defined
|
||||||
|
#define TABLE_HAS_DELETE_INSTEAD_OF_TRIGGER 0x00000002 //table has IOT defined
|
||||||
|
#define TABLE_HAS_INSERT_INSTEAD_OF_TRIGGER 0x00000004 //table has IOT defined
|
||||||
|
#define TABLE_HAS_AFTER_UPDATE_TRIGGER 0x00000008 //table has update trigger
|
||||||
|
#define TABLE_HAS_AFTER_DELETE_TRIGGER 0x00000010 //table has delete trigger
|
||||||
|
#define TABLE_HAS_AFTER_INSERT_TRIGGER 0x00000020 //table has insert trigger
|
||||||
|
#define TABLE_HAS_CASCADE_UPDATE 0x00000040 //table has cascade update
|
||||||
|
#define TABLE_HAS_CASCADE_DELETE 0x00000080 //table has cascade delete
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// PropIds for DBPROP_INIT_GENERALTIMEOUT
|
||||||
|
#if (OLEDBVER >= 0x0210)
|
||||||
|
#define DBPROP_INIT_GENERALTIMEOUT 0x11cL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// PropIds for DBPROPSET_SQLSERVERDATASOURCE
|
||||||
|
#define SSPROP_ENABLEFASTLOAD 2
|
||||||
|
#define SSPROP_ENABLEBULKCOPY 3
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// PropIds for DBPROPSET_SQLSERVERDATASOURCEINFO
|
||||||
|
#define SSPROP_UNICODELCID 2
|
||||||
|
#define SSPROP_UNICODECOMPARISONSTYLE 3
|
||||||
|
#define SSPROP_COLUMNLEVELCOLLATION 4
|
||||||
|
#define SSPROP_CHARACTERSET 5
|
||||||
|
#define SSPROP_SORTORDER 6
|
||||||
|
#define SSPROP_CURRENTCOLLATION 7
|
||||||
|
#define SSPROP_INTEGRATEDAUTHENTICATIONMETHOD 8
|
||||||
|
#define SSPROP_MUTUALLYAUTHENTICATED 9
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// PropIds for DBPROPSET_SQLSERVERDBINIT
|
||||||
|
#define SSPROP_INIT_CURRENTLANGUAGE 4
|
||||||
|
#define SSPROP_INIT_NETWORKADDRESS 5
|
||||||
|
#define SSPROP_INIT_NETWORKLIBRARY 6
|
||||||
|
#define SSPROP_INIT_USEPROCFORPREP 7
|
||||||
|
#define SSPROP_INIT_AUTOTRANSLATE 8
|
||||||
|
#define SSPROP_INIT_PACKETSIZE 9
|
||||||
|
#define SSPROP_INIT_APPNAME 10
|
||||||
|
#define SSPROP_INIT_WSID 11
|
||||||
|
#define SSPROP_INIT_FILENAME 12
|
||||||
|
#define SSPROP_INIT_ENCRYPT 13
|
||||||
|
#define SSPROP_AUTH_REPL_SERVER_NAME 14
|
||||||
|
#define SSPROP_INIT_TAGCOLUMNCOLLATION 15
|
||||||
|
#define SSPROP_INIT_MARSCONNECTION 16
|
||||||
|
#define SSPROP_INIT_FAILOVERPARTNER 18
|
||||||
|
#define SSPROP_AUTH_OLD_PASSWORD 19
|
||||||
|
#define SSPROP_INIT_DATATYPECOMPATIBILITY 20
|
||||||
|
#define SSPROP_INIT_TRUST_SERVER_CERTIFICATE 21
|
||||||
|
#define SSPROP_INIT_SERVERSPN 22
|
||||||
|
#define SSPROP_INIT_FAILOVERPARTNERSPN 23
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Values for SSPROP_INIT_USEPROCFORPREP
|
||||||
|
#define SSPROPVAL_USEPROCFORPREP_OFF 0
|
||||||
|
#define SSPROPVAL_USEPROCFORPREP_ON 1
|
||||||
|
#define SSPROPVAL_USEPROCFORPREP_ON_DROP 2
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Values for SSPROP_INIT_DATATYPECOMPATIBILITY
|
||||||
|
#define SSPROPVAL_DATATYPECOMPATIBILITY_SQL2000 80
|
||||||
|
#define SSPROPVAL_DATATYPECOMPATIBILITY_DEFAULT 0
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// PropIds for DBPROPSET_SQLSERVERSESSION
|
||||||
|
#define SSPROP_QUOTEDCATALOGNAMES 2
|
||||||
|
#define SSPROP_ALLOWNATIVEVARIANT 3
|
||||||
|
#define SSPROP_SQLXMLXPROGID 4
|
||||||
|
#define SSPROP_ASYNCH_BULKCOPY 5
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// PropIds for DBPROPSET_SQLSERVERROWSET
|
||||||
|
#define SSPROP_MAXBLOBLENGTH 8
|
||||||
|
#define SSPROP_FASTLOADOPTIONS 9
|
||||||
|
#define SSPROP_FASTLOADKEEPNULLS 10
|
||||||
|
#define SSPROP_FASTLOADKEEPIDENTITY 11
|
||||||
|
#define SSPROP_CURSORAUTOFETCH 12
|
||||||
|
#define SSPROP_DEFERPREPARE 13
|
||||||
|
#define SSPROP_IRowsetFastLoad 14
|
||||||
|
#define SSPROP_QP_NOTIFICATION_TIMEOUT 17
|
||||||
|
#define SSPROP_QP_NOTIFICATION_MSGTEXT 18
|
||||||
|
#define SSPROP_QP_NOTIFICATION_OPTIONS 19
|
||||||
|
#define SSPROP_NOCOUNT_STATUS 20
|
||||||
|
#define SSPROP_COMPUTE_ID 21
|
||||||
|
#define SSPROP_COLUMN_ID 22
|
||||||
|
#define SSPROP_COMPUTE_BYLIST 23
|
||||||
|
#define SSPROP_ISSAsynchStatus 24
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Values for SSPROP_QP_NOTIFICATION_TIMEOUT
|
||||||
|
#define SSPROPVAL_DEFAULT_NOTIFICATION_TIMEOUT 432000 /* in sec */
|
||||||
|
#define SSPROPVAL_MAX_NOTIFICATION_TIMEOUT 0x7FFFFFFF /* in sec */
|
||||||
|
#define MAX_NOTIFICATION_LEN 2000 /* NVARCHAR [2000] for both ID & DELIVERY_QUEUE */
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// PropIds for DBPROPSET_SQLSERVERCOLUMN
|
||||||
|
#define SSPROP_COL_COLLATIONNAME 14
|
||||||
|
#define SSPROP_COL_UDT_CATALOGNAME 31
|
||||||
|
#define SSPROP_COL_UDT_SCHEMANAME 32
|
||||||
|
#define SSPROP_COL_UDT_NAME 33
|
||||||
|
#define SSPROP_COL_XML_SCHEMACOLLECTION_CATALOGNAME 34
|
||||||
|
#define SSPROP_COL_XML_SCHEMACOLLECTION_SCHEMANAME 35
|
||||||
|
#define SSPROP_COL_XML_SCHEMACOLLECTIONNAME 36
|
||||||
|
#define SSPROP_COL_COMPUTED 37
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// PropIds for DBPROPSET_SQLSERVERSTREAM
|
||||||
|
#define SSPROP_STREAM_XMLROOT 19
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// PropIds for DBPROPSET_SQLSERVERPARAMETER
|
||||||
|
#define SSPROP_PARAM_XML_SCHEMACOLLECTION_CATALOGNAME 24
|
||||||
|
#define SSPROP_PARAM_XML_SCHEMACOLLECTION_SCHEMANAME 25
|
||||||
|
#define SSPROP_PARAM_XML_SCHEMACOLLECTIONNAME 26
|
||||||
|
#define SSPROP_PARAM_UDT_CATALOGNAME 27
|
||||||
|
#define SSPROP_PARAM_UDT_SCHEMANAME 28
|
||||||
|
#define SSPROP_PARAM_UDT_NAME 29
|
||||||
|
#define SSPROP_PARAM_TYPE_CATALOGNAME 38
|
||||||
|
#define SSPROP_PARAM_TYPE_SCHEMANAME 39
|
||||||
|
#define SSPROP_PARAM_TYPE_TYPENAME 40
|
||||||
|
#define SSPROP_PARAM_TABLE_DEFAULT_COLUMNS 41
|
||||||
|
#define SSPROP_PARAM_TABLE_COLUMN_SORT_ORDER 42
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// PropIds for DBPROPSET_SQLSERVERINDEX
|
||||||
|
#define SSPROP_INDEX_XML 1
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
#define BCP_TYPE_DEFAULT 0x00
|
||||||
|
#define BCP_TYPE_SQLTEXT 0x23
|
||||||
|
#define BCP_TYPE_SQLVARBINARY 0x25
|
||||||
|
#define BCP_TYPE_SQLINTN 0x26
|
||||||
|
#define BCP_TYPE_SQLVARCHAR 0x27
|
||||||
|
#define BCP_TYPE_SQLBINARY 0x2d
|
||||||
|
#define BCP_TYPE_SQLIMAGE 0x22
|
||||||
|
#define BCP_TYPE_SQLCHARACTER 0x2f
|
||||||
|
#define BCP_TYPE_SQLINT1 0x30
|
||||||
|
#define BCP_TYPE_SQLBIT 0x32
|
||||||
|
#define BCP_TYPE_SQLINT2 0x34
|
||||||
|
#define BCP_TYPE_SQLINT4 0x38
|
||||||
|
#define BCP_TYPE_SQLMONEY 0x3c
|
||||||
|
#define BCP_TYPE_SQLDATETIME 0x3d
|
||||||
|
#define BCP_TYPE_SQLFLT8 0x3e
|
||||||
|
#define BCP_TYPE_SQLFLTN 0x6d
|
||||||
|
#define BCP_TYPE_SQLMONEYN 0x6e
|
||||||
|
#define BCP_TYPE_SQLDATETIMN 0x6f
|
||||||
|
#define BCP_TYPE_SQLFLT4 0x3b
|
||||||
|
#define BCP_TYPE_SQLMONEY4 0x7a
|
||||||
|
#define BCP_TYPE_SQLDATETIM4 0x3a
|
||||||
|
#define BCP_TYPE_SQLDECIMAL 0x6a
|
||||||
|
#define BCP_TYPE_SQLNUMERIC 0x6c
|
||||||
|
#define BCP_TYPE_SQLUNIQUEID 0x24
|
||||||
|
#define BCP_TYPE_SQLBIGCHAR 0xaf
|
||||||
|
#define BCP_TYPE_SQLBIGVARCHAR 0xa7
|
||||||
|
#define BCP_TYPE_SQLBIGBINARY 0xad
|
||||||
|
#define BCP_TYPE_SQLBIGVARBINARY 0xa5
|
||||||
|
#define BCP_TYPE_SQLBITN 0x68
|
||||||
|
#define BCP_TYPE_SQLNCHAR 0xef
|
||||||
|
#define BCP_TYPE_SQLNVARCHAR 0xe7
|
||||||
|
#define BCP_TYPE_SQLNTEXT 0x63
|
||||||
|
#define BCP_TYPE_SQLDECIMALN 0x6a
|
||||||
|
#define BCP_TYPE_SQLNUMERICN 0x6c
|
||||||
|
#define BCP_TYPE_SQLINT8 0x7f
|
||||||
|
#define BCP_TYPE_SQLVARIANT 0x62
|
||||||
|
#define BCP_TYPE_SQLUDT 0xf0
|
||||||
|
#define BCP_TYPE_SQLXML 0xf1
|
||||||
|
#define BCP_TYPE_SQLDATE 0x28
|
||||||
|
#define BCP_TYPE_SQLTIME 0x29
|
||||||
|
#define BCP_TYPE_SQLDATETIME2 0x2a
|
||||||
|
#define BCP_TYPE_SQLDATETIMEOFFSET 0x2b
|
||||||
|
|
||||||
|
#define BCP_DIRECTION_IN 1
|
||||||
|
#define BCP_DIRECTION_OUT 2
|
||||||
|
|
||||||
|
#define BCP_OPTION_MAXERRS 1
|
||||||
|
#define BCP_OPTION_FIRST 2
|
||||||
|
#define BCP_OPTION_LAST 3
|
||||||
|
#define BCP_OPTION_BATCH 4
|
||||||
|
#define BCP_OPTION_KEEPNULLS 5
|
||||||
|
#define BCP_OPTION_ABORT 6
|
||||||
|
#define BCP_OPTION_KEEPIDENTITY 8
|
||||||
|
#define BCP_OPTION_HINTSA 10
|
||||||
|
#define BCP_OPTION_HINTSW 11
|
||||||
|
#define BCP_OPTION_FILECP 12
|
||||||
|
#define BCP_OPTION_UNICODEFILE 13
|
||||||
|
#define BCP_OPTION_TEXTFILE 14
|
||||||
|
#define BCP_OPTION_FILEFMT 15
|
||||||
|
#define BCP_OPTION_FMTXML 16
|
||||||
|
#define BCP_OPTION_FIRSTEX 17
|
||||||
|
#define BCP_OPTION_LASTEX 18
|
||||||
|
#define BCP_OPTION_ROWCOUNT 19
|
||||||
|
|
||||||
|
#define BCP_FILECP_ACP 0
|
||||||
|
#define BCP_FILECP_OEMCP 1
|
||||||
|
#define BCP_FILECP_RAW (-1)
|
||||||
|
|
||||||
|
#ifdef UNICODE
|
||||||
|
#define BCP_OPTION_HINTS BCP_OPTION_HINTSW
|
||||||
|
#else
|
||||||
|
#define BCP_OPTION_HINTS BCP_OPTION_HINTSA
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define BCP_PREFIX_DEFAULT (-10)
|
||||||
|
|
||||||
|
#define BCP_LENGTH_NULL (-1)
|
||||||
|
#define BCP_LENGTH_VARIABLE (-10)
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Provider-specific Class Ids
|
||||||
|
//
|
||||||
|
|
||||||
|
#if SQLNCLI_VER >= 1000
|
||||||
|
|
||||||
|
extern const GUID OLEDBDECLSPEC CLSID_SQLNCLI10 = {0x8F4A6B68L,0x4F36,0x4e3c,{0xBE,0x81,0xBC,0x7C,0xA4,0xE9,0xC4,0x5C}};
|
||||||
|
extern const GUID OLEDBDECLSPEC CLSID_SQLNCLI10_ERROR = {0x53F9C3BCL,0x275F,0x4FA5,{0xB3,0xE6,0x25,0xED,0xCD,0x51,0x20,0x23}};
|
||||||
|
extern const GUID OLEDBDECLSPEC CLSID_SQLNCLI10_ENUMERATOR = {0x91E4F2A5L,0x1B07,0x45f6,{0x86,0xBF,0x92,0x03,0xC7,0xC7,0x2B,0xE3}};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const GUID OLEDBDECLSPEC CLSID_SQLNCLI = {0x85ecafccL,0xbdd9,0x4b03,{0x97,0xa8,0xfa,0x65,0xcb,0xe3,0x85,0x9b}};
|
||||||
|
extern const GUID OLEDBDECLSPEC CLSID_SQLNCLI_ERROR = {0xe8bc0a7aL,0xea71,0x4263,{0x8c,0xda,0x94,0xf3,0x88,0xb8,0xed,0x10}};
|
||||||
|
extern const GUID OLEDBDECLSPEC CLSID_SQLNCLI_ENUMERATOR = {0x4898ad37L,0xfe05,0x42df,{0x92,0xf9,0xe8,0x57,0xdd,0xfe,0xe7,0x30}};
|
||||||
|
extern const GUID OLEDBDECLSPEC CLSID_ROWSET_TVP = {0xc7ef28d5L,0x7bee,0x443f,{0x86,0xda,0xe3,0x98,0x4f,0xcd,0x4d,0xf9}};
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Provider-specific Interface Ids
|
||||||
|
//
|
||||||
|
#ifndef _SQLOLEDB_H_
|
||||||
|
extern const GUID OLEDBDECLSPEC IID_ISQLServerErrorInfo = {0x5cf4ca12,0xef21,0x11d0,{0x97,0xe7,0x0,0xc0,0x4f,0xc2,0xad,0x98}};
|
||||||
|
extern const GUID OLEDBDECLSPEC IID_IRowsetFastLoad = {0x5cf4ca13,0xef21,0x11d0,{0x97,0xe7,0x0,0xc0,0x4f,0xc2,0xad,0x98}};
|
||||||
|
extern const GUID OLEDBDECLSPEC IID_IUMSInitialize = {0x5cf4ca14,0xef21,0x11d0,{0x97,0xe7,0x0,0xc0,0x4f,0xc2,0xad,0x98}};
|
||||||
|
extern const GUID OLEDBDECLSPEC IID_ISchemaLock = {0x4c2389fb,0x2511,0x11d4,{0xb2,0x58,0x0,0xc0,0x4f,0x79,0x71,0xce}};
|
||||||
|
extern const GUID OLEDBDECLSPEC IID_ISQLXMLHelper = {0xd22a7678L,0xf860,0x40cd,{0xa5,0x67,0x15,0x63,0xde,0xb4,0x6d,0x49}};
|
||||||
|
#endif //_SQLOLEDB_H_
|
||||||
|
extern const GUID OLEDBDECLSPEC IID_ISSAbort = {0x5cf4ca15,0xef21,0x11d0,{0x97,0xe7,0x0,0xc0,0x4f,0xc2,0xad,0x98}};
|
||||||
|
extern const GUID OLEDBDECLSPEC IID_IBCPSession = {0x88352D80,0x42D1,0x42f0,{0xA1,0x70,0xAB,0x0F,0x8B,0x45,0xB9,0x39}};
|
||||||
|
extern const GUID OLEDBDECLSPEC IID_ISSCommandWithParameters = {0xeec30162,0x6087,0x467c,{0xb9,0x95,0x7c,0x52,0x3c,0xe9,0x65,0x61}};
|
||||||
|
extern const GUID OLEDBDECLSPEC IID_ISSAsynchStatus = {0x1FF1F743,0x8BB0, 0x4c00,{0xAC,0xC4,0xC1,0x0E,0x43,0xB0,0x8F,0xC1}};
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Provider-specific schema rowsets
|
||||||
|
//
|
||||||
|
#ifndef _SQLOLEDB_H_
|
||||||
|
extern const GUID OLEDBDECLSPEC DBSCHEMA_LINKEDSERVERS = {0x9093caf4,0x2eac,0x11d1,{0x98,0x9,0x0,0xc0,0x4f,0xc2,0xad,0x98}};
|
||||||
|
#endif //_SQLOLEDB_H_
|
||||||
|
extern const GUID OLEDBDECLSPEC DBSCHEMA_SQL_ASSEMBLIES = {0x7c1112c8, 0xc2d3, 0x4f6e, {0x94, 0x9a, 0x98, 0x3d, 0x38, 0xa5, 0x8f, 0x46}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBSCHEMA_SQL_ASSEMBLY_DEPENDENCIES = {0xcb0f837b, 0x974c, 0x41b8, {0x90, 0x9d, 0x64, 0x9c, 0xaf, 0x45, 0xad, 0x2f}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBSCHEMA_SQL_USER_TYPES = {0xf1198bd8, 0xa424, 0x4ea3, {0x8d, 0x4c, 0x60, 0x7e, 0xee, 0x2b, 0xab, 0x60}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBSCHEMA_XML_COLLECTIONS = {0x56bfad8c, 0x6e8f, 0x480d, {0x91, 0xde, 0x35, 0x16, 0xd9, 0x9a, 0x5d, 0x10}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBSCHEMA_SQL_TABLE_TYPES = {0x4e26cde7, 0xaaa4, 0x41ed, {0x93, 0xdd, 0x37, 0x6e, 0x6d, 0x40, 0x9c, 0x17}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBSCHEMA_SQL_TABLE_TYPE_PRIMARY_KEYS = {0x9738faea, 0x31e8, 0x4f63, {0xae, 0xd, 0x61, 0x33, 0x16, 0x41, 0x8c, 0xdd}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBSCHEMA_SQL_TABLE_TYPE_COLUMNS = {0xa663d94b, 0xddf7, 0x4a7f, {0xa5, 0x37, 0xd6, 0x1f, 0x12, 0x36, 0x5d, 0x7c}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBSCHEMA_COLUMNS_EXTENDED = {0x66462f01, 0x633a, 0x44d9, {0xb0, 0xd0, 0xfe, 0x66, 0xf2, 0x1a, 0x0d, 0x24}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBSCHEMA_SPARSE_COLUMN_SET = {0x31a4837c, 0xf9ff, 0x405f, {0x89, 0x82, 0x02, 0x19, 0xaa, 0xaa, 0x4a, 0x12}};
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CRESTRICTIONS_DBSCHEMA_LINKEDSERVERS
|
||||||
|
#define CRESTRICTIONS_DBSCHEMA_LINKEDSERVERS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CRESTRICTIONS_DBSCHEMA_ASSEMBLIES
|
||||||
|
#define CRESTRICTIONS_DBSCHEMA_SQL_ASSEMBLIES 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CRESTRICTIONS_DBSCHEMA_ASSEMBLY_DEPENDENCIES
|
||||||
|
#define CRESTRICTIONS_DBSCHEMA_SQL_ASSEMBLY_DEPENDENCIES 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CRESTRICTIONS_DBSCHEMA_USER_TYPES
|
||||||
|
#define CRESTRICTIONS_DBSCHEMA_SQL_USER_TYPES 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CRESTRICTIONS_DBSCHEMA_XML_COLLECTIONS
|
||||||
|
#define CRESTRICTIONS_DBSCHEMA_XML_COLLECTIONS 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CRESTRICTIONS_DBSCHEMA_SQL_TABLE_TYPES
|
||||||
|
#define CRESTRICTIONS_DBSCHEMA_SQL_TABLE_TYPES 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CRESTRICTIONS_DBSCHEMA_SQL_TABLE_TYPE_PRIMARY_KEYS
|
||||||
|
#define CRESTRICTIONS_DBSCHEMA_SQL_TABLE_TYPE_PRIMARY_KEYS 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CRESTRICTIONS_DBSCHEMA_SQL_TABLE_TYPE_COLUMNS
|
||||||
|
#define CRESTRICTIONS_DBSCHEMA_SQL_TABLE_TYPE_COLUMNS 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CRESTRICTIONS_DBSCHEMA_COLUMNS_EXTENDED
|
||||||
|
#define CRESTRICTIONS_DBSCHEMA_COLUMNS_EXTENDED 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CRESTRICTIONS_DBSCHEMA_SPARSE_COLUMN_SET
|
||||||
|
#define CRESTRICTIONS_DBSCHEMA_SPARSE_COLUMN_SET 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Provider-specific property sets
|
||||||
|
//
|
||||||
|
#ifndef _SQLOLEDB_H_
|
||||||
|
extern const GUID OLEDBDECLSPEC DBPROPSET_SQLSERVERDATASOURCE = {0x28efaee4,0x2d2c,0x11d1,{0x98,0x7,0x0,0xc0,0x4f,0xc2,0xad,0x98}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBPROPSET_SQLSERVERDATASOURCEINFO= {0xdf10cb94,0x35f6,0x11d2,{0x9c,0x54,0x0,0xc0,0x4f,0x79,0x71,0xd3}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBPROPSET_SQLSERVERDBINIT = {0x5cf4ca10,0xef21,0x11d0,{0x97,0xe7,0x0,0xc0,0x4f,0xc2,0xad,0x98}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBPROPSET_SQLSERVERROWSET = {0x5cf4ca11,0xef21,0x11d0,{0x97,0xe7,0x0,0xc0,0x4f,0xc2,0xad,0x98}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBPROPSET_SQLSERVERSESSION = {0x28efaee5,0x2d2c,0x11d1,{0x98,0x7,0x0,0xc0,0x4f,0xc2,0xad,0x98}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBPROPSET_SQLSERVERCOLUMN = {0x3b63fb5e,0x3fbb,0x11d3,{0x9f,0x29,0x0,0xc0,0x4f,0x8e,0xe9,0xdc}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBPROPSET_SQLSERVERSTREAM = {0x9f79c073,0x8a6d,0x4bca,{0xa8,0xa8,0xc9,0xb7,0x9a,0x9b,0x96,0x2d}};
|
||||||
|
#endif //_SQLOLEDB_H_
|
||||||
|
extern const GUID OLEDBDECLSPEC DBPROPSET_SQLSERVERPARAMETER = {0xfee09128,0xa67d,0x47ea,{0x8d,0x40,0x24,0xa1,0xd4,0x73,0x7e,0x8d}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBPROPSET_SQLSERVERINDEX = {0xE428B84E,0xA6B7,0x413a,{0x94,0x65,0x56,0x23,0x2E,0x0D,0x2B,0xEB}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBPROPSET_PARAMETERALL = {0x2cd2b7d8,0xe7c2,0x4f6c,{0x9b,0x30,0x75,0xe2,0x58,0x46,0x10,0x97}};
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Provider-specific columns for IColumnsRowset
|
||||||
|
//
|
||||||
|
#define DBCOLUMN_SS_X_GUID {0x627bd890,0xed54,0x11d2,{0xb9,0x94,0x0,0xc0,0x4f,0x8c,0xa8,0x2c}}
|
||||||
|
//
|
||||||
|
#ifndef _SQLOLEDB_H_
|
||||||
|
extern const DBID OLEDBDECLSPEC DBCOLUMN_SS_COMPFLAGS = {DBCOLUMN_SS_X_GUID, DBKIND_GUID_PROPID, (LPOLESTR)100};
|
||||||
|
extern const DBID OLEDBDECLSPEC DBCOLUMN_SS_SORTID = {DBCOLUMN_SS_X_GUID, DBKIND_GUID_PROPID, (LPOLESTR)101};
|
||||||
|
extern const DBID OLEDBDECLSPEC DBCOLUMN_BASETABLEINSTANCE = {DBCOLUMN_SS_X_GUID, DBKIND_GUID_PROPID, (LPOLESTR)102};
|
||||||
|
extern const DBID OLEDBDECLSPEC DBCOLUMN_SS_TDSCOLLATION = {DBCOLUMN_SS_X_GUID, DBKIND_GUID_PROPID, (LPOLESTR)103};
|
||||||
|
#endif //_SQLOLEDB_H_
|
||||||
|
extern const DBID OLEDBDECLSPEC DBCOLUMN_BASESERVERNAME = {DBCOLUMN_SS_X_GUID, DBKIND_GUID_PROPID, (LPOLESTR)104};
|
||||||
|
extern const DBID OLEDBDECLSPEC DBCOLUMN_SS_XML_SCHEMACOLLECTION_CATALOGNAME= {DBCOLUMN_SS_X_GUID, DBKIND_GUID_PROPID, (LPOLESTR)105};
|
||||||
|
extern const DBID OLEDBDECLSPEC DBCOLUMN_SS_XML_SCHEMACOLLECTION_SCHEMANAME = {DBCOLUMN_SS_X_GUID, DBKIND_GUID_PROPID, (LPOLESTR)106};
|
||||||
|
extern const DBID OLEDBDECLSPEC DBCOLUMN_SS_XML_SCHEMACOLLECTIONNAME = {DBCOLUMN_SS_X_GUID, DBKIND_GUID_PROPID, (LPOLESTR)107};
|
||||||
|
extern const DBID OLEDBDECLSPEC DBCOLUMN_SS_UDT_CATALOGNAME = {DBCOLUMN_SS_X_GUID, DBKIND_GUID_PROPID, (LPOLESTR)108};
|
||||||
|
extern const DBID OLEDBDECLSPEC DBCOLUMN_SS_UDT_SCHEMANAME = {DBCOLUMN_SS_X_GUID, DBKIND_GUID_PROPID, (LPOLESTR)109};
|
||||||
|
extern const DBID OLEDBDECLSPEC DBCOLUMN_SS_UDT_NAME = {DBCOLUMN_SS_X_GUID, DBKIND_GUID_PROPID, (LPOLESTR)110};
|
||||||
|
extern const DBID OLEDBDECLSPEC DBCOLUMN_SS_ASSEMBLY_TYPENAME= {DBCOLUMN_SS_X_GUID, DBKIND_GUID_PROPID, (LPOLESTR)111};
|
||||||
|
|
||||||
|
// OLEDB part of SQL Server Native Client header - end here!
|
||||||
|
#endif // defined(_SQLNCLI_OLEDB_) || !defined(_SQLNCLI_ODBC_)
|
||||||
|
|
||||||
|
// ODBC part of SQL Server Native Client header - begin here!
|
||||||
|
#if defined(_SQLNCLI_ODBC_) || !defined(_SQLNCLI_OLEDB_)
|
||||||
|
#ifdef ODBCVER
|
||||||
|
|
||||||
|
// max SQL Server identifier length
|
||||||
|
#define SQL_MAX_SQLSERVERNAME 128
|
||||||
|
|
||||||
|
// SQLSetConnectAttr driver specific defines.
|
||||||
|
// Microsoft has 1200 thru 1249 reserved for Microsoft SQL Server Native Client driver usage.
|
||||||
|
// Connection attributes
|
||||||
|
#define SQL_COPT_SS_BASE 1200
|
||||||
|
#define SQL_COPT_SS_REMOTE_PWD (SQL_COPT_SS_BASE+1) // dbrpwset SQLSetConnectOption only
|
||||||
|
#define SQL_COPT_SS_USE_PROC_FOR_PREP (SQL_COPT_SS_BASE+2) // Use create proc for SQLPrepare
|
||||||
|
#define SQL_COPT_SS_INTEGRATED_SECURITY (SQL_COPT_SS_BASE+3) // Force integrated security on login
|
||||||
|
#define SQL_COPT_SS_PRESERVE_CURSORS (SQL_COPT_SS_BASE+4) // Preserve server cursors after SQLTransact
|
||||||
|
#define SQL_COPT_SS_USER_DATA (SQL_COPT_SS_BASE+5) // dbgetuserdata/dbsetuserdata
|
||||||
|
#define SQL_COPT_SS_ENLIST_IN_DTC SQL_ATTR_ENLIST_IN_DTC // Enlist in a DTC transaction
|
||||||
|
#define SQL_COPT_SS_ENLIST_IN_XA SQL_ATTR_ENLIST_IN_XA // Enlist in a XA transaction
|
||||||
|
#define SQL_COPT_SS_FALLBACK_CONNECT (SQL_COPT_SS_BASE+10) // Enables FallBack connections
|
||||||
|
#define SQL_COPT_SS_PERF_DATA (SQL_COPT_SS_BASE+11) // Used to access SQL Server ODBC driver performance data
|
||||||
|
#define SQL_COPT_SS_PERF_DATA_LOG (SQL_COPT_SS_BASE+12) // Used to set the logfile name for the Performance data
|
||||||
|
#define SQL_COPT_SS_PERF_QUERY_INTERVAL (SQL_COPT_SS_BASE+13) // Used to set the query logging threshold in milliseconds.
|
||||||
|
#define SQL_COPT_SS_PERF_QUERY_LOG (SQL_COPT_SS_BASE+14) // Used to set the logfile name for saving queryies.
|
||||||
|
#define SQL_COPT_SS_PERF_QUERY (SQL_COPT_SS_BASE+15) // Used to start and stop query logging.
|
||||||
|
#define SQL_COPT_SS_PERF_DATA_LOG_NOW (SQL_COPT_SS_BASE+16) // Used to make a statistics log entry to disk.
|
||||||
|
#define SQL_COPT_SS_QUOTED_IDENT (SQL_COPT_SS_BASE+17) // Enable/Disable Quoted Identifiers
|
||||||
|
#define SQL_COPT_SS_ANSI_NPW (SQL_COPT_SS_BASE+18) // Enable/Disable ANSI NULL, Padding and Warnings
|
||||||
|
#define SQL_COPT_SS_BCP (SQL_COPT_SS_BASE+19) // Allow BCP usage on connection
|
||||||
|
#define SQL_COPT_SS_TRANSLATE (SQL_COPT_SS_BASE+20) // Perform code page translation
|
||||||
|
#define SQL_COPT_SS_ATTACHDBFILENAME (SQL_COPT_SS_BASE+21) // File name to be attached as a database
|
||||||
|
#define SQL_COPT_SS_CONCAT_NULL (SQL_COPT_SS_BASE+22) // Enable/Disable CONCAT_NULL_YIELDS_NULL
|
||||||
|
#define SQL_COPT_SS_ENCRYPT (SQL_COPT_SS_BASE+23) // Allow strong encryption for data
|
||||||
|
#define SQL_COPT_SS_MARS_ENABLED (SQL_COPT_SS_BASE+24) // Multiple active result set per connection
|
||||||
|
#define SQL_COPT_SS_FAILOVER_PARTNER (SQL_COPT_SS_BASE+25) // Failover partner server
|
||||||
|
#define SQL_COPT_SS_OLDPWD (SQL_COPT_SS_BASE+26) // Old Password, used when changing password during login
|
||||||
|
#define SQL_COPT_SS_TXN_ISOLATION (SQL_COPT_SS_BASE+27) // Used to set/get any driver-specific or ODBC-defined TXN iso level
|
||||||
|
#define SQL_COPT_SS_TRUST_SERVER_CERTIFICATE (SQL_COPT_SS_BASE+28) // Trust server certificate
|
||||||
|
#define SQL_COPT_SS_SERVER_SPN (SQL_COPT_SS_BASE+29) // Server SPN
|
||||||
|
#define SQL_COPT_SS_FAILOVER_PARTNER_SPN (SQL_COPT_SS_BASE+30) // Failover partner server SPN
|
||||||
|
#define SQL_COPT_SS_INTEGRATED_AUTHENTICATION_METHOD (SQL_COPT_SS_BASE+31) // The integrated authentication method used for the connection
|
||||||
|
#define SQL_COPT_SS_MUTUALLY_AUTHENTICATED (SQL_COPT_SS_BASE+32) // Used to decide if the connection is mutually authenticated
|
||||||
|
#define SQL_COPT_SS_MAX_USED SQL_COPT_SS_MUTUALLY_AUTHENTICATED
|
||||||
|
// Define old names
|
||||||
|
#define SQL_REMOTE_PWD SQL_COPT_SS_REMOTE_PWD
|
||||||
|
#define SQL_USE_PROCEDURE_FOR_PREPARE SQL_COPT_SS_USE_PROC_FOR_PREP
|
||||||
|
#define SQL_INTEGRATED_SECURITY SQL_COPT_SS_INTEGRATED_SECURITY
|
||||||
|
#define SQL_PRESERVE_CURSORS SQL_COPT_SS_PRESERVE_CURSORS
|
||||||
|
|
||||||
|
// SQLSetStmtAttr SQL Server Native Client driver specific defines.
|
||||||
|
// Statement attributes
|
||||||
|
#define SQL_SOPT_SS_BASE 1225
|
||||||
|
#define SQL_SOPT_SS_TEXTPTR_LOGGING (SQL_SOPT_SS_BASE+0) // Text pointer logging
|
||||||
|
#define SQL_SOPT_SS_CURRENT_COMMAND (SQL_SOPT_SS_BASE+1) // dbcurcmd SQLGetStmtOption only
|
||||||
|
#define SQL_SOPT_SS_HIDDEN_COLUMNS (SQL_SOPT_SS_BASE+2) // Expose FOR BROWSE hidden columns
|
||||||
|
#define SQL_SOPT_SS_NOBROWSETABLE (SQL_SOPT_SS_BASE+3) // Set NOBROWSETABLE option
|
||||||
|
#define SQL_SOPT_SS_REGIONALIZE (SQL_SOPT_SS_BASE+4) // Regionalize output character conversions
|
||||||
|
#define SQL_SOPT_SS_CURSOR_OPTIONS (SQL_SOPT_SS_BASE+5) // Server cursor options
|
||||||
|
#define SQL_SOPT_SS_NOCOUNT_STATUS (SQL_SOPT_SS_BASE+6) // Real vs. Not Real row count indicator
|
||||||
|
#define SQL_SOPT_SS_DEFER_PREPARE (SQL_SOPT_SS_BASE+7) // Defer prepare until necessary
|
||||||
|
#define SQL_SOPT_SS_QUERYNOTIFICATION_TIMEOUT (SQL_SOPT_SS_BASE+8) // Notification timeout
|
||||||
|
#define SQL_SOPT_SS_QUERYNOTIFICATION_MSGTEXT (SQL_SOPT_SS_BASE+9) // Notification message text
|
||||||
|
#define SQL_SOPT_SS_QUERYNOTIFICATION_OPTIONS (SQL_SOPT_SS_BASE+10)// SQL service broker name
|
||||||
|
#define SQL_SOPT_SS_PARAM_FOCUS (SQL_SOPT_SS_BASE+11)// Direct subsequent calls to parameter related methods to set properties on constituent columns/parameters of container types
|
||||||
|
#define SQL_SOPT_SS_NAME_SCOPE (SQL_SOPT_SS_BASE+12)// Sets name scope for subsequent catalog function calls
|
||||||
|
#define SQL_SOPT_SS_MAX_USED SQL_SOPT_SS_NAME_SCOPE
|
||||||
|
// Define old names
|
||||||
|
#define SQL_TEXTPTR_LOGGING SQL_SOPT_SS_TEXTPTR_LOGGING
|
||||||
|
#define SQL_COPT_SS_BASE_EX 1240
|
||||||
|
#define SQL_COPT_SS_BROWSE_CONNECT (SQL_COPT_SS_BASE_EX+1) // Browse connect mode of operation
|
||||||
|
#define SQL_COPT_SS_BROWSE_SERVER (SQL_COPT_SS_BASE_EX+2) // Single Server browse request.
|
||||||
|
#define SQL_COPT_SS_WARN_ON_CP_ERROR (SQL_COPT_SS_BASE_EX+3) // Issues warning when data from the server had a loss during code page conversion.
|
||||||
|
#define SQL_COPT_SS_CONNECTION_DEAD (SQL_COPT_SS_BASE_EX+4) // dbdead SQLGetConnectOption only. It will try to ping the server. Expensive connection check
|
||||||
|
#define SQL_COPT_SS_BROWSE_CACHE_DATA (SQL_COPT_SS_BASE_EX+5) // Determines if we should cache browse info. Used when returned buffer is greater then ODBC limit (32K)
|
||||||
|
#define SQL_COPT_SS_RESET_CONNECTION (SQL_COPT_SS_BASE_EX+6) // When this option is set, we will perform connection reset on next packet
|
||||||
|
#define SQL_COPT_SS_EX_MAX_USED SQL_COPT_SS_RESET_CONNECTION
|
||||||
|
|
||||||
|
// SQLColAttributes driver specific defines.
|
||||||
|
// SQLSetDescField/SQLGetDescField driver specific defines.
|
||||||
|
// Microsoft has 1200 thru 1249 reserved for Microsoft SQL Server Native Client driver usage.
|
||||||
|
#define SQL_CA_SS_BASE 1200
|
||||||
|
#define SQL_CA_SS_COLUMN_SSTYPE (SQL_CA_SS_BASE+0) // dbcoltype/dbalttype
|
||||||
|
#define SQL_CA_SS_COLUMN_UTYPE (SQL_CA_SS_BASE+1) // dbcolutype/dbaltutype
|
||||||
|
#define SQL_CA_SS_NUM_ORDERS (SQL_CA_SS_BASE+2) // dbnumorders
|
||||||
|
#define SQL_CA_SS_COLUMN_ORDER (SQL_CA_SS_BASE+3) // dbordercol
|
||||||
|
#define SQL_CA_SS_COLUMN_VARYLEN (SQL_CA_SS_BASE+4) // dbvarylen
|
||||||
|
#define SQL_CA_SS_NUM_COMPUTES (SQL_CA_SS_BASE+5) // dbnumcompute
|
||||||
|
#define SQL_CA_SS_COMPUTE_ID (SQL_CA_SS_BASE+6) // dbnextrow status return
|
||||||
|
#define SQL_CA_SS_COMPUTE_BYLIST (SQL_CA_SS_BASE+7) // dbbylist
|
||||||
|
#define SQL_CA_SS_COLUMN_ID (SQL_CA_SS_BASE+8) // dbaltcolid
|
||||||
|
#define SQL_CA_SS_COLUMN_OP (SQL_CA_SS_BASE+9) // dbaltop
|
||||||
|
#define SQL_CA_SS_COLUMN_SIZE (SQL_CA_SS_BASE+10) // dbcollen
|
||||||
|
#define SQL_CA_SS_COLUMN_HIDDEN (SQL_CA_SS_BASE+11) // Column is hidden (FOR BROWSE)
|
||||||
|
#define SQL_CA_SS_COLUMN_KEY (SQL_CA_SS_BASE+12) // Column is key column (FOR BROWSE)
|
||||||
|
//#define SQL_DESC_BASE_COLUMN_NAME_OLD (SQL_CA_SS_BASE+13) // This is defined at another location.
|
||||||
|
#define SQL_CA_SS_COLUMN_COLLATION (SQL_CA_SS_BASE+14) // Column collation (only for chars)
|
||||||
|
#define SQL_CA_SS_VARIANT_TYPE (SQL_CA_SS_BASE+15)
|
||||||
|
#define SQL_CA_SS_VARIANT_SQL_TYPE (SQL_CA_SS_BASE+16)
|
||||||
|
#define SQL_CA_SS_VARIANT_SERVER_TYPE (SQL_CA_SS_BASE+17)
|
||||||
|
|
||||||
|
// XML, CLR UDT, and table valued parameter related metadata
|
||||||
|
#define SQL_CA_SS_UDT_CATALOG_NAME (SQL_CA_SS_BASE+18) // UDT catalog name
|
||||||
|
#define SQL_CA_SS_UDT_SCHEMA_NAME (SQL_CA_SS_BASE+19) // UDT schema name
|
||||||
|
#define SQL_CA_SS_UDT_TYPE_NAME (SQL_CA_SS_BASE+20) // UDT type name
|
||||||
|
#define SQL_CA_SS_UDT_ASSEMBLY_TYPE_NAME (SQL_CA_SS_BASE+21) // Qualified name of the assembly containing the UDT class
|
||||||
|
#define SQL_CA_SS_XML_SCHEMACOLLECTION_CATALOG_NAME (SQL_CA_SS_BASE+22) // Name of the catalog that contains XML Schema collection
|
||||||
|
#define SQL_CA_SS_XML_SCHEMACOLLECTION_SCHEMA_NAME (SQL_CA_SS_BASE+23) // Name of the schema that contains XML Schema collection
|
||||||
|
#define SQL_CA_SS_XML_SCHEMACOLLECTION_NAME (SQL_CA_SS_BASE+24) // Name of the XML Schema collection
|
||||||
|
#define SQL_CA_SS_CATALOG_NAME (SQL_CA_SS_BASE+25) // Catalog name
|
||||||
|
#define SQL_CA_SS_SCHEMA_NAME (SQL_CA_SS_BASE+26) // Schema name
|
||||||
|
#define SQL_CA_SS_TYPE_NAME (SQL_CA_SS_BASE+27) // Type name
|
||||||
|
|
||||||
|
// table valued parameter related metadata
|
||||||
|
#define SQL_CA_SS_COLUMN_COMPUTED (SQL_CA_SS_BASE+29) // column is computed
|
||||||
|
#define SQL_CA_SS_COLUMN_IN_UNIQUE_KEY (SQL_CA_SS_BASE+30) // column is part of a unique key
|
||||||
|
#define SQL_CA_SS_COLUMN_SORT_ORDER (SQL_CA_SS_BASE+31) // column sort order
|
||||||
|
#define SQL_CA_SS_COLUMN_SORT_ORDINAL (SQL_CA_SS_BASE+32) // column sort ordinal
|
||||||
|
#define SQL_CA_SS_COLUMN_HAS_DEFAULT_VALUE (SQL_CA_SS_BASE+33) // column has default value for all rows of the table valued parameter
|
||||||
|
|
||||||
|
// sparse column related metadata
|
||||||
|
#define SQL_CA_SS_IS_COLUMN_SET (SQL_CA_SS_BASE+34) // column is a column-set column for sparse columns
|
||||||
|
|
||||||
|
// Legacy datetime related metadata
|
||||||
|
#define SQL_CA_SS_SERVER_TYPE (SQL_CA_SS_BASE+35) // column type to send on the wire for datetime types
|
||||||
|
|
||||||
|
#define SQL_CA_SS_MAX_USED (SQL_CA_SS_BASE+36)
|
||||||
|
|
||||||
|
// Defines returned by SQL_ATTR_CURSOR_TYPE/SQL_CURSOR_TYPE
|
||||||
|
#define SQL_CURSOR_FAST_FORWARD_ONLY 8 // Only returned by SQLGetStmtAttr/Option
|
||||||
|
// Defines for use with SQL_COPT_SS_USE_PROC_FOR_PREP
|
||||||
|
#define SQL_UP_OFF 0L // Procedures won't be used for prepare
|
||||||
|
#define SQL_UP_ON 1L // Procedures will be used for prepare
|
||||||
|
#define SQL_UP_ON_DROP 2L // Temp procedures will be explicitly dropped
|
||||||
|
#define SQL_UP_DEFAULT SQL_UP_ON
|
||||||
|
// Defines for use with SQL_COPT_SS_INTEGRATED_SECURITY - Pre-Connect Option only
|
||||||
|
#define SQL_IS_OFF 0L // Integrated security isn't used
|
||||||
|
#define SQL_IS_ON 1L // Integrated security is used
|
||||||
|
#define SQL_IS_DEFAULT SQL_IS_OFF
|
||||||
|
// Defines for use with SQL_COPT_SS_PRESERVE_CURSORS
|
||||||
|
#define SQL_PC_OFF 0L // Cursors are closed on SQLTransact
|
||||||
|
#define SQL_PC_ON 1L // Cursors remain open on SQLTransact
|
||||||
|
#define SQL_PC_DEFAULT SQL_PC_OFF
|
||||||
|
// Defines for use with SQL_COPT_SS_USER_DATA
|
||||||
|
#define SQL_UD_NOTSET NULL // No user data pointer set
|
||||||
|
// Defines for use with SQL_COPT_SS_TRANSLATE
|
||||||
|
#define SQL_XL_OFF 0L // Code page translation is not performed
|
||||||
|
#define SQL_XL_ON 1L // Code page translation is performed
|
||||||
|
#define SQL_XL_DEFAULT SQL_XL_ON
|
||||||
|
// Defines for use with SQL_COPT_SS_FALLBACK_CONNECT - Pre-Connect Option only
|
||||||
|
#define SQL_FB_OFF 0L // FallBack connections are disabled
|
||||||
|
#define SQL_FB_ON 1L // FallBack connections are enabled
|
||||||
|
#define SQL_FB_DEFAULT SQL_FB_OFF
|
||||||
|
// Defines for use with SQL_COPT_SS_BCP - Pre-Connect Option only
|
||||||
|
#define SQL_BCP_OFF 0L // BCP is not allowed on connection
|
||||||
|
#define SQL_BCP_ON 1L // BCP is allowed on connection
|
||||||
|
#define SQL_BCP_DEFAULT SQL_BCP_OFF
|
||||||
|
// Defines for use with SQL_COPT_SS_QUOTED_IDENT
|
||||||
|
#define SQL_QI_OFF 0L // Quoted identifiers are enable
|
||||||
|
#define SQL_QI_ON 1L // Quoted identifiers are disabled
|
||||||
|
#define SQL_QI_DEFAULT SQL_QI_ON
|
||||||
|
// Defines for use with SQL_COPT_SS_ANSI_NPW - Pre-Connect Option only
|
||||||
|
#define SQL_AD_OFF 0L // ANSI NULLs, Padding and Warnings are enabled
|
||||||
|
#define SQL_AD_ON 1L // ANSI NULLs, Padding and Warnings are disabled
|
||||||
|
#define SQL_AD_DEFAULT SQL_AD_ON
|
||||||
|
// Defines for use with SQL_COPT_SS_CONCAT_NULL - Pre-Connect Option only
|
||||||
|
#define SQL_CN_OFF 0L // CONCAT_NULL_YIELDS_NULL is off
|
||||||
|
#define SQL_CN_ON 1L // CONCAT_NULL_YIELDS_NULL is on
|
||||||
|
#define SQL_CN_DEFAULT SQL_CN_ON
|
||||||
|
// Defines for use with SQL_SOPT_SS_TEXTPTR_LOGGING
|
||||||
|
#define SQL_TL_OFF 0L // No logging on text pointer ops
|
||||||
|
#define SQL_TL_ON 1L // Logging occurs on text pointer ops
|
||||||
|
#define SQL_TL_DEFAULT SQL_TL_ON
|
||||||
|
// Defines for use with SQL_SOPT_SS_HIDDEN_COLUMNS
|
||||||
|
#define SQL_HC_OFF 0L // FOR BROWSE columns are hidden
|
||||||
|
#define SQL_HC_ON 1L // FOR BROWSE columns are exposed
|
||||||
|
#define SQL_HC_DEFAULT SQL_HC_OFF
|
||||||
|
// Defines for use with SQL_SOPT_SS_NOBROWSETABLE
|
||||||
|
#define SQL_NB_OFF 0L // NO_BROWSETABLE is off
|
||||||
|
#define SQL_NB_ON 1L // NO_BROWSETABLE is on
|
||||||
|
#define SQL_NB_DEFAULT SQL_NB_OFF
|
||||||
|
// Defines for use with SQL_SOPT_SS_REGIONALIZE
|
||||||
|
#define SQL_RE_OFF 0L // No regionalization occurs on output character conversions
|
||||||
|
#define SQL_RE_ON 1L // Regionalization occurs on output character conversions
|
||||||
|
#define SQL_RE_DEFAULT SQL_RE_OFF
|
||||||
|
// Defines for use with SQL_SOPT_SS_CURSOR_OPTIONS
|
||||||
|
#define SQL_CO_OFF 0L // Clear all cursor options
|
||||||
|
#define SQL_CO_FFO 1L // Fast-forward cursor will be used
|
||||||
|
#define SQL_CO_AF 2L // Autofetch on cursor open
|
||||||
|
#define SQL_CO_FFO_AF (SQL_CO_FFO|SQL_CO_AF) // Fast-forward cursor with autofetch
|
||||||
|
#define SQL_CO_FIREHOSE_AF 4L // Auto fetch on fire-hose cursors
|
||||||
|
#define SQL_CO_DEFAULT SQL_CO_OFF
|
||||||
|
//SQL_SOPT_SS_NOCOUNT_STATUS
|
||||||
|
#define SQL_NC_OFF 0L
|
||||||
|
#define SQL_NC_ON 1L
|
||||||
|
//SQL_SOPT_SS_DEFER_PREPARE
|
||||||
|
#define SQL_DP_OFF 0L
|
||||||
|
#define SQL_DP_ON 1L
|
||||||
|
//SQL_SOPT_SS_NAME_SCOPE
|
||||||
|
#define SQL_SS_NAME_SCOPE_TABLE 0L
|
||||||
|
#define SQL_SS_NAME_SCOPE_TABLE_TYPE 1L
|
||||||
|
#define SQL_SS_NAME_SCOPE_EXTENDED 2L
|
||||||
|
#define SQL_SS_NAME_SCOPE_SPARSE_COLUMN_SET 3L
|
||||||
|
#define SQL_SS_NAME_SCOPE_DEFAULT SQL_SS_NAME_SCOPE_TABLE
|
||||||
|
//SQL_COPT_SS_ENCRYPT
|
||||||
|
#define SQL_EN_OFF 0L
|
||||||
|
#define SQL_EN_ON 1L
|
||||||
|
//SQL_COPT_SS_TRUST_SERVER_CERTIFICATE
|
||||||
|
#define SQL_TRUST_SERVER_CERTIFICATE_NO 0L
|
||||||
|
#define SQL_TRUST_SERVER_CERTIFICATE_YES 1L
|
||||||
|
//SQL_COPT_SS_BROWSE_CONNECT
|
||||||
|
#define SQL_MORE_INFO_NO 0L
|
||||||
|
#define SQL_MORE_INFO_YES 1L
|
||||||
|
//SQL_COPT_SS_BROWSE_CACHE_DATA
|
||||||
|
#define SQL_CACHE_DATA_NO 0L
|
||||||
|
#define SQL_CACHE_DATA_YES 1L
|
||||||
|
//SQL_COPT_SS_RESET_CONNECTION
|
||||||
|
#define SQL_RESET_YES 1L
|
||||||
|
//SQL_COPT_SS_WARN_ON_CP_ERROR
|
||||||
|
#define SQL_WARN_NO 0L
|
||||||
|
#define SQL_WARN_YES 1L
|
||||||
|
//SQL_COPT_SS_MARS_ENABLED
|
||||||
|
#define SQL_MARS_ENABLED_NO 0L
|
||||||
|
#define SQL_MARS_ENABLED_YES 1L
|
||||||
|
/* SQL_TXN_ISOLATION_OPTION bitmasks */
|
||||||
|
#define SQL_TXN_SS_SNAPSHOT 0x00000020L
|
||||||
|
|
||||||
|
// The following are defines for SQL_CA_SS_COLUMN_SORT_ORDER
|
||||||
|
#define SQL_SS_ORDER_UNSPECIFIED 0L
|
||||||
|
#define SQL_SS_DESCENDING_ORDER 1L
|
||||||
|
#define SQL_SS_ASCENDING_ORDER 2L
|
||||||
|
#define SQL_SS_ORDER_DEFAULT SQL_SS_ORDER_UNSPECIFIED
|
||||||
|
|
||||||
|
// Driver specific SQL data type defines.
|
||||||
|
// Microsoft has -150 thru -199 reserved for Microsoft SQL Server Native Client driver usage.
|
||||||
|
#define SQL_SS_VARIANT (-150)
|
||||||
|
#define SQL_SS_UDT (-151)
|
||||||
|
#define SQL_SS_XML (-152)
|
||||||
|
#define SQL_SS_TABLE (-153)
|
||||||
|
#define SQL_SS_TIME2 (-154)
|
||||||
|
#define SQL_SS_TIMESTAMPOFFSET (-155)
|
||||||
|
|
||||||
|
// Local types to be used with SQL_CA_SS_SERVER_TYPE
|
||||||
|
#define SQL_SS_TYPE_DEFAULT 0L
|
||||||
|
#define SQL_SS_TYPE_SMALLDATETIME 1L
|
||||||
|
#define SQL_SS_TYPE_DATETIME 2L
|
||||||
|
|
||||||
|
#ifndef SQLNCLI_NO_BCP
|
||||||
|
// Define the symbol SQLNCLI_NO_BCP if you are not using BCP in your application
|
||||||
|
// and you want to exclude the BCP-related definitions in this header file.
|
||||||
|
|
||||||
|
// SQL Server Data Type defines.
|
||||||
|
// New types for SQL 6.0 and later servers
|
||||||
|
#define SQLTEXT 0x23
|
||||||
|
#define SQLVARBINARY 0x25
|
||||||
|
#define SQLINTN 0x26
|
||||||
|
#define SQLVARCHAR 0x27
|
||||||
|
#define SQLBINARY 0x2d
|
||||||
|
#define SQLIMAGE 0x22
|
||||||
|
#define SQLCHARACTER 0x2f
|
||||||
|
#define SQLINT1 0x30
|
||||||
|
#define SQLBIT 0x32
|
||||||
|
#define SQLINT2 0x34
|
||||||
|
#define SQLINT4 0x38
|
||||||
|
#define SQLMONEY 0x3c
|
||||||
|
#define SQLDATETIME 0x3d
|
||||||
|
#define SQLFLT8 0x3e
|
||||||
|
#define SQLFLTN 0x6d
|
||||||
|
#define SQLMONEYN 0x6e
|
||||||
|
#define SQLDATETIMN 0x6f
|
||||||
|
#define SQLFLT4 0x3b
|
||||||
|
#define SQLMONEY4 0x7a
|
||||||
|
#define SQLDATETIM4 0x3a
|
||||||
|
// New types for SQL 6.0 and later servers
|
||||||
|
#define SQLDECIMAL 0x6a
|
||||||
|
#define SQLNUMERIC 0x6c
|
||||||
|
// New types for SQL 7.0 and later servers
|
||||||
|
#define SQLUNIQUEID 0x24
|
||||||
|
#define SQLBIGCHAR 0xaf
|
||||||
|
#define SQLBIGVARCHAR 0xa7
|
||||||
|
#define SQLBIGBINARY 0xad
|
||||||
|
#define SQLBIGVARBINARY 0xa5
|
||||||
|
#define SQLBITN 0x68
|
||||||
|
#define SQLNCHAR 0xef
|
||||||
|
#define SQLNVARCHAR 0xe7
|
||||||
|
#define SQLNTEXT 0x63
|
||||||
|
// New types for SQL 2000 and later servers
|
||||||
|
#define SQLINT8 0x7f
|
||||||
|
#define SQLVARIANT 0x62
|
||||||
|
// New types for SQL 2005 and later servers
|
||||||
|
#define SQLUDT 0xf0
|
||||||
|
#define SQLXML 0xf1
|
||||||
|
// New types for SQL 2008 and later servers
|
||||||
|
#define SQLTABLE 0xf3
|
||||||
|
#define SQLDATEN 0x28
|
||||||
|
#define SQLTIMEN 0x29
|
||||||
|
#define SQLDATETIME2N 0x2a
|
||||||
|
#define SQLDATETIMEOFFSETN 0x2b
|
||||||
|
// Define old names
|
||||||
|
#define SQLDECIMALN 0x6a
|
||||||
|
#define SQLNUMERICN 0x6c
|
||||||
|
#endif // SQLNCLI_NO_BCP
|
||||||
|
|
||||||
|
// SQL_SS_LENGTH_UNLIMITED is used to describe the max length of
|
||||||
|
// VARCHAR(max), VARBINARY(max), NVARCHAR(max), and XML columns
|
||||||
|
#define SQL_SS_LENGTH_UNLIMITED 0
|
||||||
|
|
||||||
|
// User Data Type definitions.
|
||||||
|
// Returned by SQLColAttributes/SQL_CA_SS_COLUMN_UTYPE.
|
||||||
|
#define SQLudtBINARY 3
|
||||||
|
#define SQLudtBIT 16
|
||||||
|
#define SQLudtBITN 0
|
||||||
|
#define SQLudtCHAR 1
|
||||||
|
#define SQLudtDATETIM4 22
|
||||||
|
#define SQLudtDATETIME 12
|
||||||
|
#define SQLudtDATETIMN 15
|
||||||
|
#define SQLudtDECML 24
|
||||||
|
#define SQLudtDECMLN 26
|
||||||
|
#define SQLudtFLT4 23
|
||||||
|
#define SQLudtFLT8 8
|
||||||
|
#define SQLudtFLTN 14
|
||||||
|
#define SQLudtIMAGE 20
|
||||||
|
#define SQLudtINT1 5
|
||||||
|
#define SQLudtINT2 6
|
||||||
|
#define SQLudtINT4 7
|
||||||
|
#define SQLudtINTN 13
|
||||||
|
#define SQLudtMONEY 11
|
||||||
|
#define SQLudtMONEY4 21
|
||||||
|
#define SQLudtMONEYN 17
|
||||||
|
#define SQLudtNUM 10
|
||||||
|
#define SQLudtNUMN 25
|
||||||
|
#define SQLudtSYSNAME 18
|
||||||
|
#define SQLudtTEXT 19
|
||||||
|
#define SQLudtTIMESTAMP 80
|
||||||
|
#define SQLudtUNIQUEIDENTIFIER 0
|
||||||
|
#define SQLudtVARBINARY 4
|
||||||
|
#define SQLudtVARCHAR 2
|
||||||
|
#define MIN_USER_DATATYPE 256
|
||||||
|
// Aggregate operator types.
|
||||||
|
// Returned by SQLColAttributes/SQL_CA_SS_COLUMN_OP.
|
||||||
|
#define SQLAOPSTDEV 0x30 // Standard deviation
|
||||||
|
#define SQLAOPSTDEVP 0x31 // Standard deviation population
|
||||||
|
#define SQLAOPVAR 0x32 // Variance
|
||||||
|
#define SQLAOPVARP 0x33 // Variance population
|
||||||
|
#define SQLAOPCNT 0x4b // Count
|
||||||
|
#define SQLAOPSUM 0x4d // Sum
|
||||||
|
#define SQLAOPAVG 0x4f // Average
|
||||||
|
#define SQLAOPMIN 0x51 // Min
|
||||||
|
#define SQLAOPMAX 0x52 // Max
|
||||||
|
#define SQLAOPANY 0x53 // Any
|
||||||
|
#define SQLAOPNOOP 0x56 // None
|
||||||
|
// SQLGetInfo driver specific defines.
|
||||||
|
// Microsoft has 1151 thru 1200 reserved for Microsoft SQL Server Native Client driver usage.
|
||||||
|
#define SQL_INFO_SS_FIRST 1199
|
||||||
|
#define SQL_INFO_SS_NETLIB_NAMEW (SQL_INFO_SS_FIRST+0) // dbprocinfo
|
||||||
|
#define SQL_INFO_SS_NETLIB_NAMEA (SQL_INFO_SS_FIRST+1) // dbprocinfo
|
||||||
|
#define SQL_INFO_SS_MAX_USED SQL_INFO_SS_NETLIB_NAMEA
|
||||||
|
#ifdef UNICODE
|
||||||
|
#define SQL_INFO_SS_NETLIB_NAME SQL_INFO_SS_NETLIB_NAMEW
|
||||||
|
#else
|
||||||
|
#define SQL_INFO_SS_NETLIB_NAME SQL_INFO_SS_NETLIB_NAMEA
|
||||||
|
#endif
|
||||||
|
// SQLGetDiagField driver specific defines.
|
||||||
|
// Microsoft has -1150 thru -1199 reserved for Microsoft SQL Server Native Client driver usage.
|
||||||
|
#define SQL_DIAG_SS_BASE (-1150)
|
||||||
|
#define SQL_DIAG_SS_MSGSTATE (SQL_DIAG_SS_BASE)
|
||||||
|
#define SQL_DIAG_SS_SEVERITY (SQL_DIAG_SS_BASE-1)
|
||||||
|
#define SQL_DIAG_SS_SRVNAME (SQL_DIAG_SS_BASE-2)
|
||||||
|
#define SQL_DIAG_SS_PROCNAME (SQL_DIAG_SS_BASE-3)
|
||||||
|
#define SQL_DIAG_SS_LINE (SQL_DIAG_SS_BASE-4)
|
||||||
|
// SQLGetDiagField/SQL_DIAG_DYNAMIC_FUNCTION_CODE driver specific defines.
|
||||||
|
// Microsoft has -200 thru -299 reserved for Microsoft SQL Server Native Client driver usage.
|
||||||
|
#define SQL_DIAG_DFC_SS_BASE (-200)
|
||||||
|
#define SQL_DIAG_DFC_SS_ALTER_DATABASE (SQL_DIAG_DFC_SS_BASE-0)
|
||||||
|
#define SQL_DIAG_DFC_SS_CHECKPOINT (SQL_DIAG_DFC_SS_BASE-1)
|
||||||
|
#define SQL_DIAG_DFC_SS_CONDITION (SQL_DIAG_DFC_SS_BASE-2)
|
||||||
|
#define SQL_DIAG_DFC_SS_CREATE_DATABASE (SQL_DIAG_DFC_SS_BASE-3)
|
||||||
|
#define SQL_DIAG_DFC_SS_CREATE_DEFAULT (SQL_DIAG_DFC_SS_BASE-4)
|
||||||
|
#define SQL_DIAG_DFC_SS_CREATE_PROCEDURE (SQL_DIAG_DFC_SS_BASE-5)
|
||||||
|
#define SQL_DIAG_DFC_SS_CREATE_RULE (SQL_DIAG_DFC_SS_BASE-6)
|
||||||
|
#define SQL_DIAG_DFC_SS_CREATE_TRIGGER (SQL_DIAG_DFC_SS_BASE-7)
|
||||||
|
#define SQL_DIAG_DFC_SS_CURSOR_DECLARE (SQL_DIAG_DFC_SS_BASE-8)
|
||||||
|
#define SQL_DIAG_DFC_SS_CURSOR_OPEN (SQL_DIAG_DFC_SS_BASE-9)
|
||||||
|
#define SQL_DIAG_DFC_SS_CURSOR_FETCH (SQL_DIAG_DFC_SS_BASE-10)
|
||||||
|
#define SQL_DIAG_DFC_SS_CURSOR_CLOSE (SQL_DIAG_DFC_SS_BASE-11)
|
||||||
|
#define SQL_DIAG_DFC_SS_DEALLOCATE_CURSOR (SQL_DIAG_DFC_SS_BASE-12)
|
||||||
|
#define SQL_DIAG_DFC_SS_DBCC (SQL_DIAG_DFC_SS_BASE-13)
|
||||||
|
#define SQL_DIAG_DFC_SS_DISK (SQL_DIAG_DFC_SS_BASE-14)
|
||||||
|
#define SQL_DIAG_DFC_SS_DROP_DATABASE (SQL_DIAG_DFC_SS_BASE-15)
|
||||||
|
#define SQL_DIAG_DFC_SS_DROP_DEFAULT (SQL_DIAG_DFC_SS_BASE-16)
|
||||||
|
#define SQL_DIAG_DFC_SS_DROP_PROCEDURE (SQL_DIAG_DFC_SS_BASE-17)
|
||||||
|
#define SQL_DIAG_DFC_SS_DROP_RULE (SQL_DIAG_DFC_SS_BASE-18)
|
||||||
|
#define SQL_DIAG_DFC_SS_DROP_TRIGGER (SQL_DIAG_DFC_SS_BASE-19)
|
||||||
|
#define SQL_DIAG_DFC_SS_DUMP_DATABASE (SQL_DIAG_DFC_SS_BASE-20)
|
||||||
|
#define SQL_DIAG_DFC_SS_BACKUP_DATABASE (SQL_DIAG_DFC_SS_BASE-20)
|
||||||
|
#define SQL_DIAG_DFC_SS_DUMP_TABLE (SQL_DIAG_DFC_SS_BASE-21)
|
||||||
|
#define SQL_DIAG_DFC_SS_DUMP_TRANSACTION (SQL_DIAG_DFC_SS_BASE-22)
|
||||||
|
#define SQL_DIAG_DFC_SS_BACKUP_TRANSACTION (SQL_DIAG_DFC_SS_BASE-22)
|
||||||
|
#define SQL_DIAG_DFC_SS_GOTO (SQL_DIAG_DFC_SS_BASE-23)
|
||||||
|
#define SQL_DIAG_DFC_SS_INSERT_BULK (SQL_DIAG_DFC_SS_BASE-24)
|
||||||
|
#define SQL_DIAG_DFC_SS_KILL (SQL_DIAG_DFC_SS_BASE-25)
|
||||||
|
#define SQL_DIAG_DFC_SS_LOAD_DATABASE (SQL_DIAG_DFC_SS_BASE-26)
|
||||||
|
#define SQL_DIAG_DFC_SS_RESTORE_DATABASE (SQL_DIAG_DFC_SS_BASE-26)
|
||||||
|
#define SQL_DIAG_DFC_SS_LOAD_HEADERONLY (SQL_DIAG_DFC_SS_BASE-27)
|
||||||
|
#define SQL_DIAG_DFC_SS_RESTORE_HEADERONLY (SQL_DIAG_DFC_SS_BASE-27)
|
||||||
|
#define SQL_DIAG_DFC_SS_LOAD_TABLE (SQL_DIAG_DFC_SS_BASE-28)
|
||||||
|
#define SQL_DIAG_DFC_SS_LOAD_TRANSACTION (SQL_DIAG_DFC_SS_BASE-29)
|
||||||
|
#define SQL_DIAG_DFC_SS_RESTORE_TRANSACTION (SQL_DIAG_DFC_SS_BASE-29)
|
||||||
|
#define SQL_DIAG_DFC_SS_PRINT (SQL_DIAG_DFC_SS_BASE-30)
|
||||||
|
#define SQL_DIAG_DFC_SS_RAISERROR (SQL_DIAG_DFC_SS_BASE-31)
|
||||||
|
#define SQL_DIAG_DFC_SS_READTEXT (SQL_DIAG_DFC_SS_BASE-32)
|
||||||
|
#define SQL_DIAG_DFC_SS_RECONFIGURE (SQL_DIAG_DFC_SS_BASE-33)
|
||||||
|
#define SQL_DIAG_DFC_SS_RETURN (SQL_DIAG_DFC_SS_BASE-34)
|
||||||
|
#define SQL_DIAG_DFC_SS_SELECT_INTO (SQL_DIAG_DFC_SS_BASE-35)
|
||||||
|
#define SQL_DIAG_DFC_SS_SET (SQL_DIAG_DFC_SS_BASE-36)
|
||||||
|
#define SQL_DIAG_DFC_SS_SET_IDENTITY_INSERT (SQL_DIAG_DFC_SS_BASE-37)
|
||||||
|
#define SQL_DIAG_DFC_SS_SET_ROW_COUNT (SQL_DIAG_DFC_SS_BASE-38)
|
||||||
|
#define SQL_DIAG_DFC_SS_SET_STATISTICS (SQL_DIAG_DFC_SS_BASE-39)
|
||||||
|
#define SQL_DIAG_DFC_SS_SET_TEXTSIZE (SQL_DIAG_DFC_SS_BASE-40)
|
||||||
|
#define SQL_DIAG_DFC_SS_SETUSER (SQL_DIAG_DFC_SS_BASE-41)
|
||||||
|
#define SQL_DIAG_DFC_SS_SHUTDOWN (SQL_DIAG_DFC_SS_BASE-42)
|
||||||
|
#define SQL_DIAG_DFC_SS_TRANS_BEGIN (SQL_DIAG_DFC_SS_BASE-43)
|
||||||
|
#define SQL_DIAG_DFC_SS_TRANS_COMMIT (SQL_DIAG_DFC_SS_BASE-44)
|
||||||
|
#define SQL_DIAG_DFC_SS_TRANS_PREPARE (SQL_DIAG_DFC_SS_BASE-45)
|
||||||
|
#define SQL_DIAG_DFC_SS_TRANS_ROLLBACK (SQL_DIAG_DFC_SS_BASE-46)
|
||||||
|
#define SQL_DIAG_DFC_SS_TRANS_SAVE (SQL_DIAG_DFC_SS_BASE-47)
|
||||||
|
#define SQL_DIAG_DFC_SS_TRUNCATE_TABLE (SQL_DIAG_DFC_SS_BASE-48)
|
||||||
|
#define SQL_DIAG_DFC_SS_UPDATE_STATISTICS (SQL_DIAG_DFC_SS_BASE-49)
|
||||||
|
#define SQL_DIAG_DFC_SS_UPDATETEXT (SQL_DIAG_DFC_SS_BASE-50)
|
||||||
|
#define SQL_DIAG_DFC_SS_USE (SQL_DIAG_DFC_SS_BASE-51)
|
||||||
|
#define SQL_DIAG_DFC_SS_WAITFOR (SQL_DIAG_DFC_SS_BASE-52)
|
||||||
|
#define SQL_DIAG_DFC_SS_WRITETEXT (SQL_DIAG_DFC_SS_BASE-53)
|
||||||
|
#define SQL_DIAG_DFC_SS_DENY (SQL_DIAG_DFC_SS_BASE-54)
|
||||||
|
#define SQL_DIAG_DFC_SS_SET_XCTLVL (SQL_DIAG_DFC_SS_BASE-55)
|
||||||
|
#define SQL_DIAG_DFC_SS_MERGE (SQL_DIAG_DFC_SS_BASE-56)
|
||||||
|
|
||||||
|
// Severity codes for SQL_DIAG_SS_SEVERITY
|
||||||
|
#define EX_ANY 0
|
||||||
|
#define EX_INFO 10
|
||||||
|
#define EX_MAXISEVERITY EX_INFO
|
||||||
|
#define EX_MISSING 11
|
||||||
|
#define EX_TYPE 12
|
||||||
|
#define EX_DEADLOCK 13
|
||||||
|
#define EX_PERMIT 14
|
||||||
|
#define EX_SYNTAX 15
|
||||||
|
#define EX_USER 16
|
||||||
|
#define EX_RESOURCE 17
|
||||||
|
#define EX_INTOK 18
|
||||||
|
#define MAXUSEVERITY EX_INTOK
|
||||||
|
#define EX_LIMIT 19
|
||||||
|
#define EX_CMDFATAL 20
|
||||||
|
#define MINFATALERR EX_CMDFATAL
|
||||||
|
#define EX_DBFATAL 21
|
||||||
|
#define EX_TABCORRUPT 22
|
||||||
|
#define EX_DBCORRUPT 23
|
||||||
|
#define EX_HARDWARE 24
|
||||||
|
#define EX_CONTROL 25
|
||||||
|
// Internal server datatypes - used when binding to SQL_C_BINARY
|
||||||
|
#ifndef MAXNUMERICLEN // Resolve ODS/DBLib conflicts
|
||||||
|
// DB-Library datatypes
|
||||||
|
#define DBMAXCHAR (8000+1) // Max length of DBVARBINARY and DBVARCHAR, etc. +1 for zero byte
|
||||||
|
#define MAXNAME (SQL_MAX_SQLSERVERNAME+1) // Max server identifier length including zero byte
|
||||||
|
#ifdef UNICODE
|
||||||
|
typedef wchar_t DBCHAR;
|
||||||
|
#else
|
||||||
|
typedef char DBCHAR;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
typedef short SQLSMALLINT;
|
||||||
|
|
||||||
|
typedef unsigned short SQLUSMALLINT;
|
||||||
|
|
||||||
|
typedef long SQLINTEGER;
|
||||||
|
|
||||||
|
typedef unsigned long SQLUINTEGER;
|
||||||
|
|
||||||
|
typedef unsigned char DBBINARY;
|
||||||
|
|
||||||
|
typedef unsigned char DBTINYINT;
|
||||||
|
|
||||||
|
typedef short DBSMALLINT;
|
||||||
|
|
||||||
|
typedef unsigned short DBUSMALLINT;
|
||||||
|
|
||||||
|
typedef double DBFLT8;
|
||||||
|
|
||||||
|
typedef unsigned char DBBIT;
|
||||||
|
|
||||||
|
typedef unsigned char DBBOOL;
|
||||||
|
|
||||||
|
typedef float DBFLT4;
|
||||||
|
|
||||||
|
typedef DBFLT4 DBREAL;
|
||||||
|
|
||||||
|
typedef UINT DBUBOOL;
|
||||||
|
|
||||||
|
typedef struct dbmoney
|
||||||
|
{
|
||||||
|
LONG mnyhigh;
|
||||||
|
ULONG mnylow;
|
||||||
|
} DBMONEY;
|
||||||
|
|
||||||
|
typedef struct dbdatetime
|
||||||
|
{
|
||||||
|
LONG dtdays;
|
||||||
|
ULONG dttime;
|
||||||
|
} DBDATETIME;
|
||||||
|
|
||||||
|
typedef struct dbdatetime4
|
||||||
|
{
|
||||||
|
USHORT numdays;
|
||||||
|
USHORT nummins;
|
||||||
|
} DBDATETIM4;
|
||||||
|
|
||||||
|
typedef LONG DBMONEY4;
|
||||||
|
|
||||||
|
#include <pshpack8.h> // 8-byte structure packing
|
||||||
|
|
||||||
|
// New Date Time Structures
|
||||||
|
// New Structure for TIME2
|
||||||
|
typedef struct tagSS_TIME2_STRUCT
|
||||||
|
{
|
||||||
|
SQLUSMALLINT hour;
|
||||||
|
SQLUSMALLINT minute;
|
||||||
|
SQLUSMALLINT second;
|
||||||
|
SQLUINTEGER fraction;
|
||||||
|
} SQL_SS_TIME2_STRUCT;
|
||||||
|
|
||||||
|
// New Structure for TIMESTAMPOFFSET
|
||||||
|
typedef struct tagSS_TIMESTAMPOFFSET_STRUCT
|
||||||
|
{
|
||||||
|
SQLSMALLINT year;
|
||||||
|
SQLUSMALLINT month;
|
||||||
|
SQLUSMALLINT day;
|
||||||
|
SQLUSMALLINT hour;
|
||||||
|
SQLUSMALLINT minute;
|
||||||
|
SQLUSMALLINT second;
|
||||||
|
SQLUINTEGER fraction;
|
||||||
|
SQLSMALLINT timezone_hour;
|
||||||
|
SQLSMALLINT timezone_minute;
|
||||||
|
} SQL_SS_TIMESTAMPOFFSET_STRUCT;
|
||||||
|
|
||||||
|
#include <poppack.h> // restore original structure packing
|
||||||
|
|
||||||
|
// Money value *10,000
|
||||||
|
#define DBNUM_PREC_TYPE BYTE
|
||||||
|
#define DBNUM_SCALE_TYPE BYTE
|
||||||
|
#define DBNUM_VAL_TYPE BYTE
|
||||||
|
|
||||||
|
#if (ODBCVER < 0x0300)
|
||||||
|
#define MAXNUMERICLEN 16
|
||||||
|
typedef struct dbnumeric // Internal representation of NUMERIC data type
|
||||||
|
{
|
||||||
|
DBNUM_PREC_TYPE precision; // Precision
|
||||||
|
DBNUM_SCALE_TYPE scale; // Scale
|
||||||
|
BYTE sign; // Sign (1 if positive, 0 if negative)
|
||||||
|
DBNUM_VAL_TYPE val[MAXNUMERICLEN];// Value
|
||||||
|
} DBNUMERIC;
|
||||||
|
typedef DBNUMERIC DBDECIMAL;// Internal representation of DECIMAL data type
|
||||||
|
#else // Use ODBC 3.0 definitions since same as DBLib
|
||||||
|
#define MAXNUMERICLEN SQL_MAX_NUMERIC_LEN
|
||||||
|
typedef SQL_NUMERIC_STRUCT DBNUMERIC;
|
||||||
|
typedef SQL_NUMERIC_STRUCT DBDECIMAL;
|
||||||
|
#endif // ODCBVER
|
||||||
|
#endif // MAXNUMERICLEN
|
||||||
|
|
||||||
|
#ifndef INT
|
||||||
|
typedef int INT;
|
||||||
|
typedef long DBINT;
|
||||||
|
typedef DBINT * LPDBINT;
|
||||||
|
#ifndef _LPCBYTE_DEFINED
|
||||||
|
#define _LPCBYTE_DEFINED
|
||||||
|
typedef BYTE const* LPCBYTE;
|
||||||
|
#endif //_LPCBYTE_DEFINED
|
||||||
|
#endif // INT
|
||||||
|
/**************************************************************************
|
||||||
|
This struct is a global used for gathering statistical data on the driver.
|
||||||
|
Access to this structure is controlled via the pStatCrit;
|
||||||
|
***************************************************************************/
|
||||||
|
typedef struct sqlperf
|
||||||
|
{
|
||||||
|
// Application Profile Statistics
|
||||||
|
DWORD TimerResolution;
|
||||||
|
DWORD SQLidu;
|
||||||
|
DWORD SQLiduRows;
|
||||||
|
DWORD SQLSelects;
|
||||||
|
DWORD SQLSelectRows;
|
||||||
|
DWORD Transactions;
|
||||||
|
DWORD SQLPrepares;
|
||||||
|
DWORD ExecDirects;
|
||||||
|
DWORD SQLExecutes;
|
||||||
|
DWORD CursorOpens;
|
||||||
|
DWORD CursorSize;
|
||||||
|
DWORD CursorUsed;
|
||||||
|
LDOUBLE PercentCursorUsed;
|
||||||
|
LDOUBLE AvgFetchTime;
|
||||||
|
LDOUBLE AvgCursorSize;
|
||||||
|
LDOUBLE AvgCursorUsed;
|
||||||
|
DWORD SQLFetchTime;
|
||||||
|
DWORD SQLFetchCount;
|
||||||
|
DWORD CurrentStmtCount;
|
||||||
|
DWORD MaxOpenStmt;
|
||||||
|
DWORD SumOpenStmt;
|
||||||
|
// Connection Statistics
|
||||||
|
DWORD CurrentConnectionCount;
|
||||||
|
DWORD MaxConnectionsOpened;
|
||||||
|
DWORD SumConnectionsOpened;
|
||||||
|
DWORD SumConnectiontime;
|
||||||
|
LDOUBLE AvgTimeOpened;
|
||||||
|
// Network Statistics
|
||||||
|
DWORD ServerRndTrips;
|
||||||
|
DWORD BuffersSent;
|
||||||
|
DWORD BuffersRec;
|
||||||
|
DWORD BytesSent;
|
||||||
|
DWORD BytesRec;
|
||||||
|
// Time Statistics;
|
||||||
|
DWORD msExecutionTime;
|
||||||
|
DWORD msNetWorkServerTime;
|
||||||
|
} SQLPERF;
|
||||||
|
// The following are options for SQL_COPT_SS_PERF_DATA and SQL_COPT_SS_PERF_QUERY
|
||||||
|
#define SQL_PERF_START 1 // Starts the driver sampling performance data.
|
||||||
|
#define SQL_PERF_STOP 2 // Stops the counters from sampling performance data.
|
||||||
|
// The following are defines for SQL_COPT_SS_PERF_DATA_LOG
|
||||||
|
#define SQL_SS_DL_DEFAULT TEXT("STATS.LOG")
|
||||||
|
// The following are defines for SQL_COPT_SS_PERF_QUERY_LOG
|
||||||
|
#define SQL_SS_QL_DEFAULT TEXT("QUERY.LOG")
|
||||||
|
// The following are defines for SQL_COPT_SS_PERF_QUERY_INTERVAL
|
||||||
|
#define SQL_SS_QI_DEFAULT 30000 // 30,000 milliseconds
|
||||||
|
|
||||||
|
#ifndef SQLNCLI_NO_BCP
|
||||||
|
// Define the symbol SQLNCLI_NO_BCP if you are not using BCP in your application
|
||||||
|
// and you want to exclude the BCP-related definitions in this header file.
|
||||||
|
|
||||||
|
// ODBC BCP prototypes and defines
|
||||||
|
// Return codes
|
||||||
|
#define SUCCEED 1
|
||||||
|
#define FAIL 0
|
||||||
|
#define SUCCEED_ABORT 2
|
||||||
|
#define SUCCEED_ASYNC 3
|
||||||
|
// Transfer directions
|
||||||
|
#define DB_IN 1 // Transfer from client to server
|
||||||
|
#define DB_OUT 2 // Transfer from server to client
|
||||||
|
// bcp_control option
|
||||||
|
#define BCPMAXERRS 1 // Sets max errors allowed
|
||||||
|
#define BCPFIRST 2 // Sets first row to be copied out
|
||||||
|
#define BCPLAST 3 // Sets number of rows to be copied out
|
||||||
|
#define BCPBATCH 4 // Sets input batch size
|
||||||
|
#define BCPKEEPNULLS 5 // Sets to insert NULLs for empty input values
|
||||||
|
#define BCPABORT 6 // Sets to have bcpexec return SUCCEED_ABORT
|
||||||
|
#define BCPODBC 7 // Sets ODBC canonical character output
|
||||||
|
#define BCPKEEPIDENTITY 8 // Sets IDENTITY_INSERT on
|
||||||
|
#if SQLNCLI_VER < 1000
|
||||||
|
#define BCP6xFILEFMT 9 // DEPRECATED: Sets 6x file format on
|
||||||
|
#endif
|
||||||
|
#define BCPHINTSA 10 // Sets server BCP hints (ANSI string)
|
||||||
|
#define BCPHINTSW 11 // Sets server BCP hints (UNICODE string)
|
||||||
|
#define BCPFILECP 12 // Sets clients code page for the file
|
||||||
|
#define BCPUNICODEFILE 13 // Sets that the file contains unicode header
|
||||||
|
#define BCPTEXTFILE 14 // Sets BCP mode to expect a text file and to detect Unicode or ANSI automatically
|
||||||
|
#define BCPFILEFMT 15 // Sets file format version
|
||||||
|
#define BCPFMTXML 16 // Sets the format file type to xml
|
||||||
|
#define BCPFIRSTEX 17 // Starting Row for BCP operation (64 bit)
|
||||||
|
#define BCPLASTEX 18 // Ending Row for BCP operation (64 bit)
|
||||||
|
#define BCPROWCOUNT 19 // Total Number of Rows Copied (64 bit)
|
||||||
|
// BCPFILECP values
|
||||||
|
// Any valid code page that is installed on the client can be passed plus:
|
||||||
|
#define BCPFILECP_ACP 0 // Data in file is in Windows code page
|
||||||
|
#define BCPFILECP_OEMCP 1 // Data in file is in OEM code page (default)
|
||||||
|
#define BCPFILECP_RAW (-1)// Data in file is in Server code page (no conversion)
|
||||||
|
// bcp_collen definition
|
||||||
|
#define SQL_VARLEN_DATA (-10) // Use default length for column
|
||||||
|
// BCP column format properties
|
||||||
|
#define BCP_FMT_TYPE 0x01
|
||||||
|
#define BCP_FMT_INDICATOR_LEN 0x02
|
||||||
|
#define BCP_FMT_DATA_LEN 0x03
|
||||||
|
#define BCP_FMT_TERMINATOR 0x04
|
||||||
|
#define BCP_FMT_SERVER_COL 0x05
|
||||||
|
#define BCP_FMT_COLLATION 0x06
|
||||||
|
#define BCP_FMT_COLLATION_ID 0x07
|
||||||
|
// BCP functions
|
||||||
|
DBINT SQL_API bcp_batch (HDBC);
|
||||||
|
RETCODE SQL_API bcp_bind (HDBC, LPCBYTE, INT, DBINT, LPCBYTE, INT, INT, INT);
|
||||||
|
RETCODE SQL_API bcp_colfmt (HDBC, INT, BYTE, INT, DBINT, LPCBYTE, INT, INT);
|
||||||
|
RETCODE SQL_API bcp_collen (HDBC, DBINT, INT);
|
||||||
|
RETCODE SQL_API bcp_colptr (HDBC, LPCBYTE, INT);
|
||||||
|
RETCODE SQL_API bcp_columns (HDBC, INT);
|
||||||
|
RETCODE SQL_API bcp_control (HDBC, INT, void *);
|
||||||
|
DBINT SQL_API bcp_done (HDBC);
|
||||||
|
RETCODE SQL_API bcp_exec (HDBC, LPDBINT);
|
||||||
|
RETCODE SQL_API bcp_getcolfmt (HDBC, INT, INT, void *, INT, INT *);
|
||||||
|
RETCODE SQL_API bcp_initA (HDBC, LPCSTR, LPCSTR, LPCSTR, INT);
|
||||||
|
RETCODE SQL_API bcp_initW (HDBC, LPCWSTR, LPCWSTR, LPCWSTR, INT);
|
||||||
|
RETCODE SQL_API bcp_moretext (HDBC, DBINT, LPCBYTE);
|
||||||
|
RETCODE SQL_API bcp_readfmtA (HDBC, LPCSTR);
|
||||||
|
RETCODE SQL_API bcp_readfmtW (HDBC, LPCWSTR);
|
||||||
|
RETCODE SQL_API bcp_sendrow (HDBC);
|
||||||
|
RETCODE SQL_API bcp_setcolfmt (HDBC, INT, INT, void *, INT);
|
||||||
|
RETCODE SQL_API bcp_writefmtA (HDBC, LPCSTR);
|
||||||
|
RETCODE SQL_API bcp_writefmtW (HDBC, LPCWSTR);
|
||||||
|
CHAR* SQL_API dbprtypeA (INT);
|
||||||
|
WCHAR* SQL_API dbprtypeW (INT);
|
||||||
|
CHAR* SQL_API bcp_gettypenameA (INT, DBBOOL);
|
||||||
|
WCHAR* SQL_API bcp_gettypenameW (INT, DBBOOL);
|
||||||
|
#ifdef UNICODE
|
||||||
|
#define bcp_init bcp_initW
|
||||||
|
#define bcp_readfmt bcp_readfmtW
|
||||||
|
#define bcp_writefmt bcp_writefmtW
|
||||||
|
#define dbprtype dbprtypeW
|
||||||
|
#define bcp_gettypename bcp_gettypenameW
|
||||||
|
#define BCPHINTS BCPHINTSW
|
||||||
|
#else
|
||||||
|
#define bcp_init bcp_initA
|
||||||
|
#define bcp_readfmt bcp_readfmtA
|
||||||
|
#define bcp_writefmt bcp_writefmtA
|
||||||
|
#define dbprtype dbprtypeA
|
||||||
|
#define bcp_gettypename bcp_gettypenameA
|
||||||
|
#define BCPHINTS BCPHINTSA
|
||||||
|
#endif // UNICODE
|
||||||
|
|
||||||
|
#endif // SQLNCLI_NO_BCP
|
||||||
|
|
||||||
|
// The following options have been deprecated
|
||||||
|
#define SQL_FAST_CONNECT (SQL_COPT_SS_BASE+0)
|
||||||
|
// Defines for use with SQL_FAST_CONNECT - only useable before connecting
|
||||||
|
#define SQL_FC_OFF 0L // Fast connect is off
|
||||||
|
#define SQL_FC_ON 1L // Fast connect is on
|
||||||
|
#define SQL_FC_DEFAULT SQL_FC_OFF
|
||||||
|
#define SQL_COPT_SS_ANSI_OEM (SQL_COPT_SS_BASE+6)
|
||||||
|
#define SQL_AO_OFF 0L
|
||||||
|
#define SQL_AO_ON 1L
|
||||||
|
#define SQL_AO_DEFAULT SQL_AO_OFF
|
||||||
|
#define SQL_CA_SS_BASE_COLUMN_NAME SQL_DESC_BASE_COLUMN_NAME
|
||||||
|
|
||||||
|
#endif // ODBCVER
|
||||||
|
#endif // defined(_SQLNCLI_ODBC_) || !defined(_SQLNCLI_OLEDB_)
|
||||||
|
// ODBC part of SQL Server Native Client header - end here!
|
||||||
|
|
||||||
|
//The following facilitates opening a handle to a SQL filestream
|
||||||
|
typedef enum _SQL_FILESTREAM_DESIRED_ACCESS {
|
||||||
|
SQL_FILESTREAM_READ = 0,
|
||||||
|
SQL_FILESTREAM_WRITE = 1,
|
||||||
|
SQL_FILESTREAM_READWRITE = 2
|
||||||
|
} SQL_FILESTREAM_DESIRED_ACCESS;
|
||||||
|
#define SQL_FILESTREAM_OPEN_FLAG_ASYNC 0x00000001L
|
||||||
|
#define SQL_FILESTREAM_OPEN_FLAG_NO_BUFFERING 0x00000002L
|
||||||
|
#define SQL_FILESTREAM_OPEN_FLAG_NO_WRITE_THROUGH 0x00000004L
|
||||||
|
#define SQL_FILESTREAM_OPEN_FLAG_SEQUENTIAL_SCAN 0x00000008L
|
||||||
|
#define SQL_FILESTREAM_OPEN_FLAG_RANDOM_ACCESS 0x00000010L
|
||||||
|
HANDLE __stdcall OpenSqlFilestream (
|
||||||
|
LPCWSTR FilestreamPath,
|
||||||
|
SQL_FILESTREAM_DESIRED_ACCESS DesiredAccess,
|
||||||
|
ULONG OpenOptions,
|
||||||
|
LPBYTE FilestreamTransactionContext,
|
||||||
|
SSIZE_T FilestreamTransactionContextLength,
|
||||||
|
PLARGE_INTEGER AllocationSize);
|
||||||
|
#define FSCTL_SQL_FILESTREAM_FETCH_OLD_CONTENT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2392, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern RPC_IF_HANDLE __MIDL_itf_sqlncli_0000_0010_v0_0_c_ifspec;
|
||||||
|
extern RPC_IF_HANDLE __MIDL_itf_sqlncli_0000_0010_v0_0_s_ifspec;
|
||||||
|
|
||||||
|
/* Additional Prototypes for ALL interfaces */
|
||||||
|
|
||||||
|
/* end of Additional Prototypes */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
//
|
//
|
||||||
// Contents: Version resource
|
// Contents: Version resource
|
||||||
//
|
//
|
||||||
// Copyright 2010 Microsoft Corporation
|
// Copyright Microsoft Corporation
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -65,7 +65,7 @@ BEGIN
|
||||||
VALUE "FileDescription", "Microsoft Drivers for PHP for SQL Server (PDO Driver)\0"
|
VALUE "FileDescription", "Microsoft Drivers for PHP for SQL Server (PDO Driver)\0"
|
||||||
VALUE "FileVersion", STRVER4(SQLVERSION_MAJOR,SQLVERSION_MINOR, SQLVERSION_MMDD, SQLVERSION_REVISION)
|
VALUE "FileVersion", STRVER4(SQLVERSION_MAJOR,SQLVERSION_MINOR, SQLVERSION_MMDD, SQLVERSION_REVISION)
|
||||||
VALUE "InternalName", FILE_NAME "\0"
|
VALUE "InternalName", FILE_NAME "\0"
|
||||||
VALUE "LegalCopyright", "Copyright 2010 Microsoft Corporation.\0"
|
VALUE "LegalCopyright", "Copyright Microsoft Corporation.\0"
|
||||||
VALUE "OriginalFilename", FILE_NAME "\0"
|
VALUE "OriginalFilename", FILE_NAME "\0"
|
||||||
VALUE "ProductName", "Microsoft Drivers for PHP for SQL Server\0"
|
VALUE "ProductName", "Microsoft Drivers for PHP for SQL Server\0"
|
||||||
VALUE "ProductVersion", STRVER3(SQLVERSION_MAJOR,SQLVERSION_MINOR, SQLVERSION_MMDD)
|
VALUE "ProductVersion", STRVER3(SQLVERSION_MAJOR,SQLVERSION_MINOR, SQLVERSION_MMDD)
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
//---------------------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------------------
|
||||||
// File: version.h
|
// File: version.h
|
||||||
//
|
//
|
||||||
// Contents: Version information for compile and resources
|
// Contents: Version number constants
|
||||||
//
|
//
|
||||||
// Copyright 2010 Microsoft Corporation
|
// Copyright Microsoft Corporation
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -16,11 +16,11 @@
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//---------------------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
#define VER_FILEVERSION_STR "2.0.0.200"
|
#define VER_FILEVERSION_STR "3.0.0.0"
|
||||||
#define _FILEVERSION 2,0,0,200
|
#define _FILEVERSION 3,0,0,0
|
||||||
#define SQLVERSION_MAJOR 2
|
#define SQLVERSION_MAJOR 3
|
||||||
#define SQLVERSION_MINOR 0
|
#define SQLVERSION_MINOR 0
|
||||||
#define SQLVERSION_MMDD 0
|
#define SQLVERSION_MMDD 0
|
||||||
#define SQLVERSION_REVISION 200
|
#define SQLVERSION_REVISION 0
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Microsoft Drivers for PHP for SQL Server 2.0 Cumulative Update 1
|
Microsoft Drivers 3.0 for PHP for SQL Server (SQLSRV driver)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
* Copyright and License Information *
|
* Copyright and License Information *
|
||||||
|
|
||||||
Copyright 2010 Microsoft Corporation
|
Copyright Microsoft Corporation
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License"); you
|
Licensed under the Apache License, Version 2.0 (the "License"); you
|
||||||
may not use this file except in compliance with the License.
|
may not use this file except in compliance with the License.
|
||||||
|
@ -14,33 +14,25 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
implied. See the License for the specific language governing
|
implied. See the License for the specific language governing
|
||||||
permissions and limitations under the License.
|
permissions and limitations under the License.
|
||||||
|
|
||||||
* Notes about changes to the Microsoft Drivers for PHP for SQL Server
|
* Notes about changes to the Microsoft Drivers 3.0 for PHP for SQL Server *
|
||||||
Driver 2.0 *
|
|
||||||
|
|
||||||
For details about the changes included in this release, please see our blog at
|
For details about the changes included in this release, please see our blog at
|
||||||
http://blogs.msdn.com/sqlphp or see the SQLSRV20_Readme.htm
|
http://blogs.msdn.com/sqlphp or see the SQLSRV_Readme.htm
|
||||||
file that is part of the download package.
|
file that is part of the download package.
|
||||||
|
|
||||||
* Notes about compiling the Microsoft Drivers for PHP for SQL Server 2.0 *
|
* Notes about compiling the Microsoft Drivers 3.0 for PHP for SQL Server *
|
||||||
|
|
||||||
Prerequisites:
|
Prerequisites:
|
||||||
|
|
||||||
* You must first be able to build PHP without including these
|
* You must first be able to build PHP without including these
|
||||||
extensions. For help with doing this, see xthe official PHP website,
|
extensions. For help with doing this, see the official PHP website,
|
||||||
http://php.net.
|
http://php.net.
|
||||||
|
|
||||||
* The header file sqlncli.h is required to build these extensions. It
|
To compile the SQLSRV30 and PDO_SQLSRV30:
|
||||||
may be installed with the Microsoft SQL Server® 2008 R2 Native Client
|
|
||||||
(found at Microsoft.com)
|
|
||||||
|
|
||||||
To compile the SQLSRV20 and PDO_SQLSRV20:
|
|
||||||
|
|
||||||
1) Copy the source code directories from this repository into the ext
|
1) Copy the source code directories from this repository into the ext
|
||||||
subdirectory.
|
subdirectory.
|
||||||
|
|
||||||
1a) Make sure that sqlncli.h is either on the INCLUDE file path or
|
|
||||||
copied locally to the extension directories.
|
|
||||||
|
|
||||||
2) run buildconf.bat to rebuild the configure.js script to include the
|
2) run buildconf.bat to rebuild the configure.js script to include the
|
||||||
new drivers.
|
new drivers.
|
||||||
|
|
||||||
|
@ -61,8 +53,8 @@ wish to do so, run "nmake clean" first.
|
||||||
php_sqlsrv.dll and php_pdo_sqlsrv.dll to your PHP extension directory.
|
php_sqlsrv.dll and php_pdo_sqlsrv.dll to your PHP extension directory.
|
||||||
Also enable them within your PHP installation's php.ini file.
|
Also enable them within your PHP installation's php.ini file.
|
||||||
|
|
||||||
This software has been compiled and tested under PHP 5.2.10 and PHP 5.3.0
|
This software has been compiled and tested under PHP 5.3.6 and later
|
||||||
using the Visual C++ 2008 Express and Standard compilers.
|
using the Visual C++ 2008 and 2010, Express and Standard compilers.
|
||||||
|
|
||||||
* Note about version.h *
|
* Note about version.h *
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
//
|
//
|
||||||
// Contents: JScript build configuration used by buildconf.bat
|
// Contents: JScript build configuration used by buildconf.bat
|
||||||
//
|
//
|
||||||
// Copyright 2010 Microsoft Corporation
|
// Copyright Microsoft Corporation
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -18,18 +18,20 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//----------------------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
ARG_ENABLE("sqlsrv", "enable MS SQL Server extension", "no");
|
ARG_ENABLE("sqlsrv", "enable Microsoft Drivers for PHP for SQL Server (SQLSRV driver)", "no");
|
||||||
|
|
||||||
if( PHP_SQLSRV != "no" ) {
|
if( PHP_SQLSRV != "no" ) {
|
||||||
|
|
||||||
if (CHECK_LIB("odbc32.lib", "sqlsrv") && CHECK_LIB("odbccp32.lib", "sqlsrv") &&
|
if (CHECK_LIB("odbc32.lib", "sqlsrv") && CHECK_LIB("odbccp32.lib", "sqlsrv") &&
|
||||||
CHECK_LIB("version.lib", "sqlsrv") && CHECK_LIB("psapi.lib", "sqlsrv")) {
|
CHECK_LIB("version.lib", "sqlsrv") && CHECK_LIB("psapi.lib", "sqlsrv")) {
|
||||||
|
|
||||||
EXTENSION("sqlsrv", "conn.cpp init.cpp stmt.cpp util.cpp core_init.cpp core_conn.cpp core_stmt.cpp core_util.cpp core_stream.cpp" )
|
EXTENSION("sqlsrv", "conn.cpp init.cpp stmt.cpp util.cpp core_init.cpp core_conn.cpp core_stmt.cpp core_util.cpp core_stream.cpp core_results.cpp" )
|
||||||
|
|
||||||
CHECK_HEADER_ADD_INCLUDE('sql.h', 'CFLAGS_SQLSRV_ODBC');
|
CHECK_HEADER_ADD_INCLUDE('sql.h', 'CFLAGS_SQLSRV_ODBC');
|
||||||
CHECK_HEADER_ADD_INCLUDE('sqlext.h', 'CFLAGS_SQLSRV_ODBC');
|
CHECK_HEADER_ADD_INCLUDE('sqlext.h', 'CFLAGS_SQLSRV_ODBC');
|
||||||
ADD_FLAG( 'LDFLAGS_SQLSRV', '/NXCOMPAT /DYNAMICBASE' );
|
ADD_FLAG( 'LDFLAGS_SQLSRV', '/NXCOMPAT /DYNAMICBASE' );
|
||||||
|
ADD_FLAG( 'CFLAGS_SQLSRV', '/D ZEND_WIN32_FORCE_INLINE' );
|
||||||
|
ADD_FLAG( 'CFLAGS_SQLSRV', '/D _HAS_CPP0X=0' );
|
||||||
ADD_FLAG( 'CFLAGS_SQLSRV', '/EHsc' );
|
ADD_FLAG( 'CFLAGS_SQLSRV', '/EHsc' );
|
||||||
ADD_FLAG( 'CFLAGS_SQLSRV', '/GS' );
|
ADD_FLAG( 'CFLAGS_SQLSRV', '/GS' );
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
//
|
//
|
||||||
// Contents: Routines that use connection handles
|
// Contents: Routines that use connection handles
|
||||||
//
|
//
|
||||||
// Copyright 2010 Microsoft Corporation
|
// Copyright Microsoft Corporation
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -162,6 +162,7 @@ namespace SSStmtOptionNames {
|
||||||
const char QUERY_TIMEOUT[]= "QueryTimeout";
|
const char QUERY_TIMEOUT[]= "QueryTimeout";
|
||||||
const char SEND_STREAMS_AT_EXEC[] = "SendStreamParamsAtExec";
|
const char SEND_STREAMS_AT_EXEC[] = "SendStreamParamsAtExec";
|
||||||
const char SCROLLABLE[] = "Scrollable";
|
const char SCROLLABLE[] = "Scrollable";
|
||||||
|
const char CLIENT_BUFFER_MAX_SIZE[] = INI_BUFFERED_QUERY_LIMIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace SSConnOptionNames {
|
namespace SSConnOptionNames {
|
||||||
|
@ -169,6 +170,8 @@ namespace SSConnOptionNames {
|
||||||
// most of these strings are the same for both the sqlsrv_connect connection option
|
// most of these strings are the same for both the sqlsrv_connect connection option
|
||||||
// and the name put into the connection string. MARS is the only one that's different.
|
// and the name put into the connection string. MARS is the only one that's different.
|
||||||
const char APP[] = "APP";
|
const char APP[] = "APP";
|
||||||
|
const char ApplicationIntent[] = "ApplicationIntent";
|
||||||
|
const char AttachDBFileName[] = "AttachDbFileName";
|
||||||
const char CharacterSet[] = "CharacterSet";
|
const char CharacterSet[] = "CharacterSet";
|
||||||
const char ConnectionPooling[] = "ConnectionPooling";
|
const char ConnectionPooling[] = "ConnectionPooling";
|
||||||
const char Database[] = "Database";
|
const char Database[] = "Database";
|
||||||
|
@ -177,6 +180,7 @@ const char Encrypt[] = "Encrypt";
|
||||||
const char Failover_Partner[] = "Failover_Partner";
|
const char Failover_Partner[] = "Failover_Partner";
|
||||||
const char LoginTimeout[] = "LoginTimeout";
|
const char LoginTimeout[] = "LoginTimeout";
|
||||||
const char MARS_Option[] = "MultipleActiveResultSets";
|
const char MARS_Option[] = "MultipleActiveResultSets";
|
||||||
|
const char MultiSubnetFailover[] = "MultiSubnetFailover";
|
||||||
const char PWD[] = "PWD";
|
const char PWD[] = "PWD";
|
||||||
const char QuotedId[] = "QuotedId";
|
const char QuotedId[] = "QuotedId";
|
||||||
const char TraceFile[] = "TraceFile";
|
const char TraceFile[] = "TraceFile";
|
||||||
|
@ -213,6 +217,12 @@ const stmt_option SS_STMT_OPTS[] = {
|
||||||
SQLSRV_STMT_OPTION_SCROLLABLE,
|
SQLSRV_STMT_OPTION_SCROLLABLE,
|
||||||
new stmt_option_scrollable
|
new stmt_option_scrollable
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
SSStmtOptionNames::CLIENT_BUFFER_MAX_SIZE,
|
||||||
|
sizeof( SSStmtOptionNames::CLIENT_BUFFER_MAX_SIZE ),
|
||||||
|
SQLSRV_STMT_OPTION_CLIENT_BUFFER_MAX_SIZE,
|
||||||
|
new stmt_option_buffered_query_limit
|
||||||
|
},
|
||||||
{ NULL, 0, SQLSRV_STMT_OPTION_INVALID, NULL },
|
{ NULL, 0, SQLSRV_STMT_OPTION_INVALID, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -228,6 +238,24 @@ const connection_option SS_CONN_OPTS[] = {
|
||||||
CONN_ATTR_STRING,
|
CONN_ATTR_STRING,
|
||||||
conn_str_append_func::func
|
conn_str_append_func::func
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
SSConnOptionNames::ApplicationIntent,
|
||||||
|
sizeof( SSConnOptionNames::ApplicationIntent ),
|
||||||
|
SQLSRV_CONN_OPTION_APPLICATION_INTENT,
|
||||||
|
ODBCConnOptions::ApplicationIntent,
|
||||||
|
sizeof( ODBCConnOptions::ApplicationIntent ),
|
||||||
|
CONN_ATTR_STRING,
|
||||||
|
conn_str_append_func::func
|
||||||
|
},
|
||||||
|
{
|
||||||
|
SSConnOptionNames::AttachDBFileName,
|
||||||
|
sizeof( SSConnOptionNames::AttachDBFileName ),
|
||||||
|
SQLSRV_CONN_OPTION_ATTACHDBFILENAME,
|
||||||
|
ODBCConnOptions::AttachDBFileName,
|
||||||
|
sizeof( ODBCConnOptions::AttachDBFileName ),
|
||||||
|
CONN_ATTR_STRING,
|
||||||
|
conn_str_append_func::func
|
||||||
|
},
|
||||||
{
|
{
|
||||||
SSConnOptionNames::CharacterSet,
|
SSConnOptionNames::CharacterSet,
|
||||||
sizeof( SSConnOptionNames::CharacterSet ),
|
sizeof( SSConnOptionNames::CharacterSet ),
|
||||||
|
@ -291,6 +319,15 @@ const connection_option SS_CONN_OPTS[] = {
|
||||||
CONN_ATTR_BOOL,
|
CONN_ATTR_BOOL,
|
||||||
bool_conn_str_func::func
|
bool_conn_str_func::func
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
SSConnOptionNames::MultiSubnetFailover,
|
||||||
|
sizeof( SSConnOptionNames::MultiSubnetFailover ),
|
||||||
|
SQLSRV_CONN_OPTION_MULTI_SUBNET_FAILOVER,
|
||||||
|
ODBCConnOptions::MultiSubnetFailover,
|
||||||
|
sizeof( ODBCConnOptions::MultiSubnetFailover ),
|
||||||
|
CONN_ATTR_BOOL,
|
||||||
|
bool_conn_str_func::func
|
||||||
|
},
|
||||||
{
|
{
|
||||||
SSConnOptionNames::QuotedId,
|
SSConnOptionNames::QuotedId,
|
||||||
sizeof( SSConnOptionNames::QuotedId ),
|
sizeof( SSConnOptionNames::QuotedId ),
|
||||||
|
@ -868,6 +905,19 @@ PHP_FUNCTION( sqlsrv_prepare )
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( params_z && Z_TYPE_P( params_z ) != IS_ARRAY ) {
|
||||||
|
THROW_SS_ERROR( conn, SS_SQLSRV_ERROR_INVALID_FUNCTION_PARAMETER, _FN_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( options_z && Z_TYPE_P( options_z ) != IS_ARRAY ) {
|
||||||
|
THROW_SS_ERROR( conn, SS_SQLSRV_ERROR_INVALID_FUNCTION_PARAMETER, _FN_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( sql == NULL ) {
|
||||||
|
|
||||||
|
DIE( "sqlsrv_query: sql string was null." );
|
||||||
|
}
|
||||||
|
|
||||||
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 TSRMLS_CC ) );
|
||||||
|
@ -979,6 +1029,14 @@ PHP_FUNCTION( sqlsrv_query )
|
||||||
validate_stmt_options( *conn, options_z, ss_stmt_options_ht TSRMLS_CC );
|
validate_stmt_options( *conn, options_z, ss_stmt_options_ht TSRMLS_CC );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( params_z && Z_TYPE_P( params_z ) != IS_ARRAY ) {
|
||||||
|
THROW_SS_ERROR( conn, SS_SQLSRV_ERROR_INVALID_FUNCTION_PARAMETER, _FN_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( options_z && Z_TYPE_P( options_z ) != IS_ARRAY ) {
|
||||||
|
THROW_SS_ERROR( conn, SS_SQLSRV_ERROR_INVALID_FUNCTION_PARAMETER, _FN_ );
|
||||||
|
}
|
||||||
|
|
||||||
if( sql == NULL ) {
|
if( sql == NULL ) {
|
||||||
|
|
||||||
DIE( "sqlsrv_query: sql string was null." );
|
DIE( "sqlsrv_query: sql string was null." );
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
//
|
//
|
||||||
// Contents: Core routines that use connection handles shared between sqlsrv and pdo_sqlsrv
|
// Contents: Core routines that use connection handles shared between sqlsrv and pdo_sqlsrv
|
||||||
//
|
//
|
||||||
// Copyright 2010 Microsoft Corporation
|
// Copyright Microsoft Corporation
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -43,7 +43,7 @@ const int INFO_BUFFER_LEN = 256;
|
||||||
const char* PROCESSOR_ARCH[] = { "x86", "x64", "ia64" };
|
const char* PROCESSOR_ARCH[] = { "x86", "x64", "ia64" };
|
||||||
|
|
||||||
// ODBC driver name.
|
// ODBC driver name.
|
||||||
const char CONNECTION_STRING_DRIVER_NAME[] = "Driver={SQL Server Native Client 10.0};";
|
const char CONNECTION_STRING_DRIVER_NAME[] = "Driver={SQL Server Native Client 11.0};";
|
||||||
|
|
||||||
// default options if only the server is specified
|
// default options if only the server is specified
|
||||||
const char CONNECTION_STRING_DEFAULT_OPTIONS[] = "Mars_Connection={Yes}";
|
const char CONNECTION_STRING_DEFAULT_OPTIONS[] = "Mars_Connection={Yes}";
|
||||||
|
@ -562,6 +562,20 @@ void build_connection_string_and_set_conn_attr( sqlsrv_conn* conn, const char* s
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// workaround for a bug in ODBC Driver Manager wherein the Driver Manager creates a 0 KB file
|
||||||
|
// if the TraceFile option is set, even if the "TraceOn" is not present or the "TraceOn"
|
||||||
|
// flag is set to false.
|
||||||
|
if( zend_hash_index_exists( options, SQLSRV_CONN_OPTION_TRACE_FILE )) {
|
||||||
|
|
||||||
|
zval** trace_value = NULL;
|
||||||
|
int zr = zend_hash_index_find( options, SQLSRV_CONN_OPTION_TRACE_ON, (void**)&trace_value );
|
||||||
|
|
||||||
|
if( zr == FAILURE || !zend_is_true( *trace_value )) {
|
||||||
|
|
||||||
|
zend_hash_index_del( options, SQLSRV_CONN_OPTION_TRACE_FILE );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for( zend_hash_internal_pointer_reset( options );
|
for( zend_hash_internal_pointer_reset( options );
|
||||||
zend_hash_has_more_elements( options ) == SUCCESS;
|
zend_hash_has_more_elements( options ) == SUCCESS;
|
||||||
zend_hash_move_forward( options )) {
|
zend_hash_move_forward( options )) {
|
||||||
|
@ -573,9 +587,9 @@ void build_connection_string_and_set_conn_attr( sqlsrv_conn* conn, const char* s
|
||||||
zval** data = NULL;
|
zval** data = NULL;
|
||||||
|
|
||||||
type = zend_hash_get_current_key_ex( options, &key, &key_len, &index, 0, NULL );
|
type = zend_hash_get_current_key_ex( options, &key, &key_len, &index, 0, NULL );
|
||||||
CHECK_CUSTOM_ERROR(( type != HASH_KEY_IS_LONG ), conn, SQLSRV_ERROR_INVALID_OPTION_KEY ) {
|
|
||||||
throw core::CoreException();
|
// 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." );
|
||||||
|
|
||||||
core::sqlsrv_zend_hash_get_current_data( *conn, options, (void**) &data TSRMLS_CC );
|
core::sqlsrv_zend_hash_get_current_data( *conn, options, (void**) &data TSRMLS_CC );
|
||||||
|
|
||||||
|
@ -660,13 +674,14 @@ void determine_server_version( sqlsrv_conn* conn TSRMLS_DC )
|
||||||
char p[ INFO_BUFFER_LEN ];
|
char p[ INFO_BUFFER_LEN ];
|
||||||
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 TSRMLS_CC );
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
char version_major_str[ 3 ];
|
char version_major_str[ 3 ];
|
||||||
SERVER_VERSION version_major;
|
SERVER_VERSION version_major;
|
||||||
memcpy( version_major_str, p, 2 );
|
memcpy( version_major_str, p, 2 );
|
||||||
version_major_str[ 2 ] = '\0';
|
version_major_str[ 2 ] = '\0';
|
||||||
version_major = static_cast<SERVER_VERSION>( atoi( version_major_str ));
|
version_major = static_cast<SERVER_VERSION>( atoi( version_major_str ));
|
||||||
|
|
||||||
CHECK_CUSTOM_ERROR( version_major == 0 || errno == ERANGE || errno == EINVAL, conn, SQLSRV_ERROR_UNKNOWN_SERVER_VERSION )
|
CHECK_CUSTOM_ERROR( version_major == 0 && ( errno == ERANGE || errno == EINVAL ), conn, SQLSRV_ERROR_UNKNOWN_SERVER_VERSION )
|
||||||
{
|
{
|
||||||
throw core::CoreException();
|
throw core::CoreException();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
//
|
//
|
||||||
// Contents: common initialization routines shared by PDO and sqlsrv
|
// Contents: common initialization routines shared by PDO and sqlsrv
|
||||||
//
|
//
|
||||||
// Copyright 2010 Microsoft Corporation
|
// Copyright Microsoft Corporation
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
|
1338
sqlsrv/core_results.cpp
Normal file
1338
sqlsrv/core_results.cpp
Normal file
|
@ -0,0 +1,1338 @@
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
// File: core_results.cpp
|
||||||
|
//
|
||||||
|
// Contents: Result sets
|
||||||
|
//
|
||||||
|
// Copyright Microsoft Corporation
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
//
|
||||||
|
// You may obtain a copy of the License at:
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "core_sqlsrv.h"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
using namespace core;
|
||||||
|
|
||||||
|
// conversion matrix
|
||||||
|
// each entry holds a function that can perform the conversion or NULL which means the conversion isn't supported
|
||||||
|
// this is initialized the first time the buffered result set is created.
|
||||||
|
sqlsrv_buffered_result_set::conv_matrix_t sqlsrv_buffered_result_set::conv_matrix;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// *** internal types ***
|
||||||
|
|
||||||
|
#pragma warning(disable:4200)
|
||||||
|
|
||||||
|
// *** internal constants ***
|
||||||
|
|
||||||
|
const int INITIAL_FIELD_STRING_LEN = 256; // base allocation size when retrieving a string field
|
||||||
|
|
||||||
|
// *** internal functions ***
|
||||||
|
|
||||||
|
// return an integral type rounded up to a certain number
|
||||||
|
template <int align, typename T>
|
||||||
|
T align_to( T number )
|
||||||
|
{
|
||||||
|
DEBUG_SQLSRV_ASSERT( (number + align) > number, "Number to align overflowed" );
|
||||||
|
return ((number % align) == 0) ? number : (number + align - (number % align));
|
||||||
|
}
|
||||||
|
|
||||||
|
// return a pointer address aligned to a certain address boundary
|
||||||
|
template <int align, typename T>
|
||||||
|
T* align_to( T* ptr )
|
||||||
|
{
|
||||||
|
size_t p_value = (size_t) ptr;
|
||||||
|
return align_to<align, size_t>( p_value );
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the nth bit of the bitstream starting at ptr
|
||||||
|
void set_bit( void* ptr, unsigned int bit )
|
||||||
|
{
|
||||||
|
unsigned char* null_bits = reinterpret_cast<unsigned char*>( ptr );
|
||||||
|
null_bits += bit >> 3;
|
||||||
|
*null_bits |= 1 << ( 7 - ( bit & 0x7 ));
|
||||||
|
}
|
||||||
|
|
||||||
|
// retrieve the nth bit from the bitstream starting at ptr
|
||||||
|
bool get_bit( void* ptr, unsigned int bit )
|
||||||
|
{
|
||||||
|
unsigned char* null_bits = reinterpret_cast<unsigned char*>( ptr );
|
||||||
|
null_bits += bit >> 3;
|
||||||
|
return ((*null_bits & (1 << ( 7 - ( bit & 0x07 )))) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// read in LOB field during buffered result creation
|
||||||
|
SQLPOINTER read_lob_field( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_buffered_result_set::meta_data& meta,
|
||||||
|
unsigned long mem_used TSRMLS_DC );
|
||||||
|
|
||||||
|
// dtor for each row in the cache
|
||||||
|
void cache_row_dtor( void* data );
|
||||||
|
|
||||||
|
// convert a number to a string using locales
|
||||||
|
// There is an extra copy here, but given the size is short (usually <20 bytes) and the complications of
|
||||||
|
// subclassing a new streambuf just to avoid the copy, it's easier to do the copy
|
||||||
|
template <typename Char, typename Number>
|
||||||
|
SQLRETURN number_to_string( Number* number_data, __out void* buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length,
|
||||||
|
sqlsrv_error_auto_ptr& last_error )
|
||||||
|
{
|
||||||
|
std::basic_ostringstream<Char> os;
|
||||||
|
std::locale loc;
|
||||||
|
os.imbue( loc );
|
||||||
|
std::use_facet< std::num_put< Char > >( loc ).put( std::basic_ostream<Char>::_Iter( os.rdbuf() ), os, ' ', *number_data );
|
||||||
|
std::basic_string<Char>& str_num = os.str();
|
||||||
|
|
||||||
|
if( os.fail() ) {
|
||||||
|
last_error = new ( sqlsrv_malloc( sizeof( sqlsrv_error ))) sqlsrv_error(
|
||||||
|
(SQLCHAR*) "IMSSP", (SQLCHAR*) "Failed to convert number to string", -1 );
|
||||||
|
return SQL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( str_num.size() * sizeof(Char) + sizeof(Char) > (size_t) buffer_length ) {
|
||||||
|
last_error = new ( sqlsrv_malloc( sizeof( sqlsrv_error ))) sqlsrv_error(
|
||||||
|
(SQLCHAR*) "HY090", (SQLCHAR*) "Buffer length too small to hold number as string", -1 );
|
||||||
|
return SQL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_buffer_length = str_num.size() * sizeof(Char) + sizeof(Char); // include NULL terminator
|
||||||
|
memcpy( buffer, str_num.c_str(), *out_buffer_length );
|
||||||
|
|
||||||
|
return SQL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Number, typename Char>
|
||||||
|
SQLRETURN string_to_number( Char* string_data, SQLLEN str_len, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length, sqlsrv_error_auto_ptr& last_error )
|
||||||
|
{
|
||||||
|
Number* number_data = reinterpret_cast<Number*>( buffer );
|
||||||
|
std::locale loc; // default locale should match system
|
||||||
|
std::basic_istringstream<Char> is;
|
||||||
|
is.str( string_data );
|
||||||
|
is.imbue( loc );
|
||||||
|
std::ios_base::iostate st = 0;
|
||||||
|
|
||||||
|
std::use_facet< std::num_get< Char > >( loc ).get( std::basic_istream<Char>::_Iter( is.rdbuf( ) ),
|
||||||
|
std::basic_istream<Char>::_Iter(0), is, st, *number_data );
|
||||||
|
|
||||||
|
if( st & std::ios_base::failbit ) {
|
||||||
|
last_error = new ( sqlsrv_malloc( sizeof( sqlsrv_error ))) sqlsrv_error(
|
||||||
|
(SQLCHAR*) "22003", (SQLCHAR*) "Numeric value out of range", 103 );
|
||||||
|
return SQL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_buffer_length = sizeof( Number );
|
||||||
|
|
||||||
|
return SQL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// "closure" for the hash table destructor
|
||||||
|
struct row_dtor_closure {
|
||||||
|
|
||||||
|
sqlsrv_buffered_result_set* results;
|
||||||
|
BYTE* row_data;
|
||||||
|
|
||||||
|
row_dtor_closure( sqlsrv_buffered_result_set* st, BYTE* row ) :
|
||||||
|
results( st ), row_data( row )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
sqlsrv_error* odbc_get_diag_rec( sqlsrv_stmt* odbc, SQLSMALLINT record_number )
|
||||||
|
{
|
||||||
|
SQLWCHAR wsql_state[ SQL_SQLSTATE_BUFSIZE ];
|
||||||
|
SQLCHAR* sql_state = reinterpret_cast<SQLCHAR*>( wsql_state );
|
||||||
|
SQLWCHAR wnative_message[ SQL_MAX_MESSAGE_LENGTH + 1 ];
|
||||||
|
sqlsrv_malloc_auto_ptr<SQLCHAR> native_message;
|
||||||
|
SQLINTEGER native_code;
|
||||||
|
SQLINTEGER message_len;
|
||||||
|
|
||||||
|
SQLRETURN r = SQLGetDiagRecW( SQL_HANDLE_STMT, odbc->handle(), record_number, wsql_state, &native_code, wnative_message,
|
||||||
|
SQL_MAX_MESSAGE_LENGTH + 1, NULL );
|
||||||
|
if( !SQL_SUCCEEDED( r ) || r == SQL_NO_DATA ) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert the error into the encoding of the context
|
||||||
|
SQLSRV_ENCODING enc = odbc->encoding();
|
||||||
|
if( enc == SQLSRV_ENCODING_DEFAULT ) {
|
||||||
|
enc = odbc->conn->encoding();
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert the error into the encoding of the context
|
||||||
|
message_len = SQL_SQLSTATE_BUFSIZE * sizeof(WCHAR);
|
||||||
|
convert_string_from_utf16( enc, reinterpret_cast<char**>( &sql_state ), message_len,
|
||||||
|
false /*no free*/ );
|
||||||
|
message_len = (SQL_MAX_MESSAGE_LENGTH + 1) * sizeof( WCHAR );
|
||||||
|
native_message = reinterpret_cast<SQLCHAR*>( wnative_message );
|
||||||
|
convert_string_from_utf16( enc, reinterpret_cast<char**>( &native_message ), message_len,
|
||||||
|
false /*no free*/ );
|
||||||
|
|
||||||
|
return new (sqlsrv_malloc( sizeof( sqlsrv_error ))) sqlsrv_error( (SQLCHAR*) sql_state, (SQLCHAR*) native_message,
|
||||||
|
native_code );
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// base class result set
|
||||||
|
|
||||||
|
sqlsrv_result_set::sqlsrv_result_set( sqlsrv_stmt* stmt ) :
|
||||||
|
odbc( stmt )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ODBC result set
|
||||||
|
// This object simply wraps ODBC function calls
|
||||||
|
|
||||||
|
sqlsrv_odbc_result_set::sqlsrv_odbc_result_set( sqlsrv_stmt* stmt ) :
|
||||||
|
sqlsrv_result_set( stmt )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlsrv_odbc_result_set::~sqlsrv_odbc_result_set( void )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_odbc_result_set::fetch( SQLSMALLINT orientation, SQLLEN offset TSRMLS_DC )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( odbc != NULL, "Invalid statement handle" );
|
||||||
|
return core::SQLFetchScroll( odbc, orientation, offset TSRMLS_CC );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_odbc_result_set::get_data( SQLUSMALLINT field_index, SQLSMALLINT target_type,
|
||||||
|
__out SQLPOINTER buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length,
|
||||||
|
bool handle_warning TSRMLS_DC )
|
||||||
|
{
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_odbc_result_set::get_diag_field( SQLSMALLINT record_number, SQLSMALLINT diag_identifier,
|
||||||
|
__out SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
|
||||||
|
__out SQLSMALLINT* out_buffer_length TSRMLS_DC )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( odbc != NULL, "Invalid statement handle" );
|
||||||
|
return core::SQLGetDiagField( odbc, record_number, diag_identifier, diag_info_buffer, buffer_length,
|
||||||
|
out_buffer_length TSRMLS_CC );
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlsrv_error* sqlsrv_odbc_result_set::get_diag_rec( SQLSMALLINT record_number )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( odbc != NULL, "Invalid statement handle" );
|
||||||
|
return odbc_get_diag_rec( odbc, record_number );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLLEN sqlsrv_odbc_result_set::row_count( TSRMLS_D )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( odbc != NULL, "Invalid statement handle" );
|
||||||
|
return core::SQLRowCount( odbc TSRMLS_CC );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Buffered result set
|
||||||
|
// This class holds a result set in memory
|
||||||
|
|
||||||
|
sqlsrv_buffered_result_set::sqlsrv_buffered_result_set( sqlsrv_stmt* stmt TSRMLS_DC ) :
|
||||||
|
sqlsrv_result_set( stmt ),
|
||||||
|
cache(NULL),
|
||||||
|
col_count(0),
|
||||||
|
meta(NULL),
|
||||||
|
current(0),
|
||||||
|
last_field_index(-1),
|
||||||
|
read_so_far(0)
|
||||||
|
{
|
||||||
|
// 10 is an arbitrary number for now for the initial size of the cache
|
||||||
|
ALLOC_HASHTABLE( cache );
|
||||||
|
|
||||||
|
core::sqlsrv_zend_hash_init( *stmt, cache, 10 /* # of buckets */, NULL /* hashfn */, cache_row_dtor /*dtor*/, 0 /*persistent*/
|
||||||
|
TSRMLS_CC );
|
||||||
|
col_count = core::SQLNumResultCols( stmt TSRMLS_CC );
|
||||||
|
// there is no result set to buffer
|
||||||
|
if( col_count == 0 ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLULEN null_bytes = ( col_count / 8 ) + 1; // number of bits to reserve at the beginning of each row for NULL flags
|
||||||
|
meta = static_cast<sqlsrv_buffered_result_set::meta_data*>( sqlsrv_malloc( col_count *
|
||||||
|
sizeof( sqlsrv_buffered_result_set::meta_data )));
|
||||||
|
|
||||||
|
// set up the conversion matrix if this is the first time we're called
|
||||||
|
if( conv_matrix.size() == 0 ) {
|
||||||
|
|
||||||
|
conv_matrix[ SQL_C_CHAR ][ SQL_C_CHAR ] = &sqlsrv_buffered_result_set::to_same_string;
|
||||||
|
conv_matrix[ SQL_C_CHAR ][ SQL_C_WCHAR ] = &sqlsrv_buffered_result_set::system_to_wide_string;
|
||||||
|
conv_matrix[ SQL_C_CHAR ][ SQL_C_BINARY ] = &sqlsrv_buffered_result_set::to_binary_string;
|
||||||
|
conv_matrix[ SQL_C_CHAR ][ SQL_C_DOUBLE ] = &sqlsrv_buffered_result_set::string_to_double;
|
||||||
|
conv_matrix[ SQL_C_CHAR ][ SQL_C_LONG ] = &sqlsrv_buffered_result_set::string_to_long;
|
||||||
|
conv_matrix[ SQL_C_WCHAR ][ SQL_C_WCHAR ] = &sqlsrv_buffered_result_set::to_same_string;
|
||||||
|
conv_matrix[ SQL_C_WCHAR ][ SQL_C_BINARY ] = &sqlsrv_buffered_result_set::to_binary_string;
|
||||||
|
conv_matrix[ SQL_C_WCHAR ][ SQL_C_CHAR ] = &sqlsrv_buffered_result_set::wide_to_system_string;
|
||||||
|
conv_matrix[ SQL_C_WCHAR ][ SQL_C_DOUBLE ] = &sqlsrv_buffered_result_set::wstring_to_double;
|
||||||
|
conv_matrix[ SQL_C_WCHAR ][ SQL_C_LONG ] = &sqlsrv_buffered_result_set::wstring_to_long;
|
||||||
|
conv_matrix[ SQL_C_BINARY ][ SQL_C_BINARY ] = &sqlsrv_buffered_result_set::to_same_string;
|
||||||
|
conv_matrix[ SQL_C_BINARY ][ SQL_C_CHAR ] = &sqlsrv_buffered_result_set::binary_to_system_string;
|
||||||
|
conv_matrix[ SQL_C_BINARY ][ SQL_C_WCHAR ] = &sqlsrv_buffered_result_set::binary_to_wide_string;
|
||||||
|
conv_matrix[ SQL_C_LONG ][ SQL_C_DOUBLE ] = &sqlsrv_buffered_result_set::long_to_double;
|
||||||
|
conv_matrix[ SQL_C_LONG ][ SQL_C_LONG ] = &sqlsrv_buffered_result_set::to_long;
|
||||||
|
conv_matrix[ SQL_C_LONG ][ SQL_C_BINARY ] = &sqlsrv_buffered_result_set::to_long;
|
||||||
|
conv_matrix[ SQL_C_LONG ][ SQL_C_CHAR ] = &sqlsrv_buffered_result_set::long_to_system_string;
|
||||||
|
conv_matrix[ SQL_C_LONG ][ SQL_C_WCHAR ] = &sqlsrv_buffered_result_set::long_to_wide_string;
|
||||||
|
conv_matrix[ SQL_C_DOUBLE ][ SQL_C_DOUBLE ] = &sqlsrv_buffered_result_set::to_double;
|
||||||
|
conv_matrix[ SQL_C_DOUBLE ][ SQL_C_BINARY ] = &sqlsrv_buffered_result_set::to_double;
|
||||||
|
conv_matrix[ SQL_C_DOUBLE ][ SQL_C_CHAR ] = &sqlsrv_buffered_result_set::double_to_system_string;
|
||||||
|
conv_matrix[ SQL_C_DOUBLE ][ SQL_C_LONG ] = &sqlsrv_buffered_result_set::double_to_long;
|
||||||
|
conv_matrix[ SQL_C_DOUBLE ][ SQL_C_WCHAR ] = &sqlsrv_buffered_result_set::double_to_wide_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the meta data and calculate the size of a row buffer
|
||||||
|
SQLULEN offset = null_bytes;
|
||||||
|
for( SQLSMALLINT i = 0; i < col_count; ++i ) {
|
||||||
|
|
||||||
|
core::SQLDescribeCol( stmt, i + 1, NULL, 0, NULL, &meta[i].type, &meta[i].length, &meta[i].scale, NULL TSRMLS_CC );
|
||||||
|
|
||||||
|
offset = align_to<4>( offset );
|
||||||
|
meta[i].offset = offset;
|
||||||
|
|
||||||
|
switch( meta[i].type ) {
|
||||||
|
|
||||||
|
// these types are the display size
|
||||||
|
case SQL_BIGINT:
|
||||||
|
case SQL_DECIMAL:
|
||||||
|
case SQL_GUID:
|
||||||
|
case SQL_NUMERIC:
|
||||||
|
core::SQLColAttribute( stmt, i + 1, SQL_DESC_DISPLAY_SIZE, NULL, 0, NULL,
|
||||||
|
reinterpret_cast<SQLLEN*>( &meta[i].length ) TSRMLS_CC );
|
||||||
|
meta[i].length += sizeof( char ) + sizeof( SQLULEN ); // null terminator space
|
||||||
|
offset += meta[i].length;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// these types are the column size
|
||||||
|
case SQL_BINARY:
|
||||||
|
case SQL_CHAR:
|
||||||
|
case SQL_SS_UDT:
|
||||||
|
case SQL_VARBINARY:
|
||||||
|
case SQL_VARCHAR:
|
||||||
|
// var* field types are length prefixed
|
||||||
|
if( meta[i].length == sqlsrv_buffered_result_set::meta_data::SIZE_UNKNOWN ) {
|
||||||
|
offset += sizeof( void* );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
meta[i].length += sizeof( SQLULEN ) + sizeof( char ); // length plus null terminator space
|
||||||
|
offset += meta[i].length;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SQL_WCHAR:
|
||||||
|
case SQL_WVARCHAR:
|
||||||
|
if( meta[i].length == sqlsrv_buffered_result_set::meta_data::SIZE_UNKNOWN ) {
|
||||||
|
offset += sizeof( void* );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
meta[i].length *= sizeof( WCHAR );
|
||||||
|
meta[i].length += sizeof( SQLULEN ) + sizeof( WCHAR ); // length plus null terminator space
|
||||||
|
offset += meta[i].length;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// these types are LOBs
|
||||||
|
case SQL_LONGVARBINARY:
|
||||||
|
case SQL_LONGVARCHAR:
|
||||||
|
case SQL_WLONGVARCHAR:
|
||||||
|
case SQL_SS_XML:
|
||||||
|
meta[i].length = sqlsrv_buffered_result_set::meta_data::SIZE_UNKNOWN;
|
||||||
|
offset += sizeof( void* );
|
||||||
|
break;
|
||||||
|
|
||||||
|
// these types are the ISO date size
|
||||||
|
case SQL_DATETIME:
|
||||||
|
case SQL_TYPE_DATE:
|
||||||
|
case SQL_SS_TIME2:
|
||||||
|
case SQL_SS_TIMESTAMPOFFSET:
|
||||||
|
case SQL_TYPE_TIMESTAMP:
|
||||||
|
core::SQLColAttribute( stmt, i + 1, SQL_DESC_DISPLAY_SIZE, NULL, 0, NULL,
|
||||||
|
reinterpret_cast<SQLLEN*>( &meta[i].length ) TSRMLS_CC );
|
||||||
|
meta[i].length += sizeof(char) + sizeof( SQLULEN ); // null terminator space
|
||||||
|
offset += meta[i].length;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// these types are the native size
|
||||||
|
case SQL_BIT:
|
||||||
|
case SQL_INTEGER:
|
||||||
|
case SQL_SMALLINT:
|
||||||
|
case SQL_TINYINT:
|
||||||
|
meta[i].length = sizeof( long );
|
||||||
|
offset += meta[i].length;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SQL_REAL:
|
||||||
|
case SQL_FLOAT:
|
||||||
|
meta[i].length = sizeof( double );
|
||||||
|
offset += meta[i].length;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
SQLSRV_ASSERT( false, "Unknown type in sqlsrv_buffered_query::sqlsrv_buffered_query" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( meta[i].type ) {
|
||||||
|
|
||||||
|
case SQL_BIGINT:
|
||||||
|
case SQL_CHAR:
|
||||||
|
case SQL_DATETIME:
|
||||||
|
case SQL_DECIMAL:
|
||||||
|
case SQL_GUID:
|
||||||
|
case SQL_NUMERIC:
|
||||||
|
case SQL_LONGVARCHAR:
|
||||||
|
case SQL_TYPE_DATE:
|
||||||
|
case SQL_SS_TIME2:
|
||||||
|
case SQL_SS_TIMESTAMPOFFSET:
|
||||||
|
case SQL_SS_XML:
|
||||||
|
case SQL_TYPE_TIMESTAMP:
|
||||||
|
case SQL_VARCHAR:
|
||||||
|
meta[i].c_type = SQL_C_CHAR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SQL_SS_UDT:
|
||||||
|
case SQL_LONGVARBINARY:
|
||||||
|
case SQL_BINARY:
|
||||||
|
case SQL_VARBINARY:
|
||||||
|
meta[i].c_type = SQL_C_BINARY;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SQL_WLONGVARCHAR:
|
||||||
|
case SQL_WCHAR:
|
||||||
|
case SQL_WVARCHAR:
|
||||||
|
meta[i].c_type = SQL_C_WCHAR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SQL_BIT:
|
||||||
|
case SQL_INTEGER:
|
||||||
|
case SQL_SMALLINT:
|
||||||
|
case SQL_TINYINT:
|
||||||
|
meta[i].c_type = SQL_C_LONG;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SQL_REAL:
|
||||||
|
case SQL_FLOAT:
|
||||||
|
meta[i].c_type = SQL_C_DOUBLE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
SQLSRV_ASSERT( false, "Unknown type in sqlsrv_buffered_query::sqlsrv_buffered_query" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// read the data into the cache
|
||||||
|
// (offset from the above loop has the size of the row buffer necessary)
|
||||||
|
unsigned long mem_used = 0;
|
||||||
|
unsigned long row_count = 0;
|
||||||
|
|
||||||
|
while( core::SQLFetchScroll( stmt, SQL_FETCH_NEXT, 0 TSRMLS_CC ) != SQL_NO_DATA ) {
|
||||||
|
|
||||||
|
// allocate the row buffer
|
||||||
|
unsigned char* row = static_cast<unsigned char*>( sqlsrv_malloc( offset ));
|
||||||
|
memset( row, 0, offset );
|
||||||
|
|
||||||
|
// read the fields into the row buffer
|
||||||
|
for( SQLSMALLINT i = 0; i < col_count; ++i ) {
|
||||||
|
|
||||||
|
SQLLEN out_buffer_temp = SQL_NULL_DATA;
|
||||||
|
SQLPOINTER buffer;
|
||||||
|
SQLLEN* out_buffer_length = &out_buffer_temp;
|
||||||
|
|
||||||
|
switch( meta[i].c_type ) {
|
||||||
|
|
||||||
|
case SQL_C_CHAR:
|
||||||
|
case SQL_C_WCHAR:
|
||||||
|
case SQL_C_BINARY:
|
||||||
|
if( meta[i].length == sqlsrv_buffered_result_set::meta_data::SIZE_UNKNOWN ) {
|
||||||
|
|
||||||
|
out_buffer_length = &out_buffer_temp;
|
||||||
|
SQLPOINTER* lob_addr = reinterpret_cast<SQLPOINTER*>( &row[ meta[i].offset ] );
|
||||||
|
*lob_addr = read_lob_field( stmt, i, meta[i], mem_used TSRMLS_CC );
|
||||||
|
// a NULL pointer means NULL field
|
||||||
|
if( *lob_addr == NULL ) {
|
||||||
|
*out_buffer_length = SQL_NULL_DATA;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*out_buffer_length = **reinterpret_cast<SQLLEN**>( lob_addr );
|
||||||
|
mem_used += *out_buffer_length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
mem_used += meta[i].length;
|
||||||
|
CHECK_CUSTOM_ERROR( mem_used > stmt->buffered_query_limit * 1024, stmt,
|
||||||
|
SQLSRV_ERROR_BUFFER_LIMIT_EXCEEDED, stmt->buffered_query_limit ) {
|
||||||
|
|
||||||
|
throw core::CoreException();
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = row + meta[i].offset + sizeof( SQLULEN );
|
||||||
|
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,
|
||||||
|
false TSRMLS_CC );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SQL_C_LONG:
|
||||||
|
case SQL_C_DOUBLE:
|
||||||
|
{
|
||||||
|
mem_used += meta[i].length;
|
||||||
|
CHECK_CUSTOM_ERROR( mem_used > stmt->buffered_query_limit * 1024, stmt,
|
||||||
|
SQLSRV_ERROR_BUFFER_LIMIT_EXCEEDED, stmt->buffered_query_limit ) {
|
||||||
|
|
||||||
|
throw core::CoreException();
|
||||||
|
}
|
||||||
|
buffer = row + meta[i].offset;
|
||||||
|
out_buffer_length = &out_buffer_temp;
|
||||||
|
core::SQLGetData( stmt, i + 1, meta[i].c_type, buffer, meta[i].length, out_buffer_length,
|
||||||
|
false TSRMLS_CC );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
SQLSRV_ASSERT( false, "Unknown C type" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( *out_buffer_length == SQL_NULL_DATA ) {
|
||||||
|
unsigned char* null_bits = reinterpret_cast<unsigned char*>( row );
|
||||||
|
set_bit( row, i );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLSRV_ASSERT( row_count < LONG_MAX, "Hard maximum of 2 billion rows exceeded in a buffered query" );
|
||||||
|
|
||||||
|
// add it to the cache
|
||||||
|
row_dtor_closure cl( this, row );
|
||||||
|
sqlsrv_zend_hash_next_index_insert( *stmt, cache, &cl, sizeof( cl ) TSRMLS_CC );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlsrv_buffered_result_set::~sqlsrv_buffered_result_set( void )
|
||||||
|
{
|
||||||
|
// free the rows
|
||||||
|
if( cache ) {
|
||||||
|
zend_hash_destroy( cache );
|
||||||
|
FREE_HASHTABLE( cache );
|
||||||
|
cache = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// free the meta data
|
||||||
|
if( meta ) {
|
||||||
|
efree( meta );
|
||||||
|
meta = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::fetch( SQLSMALLINT orientation, SQLLEN offset TSRMLS_DC )
|
||||||
|
{
|
||||||
|
last_error = NULL;
|
||||||
|
last_field_index = -1;
|
||||||
|
read_so_far = 0;
|
||||||
|
|
||||||
|
switch( orientation ) {
|
||||||
|
|
||||||
|
case SQL_FETCH_NEXT:
|
||||||
|
offset = 1;
|
||||||
|
orientation = SQL_FETCH_RELATIVE;
|
||||||
|
break;
|
||||||
|
case SQL_FETCH_PRIOR:
|
||||||
|
offset = -1;
|
||||||
|
orientation = SQL_FETCH_RELATIVE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( orientation ) {
|
||||||
|
|
||||||
|
case SQL_FETCH_FIRST:
|
||||||
|
current = 1;
|
||||||
|
break;
|
||||||
|
case SQL_FETCH_LAST:
|
||||||
|
current = row_count( TSRMLS_C );
|
||||||
|
break;
|
||||||
|
case SQL_FETCH_ABSOLUTE:
|
||||||
|
current = offset;
|
||||||
|
break;
|
||||||
|
case SQL_FETCH_RELATIVE:
|
||||||
|
current += offset;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SQLSRV_ASSERT( false, "Invalid fetch orientation. Should have been caught before here." );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check validity of current row
|
||||||
|
// the cursor can never get further away than just before the first row
|
||||||
|
if( current <= 0 && ( offset < 0 || orientation != SQL_FETCH_RELATIVE )) {
|
||||||
|
current = 0;
|
||||||
|
return SQL_NO_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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*/ ) {
|
||||||
|
current = row_count( TSRMLS_C ) + 1;
|
||||||
|
return SQL_NO_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SQL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::get_data( SQLUSMALLINT field_index, SQLSMALLINT target_type,
|
||||||
|
__out SQLPOINTER buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length,
|
||||||
|
bool handle_warning TSRMLS_DC )
|
||||||
|
{
|
||||||
|
last_error = NULL;
|
||||||
|
field_index--; // convert from 1 based to 0 based
|
||||||
|
SQLSRV_ASSERT( field_index < column_count(), "Invalid field index requested" );
|
||||||
|
|
||||||
|
if( field_index != last_field_index ) {
|
||||||
|
last_field_index = field_index;
|
||||||
|
read_so_far = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
|
||||||
|
// if the field is null, then return SQL_NULL_DATA
|
||||||
|
if( get_bit( row, field_index )) {
|
||||||
|
*out_buffer_length = SQL_NULL_DATA;
|
||||||
|
return SQL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check to make sure the conversion type is valid
|
||||||
|
if( conv_matrix.find( meta[ field_index ].c_type ) == conv_matrix.end() ||
|
||||||
|
conv_matrix.find( meta[ field_index ].c_type )->second.find( target_type ) ==
|
||||||
|
conv_matrix.find( meta[ field_index ].c_type )->second.end() ) {
|
||||||
|
|
||||||
|
last_error = new (sqlsrv_malloc( sizeof( sqlsrv_error )))
|
||||||
|
sqlsrv_error( (SQLCHAR*) "07006",
|
||||||
|
(SQLCHAR*) "Restricted data type attribute violation", 0 );
|
||||||
|
return SQL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (( this )->*( conv_matrix[ meta[ field_index ].c_type ][ target_type ] ))( field_index, buffer, buffer_length,
|
||||||
|
out_buffer_length );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::get_diag_field( SQLSMALLINT record_number, SQLSMALLINT diag_identifier,
|
||||||
|
__out SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
|
||||||
|
__out SQLSMALLINT* out_buffer_length TSRMLS_DC )
|
||||||
|
{
|
||||||
|
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,
|
||||||
|
"Only SQL_DIAG_SQLSTATE can be fetched by sqlsrv_buffered_result_set::get_diag_field" );
|
||||||
|
SQLSRV_ASSERT( buffer_length >= SQL_SQLSTATE_BUFSIZE,
|
||||||
|
"Buffer not big enough to return SQLSTATE in sqlsrv_buffered_result_set::get_diag_field" );
|
||||||
|
|
||||||
|
if( last_error == NULL ) {
|
||||||
|
return SQL_NO_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLSRV_ASSERT( last_error->sqlstate != NULL,
|
||||||
|
"Must have a SQLSTATE in a valid last_error in sqlsrv_buffered_result_set::get_diag_field" );
|
||||||
|
|
||||||
|
memcpy( diag_info_buffer, last_error->sqlstate, min( buffer_length, SQL_SQLSTATE_BUFSIZE ));
|
||||||
|
|
||||||
|
return SQL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char* sqlsrv_buffered_result_set::get_row( void )
|
||||||
|
{
|
||||||
|
row_dtor_closure* cl_ptr;
|
||||||
|
int zr = zend_hash_index_find( cache, current - 1, (void**) &cl_ptr );
|
||||||
|
SQLSRV_ASSERT( zr == SUCCESS, "Failed to find row %1!d! in the cache", current );
|
||||||
|
return cl_ptr->row_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlsrv_error* sqlsrv_buffered_result_set::get_diag_rec( SQLSMALLINT record_number )
|
||||||
|
{
|
||||||
|
// we only hold a single error if there is one, otherwise return the ODBC error(s)
|
||||||
|
if( last_error == NULL ) {
|
||||||
|
return odbc_get_diag_rec( odbc, record_number );
|
||||||
|
}
|
||||||
|
if( record_number > 1 ) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new (sqlsrv_malloc( sizeof( sqlsrv_error )))
|
||||||
|
sqlsrv_error( last_error->sqlstate, last_error->native_message, last_error->native_code );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLLEN sqlsrv_buffered_result_set::row_count( TSRMLS_D )
|
||||||
|
{
|
||||||
|
last_error = NULL;
|
||||||
|
|
||||||
|
return zend_hash_num_elements( cache );
|
||||||
|
}
|
||||||
|
|
||||||
|
// private functions
|
||||||
|
template <typename Char>
|
||||||
|
SQLRETURN binary_to_string( SQLCHAR* field_data, SQLLEN& read_so_far, __out void* buffer,
|
||||||
|
SQLLEN buffer_length, __out SQLLEN* out_buffer_length,
|
||||||
|
sqlsrv_error_auto_ptr& out_error )
|
||||||
|
{
|
||||||
|
// hex characters for the conversion loop below
|
||||||
|
static char hex_chars[] = "0123456789ABCDEF";
|
||||||
|
|
||||||
|
SQLSRV_ASSERT( out_error == NULL, "Pending error for sqlsrv_buffered_results_set::binary_to_string" );
|
||||||
|
|
||||||
|
SQLRETURN r = SQL_ERROR;
|
||||||
|
|
||||||
|
// Set the amount of space necessary for null characters at the end of the data.
|
||||||
|
SQLSMALLINT extra = sizeof(Char);
|
||||||
|
|
||||||
|
SQLSRV_ASSERT( ((buffer_length - extra) % (extra * 2)) == 0, "Must be multiple of 2 for binary to system string or "
|
||||||
|
"multiple of 4 for binary to wide string" );
|
||||||
|
|
||||||
|
// all fields will be treated as ODBC returns varchar(max) fields:
|
||||||
|
// the entire length of the string is returned the first
|
||||||
|
// call in out_buffer_len. Successive calls return how much is
|
||||||
|
// left minus how much has already been read by previous reads
|
||||||
|
// *2 is for each byte to hex conversion and * extra is for either system or wide string allocation
|
||||||
|
*out_buffer_length = (*reinterpret_cast<SQLLEN*>( field_data - sizeof( SQLULEN )) - read_so_far) * 2 * extra;
|
||||||
|
|
||||||
|
// copy as much as we can into the buffer
|
||||||
|
SQLLEN to_copy;
|
||||||
|
if( buffer_length < *out_buffer_length + extra ) {
|
||||||
|
to_copy = (buffer_length - extra);
|
||||||
|
out_error = new ( sqlsrv_malloc( sizeof( sqlsrv_error )))
|
||||||
|
sqlsrv_error( (SQLCHAR*) "01004", (SQLCHAR*) "String data, right truncated", -1 );
|
||||||
|
r = SQL_SUCCESS_WITH_INFO;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
r = SQL_SUCCESS;
|
||||||
|
to_copy = *out_buffer_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if there are bytes to copy as hex
|
||||||
|
if( to_copy > 0 ) {
|
||||||
|
// quick hex conversion routine
|
||||||
|
Char* h = reinterpret_cast<Char*>( buffer );
|
||||||
|
BYTE* b = reinterpret_cast<BYTE*>( field_data );
|
||||||
|
// to_copy contains the number of bytes to copy, so we divide the number in half (or quarter)
|
||||||
|
// to get the number of hex digits we can copy
|
||||||
|
SQLLEN to_copy_hex = to_copy / (2 * extra);
|
||||||
|
for( int i = 0; i < to_copy_hex; ++i ) {
|
||||||
|
*h = hex_chars[ (*b & 0xf0) >> 4 ];
|
||||||
|
h++;
|
||||||
|
*h = hex_chars[ (*b++ & 0x0f) ];
|
||||||
|
h++;
|
||||||
|
}
|
||||||
|
read_so_far += to_copy_hex;
|
||||||
|
*h = static_cast<Char>( 0 );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
reinterpret_cast<char*>( buffer )[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::binary_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLCHAR* row = get_row();
|
||||||
|
SQLCHAR* field_data = NULL;
|
||||||
|
|
||||||
|
if( meta[ field_index ].length == sqlsrv_buffered_result_set::meta_data::SIZE_UNKNOWN ) {
|
||||||
|
|
||||||
|
field_data = *reinterpret_cast<SQLCHAR**>( &row[ meta[ field_index ].offset ] ) + sizeof( SQLULEN );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
field_data = &row[ meta[ field_index ].offset ] + sizeof( SQLULEN );
|
||||||
|
}
|
||||||
|
|
||||||
|
return binary_to_string<char>( field_data, read_so_far, buffer, buffer_length, out_buffer_length, last_error );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::binary_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLCHAR* row = get_row();
|
||||||
|
SQLCHAR* field_data = NULL;
|
||||||
|
|
||||||
|
if( meta[ field_index ].length == sqlsrv_buffered_result_set::meta_data::SIZE_UNKNOWN ) {
|
||||||
|
|
||||||
|
field_data = *reinterpret_cast<SQLCHAR**>( &row[ meta[ field_index ].offset ] ) + sizeof( SQLULEN );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
field_data = &row[ meta[ field_index ].offset ] + sizeof( SQLULEN );
|
||||||
|
}
|
||||||
|
|
||||||
|
return binary_to_string<WCHAR>( field_data, read_so_far, buffer, buffer_length, out_buffer_length, last_error );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::double_to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_DOUBLE, "Invalid conversion to long" );
|
||||||
|
SQLSRV_ASSERT( buffer_length >= sizeof(LONG), "Buffer length must be able to find a long in "
|
||||||
|
"sqlsrv_buffered_result_set::double_to_long" );
|
||||||
|
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
double* double_data = reinterpret_cast<double*>( &row[ meta[ field_index ].offset ] );
|
||||||
|
LONG* long_data = reinterpret_cast<LONG*>( buffer );
|
||||||
|
|
||||||
|
if( *double_data < double( LONG_MIN ) || *double_data > double( LONG_MAX )) {
|
||||||
|
last_error = new (sqlsrv_malloc( sizeof( sqlsrv_error ))) sqlsrv_error( (SQLCHAR*) "22003",
|
||||||
|
(SQLCHAR*) "Numeric value out of range", 0 );
|
||||||
|
return SQL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( *double_data != floor( *double_data )) {
|
||||||
|
last_error = new (sqlsrv_malloc( sizeof( sqlsrv_error ))) sqlsrv_error( (SQLCHAR*) "01S07",
|
||||||
|
(SQLCHAR*) "Fractional truncation", 0 );
|
||||||
|
return SQL_SUCCESS_WITH_INFO;
|
||||||
|
}
|
||||||
|
|
||||||
|
*long_data = static_cast<LONG>( *double_data );
|
||||||
|
*out_buffer_length = sizeof( LONG );
|
||||||
|
|
||||||
|
return SQL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::double_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_DOUBLE, "Invalid conversion to system string" );
|
||||||
|
SQLSRV_ASSERT( buffer_length > 0, "Buffer length must be > 0 in sqlsrv_buffered_result_set::double_to_system_string" );
|
||||||
|
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
double* double_data = reinterpret_cast<double*>( &row[ meta[ field_index ].offset ] );
|
||||||
|
|
||||||
|
return number_to_string<char>( double_data, buffer, buffer_length, out_buffer_length, last_error );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::double_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_DOUBLE, "Invalid conversion to wide string" );
|
||||||
|
SQLSRV_ASSERT( buffer_length > 0, "Buffer length must be > 0 in sqlsrv_buffered_result_set::double_to_wide_string" );
|
||||||
|
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
double* double_data = reinterpret_cast<double*>( &row[ meta[ field_index ].offset ] );
|
||||||
|
|
||||||
|
return number_to_string<WCHAR>( double_data, buffer, buffer_length, out_buffer_length, last_error );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::long_to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_LONG, "Invalid conversion to long" );
|
||||||
|
SQLSRV_ASSERT( buffer_length >= sizeof(double), "Buffer length must be able to find a long in sqlsrv_buffered_result_set::double_to_long" );
|
||||||
|
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
double* double_data = reinterpret_cast<double*>( buffer );
|
||||||
|
LONG* long_data = reinterpret_cast<LONG*>( &row[ meta[ field_index ].offset ] );
|
||||||
|
|
||||||
|
*double_data = static_cast<LONG>( *long_data );
|
||||||
|
*out_buffer_length = sizeof( double );
|
||||||
|
|
||||||
|
return SQL_SUCCESS;
|
||||||
|
}
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::long_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_LONG, "Invalid conversion to system string" );
|
||||||
|
SQLSRV_ASSERT( buffer_length > 0, "Buffer length must be > 0 in sqlsrv_buffered_result_set::long_to_system_string" );
|
||||||
|
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
LONG* long_data = reinterpret_cast<LONG*>( &row[ meta[ field_index ].offset ] );
|
||||||
|
|
||||||
|
return number_to_string<char>( long_data, buffer, buffer_length, out_buffer_length, last_error );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::long_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_LONG, "Invalid conversion to wide string" );
|
||||||
|
SQLSRV_ASSERT( buffer_length > 0, "Buffer length must be > 0 in sqlsrv_buffered_result_set::long_to_wide_string" );
|
||||||
|
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
LONG* long_data = reinterpret_cast<LONG*>( &row[ meta[ field_index ].offset ] );
|
||||||
|
|
||||||
|
return number_to_string<WCHAR>( long_data, buffer, buffer_length, out_buffer_length, last_error );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::string_to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_CHAR, "Invalid conversion from string to double" );
|
||||||
|
SQLSRV_ASSERT( buffer_length >= sizeof( double ), "Buffer needs to be big enough to hold a double" );
|
||||||
|
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
char* string_data = reinterpret_cast<char*>( &row[ meta[ field_index ].offset ] ) + sizeof( SQLULEN );
|
||||||
|
|
||||||
|
return string_to_number<double>( string_data, meta[ field_index ].length, buffer, buffer_length, out_buffer_length, last_error );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::wstring_to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_WCHAR, "Invalid conversion from wide string to double" );
|
||||||
|
SQLSRV_ASSERT( buffer_length >= sizeof( double ), "Buffer needs to be big enough to hold a double" );
|
||||||
|
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
SQLWCHAR* string_data = reinterpret_cast<SQLWCHAR*>( &row[ meta[ field_index ].offset ] ) + sizeof( SQLULEN ) / sizeof( SQLWCHAR );
|
||||||
|
|
||||||
|
return string_to_number<double>( string_data, meta[ field_index ].length, buffer, buffer_length, out_buffer_length, last_error );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::string_to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_CHAR, "Invalid conversion from string to long" );
|
||||||
|
SQLSRV_ASSERT( buffer_length >= sizeof( LONG ), "Buffer needs to be big enough to hold a long" );
|
||||||
|
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
char* string_data = reinterpret_cast<char*>( &row[ meta[ field_index ].offset ] ) + sizeof( SQLULEN );
|
||||||
|
|
||||||
|
return string_to_number<LONG>( string_data, meta[ field_index ].length, buffer, buffer_length, out_buffer_length, last_error );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::wstring_to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_WCHAR, "Invalid conversion from wide string to long" );
|
||||||
|
SQLSRV_ASSERT( buffer_length >= sizeof( LONG ), "Buffer needs to be big enough to hold a long" );
|
||||||
|
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
SQLWCHAR* string_data = reinterpret_cast<SQLWCHAR*>( &row[ meta[ field_index ].offset ] ) + sizeof( SQLULEN ) / sizeof( SQLWCHAR );
|
||||||
|
|
||||||
|
return string_to_number<LONG>( string_data, meta[ field_index ].length, buffer, buffer_length, out_buffer_length, last_error );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::system_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( last_error == NULL, "Pending error for sqlsrv_buffered_results_set::system_to_wide_string" );
|
||||||
|
SQLSRV_ASSERT( buffer_length % 2 == 0, "Odd buffer length passed to sqlsrv_buffered_result_set::system_to_wide_string" );
|
||||||
|
|
||||||
|
SQLRETURN r = SQL_ERROR;
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
|
||||||
|
SQLCHAR* field_data = NULL;
|
||||||
|
SQLULEN field_len = NULL;
|
||||||
|
|
||||||
|
if( meta[ field_index ].length == sqlsrv_buffered_result_set::meta_data::SIZE_UNKNOWN ) {
|
||||||
|
|
||||||
|
field_len = **reinterpret_cast<SQLLEN**>( &row[ meta[ field_index ].offset ] );
|
||||||
|
field_data = *reinterpret_cast<SQLCHAR**>( &row[ meta[ field_index ].offset ] ) + sizeof( SQLULEN ) + read_so_far;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
field_len = *reinterpret_cast<SQLLEN*>( &row[ meta[ field_index ].offset ] );
|
||||||
|
field_data = &row[ meta[ field_index ].offset ] + sizeof( SQLULEN ) + read_so_far;
|
||||||
|
}
|
||||||
|
|
||||||
|
// all fields will be treated as ODBC returns varchar(max) fields:
|
||||||
|
// the entire length of the string is returned the first
|
||||||
|
// call in out_buffer_len. Successive calls return how much is
|
||||||
|
// left minus how much has already been read by previous reads
|
||||||
|
*out_buffer_length = (*reinterpret_cast<SQLLEN*>( field_data - sizeof( SQLULEN )) - read_so_far) * sizeof(WCHAR);
|
||||||
|
|
||||||
|
// to_copy is the number of characters to copy, not including the null terminator
|
||||||
|
// supposedly it will never happen that a Windows MBCS will explode to UTF-16 surrogate pair.
|
||||||
|
SQLLEN to_copy;
|
||||||
|
|
||||||
|
if( (size_t) buffer_length < (field_len - read_so_far + sizeof(char)) * sizeof(WCHAR)) {
|
||||||
|
|
||||||
|
to_copy = (buffer_length - sizeof(WCHAR)) / sizeof(WCHAR); // to_copy is the number of characters
|
||||||
|
last_error = new ( sqlsrv_malloc( sizeof( sqlsrv_error )))
|
||||||
|
sqlsrv_error( (SQLCHAR*) "01004", (SQLCHAR*) "String data, right truncated", -1 );
|
||||||
|
r = SQL_SUCCESS_WITH_INFO;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
r = SQL_SUCCESS;
|
||||||
|
to_copy = field_len - read_so_far;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( to_copy > 0 ) {
|
||||||
|
|
||||||
|
bool tried_again = false;
|
||||||
|
do {
|
||||||
|
int ch_space = MultiByteToWideChar( CP_ACP, MB_ERR_INVALID_CHARS, (LPCSTR) field_data, to_copy,
|
||||||
|
(LPWSTR) buffer, to_copy );
|
||||||
|
if( ch_space == 0 ) {
|
||||||
|
|
||||||
|
switch( GetLastError() ) {
|
||||||
|
|
||||||
|
case ERROR_NO_UNICODE_TRANSLATION:
|
||||||
|
// the theory here is the conversion failed because the end of the buffer we provided contained only
|
||||||
|
// half a character at the end
|
||||||
|
if( !tried_again ) {
|
||||||
|
to_copy--;
|
||||||
|
tried_again = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
last_error = new ( sqlsrv_malloc( sizeof( sqlsrv_error )))
|
||||||
|
sqlsrv_error( (SQLCHAR*) "IMSSP", (SQLCHAR*) "Invalid Unicode translation", -1 );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SQLSRV_ASSERT( false, "Severe error translating Unicode" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SQL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
((WCHAR*)buffer)[ to_copy ] = L'\0';
|
||||||
|
read_so_far += to_copy;
|
||||||
|
break;
|
||||||
|
|
||||||
|
} while( true );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
reinterpret_cast<WCHAR*>( buffer )[0] = L'\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::to_same_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( last_error == NULL, "Pending error for sqlsrv_buffered_results_set::to_same_string" );
|
||||||
|
|
||||||
|
SQLRETURN r = SQL_ERROR;
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
|
||||||
|
// Set the amount of space necessary for null characters at the end of the data.
|
||||||
|
SQLSMALLINT extra = 0;
|
||||||
|
|
||||||
|
switch( meta[ field_index ].c_type ) {
|
||||||
|
case SQL_C_WCHAR:
|
||||||
|
extra = sizeof( SQLWCHAR );
|
||||||
|
break;
|
||||||
|
case SQL_C_BINARY:
|
||||||
|
extra = 0;
|
||||||
|
break;
|
||||||
|
case SQL_C_CHAR:
|
||||||
|
extra = sizeof( SQLCHAR );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SQLSRV_ASSERT( false, "Invalid type in get_string_data" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLCHAR* field_data = NULL;
|
||||||
|
|
||||||
|
if( meta[ field_index ].length == sqlsrv_buffered_result_set::meta_data::SIZE_UNKNOWN ) {
|
||||||
|
|
||||||
|
field_data = *reinterpret_cast<SQLCHAR**>( &row[ meta[ field_index ].offset ] ) + sizeof( SQLULEN );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
field_data = &row[ meta[ field_index ].offset ] + sizeof( SQLULEN );
|
||||||
|
}
|
||||||
|
|
||||||
|
// all fields will be treated as ODBC returns varchar(max) fields:
|
||||||
|
// the entire length of the string is returned the first
|
||||||
|
// call in out_buffer_len. Successive calls return how much is
|
||||||
|
// left minus how much has already been read by previous reads
|
||||||
|
*out_buffer_length = *reinterpret_cast<SQLLEN*>( field_data - sizeof( SQLULEN )) - read_so_far;
|
||||||
|
|
||||||
|
// copy as much as we can into the buffer
|
||||||
|
SQLLEN to_copy;
|
||||||
|
if( buffer_length < *out_buffer_length + extra ) {
|
||||||
|
to_copy = buffer_length - extra;
|
||||||
|
last_error = new ( sqlsrv_malloc( sizeof( sqlsrv_error )))
|
||||||
|
sqlsrv_error( (SQLCHAR*) "01004", (SQLCHAR*) "String data, right truncated", -1 );
|
||||||
|
r = SQL_SUCCESS_WITH_INFO;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
r = SQL_SUCCESS;
|
||||||
|
to_copy = *out_buffer_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLSRV_ASSERT( to_copy >= 0, "Negative field length calculated in buffered result set" );
|
||||||
|
|
||||||
|
if( to_copy > 0 ) {
|
||||||
|
memcpy( buffer, field_data + read_so_far, to_copy );
|
||||||
|
read_so_far += to_copy;
|
||||||
|
}
|
||||||
|
if( extra ) {
|
||||||
|
OACR_WARNING_SUPPRESS( 26001, "Buffer length verified above" );
|
||||||
|
memcpy( reinterpret_cast<SQLCHAR*>( buffer ) + to_copy, L"\0", extra );
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::wide_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( last_error == NULL, "Pending error for sqlsrv_buffered_results_set::wide_to_system_string" );
|
||||||
|
|
||||||
|
SQLRETURN r = SQL_ERROR;
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
|
||||||
|
SQLCHAR* field_data = NULL;
|
||||||
|
SQLULEN field_len = NULL;
|
||||||
|
|
||||||
|
// if this is the first time called for this field, just convert the entire string to system first then
|
||||||
|
// use that to read from instead of converting chunk by chunk. This is because it's impossible to know
|
||||||
|
// the total length of the string for output_buffer_length without doing the conversion and returning
|
||||||
|
// SQL_NO_TOTAL is not consistent with what our other conversion functions do (system_to_wide_string and
|
||||||
|
// to_same_string).
|
||||||
|
|
||||||
|
if( read_so_far == 0 ) {
|
||||||
|
|
||||||
|
if( meta[ field_index ].length == sqlsrv_buffered_result_set::meta_data::SIZE_UNKNOWN ) {
|
||||||
|
|
||||||
|
field_len = **reinterpret_cast<SQLLEN**>( &row[ meta[ field_index ].offset ] );
|
||||||
|
field_data = *reinterpret_cast<SQLCHAR**>( &row[ meta[ field_index ].offset ] ) + sizeof( SQLULEN ) + read_so_far;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
field_len = *reinterpret_cast<SQLLEN*>( &row[ meta[ field_index ].offset ] );
|
||||||
|
field_data = &row[ meta[ field_index ].offset ] + sizeof( SQLULEN ) + read_so_far;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL default_char_used = FALSE;
|
||||||
|
char default_char = '?';
|
||||||
|
|
||||||
|
// allocate enough to handle WC -> DBCS conversion if it happens
|
||||||
|
temp_string = reinterpret_cast<SQLCHAR*>( sqlsrv_malloc( field_len, sizeof( char ), sizeof(char)));
|
||||||
|
temp_length = WideCharToMultiByte( CP_ACP, 0, (LPCWSTR) field_data, field_len / sizeof(WCHAR),
|
||||||
|
(LPSTR) temp_string.get(), field_len, &default_char, &default_char_used );
|
||||||
|
|
||||||
|
if( temp_length == 0 ) {
|
||||||
|
|
||||||
|
switch( GetLastError() ) {
|
||||||
|
|
||||||
|
case ERROR_NO_UNICODE_TRANSLATION:
|
||||||
|
last_error = new ( sqlsrv_malloc( sizeof( sqlsrv_error )))
|
||||||
|
sqlsrv_error( (SQLCHAR*) "IMSSP", (SQLCHAR*) "Invalid Unicode translation", -1 );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SQLSRV_ASSERT( false, "Severe error translating Unicode" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SQL_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_buffer_length = (temp_length - read_so_far);
|
||||||
|
|
||||||
|
SQLLEN to_copy = 0;
|
||||||
|
|
||||||
|
if( (size_t) buffer_length < (temp_length - read_so_far + sizeof(char))) {
|
||||||
|
|
||||||
|
to_copy = buffer_length - sizeof(char);
|
||||||
|
last_error = new ( sqlsrv_malloc( sizeof( sqlsrv_error )))
|
||||||
|
sqlsrv_error( (SQLCHAR*) "01004", (SQLCHAR*) "String data, right truncated", -1 );
|
||||||
|
r = SQL_SUCCESS_WITH_INFO;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
to_copy = (temp_length - read_so_far);
|
||||||
|
r = SQL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( to_copy > 0 ) {
|
||||||
|
|
||||||
|
memcpy( buffer, temp_string.get() + read_so_far, to_copy );
|
||||||
|
}
|
||||||
|
SQLSRV_ASSERT( to_copy >= 0, "Invalid field copy length" );
|
||||||
|
OACR_WARNING_SUPPRESS( BUFFER_UNDERFLOW, "Buffer length verified above" );
|
||||||
|
((SQLCHAR*) buffer)[ to_copy ] = '\0';
|
||||||
|
read_so_far += to_copy;
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::to_binary_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
return to_same_string( field_index, buffer, buffer_length, out_buffer_length );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_LONG, "Invlid conversion to long" );
|
||||||
|
SQLSRV_ASSERT( buffer_length >= sizeof( LONG ), "Buffer too small for SQL_C_LONG" ); // technically should ignore this
|
||||||
|
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
LONG* long_data = reinterpret_cast<LONG*>( &row[ meta[ field_index ].offset ] );
|
||||||
|
|
||||||
|
memcpy( buffer, long_data, sizeof( LONG ));
|
||||||
|
*out_buffer_length = sizeof( LONG );
|
||||||
|
|
||||||
|
return SQL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLRETURN sqlsrv_buffered_result_set::to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length )
|
||||||
|
{
|
||||||
|
SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_DOUBLE, "Invlid conversion to double" );
|
||||||
|
SQLSRV_ASSERT( buffer_length >= sizeof( double ), "Buffer too small for SQL_C_DOUBLE" ); // technically should ignore this
|
||||||
|
|
||||||
|
unsigned char* row = get_row();
|
||||||
|
double* double_data = reinterpret_cast<double*>( &row[ meta[ field_index ].offset ] );
|
||||||
|
|
||||||
|
memcpy( buffer, double_data, sizeof( double ));
|
||||||
|
*out_buffer_length = sizeof( double );
|
||||||
|
|
||||||
|
return SQL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// called for each row in the cache when the cache is destroyed in the destructor
|
||||||
|
void cache_row_dtor( void* data )
|
||||||
|
{
|
||||||
|
row_dtor_closure* cl = reinterpret_cast<row_dtor_closure*>( data );
|
||||||
|
BYTE* row = cl->row_data;
|
||||||
|
// don't release this here, since this is called from the destructor of the result_set
|
||||||
|
sqlsrv_buffered_result_set* result_set = cl->results;
|
||||||
|
|
||||||
|
for( SQLSMALLINT i = 0; i < result_set->column_count(); ++i ) {
|
||||||
|
|
||||||
|
if( result_set->col_meta_data(i).length == sqlsrv_buffered_result_set::meta_data::SIZE_UNKNOWN ) {
|
||||||
|
|
||||||
|
void* out_of_row_data = *reinterpret_cast<void**>( &row[ result_set->col_meta_data(i).offset ] );
|
||||||
|
sqlsrv_free( out_of_row_data );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlsrv_free( row );
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLPOINTER read_lob_field( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_buffered_result_set::meta_data& meta,
|
||||||
|
unsigned long mem_used TSRMLS_DC )
|
||||||
|
{
|
||||||
|
SQLSMALLINT extra = 0;
|
||||||
|
SQLLEN* output_buffer_len = NULL;
|
||||||
|
|
||||||
|
// Set the amount of space necessary for null characters at the end of the data.
|
||||||
|
switch( meta.c_type ) {
|
||||||
|
case SQL_C_WCHAR:
|
||||||
|
extra = sizeof( SQLWCHAR );
|
||||||
|
break;
|
||||||
|
case SQL_C_BINARY:
|
||||||
|
extra = 0;
|
||||||
|
break;
|
||||||
|
case SQL_C_CHAR:
|
||||||
|
extra = sizeof( SQLCHAR );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SQLSRV_ASSERT( false, "Invalid type in read_lob_field" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLLEN already_read = 0;
|
||||||
|
SQLLEN to_read = INITIAL_FIELD_STRING_LEN;
|
||||||
|
sqlsrv_malloc_auto_ptr<char> buffer;
|
||||||
|
buffer = static_cast<char*>( sqlsrv_malloc( INITIAL_FIELD_STRING_LEN + extra + sizeof( SQLULEN )));
|
||||||
|
SQLRETURN r = SQL_SUCCESS;
|
||||||
|
SQLCHAR state[ SQL_SQLSTATE_BUFSIZE ];
|
||||||
|
SQLLEN last_field_len = 0;
|
||||||
|
bool full_length_returned = false;
|
||||||
|
|
||||||
|
do {
|
||||||
|
|
||||||
|
|
||||||
|
output_buffer_len = reinterpret_cast<SQLLEN*>( buffer.get() );
|
||||||
|
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 );
|
||||||
|
|
||||||
|
// if the field is NULL, then return a NULL pointer
|
||||||
|
if( last_field_len == SQL_NULL_DATA ) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the last read was successful, we're done
|
||||||
|
if( r == SQL_SUCCESS ) {
|
||||||
|
// check to make sure we haven't overflown our memory limit
|
||||||
|
CHECK_CUSTOM_ERROR( mem_used + last_field_len > stmt->buffered_query_limit * 1024, stmt,
|
||||||
|
SQLSRV_ERROR_BUFFER_LIMIT_EXCEEDED, stmt->buffered_query_limit ) {
|
||||||
|
|
||||||
|
throw core::CoreException();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// else if it wasn't the truncated warning (01004) then we're done
|
||||||
|
else if( r == SQL_SUCCESS_WITH_INFO ) {
|
||||||
|
SQLSMALLINT len;
|
||||||
|
core::SQLGetDiagField( stmt, 1, SQL_DIAG_SQLSTATE, state, SQL_SQLSTATE_BUFSIZE, &len
|
||||||
|
TSRMLS_CC );
|
||||||
|
|
||||||
|
if( !is_truncated_warning( state )) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLSRV_ASSERT( SQL_SUCCEEDED( r ), "Unknown SQL error not triggered" );
|
||||||
|
|
||||||
|
// if the type of the field returns the total to be read, we use that and preallocate the buffer
|
||||||
|
if( last_field_len != SQL_NO_TOTAL ) {
|
||||||
|
|
||||||
|
CHECK_CUSTOM_ERROR( mem_used + last_field_len > stmt->buffered_query_limit * 1024, stmt,
|
||||||
|
SQLSRV_ERROR_BUFFER_LIMIT_EXCEEDED, stmt->buffered_query_limit ) {
|
||||||
|
|
||||||
|
throw core::CoreException();
|
||||||
|
}
|
||||||
|
|
||||||
|
already_read += to_read - already_read;
|
||||||
|
to_read = last_field_len;
|
||||||
|
buffer.resize( to_read + extra + sizeof( SQLULEN ));
|
||||||
|
output_buffer_len = reinterpret_cast<SQLLEN*>( buffer.get() );
|
||||||
|
// record the size of the field since we have it available
|
||||||
|
*output_buffer_len = last_field_len;
|
||||||
|
full_length_returned = true;
|
||||||
|
}
|
||||||
|
// otherwise allocate another chunk of memory to read in
|
||||||
|
else {
|
||||||
|
already_read += to_read - already_read;
|
||||||
|
to_read *= 2;
|
||||||
|
CHECK_CUSTOM_ERROR( mem_used + to_read > stmt->buffered_query_limit * 1024, stmt,
|
||||||
|
SQLSRV_ERROR_BUFFER_LIMIT_EXCEEDED, stmt->buffered_query_limit ) {
|
||||||
|
|
||||||
|
throw core::CoreException();
|
||||||
|
}
|
||||||
|
buffer.resize( to_read + extra + sizeof( SQLULEN ));
|
||||||
|
output_buffer_len = reinterpret_cast<SQLLEN*>( buffer.get() );
|
||||||
|
}
|
||||||
|
|
||||||
|
} while( true );
|
||||||
|
|
||||||
|
SQLSRV_ASSERT( output_buffer_len != NULL, "Output buffer not allocated properly" );
|
||||||
|
|
||||||
|
// most LOB field types return the total length in the last_field_len, but some field types such as XML
|
||||||
|
// only return the amount read on the last read
|
||||||
|
if( !full_length_returned ) {
|
||||||
|
*output_buffer_len = already_read + last_field_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* return_buffer = buffer;
|
||||||
|
buffer.transferred();
|
||||||
|
return return_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -6,7 +6,7 @@
|
||||||
//
|
//
|
||||||
// Contents: Core routines and constants shared by the Microsoft Drivers for PHP for SQL Server
|
// Contents: Core routines and constants shared by the Microsoft Drivers for PHP for SQL Server
|
||||||
//
|
//
|
||||||
// Copyright 2010 Microsoft Corporation
|
// Copyright Microsoft Corporation
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -45,6 +45,10 @@ OACR_WARNING_DISABLE( INDEX_NEGATIVE, "Third party code." )
|
||||||
OACR_WARNING_DISABLE( UNANNOTATED_BUFFER, "Third party code." )
|
OACR_WARNING_DISABLE( UNANNOTATED_BUFFER, "Third party code." )
|
||||||
OACR_WARNING_DISABLE( INDEX_UNDERFLOW, "Third party code." )
|
OACR_WARNING_DISABLE( INDEX_UNDERFLOW, "Third party code." )
|
||||||
OACR_WARNING_DISABLE( REALLOCLEAK, "Third party code." )
|
OACR_WARNING_DISABLE( REALLOCLEAK, "Third party code." )
|
||||||
|
OACR_WARNING_DISABLE( ALLOC_SIZE_OVERFLOW_WITH_ACCESS, "Third party code." )
|
||||||
|
#else
|
||||||
|
// define to eliminate static analysis hints in the code
|
||||||
|
#define OACR_WARNING_SUPPRESS( warning, msg )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -88,8 +92,6 @@ OACR_WARNING_POP
|
||||||
#include <sql.h>
|
#include <sql.h>
|
||||||
#include <sqlext.h>
|
#include <sqlext.h>
|
||||||
|
|
||||||
#include <deque>
|
|
||||||
|
|
||||||
#if !defined(WC_ERR_INVALID_CHARS)
|
#if !defined(WC_ERR_INVALID_CHARS)
|
||||||
// imported from winnls.h as it isn't included by 5.3.0
|
// imported from winnls.h as it isn't included by 5.3.0
|
||||||
#define WC_ERR_INVALID_CHARS 0x00000080 // error for invalid chars
|
#define WC_ERR_INVALID_CHARS 0x00000080 // error for invalid chars
|
||||||
|
@ -101,8 +103,10 @@ OACR_WARNING_POP
|
||||||
#undef inline
|
#undef inline
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <deque>
|
||||||
|
#include <map>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <limits>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <strsafe.h>
|
#include <strsafe.h>
|
||||||
|
|
||||||
|
@ -216,10 +220,46 @@ struct sqlsrv_static_assert<true> { static const int value = 1; };
|
||||||
#define SQLSRV_STATIC_ASSERT( c ) (sqlsrv_static_assert<(c) != 0>() )
|
#define SQLSRV_STATIC_ASSERT( c ) (sqlsrv_static_assert<(c) != 0>() )
|
||||||
|
|
||||||
|
|
||||||
|
//*********************************************************************************************************************************
|
||||||
|
// Logging
|
||||||
|
//*********************************************************************************************************************************
|
||||||
|
// log_callback
|
||||||
|
// a driver specific callback for logging messages
|
||||||
|
// severity - severity of the message: notice, warning, or error
|
||||||
|
// msg - the message to log in a FormatMessage style formatting
|
||||||
|
// print_args - args to the message
|
||||||
|
typedef void (*log_callback)( unsigned int severity TSRMLS_DC, const char* msg, va_list* print_args );
|
||||||
|
|
||||||
|
// each driver must register a log callback. This should be the first thing a driver does.
|
||||||
|
void core_sqlsrv_register_logger( log_callback );
|
||||||
|
|
||||||
|
// a simple wrapper around a PHP error logging function.
|
||||||
|
void write_to_log( unsigned int severity TSRMLS_DC, const char* msg, ... );
|
||||||
|
|
||||||
|
// a macro to make it convenient to use the function.
|
||||||
|
#define LOG( severity, msg, ...) write_to_log( severity TSRMLS_CC, msg, __VA_ARGS__ )
|
||||||
|
|
||||||
|
// mask for filtering which severities are written to the log
|
||||||
|
enum logging_severity {
|
||||||
|
SEV_ERROR = 0x01,
|
||||||
|
SEV_WARNING = 0x02,
|
||||||
|
SEV_NOTICE = 0x04,
|
||||||
|
SEV_ALL = -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Kill the PHP process and log the message to PHP
|
||||||
|
void die( const char* msg, ... );
|
||||||
|
#define DIE( msg, ... ) { die( msg, __VA_ARGS__ ); }
|
||||||
|
|
||||||
|
|
||||||
//*********************************************************************************************************************************
|
//*********************************************************************************************************************************
|
||||||
// Resource/Memory Management
|
// Resource/Memory Management
|
||||||
//*********************************************************************************************************************************
|
//*********************************************************************************************************************************
|
||||||
|
|
||||||
|
// the macro max is defined and overrides the call to max in the allocator class
|
||||||
|
#pragma push_macro( "max" )
|
||||||
|
#undef max
|
||||||
|
|
||||||
// new memory allocation/free debugging facilities to help us verify that all allocations are being
|
// new memory allocation/free debugging facilities to help us verify that all allocations are being
|
||||||
// released in a timely manner and not just at the end of the script.
|
// released in a timely manner and not just at the end of the script.
|
||||||
// Zend has memory logging and checking, but it can generate a lot of noise for just one extension.
|
// Zend has memory logging and checking, but it can generate a lot of noise for just one extension.
|
||||||
|
@ -229,36 +269,89 @@ struct sqlsrv_static_assert<true> { static const int value = 1; };
|
||||||
// #define SQLSRV_MEM_DEBUG 1
|
// #define SQLSRV_MEM_DEBUG 1
|
||||||
#if defined( PHP_DEBUG ) && !defined( ZTS ) && defined( SQLSRV_MEM_DEBUG )
|
#if defined( PHP_DEBUG ) && !defined( ZTS ) && defined( SQLSRV_MEM_DEBUG )
|
||||||
|
|
||||||
// macro to log memory allocation and frees locations and their sizes
|
inline void* sqlsrv_malloc_trace( size_t size, const char* file, int line )
|
||||||
inline void* emalloc_trace( size_t size, const char* file, int line )
|
|
||||||
{
|
{
|
||||||
void* ptr = emalloc( size );
|
void* ptr = emalloc( size );
|
||||||
LOG( SEV_NOTICE, "emalloc returned %4!08x!: %1!d! bytes at %2!s!:%3!d!", size, file, line, ptr );
|
LOG( SEV_NOTICE, "emalloc returned %4!08x!: %1!d! bytes at %2!s!:%3!d!", size, file, line, ptr );
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void* erealloc_trace( void* original, size_t size, const char* file, int line )
|
inline void* sqlsrv_malloc_trace( size_t element_count, size_t element_size, size_t extra, const char* file, int line )
|
||||||
|
{
|
||||||
|
OACR_WARNING_SUPPRESS( ALLOC_SIZE_OVERFLOW_IN_ALLOC_WRAPPER, "Overflow verified below" );
|
||||||
|
|
||||||
|
if(( element_count > 0 && element_size > 0 ) &&
|
||||||
|
( element_count > element_size * element_count || element_size > element_size * element_count )) {
|
||||||
|
DIE( "Integer overflow in sqlsrv_malloc" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( element_size * element_count > element_size * element_count + extra ) {
|
||||||
|
DIE( "Integer overflow in sqlsrv_malloc" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( element_size * element_count + extra == 0 ) {
|
||||||
|
DIE( "Allocation size must be more than 0" );
|
||||||
|
}
|
||||||
|
|
||||||
|
void* ptr = emalloc( element_size * element_count + extra );
|
||||||
|
LOG( SEV_NOTICE, "emalloc returned %4!08x!: %1!d! bytes at %2!s!:%3!d!", size, file, line, ptr );
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void* sqlsrv_realloc_trace( void* buffer, size_t size, const char* file, int line )
|
||||||
{
|
{
|
||||||
void* ptr = erealloc( original, size );
|
void* ptr = erealloc( original, size );
|
||||||
LOG( SEV_NOTICE, "erealloc returned %5!08x! from %4!08x!: %1!d! bytes at %2!s!:%3!d!", size, file, line, ptr, original );
|
LOG( SEV_NOTICE, "erealloc returned %5!08x! from %4!08x!: %1!d! bytes at %2!s!:%3!d!", size, file, line, ptr, original );
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void efree_trace( void* ptr, const char* file, int line )
|
inline void sqlsrv_free_trace( void* ptr, const char* file, int line )
|
||||||
{
|
{
|
||||||
LOG( SEV_NOTICE, "efree %1!08x! at %2!s!:%3!d!", ptr, file, line );
|
LOG( SEV_NOTICE, "efree %1!08x! at %2!s!:%3!d!", ptr, file, line );
|
||||||
efree( ptr );
|
efree( ptr );
|
||||||
}
|
}
|
||||||
|
|
||||||
#define sqlsrv_malloc( size ) emalloc_trace( size, __FILE__, __LINE__ )
|
#define sqlsrv_malloc( size ) sqlsrv_malloc_trace( size, __FILE__, __LINE__ )
|
||||||
#define sqlsrv_realloc( buffer, size ) erealloc_trace( buffer, size, __FILE__, __LINE__ )
|
#define sqlsrv_malloc( count, size, extra ) sqlsrv_malloc_trace( count, size, extra, __FILE__, __LINE__ )
|
||||||
#define sqlsrv_free( ptr ) efree_trace( ptr, __FILE__, __LINE__ )
|
#define sqlsrv_realloc( buffer, size ) sqlsrv_realloc_trace( buffer, size, __FILE__, __LINE__ )
|
||||||
|
#define sqlsrv_free( ptr ) sqlsrv_free_trace( ptr, __FILE__, __LINE__ )
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define sqlsrv_malloc( size ) emalloc( size )
|
inline void* sqlsrv_malloc( size_t size )
|
||||||
#define sqlsrv_realloc( buffer, size ) erealloc( buffer, size )
|
{
|
||||||
#define sqlsrv_free( ptr ) efree( ptr )
|
return emalloc( size );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void* sqlsrv_malloc( size_t element_count, size_t element_size, size_t extra )
|
||||||
|
{
|
||||||
|
OACR_WARNING_SUPPRESS( ALLOC_SIZE_OVERFLOW_IN_ALLOC_WRAPPER, "Overflow verified below" );
|
||||||
|
|
||||||
|
if(( element_count > 0 && element_size > 0 ) &&
|
||||||
|
( element_count > element_size * element_count || element_size > element_size * element_count )) {
|
||||||
|
DIE( "Integer overflow in sqlsrv_malloc" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( element_size * element_count > element_size * element_count + extra ) {
|
||||||
|
DIE( "Integer overflow in sqlsrv_malloc" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( element_size * element_count + extra == 0 ) {
|
||||||
|
DIE( "Allocation size must be more than 0" );
|
||||||
|
}
|
||||||
|
|
||||||
|
return emalloc( element_size * element_count + extra );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void* sqlsrv_realloc( void* buffer, size_t size )
|
||||||
|
{
|
||||||
|
return erealloc( buffer, size );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void sqlsrv_free( void* ptr )
|
||||||
|
{
|
||||||
|
efree( ptr );
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -273,6 +366,84 @@ struct remove_const<const T*> {
|
||||||
typedef T* type;
|
typedef T* type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// allocator that uses the zend memory manager to manage memory
|
||||||
|
// this allows us to use STL classes that still work with Zend objects
|
||||||
|
template<typename T>
|
||||||
|
struct sqlsrv_allocator {
|
||||||
|
|
||||||
|
// typedefs used by the STL classes
|
||||||
|
typedef T value_type;
|
||||||
|
typedef value_type* pointer;
|
||||||
|
typedef const value_type* const_pointer;
|
||||||
|
typedef value_type& reference;
|
||||||
|
typedef const value_type& const_reference;
|
||||||
|
typedef std::size_t size_type;
|
||||||
|
typedef std::ptrdiff_t difference_type;
|
||||||
|
|
||||||
|
// conversion typedef (used by list and other STL classes)
|
||||||
|
template<typename U>
|
||||||
|
struct rebind {
|
||||||
|
typedef sqlsrv_allocator<U> other;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline sqlsrv_allocator() {}
|
||||||
|
inline ~sqlsrv_allocator() {}
|
||||||
|
inline sqlsrv_allocator( sqlsrv_allocator const& ) {}
|
||||||
|
template<typename U>
|
||||||
|
inline sqlsrv_allocator( sqlsrv_allocator<U> const& ) {}
|
||||||
|
|
||||||
|
// address (doesn't work if the class defines operator&)
|
||||||
|
inline pointer address( reference r )
|
||||||
|
{
|
||||||
|
return &r;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const_pointer address( const_reference r )
|
||||||
|
{
|
||||||
|
return &r;
|
||||||
|
}
|
||||||
|
|
||||||
|
// memory allocation/deallocation
|
||||||
|
inline pointer allocate( size_type cnt,
|
||||||
|
typename std::allocator<void>::const_pointer = 0 )
|
||||||
|
{
|
||||||
|
return reinterpret_cast<pointer>( sqlsrv_malloc(cnt, sizeof (T), 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void deallocate( pointer p, size_type )
|
||||||
|
{
|
||||||
|
sqlsrv_free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
// size
|
||||||
|
inline size_type max_size( void ) const
|
||||||
|
{
|
||||||
|
return std::numeric_limits<size_type>::max() / sizeof(T);
|
||||||
|
}
|
||||||
|
|
||||||
|
// object construction/destruction
|
||||||
|
inline void construct( pointer p, const T& t )
|
||||||
|
{
|
||||||
|
new(p) T(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void destroy(pointer p)
|
||||||
|
{
|
||||||
|
p->~T();
|
||||||
|
}
|
||||||
|
|
||||||
|
// equality operators
|
||||||
|
inline bool operator==( sqlsrv_allocator const& )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator!=( sqlsrv_allocator const& a )
|
||||||
|
{
|
||||||
|
return !operator==(a);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// base class for auto_ptrs that we define below. It provides common operators and functions
|
// base class for auto_ptrs that we define below. It provides common operators and functions
|
||||||
// used by all the classes.
|
// used by all the classes.
|
||||||
|
@ -398,6 +569,8 @@ protected:
|
||||||
// in a variable of sqlsrv_malloc_auto_ptr. sqlsrv_malloc_auto_ptr will "own" that block and assure that it is
|
// in a variable of sqlsrv_malloc_auto_ptr. sqlsrv_malloc_auto_ptr will "own" that block and assure that it is
|
||||||
// freed until the variable is destroyed (out of scope) or ownership is transferred using the function
|
// freed until the variable is destroyed (out of scope) or ownership is transferred using the function
|
||||||
// "transferred".
|
// "transferred".
|
||||||
|
// DO NOT CALL sqlsrv_realloc with a sqlsrv_malloc_auto_ptr. Use the resize member function.
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class sqlsrv_malloc_auto_ptr : public sqlsrv_auto_ptr<T, sqlsrv_malloc_auto_ptr<T> > {
|
class sqlsrv_malloc_auto_ptr : public sqlsrv_auto_ptr<T, sqlsrv_malloc_auto_ptr<T> > {
|
||||||
|
|
||||||
|
@ -432,6 +605,13 @@ public:
|
||||||
src.transferred();
|
src.transferred();
|
||||||
this->_ptr = p;
|
this->_ptr = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DO NOT CALL sqlsrv_realloc with a sqlsrv_malloc_auto_ptr. Use the resize member function.
|
||||||
|
// has the same parameter list as sqlsrv_realloc: new_size is the size in bytes of the newly allocated buffer
|
||||||
|
void resize( size_t new_size )
|
||||||
|
{
|
||||||
|
_ptr = reinterpret_cast<T*>( sqlsrv_realloc( _ptr, new_size ));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -507,6 +687,9 @@ private:
|
||||||
zval_auto_ptr( const zval_auto_ptr& src );
|
zval_auto_ptr( const zval_auto_ptr& src );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#pragma pop_macro( "max" )
|
||||||
|
|
||||||
|
|
||||||
//*********************************************************************************************************************************
|
//*********************************************************************************************************************************
|
||||||
// sqlsrv_error
|
// sqlsrv_error
|
||||||
//*********************************************************************************************************************************
|
//*********************************************************************************************************************************
|
||||||
|
@ -546,6 +729,11 @@ struct sqlsrv_error : public sqlsrv_error_const {
|
||||||
format = printf_format;
|
format = printf_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sqlsrv_error( sqlsrv_error_const const& prototype )
|
||||||
|
{
|
||||||
|
sqlsrv_error( prototype.sqlstate, prototype.native_message, prototype.native_code, prototype.format );
|
||||||
|
}
|
||||||
|
|
||||||
~sqlsrv_error( void )
|
~sqlsrv_error( void )
|
||||||
{
|
{
|
||||||
if( sqlstate != NULL ) {
|
if( sqlstate != NULL ) {
|
||||||
|
@ -816,6 +1004,7 @@ enum SQLSRV_STMT_OPTIONS {
|
||||||
SQLSRV_STMT_OPTION_QUERY_TIMEOUT,
|
SQLSRV_STMT_OPTION_QUERY_TIMEOUT,
|
||||||
SQLSRV_STMT_OPTION_SEND_STREAMS_AT_EXEC,
|
SQLSRV_STMT_OPTION_SEND_STREAMS_AT_EXEC,
|
||||||
SQLSRV_STMT_OPTION_SCROLLABLE,
|
SQLSRV_STMT_OPTION_SCROLLABLE,
|
||||||
|
SQLSRV_STMT_OPTION_CLIENT_BUFFER_MAX_SIZE,
|
||||||
|
|
||||||
// Driver specific connection options
|
// Driver specific connection options
|
||||||
SQLSRV_STMT_OPTION_DRIVER_SPECIFIC = 1000,
|
SQLSRV_STMT_OPTION_DRIVER_SPECIFIC = 1000,
|
||||||
|
@ -825,6 +1014,8 @@ enum SQLSRV_STMT_OPTIONS {
|
||||||
namespace ODBCConnOptions {
|
namespace ODBCConnOptions {
|
||||||
|
|
||||||
const char APP[] = "APP";
|
const char APP[] = "APP";
|
||||||
|
const char ApplicationIntent[] = "ApplicationIntent";
|
||||||
|
const char AttachDBFileName[] = "AttachDbFileName";
|
||||||
const char CharacterSet[] = "CharacterSet";
|
const char CharacterSet[] = "CharacterSet";
|
||||||
const char ConnectionPooling[] = "ConnectionPooling";
|
const char ConnectionPooling[] = "ConnectionPooling";
|
||||||
const char Database[] = "Database";
|
const char Database[] = "Database";
|
||||||
|
@ -832,6 +1023,7 @@ const char Encrypt[] = "Encrypt";
|
||||||
const char Failover_Partner[] = "Failover_Partner";
|
const char Failover_Partner[] = "Failover_Partner";
|
||||||
const char LoginTimeout[] = "LoginTimggeout";
|
const char LoginTimeout[] = "LoginTimggeout";
|
||||||
const char MARS_ODBC[] = "MARS_Connection";
|
const char MARS_ODBC[] = "MARS_Connection";
|
||||||
|
const char MultiSubnetFailover[] = "MultiSubnetFailover";
|
||||||
const char QuotedId[] = "QuotedId";
|
const char QuotedId[] = "QuotedId";
|
||||||
const char TraceFile[] = "TraceFile";
|
const char TraceFile[] = "TraceFile";
|
||||||
const char TraceOn[] = "TraceOn";
|
const char TraceOn[] = "TraceOn";
|
||||||
|
@ -861,6 +1053,9 @@ enum SQLSRV_CONN_OPTIONS {
|
||||||
SQLSRV_CONN_OPTION_TRANS_ISOLATION,
|
SQLSRV_CONN_OPTION_TRANS_ISOLATION,
|
||||||
SQLSRV_CONN_OPTION_TRUST_SERVER_CERT,
|
SQLSRV_CONN_OPTION_TRUST_SERVER_CERT,
|
||||||
SQLSRV_CONN_OPTION_WSID,
|
SQLSRV_CONN_OPTION_WSID,
|
||||||
|
SQLSRV_CONN_OPTION_ATTACHDBFILENAME,
|
||||||
|
SQLSRV_CONN_OPTION_APPLICATION_INTENT,
|
||||||
|
SQLSRV_CONN_OPTION_MULTI_SUBNET_FAILOVER,
|
||||||
|
|
||||||
// Driver specific connection options
|
// Driver specific connection options
|
||||||
SQLSRV_CONN_OPTION_DRIVER_SPECIFIC = 1000,
|
SQLSRV_CONN_OPTION_DRIVER_SPECIFIC = 1000,
|
||||||
|
@ -963,6 +1158,11 @@ struct stmt_option_send_at_exec : public stmt_option_functor {
|
||||||
virtual void operator()( sqlsrv_stmt* stmt, stmt_option const* opt, zval* value_z TSRMLS_DC );
|
virtual void operator()( sqlsrv_stmt* stmt, stmt_option const* opt, zval* value_z TSRMLS_DC );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct stmt_option_buffered_query_limit : public stmt_option_functor {
|
||||||
|
|
||||||
|
virtual void operator()( sqlsrv_stmt* stmt, stmt_option const* opt, zval* value_z TSRMLS_DC );
|
||||||
|
};
|
||||||
|
|
||||||
// used to hold the table for statment options
|
// used to hold the table for statment options
|
||||||
struct stmt_option {
|
struct stmt_option {
|
||||||
|
|
||||||
|
@ -1029,25 +1229,28 @@ struct sqlsrv_output_param {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// forward decls
|
||||||
|
struct sqlsrv_result_set;
|
||||||
|
|
||||||
// *** 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( TSRMLS_D );
|
||||||
virtual void new_result_set( void );
|
virtual void new_result_set( TSRMLS_D );
|
||||||
|
|
||||||
sqlsrv_conn* conn; // Connection that created this statement
|
sqlsrv_conn* conn; // Connection that created this statement
|
||||||
|
|
||||||
bool executed; // Whether the statement has been executed yet (used for error messages)
|
bool executed; // Whether the statement has been executed yet (used for error messages)
|
||||||
bool past_fetch_end; // Core_sqlsrv_fetch sets this field when the statement goes beyond the last row
|
bool past_fetch_end; // Core_sqlsrv_fetch sets this field when the statement goes beyond the last row
|
||||||
bool scrollable; // Determines if the statement was created with the Scrollable query attribute
|
sqlsrv_result_set* current_results; // Current result set
|
||||||
// (don't have to use ODBC to find out)
|
SQLULEN cursor_type; // Type of cursor for the current result set
|
||||||
bool scroll_is_dynamic; // if scrollable, is it a dynamic cursor.
|
|
||||||
bool has_rows; // Has_rows is set if there are actual rows in the row set
|
bool has_rows; // Has_rows is set if there are actual rows in the row set
|
||||||
bool fetch_called; // Used by core_sqlsrv_get_field to return an informative error if fetch not yet called
|
bool fetch_called; // Used by core_sqlsrv_get_field to return an informative error if fetch not yet called
|
||||||
int last_field_index; // last field retrieved by core_sqlsrv_get_field
|
int last_field_index; // last field retrieved by core_sqlsrv_get_field
|
||||||
bool past_next_result_end; // core_sqlsrv_next_result sets this to true when the statement goes beyond the
|
bool past_next_result_end; // core_sqlsrv_next_result sets this to true when the statement goes beyond the
|
||||||
// last results
|
// last results
|
||||||
unsigned long query_timeout; // maximum allowed statement execution time
|
unsigned long query_timeout; // maximum allowed statement execution time
|
||||||
|
unsigned long buffered_query_limit; // maximum allowed memory for a buffered query (measured in KB)
|
||||||
|
|
||||||
// holds output pointers for SQLBindParameter
|
// holds output pointers for SQLBindParameter
|
||||||
// We use a deque because it 1) provides the at/[] access in constant time, and 2) grows dynamically without moving
|
// We use a deque because it 1) provides the at/[] access in constant time, and 2) grows dynamically without moving
|
||||||
|
@ -1101,6 +1304,9 @@ const int SQLSRV_DEFAULT_SIZE = -1; // size given for an output parameter th
|
||||||
// uninitialized query timeout value
|
// uninitialized query timeout value
|
||||||
const unsigned int QUERY_TIMEOUT_INVALID = 0xffffffff;
|
const unsigned int QUERY_TIMEOUT_INVALID = 0xffffffff;
|
||||||
|
|
||||||
|
// special buffered query constant
|
||||||
|
const size_t SQLSRV_CURSOR_BUFFERED = 0xfffffffeUL; // arbitrary number that doesn't map to any other SQL_CURSOR_* constant
|
||||||
|
|
||||||
// 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 TSRMLS_DC );
|
||||||
|
|
||||||
|
@ -1117,42 +1323,181 @@ void core_sqlsrv_get_field( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_
|
||||||
__out void** field_value, __out SQLLEN* field_length, bool cache_field,
|
__out void** field_value, __out SQLLEN* field_length, bool cache_field,
|
||||||
__out SQLSRV_PHPTYPE *sqlsrv_php_type_out TSRMLS_DC );
|
__out SQLSRV_PHPTYPE *sqlsrv_php_type_out TSRMLS_DC );
|
||||||
bool core_sqlsrv_has_any_result( sqlsrv_stmt* stmt TSRMLS_DC );
|
bool core_sqlsrv_has_any_result( sqlsrv_stmt* stmt TSRMLS_DC );
|
||||||
void core_sqlsrv_next_result( sqlsrv_stmt* stmt TSRMLS_DC, bool finalize_output_params = true );
|
void core_sqlsrv_next_result( sqlsrv_stmt* stmt TSRMLS_DC, bool finalize_output_params = true, bool throw_on_errors = true );
|
||||||
void core_sqlsrv_post_param( sqlsrv_stmt* stmt, unsigned int paramno, zval* param_z TSRMLS_DC );
|
void core_sqlsrv_post_param( sqlsrv_stmt* stmt, unsigned int paramno, zval* param_z TSRMLS_DC );
|
||||||
void core_sqlsrv_set_scrollable( sqlsrv_stmt* stmt, unsigned int cursor_type TSRMLS_DC );
|
void core_sqlsrv_set_scrollable( sqlsrv_stmt* stmt, unsigned int cursor_type TSRMLS_DC );
|
||||||
void core_sqlsrv_set_query_timeout( sqlsrv_stmt* stmt, long timeout TSRMLS_DC );
|
void core_sqlsrv_set_query_timeout( sqlsrv_stmt* stmt, long timeout TSRMLS_DC );
|
||||||
void core_sqlsrv_set_query_timeout( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC );
|
void core_sqlsrv_set_query_timeout( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC );
|
||||||
void core_sqlsrv_set_send_at_exec( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC );
|
void core_sqlsrv_set_send_at_exec( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC );
|
||||||
bool core_sqlsrv_send_stream_packet( sqlsrv_stmt* stmt TSRMLS_DC );
|
bool core_sqlsrv_send_stream_packet( sqlsrv_stmt* stmt TSRMLS_DC );
|
||||||
|
void core_sqlsrv_set_buffered_query_limit( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC );
|
||||||
|
void core_sqlsrv_set_buffered_query_limit( sqlsrv_stmt* stmt, long limit TSRMLS_DC );
|
||||||
|
|
||||||
|
|
||||||
//*********************************************************************************************************************************
|
//*********************************************************************************************************************************
|
||||||
// Logging
|
// Result Set
|
||||||
//*********************************************************************************************************************************
|
//*********************************************************************************************************************************
|
||||||
// log_callback
|
|
||||||
// a driver specific callback for logging messages
|
|
||||||
// severity - severity of the message: notice, warning, or error
|
|
||||||
// msg - the message to log in a FormatMessage style formatting
|
|
||||||
// print_args - args to the message
|
|
||||||
typedef void (*log_callback)( unsigned int severity TSRMLS_DC, const char* msg, va_list* print_args );
|
|
||||||
|
|
||||||
// each driver must register a log callback. This should be the first thing a driver does.
|
// Abstract the result set so that a result set can either be used as is from ODBC or buffered.
|
||||||
void core_sqlsrv_register_logger( log_callback );
|
// This is not a complete abstraction of a result set. Only enough is abstracted to allow for
|
||||||
|
// information and capabilities normally not available when a result set is not buffered
|
||||||
|
// (e.g., forward only vs buffered means row count is available and cursor movement is possible).
|
||||||
|
// Otherwise, normal ODBC calls are still valid and should be used to get information about the
|
||||||
|
// result set (e.g., SQLNumResultCols).
|
||||||
|
|
||||||
// a simple wrapper around a PHP error logging function.
|
struct sqlsrv_result_set {
|
||||||
void write_to_log( unsigned int severity TSRMLS_DC, const char* msg, ... );
|
|
||||||
|
|
||||||
// a macro to make it convenient to use the function.
|
sqlsrv_stmt* odbc;
|
||||||
#define LOG( severity, msg, ...) write_to_log( severity TSRMLS_CC, msg, __VA_ARGS__ )
|
|
||||||
|
|
||||||
// mask for filtering which severities are written to the log
|
explicit sqlsrv_result_set( sqlsrv_stmt* );
|
||||||
enum logging_severity {
|
virtual ~sqlsrv_result_set( void ) { }
|
||||||
SEV_ERROR = 0x01,
|
|
||||||
SEV_WARNING = 0x02,
|
virtual bool cached( int field_index ) = 0;
|
||||||
SEV_NOTICE = 0x04,
|
virtual SQLRETURN fetch( SQLSMALLINT fetch_orientation, SQLLEN fetch_offset TSRMLS_DC ) = 0;
|
||||||
SEV_ALL = -1,
|
virtual SQLRETURN get_data( SQLUSMALLINT field_index, SQLSMALLINT target_type,
|
||||||
|
__out void* buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length,
|
||||||
|
bool handle_warning TSRMLS_DC )= 0;
|
||||||
|
virtual SQLRETURN get_diag_field( SQLSMALLINT record_number, SQLSMALLINT diag_identifier,
|
||||||
|
__out SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
|
||||||
|
__out SQLSMALLINT* out_buffer_length TSRMLS_DC ) = 0;
|
||||||
|
virtual sqlsrv_error* get_diag_rec( SQLSMALLINT record_number ) = 0;
|
||||||
|
virtual SQLLEN row_count( TSRMLS_D ) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct sqlsrv_odbc_result_set : public sqlsrv_result_set {
|
||||||
|
|
||||||
|
explicit sqlsrv_odbc_result_set( sqlsrv_stmt* );
|
||||||
|
virtual ~sqlsrv_odbc_result_set( void );
|
||||||
|
|
||||||
|
virtual bool cached( int field_index ) { return false; }
|
||||||
|
virtual SQLRETURN fetch( SQLSMALLINT fetch_orientation, SQLLEN fetch_offset TSRMLS_DC );
|
||||||
|
virtual SQLRETURN get_data( SQLUSMALLINT field_index, SQLSMALLINT target_type,
|
||||||
|
__out void* buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length,
|
||||||
|
bool handle_warning TSRMLS_DC );
|
||||||
|
virtual SQLRETURN get_diag_field( SQLSMALLINT record_number, SQLSMALLINT diag_identifier,
|
||||||
|
__out SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
|
||||||
|
__out SQLSMALLINT* out_buffer_length TSRMLS_DC );
|
||||||
|
virtual sqlsrv_error* get_diag_rec( SQLSMALLINT record_number );
|
||||||
|
virtual SQLLEN row_count( TSRMLS_D );
|
||||||
|
|
||||||
|
private:
|
||||||
|
// prevent invalid instantiations and assignments
|
||||||
|
sqlsrv_odbc_result_set( void );
|
||||||
|
sqlsrv_odbc_result_set( sqlsrv_odbc_result_set& );
|
||||||
|
sqlsrv_odbc_result_set& operator=( sqlsrv_odbc_result_set& );
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sqlsrv_buffered_result_set : public sqlsrv_result_set {
|
||||||
|
|
||||||
|
struct meta_data {
|
||||||
|
SQLSMALLINT type;
|
||||||
|
SQLSMALLINT c_type; // convenience
|
||||||
|
SQLULEN offset; // in bytes
|
||||||
|
SQLULEN length; // in bytes
|
||||||
|
SQLSMALLINT scale;
|
||||||
|
|
||||||
|
static const SQLULEN SIZE_UNKNOWN = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// default maximum amount of memory that a buffered query can consume
|
||||||
|
#define INI_BUFFERED_QUERY_LIMIT_DEFAULT "10240" // default used by the php.ini settings
|
||||||
|
static const unsigned long BUFFERED_QUERY_LIMIT_DEFAULT = 10240; // measured in KB
|
||||||
|
static const long BUFFERED_QUERY_LIMIT_INVALID = 0;
|
||||||
|
|
||||||
|
explicit sqlsrv_buffered_result_set( sqlsrv_stmt* odbc TSRMLS_DC );
|
||||||
|
virtual ~sqlsrv_buffered_result_set( void );
|
||||||
|
|
||||||
|
virtual bool cached( int field_index ) { return true; }
|
||||||
|
virtual SQLRETURN fetch( SQLSMALLINT fetch_orientation, SQLLEN fetch_offset TSRMLS_DC );
|
||||||
|
virtual SQLRETURN get_data( SQLUSMALLINT field_index, SQLSMALLINT target_type,
|
||||||
|
__out void* buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length,
|
||||||
|
bool handle_warning TSRMLS_DC );
|
||||||
|
virtual SQLRETURN get_diag_field( SQLSMALLINT record_number, SQLSMALLINT diag_identifier,
|
||||||
|
__out SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length,
|
||||||
|
__out SQLSMALLINT* out_buffer_length TSRMLS_DC );
|
||||||
|
virtual sqlsrv_error* get_diag_rec( SQLSMALLINT record_number );
|
||||||
|
virtual SQLLEN row_count( TSRMLS_D );
|
||||||
|
|
||||||
|
// buffered result set specific
|
||||||
|
SQLSMALLINT column_count( void )
|
||||||
|
{
|
||||||
|
return col_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct meta_data& col_meta_data( SQLSMALLINT i )
|
||||||
|
{
|
||||||
|
return meta[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// prevent invalid instantiations and assignments
|
||||||
|
sqlsrv_buffered_result_set( void );
|
||||||
|
sqlsrv_buffered_result_set( sqlsrv_buffered_result_set& );
|
||||||
|
sqlsrv_buffered_result_set& operator=( sqlsrv_buffered_result_set& );
|
||||||
|
|
||||||
|
HashTable* cache; // rows of data kept in index based hash table
|
||||||
|
SQLSMALLINT col_count; // number of columns in the current result set
|
||||||
|
meta_data* meta; // metadata for fields in the cache
|
||||||
|
SQLLEN current; // 1 based, 0 means before first row
|
||||||
|
sqlsrv_error_auto_ptr last_error; // if an error occurred, it is kept here
|
||||||
|
SQLUSMALLINT last_field_index; // the last field data retrieved from
|
||||||
|
SQLLEN read_so_far; // position within string to read from (for partial reads of strings)
|
||||||
|
sqlsrv_malloc_auto_ptr<SQLCHAR> temp_string; // temp buffer to hold a converted field while in use
|
||||||
|
SQLLEN temp_length; // number of bytes in the temp conversion buffer
|
||||||
|
|
||||||
|
typedef SQLRETURN (sqlsrv_buffered_result_set::*conv_fn)( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
typedef std::map< SQLINTEGER, std::map< SQLINTEGER, conv_fn > > conv_matrix_t;
|
||||||
|
|
||||||
|
// two dimentional sparse matrix that holds the [from][to] functions that do conversions
|
||||||
|
static conv_matrix_t conv_matrix;
|
||||||
|
|
||||||
|
// string conversion functions
|
||||||
|
SQLRETURN binary_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
SQLRETURN binary_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
SQLRETURN system_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
SQLRETURN to_binary_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
SQLRETURN to_same_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
SQLRETURN wide_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
|
||||||
|
// long conversion functions
|
||||||
|
SQLRETURN to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length );
|
||||||
|
SQLRETURN long_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
SQLRETURN long_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
SQLRETURN long_to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
|
||||||
|
// double conversion functions
|
||||||
|
SQLRETURN to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length, __out SQLLEN* out_buffer_length );
|
||||||
|
SQLRETURN double_to_system_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
SQLRETURN double_to_wide_string( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
SQLRETURN double_to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
|
||||||
|
// string to number conversion functions
|
||||||
|
// Future: See if these can be converted directly to template member functions
|
||||||
|
SQLRETURN string_to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
SQLRETURN string_to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
SQLRETURN wstring_to_double( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
SQLRETURN wstring_to_long( SQLSMALLINT field_index, __out void* buffer, SQLLEN buffer_length,
|
||||||
|
__out SQLLEN* out_buffer_length );
|
||||||
|
|
||||||
|
// utility functions for conversions
|
||||||
|
unsigned char* get_row( void );
|
||||||
|
};
|
||||||
|
|
||||||
//*********************************************************************************************************************************
|
//*********************************************************************************************************************************
|
||||||
// Utility
|
// Utility
|
||||||
|
@ -1205,7 +1550,7 @@ enum SQLSRV_ERROR_CODES {
|
||||||
SQLSRV_ERROR_INVALID_CONNECTION_KEY,
|
SQLSRV_ERROR_INVALID_CONNECTION_KEY,
|
||||||
SQLSRV_ERROR_MAX_PARAMS_EXCEEDED,
|
SQLSRV_ERROR_MAX_PARAMS_EXCEEDED,
|
||||||
SQLSRV_ERROR_INVALID_OPTION_KEY,
|
SQLSRV_ERROR_INVALID_OPTION_KEY,
|
||||||
SQLSRV_ERROR_INVALID_OPTION_VALUE,
|
SQLSRV_ERROR_INVALID_QUERY_TIMEOUT_VALUE,
|
||||||
SQLSRV_ERROR_INVALID_OPTION_SCROLLABLE,
|
SQLSRV_ERROR_INVALID_OPTION_SCROLLABLE,
|
||||||
SQLSRV_ERROR_QUERY_STRING_ENCODING_TRANSLATE,
|
SQLSRV_ERROR_QUERY_STRING_ENCODING_TRANSLATE,
|
||||||
SQLSRV_ERROR_OUTPUT_PARAM_TRUNCATED,
|
SQLSRV_ERROR_OUTPUT_PARAM_TRUNCATED,
|
||||||
|
@ -1215,6 +1560,8 @@ enum SQLSRV_ERROR_CODES {
|
||||||
SQLSRV_ERROR_STREAM_CREATE,
|
SQLSRV_ERROR_STREAM_CREATE,
|
||||||
SQLSRV_ERROR_MARS_OFF,
|
SQLSRV_ERROR_MARS_OFF,
|
||||||
SQLSRV_ERROR_FIELD_INDEX_ERROR,
|
SQLSRV_ERROR_FIELD_INDEX_ERROR,
|
||||||
|
SQLSRV_ERROR_BUFFER_LIMIT_EXCEEDED,
|
||||||
|
SQLSRV_ERROR_INVALID_BUFFER_LIMIT,
|
||||||
|
|
||||||
// Driver specific error codes starts from here.
|
// Driver specific error codes starts from here.
|
||||||
SQLSRV_ERROR_DRIVER_SPECIFIC = 1000,
|
SQLSRV_ERROR_DRIVER_SPECIFIC = 1000,
|
||||||
|
@ -1222,7 +1569,8 @@ enum SQLSRV_ERROR_CODES {
|
||||||
};
|
};
|
||||||
|
|
||||||
// the message returned by SQL Native Client
|
// the message returned by SQL Native Client
|
||||||
const char CONNECTION_BUSY_ODBC_ERROR[] = "[Microsoft][SQL Server Native Client 10.0]Connection is busy with results for another command";
|
const char CONNECTION_BUSY_ODBC_ERROR[] = "[Microsoft][SQL Server Native Client 11.0]Connection is busy with results for "
|
||||||
|
"another command";
|
||||||
|
|
||||||
// SQLSTATE for all internal errors
|
// SQLSTATE for all internal errors
|
||||||
extern SQLCHAR IMSSP[];
|
extern SQLCHAR IMSSP[];
|
||||||
|
@ -1244,11 +1592,12 @@ enum error_handling_flags {
|
||||||
// 2/code) driver specific error code
|
// 2/code) driver specific error code
|
||||||
// 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( sqlsrv_context& ctx, int record_number, sqlsrv_error* error, logging_severity severity TSRMLS_DC );
|
bool core_sqlsrv_get_odbc_error( sqlsrv_context& ctx, int record_number, __out sqlsrv_error_auto_ptr& error,
|
||||||
|
logging_severity severity TSRMLS_DC );
|
||||||
|
|
||||||
// format and return a driver specfic error
|
// format and return a driver specfic error
|
||||||
void core_sqlsrv_format_driver_error( sqlsrv_context& ctx, sqlsrv_error_const const* custom_error,
|
void core_sqlsrv_format_driver_error( sqlsrv_context& ctx, sqlsrv_error_const const* custom_error,
|
||||||
sqlsrv_error* formatted_error, logging_severity severity TSRMLS_DC, va_list* args );
|
sqlsrv_error_auto_ptr& formatted_error, logging_severity severity TSRMLS_DC, 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
|
||||||
|
@ -1278,10 +1627,6 @@ inline bool call_error_handler( sqlsrv_context* ctx, unsigned int sqlsrv_error_c
|
||||||
return ignored;
|
return ignored;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kill the PHP process and log the message to PHP
|
|
||||||
void die( const char* msg, ... );
|
|
||||||
#define DIE( msg, ... ) { die( msg, __VA_ARGS__ ); }
|
|
||||||
|
|
||||||
// PHP equivalent of ASSERT. C asserts cause a dialog to show and halt the process which
|
// PHP equivalent of ASSERT. C asserts cause a dialog to show and halt the process which
|
||||||
// we don't want on a web server
|
// we don't want on a web server
|
||||||
|
|
||||||
|
@ -1300,7 +1645,6 @@ void die( const char* msg, ... );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// check to see if the sqlstate is 01004, truncated field retrieved. Used for retrieving large fields.
|
// check to see if the sqlstate is 01004, truncated field retrieved. Used for retrieving large fields.
|
||||||
inline bool is_truncated_warning( SQLCHAR* state )
|
inline bool is_truncated_warning( SQLCHAR* state )
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
//
|
//
|
||||||
// Contents: Core routines that use statement handles shared between sqlsrv and pdo_sqlsrv
|
// Contents: Core routines that use statement handles shared between sqlsrv and pdo_sqlsrv
|
||||||
//
|
//
|
||||||
// Copyright 2010 Microsoft Corporation
|
// Copyright Microsoft Corporation
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -28,8 +28,10 @@ struct field_cache {
|
||||||
|
|
||||||
void* value;
|
void* value;
|
||||||
SQLLEN len;
|
SQLLEN len;
|
||||||
|
sqlsrv_phptype type;
|
||||||
|
|
||||||
field_cache( void* field_value, SQLLEN field_len )
|
field_cache( void* field_value, SQLLEN field_len, sqlsrv_phptype t )
|
||||||
|
: type( t )
|
||||||
{
|
{
|
||||||
// if the value is NULL, then just record a NULL pointer
|
// if the value is NULL, then just record a NULL pointer
|
||||||
if( field_value != NULL ) {
|
if( field_value != NULL ) {
|
||||||
|
@ -105,7 +107,6 @@ void send_param_streams( sqlsrv_stmt* stmt TSRMLS_DC );
|
||||||
void sqlsrv_output_param_dtor( void* data );
|
void sqlsrv_output_param_dtor( void* data );
|
||||||
// called when a bound stream parameter is to be destroyed.
|
// called when a bound stream parameter is to be destroyed.
|
||||||
void sqlsrv_stream_dtor( void* data );
|
void sqlsrv_stream_dtor( void* data );
|
||||||
sqlsrv_phptype sql_type_to_php_type( sqlsrv_stmt const* stmt, SQLINTEGER sql_type, SQLUINTEGER size, bool prefer_string );
|
|
||||||
bool is_streamable_type( SQLINTEGER sql_type );
|
bool is_streamable_type( SQLINTEGER sql_type );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -116,7 +117,8 @@ sqlsrv_stmt::sqlsrv_stmt( sqlsrv_conn* c, SQLHANDLE handle, error_callback e, vo
|
||||||
conn( c ),
|
conn( c ),
|
||||||
executed( false ),
|
executed( false ),
|
||||||
past_fetch_end( false ),
|
past_fetch_end( false ),
|
||||||
scrollable( false ),
|
current_results( NULL ),
|
||||||
|
cursor_type( SQL_CURSOR_FORWARD_ONLY ),
|
||||||
has_rows( false ),
|
has_rows( false ),
|
||||||
fetch_called( false ),
|
fetch_called( false ),
|
||||||
last_field_index( -1 ),
|
last_field_index( -1 ),
|
||||||
|
@ -126,6 +128,7 @@ sqlsrv_stmt::sqlsrv_stmt( sqlsrv_conn* c, SQLHANDLE handle, error_callback e, vo
|
||||||
current_stream( NULL, SQLSRV_ENCODING_DEFAULT ),
|
current_stream( NULL, SQLSRV_ENCODING_DEFAULT ),
|
||||||
current_stream_read( 0 ),
|
current_stream_read( 0 ),
|
||||||
query_timeout( QUERY_TIMEOUT_INVALID ),
|
query_timeout( QUERY_TIMEOUT_INVALID ),
|
||||||
|
buffered_query_limit( sqlsrv_buffered_result_set::BUFFERED_QUERY_LIMIT_INVALID ),
|
||||||
active_stream( NULL )
|
active_stream( NULL )
|
||||||
{
|
{
|
||||||
// initialize the input string parameters array (which holds zvals)
|
// initialize the input string parameters array (which holds zvals)
|
||||||
|
@ -165,6 +168,14 @@ sqlsrv_stmt::~sqlsrv_stmt( void )
|
||||||
TSRMLS_FETCH();
|
TSRMLS_FETCH();
|
||||||
close_active_stream( this TSRMLS_CC );
|
close_active_stream( this TSRMLS_CC );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// delete any current results
|
||||||
|
if( current_results ) {
|
||||||
|
current_results->~sqlsrv_result_set();
|
||||||
|
efree( current_results );
|
||||||
|
current_results = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
invalidate();
|
invalidate();
|
||||||
zval_ptr_dtor( ¶m_input_strings );
|
zval_ptr_dtor( ¶m_input_strings );
|
||||||
zval_ptr_dtor( &output_params );
|
zval_ptr_dtor( &output_params );
|
||||||
|
@ -192,13 +203,28 @@ 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( void )
|
void sqlsrv_stmt::new_result_set( TSRMLS_D )
|
||||||
{
|
{
|
||||||
this->fetch_called = false;
|
this->fetch_called = false;
|
||||||
this->has_rows = false;
|
this->has_rows = false;
|
||||||
this->past_next_result_end = false;
|
this->past_next_result_end = false;
|
||||||
this->past_fetch_end = false;
|
this->past_fetch_end = false;
|
||||||
this->last_field_index = -1;
|
this->last_field_index = -1;
|
||||||
|
|
||||||
|
// delete any current results
|
||||||
|
if( current_results ) {
|
||||||
|
current_results->~sqlsrv_result_set();
|
||||||
|
efree( current_results );
|
||||||
|
current_results = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a new result set
|
||||||
|
if( cursor_type == SQLSRV_CURSOR_BUFFERED ) {
|
||||||
|
current_results = new (sqlsrv_malloc( sizeof( sqlsrv_buffered_result_set ))) sqlsrv_buffered_result_set( this TSRMLS_CC );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
current_results = new (sqlsrv_malloc( sizeof( sqlsrv_odbc_result_set ))) sqlsrv_odbc_result_set( this );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// core_sqlsrv_create_stmt
|
// core_sqlsrv_create_stmt
|
||||||
|
@ -247,16 +273,15 @@ sqlsrv_stmt* core_sqlsrv_create_stmt( sqlsrv_conn* conn, driver_stmt_factory stm
|
||||||
int type = zend_hash_get_current_key_ex( options_ht, &key, &key_len, &index, 0, NULL );
|
int type = zend_hash_get_current_key_ex( options_ht, &key, &key_len, &index, 0, NULL );
|
||||||
|
|
||||||
// The driver layer should ensure a valid key.
|
// The driver layer should ensure a valid key.
|
||||||
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." );
|
||||||
|
|
||||||
core::sqlsrv_zend_hash_get_current_data( *(stmt->conn), options_ht, (void**) &value_z TSRMLS_CC );
|
core::sqlsrv_zend_hash_get_current_data( *(stmt->conn), options_ht, (void**) &value_z TSRMLS_CC );
|
||||||
|
|
||||||
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 TSRMLS_CC );
|
||||||
|
|
||||||
// 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.
|
||||||
if( !stmt_opt ) {
|
// The driver layer should ensure that the key is valid.
|
||||||
THROW_CORE_ERROR( stmt->conn, SQLSRV_ERROR_INVALID_OPTION_KEY );
|
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 TSRMLS_CC );
|
||||||
|
@ -273,6 +298,8 @@ sqlsrv_stmt* core_sqlsrv_create_stmt( sqlsrv_conn* conn, driver_stmt_factory stm
|
||||||
catch( core::CoreException& )
|
catch( core::CoreException& )
|
||||||
{
|
{
|
||||||
if( stmt ) {
|
if( stmt ) {
|
||||||
|
|
||||||
|
conn->set_last_error( stmt->last_error() );
|
||||||
stmt->~sqlsrv_stmt();
|
stmt->~sqlsrv_stmt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,7 +348,7 @@ void core_sqlsrv_bind_param( sqlsrv_stmt* stmt, unsigned int param_num, int dire
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// check is only < because params are 0 based
|
// check is only < because params are 0 based
|
||||||
CHECK_CUSTOM_ERROR( param_num >= SQL_SERVER_MAX_PARAMS, stmt, SQLSRV_ERROR_MAX_PARAMS_EXCEEDED, param_num ) {
|
CHECK_CUSTOM_ERROR( param_num >= SQL_SERVER_MAX_PARAMS, stmt, SQLSRV_ERROR_MAX_PARAMS_EXCEEDED, param_num + 1 ) {
|
||||||
throw core::CoreException();
|
throw core::CoreException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -498,6 +525,27 @@ void core_sqlsrv_bind_param( sqlsrv_stmt* stmt, unsigned int param_num, int dire
|
||||||
// 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_z, encoding, param_num, buffer_len );
|
sqlsrv_output_param output_param( param_z, encoding, param_num, buffer_len );
|
||||||
save_output_param_for_later( stmt, output_param TSRMLS_CC );
|
save_output_param_for_later( stmt, output_param TSRMLS_CC );
|
||||||
|
|
||||||
|
// For output parameters, if we set the column_size to be same as the buffer_len,
|
||||||
|
// than if there is a truncation due to the data coming from the server being
|
||||||
|
// greater than the column_size, we don't get any truncation error. In order to
|
||||||
|
// avoid this silent truncation, we set the column_size to be "MAX" size for
|
||||||
|
// string types. This will guarantee that there is no silent truncation for
|
||||||
|
// output parameters.
|
||||||
|
if( direction == SQL_PARAM_OUTPUT ) {
|
||||||
|
|
||||||
|
switch( sql_type ) {
|
||||||
|
|
||||||
|
case SQL_VARBINARY:
|
||||||
|
case SQL_VARCHAR:
|
||||||
|
case SQL_WVARCHAR:
|
||||||
|
column_size = SQL_SS_LENGTH_UNLIMITED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IS_RESOURCE:
|
case IS_RESOURCE:
|
||||||
|
@ -516,22 +564,33 @@ void core_sqlsrv_bind_param( sqlsrv_stmt* stmt, unsigned int param_num, int dire
|
||||||
case IS_OBJECT:
|
case IS_OBJECT:
|
||||||
{
|
{
|
||||||
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_malloc_auto_ptr<char> class_name;
|
|
||||||
zend_uint class_name_len;
|
|
||||||
zval_auto_ptr function_z;
|
zval_auto_ptr function_z;
|
||||||
zval_auto_ptr buffer_z;
|
zval_auto_ptr buffer_z;
|
||||||
zval_auto_ptr format_z;
|
zval_auto_ptr format_z;
|
||||||
zval* params[1];
|
zval* params[1];
|
||||||
|
bool valid_class_name_found = false;
|
||||||
|
|
||||||
int zr = zend_get_object_classname( param_z, &class_name, &class_name_len TSRMLS_CC );
|
zend_class_entry *class_entry = zend_get_class_entry( param_z TSRMLS_CC );
|
||||||
CHECK_CUSTOM_ERROR( zr == FAILURE, stmt, SQLSRV_ERROR_INVALID_PARAMETER_PHPTYPE, param_num + 1 ) {
|
|
||||||
throw core::CoreException();
|
while( class_entry != NULL ) {
|
||||||
}
|
|
||||||
CHECK_CUSTOM_ERROR( class_name_len != DateTime::DATETIME_CLASS_NAME_LEN ||
|
if( class_entry->name_length == DateTime::DATETIME_CLASS_NAME_LEN && class_entry->name != NULL &&
|
||||||
stricmp( class_name, DateTime::DATETIME_CLASS_NAME ),
|
stricmp( class_entry->name, DateTime::DATETIME_CLASS_NAME ) == 0 ) {
|
||||||
stmt, SQLSRV_ERROR_INVALID_PARAMETER_PHPTYPE, param_num + 1 ) {
|
valid_class_name_found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
|
||||||
|
// Check the parent
|
||||||
|
class_entry = class_entry->parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK_CUSTOM_ERROR( !valid_class_name_found, stmt, SQLSRV_ERROR_INVALID_PARAMETER_PHPTYPE, param_num + 1 ) {
|
||||||
throw core::CoreException();
|
throw core::CoreException();
|
||||||
}
|
}
|
||||||
|
|
||||||
ALLOC_INIT_ZVAL( buffer_z );
|
ALLOC_INIT_ZVAL( buffer_z );
|
||||||
ALLOC_INIT_ZVAL( function_z );
|
ALLOC_INIT_ZVAL( function_z );
|
||||||
ALLOC_INIT_ZVAL( format_z );
|
ALLOC_INIT_ZVAL( format_z );
|
||||||
|
@ -554,7 +613,7 @@ void core_sqlsrv_bind_param( sqlsrv_stmt* stmt, unsigned int param_num, int dire
|
||||||
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.
|
||||||
zr = call_user_function( EG( function_table ), ¶m_z, function_z, buffer_z, 1, params TSRMLS_CC );
|
int zr = call_user_function( EG( function_table ), ¶m_z, function_z, buffer_z, 1, params TSRMLS_CC );
|
||||||
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 ) {
|
||||||
throw core::CoreException();
|
throw core::CoreException();
|
||||||
}
|
}
|
||||||
|
@ -602,6 +661,8 @@ void core_sqlsrv_bind_param( sqlsrv_stmt* stmt, unsigned int param_num, int dire
|
||||||
|
|
||||||
void core_sqlsrv_execute( sqlsrv_stmt* stmt TSRMLS_DC, const char* sql, int sql_len )
|
void core_sqlsrv_execute( sqlsrv_stmt* stmt TSRMLS_DC, const char* sql, int sql_len )
|
||||||
{
|
{
|
||||||
|
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 TSRMLS_CC );
|
||||||
|
|
||||||
|
@ -632,7 +693,7 @@ void core_sqlsrv_execute( sqlsrv_stmt* stmt TSRMLS_DC, const char* sql, int sql_
|
||||||
r = core::SQLExecute( stmt TSRMLS_CC );
|
r = core::SQLExecute( stmt TSRMLS_CC );
|
||||||
}
|
}
|
||||||
|
|
||||||
stmt->new_result_set();
|
stmt->new_result_set( TSRMLS_C );
|
||||||
stmt->executed = true;
|
stmt->executed = true;
|
||||||
|
|
||||||
// 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
|
||||||
|
@ -646,6 +707,19 @@ void core_sqlsrv_execute( sqlsrv_stmt* stmt TSRMLS_DC, const char* sql, int sql_
|
||||||
|
|
||||||
finalize_output_parameters( stmt TSRMLS_CC );
|
finalize_output_parameters( stmt TSRMLS_CC );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch( core::CoreException& e ) {
|
||||||
|
|
||||||
|
// if the statement executed but failed in a subsequent operation before returning,
|
||||||
|
// we need to cancel the statement
|
||||||
|
if( stmt->executed ) {
|
||||||
|
SQLCancel( stmt->handle() );
|
||||||
|
// stmt->executed = false; should this be reset if something fails?
|
||||||
|
}
|
||||||
|
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -689,20 +763,19 @@ bool core_sqlsrv_fetch( sqlsrv_stmt* stmt, SQLSMALLINT fetch_orientation, SQLLEN
|
||||||
|
|
||||||
// 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.
|
||||||
if( !stmt->scrollable && stmt->has_rows && !stmt->fetch_called ) {
|
if( stmt->cursor_type == SQL_CURSOR_FORWARD_ONLY && stmt->has_rows && !stmt->fetch_called ) {
|
||||||
stmt->fetch_called = true;
|
stmt->fetch_called = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 = core::SQLFetchScroll( stmt, fetch_orientation,
|
SQLRETURN r = stmt->current_results->fetch( fetch_orientation,
|
||||||
( fetch_orientation == SQL_FETCH_RELATIVE ) ? fetch_offset : fetch_offset + 1
|
( fetch_orientation == SQL_FETCH_RELATIVE ) ? fetch_offset : fetch_offset + 1
|
||||||
TSRMLS_CC );
|
TSRMLS_CC );
|
||||||
|
|
||||||
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
|
||||||
if( !stmt->scrollable ) {
|
if( stmt->cursor_type == SQL_CURSOR_FORWARD_ONLY ) {
|
||||||
stmt->past_fetch_end = true;
|
stmt->past_fetch_end = true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -812,13 +885,18 @@ void core_sqlsrv_get_field( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_
|
||||||
if( cached->value == NULL ) {
|
if( cached->value == NULL ) {
|
||||||
*field_value = NULL;
|
*field_value = NULL;
|
||||||
*field_len = 0;
|
*field_len = 0;
|
||||||
|
if( sqlsrv_php_type_out ) { *sqlsrv_php_type_out = SQLSRV_PHPTYPE_NULL; }
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
*field_value = sqlsrv_malloc( cached->len + 1 );
|
*field_value = sqlsrv_malloc( cached->len, sizeof( char ), 1 );
|
||||||
memcpy( *field_value, cached->value, cached->len );
|
memcpy( *field_value, cached->value, cached->len );
|
||||||
reinterpret_cast<char*>( *field_value )[ cached->len ] = '\0'; // prevent the 'string not null terminated' warning
|
if( cached->type.typeinfo.type == SQLSRV_PHPTYPE_STRING ) {
|
||||||
|
// prevent the 'string not null terminated' warning
|
||||||
|
reinterpret_cast<char*>( *field_value )[ cached->len ] = '\0';
|
||||||
|
}
|
||||||
*field_len = cached->len;
|
*field_len = cached->len;
|
||||||
|
if( sqlsrv_php_type_out ) { *sqlsrv_php_type_out = static_cast<SQLSRV_PHPTYPE>( cached->type.typeinfo.type ); }
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -878,7 +956,7 @@ void core_sqlsrv_get_field( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_
|
||||||
|
|
||||||
// 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 );
|
field_cache cache( *field_value, *field_len, sqlsrv_php_type );
|
||||||
core::sqlsrv_zend_hash_index_update( *stmt, Z_ARRVAL_P( stmt->field_cache ), field_index, &cache,
|
core::sqlsrv_zend_hash_index_update( *stmt, Z_ARRVAL_P( stmt->field_cache ), field_index, &cache,
|
||||||
sizeof( field_cache ) TSRMLS_CC );
|
sizeof( field_cache ) TSRMLS_CC );
|
||||||
}
|
}
|
||||||
|
@ -913,7 +991,7 @@ bool core_sqlsrv_has_any_result( sqlsrv_stmt* stmt TSRMLS_DC )
|
||||||
// Returns
|
// Returns
|
||||||
// Nothing, exception thrown if problem occurs
|
// Nothing, exception thrown if problem occurs
|
||||||
|
|
||||||
void core_sqlsrv_next_result( sqlsrv_stmt* stmt TSRMLS_DC, bool finalize_output_params )
|
void core_sqlsrv_next_result( sqlsrv_stmt* stmt TSRMLS_DC, bool finalize_output_params, bool throw_on_errors )
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
@ -928,7 +1006,13 @@ void core_sqlsrv_next_result( sqlsrv_stmt* stmt TSRMLS_DC, bool finalize_output_
|
||||||
|
|
||||||
close_active_stream( stmt TSRMLS_CC );
|
close_active_stream( stmt TSRMLS_CC );
|
||||||
|
|
||||||
SQLRETURN r = core::SQLMoreResults( stmt TSRMLS_CC );
|
SQLRETURN r;
|
||||||
|
if( throw_on_errors ) {
|
||||||
|
r = core::SQLMoreResults( stmt TSRMLS_CC );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
r = SQLMoreResults( stmt->handle() );
|
||||||
|
}
|
||||||
|
|
||||||
if( r == SQL_NO_DATA ) {
|
if( r == SQL_NO_DATA ) {
|
||||||
|
|
||||||
|
@ -942,7 +1026,7 @@ void core_sqlsrv_next_result( sqlsrv_stmt* stmt TSRMLS_DC, bool finalize_output_
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
stmt->new_result_set();
|
stmt->new_result_set( TSRMLS_C );
|
||||||
}
|
}
|
||||||
catch( core::CoreException& e ) {
|
catch( core::CoreException& e ) {
|
||||||
|
|
||||||
|
@ -991,42 +1075,62 @@ void core_sqlsrv_set_scrollable( sqlsrv_stmt* stmt, unsigned int cursor_type TSR
|
||||||
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 TSRMLS_CC );
|
||||||
stmt->scrollable = true;
|
|
||||||
stmt->scroll_is_dynamic = false;
|
|
||||||
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 TSRMLS_CC );
|
||||||
stmt->scrollable = true;
|
|
||||||
stmt->scroll_is_dynamic = true; // this cursor is dynamic
|
|
||||||
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 TSRMLS_CC );
|
||||||
stmt->scrollable = true;
|
|
||||||
stmt->scroll_is_dynamic = false;
|
|
||||||
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 TSRMLS_CC );
|
||||||
stmt->scrollable = false; // reset since forward isn't scrollable
|
break;
|
||||||
stmt->scroll_is_dynamic = false;
|
|
||||||
|
case SQLSRV_CURSOR_BUFFERED:
|
||||||
|
core::SQLSetStmtAttr( stmt, SQL_ATTR_CURSOR_TYPE,
|
||||||
|
reinterpret_cast<SQLPOINTER>( SQL_CURSOR_FORWARD_ONLY ), SQL_IS_UINTEGER TSRMLS_CC );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
THROW_CORE_ERROR( stmt, SQLSRV_ERROR_INVALID_OPTION_SCROLLABLE );
|
THROW_CORE_ERROR( stmt, SQLSRV_ERROR_INVALID_OPTION_SCROLLABLE );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
stmt->cursor_type = cursor_type;
|
||||||
|
|
||||||
|
}
|
||||||
catch( core::CoreException& ) {
|
catch( core::CoreException& ) {
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void core_sqlsrv_set_buffered_query_limit( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC )
|
||||||
|
{
|
||||||
|
if( Z_TYPE_P( value_z ) != IS_LONG ) {
|
||||||
|
|
||||||
|
THROW_CORE_ERROR( stmt, SQLSRV_ERROR_INVALID_BUFFER_LIMIT );
|
||||||
|
}
|
||||||
|
|
||||||
|
core_sqlsrv_set_buffered_query_limit( stmt, Z_LVAL_P( value_z ) TSRMLS_CC );
|
||||||
|
}
|
||||||
|
|
||||||
|
void core_sqlsrv_set_buffered_query_limit( sqlsrv_stmt* stmt, long limit TSRMLS_DC )
|
||||||
|
{
|
||||||
|
if( limit <= 0 ) {
|
||||||
|
|
||||||
|
THROW_CORE_ERROR( stmt, SQLSRV_ERROR_INVALID_BUFFER_LIMIT );
|
||||||
|
}
|
||||||
|
|
||||||
|
stmt->buffered_query_limit = limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Overloaded. Extracts the long value and calls the core_sqlsrv_set_query_timeout
|
// Overloaded. 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.
|
||||||
|
@ -1038,7 +1142,7 @@ void core_sqlsrv_set_query_timeout( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC )
|
||||||
if( Z_TYPE_P( value_z ) != IS_LONG || Z_LVAL_P( value_z ) < 0 ) {
|
if( Z_TYPE_P( value_z ) != IS_LONG || Z_LVAL_P( value_z ) < 0 ) {
|
||||||
|
|
||||||
convert_to_string( value_z );
|
convert_to_string( value_z );
|
||||||
THROW_CORE_ERROR( stmt, SQLSRV_ERROR_INVALID_OPTION_VALUE, Z_STRVAL_P( value_z ) );
|
THROW_CORE_ERROR( stmt, SQLSRV_ERROR_INVALID_QUERY_TIMEOUT_VALUE, Z_STRVAL_P( value_z ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
core_sqlsrv_set_query_timeout( stmt, Z_LVAL_P( value_z ) TSRMLS_CC );
|
core_sqlsrv_set_query_timeout( stmt, Z_LVAL_P( value_z ) TSRMLS_CC );
|
||||||
|
@ -1214,6 +1318,11 @@ void stmt_option_send_at_exec:: operator()( sqlsrv_stmt* stmt, stmt_option const
|
||||||
core_sqlsrv_set_send_at_exec( stmt, value_z TSRMLS_CC );
|
core_sqlsrv_set_send_at_exec( stmt, value_z TSRMLS_CC );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void stmt_option_buffered_query_limit:: operator()( sqlsrv_stmt* stmt, stmt_option const* /*opt*/, zval* value_z TSRMLS_DC )
|
||||||
|
{
|
||||||
|
core_sqlsrv_set_buffered_query_limit( stmt, value_z TSRMLS_CC );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 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.
|
||||||
|
@ -1382,9 +1491,13 @@ void core_get_field_common( __inout sqlsrv_stmt* stmt, SQLUSMALLINT field_index,
|
||||||
sqlsrv_malloc_auto_ptr<long> field_value_temp;
|
sqlsrv_malloc_auto_ptr<long> field_value_temp;
|
||||||
field_value_temp = static_cast<long*>( sqlsrv_malloc( sizeof( long )));
|
field_value_temp = static_cast<long*>( sqlsrv_malloc( sizeof( long )));
|
||||||
|
|
||||||
SQLRETURN r = core::SQLGetData( stmt, field_index + 1, SQL_C_LONG, field_value_temp, 0,
|
SQLRETURN r = stmt->current_results->get_data(field_index + 1, SQL_C_LONG, field_value_temp, sizeof( long ),
|
||||||
field_len, true /*handle_warning*/ TSRMLS_CC );
|
field_len, true /*handle_warning*/ TSRMLS_CC );
|
||||||
|
|
||||||
|
CHECK_SQL_ERROR_OR_WARNING( r, stmt ) {
|
||||||
|
throw core::CoreException();
|
||||||
|
}
|
||||||
|
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
@ -1404,9 +1517,13 @@ void core_get_field_common( __inout sqlsrv_stmt* stmt, SQLUSMALLINT field_index,
|
||||||
sqlsrv_malloc_auto_ptr<double> field_value_temp;
|
sqlsrv_malloc_auto_ptr<double> field_value_temp;
|
||||||
field_value_temp = static_cast<double*>( sqlsrv_malloc( sizeof( double )));
|
field_value_temp = static_cast<double*>( sqlsrv_malloc( sizeof( double )));
|
||||||
|
|
||||||
SQLRETURN r = core::SQLGetData( stmt, field_index + 1, SQL_C_DOUBLE, field_value_temp, 0,
|
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*/ TSRMLS_CC );
|
||||||
|
|
||||||
|
CHECK_SQL_ERROR_OR_WARNING( r, stmt ) {
|
||||||
|
throw core::CoreException();
|
||||||
|
}
|
||||||
|
|
||||||
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 ();
|
||||||
}
|
}
|
||||||
|
@ -1440,8 +1557,8 @@ void core_get_field_common( __inout sqlsrv_stmt* stmt, SQLUSMALLINT field_index,
|
||||||
ALLOC_INIT_ZVAL( function_z );
|
ALLOC_INIT_ZVAL( function_z );
|
||||||
ALLOC_INIT_ZVAL( return_value_z );
|
ALLOC_INIT_ZVAL( return_value_z );
|
||||||
|
|
||||||
SQLRETURN r = core::SQLGetData( stmt, field_index + 1, SQL_C_CHAR, field_value_temp, MAX_DATETIME_STRING_LEN,
|
SQLRETURN r = stmt->current_results->get_data( field_index + 1, SQL_C_CHAR, field_value_temp,
|
||||||
field_len, true TSRMLS_CC );
|
MAX_DATETIME_STRING_LEN, field_len, true TSRMLS_CC );
|
||||||
|
|
||||||
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 ();
|
||||||
|
@ -1512,6 +1629,11 @@ void core_get_field_common( __inout sqlsrv_stmt* stmt, SQLUSMALLINT field_index,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SQLSRV_PHPTYPE_NULL:
|
||||||
|
*field_value = NULL;
|
||||||
|
*field_len = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DIE( "core_get_field_common: Unexpected sqlsrv_phptype provided" );
|
DIE( "core_get_field_common: Unexpected sqlsrv_phptype provided" );
|
||||||
break;
|
break;
|
||||||
|
@ -1951,7 +2073,7 @@ void get_field_as_string( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_ph
|
||||||
|
|
||||||
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 = core::SQLGetData( stmt, 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*/ TSRMLS_CC );
|
||||||
|
|
||||||
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 ) {
|
||||||
|
@ -1969,7 +2091,7 @@ void get_field_as_string( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_ph
|
||||||
SQLCHAR state[ SQL_SQLSTATE_BUFSIZE ];
|
SQLCHAR state[ SQL_SQLSTATE_BUFSIZE ];
|
||||||
SQLSMALLINT len;
|
SQLSMALLINT len;
|
||||||
|
|
||||||
core::SQLGetDiagField( stmt, 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 TSRMLS_CC );
|
||||||
|
|
||||||
if( is_truncated_warning( state ) ) {
|
if( is_truncated_warning( state ) ) {
|
||||||
|
|
||||||
|
@ -1993,8 +2115,9 @@ void get_field_as_string( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_ph
|
||||||
field_len_temp -= initial_field_len;
|
field_len_temp -= initial_field_len;
|
||||||
|
|
||||||
// Get the rest of the data.
|
// Get the rest of the data.
|
||||||
r = core::SQLGetData( stmt, 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*/ TSRMLS_CC );
|
||||||
|
|
||||||
// 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.
|
||||||
|
@ -2019,8 +2142,9 @@ void get_field_as_string( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_ph
|
||||||
field_len_temp -= INITIAL_FIELD_STRING_LEN;
|
field_len_temp -= INITIAL_FIELD_STRING_LEN;
|
||||||
|
|
||||||
// Get the rest of the data.
|
// Get the rest of the data.
|
||||||
r = core::SQLGetData( stmt, field_index + 1, c_type, field_value_temp + INITIAL_FIELD_STRING_LEN,
|
r = stmt->current_results->get_data( field_index + 1, c_type, field_value_temp + INITIAL_FIELD_STRING_LEN,
|
||||||
field_len_temp + extra, &dummy_field_len, true /*handle_warning*/ TSRMLS_CC );
|
field_len_temp + extra, &dummy_field_len,
|
||||||
|
true /*handle_warning*/ TSRMLS_CC );
|
||||||
|
|
||||||
if( dummy_field_len == SQL_NULL_DATA ) {
|
if( dummy_field_len == SQL_NULL_DATA ) {
|
||||||
*field_value = NULL;
|
*field_value = NULL;
|
||||||
|
@ -2072,9 +2196,11 @@ void get_field_as_string( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_ph
|
||||||
field_value_temp = static_cast<char*>( sqlsrv_malloc( sql_display_size + extra + 1 ));
|
field_value_temp = static_cast<char*>( sqlsrv_malloc( sql_display_size + extra + 1 ));
|
||||||
|
|
||||||
// get the data
|
// get the data
|
||||||
r = core::SQLGetData( stmt, 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*/ TSRMLS_CC );
|
||||||
|
CHECK_SQL_ERROR( r, stmt ) {
|
||||||
|
throw core::CoreException();
|
||||||
|
}
|
||||||
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 ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
//
|
//
|
||||||
// Contents: Implementation of PHP streams for reading SQL Server data
|
// Contents: Implementation of PHP streams for reading SQL Server data
|
||||||
//
|
//
|
||||||
// Copyright 2010 Microsoft Corporation
|
// Copyright Microsoft Corporation
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -113,7 +113,8 @@ size_t sqlsrv_stream_read( php_stream* stream, __out_bcount(count) char* buf, si
|
||||||
|
|
||||||
SQLCHAR state[ SQL_SQLSTATE_BUFSIZE ];
|
SQLCHAR state[ SQL_SQLSTATE_BUFSIZE ];
|
||||||
SQLSMALLINT len;
|
SQLSMALLINT len;
|
||||||
core::SQLGetDiagField( ss->stmt, 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 TSRMLS_CC );
|
||||||
|
|
||||||
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 "
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
//
|
//
|
||||||
// Comments: Mostly error handling and some type handling
|
// Comments: Mostly error handling and some type handling
|
||||||
//
|
//
|
||||||
// Copyright 2010 Microsoft Corporation
|
// Copyright Microsoft Corporation
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -147,7 +147,8 @@ wchar_t* utf16_string_from_mbcs_string( SQLSRV_ENCODING php_encoding, const char
|
||||||
// 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( sqlsrv_context& ctx, int record_number, sqlsrv_error* error, logging_severity severity TSRMLS_DC )
|
bool core_sqlsrv_get_odbc_error( sqlsrv_context& ctx, int record_number, sqlsrv_error_auto_ptr& error, 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();
|
||||||
|
@ -165,7 +166,33 @@ bool core_sqlsrv_get_odbc_error( sqlsrv_context& ctx, int record_number, sqlsrv_
|
||||||
SQLINTEGER message_len = 0;
|
SQLINTEGER message_len = 0;
|
||||||
SQLWCHAR wsqlstate[ SQL_SQLSTATE_BUFSIZE ];
|
SQLWCHAR wsqlstate[ SQL_SQLSTATE_BUFSIZE ];
|
||||||
SQLWCHAR wnative_message[ SQL_MAX_MESSAGE_LENGTH + 1 ];
|
SQLWCHAR wnative_message[ SQL_MAX_MESSAGE_LENGTH + 1 ];
|
||||||
|
SQLSRV_ENCODING enc = ctx.encoding();
|
||||||
|
|
||||||
|
switch( h_type ) {
|
||||||
|
|
||||||
|
case SQL_HANDLE_STMT:
|
||||||
|
{
|
||||||
|
sqlsrv_stmt* stmt = static_cast<sqlsrv_stmt*>( &ctx );
|
||||||
|
if( stmt->current_results != NULL ) {
|
||||||
|
|
||||||
|
error = stmt->current_results->get_diag_rec( record_number );
|
||||||
|
// don't use the CHECK* macros here since it will trigger reentry into the error handling system
|
||||||
|
if( error == NULL ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert the error into the encoding of the context
|
||||||
|
if( enc == SQLSRV_ENCODING_DEFAULT ) {
|
||||||
|
enc = stmt->conn->encoding();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
error = new ( sqlsrv_malloc( sizeof( sqlsrv_error ))) sqlsrv_error();
|
||||||
r = SQLGetDiagRecW( h_type, h, record_number, wsqlstate, &error->native_code, wnative_message,
|
r = SQLGetDiagRecW( h_type, h, record_number, wsqlstate, &error->native_code, wnative_message,
|
||||||
SQL_MAX_MESSAGE_LENGTH + 1, &wmessage_len );
|
SQL_MAX_MESSAGE_LENGTH + 1, &wmessage_len );
|
||||||
// don't use the CHECK* macros here since it will trigger reentry into the error handling system
|
// don't use the CHECK* macros here since it will trigger reentry into the error handling system
|
||||||
|
@ -173,14 +200,16 @@ bool core_sqlsrv_get_odbc_error( sqlsrv_context& ctx, int record_number, sqlsrv_
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert the error into the encoding of the context
|
|
||||||
error->sqlstate = reinterpret_cast<SQLCHAR*>( wsqlstate );
|
error->sqlstate = reinterpret_cast<SQLCHAR*>( wsqlstate );
|
||||||
convert_string_from_utf16( ctx.encoding(), reinterpret_cast<char**>( &error->sqlstate ), sqlstate_len,
|
convert_string_from_utf16( enc, reinterpret_cast<char**>( &error->sqlstate ), sqlstate_len,
|
||||||
false /*no free*/ );
|
false /*no free*/ );
|
||||||
error->native_message = reinterpret_cast<SQLCHAR*>( wnative_message );
|
error->native_message = reinterpret_cast<SQLCHAR*>( wnative_message );
|
||||||
message_len = wmessage_len * sizeof( wchar_t );
|
message_len = wmessage_len * sizeof( wchar_t );
|
||||||
convert_string_from_utf16( ctx.encoding(), reinterpret_cast<char**>( &error->native_message ), message_len,
|
convert_string_from_utf16( enc, reinterpret_cast<char**>( &error->native_message ), message_len,
|
||||||
false /*no free*/ );
|
false /*no free*/ );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// log the error first
|
// log the error first
|
||||||
LOG( severity, "%1!s!: SQLSTATE = %2!s!", ctx.func(), error->sqlstate );
|
LOG( severity, "%1!s!: SQLSTATE = %2!s!", ctx.func(), error->sqlstate );
|
||||||
|
@ -194,9 +223,10 @@ bool core_sqlsrv_get_odbc_error( sqlsrv_context& ctx, int record_number, sqlsrv_
|
||||||
|
|
||||||
// format and return a driver specfic error
|
// format and return a driver specfic error
|
||||||
void core_sqlsrv_format_driver_error( sqlsrv_context& ctx, sqlsrv_error_const const* custom_error,
|
void core_sqlsrv_format_driver_error( sqlsrv_context& ctx, sqlsrv_error_const const* custom_error,
|
||||||
sqlsrv_error* formatted_error, logging_severity severity TSRMLS_DC, va_list* args )
|
sqlsrv_error_auto_ptr& formatted_error, logging_severity severity TSRMLS_DC, 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->sqlstate = reinterpret_cast<SQLCHAR*>( sqlsrv_malloc( SQL_SQLSTATE_BUFSIZE ));
|
formatted_error->sqlstate = reinterpret_cast<SQLCHAR*>( sqlsrv_malloc( SQL_SQLSTATE_BUFSIZE ));
|
||||||
formatted_error->native_message = reinterpret_cast<SQLCHAR*>( sqlsrv_malloc( SQL_MAX_MESSAGE_LENGTH + 1 ));
|
formatted_error->native_message = reinterpret_cast<SQLCHAR*>( sqlsrv_malloc( SQL_MAX_MESSAGE_LENGTH + 1 ));
|
||||||
|
|
||||||
|
|
110
sqlsrv/init.cpp
110
sqlsrv/init.cpp
|
@ -2,7 +2,7 @@
|
||||||
// File: init.cpp
|
// File: init.cpp
|
||||||
// Contents: initialization routines for the extension
|
// Contents: initialization routines for the extension
|
||||||
//
|
//
|
||||||
// Copyright 2010 Microsoft Corporation
|
// Copyright Microsoft Corporation
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -46,134 +46,137 @@ unsigned int current_log_subsystem = LOG_INIT;
|
||||||
// argument info structures for functions, arranged alphabetically.
|
// argument info structures for functions, arranged alphabetically.
|
||||||
// see zend_API.h in the PHP sources for more information about these macros
|
// see zend_API.h in the PHP sources for more information about these macros
|
||||||
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_begin_transaction_arginfo, 0, 0, 1 )
|
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_begin_transaction_arginfo, 0, 0, 1 )
|
||||||
ZEND_ARG_INFO( 0, "connection resource" )
|
ZEND_ARG_INFO( 0, conn )
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO( sqlsrv_cancel_arginfo, 0 )
|
ZEND_BEGIN_ARG_INFO( sqlsrv_cancel_arginfo, 0 )
|
||||||
ZEND_ARG_INFO( 0, "statement resource" )
|
ZEND_ARG_INFO( 0, stmt )
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_close_arginfo, 0, 0, 1 )
|
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_close_arginfo, 0, 0, 1 )
|
||||||
ZEND_ARG_INFO( 0, "connection resource" )
|
ZEND_ARG_INFO( 0, conn )
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_client_info_arginfo, 0, 0, 0 )
|
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_client_info_arginfo, 0, 0, 1 )
|
||||||
ZEND_ARG_INFO( 0, "connection resource" )
|
ZEND_ARG_INFO( 0, conn )
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_commit_arginfo, 0, 0, 1 )
|
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_commit_arginfo, 0, 0, 1 )
|
||||||
ZEND_ARG_INFO( 0, "connection resource" )
|
ZEND_ARG_INFO( 0, conn )
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_configure_arginfo, 0, 0, 2 )
|
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_configure_arginfo, 0, 0, 2 )
|
||||||
ZEND_ARG_INFO( 0, "option name" )
|
ZEND_ARG_INFO( 0, setting )
|
||||||
ZEND_ARG_INFO( 0, "value" )
|
ZEND_ARG_INFO( 0, value )
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_connect_arginfo, 0, 0, 1 )
|
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_connect_arginfo, 0, 0, 1 )
|
||||||
ZEND_ARG_INFO( 0, "server" )
|
ZEND_ARG_INFO( 0, server_name )
|
||||||
ZEND_ARG_ARRAY_INFO( 0, "options", 0 )
|
ZEND_ARG_ARRAY_INFO( 0, connection_info, 0 )
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_errors_arginfo, 0, 1, 0 )
|
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_errors_arginfo, 0, 1, 0 )
|
||||||
ZEND_ARG_INFO( 0, "flags (errors, warnings, or all)" )
|
ZEND_ARG_INFO( 0, errors_and_or_warnings )
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_execute_arginfo, 0, 0, 1 )
|
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_execute_arginfo, 0, 0, 1 )
|
||||||
ZEND_ARG_INFO( 0, "statement resource" )
|
ZEND_ARG_INFO( 0, stmt )
|
||||||
ZEND_ARG_INFO( 0, "parameters" )
|
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_fetch_arginfo, 0, 0, 1 )
|
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_fetch_arginfo, 0, 0, 1 )
|
||||||
ZEND_ARG_INFO( 0, "statement resource" )
|
ZEND_ARG_INFO( 0, stmt )
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_fetch_array_arginfo, 0, 1, 1 )
|
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_fetch_array_arginfo, 0, 1, 1 )
|
||||||
ZEND_ARG_INFO( 0, "statement resource" )
|
ZEND_ARG_INFO( 0, stmt )
|
||||||
ZEND_ARG_INFO( 0, "array type" )
|
ZEND_ARG_INFO( 0, fetch_type )
|
||||||
|
ZEND_ARG_INFO( 0, row )
|
||||||
|
ZEND_ARG_INFO( 0, offset )
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_fetch_object_arginfo, 0, 1, 1 )
|
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_fetch_object_arginfo, 0, 1, 1 )
|
||||||
ZEND_ARG_INFO( 0, "statement resource" )
|
ZEND_ARG_INFO( 0, stmt )
|
||||||
ZEND_ARG_INFO( 0, "class name" )
|
ZEND_ARG_INFO( 0, class_name )
|
||||||
ZEND_ARG_INFO( 0, "ctor params" )
|
ZEND_ARG_INFO( 0, ctor_params )
|
||||||
|
ZEND_ARG_INFO( 0, row )
|
||||||
|
ZEND_ARG_INFO( 0, offset )
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_field_metadata_arginfo, 0, 1, 1 )
|
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_field_metadata_arginfo, 0, 1, 1 )
|
||||||
ZEND_ARG_INFO( 0, "statement resource" )
|
ZEND_ARG_INFO( 0, stmt )
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO( sqlsrv_free_stmt_arginfo, 0 )
|
ZEND_BEGIN_ARG_INFO( sqlsrv_free_stmt_arginfo, 0 )
|
||||||
ZEND_ARG_INFO( 0, "statement resource" )
|
ZEND_ARG_INFO( 0, stmt )
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_get_config_arginfo, 0, 0, 1 )
|
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_get_config_arginfo, 0, 0, 1 )
|
||||||
ZEND_ARG_INFO( 0, "option name" )
|
ZEND_ARG_INFO( 0, setting )
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_get_field_arginfo, 0, 1, 2 )
|
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_get_field_arginfo, 0, 1, 2 )
|
||||||
ZEND_ARG_INFO( 0, "statement resource" )
|
ZEND_ARG_INFO( 0, stmt )
|
||||||
ZEND_ARG_INFO( 0, "field index" )
|
ZEND_ARG_INFO( 0, field_index )
|
||||||
ZEND_ARG_INFO( 0, "type" )
|
ZEND_ARG_INFO( 0, get_as_type )
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO( sqlsrv_has_rows_arginfo, 0 )
|
ZEND_BEGIN_ARG_INFO( sqlsrv_has_rows_arginfo, 0 )
|
||||||
ZEND_ARG_INFO( 0, "statement resource" )
|
ZEND_ARG_INFO( 0, stmt )
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO( sqlsrv_next_result_arginfo, 0 )
|
ZEND_BEGIN_ARG_INFO( sqlsrv_next_result_arginfo, 0 )
|
||||||
ZEND_ARG_INFO( 0, "statement resource" )
|
ZEND_ARG_INFO( 0, stmt )
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO( sqlsrv_num_fields_arginfo, 0 )
|
ZEND_BEGIN_ARG_INFO( sqlsrv_num_fields_arginfo, 0 )
|
||||||
ZEND_ARG_INFO( 0, "statement resource" )
|
ZEND_ARG_INFO( 0, stmt )
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO( sqlsrv_num_rows_arginfo, 0 )
|
ZEND_BEGIN_ARG_INFO( sqlsrv_num_rows_arginfo, 0 )
|
||||||
ZEND_ARG_INFO( 0, "statement resource" )
|
ZEND_ARG_INFO( 0, stmt )
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_prepare_arginfo, 0, 1, 2 )
|
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_prepare_arginfo, 0, 1, 2 )
|
||||||
ZEND_ARG_INFO( 0, "connection resource" )
|
ZEND_ARG_INFO( 0, conn )
|
||||||
ZEND_ARG_INFO( 0, "sql command" )
|
ZEND_ARG_INFO( 0, tsql )
|
||||||
ZEND_ARG_INFO( 0, "parameters" )
|
ZEND_ARG_INFO( 0, params )
|
||||||
ZEND_ARG_ARRAY_INFO( 0, "options", 0 )
|
ZEND_ARG_INFO( 0, options )
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_query_arginfo, 0, 1, 2 )
|
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_query_arginfo, 0, 1, 2 )
|
||||||
ZEND_ARG_INFO( 0, "connection resource" )
|
ZEND_ARG_INFO( 0, conn )
|
||||||
ZEND_ARG_INFO( 0, "sql command" )
|
ZEND_ARG_INFO( 0, tsql )
|
||||||
ZEND_ARG_INFO( 0, "parameters" )
|
ZEND_ARG_INFO( 0, params )
|
||||||
ZEND_ARG_ARRAY_INFO( 0, "options", 0 )
|
ZEND_ARG_INFO( 0, options )
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_rollback_arginfo, 0, 0, 1 )
|
ZEND_BEGIN_ARG_INFO_EX( sqlsrv_rollback_arginfo, 0, 0, 1 )
|
||||||
ZEND_ARG_INFO( 0, "connection resource" )
|
ZEND_ARG_INFO( 0, conn )
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO( sqlsrv_rows_affected_arginfo, 0 )
|
ZEND_BEGIN_ARG_INFO( sqlsrv_rows_affected_arginfo, 0 )
|
||||||
ZEND_ARG_INFO( 0, "statement resource" )
|
ZEND_ARG_INFO( 0, stmt )
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO( sqlsrv_send_stream_data_arginfo, 0 )
|
ZEND_BEGIN_ARG_INFO( sqlsrv_send_stream_data_arginfo, 0 )
|
||||||
ZEND_ARG_INFO( 0, "statement resource" )
|
ZEND_ARG_INFO( 0, stmt )
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO( sqlsrv_server_info_arginfo, 0 )
|
ZEND_BEGIN_ARG_INFO( sqlsrv_server_info_arginfo, 0 )
|
||||||
ZEND_ARG_INFO( 0, "statement resource" )
|
ZEND_ARG_INFO( 0, stmt )
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO( sqlsrv_sqltype_size_arginfo, 0 )
|
ZEND_BEGIN_ARG_INFO( sqlsrv_sqltype_size_arginfo, 0 )
|
||||||
ZEND_ARG_INFO( 0, "size" )
|
ZEND_ARG_INFO( 0, size )
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO( sqlsrv_sqltype_precision_scale_arginfo, 0 )
|
ZEND_BEGIN_ARG_INFO( sqlsrv_sqltype_precision_scale_arginfo, 0 )
|
||||||
ZEND_ARG_INFO( 0, "precision" )
|
ZEND_ARG_INFO( 0, precision )
|
||||||
ZEND_ARG_INFO( 0, "scale" )
|
ZEND_ARG_INFO( 0, scale )
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO( sqlsrv_phptype_encoding_arginfo, 0 )
|
ZEND_BEGIN_ARG_INFO( sqlsrv_phptype_encoding_arginfo, 0 )
|
||||||
ZEND_ARG_INFO( 0, "encoding" )
|
ZEND_ARG_INFO( 0, encoding )
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
// function table with associated arginfo structures
|
// function table with associated arginfo structures
|
||||||
|
@ -290,7 +293,8 @@ PHP_MINIT_FUNCTION(sqlsrv)
|
||||||
REGISTER_LONG_CONSTANT( "SQLSRV_LOG_SEVERITY_ALL", -1, CONST_PERSISTENT | CONST_CS ); // -1 so that all the bits are set
|
REGISTER_LONG_CONSTANT( "SQLSRV_LOG_SEVERITY_ALL", -1, CONST_PERSISTENT | CONST_CS ); // -1 so that all the bits are set
|
||||||
|
|
||||||
// register connection resource
|
// register connection resource
|
||||||
ss_sqlsrv_conn::descriptor = zend_register_list_destructors_ex( sqlsrv_conn_dtor, NULL, "SQL Server Connection", module_number );
|
ss_sqlsrv_conn::descriptor = zend_register_list_destructors_ex( sqlsrv_conn_dtor, NULL, "SQL Server Connection",
|
||||||
|
module_number );
|
||||||
|
|
||||||
if( ss_sqlsrv_conn::descriptor == FAILURE ) {
|
if( ss_sqlsrv_conn::descriptor == FAILURE ) {
|
||||||
LOG( SEV_ERROR, "%1!s!: connection resource registration failed", _FN_ );
|
LOG( SEV_ERROR, "%1!s!: connection resource registration failed", _FN_ );
|
||||||
|
@ -319,8 +323,8 @@ PHP_MINIT_FUNCTION(sqlsrv)
|
||||||
REGISTER_STRING_CONSTANT( "SQLSRV_ENC_BINARY", "binary", CONST_PERSISTENT | CONST_CS );
|
REGISTER_STRING_CONSTANT( "SQLSRV_ENC_BINARY", "binary", CONST_PERSISTENT | CONST_CS );
|
||||||
REGISTER_STRING_CONSTANT( "SQLSRV_ENC_CHAR", "char", CONST_PERSISTENT | CONST_CS );
|
REGISTER_STRING_CONSTANT( "SQLSRV_ENC_CHAR", "char", CONST_PERSISTENT | CONST_CS );
|
||||||
|
|
||||||
REGISTER_LONG_CONSTANT( "SQLSRV_NULLABLE_YES", 0, CONST_PERSISTENT | CONST_CS );
|
REGISTER_LONG_CONSTANT( "SQLSRV_NULLABLE_NO", 0, CONST_PERSISTENT | CONST_CS );
|
||||||
REGISTER_LONG_CONSTANT( "SQLSRV_NULLABLE_NO", 1, CONST_PERSISTENT | CONST_CS );
|
REGISTER_LONG_CONSTANT( "SQLSRV_NULLABLE_YES", 1, CONST_PERSISTENT | CONST_CS );
|
||||||
REGISTER_LONG_CONSTANT( "SQLSRV_NULLABLE_UNKNOWN", 2, CONST_PERSISTENT | CONST_CS );
|
REGISTER_LONG_CONSTANT( "SQLSRV_NULLABLE_UNKNOWN", 2, CONST_PERSISTENT | CONST_CS );
|
||||||
|
|
||||||
REGISTER_LONG_CONSTANT( "SQLSRV_SQLTYPE_BIGINT", SQL_BIGINT, CONST_PERSISTENT | CONST_CS );
|
REGISTER_LONG_CONSTANT( "SQLSRV_SQLTYPE_BIGINT", SQL_BIGINT, CONST_PERSISTENT | CONST_CS );
|
||||||
|
@ -394,6 +398,7 @@ PHP_MINIT_FUNCTION(sqlsrv)
|
||||||
REGISTER_STRING_CONSTANT( "SQLSRV_CURSOR_STATIC", "static", CONST_PERSISTENT | CONST_CS );
|
REGISTER_STRING_CONSTANT( "SQLSRV_CURSOR_STATIC", "static", CONST_PERSISTENT | CONST_CS );
|
||||||
REGISTER_STRING_CONSTANT( "SQLSRV_CURSOR_DYNAMIC", "dynamic", CONST_PERSISTENT | CONST_CS );
|
REGISTER_STRING_CONSTANT( "SQLSRV_CURSOR_DYNAMIC", "dynamic", CONST_PERSISTENT | CONST_CS );
|
||||||
REGISTER_STRING_CONSTANT( "SQLSRV_CURSOR_KEYSET", "keyset", CONST_PERSISTENT | CONST_CS );
|
REGISTER_STRING_CONSTANT( "SQLSRV_CURSOR_KEYSET", "keyset", CONST_PERSISTENT | CONST_CS );
|
||||||
|
REGISTER_STRING_CONSTANT( "SQLSRV_CURSOR_CLIENT_BUFFERED", "buffered", CONST_PERSISTENT | CONST_CS );
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
@ -601,9 +606,16 @@ PHP_RINIT_FUNCTION(sqlsrv)
|
||||||
|
|
||||||
LOG_FUNCTION( "PHP_RINIT for php_sqlsrv" );
|
LOG_FUNCTION( "PHP_RINIT for php_sqlsrv" );
|
||||||
|
|
||||||
|
// read INI settings
|
||||||
|
SQLSRV_G( warnings_return_as_errors ) = INI_BOOL( INI_PREFIX INI_WARNINGS_RETURN_AS_ERRORS );
|
||||||
|
SQLSRV_G( log_severity ) = INI_INT( INI_PREFIX INI_LOG_SEVERITY );
|
||||||
|
SQLSRV_G( log_subsystems ) = INI_INT( INI_PREFIX INI_LOG_SUBSYSTEMS );
|
||||||
|
SQLSRV_G( buffered_query_limit ) = INI_INT( INI_PREFIX INI_BUFFERED_QUERY_LIMIT );
|
||||||
|
|
||||||
LOG( SEV_NOTICE, INI_PREFIX INI_WARNINGS_RETURN_AS_ERRORS " = %1!s!", SQLSRV_G( warnings_return_as_errors ) ? "On" : "Off");
|
LOG( SEV_NOTICE, INI_PREFIX INI_WARNINGS_RETURN_AS_ERRORS " = %1!s!", SQLSRV_G( warnings_return_as_errors ) ? "On" : "Off");
|
||||||
LOG( SEV_NOTICE, INI_PREFIX INI_LOG_SEVERITY " = %1!d!", SQLSRV_G( log_severity ));
|
LOG( SEV_NOTICE, INI_PREFIX INI_LOG_SEVERITY " = %1!d!", SQLSRV_G( log_severity ));
|
||||||
LOG( SEV_NOTICE, INI_PREFIX INI_LOG_SUBSYSTEMS " = %1!d!", SQLSRV_G( log_subsystems ));
|
LOG( SEV_NOTICE, INI_PREFIX INI_LOG_SUBSYSTEMS " = %1!d!", SQLSRV_G( log_subsystems ));
|
||||||
|
LOG( SEV_NOTICE, INI_PREFIX INI_BUFFERED_QUERY_LIMIT " = %1!d!", SQLSRV_G( buffered_query_limit ));
|
||||||
|
|
||||||
// verify memory at the end of the request (in debug mode only)
|
// verify memory at the end of the request (in debug mode only)
|
||||||
full_mem_check(MEMCHECK_SILENT);
|
full_mem_check(MEMCHECK_SILENT);
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
//
|
//
|
||||||
// Comments: Also contains "internal" declarations shared across source files.
|
// Comments: Also contains "internal" declarations shared across source files.
|
||||||
//
|
//
|
||||||
// Copyright 2010 Microsoft Corporation
|
// Copyright Microsoft Corporation
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -169,19 +169,11 @@ struct stmt_option_scrollable : public stmt_option_functor {
|
||||||
// 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( sqlsrv_conn* c, SQLHANDLE handle, error_callback e, void* drv TSRMLS_DC ) :
|
ss_sqlsrv_stmt( sqlsrv_conn* c, SQLHANDLE handle, error_callback e, void* drv TSRMLS_DC );
|
||||||
sqlsrv_stmt( c, handle, e, drv TSRMLS_CC ),
|
|
||||||
prepared( false ),
|
|
||||||
conn_index( -1 ),
|
|
||||||
params_z( NULL ),
|
|
||||||
fetch_field_names( NULL ),
|
|
||||||
fetch_fields_count ( 0 )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~ss_sqlsrv_stmt( void );
|
virtual ~ss_sqlsrv_stmt( void );
|
||||||
|
|
||||||
void new_result_set( void );
|
void new_result_set( TSRMLS_D );
|
||||||
|
|
||||||
// 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( SQLINTEGER sql_type, SQLUINTEGER size, bool prefer_string_to_stream );
|
sqlsrv_phptype sql_type_to_php_type( SQLINTEGER sql_type, SQLUINTEGER size, bool prefer_string_to_stream );
|
||||||
|
@ -278,10 +270,11 @@ zval* errors;
|
||||||
zval* warnings;
|
zval* warnings;
|
||||||
|
|
||||||
// flags for error handling and logging (set via sqlsrv_configure or php.ini)
|
// flags for error handling and logging (set via sqlsrv_configure or php.ini)
|
||||||
unsigned int log_severity;
|
long log_severity;
|
||||||
unsigned int log_subsystems;
|
long log_subsystems;
|
||||||
unsigned int current_subsystem;
|
long current_subsystem;
|
||||||
zend_bool warnings_return_as_errors;
|
zend_bool warnings_return_as_errors;
|
||||||
|
long buffered_query_limit;
|
||||||
|
|
||||||
ZEND_END_MODULE_GLOBALS(sqlsrv)
|
ZEND_END_MODULE_GLOBALS(sqlsrv)
|
||||||
|
|
||||||
|
@ -301,6 +294,7 @@ ZEND_EXTERN_MODULE_GLOBALS(sqlsrv);
|
||||||
#define INI_WARNINGS_RETURN_AS_ERRORS "WarningsReturnAsErrors"
|
#define INI_WARNINGS_RETURN_AS_ERRORS "WarningsReturnAsErrors"
|
||||||
#define INI_LOG_SEVERITY "LogSeverity"
|
#define INI_LOG_SEVERITY "LogSeverity"
|
||||||
#define INI_LOG_SUBSYSTEMS "LogSubsystems"
|
#define INI_LOG_SUBSYSTEMS "LogSubsystems"
|
||||||
|
#define INI_BUFFERED_QUERY_LIMIT "ClientBufferMaxKBSize"
|
||||||
#define INI_PREFIX "sqlsrv."
|
#define INI_PREFIX "sqlsrv."
|
||||||
|
|
||||||
PHP_INI_BEGIN()
|
PHP_INI_BEGIN()
|
||||||
|
@ -310,6 +304,8 @@ PHP_INI_BEGIN()
|
||||||
sqlsrv_globals )
|
sqlsrv_globals )
|
||||||
STD_PHP_INI_ENTRY( INI_PREFIX INI_LOG_SUBSYSTEMS, "0", PHP_INI_ALL, OnUpdateLong, log_subsystems, zend_sqlsrv_globals,
|
STD_PHP_INI_ENTRY( INI_PREFIX INI_LOG_SUBSYSTEMS, "0", PHP_INI_ALL, OnUpdateLong, log_subsystems, zend_sqlsrv_globals,
|
||||||
sqlsrv_globals )
|
sqlsrv_globals )
|
||||||
|
STD_PHP_INI_ENTRY( INI_PREFIX INI_BUFFERED_QUERY_LIMIT, INI_BUFFERED_QUERY_LIMIT_DEFAULT, PHP_INI_ALL, OnUpdateLong, buffered_query_limit,
|
||||||
|
zend_sqlsrv_globals, sqlsrv_globals )
|
||||||
PHP_INI_END()
|
PHP_INI_END()
|
||||||
|
|
||||||
//*********************************************************************************************************************************
|
//*********************************************************************************************************************************
|
||||||
|
@ -366,7 +362,6 @@ bool ss_error_handler( sqlsrv_context& ctx, unsigned int sqlsrv_error_code, bool
|
||||||
|
|
||||||
// *** extension error functions ***
|
// *** extension error functions ***
|
||||||
PHP_FUNCTION(sqlsrv_errors);
|
PHP_FUNCTION(sqlsrv_errors);
|
||||||
PHP_FUNCTION(sqlsrv_warnings);
|
|
||||||
|
|
||||||
// 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
|
||||||
|
@ -461,7 +456,8 @@ public:
|
||||||
#define LOG_FUNCTION( function_name ) \
|
#define LOG_FUNCTION( function_name ) \
|
||||||
const char* _FN_ = function_name; \
|
const char* _FN_ = function_name; \
|
||||||
SQLSRV_G( current_subsystem ) = current_log_subsystem; \
|
SQLSRV_G( current_subsystem ) = current_log_subsystem; \
|
||||||
LOG( SEV_NOTICE, "%1!s!: entering", _FN_ );
|
LOG( SEV_NOTICE, "%1!s!: entering", _FN_ ); \
|
||||||
|
CheckMemory _check_memory_;
|
||||||
|
|
||||||
#define SET_FUNCTION_NAME( context ) \
|
#define SET_FUNCTION_NAME( context ) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -480,6 +476,22 @@ enum logging_subsystems {
|
||||||
LOG_ALL = -1,
|
LOG_ALL = -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CheckMemory {
|
||||||
|
|
||||||
|
CheckMemory( void )
|
||||||
|
{
|
||||||
|
// test the integrity of the Zend heap.
|
||||||
|
full_mem_check(MEMCHECK_SILENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
~CheckMemory( void )
|
||||||
|
{
|
||||||
|
// test the integrity of the Zend heap.
|
||||||
|
full_mem_check(MEMCHECK_SILENT);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
//*********************************************************************************************************************************
|
//*********************************************************************************************************************************
|
||||||
// Utility Functions
|
// Utility Functions
|
||||||
//*********************************************************************************************************************************
|
//*********************************************************************************************************************************
|
||||||
|
@ -497,9 +509,6 @@ inline H* process_params( INTERNAL_FUNCTION_PARAMETERS, char const* param_spec,
|
||||||
zval* rsrc;
|
zval* rsrc;
|
||||||
H* h;
|
H* h;
|
||||||
|
|
||||||
// test the integrity of the Zend heap.
|
|
||||||
full_mem_check(MEMCHECK_SILENT);
|
|
||||||
|
|
||||||
// reset the errors from the previous API call
|
// reset the errors from the previous API call
|
||||||
reset_errors( TSRMLS_C );
|
reset_errors( TSRMLS_C );
|
||||||
|
|
||||||
|
@ -529,8 +538,8 @@ inline H* process_params( INTERNAL_FUNCTION_PARAMETERS, char const* param_spec,
|
||||||
int result = SUCCESS;
|
int result = SUCCESS;
|
||||||
|
|
||||||
// dummy context to pass to the error handler
|
// dummy context to pass to the error handler
|
||||||
sqlsrv_context *error_ctx = new sqlsrv_context( 0, ss_error_handler, NULL );
|
sqlsrv_context error_ctx( 0, ss_error_handler, NULL );;
|
||||||
error_ctx->set_func( calling_func );
|
error_ctx.set_func( calling_func );
|
||||||
|
|
||||||
switch( param_count ) {
|
switch( param_count ) {
|
||||||
|
|
||||||
|
@ -574,7 +583,7 @@ inline H* process_params( INTERNAL_FUNCTION_PARAMETERS, char const* param_spec,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECK_CUSTOM_ERROR(( result == FAILURE ), error_ctx, SS_SQLSRV_ERROR_INVALID_FUNCTION_PARAMETER, calling_func ) {
|
CHECK_CUSTOM_ERROR(( result == FAILURE ), &error_ctx, SS_SQLSRV_ERROR_INVALID_FUNCTION_PARAMETER, calling_func ) {
|
||||||
|
|
||||||
throw ss::SSException();
|
throw ss::SSException();
|
||||||
}
|
}
|
||||||
|
@ -582,7 +591,7 @@ inline H* process_params( INTERNAL_FUNCTION_PARAMETERS, char const* param_spec,
|
||||||
// get the resource registered
|
// get the resource registered
|
||||||
h = static_cast<H*>( zend_fetch_resource( &rsrc TSRMLS_CC, -1, H::resource_name, NULL, 1, H::descriptor ));
|
h = static_cast<H*>( zend_fetch_resource( &rsrc TSRMLS_CC, -1, H::resource_name, NULL, 1, 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 ) {
|
||||||
|
|
||||||
throw ss::SSException();
|
throw ss::SSException();
|
||||||
}
|
}
|
||||||
|
|
3043
sqlsrv/sqlncli.h
Normal file
3043
sqlsrv/sqlncli.h
Normal file
|
@ -0,0 +1,3043 @@
|
||||||
|
|
||||||
|
|
||||||
|
/* this ALWAYS GENERATED file contains the definitions for the interfaces */
|
||||||
|
|
||||||
|
|
||||||
|
/* File created by MIDL compiler version 7.00.0474 */
|
||||||
|
/* Compiler settings for sqlncli.idl:
|
||||||
|
Oicf, W1, Zp8, env=Win32 (32b run)
|
||||||
|
protocol : dce , ms_ext, c_ext, robust
|
||||||
|
error checks: allocation ref bounds_check enum stub_data
|
||||||
|
VC __declspec() decoration level:
|
||||||
|
__declspec(uuid()), __declspec(selectany), __declspec(novtable)
|
||||||
|
DECLSPEC_UUID(), MIDL_INTERFACE()
|
||||||
|
*/
|
||||||
|
//@@MIDL_FILE_HEADING( )
|
||||||
|
|
||||||
|
#pragma warning( disable: 4049 ) /* more than 64k source lines */
|
||||||
|
|
||||||
|
|
||||||
|
/* verify that the <rpcndr.h> version is high enough to compile this file*/
|
||||||
|
#ifndef __REQUIRED_RPCNDR_H_VERSION__
|
||||||
|
#define __REQUIRED_RPCNDR_H_VERSION__ 475
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "rpc.h"
|
||||||
|
#include "rpcndr.h"
|
||||||
|
|
||||||
|
#ifndef __RPCNDR_H_VERSION__
|
||||||
|
#error this stub requires an updated version of <rpcndr.h>
|
||||||
|
#endif // __RPCNDR_H_VERSION__
|
||||||
|
|
||||||
|
#ifndef COM_NO_WINDOWS_H
|
||||||
|
#include "windows.h"
|
||||||
|
#include "ole2.h"
|
||||||
|
#endif /*COM_NO_WINDOWS_H*/
|
||||||
|
|
||||||
|
#ifndef __sqlncli_h__
|
||||||
|
#define __sqlncli_h__
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Forward Declarations */
|
||||||
|
|
||||||
|
#ifndef __ICommandWithParameters_FWD_DEFINED__
|
||||||
|
#define __ICommandWithParameters_FWD_DEFINED__
|
||||||
|
typedef interface ICommandWithParameters ICommandWithParameters;
|
||||||
|
#endif /* __ICommandWithParameters_FWD_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __IUMSInitialize_FWD_DEFINED__
|
||||||
|
#define __IUMSInitialize_FWD_DEFINED__
|
||||||
|
typedef interface IUMSInitialize IUMSInitialize;
|
||||||
|
#endif /* __IUMSInitialize_FWD_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __ISQLServerErrorInfo_FWD_DEFINED__
|
||||||
|
#define __ISQLServerErrorInfo_FWD_DEFINED__
|
||||||
|
typedef interface ISQLServerErrorInfo ISQLServerErrorInfo;
|
||||||
|
#endif /* __ISQLServerErrorInfo_FWD_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __IRowsetFastLoad_FWD_DEFINED__
|
||||||
|
#define __IRowsetFastLoad_FWD_DEFINED__
|
||||||
|
typedef interface IRowsetFastLoad IRowsetFastLoad;
|
||||||
|
#endif /* __IRowsetFastLoad_FWD_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __ISchemaLock_FWD_DEFINED__
|
||||||
|
#define __ISchemaLock_FWD_DEFINED__
|
||||||
|
typedef interface ISchemaLock ISchemaLock;
|
||||||
|
#endif /* __ISchemaLock_FWD_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __IBCPSession_FWD_DEFINED__
|
||||||
|
#define __IBCPSession_FWD_DEFINED__
|
||||||
|
typedef interface IBCPSession IBCPSession;
|
||||||
|
#endif /* __IBCPSession_FWD_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __ISSAbort_FWD_DEFINED__
|
||||||
|
#define __ISSAbort_FWD_DEFINED__
|
||||||
|
typedef interface ISSAbort ISSAbort;
|
||||||
|
#endif /* __ISSAbort_FWD_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __ISSCommandWithParameters_FWD_DEFINED__
|
||||||
|
#define __ISSCommandWithParameters_FWD_DEFINED__
|
||||||
|
typedef interface ISSCommandWithParameters ISSCommandWithParameters;
|
||||||
|
#endif /* __ISSCommandWithParameters_FWD_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __IDBAsynchStatus_FWD_DEFINED__
|
||||||
|
#define __IDBAsynchStatus_FWD_DEFINED__
|
||||||
|
typedef interface IDBAsynchStatus IDBAsynchStatus;
|
||||||
|
#endif /* __IDBAsynchStatus_FWD_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __ISSAsynchStatus_FWD_DEFINED__
|
||||||
|
#define __ISSAsynchStatus_FWD_DEFINED__
|
||||||
|
typedef interface ISSAsynchStatus ISSAsynchStatus;
|
||||||
|
#endif /* __ISSAsynchStatus_FWD_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
/* header files for imported files */
|
||||||
|
#include "unknwn.h"
|
||||||
|
#include "oaidl.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* interface __MIDL_itf_sqlncli_0000_0000 */
|
||||||
|
/* [local] */
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// File: sqlncli.h
|
||||||
|
//
|
||||||
|
// Copyright: Copyright (c) Microsoft Corporation
|
||||||
|
//
|
||||||
|
// Contents: SQL Server Native Client OLEDB provider and ODBC driver specific
|
||||||
|
// definitions.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if !defined(SQLNCLI_VER)
|
||||||
|
#define SQLNCLI_VER 1000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SQLNCLI_VER >= 1000
|
||||||
|
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_FULL_VER_ANSI "Microsoft SQL Server Native Client 10.0"
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_FULL_ANSI "Microsoft SQL Server Native Client"
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_SHORT_VER_ANSI "SQL Server Native Client 10.0"
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_SHORT_ANSI "SQL Server Native Client"
|
||||||
|
|
||||||
|
#define SQLNCLI_FILE_NAME_ANSI "sqlncli"
|
||||||
|
#define SQLNCLI_FILE_NAME_VER_ANSI "sqlncli10"
|
||||||
|
#define SQLNCLI_FILE_NAME_FULL_ANSI "sqlncli10.dll"
|
||||||
|
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_FULL_VER_UNICODE L"Microsoft SQL Server Native Client 10.0"
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_FULL_UNICODE L"Microsoft SQL Server Native Client"
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_SHORT_VER_UNICODE L"SQL Server Native Client 10.0"
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_SHORT_UNICODE L"SQL Server Native Client"
|
||||||
|
|
||||||
|
#define SQLNCLI_FILE_NAME_UNICODE L"sqlncli"
|
||||||
|
#define SQLNCLI_FILE_NAME_VER_UNICODE L"sqlncli10"
|
||||||
|
#define SQLNCLI_FILE_NAME_FULL_UNICODE L"sqlncli10.dll"
|
||||||
|
|
||||||
|
#if defined(_SQLNCLI_OLEDB_) || !defined(_SQLNCLI_ODBC_)
|
||||||
|
|
||||||
|
#define SQLNCLI_VI_PROG_ID_ANSI "SQLNCLI10"
|
||||||
|
#define SQLNCLI_VI_ERROR_LOOKUP_PROG_ID_ANSI "SQLNCLI10 ErrorLookup"
|
||||||
|
#define SQLNCLI_VI_ENUMERATOR_PROG_ID_ANSI "SQLNCLI10 Enumerator"
|
||||||
|
|
||||||
|
#define SQLNCLI_PROG_ID_ANSI "SQLNCLI10.1"
|
||||||
|
#define SQLNCLI_ERROR_LOOKUP_PROG_ID_ANSI "SQLNCLI10 ErrorLookup.1"
|
||||||
|
#define SQLNCLI_ENUMERATOR_PROG_ID_ANSI "SQLNCLI10 Enumerator.1"
|
||||||
|
|
||||||
|
#define SQLNCLI_VI_PROG_ID_UNICODE L"SQLNCLI10"
|
||||||
|
#define SQLNCLI_VI_ERROR_LOOKUP_PROG_ID_UNICODE L"SQLNCLI10 ErrorLookup"
|
||||||
|
#define SQLNCLI_VI_ENUMERATOR_PROG_ID_UNICODE L"SQLNCLI10 Enumerator"
|
||||||
|
|
||||||
|
#define SQLNCLI_PROG_ID_UNICODE L"SQLNCLI10.1"
|
||||||
|
#define SQLNCLI_ERROR_LOOKUP_PROG_ID_UNICODE L"SQLNCLI10 ErrorLookup.1"
|
||||||
|
#define SQLNCLI_ENUMERATOR_PROG_ID_UNICODE L"SQLNCLI10 Enumerator.1"
|
||||||
|
|
||||||
|
#define SQLNCLI_CLSID CLSID_SQLNCLI10
|
||||||
|
#define SQLNCLI_ERROR_CLSID CLSID_SQLNCLI10_ERROR
|
||||||
|
#define SQLNCLI_ENUMERATOR_CLSID CLSID_SQLNCLI10_ENUMERATOR
|
||||||
|
|
||||||
|
#endif // defined(_SQLNCLI_OLEDB_) || !defined(_SQLNCLI_ODBC_)
|
||||||
|
|
||||||
|
#else // SQLNCLI_VER >= 1000
|
||||||
|
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_FULL_VER_ANSI "Microsoft SQL Server Native Client"
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_FULL_ANSI "Microsoft SQL Server Native Client"
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_SHORT_VER_ANSI "SQL Native Client"
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_SHORT_ANSI "SQL Native Client"
|
||||||
|
|
||||||
|
#define SQLNCLI_FILE_NAME_ANSI "sqlncli"
|
||||||
|
#define SQLNCLI_FILE_NAME_VER_ANSI "sqlncli"
|
||||||
|
#define SQLNCLI_FILE_NAME_FULL_ANSI "sqlncli.dll"
|
||||||
|
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_FULL_VER_UNICODE L"Microsoft SQL Server Native Client"
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_FULL_UNICODE L"Microsoft SQL Server Native Client"
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_SHORT_VER_UNICODE L"SQL Native Client"
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_SHORT_UNICODE L"SQL Native Client"
|
||||||
|
|
||||||
|
#define SQLNCLI_FILE_NAME_UNICODE L"sqlncli"
|
||||||
|
#define SQLNCLI_FILE_NAME_VER_UNICODE L"sqlncli"
|
||||||
|
#define SQLNCLI_FILE_NAME_FULL_UNICODE L"sqlncli.dll"
|
||||||
|
|
||||||
|
#if defined(_SQLNCLI_OLEDB_) || !defined(_SQLNCLI_ODBC_)
|
||||||
|
|
||||||
|
#define SQLNCLI_VI_PROG_ID_ANSI "SQLNCLI"
|
||||||
|
#define SQLNCLI_VI_ERROR_LOOKUP_PROG_ID_ANSI "SQLNCLI ErrorLookup"
|
||||||
|
#define SQLNCLI_VI_ENUMERATOR_PROG_ID_ANSI "SQLNCLI Enumerator"
|
||||||
|
|
||||||
|
#define SQLNCLI_PROG_ID_ANSI "SQLNCLI.1"
|
||||||
|
#define SQLNCLI_ERROR_LOOKUP_PROG_ID_ANSI "SQLNCLI ErrorLookup.1"
|
||||||
|
#define SQLNCLI_ENUMERATOR_PROG_ID_ANSI "SQLNCLI Enumerator.1"
|
||||||
|
|
||||||
|
#define SQLNCLI_VI_PROG_ID_UNICODE L"SQLNCLI"
|
||||||
|
#define SQLNCLI_VI_ERROR_LOOKUP_PROG_ID_UNICODE L"SQLNCLI ErrorLookup"
|
||||||
|
#define SQLNCLI_VI_ENUMERATOR_PROG_ID_UNICODE L"SQLNCLI Enumerator"
|
||||||
|
|
||||||
|
#define SQLNCLI_PROG_ID_UNICODE L"SQLNCLI.1"
|
||||||
|
#define SQLNCLI_ERROR_LOOKUP_PROG_ID_UNICODE L"SQLNCLI ErrorLookup.1"
|
||||||
|
#define SQLNCLI_ENUMERATOR_PROG_ID_UNICODE L"SQLNCLI Enumerator.1"
|
||||||
|
|
||||||
|
#define SQLNCLI_CLSID CLSID_SQLNCLI
|
||||||
|
#define SQLNCLI_ERROR_CLSID CLSID_SQLNCLI_ERROR
|
||||||
|
#define SQLNCLI_ENUMERATOR_CLSID CLSID_SQLNCLI_ENUMERATOR
|
||||||
|
|
||||||
|
#endif // defined(_SQLNCLI_OLEDB_) || !defined(_SQLNCLI_ODBC_)
|
||||||
|
|
||||||
|
#endif // SQLNCLI_VER >= 1000
|
||||||
|
|
||||||
|
// define the character type agnostic constants
|
||||||
|
#if defined(_UNICODE) || defined(UNICODE)
|
||||||
|
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_FULL_VER SQLNCLI_PRODUCT_NAME_FULL_VER_UNICODE
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_FULL SQLNCLI_PRODUCT_NAME_FULL_UNICODE
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_SHORT_VER SQLNCLI_PRODUCT_NAME_SHORT_VER_UNICODE
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_SHORT SQLNCLI_PRODUCT_NAME_SHORT_UNICODE
|
||||||
|
|
||||||
|
#define SQLNCLI_FILE_NAME SQLNCLI_FILE_NAME_UNICODE
|
||||||
|
#define SQLNCLI_FILE_NAME_VER SQLNCLI_FILE_NAME_VER_UNICODE
|
||||||
|
#define SQLNCLI_FILE_NAME_FULL SQLNCLI_FILE_NAME_FULL_UNICODE
|
||||||
|
|
||||||
|
#if defined(_SQLNCLI_OLEDB_) || !defined(_SQLNCLI_ODBC_)
|
||||||
|
|
||||||
|
#define SQLNCLI_VI_PROG_ID SQLNCLI_VI_PROG_ID_UNICODE
|
||||||
|
#define SQLNCLI_VI_ERROR_LOOKUP_PROG_ID SQLNCLI_VI_ERROR_LOOKUP_PROG_ID_UNICODE
|
||||||
|
#define SQLNCLI_VI_ENUMERATOR_PROG_ID SQLNCLI_VI_ENUMERATOR_PROG_ID_UNICODE
|
||||||
|
|
||||||
|
#define SQLNCLI_PROG_ID SQLNCLI_PROG_ID_UNICODE
|
||||||
|
#define SQLNCLI_ERROR_LOOKUP_PROG_ID SQLNCLI_ERROR_LOOKUP_PROG_ID_UNICODE
|
||||||
|
#define SQLNCLI_ENUMERATOR_PROG_ID SQLNCLI_ENUMERATOR_PROG_ID_UNICODE
|
||||||
|
|
||||||
|
#endif // defined(_SQLNCLI_OLEDB_) || !defined(_SQLNCLI_ODBC_)
|
||||||
|
|
||||||
|
#else // _UNICODE || UNICODE
|
||||||
|
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_FULL_VER SQLNCLI_PRODUCT_NAME_FULL_VER_ANSI
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_FULL SQLNCLI_PRODUCT_NAME_FULL_ANSI
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_SHORT_VER SQLNCLI_PRODUCT_NAME_SHORT_VER_ANSI
|
||||||
|
#define SQLNCLI_PRODUCT_NAME_SHORT SQLNCLI_PRODUCT_NAME_SHORT_ANSI
|
||||||
|
|
||||||
|
#define SQLNCLI_FILE_NAME SQLNCLI_FILE_NAME_ANSI
|
||||||
|
#define SQLNCLI_FILE_NAME_VER SQLNCLI_FILE_NAME_VER_ANSI
|
||||||
|
#define SQLNCLI_FILE_NAME_FULL SQLNCLI_FILE_NAME_FULL_ANSI
|
||||||
|
|
||||||
|
#if defined(_SQLNCLI_OLEDB_) || !defined(_SQLNCLI_ODBC_)
|
||||||
|
|
||||||
|
#define SQLNCLI_VI_PROG_ID SQLNCLI_VI_PROG_ID_ANSI
|
||||||
|
#define SQLNCLI_VI_ERROR_LOOKUP_PROG_ID SQLNCLI_VI_ERROR_LOOKUP_PROG_ID_ANSI
|
||||||
|
#define SQLNCLI_VI_ENUMERATOR_PROG_ID SQLNCLI_VI_ENUMERATOR_PROG_ID_ANSI
|
||||||
|
|
||||||
|
#define SQLNCLI_PROG_ID SQLNCLI_PROG_ID_ANSI
|
||||||
|
#define SQLNCLI_ERROR_LOOKUP_PROG_ID SQLNCLI_ERROR_LOOKUP_PROG_ID_ANSI
|
||||||
|
#define SQLNCLI_ENUMERATOR_PROG_ID SQLNCLI_ENUMERATOR_PROG_ID_ANSI
|
||||||
|
|
||||||
|
#endif // defined(_SQLNCLI_OLEDB_) || !defined(_SQLNCLI_ODBC_)
|
||||||
|
|
||||||
|
#endif // _UNICODE || UNICODE
|
||||||
|
|
||||||
|
#if defined(_SQLNCLI_ODBC_) || !defined(_SQLNCLI_OLEDB_)
|
||||||
|
|
||||||
|
#define SQLNCLI_DRIVER_NAME SQLNCLI_PRODUCT_NAME_SHORT_VER
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// OLEDB part of SQL Server Native Client header - begin here
|
||||||
|
#if defined(_SQLNCLI_OLEDB_) || !defined(_SQLNCLI_ODBC_)
|
||||||
|
#ifndef __oledb_h__
|
||||||
|
#include <oledb.h>
|
||||||
|
#endif /*__oledb_h__*/
|
||||||
|
|
||||||
|
#if 0 // This is already defined in oledb.h
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
|
||||||
|
// Length of a non-character object, size
|
||||||
|
typedef ULONGLONG DBLENGTH;
|
||||||
|
|
||||||
|
// Offset within a rowset
|
||||||
|
typedef LONGLONG DBROWOFFSET;
|
||||||
|
|
||||||
|
// Number of rows
|
||||||
|
typedef LONGLONG DBROWCOUNT;
|
||||||
|
|
||||||
|
typedef ULONGLONG DBCOUNTITEM;
|
||||||
|
|
||||||
|
// Ordinal (column number, etc.)
|
||||||
|
typedef ULONGLONG DBORDINAL;
|
||||||
|
|
||||||
|
typedef LONGLONG DB_LORDINAL;
|
||||||
|
|
||||||
|
// Bookmarks
|
||||||
|
typedef ULONGLONG DBBKMARK;
|
||||||
|
// Offset in the buffer
|
||||||
|
|
||||||
|
typedef ULONGLONG DBBYTEOFFSET;
|
||||||
|
// Reference count of each row/accessor handle
|
||||||
|
|
||||||
|
typedef ULONG DBREFCOUNT;
|
||||||
|
|
||||||
|
// Parameters
|
||||||
|
typedef ULONGLONG DB_UPARAMS;
|
||||||
|
|
||||||
|
typedef LONGLONG DB_LPARAMS;
|
||||||
|
|
||||||
|
// hash values corresponding to the elements (bookmarks)
|
||||||
|
typedef DWORDLONG DBHASHVALUE;
|
||||||
|
|
||||||
|
// For reserve
|
||||||
|
typedef DWORDLONG DB_DWRESERVE;
|
||||||
|
|
||||||
|
typedef LONGLONG DB_LRESERVE;
|
||||||
|
|
||||||
|
typedef ULONGLONG DB_URESERVE;
|
||||||
|
|
||||||
|
#else //_WIN64
|
||||||
|
|
||||||
|
// Length of a non-character object, size
|
||||||
|
typedef ULONG DBLENGTH;
|
||||||
|
|
||||||
|
// Offset within a rowset
|
||||||
|
typedef LONG DBROWOFFSET;
|
||||||
|
|
||||||
|
// Number of rows
|
||||||
|
typedef LONG DBROWCOUNT;
|
||||||
|
|
||||||
|
typedef ULONG DBCOUNTITEM;
|
||||||
|
|
||||||
|
// Ordinal (column number, etc.)
|
||||||
|
typedef ULONG DBORDINAL;
|
||||||
|
|
||||||
|
typedef LONG DB_LORDINAL;
|
||||||
|
|
||||||
|
// Bookmarks
|
||||||
|
typedef ULONG DBBKMARK;
|
||||||
|
|
||||||
|
// Offset in the buffer
|
||||||
|
typedef ULONG DBBYTEOFFSET;
|
||||||
|
|
||||||
|
// Reference count of each row handle
|
||||||
|
typedef ULONG DBREFCOUNT;
|
||||||
|
|
||||||
|
// Parameters
|
||||||
|
typedef ULONG DB_UPARAMS;
|
||||||
|
|
||||||
|
typedef LONG DB_LPARAMS;
|
||||||
|
|
||||||
|
// hash values corresponding to the elements (bookmarks)
|
||||||
|
typedef DWORD DBHASHVALUE;
|
||||||
|
|
||||||
|
// For reserve
|
||||||
|
typedef DWORD DB_DWRESERVE;
|
||||||
|
|
||||||
|
typedef LONG DB_LRESERVE;
|
||||||
|
|
||||||
|
typedef ULONG DB_URESERVE;
|
||||||
|
|
||||||
|
#endif // _WIN64
|
||||||
|
typedef DWORD DBKIND;
|
||||||
|
|
||||||
|
|
||||||
|
enum DBKINDENUM
|
||||||
|
{ DBKIND_GUID_NAME = 0,
|
||||||
|
DBKIND_GUID_PROPID = ( DBKIND_GUID_NAME + 1 ) ,
|
||||||
|
DBKIND_NAME = ( DBKIND_GUID_PROPID + 1 ) ,
|
||||||
|
DBKIND_PGUID_NAME = ( DBKIND_NAME + 1 ) ,
|
||||||
|
DBKIND_PGUID_PROPID = ( DBKIND_PGUID_NAME + 1 ) ,
|
||||||
|
DBKIND_PROPID = ( DBKIND_PGUID_PROPID + 1 ) ,
|
||||||
|
DBKIND_GUID = ( DBKIND_PROPID + 1 )
|
||||||
|
} ;
|
||||||
|
typedef struct tagDBID
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
GUID guid;
|
||||||
|
GUID *pguid;
|
||||||
|
/* Empty union arm */
|
||||||
|
} uGuid;
|
||||||
|
DBKIND eKind;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
LPOLESTR pwszName;
|
||||||
|
ULONG ulPropid;
|
||||||
|
/* Empty union arm */
|
||||||
|
} uName;
|
||||||
|
} DBID;
|
||||||
|
|
||||||
|
typedef struct tagDB_NUMERIC
|
||||||
|
{
|
||||||
|
BYTE precision;
|
||||||
|
BYTE scale;
|
||||||
|
BYTE sign;
|
||||||
|
BYTE val[ 16 ];
|
||||||
|
} DB_NUMERIC;
|
||||||
|
|
||||||
|
typedef struct tagDBDATE
|
||||||
|
{
|
||||||
|
SHORT year;
|
||||||
|
USHORT month;
|
||||||
|
USHORT day;
|
||||||
|
} DBDATE;
|
||||||
|
|
||||||
|
typedef struct tagDBTIME
|
||||||
|
{
|
||||||
|
USHORT hour;
|
||||||
|
USHORT minute;
|
||||||
|
USHORT second;
|
||||||
|
} DBTIME;
|
||||||
|
|
||||||
|
typedef struct tagDBTIMESTAMP
|
||||||
|
{
|
||||||
|
SHORT year;
|
||||||
|
USHORT month;
|
||||||
|
USHORT day;
|
||||||
|
USHORT hour;
|
||||||
|
USHORT minute;
|
||||||
|
USHORT second;
|
||||||
|
ULONG fraction;
|
||||||
|
} DBTIMESTAMP;
|
||||||
|
|
||||||
|
typedef struct tagDBOBJECT
|
||||||
|
{
|
||||||
|
DWORD dwFlags;
|
||||||
|
IID iid;
|
||||||
|
} DBOBJECT;
|
||||||
|
|
||||||
|
typedef WORD DBTYPE;
|
||||||
|
|
||||||
|
typedef ULONG_PTR HACCESSOR;
|
||||||
|
|
||||||
|
typedef ULONG_PTR HCHAPTER;
|
||||||
|
|
||||||
|
typedef DWORD DBPARAMFLAGS;
|
||||||
|
|
||||||
|
typedef struct tagDBPARAMINFO
|
||||||
|
{
|
||||||
|
DBPARAMFLAGS dwFlags;
|
||||||
|
DBORDINAL iOrdinal;
|
||||||
|
LPOLESTR pwszName;
|
||||||
|
ITypeInfo *pTypeInfo;
|
||||||
|
DBLENGTH ulParamSize;
|
||||||
|
DBTYPE wType;
|
||||||
|
BYTE bPrecision;
|
||||||
|
BYTE bScale;
|
||||||
|
} DBPARAMINFO;
|
||||||
|
|
||||||
|
typedef DWORD DBPROPID;
|
||||||
|
|
||||||
|
typedef struct tagDBPROPIDSET
|
||||||
|
{
|
||||||
|
DBPROPID *rgPropertyIDs;
|
||||||
|
ULONG cPropertyIDs;
|
||||||
|
GUID guidPropertySet;
|
||||||
|
} DBPROPIDSET;
|
||||||
|
|
||||||
|
typedef DWORD DBPROPFLAGS;
|
||||||
|
|
||||||
|
typedef DWORD DBPROPOPTIONS;
|
||||||
|
|
||||||
|
typedef DWORD DBPROPSTATUS;
|
||||||
|
|
||||||
|
typedef struct tagDBPROP
|
||||||
|
{
|
||||||
|
DBPROPID dwPropertyID;
|
||||||
|
DBPROPOPTIONS dwOptions;
|
||||||
|
DBPROPSTATUS dwStatus;
|
||||||
|
DBID colid;
|
||||||
|
VARIANT vValue;
|
||||||
|
} DBPROP;
|
||||||
|
|
||||||
|
typedef struct tagDBPROPSET
|
||||||
|
{
|
||||||
|
DBPROP *rgProperties;
|
||||||
|
ULONG cProperties;
|
||||||
|
GUID guidPropertySet;
|
||||||
|
} DBPROPSET;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern RPC_IF_HANDLE __MIDL_itf_sqlncli_0000_0000_v0_0_c_ifspec;
|
||||||
|
extern RPC_IF_HANDLE __MIDL_itf_sqlncli_0000_0000_v0_0_s_ifspec;
|
||||||
|
|
||||||
|
#ifndef __ICommandWithParameters_INTERFACE_DEFINED__
|
||||||
|
#define __ICommandWithParameters_INTERFACE_DEFINED__
|
||||||
|
|
||||||
|
/* interface ICommandWithParameters */
|
||||||
|
/* [unique][uuid][object][local] */
|
||||||
|
|
||||||
|
typedef struct tagDBPARAMBINDINFO
|
||||||
|
{
|
||||||
|
LPOLESTR pwszDataSourceType;
|
||||||
|
LPOLESTR pwszName;
|
||||||
|
DBLENGTH ulParamSize;
|
||||||
|
DBPARAMFLAGS dwFlags;
|
||||||
|
BYTE bPrecision;
|
||||||
|
BYTE bScale;
|
||||||
|
} DBPARAMBINDINFO;
|
||||||
|
|
||||||
|
|
||||||
|
EXTERN_C const IID IID_ICommandWithParameters;
|
||||||
|
|
||||||
|
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||||
|
|
||||||
|
MIDL_INTERFACE("0c733a64-2a1c-11ce-ade5-00aa0044773d")
|
||||||
|
ICommandWithParameters : public IUnknown
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetParameterInfo(
|
||||||
|
/* [out][in] */ DB_UPARAMS *pcParams,
|
||||||
|
/* [size_is][size_is][out] */ DBPARAMINFO **prgParamInfo,
|
||||||
|
/* [out] */ OLECHAR **ppNamesBuffer) = 0;
|
||||||
|
|
||||||
|
virtual /* [local] */ HRESULT STDMETHODCALLTYPE MapParameterNames(
|
||||||
|
/* [in] */ DB_UPARAMS cParamNames,
|
||||||
|
/* [size_is][in] */ const OLECHAR *rgParamNames[ ],
|
||||||
|
/* [size_is][out] */ DB_LPARAMS rgParamOrdinals[ ]) = 0;
|
||||||
|
|
||||||
|
virtual /* [local] */ HRESULT STDMETHODCALLTYPE SetParameterInfo(
|
||||||
|
/* [in] */ DB_UPARAMS cParams,
|
||||||
|
/* [size_is][unique][in] */ const DB_UPARAMS rgParamOrdinals[ ],
|
||||||
|
/* [size_is][unique][in] */ const DBPARAMBINDINFO rgParamBindInfo[ ]) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#else /* C style interface */
|
||||||
|
|
||||||
|
typedef struct ICommandWithParametersVtbl
|
||||||
|
{
|
||||||
|
BEGIN_INTERFACE
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||||
|
ICommandWithParameters * This,
|
||||||
|
/* [in] */ REFIID riid,
|
||||||
|
/* [iid_is][out] */
|
||||||
|
__RPC__deref_out void **ppvObject);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||||
|
ICommandWithParameters * This);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||||
|
ICommandWithParameters * This);
|
||||||
|
|
||||||
|
/* [local] */ HRESULT ( STDMETHODCALLTYPE *GetParameterInfo )(
|
||||||
|
ICommandWithParameters * This,
|
||||||
|
/* [out][in] */ DB_UPARAMS *pcParams,
|
||||||
|
/* [size_is][size_is][out] */ DBPARAMINFO **prgParamInfo,
|
||||||
|
/* [out] */ OLECHAR **ppNamesBuffer);
|
||||||
|
|
||||||
|
/* [local] */ HRESULT ( STDMETHODCALLTYPE *MapParameterNames )(
|
||||||
|
ICommandWithParameters * This,
|
||||||
|
/* [in] */ DB_UPARAMS cParamNames,
|
||||||
|
/* [size_is][in] */ const OLECHAR *rgParamNames[ ],
|
||||||
|
/* [size_is][out] */ DB_LPARAMS rgParamOrdinals[ ]);
|
||||||
|
|
||||||
|
/* [local] */ HRESULT ( STDMETHODCALLTYPE *SetParameterInfo )(
|
||||||
|
ICommandWithParameters * This,
|
||||||
|
/* [in] */ DB_UPARAMS cParams,
|
||||||
|
/* [size_is][unique][in] */ const DB_UPARAMS rgParamOrdinals[ ],
|
||||||
|
/* [size_is][unique][in] */ const DBPARAMBINDINFO rgParamBindInfo[ ]);
|
||||||
|
|
||||||
|
END_INTERFACE
|
||||||
|
} ICommandWithParametersVtbl;
|
||||||
|
|
||||||
|
interface ICommandWithParameters
|
||||||
|
{
|
||||||
|
CONST_VTBL struct ICommandWithParametersVtbl *lpVtbl;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef COBJMACROS
|
||||||
|
|
||||||
|
|
||||||
|
#define ICommandWithParameters_QueryInterface(This,riid,ppvObject) \
|
||||||
|
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
|
||||||
|
|
||||||
|
#define ICommandWithParameters_AddRef(This) \
|
||||||
|
( (This)->lpVtbl -> AddRef(This) )
|
||||||
|
|
||||||
|
#define ICommandWithParameters_Release(This) \
|
||||||
|
( (This)->lpVtbl -> Release(This) )
|
||||||
|
|
||||||
|
|
||||||
|
#define ICommandWithParameters_GetParameterInfo(This,pcParams,prgParamInfo,ppNamesBuffer) \
|
||||||
|
( (This)->lpVtbl -> GetParameterInfo(This,pcParams,prgParamInfo,ppNamesBuffer) )
|
||||||
|
|
||||||
|
#define ICommandWithParameters_MapParameterNames(This,cParamNames,rgParamNames,rgParamOrdinals) \
|
||||||
|
( (This)->lpVtbl -> MapParameterNames(This,cParamNames,rgParamNames,rgParamOrdinals) )
|
||||||
|
|
||||||
|
#define ICommandWithParameters_SetParameterInfo(This,cParams,rgParamOrdinals,rgParamBindInfo) \
|
||||||
|
( (This)->lpVtbl -> SetParameterInfo(This,cParams,rgParamOrdinals,rgParamBindInfo) )
|
||||||
|
|
||||||
|
#endif /* COBJMACROS */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* C style interface */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* [call_as] */ HRESULT STDMETHODCALLTYPE ICommandWithParameters_RemoteGetParameterInfo_Proxy(
|
||||||
|
ICommandWithParameters * This,
|
||||||
|
/* [out][in] */ DB_UPARAMS *pcParams,
|
||||||
|
/* [size_is][size_is][out] */ DBPARAMINFO **prgParamInfo,
|
||||||
|
/* [size_is][size_is][out] */ DBBYTEOFFSET **prgNameOffsets,
|
||||||
|
/* [out][in] */ DBLENGTH *pcbNamesBuffer,
|
||||||
|
/* [size_is][size_is][unique][out][in] */ OLECHAR **ppNamesBuffer,
|
||||||
|
/* [out] */ IErrorInfo **ppErrorInfoRem);
|
||||||
|
|
||||||
|
|
||||||
|
void __RPC_STUB ICommandWithParameters_RemoteGetParameterInfo_Stub(
|
||||||
|
IRpcStubBuffer *This,
|
||||||
|
IRpcChannelBuffer *_pRpcChannelBuffer,
|
||||||
|
PRPC_MESSAGE _pRpcMessage,
|
||||||
|
DWORD *_pdwStubPhase);
|
||||||
|
|
||||||
|
|
||||||
|
/* [call_as] */ HRESULT STDMETHODCALLTYPE ICommandWithParameters_RemoteMapParameterNames_Proxy(
|
||||||
|
ICommandWithParameters * This,
|
||||||
|
/* [in] */ DB_UPARAMS cParamNames,
|
||||||
|
/* [size_is][in] */ LPCOLESTR *rgParamNames,
|
||||||
|
/* [size_is][out] */ DB_LPARAMS *rgParamOrdinals,
|
||||||
|
/* [out] */ IErrorInfo **ppErrorInfoRem);
|
||||||
|
|
||||||
|
|
||||||
|
void __RPC_STUB ICommandWithParameters_RemoteMapParameterNames_Stub(
|
||||||
|
IRpcStubBuffer *This,
|
||||||
|
IRpcChannelBuffer *_pRpcChannelBuffer,
|
||||||
|
PRPC_MESSAGE _pRpcMessage,
|
||||||
|
DWORD *_pdwStubPhase);
|
||||||
|
|
||||||
|
|
||||||
|
/* [call_as] */ HRESULT STDMETHODCALLTYPE ICommandWithParameters_RemoteSetParameterInfo_Proxy(
|
||||||
|
ICommandWithParameters * This,
|
||||||
|
/* [in] */ DB_UPARAMS cParams,
|
||||||
|
/* [size_is][unique][in] */ const DB_UPARAMS *rgParamOrdinals,
|
||||||
|
/* [size_is][unique][in] */ const DBPARAMBINDINFO *rgParamBindInfo,
|
||||||
|
/* [out] */ IErrorInfo **ppErrorInfoRem);
|
||||||
|
|
||||||
|
|
||||||
|
void __RPC_STUB ICommandWithParameters_RemoteSetParameterInfo_Stub(
|
||||||
|
IRpcStubBuffer *This,
|
||||||
|
IRpcChannelBuffer *_pRpcChannelBuffer,
|
||||||
|
PRPC_MESSAGE _pRpcMessage,
|
||||||
|
DWORD *_pdwStubPhase);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __ICommandWithParameters_INTERFACE_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
/* interface __MIDL_itf_sqlncli_0000_0001 */
|
||||||
|
/* [local] */
|
||||||
|
|
||||||
|
typedef DWORD DBASYNCHOP;
|
||||||
|
|
||||||
|
typedef DWORD DBASYNCHPHASE;
|
||||||
|
|
||||||
|
#endif // This is already defined in oledb.h
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Variant Access macros, similar to ole automation.
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
#define V_SS_VT(X) ((X)->vt)
|
||||||
|
#define V_SS_UNION(X, Y) ((X)->Y)
|
||||||
|
|
||||||
|
#define V_SS_UI1(X) V_SS_UNION(X, bTinyIntVal)
|
||||||
|
#define V_SS_I2(X) V_SS_UNION(X, sShortIntVal)
|
||||||
|
#define V_SS_I4(X) V_SS_UNION(X, lIntVal)
|
||||||
|
#define V_SS_I8(X) V_SS_UNION(X, llBigIntVal)
|
||||||
|
|
||||||
|
#define V_SS_R4(X) V_SS_UNION(X, fltRealVal)
|
||||||
|
#define V_SS_R8(X) V_SS_UNION(X, dblFloatVal)
|
||||||
|
#define V_SS_UI4(X) V_SS_UNION(X, ulVal)
|
||||||
|
|
||||||
|
#define V_SS_MONEY(X) V_SS_UNION(X, cyMoneyVal)
|
||||||
|
#define V_SS_SMALLMONEY(X) V_SS_UNION(X, cyMoneyVal)
|
||||||
|
|
||||||
|
#define V_SS_WSTRING(X) V_SS_UNION(X, NCharVal)
|
||||||
|
#define V_SS_WVARSTRING(X) V_SS_UNION(X, NCharVal)
|
||||||
|
|
||||||
|
#define V_SS_STRING(X) V_SS_UNION(X, CharVal)
|
||||||
|
#define V_SS_VARSTRING(X) V_SS_UNION(X, CharVal)
|
||||||
|
|
||||||
|
#define V_SS_BIT(X) V_SS_UNION(X, fBitVal)
|
||||||
|
#define V_SS_GUID(X) V_SS_UNION(X, rgbGuidVal)
|
||||||
|
|
||||||
|
#define V_SS_NUMERIC(X) V_SS_UNION(X, numNumericVal)
|
||||||
|
#define V_SS_DECIMAL(X) V_SS_UNION(X, numNumericVal)
|
||||||
|
|
||||||
|
#define V_SS_BINARY(X) V_SS_UNION(X, BinaryVal)
|
||||||
|
#define V_SS_VARBINARY(X) V_SS_UNION(X, BinaryVal)
|
||||||
|
|
||||||
|
#define V_SS_DATETIME(X) V_SS_UNION(X, tsDateTimeVal)
|
||||||
|
#define V_SS_SMALLDATETIME(X) V_SS_UNION(X, tsDateTimeVal)
|
||||||
|
|
||||||
|
#define V_SS_UNKNOWN(X) V_SS_UNION(X, UnknownType)
|
||||||
|
|
||||||
|
//Text and image types.
|
||||||
|
#define V_SS_IMAGE(X) V_SS_UNION(X, ImageVal)
|
||||||
|
#define V_SS_TEXT(X) V_SS_UNION(X, TextVal)
|
||||||
|
#define V_SS_NTEXT(X) V_SS_UNION(X, NTextVal)
|
||||||
|
|
||||||
|
//Microsoft SQL Server 2008 datetime.
|
||||||
|
#define V_SS_DATE(X) V_SS_UNION(X, dDateVal)
|
||||||
|
#define V_SS_TIME2(X) V_SS_UNION(X, Time2Val)
|
||||||
|
#define V_SS_DATETIME2(X) V_SS_UNION(X, DateTimeVal)
|
||||||
|
#define V_SS_DATETIMEOFFSET(X) V_SS_UNION(X, DateTimeOffsetVal)
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// define SQL Server specific types.
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
typedef enum DBTYPEENUM EOledbTypes;
|
||||||
|
#define DBTYPE_XML ((EOledbTypes) 141) // introduced in SQL 2005
|
||||||
|
#define DBTYPE_TABLE ((EOledbTypes) 143) // introduced in SQL 2008
|
||||||
|
#define DBTYPE_DBTIME2 ((EOledbTypes) 145) // introduced in SQL 2008
|
||||||
|
#define DBTYPE_DBTIMESTAMPOFFSET ((EOledbTypes) 146) // introduced in SQL 2008
|
||||||
|
#ifdef _SQLOLEDB_H_
|
||||||
|
#undef DBTYPE_SQLVARIANT
|
||||||
|
#endif //_SQLOLEDB_H_
|
||||||
|
#define DBTYPE_SQLVARIANT ((EOledbTypes) 144) // introduced in MDAC 2.5
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _SQLOLEDB_H_
|
||||||
|
enum SQLVARENUM
|
||||||
|
{
|
||||||
|
VT_SS_EMPTY = DBTYPE_EMPTY,
|
||||||
|
VT_SS_NULL = DBTYPE_NULL,
|
||||||
|
VT_SS_UI1 = DBTYPE_UI1,
|
||||||
|
VT_SS_I2 = DBTYPE_I2,
|
||||||
|
VT_SS_I4 = DBTYPE_I4,
|
||||||
|
VT_SS_I8 = DBTYPE_I8,
|
||||||
|
|
||||||
|
//Floats
|
||||||
|
VT_SS_R4 = DBTYPE_R4,
|
||||||
|
VT_SS_R8 = DBTYPE_R8,
|
||||||
|
|
||||||
|
//Money
|
||||||
|
VT_SS_MONEY = DBTYPE_CY,
|
||||||
|
VT_SS_SMALLMONEY = 200,
|
||||||
|
|
||||||
|
//Strings
|
||||||
|
VT_SS_WSTRING = 201,
|
||||||
|
VT_SS_WVARSTRING = 202,
|
||||||
|
|
||||||
|
VT_SS_STRING = 203,
|
||||||
|
VT_SS_VARSTRING = 204,
|
||||||
|
|
||||||
|
//Bit
|
||||||
|
VT_SS_BIT = DBTYPE_BOOL,
|
||||||
|
|
||||||
|
//Guid
|
||||||
|
VT_SS_GUID = DBTYPE_GUID,
|
||||||
|
|
||||||
|
//Exact precision
|
||||||
|
VT_SS_NUMERIC = DBTYPE_NUMERIC,
|
||||||
|
VT_SS_DECIMAL = 205,
|
||||||
|
|
||||||
|
//Datetime
|
||||||
|
VT_SS_DATETIME = DBTYPE_DBTIMESTAMP,
|
||||||
|
VT_SS_SMALLDATETIME =206,
|
||||||
|
|
||||||
|
//Binary
|
||||||
|
VT_SS_BINARY =207,
|
||||||
|
VT_SS_VARBINARY = 208,
|
||||||
|
//Future
|
||||||
|
VT_SS_UNKNOWN = 209,
|
||||||
|
|
||||||
|
//Additional datetime
|
||||||
|
VT_SS_DATE = DBTYPE_DBDATE,
|
||||||
|
VT_SS_TIME2 = DBTYPE_DBTIME2,
|
||||||
|
VT_SS_DATETIME2 = 212,
|
||||||
|
VT_SS_DATETIMEOFFSET = DBTYPE_DBTIMESTAMPOFFSET,
|
||||||
|
};
|
||||||
|
typedef unsigned short SSVARTYPE;
|
||||||
|
|
||||||
|
|
||||||
|
enum DBPARAMFLAGSENUM_SS_100
|
||||||
|
{ DBPARAMFLAGS_SS_ISVARIABLESCALE = 0x40000000
|
||||||
|
} ;
|
||||||
|
enum DBCOLUMNFLAGSENUM_SS_100
|
||||||
|
{ DBCOLUMNFLAGS_SS_ISVARIABLESCALE = 0x40000000,
|
||||||
|
DBCOLUMNFLAGS_SS_ISCOLUMNSET = 0x80000000
|
||||||
|
} ;
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Class Factory Interface used to initialize pointer to UMS.
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
extern RPC_IF_HANDLE __MIDL_itf_sqlncli_0000_0001_v0_0_c_ifspec;
|
||||||
|
extern RPC_IF_HANDLE __MIDL_itf_sqlncli_0000_0001_v0_0_s_ifspec;
|
||||||
|
|
||||||
|
#ifndef __IUMSInitialize_INTERFACE_DEFINED__
|
||||||
|
#define __IUMSInitialize_INTERFACE_DEFINED__
|
||||||
|
|
||||||
|
/* interface IUMSInitialize */
|
||||||
|
/* [unique][uuid][object][local] */
|
||||||
|
|
||||||
|
|
||||||
|
EXTERN_C const IID IID_IUMSInitialize;
|
||||||
|
|
||||||
|
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||||
|
|
||||||
|
MIDL_INTERFACE("5cf4ca14-ef21-11d0-97e7-00c04fc2ad98")
|
||||||
|
IUMSInitialize : public IUnknown
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE Initialize(
|
||||||
|
/* [in] */ void *pUMS) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#else /* C style interface */
|
||||||
|
|
||||||
|
typedef struct IUMSInitializeVtbl
|
||||||
|
{
|
||||||
|
BEGIN_INTERFACE
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||||
|
IUMSInitialize * This,
|
||||||
|
/* [in] */ REFIID riid,
|
||||||
|
/* [iid_is][out] */
|
||||||
|
__RPC__deref_out void **ppvObject);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||||
|
IUMSInitialize * This);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||||
|
IUMSInitialize * This);
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *Initialize )(
|
||||||
|
IUMSInitialize * This,
|
||||||
|
/* [in] */ void *pUMS);
|
||||||
|
|
||||||
|
END_INTERFACE
|
||||||
|
} IUMSInitializeVtbl;
|
||||||
|
|
||||||
|
interface IUMSInitialize
|
||||||
|
{
|
||||||
|
CONST_VTBL struct IUMSInitializeVtbl *lpVtbl;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef COBJMACROS
|
||||||
|
|
||||||
|
|
||||||
|
#define IUMSInitialize_QueryInterface(This,riid,ppvObject) \
|
||||||
|
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
|
||||||
|
|
||||||
|
#define IUMSInitialize_AddRef(This) \
|
||||||
|
( (This)->lpVtbl -> AddRef(This) )
|
||||||
|
|
||||||
|
#define IUMSInitialize_Release(This) \
|
||||||
|
( (This)->lpVtbl -> Release(This) )
|
||||||
|
|
||||||
|
|
||||||
|
#define IUMSInitialize_Initialize(This,pUMS) \
|
||||||
|
( (This)->lpVtbl -> Initialize(This,pUMS) )
|
||||||
|
|
||||||
|
#endif /* COBJMACROS */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* C style interface */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __IUMSInitialize_INTERFACE_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
/* interface __MIDL_itf_sqlncli_0000_0002 */
|
||||||
|
/* [local] */
|
||||||
|
|
||||||
|
|
||||||
|
// the structure returned by ISQLServerErrorInfo::GetSQLServerInfo
|
||||||
|
typedef struct tagSSErrorInfo
|
||||||
|
{
|
||||||
|
LPOLESTR pwszMessage;
|
||||||
|
LPOLESTR pwszServer;
|
||||||
|
LPOLESTR pwszProcedure;
|
||||||
|
LONG lNative;
|
||||||
|
BYTE bState;
|
||||||
|
BYTE bClass;
|
||||||
|
WORD wLineNumber;
|
||||||
|
} SSERRORINFO;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern RPC_IF_HANDLE __MIDL_itf_sqlncli_0000_0002_v0_0_c_ifspec;
|
||||||
|
extern RPC_IF_HANDLE __MIDL_itf_sqlncli_0000_0002_v0_0_s_ifspec;
|
||||||
|
|
||||||
|
#ifndef __ISQLServerErrorInfo_INTERFACE_DEFINED__
|
||||||
|
#define __ISQLServerErrorInfo_INTERFACE_DEFINED__
|
||||||
|
|
||||||
|
/* interface ISQLServerErrorInfo */
|
||||||
|
/* [unique][uuid][object][local] */
|
||||||
|
|
||||||
|
|
||||||
|
EXTERN_C const IID IID_ISQLServerErrorInfo;
|
||||||
|
|
||||||
|
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||||
|
|
||||||
|
MIDL_INTERFACE("5CF4CA12-EF21-11d0-97E7-00C04FC2AD98")
|
||||||
|
ISQLServerErrorInfo : public IUnknown
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE GetErrorInfo(
|
||||||
|
/* [out] */ SSERRORINFO **ppErrorInfo,
|
||||||
|
/* [out] */ OLECHAR **ppStringsBuffer) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#else /* C style interface */
|
||||||
|
|
||||||
|
typedef struct ISQLServerErrorInfoVtbl
|
||||||
|
{
|
||||||
|
BEGIN_INTERFACE
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||||
|
ISQLServerErrorInfo * This,
|
||||||
|
/* [in] */ REFIID riid,
|
||||||
|
/* [iid_is][out] */
|
||||||
|
__RPC__deref_out void **ppvObject);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||||
|
ISQLServerErrorInfo * This);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||||
|
ISQLServerErrorInfo * This);
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *GetErrorInfo )(
|
||||||
|
ISQLServerErrorInfo * This,
|
||||||
|
/* [out] */ SSERRORINFO **ppErrorInfo,
|
||||||
|
/* [out] */ OLECHAR **ppStringsBuffer);
|
||||||
|
|
||||||
|
END_INTERFACE
|
||||||
|
} ISQLServerErrorInfoVtbl;
|
||||||
|
|
||||||
|
interface ISQLServerErrorInfo
|
||||||
|
{
|
||||||
|
CONST_VTBL struct ISQLServerErrorInfoVtbl *lpVtbl;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef COBJMACROS
|
||||||
|
|
||||||
|
|
||||||
|
#define ISQLServerErrorInfo_QueryInterface(This,riid,ppvObject) \
|
||||||
|
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
|
||||||
|
|
||||||
|
#define ISQLServerErrorInfo_AddRef(This) \
|
||||||
|
( (This)->lpVtbl -> AddRef(This) )
|
||||||
|
|
||||||
|
#define ISQLServerErrorInfo_Release(This) \
|
||||||
|
( (This)->lpVtbl -> Release(This) )
|
||||||
|
|
||||||
|
|
||||||
|
#define ISQLServerErrorInfo_GetErrorInfo(This,ppErrorInfo,ppStringsBuffer) \
|
||||||
|
( (This)->lpVtbl -> GetErrorInfo(This,ppErrorInfo,ppStringsBuffer) )
|
||||||
|
|
||||||
|
#endif /* COBJMACROS */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* C style interface */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __ISQLServerErrorInfo_INTERFACE_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __IRowsetFastLoad_INTERFACE_DEFINED__
|
||||||
|
#define __IRowsetFastLoad_INTERFACE_DEFINED__
|
||||||
|
|
||||||
|
/* interface IRowsetFastLoad */
|
||||||
|
/* [unique][uuid][object][local] */
|
||||||
|
|
||||||
|
|
||||||
|
EXTERN_C const IID IID_IRowsetFastLoad;
|
||||||
|
|
||||||
|
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||||
|
|
||||||
|
MIDL_INTERFACE("5CF4CA13-EF21-11d0-97E7-00C04FC2AD98")
|
||||||
|
IRowsetFastLoad : public IUnknown
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE InsertRow(
|
||||||
|
/* [in] */ HACCESSOR hAccessor,
|
||||||
|
/* [in] */ void *pData) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE Commit(
|
||||||
|
/* [in] */ BOOL fDone) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#else /* C style interface */
|
||||||
|
|
||||||
|
typedef struct IRowsetFastLoadVtbl
|
||||||
|
{
|
||||||
|
BEGIN_INTERFACE
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||||
|
IRowsetFastLoad * This,
|
||||||
|
/* [in] */ REFIID riid,
|
||||||
|
/* [iid_is][out] */
|
||||||
|
__RPC__deref_out void **ppvObject);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||||
|
IRowsetFastLoad * This);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||||
|
IRowsetFastLoad * This);
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *InsertRow )(
|
||||||
|
IRowsetFastLoad * This,
|
||||||
|
/* [in] */ HACCESSOR hAccessor,
|
||||||
|
/* [in] */ void *pData);
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *Commit )(
|
||||||
|
IRowsetFastLoad * This,
|
||||||
|
/* [in] */ BOOL fDone);
|
||||||
|
|
||||||
|
END_INTERFACE
|
||||||
|
} IRowsetFastLoadVtbl;
|
||||||
|
|
||||||
|
interface IRowsetFastLoad
|
||||||
|
{
|
||||||
|
CONST_VTBL struct IRowsetFastLoadVtbl *lpVtbl;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef COBJMACROS
|
||||||
|
|
||||||
|
|
||||||
|
#define IRowsetFastLoad_QueryInterface(This,riid,ppvObject) \
|
||||||
|
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
|
||||||
|
|
||||||
|
#define IRowsetFastLoad_AddRef(This) \
|
||||||
|
( (This)->lpVtbl -> AddRef(This) )
|
||||||
|
|
||||||
|
#define IRowsetFastLoad_Release(This) \
|
||||||
|
( (This)->lpVtbl -> Release(This) )
|
||||||
|
|
||||||
|
|
||||||
|
#define IRowsetFastLoad_InsertRow(This,hAccessor,pData) \
|
||||||
|
( (This)->lpVtbl -> InsertRow(This,hAccessor,pData) )
|
||||||
|
|
||||||
|
#define IRowsetFastLoad_Commit(This,fDone) \
|
||||||
|
( (This)->lpVtbl -> Commit(This,fDone) )
|
||||||
|
|
||||||
|
#endif /* COBJMACROS */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* C style interface */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __IRowsetFastLoad_INTERFACE_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
/* interface __MIDL_itf_sqlncli_0000_0004 */
|
||||||
|
/* [local] */
|
||||||
|
|
||||||
|
#include <pshpack8.h> // 8-byte structure packing
|
||||||
|
|
||||||
|
typedef struct tagDBTIME2
|
||||||
|
{
|
||||||
|
USHORT hour;
|
||||||
|
USHORT minute;
|
||||||
|
USHORT second;
|
||||||
|
ULONG fraction;
|
||||||
|
} DBTIME2;
|
||||||
|
|
||||||
|
typedef struct tagDBTIMESTAMPOFFSET
|
||||||
|
{
|
||||||
|
SHORT year;
|
||||||
|
USHORT month;
|
||||||
|
USHORT day;
|
||||||
|
USHORT hour;
|
||||||
|
USHORT minute;
|
||||||
|
USHORT second;
|
||||||
|
ULONG fraction;
|
||||||
|
SHORT timezone_hour;
|
||||||
|
SHORT timezone_minute;
|
||||||
|
} DBTIMESTAMPOFFSET;
|
||||||
|
|
||||||
|
#include <poppack.h> // restore original structure packing
|
||||||
|
|
||||||
|
struct SSVARIANT
|
||||||
|
{
|
||||||
|
SSVARTYPE vt;
|
||||||
|
DWORD dwReserved1;
|
||||||
|
DWORD dwReserved2;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
BYTE bTinyIntVal;
|
||||||
|
SHORT sShortIntVal;
|
||||||
|
LONG lIntVal;
|
||||||
|
LONGLONG llBigIntVal;
|
||||||
|
FLOAT fltRealVal;
|
||||||
|
DOUBLE dblFloatVal;
|
||||||
|
CY cyMoneyVal;
|
||||||
|
VARIANT_BOOL fBitVal;
|
||||||
|
BYTE rgbGuidVal[ 16 ];
|
||||||
|
DB_NUMERIC numNumericVal;
|
||||||
|
DBDATE dDateVal;
|
||||||
|
DBTIMESTAMP tsDateTimeVal;
|
||||||
|
struct _Time2Val
|
||||||
|
{
|
||||||
|
DBTIME2 tTime2Val;
|
||||||
|
BYTE bScale;
|
||||||
|
} Time2Val;
|
||||||
|
struct _DateTimeVal
|
||||||
|
{
|
||||||
|
DBTIMESTAMP tsDateTimeVal;
|
||||||
|
BYTE bScale;
|
||||||
|
} DateTimeVal;
|
||||||
|
struct _DateTimeOffsetVal
|
||||||
|
{
|
||||||
|
DBTIMESTAMPOFFSET tsoDateTimeOffsetVal;
|
||||||
|
BYTE bScale;
|
||||||
|
} DateTimeOffsetVal;
|
||||||
|
struct _NCharVal
|
||||||
|
{
|
||||||
|
SHORT sActualLength;
|
||||||
|
SHORT sMaxLength;
|
||||||
|
WCHAR *pwchNCharVal;
|
||||||
|
BYTE rgbReserved[ 5 ];
|
||||||
|
DWORD dwReserved;
|
||||||
|
WCHAR *pwchReserved;
|
||||||
|
} NCharVal;
|
||||||
|
struct _CharVal
|
||||||
|
{
|
||||||
|
SHORT sActualLength;
|
||||||
|
SHORT sMaxLength;
|
||||||
|
CHAR *pchCharVal;
|
||||||
|
BYTE rgbReserved[ 5 ];
|
||||||
|
DWORD dwReserved;
|
||||||
|
WCHAR *pwchReserved;
|
||||||
|
} CharVal;
|
||||||
|
struct _BinaryVal
|
||||||
|
{
|
||||||
|
SHORT sActualLength;
|
||||||
|
SHORT sMaxLength;
|
||||||
|
BYTE *prgbBinaryVal;
|
||||||
|
DWORD dwReserved;
|
||||||
|
} BinaryVal;
|
||||||
|
struct _UnknownType
|
||||||
|
{
|
||||||
|
DWORD dwActualLength;
|
||||||
|
BYTE rgMetadata[ 16 ];
|
||||||
|
BYTE *pUnknownData;
|
||||||
|
} UnknownType;
|
||||||
|
struct _BLOBType
|
||||||
|
{
|
||||||
|
DBOBJECT dbobj;
|
||||||
|
IUnknown *pUnk;
|
||||||
|
} BLOBType;
|
||||||
|
} ;
|
||||||
|
} ;
|
||||||
|
typedef DWORD LOCKMODE;
|
||||||
|
|
||||||
|
|
||||||
|
enum LOCKMODEENUM
|
||||||
|
{ LOCKMODE_INVALID = 0,
|
||||||
|
LOCKMODE_EXCLUSIVE = ( LOCKMODE_INVALID + 1 ) ,
|
||||||
|
LOCKMODE_SHARED = ( LOCKMODE_EXCLUSIVE + 1 )
|
||||||
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
extern RPC_IF_HANDLE __MIDL_itf_sqlncli_0000_0004_v0_0_c_ifspec;
|
||||||
|
extern RPC_IF_HANDLE __MIDL_itf_sqlncli_0000_0004_v0_0_s_ifspec;
|
||||||
|
|
||||||
|
#ifndef __ISchemaLock_INTERFACE_DEFINED__
|
||||||
|
#define __ISchemaLock_INTERFACE_DEFINED__
|
||||||
|
|
||||||
|
/* interface ISchemaLock */
|
||||||
|
/* [unique][uuid][object][local] */
|
||||||
|
|
||||||
|
|
||||||
|
EXTERN_C const IID IID_ISchemaLock;
|
||||||
|
|
||||||
|
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||||
|
|
||||||
|
MIDL_INTERFACE("4C2389FB-2511-11d4-B258-00C04F7971CE")
|
||||||
|
ISchemaLock : public IUnknown
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE GetSchemaLock(
|
||||||
|
/* [in] */ DBID *pTableID,
|
||||||
|
/* [in] */ LOCKMODE lmMode,
|
||||||
|
/* [out] */ HANDLE *phLockHandle,
|
||||||
|
/* [out] */ ULONGLONG *pTableVersion) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE ReleaseSchemaLock(
|
||||||
|
/* [in] */ HANDLE hLockHandle) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#else /* C style interface */
|
||||||
|
|
||||||
|
typedef struct ISchemaLockVtbl
|
||||||
|
{
|
||||||
|
BEGIN_INTERFACE
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||||
|
ISchemaLock * This,
|
||||||
|
/* [in] */ REFIID riid,
|
||||||
|
/* [iid_is][out] */
|
||||||
|
__RPC__deref_out void **ppvObject);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||||
|
ISchemaLock * This);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||||
|
ISchemaLock * This);
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *GetSchemaLock )(
|
||||||
|
ISchemaLock * This,
|
||||||
|
/* [in] */ DBID *pTableID,
|
||||||
|
/* [in] */ LOCKMODE lmMode,
|
||||||
|
/* [out] */ HANDLE *phLockHandle,
|
||||||
|
/* [out] */ ULONGLONG *pTableVersion);
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *ReleaseSchemaLock )(
|
||||||
|
ISchemaLock * This,
|
||||||
|
/* [in] */ HANDLE hLockHandle);
|
||||||
|
|
||||||
|
END_INTERFACE
|
||||||
|
} ISchemaLockVtbl;
|
||||||
|
|
||||||
|
interface ISchemaLock
|
||||||
|
{
|
||||||
|
CONST_VTBL struct ISchemaLockVtbl *lpVtbl;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef COBJMACROS
|
||||||
|
|
||||||
|
|
||||||
|
#define ISchemaLock_QueryInterface(This,riid,ppvObject) \
|
||||||
|
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
|
||||||
|
|
||||||
|
#define ISchemaLock_AddRef(This) \
|
||||||
|
( (This)->lpVtbl -> AddRef(This) )
|
||||||
|
|
||||||
|
#define ISchemaLock_Release(This) \
|
||||||
|
( (This)->lpVtbl -> Release(This) )
|
||||||
|
|
||||||
|
|
||||||
|
#define ISchemaLock_GetSchemaLock(This,pTableID,lmMode,phLockHandle,pTableVersion) \
|
||||||
|
( (This)->lpVtbl -> GetSchemaLock(This,pTableID,lmMode,phLockHandle,pTableVersion) )
|
||||||
|
|
||||||
|
#define ISchemaLock_ReleaseSchemaLock(This,hLockHandle) \
|
||||||
|
( (This)->lpVtbl -> ReleaseSchemaLock(This,hLockHandle) )
|
||||||
|
|
||||||
|
#endif /* COBJMACROS */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* C style interface */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __ISchemaLock_INTERFACE_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __IBCPSession_INTERFACE_DEFINED__
|
||||||
|
#define __IBCPSession_INTERFACE_DEFINED__
|
||||||
|
|
||||||
|
/* interface IBCPSession */
|
||||||
|
/* [unique][uuid][object][local] */
|
||||||
|
|
||||||
|
|
||||||
|
EXTERN_C const IID IID_IBCPSession;
|
||||||
|
|
||||||
|
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||||
|
|
||||||
|
MIDL_INTERFACE("88352D80-42D1-42f0-A170-AB0F8B45B939")
|
||||||
|
IBCPSession : public IUnknown
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE BCPColFmt(
|
||||||
|
/* [in] */ DBORDINAL idxUserDataCol,
|
||||||
|
/* [in] */ int eUserDataType,
|
||||||
|
/* [in] */ int cbIndicator,
|
||||||
|
/* [in] */ int cbUserData,
|
||||||
|
/* [size_is][in] */ BYTE *pbUserDataTerm,
|
||||||
|
/* [in] */ int cbUserDataTerm,
|
||||||
|
/* [in] */ DBORDINAL idxServerCol) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE BCPColumns(
|
||||||
|
/* [in] */ DBCOUNTITEM nColumns) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE BCPControl(
|
||||||
|
/* [in] */ int eOption,
|
||||||
|
/* [in] */ void *iValue) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE BCPDone( void) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE BCPExec(
|
||||||
|
/* [out] */ DBROWCOUNT *pRowsCopied) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE BCPInit(
|
||||||
|
/* [string][in] */ const wchar_t *pwszTable,
|
||||||
|
/* [string][in] */ const wchar_t *pwszDataFile,
|
||||||
|
/* [string][in] */ const wchar_t *pwszErrorFile,
|
||||||
|
/* [in] */ int eDirection) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE BCPReadFmt(
|
||||||
|
/* [string][in] */ const wchar_t *pwszFormatFile) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE BCPWriteFmt(
|
||||||
|
/* [string][in] */ const wchar_t *pwszFormatFile) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#else /* C style interface */
|
||||||
|
|
||||||
|
typedef struct IBCPSessionVtbl
|
||||||
|
{
|
||||||
|
BEGIN_INTERFACE
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||||
|
IBCPSession * This,
|
||||||
|
/* [in] */ REFIID riid,
|
||||||
|
/* [iid_is][out] */
|
||||||
|
__RPC__deref_out void **ppvObject);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||||
|
IBCPSession * This);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||||
|
IBCPSession * This);
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *BCPColFmt )(
|
||||||
|
IBCPSession * This,
|
||||||
|
/* [in] */ DBORDINAL idxUserDataCol,
|
||||||
|
/* [in] */ int eUserDataType,
|
||||||
|
/* [in] */ int cbIndicator,
|
||||||
|
/* [in] */ int cbUserData,
|
||||||
|
/* [size_is][in] */ BYTE *pbUserDataTerm,
|
||||||
|
/* [in] */ int cbUserDataTerm,
|
||||||
|
/* [in] */ DBORDINAL idxServerCol);
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *BCPColumns )(
|
||||||
|
IBCPSession * This,
|
||||||
|
/* [in] */ DBCOUNTITEM nColumns);
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *BCPControl )(
|
||||||
|
IBCPSession * This,
|
||||||
|
/* [in] */ int eOption,
|
||||||
|
/* [in] */ void *iValue);
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *BCPDone )(
|
||||||
|
IBCPSession * This);
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *BCPExec )(
|
||||||
|
IBCPSession * This,
|
||||||
|
/* [out] */ DBROWCOUNT *pRowsCopied);
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *BCPInit )(
|
||||||
|
IBCPSession * This,
|
||||||
|
/* [string][in] */ const wchar_t *pwszTable,
|
||||||
|
/* [string][in] */ const wchar_t *pwszDataFile,
|
||||||
|
/* [string][in] */ const wchar_t *pwszErrorFile,
|
||||||
|
/* [in] */ int eDirection);
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *BCPReadFmt )(
|
||||||
|
IBCPSession * This,
|
||||||
|
/* [string][in] */ const wchar_t *pwszFormatFile);
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *BCPWriteFmt )(
|
||||||
|
IBCPSession * This,
|
||||||
|
/* [string][in] */ const wchar_t *pwszFormatFile);
|
||||||
|
|
||||||
|
END_INTERFACE
|
||||||
|
} IBCPSessionVtbl;
|
||||||
|
|
||||||
|
interface IBCPSession
|
||||||
|
{
|
||||||
|
CONST_VTBL struct IBCPSessionVtbl *lpVtbl;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef COBJMACROS
|
||||||
|
|
||||||
|
|
||||||
|
#define IBCPSession_QueryInterface(This,riid,ppvObject) \
|
||||||
|
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
|
||||||
|
|
||||||
|
#define IBCPSession_AddRef(This) \
|
||||||
|
( (This)->lpVtbl -> AddRef(This) )
|
||||||
|
|
||||||
|
#define IBCPSession_Release(This) \
|
||||||
|
( (This)->lpVtbl -> Release(This) )
|
||||||
|
|
||||||
|
|
||||||
|
#define IBCPSession_BCPColFmt(This,idxUserDataCol,eUserDataType,cbIndicator,cbUserData,pbUserDataTerm,cbUserDataTerm,idxServerCol) \
|
||||||
|
( (This)->lpVtbl -> BCPColFmt(This,idxUserDataCol,eUserDataType,cbIndicator,cbUserData,pbUserDataTerm,cbUserDataTerm,idxServerCol) )
|
||||||
|
|
||||||
|
#define IBCPSession_BCPColumns(This,nColumns) \
|
||||||
|
( (This)->lpVtbl -> BCPColumns(This,nColumns) )
|
||||||
|
|
||||||
|
#define IBCPSession_BCPControl(This,eOption,iValue) \
|
||||||
|
( (This)->lpVtbl -> BCPControl(This,eOption,iValue) )
|
||||||
|
|
||||||
|
#define IBCPSession_BCPDone(This) \
|
||||||
|
( (This)->lpVtbl -> BCPDone(This) )
|
||||||
|
|
||||||
|
#define IBCPSession_BCPExec(This,pRowsCopied) \
|
||||||
|
( (This)->lpVtbl -> BCPExec(This,pRowsCopied) )
|
||||||
|
|
||||||
|
#define IBCPSession_BCPInit(This,pwszTable,pwszDataFile,pwszErrorFile,eDirection) \
|
||||||
|
( (This)->lpVtbl -> BCPInit(This,pwszTable,pwszDataFile,pwszErrorFile,eDirection) )
|
||||||
|
|
||||||
|
#define IBCPSession_BCPReadFmt(This,pwszFormatFile) \
|
||||||
|
( (This)->lpVtbl -> BCPReadFmt(This,pwszFormatFile) )
|
||||||
|
|
||||||
|
#define IBCPSession_BCPWriteFmt(This,pwszFormatFile) \
|
||||||
|
( (This)->lpVtbl -> BCPWriteFmt(This,pwszFormatFile) )
|
||||||
|
|
||||||
|
#endif /* COBJMACROS */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* C style interface */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __IBCPSession_INTERFACE_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
/* interface __MIDL_itf_sqlncli_0000_0006 */
|
||||||
|
/* [local] */
|
||||||
|
|
||||||
|
|
||||||
|
#endif //_SQLOLEDB_H_
|
||||||
|
|
||||||
|
#define ISOLATIONLEVEL_SNAPSHOT ((ISOLATIONLEVEL)(0x01000000)) // Changes made in other transactions can not be seen.
|
||||||
|
|
||||||
|
#define DBPROPVAL_TI_SNAPSHOT 0x01000000L
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern RPC_IF_HANDLE __MIDL_itf_sqlncli_0000_0006_v0_0_c_ifspec;
|
||||||
|
extern RPC_IF_HANDLE __MIDL_itf_sqlncli_0000_0006_v0_0_s_ifspec;
|
||||||
|
|
||||||
|
#ifndef __ISSAbort_INTERFACE_DEFINED__
|
||||||
|
#define __ISSAbort_INTERFACE_DEFINED__
|
||||||
|
|
||||||
|
/* interface ISSAbort */
|
||||||
|
/* [unique][uuid][object][local] */
|
||||||
|
|
||||||
|
|
||||||
|
EXTERN_C const IID IID_ISSAbort;
|
||||||
|
|
||||||
|
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||||
|
|
||||||
|
MIDL_INTERFACE("5CF4CA15-EF21-11d0-97E7-00C04FC2AD98")
|
||||||
|
ISSAbort : public IUnknown
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE Abort( void) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#else /* C style interface */
|
||||||
|
|
||||||
|
typedef struct ISSAbortVtbl
|
||||||
|
{
|
||||||
|
BEGIN_INTERFACE
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||||
|
ISSAbort * This,
|
||||||
|
/* [in] */ REFIID riid,
|
||||||
|
/* [iid_is][out] */
|
||||||
|
__RPC__deref_out void **ppvObject);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||||
|
ISSAbort * This);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||||
|
ISSAbort * This);
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *Abort )(
|
||||||
|
ISSAbort * This);
|
||||||
|
|
||||||
|
END_INTERFACE
|
||||||
|
} ISSAbortVtbl;
|
||||||
|
|
||||||
|
interface ISSAbort
|
||||||
|
{
|
||||||
|
CONST_VTBL struct ISSAbortVtbl *lpVtbl;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef COBJMACROS
|
||||||
|
|
||||||
|
|
||||||
|
#define ISSAbort_QueryInterface(This,riid,ppvObject) \
|
||||||
|
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
|
||||||
|
|
||||||
|
#define ISSAbort_AddRef(This) \
|
||||||
|
( (This)->lpVtbl -> AddRef(This) )
|
||||||
|
|
||||||
|
#define ISSAbort_Release(This) \
|
||||||
|
( (This)->lpVtbl -> Release(This) )
|
||||||
|
|
||||||
|
|
||||||
|
#define ISSAbort_Abort(This) \
|
||||||
|
( (This)->lpVtbl -> Abort(This) )
|
||||||
|
|
||||||
|
#endif /* COBJMACROS */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* C style interface */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __ISSAbort_INTERFACE_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
/* interface __MIDL_itf_sqlncli_0000_0007 */
|
||||||
|
/* [local] */
|
||||||
|
|
||||||
|
|
||||||
|
enum DBBINDFLAGENUM90
|
||||||
|
{ DBBINDFLAG_OBJECT = 0x2
|
||||||
|
} ;
|
||||||
|
|
||||||
|
enum SSACCESSORFLAGS
|
||||||
|
{ SSACCESSOR_ROWDATA = 0x100
|
||||||
|
} ;
|
||||||
|
|
||||||
|
enum DBPROPFLAGSENUM90
|
||||||
|
{ DBPROPFLAGS_PARAMETER = 0x10000
|
||||||
|
} ;
|
||||||
|
typedef struct tagSSPARAMPROPS
|
||||||
|
{
|
||||||
|
DBORDINAL iOrdinal;
|
||||||
|
ULONG cPropertySets;
|
||||||
|
DBPROPSET *rgPropertySets;
|
||||||
|
} SSPARAMPROPS;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern RPC_IF_HANDLE __MIDL_itf_sqlncli_0000_0007_v0_0_c_ifspec;
|
||||||
|
extern RPC_IF_HANDLE __MIDL_itf_sqlncli_0000_0007_v0_0_s_ifspec;
|
||||||
|
|
||||||
|
#ifndef __ISSCommandWithParameters_INTERFACE_DEFINED__
|
||||||
|
#define __ISSCommandWithParameters_INTERFACE_DEFINED__
|
||||||
|
|
||||||
|
/* interface ISSCommandWithParameters */
|
||||||
|
/* [unique][uuid][object][local] */
|
||||||
|
|
||||||
|
|
||||||
|
EXTERN_C const IID IID_ISSCommandWithParameters;
|
||||||
|
|
||||||
|
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||||
|
|
||||||
|
MIDL_INTERFACE("eec30162-6087-467c-b995-7c523ce96561")
|
||||||
|
ISSCommandWithParameters : public ICommandWithParameters
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetParameterProperties(
|
||||||
|
/* [out][in] */ DB_UPARAMS *pcParams,
|
||||||
|
/* [size_is][size_is][out] */ SSPARAMPROPS **prgParamProperties) = 0;
|
||||||
|
|
||||||
|
virtual /* [local] */ HRESULT STDMETHODCALLTYPE SetParameterProperties(
|
||||||
|
/* [in] */ DB_UPARAMS cParams,
|
||||||
|
/* [size_is][unique][in] */ SSPARAMPROPS rgParamProperties[ ]) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#else /* C style interface */
|
||||||
|
|
||||||
|
typedef struct ISSCommandWithParametersVtbl
|
||||||
|
{
|
||||||
|
BEGIN_INTERFACE
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||||
|
ISSCommandWithParameters * This,
|
||||||
|
/* [in] */ REFIID riid,
|
||||||
|
/* [iid_is][out] */
|
||||||
|
__RPC__deref_out void **ppvObject);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||||
|
ISSCommandWithParameters * This);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||||
|
ISSCommandWithParameters * This);
|
||||||
|
|
||||||
|
/* [local] */ HRESULT ( STDMETHODCALLTYPE *GetParameterInfo )(
|
||||||
|
ISSCommandWithParameters * This,
|
||||||
|
/* [out][in] */ DB_UPARAMS *pcParams,
|
||||||
|
/* [size_is][size_is][out] */ DBPARAMINFO **prgParamInfo,
|
||||||
|
/* [out] */ OLECHAR **ppNamesBuffer);
|
||||||
|
|
||||||
|
/* [local] */ HRESULT ( STDMETHODCALLTYPE *MapParameterNames )(
|
||||||
|
ISSCommandWithParameters * This,
|
||||||
|
/* [in] */ DB_UPARAMS cParamNames,
|
||||||
|
/* [size_is][in] */ const OLECHAR *rgParamNames[ ],
|
||||||
|
/* [size_is][out] */ DB_LPARAMS rgParamOrdinals[ ]);
|
||||||
|
|
||||||
|
/* [local] */ HRESULT ( STDMETHODCALLTYPE *SetParameterInfo )(
|
||||||
|
ISSCommandWithParameters * This,
|
||||||
|
/* [in] */ DB_UPARAMS cParams,
|
||||||
|
/* [size_is][unique][in] */ const DB_UPARAMS rgParamOrdinals[ ],
|
||||||
|
/* [size_is][unique][in] */ const DBPARAMBINDINFO rgParamBindInfo[ ]);
|
||||||
|
|
||||||
|
/* [local] */ HRESULT ( STDMETHODCALLTYPE *GetParameterProperties )(
|
||||||
|
ISSCommandWithParameters * This,
|
||||||
|
/* [out][in] */ DB_UPARAMS *pcParams,
|
||||||
|
/* [size_is][size_is][out] */ SSPARAMPROPS **prgParamProperties);
|
||||||
|
|
||||||
|
/* [local] */ HRESULT ( STDMETHODCALLTYPE *SetParameterProperties )(
|
||||||
|
ISSCommandWithParameters * This,
|
||||||
|
/* [in] */ DB_UPARAMS cParams,
|
||||||
|
/* [size_is][unique][in] */ SSPARAMPROPS rgParamProperties[ ]);
|
||||||
|
|
||||||
|
END_INTERFACE
|
||||||
|
} ISSCommandWithParametersVtbl;
|
||||||
|
|
||||||
|
interface ISSCommandWithParameters
|
||||||
|
{
|
||||||
|
CONST_VTBL struct ISSCommandWithParametersVtbl *lpVtbl;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef COBJMACROS
|
||||||
|
|
||||||
|
|
||||||
|
#define ISSCommandWithParameters_QueryInterface(This,riid,ppvObject) \
|
||||||
|
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
|
||||||
|
|
||||||
|
#define ISSCommandWithParameters_AddRef(This) \
|
||||||
|
( (This)->lpVtbl -> AddRef(This) )
|
||||||
|
|
||||||
|
#define ISSCommandWithParameters_Release(This) \
|
||||||
|
( (This)->lpVtbl -> Release(This) )
|
||||||
|
|
||||||
|
|
||||||
|
#define ISSCommandWithParameters_GetParameterInfo(This,pcParams,prgParamInfo,ppNamesBuffer) \
|
||||||
|
( (This)->lpVtbl -> GetParameterInfo(This,pcParams,prgParamInfo,ppNamesBuffer) )
|
||||||
|
|
||||||
|
#define ISSCommandWithParameters_MapParameterNames(This,cParamNames,rgParamNames,rgParamOrdinals) \
|
||||||
|
( (This)->lpVtbl -> MapParameterNames(This,cParamNames,rgParamNames,rgParamOrdinals) )
|
||||||
|
|
||||||
|
#define ISSCommandWithParameters_SetParameterInfo(This,cParams,rgParamOrdinals,rgParamBindInfo) \
|
||||||
|
( (This)->lpVtbl -> SetParameterInfo(This,cParams,rgParamOrdinals,rgParamBindInfo) )
|
||||||
|
|
||||||
|
|
||||||
|
#define ISSCommandWithParameters_GetParameterProperties(This,pcParams,prgParamProperties) \
|
||||||
|
( (This)->lpVtbl -> GetParameterProperties(This,pcParams,prgParamProperties) )
|
||||||
|
|
||||||
|
#define ISSCommandWithParameters_SetParameterProperties(This,cParams,rgParamProperties) \
|
||||||
|
( (This)->lpVtbl -> SetParameterProperties(This,cParams,rgParamProperties) )
|
||||||
|
|
||||||
|
#endif /* COBJMACROS */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* C style interface */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __ISSCommandWithParameters_INTERFACE_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __IDBAsynchStatus_INTERFACE_DEFINED__
|
||||||
|
#define __IDBAsynchStatus_INTERFACE_DEFINED__
|
||||||
|
|
||||||
|
/* interface IDBAsynchStatus */
|
||||||
|
/* [unique][uuid][object][local] */
|
||||||
|
|
||||||
|
|
||||||
|
EXTERN_C const IID IID_IDBAsynchStatus;
|
||||||
|
|
||||||
|
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||||
|
|
||||||
|
MIDL_INTERFACE("0c733a95-2a1c-11ce-ade5-00aa0044773d")
|
||||||
|
IDBAsynchStatus : public IUnknown
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual /* [local] */ HRESULT STDMETHODCALLTYPE Abort(
|
||||||
|
/* [in] */ HCHAPTER hChapter,
|
||||||
|
/* [in] */ DBASYNCHOP eOperation) = 0;
|
||||||
|
|
||||||
|
virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetStatus(
|
||||||
|
/* [in] */ HCHAPTER hChapter,
|
||||||
|
/* [in] */ DBASYNCHOP eOperation,
|
||||||
|
/* [out] */ DBCOUNTITEM *pulProgress,
|
||||||
|
/* [out] */ DBCOUNTITEM *pulProgressMax,
|
||||||
|
/* [out] */ DBASYNCHPHASE *peAsynchPhase,
|
||||||
|
/* [out] */ LPOLESTR *ppwszStatusText) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#else /* C style interface */
|
||||||
|
|
||||||
|
typedef struct IDBAsynchStatusVtbl
|
||||||
|
{
|
||||||
|
BEGIN_INTERFACE
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||||
|
IDBAsynchStatus * This,
|
||||||
|
/* [in] */ REFIID riid,
|
||||||
|
/* [iid_is][out] */
|
||||||
|
__RPC__deref_out void **ppvObject);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||||
|
IDBAsynchStatus * This);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||||
|
IDBAsynchStatus * This);
|
||||||
|
|
||||||
|
/* [local] */ HRESULT ( STDMETHODCALLTYPE *Abort )(
|
||||||
|
IDBAsynchStatus * This,
|
||||||
|
/* [in] */ HCHAPTER hChapter,
|
||||||
|
/* [in] */ DBASYNCHOP eOperation);
|
||||||
|
|
||||||
|
/* [local] */ HRESULT ( STDMETHODCALLTYPE *GetStatus )(
|
||||||
|
IDBAsynchStatus * This,
|
||||||
|
/* [in] */ HCHAPTER hChapter,
|
||||||
|
/* [in] */ DBASYNCHOP eOperation,
|
||||||
|
/* [out] */ DBCOUNTITEM *pulProgress,
|
||||||
|
/* [out] */ DBCOUNTITEM *pulProgressMax,
|
||||||
|
/* [out] */ DBASYNCHPHASE *peAsynchPhase,
|
||||||
|
/* [out] */ LPOLESTR *ppwszStatusText);
|
||||||
|
|
||||||
|
END_INTERFACE
|
||||||
|
} IDBAsynchStatusVtbl;
|
||||||
|
|
||||||
|
interface IDBAsynchStatus
|
||||||
|
{
|
||||||
|
CONST_VTBL struct IDBAsynchStatusVtbl *lpVtbl;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef COBJMACROS
|
||||||
|
|
||||||
|
|
||||||
|
#define IDBAsynchStatus_QueryInterface(This,riid,ppvObject) \
|
||||||
|
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
|
||||||
|
|
||||||
|
#define IDBAsynchStatus_AddRef(This) \
|
||||||
|
( (This)->lpVtbl -> AddRef(This) )
|
||||||
|
|
||||||
|
#define IDBAsynchStatus_Release(This) \
|
||||||
|
( (This)->lpVtbl -> Release(This) )
|
||||||
|
|
||||||
|
|
||||||
|
#define IDBAsynchStatus_Abort(This,hChapter,eOperation) \
|
||||||
|
( (This)->lpVtbl -> Abort(This,hChapter,eOperation) )
|
||||||
|
|
||||||
|
#define IDBAsynchStatus_GetStatus(This,hChapter,eOperation,pulProgress,pulProgressMax,peAsynchPhase,ppwszStatusText) \
|
||||||
|
( (This)->lpVtbl -> GetStatus(This,hChapter,eOperation,pulProgress,pulProgressMax,peAsynchPhase,ppwszStatusText) )
|
||||||
|
|
||||||
|
#endif /* COBJMACROS */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* C style interface */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* [call_as] */ HRESULT STDMETHODCALLTYPE IDBAsynchStatus_RemoteAbort_Proxy(
|
||||||
|
IDBAsynchStatus * This,
|
||||||
|
/* [in] */ HCHAPTER hChapter,
|
||||||
|
/* [in] */ DBASYNCHOP eOperation,
|
||||||
|
/* [out] */ IErrorInfo **ppErrorInfoRem);
|
||||||
|
|
||||||
|
|
||||||
|
void __RPC_STUB IDBAsynchStatus_RemoteAbort_Stub(
|
||||||
|
IRpcStubBuffer *This,
|
||||||
|
IRpcChannelBuffer *_pRpcChannelBuffer,
|
||||||
|
PRPC_MESSAGE _pRpcMessage,
|
||||||
|
DWORD *_pdwStubPhase);
|
||||||
|
|
||||||
|
|
||||||
|
/* [call_as] */ HRESULT STDMETHODCALLTYPE IDBAsynchStatus_RemoteGetStatus_Proxy(
|
||||||
|
IDBAsynchStatus * This,
|
||||||
|
/* [in] */ HCHAPTER hChapter,
|
||||||
|
/* [in] */ DBASYNCHOP eOperation,
|
||||||
|
/* [unique][out][in] */ DBCOUNTITEM *pulProgress,
|
||||||
|
/* [unique][out][in] */ DBCOUNTITEM *pulProgressMax,
|
||||||
|
/* [unique][out][in] */ DBASYNCHPHASE *peAsynchPhase,
|
||||||
|
/* [unique][out][in] */ LPOLESTR *ppwszStatusText,
|
||||||
|
/* [out] */ IErrorInfo **ppErrorInfoRem);
|
||||||
|
|
||||||
|
|
||||||
|
void __RPC_STUB IDBAsynchStatus_RemoteGetStatus_Stub(
|
||||||
|
IRpcStubBuffer *This,
|
||||||
|
IRpcChannelBuffer *_pRpcChannelBuffer,
|
||||||
|
PRPC_MESSAGE _pRpcMessage,
|
||||||
|
DWORD *_pdwStubPhase);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __IDBAsynchStatus_INTERFACE_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __ISSAsynchStatus_INTERFACE_DEFINED__
|
||||||
|
#define __ISSAsynchStatus_INTERFACE_DEFINED__
|
||||||
|
|
||||||
|
/* interface ISSAsynchStatus */
|
||||||
|
/* [unique][uuid][object][local] */
|
||||||
|
|
||||||
|
|
||||||
|
EXTERN_C const IID IID_ISSAsynchStatus;
|
||||||
|
|
||||||
|
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||||
|
|
||||||
|
MIDL_INTERFACE("1FF1F743-8BB0-4c00-ACC4-C10E43B08FC1")
|
||||||
|
ISSAsynchStatus : public IDBAsynchStatus
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual /* [local] */ HRESULT STDMETHODCALLTYPE WaitForAsynchCompletion(
|
||||||
|
/* [in] */ DWORD dwMillisecTimeOut) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#else /* C style interface */
|
||||||
|
|
||||||
|
typedef struct ISSAsynchStatusVtbl
|
||||||
|
{
|
||||||
|
BEGIN_INTERFACE
|
||||||
|
|
||||||
|
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||||
|
ISSAsynchStatus * This,
|
||||||
|
/* [in] */ REFIID riid,
|
||||||
|
/* [iid_is][out] */
|
||||||
|
__RPC__deref_out void **ppvObject);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||||
|
ISSAsynchStatus * This);
|
||||||
|
|
||||||
|
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||||
|
ISSAsynchStatus * This);
|
||||||
|
|
||||||
|
/* [local] */ HRESULT ( STDMETHODCALLTYPE *Abort )(
|
||||||
|
ISSAsynchStatus * This,
|
||||||
|
/* [in] */ HCHAPTER hChapter,
|
||||||
|
/* [in] */ DBASYNCHOP eOperation);
|
||||||
|
|
||||||
|
/* [local] */ HRESULT ( STDMETHODCALLTYPE *GetStatus )(
|
||||||
|
ISSAsynchStatus * This,
|
||||||
|
/* [in] */ HCHAPTER hChapter,
|
||||||
|
/* [in] */ DBASYNCHOP eOperation,
|
||||||
|
/* [out] */ DBCOUNTITEM *pulProgress,
|
||||||
|
/* [out] */ DBCOUNTITEM *pulProgressMax,
|
||||||
|
/* [out] */ DBASYNCHPHASE *peAsynchPhase,
|
||||||
|
/* [out] */ LPOLESTR *ppwszStatusText);
|
||||||
|
|
||||||
|
/* [local] */ HRESULT ( STDMETHODCALLTYPE *WaitForAsynchCompletion )(
|
||||||
|
ISSAsynchStatus * This,
|
||||||
|
/* [in] */ DWORD dwMillisecTimeOut);
|
||||||
|
|
||||||
|
END_INTERFACE
|
||||||
|
} ISSAsynchStatusVtbl;
|
||||||
|
|
||||||
|
interface ISSAsynchStatus
|
||||||
|
{
|
||||||
|
CONST_VTBL struct ISSAsynchStatusVtbl *lpVtbl;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef COBJMACROS
|
||||||
|
|
||||||
|
|
||||||
|
#define ISSAsynchStatus_QueryInterface(This,riid,ppvObject) \
|
||||||
|
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
|
||||||
|
|
||||||
|
#define ISSAsynchStatus_AddRef(This) \
|
||||||
|
( (This)->lpVtbl -> AddRef(This) )
|
||||||
|
|
||||||
|
#define ISSAsynchStatus_Release(This) \
|
||||||
|
( (This)->lpVtbl -> Release(This) )
|
||||||
|
|
||||||
|
|
||||||
|
#define ISSAsynchStatus_Abort(This,hChapter,eOperation) \
|
||||||
|
( (This)->lpVtbl -> Abort(This,hChapter,eOperation) )
|
||||||
|
|
||||||
|
#define ISSAsynchStatus_GetStatus(This,hChapter,eOperation,pulProgress,pulProgressMax,peAsynchPhase,ppwszStatusText) \
|
||||||
|
( (This)->lpVtbl -> GetStatus(This,hChapter,eOperation,pulProgress,pulProgressMax,peAsynchPhase,ppwszStatusText) )
|
||||||
|
|
||||||
|
|
||||||
|
#define ISSAsynchStatus_WaitForAsynchCompletion(This,dwMillisecTimeOut) \
|
||||||
|
( (This)->lpVtbl -> WaitForAsynchCompletion(This,dwMillisecTimeOut) )
|
||||||
|
|
||||||
|
#endif /* COBJMACROS */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* C style interface */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __ISSAsynchStatus_INTERFACE_DEFINED__ */
|
||||||
|
|
||||||
|
|
||||||
|
/* interface __MIDL_itf_sqlncli_0000_0010 */
|
||||||
|
/* [local] */
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Values for STATUS bitmask for DBSCHEMA_TABLES & DBSCHEMA_TABLES_INFO
|
||||||
|
#define TABLE_HAS_UPDATE_INSTEAD_OF_TRIGGER 0x00000001 //table has IOT defined
|
||||||
|
#define TABLE_HAS_DELETE_INSTEAD_OF_TRIGGER 0x00000002 //table has IOT defined
|
||||||
|
#define TABLE_HAS_INSERT_INSTEAD_OF_TRIGGER 0x00000004 //table has IOT defined
|
||||||
|
#define TABLE_HAS_AFTER_UPDATE_TRIGGER 0x00000008 //table has update trigger
|
||||||
|
#define TABLE_HAS_AFTER_DELETE_TRIGGER 0x00000010 //table has delete trigger
|
||||||
|
#define TABLE_HAS_AFTER_INSERT_TRIGGER 0x00000020 //table has insert trigger
|
||||||
|
#define TABLE_HAS_CASCADE_UPDATE 0x00000040 //table has cascade update
|
||||||
|
#define TABLE_HAS_CASCADE_DELETE 0x00000080 //table has cascade delete
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// PropIds for DBPROP_INIT_GENERALTIMEOUT
|
||||||
|
#if (OLEDBVER >= 0x0210)
|
||||||
|
#define DBPROP_INIT_GENERALTIMEOUT 0x11cL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// PropIds for DBPROPSET_SQLSERVERDATASOURCE
|
||||||
|
#define SSPROP_ENABLEFASTLOAD 2
|
||||||
|
#define SSPROP_ENABLEBULKCOPY 3
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// PropIds for DBPROPSET_SQLSERVERDATASOURCEINFO
|
||||||
|
#define SSPROP_UNICODELCID 2
|
||||||
|
#define SSPROP_UNICODECOMPARISONSTYLE 3
|
||||||
|
#define SSPROP_COLUMNLEVELCOLLATION 4
|
||||||
|
#define SSPROP_CHARACTERSET 5
|
||||||
|
#define SSPROP_SORTORDER 6
|
||||||
|
#define SSPROP_CURRENTCOLLATION 7
|
||||||
|
#define SSPROP_INTEGRATEDAUTHENTICATIONMETHOD 8
|
||||||
|
#define SSPROP_MUTUALLYAUTHENTICATED 9
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// PropIds for DBPROPSET_SQLSERVERDBINIT
|
||||||
|
#define SSPROP_INIT_CURRENTLANGUAGE 4
|
||||||
|
#define SSPROP_INIT_NETWORKADDRESS 5
|
||||||
|
#define SSPROP_INIT_NETWORKLIBRARY 6
|
||||||
|
#define SSPROP_INIT_USEPROCFORPREP 7
|
||||||
|
#define SSPROP_INIT_AUTOTRANSLATE 8
|
||||||
|
#define SSPROP_INIT_PACKETSIZE 9
|
||||||
|
#define SSPROP_INIT_APPNAME 10
|
||||||
|
#define SSPROP_INIT_WSID 11
|
||||||
|
#define SSPROP_INIT_FILENAME 12
|
||||||
|
#define SSPROP_INIT_ENCRYPT 13
|
||||||
|
#define SSPROP_AUTH_REPL_SERVER_NAME 14
|
||||||
|
#define SSPROP_INIT_TAGCOLUMNCOLLATION 15
|
||||||
|
#define SSPROP_INIT_MARSCONNECTION 16
|
||||||
|
#define SSPROP_INIT_FAILOVERPARTNER 18
|
||||||
|
#define SSPROP_AUTH_OLD_PASSWORD 19
|
||||||
|
#define SSPROP_INIT_DATATYPECOMPATIBILITY 20
|
||||||
|
#define SSPROP_INIT_TRUST_SERVER_CERTIFICATE 21
|
||||||
|
#define SSPROP_INIT_SERVERSPN 22
|
||||||
|
#define SSPROP_INIT_FAILOVERPARTNERSPN 23
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Values for SSPROP_INIT_USEPROCFORPREP
|
||||||
|
#define SSPROPVAL_USEPROCFORPREP_OFF 0
|
||||||
|
#define SSPROPVAL_USEPROCFORPREP_ON 1
|
||||||
|
#define SSPROPVAL_USEPROCFORPREP_ON_DROP 2
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Values for SSPROP_INIT_DATATYPECOMPATIBILITY
|
||||||
|
#define SSPROPVAL_DATATYPECOMPATIBILITY_SQL2000 80
|
||||||
|
#define SSPROPVAL_DATATYPECOMPATIBILITY_DEFAULT 0
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// PropIds for DBPROPSET_SQLSERVERSESSION
|
||||||
|
#define SSPROP_QUOTEDCATALOGNAMES 2
|
||||||
|
#define SSPROP_ALLOWNATIVEVARIANT 3
|
||||||
|
#define SSPROP_SQLXMLXPROGID 4
|
||||||
|
#define SSPROP_ASYNCH_BULKCOPY 5
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// PropIds for DBPROPSET_SQLSERVERROWSET
|
||||||
|
#define SSPROP_MAXBLOBLENGTH 8
|
||||||
|
#define SSPROP_FASTLOADOPTIONS 9
|
||||||
|
#define SSPROP_FASTLOADKEEPNULLS 10
|
||||||
|
#define SSPROP_FASTLOADKEEPIDENTITY 11
|
||||||
|
#define SSPROP_CURSORAUTOFETCH 12
|
||||||
|
#define SSPROP_DEFERPREPARE 13
|
||||||
|
#define SSPROP_IRowsetFastLoad 14
|
||||||
|
#define SSPROP_QP_NOTIFICATION_TIMEOUT 17
|
||||||
|
#define SSPROP_QP_NOTIFICATION_MSGTEXT 18
|
||||||
|
#define SSPROP_QP_NOTIFICATION_OPTIONS 19
|
||||||
|
#define SSPROP_NOCOUNT_STATUS 20
|
||||||
|
#define SSPROP_COMPUTE_ID 21
|
||||||
|
#define SSPROP_COLUMN_ID 22
|
||||||
|
#define SSPROP_COMPUTE_BYLIST 23
|
||||||
|
#define SSPROP_ISSAsynchStatus 24
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Values for SSPROP_QP_NOTIFICATION_TIMEOUT
|
||||||
|
#define SSPROPVAL_DEFAULT_NOTIFICATION_TIMEOUT 432000 /* in sec */
|
||||||
|
#define SSPROPVAL_MAX_NOTIFICATION_TIMEOUT 0x7FFFFFFF /* in sec */
|
||||||
|
#define MAX_NOTIFICATION_LEN 2000 /* NVARCHAR [2000] for both ID & DELIVERY_QUEUE */
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// PropIds for DBPROPSET_SQLSERVERCOLUMN
|
||||||
|
#define SSPROP_COL_COLLATIONNAME 14
|
||||||
|
#define SSPROP_COL_UDT_CATALOGNAME 31
|
||||||
|
#define SSPROP_COL_UDT_SCHEMANAME 32
|
||||||
|
#define SSPROP_COL_UDT_NAME 33
|
||||||
|
#define SSPROP_COL_XML_SCHEMACOLLECTION_CATALOGNAME 34
|
||||||
|
#define SSPROP_COL_XML_SCHEMACOLLECTION_SCHEMANAME 35
|
||||||
|
#define SSPROP_COL_XML_SCHEMACOLLECTIONNAME 36
|
||||||
|
#define SSPROP_COL_COMPUTED 37
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// PropIds for DBPROPSET_SQLSERVERSTREAM
|
||||||
|
#define SSPROP_STREAM_XMLROOT 19
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// PropIds for DBPROPSET_SQLSERVERPARAMETER
|
||||||
|
#define SSPROP_PARAM_XML_SCHEMACOLLECTION_CATALOGNAME 24
|
||||||
|
#define SSPROP_PARAM_XML_SCHEMACOLLECTION_SCHEMANAME 25
|
||||||
|
#define SSPROP_PARAM_XML_SCHEMACOLLECTIONNAME 26
|
||||||
|
#define SSPROP_PARAM_UDT_CATALOGNAME 27
|
||||||
|
#define SSPROP_PARAM_UDT_SCHEMANAME 28
|
||||||
|
#define SSPROP_PARAM_UDT_NAME 29
|
||||||
|
#define SSPROP_PARAM_TYPE_CATALOGNAME 38
|
||||||
|
#define SSPROP_PARAM_TYPE_SCHEMANAME 39
|
||||||
|
#define SSPROP_PARAM_TYPE_TYPENAME 40
|
||||||
|
#define SSPROP_PARAM_TABLE_DEFAULT_COLUMNS 41
|
||||||
|
#define SSPROP_PARAM_TABLE_COLUMN_SORT_ORDER 42
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// PropIds for DBPROPSET_SQLSERVERINDEX
|
||||||
|
#define SSPROP_INDEX_XML 1
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
#define BCP_TYPE_DEFAULT 0x00
|
||||||
|
#define BCP_TYPE_SQLTEXT 0x23
|
||||||
|
#define BCP_TYPE_SQLVARBINARY 0x25
|
||||||
|
#define BCP_TYPE_SQLINTN 0x26
|
||||||
|
#define BCP_TYPE_SQLVARCHAR 0x27
|
||||||
|
#define BCP_TYPE_SQLBINARY 0x2d
|
||||||
|
#define BCP_TYPE_SQLIMAGE 0x22
|
||||||
|
#define BCP_TYPE_SQLCHARACTER 0x2f
|
||||||
|
#define BCP_TYPE_SQLINT1 0x30
|
||||||
|
#define BCP_TYPE_SQLBIT 0x32
|
||||||
|
#define BCP_TYPE_SQLINT2 0x34
|
||||||
|
#define BCP_TYPE_SQLINT4 0x38
|
||||||
|
#define BCP_TYPE_SQLMONEY 0x3c
|
||||||
|
#define BCP_TYPE_SQLDATETIME 0x3d
|
||||||
|
#define BCP_TYPE_SQLFLT8 0x3e
|
||||||
|
#define BCP_TYPE_SQLFLTN 0x6d
|
||||||
|
#define BCP_TYPE_SQLMONEYN 0x6e
|
||||||
|
#define BCP_TYPE_SQLDATETIMN 0x6f
|
||||||
|
#define BCP_TYPE_SQLFLT4 0x3b
|
||||||
|
#define BCP_TYPE_SQLMONEY4 0x7a
|
||||||
|
#define BCP_TYPE_SQLDATETIM4 0x3a
|
||||||
|
#define BCP_TYPE_SQLDECIMAL 0x6a
|
||||||
|
#define BCP_TYPE_SQLNUMERIC 0x6c
|
||||||
|
#define BCP_TYPE_SQLUNIQUEID 0x24
|
||||||
|
#define BCP_TYPE_SQLBIGCHAR 0xaf
|
||||||
|
#define BCP_TYPE_SQLBIGVARCHAR 0xa7
|
||||||
|
#define BCP_TYPE_SQLBIGBINARY 0xad
|
||||||
|
#define BCP_TYPE_SQLBIGVARBINARY 0xa5
|
||||||
|
#define BCP_TYPE_SQLBITN 0x68
|
||||||
|
#define BCP_TYPE_SQLNCHAR 0xef
|
||||||
|
#define BCP_TYPE_SQLNVARCHAR 0xe7
|
||||||
|
#define BCP_TYPE_SQLNTEXT 0x63
|
||||||
|
#define BCP_TYPE_SQLDECIMALN 0x6a
|
||||||
|
#define BCP_TYPE_SQLNUMERICN 0x6c
|
||||||
|
#define BCP_TYPE_SQLINT8 0x7f
|
||||||
|
#define BCP_TYPE_SQLVARIANT 0x62
|
||||||
|
#define BCP_TYPE_SQLUDT 0xf0
|
||||||
|
#define BCP_TYPE_SQLXML 0xf1
|
||||||
|
#define BCP_TYPE_SQLDATE 0x28
|
||||||
|
#define BCP_TYPE_SQLTIME 0x29
|
||||||
|
#define BCP_TYPE_SQLDATETIME2 0x2a
|
||||||
|
#define BCP_TYPE_SQLDATETIMEOFFSET 0x2b
|
||||||
|
|
||||||
|
#define BCP_DIRECTION_IN 1
|
||||||
|
#define BCP_DIRECTION_OUT 2
|
||||||
|
|
||||||
|
#define BCP_OPTION_MAXERRS 1
|
||||||
|
#define BCP_OPTION_FIRST 2
|
||||||
|
#define BCP_OPTION_LAST 3
|
||||||
|
#define BCP_OPTION_BATCH 4
|
||||||
|
#define BCP_OPTION_KEEPNULLS 5
|
||||||
|
#define BCP_OPTION_ABORT 6
|
||||||
|
#define BCP_OPTION_KEEPIDENTITY 8
|
||||||
|
#define BCP_OPTION_HINTSA 10
|
||||||
|
#define BCP_OPTION_HINTSW 11
|
||||||
|
#define BCP_OPTION_FILECP 12
|
||||||
|
#define BCP_OPTION_UNICODEFILE 13
|
||||||
|
#define BCP_OPTION_TEXTFILE 14
|
||||||
|
#define BCP_OPTION_FILEFMT 15
|
||||||
|
#define BCP_OPTION_FMTXML 16
|
||||||
|
#define BCP_OPTION_FIRSTEX 17
|
||||||
|
#define BCP_OPTION_LASTEX 18
|
||||||
|
#define BCP_OPTION_ROWCOUNT 19
|
||||||
|
|
||||||
|
#define BCP_FILECP_ACP 0
|
||||||
|
#define BCP_FILECP_OEMCP 1
|
||||||
|
#define BCP_FILECP_RAW (-1)
|
||||||
|
|
||||||
|
#ifdef UNICODE
|
||||||
|
#define BCP_OPTION_HINTS BCP_OPTION_HINTSW
|
||||||
|
#else
|
||||||
|
#define BCP_OPTION_HINTS BCP_OPTION_HINTSA
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define BCP_PREFIX_DEFAULT (-10)
|
||||||
|
|
||||||
|
#define BCP_LENGTH_NULL (-1)
|
||||||
|
#define BCP_LENGTH_VARIABLE (-10)
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Provider-specific Class Ids
|
||||||
|
//
|
||||||
|
|
||||||
|
#if SQLNCLI_VER >= 1000
|
||||||
|
|
||||||
|
extern const GUID OLEDBDECLSPEC CLSID_SQLNCLI10 = {0x8F4A6B68L,0x4F36,0x4e3c,{0xBE,0x81,0xBC,0x7C,0xA4,0xE9,0xC4,0x5C}};
|
||||||
|
extern const GUID OLEDBDECLSPEC CLSID_SQLNCLI10_ERROR = {0x53F9C3BCL,0x275F,0x4FA5,{0xB3,0xE6,0x25,0xED,0xCD,0x51,0x20,0x23}};
|
||||||
|
extern const GUID OLEDBDECLSPEC CLSID_SQLNCLI10_ENUMERATOR = {0x91E4F2A5L,0x1B07,0x45f6,{0x86,0xBF,0x92,0x03,0xC7,0xC7,0x2B,0xE3}};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const GUID OLEDBDECLSPEC CLSID_SQLNCLI = {0x85ecafccL,0xbdd9,0x4b03,{0x97,0xa8,0xfa,0x65,0xcb,0xe3,0x85,0x9b}};
|
||||||
|
extern const GUID OLEDBDECLSPEC CLSID_SQLNCLI_ERROR = {0xe8bc0a7aL,0xea71,0x4263,{0x8c,0xda,0x94,0xf3,0x88,0xb8,0xed,0x10}};
|
||||||
|
extern const GUID OLEDBDECLSPEC CLSID_SQLNCLI_ENUMERATOR = {0x4898ad37L,0xfe05,0x42df,{0x92,0xf9,0xe8,0x57,0xdd,0xfe,0xe7,0x30}};
|
||||||
|
extern const GUID OLEDBDECLSPEC CLSID_ROWSET_TVP = {0xc7ef28d5L,0x7bee,0x443f,{0x86,0xda,0xe3,0x98,0x4f,0xcd,0x4d,0xf9}};
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Provider-specific Interface Ids
|
||||||
|
//
|
||||||
|
#ifndef _SQLOLEDB_H_
|
||||||
|
extern const GUID OLEDBDECLSPEC IID_ISQLServerErrorInfo = {0x5cf4ca12,0xef21,0x11d0,{0x97,0xe7,0x0,0xc0,0x4f,0xc2,0xad,0x98}};
|
||||||
|
extern const GUID OLEDBDECLSPEC IID_IRowsetFastLoad = {0x5cf4ca13,0xef21,0x11d0,{0x97,0xe7,0x0,0xc0,0x4f,0xc2,0xad,0x98}};
|
||||||
|
extern const GUID OLEDBDECLSPEC IID_IUMSInitialize = {0x5cf4ca14,0xef21,0x11d0,{0x97,0xe7,0x0,0xc0,0x4f,0xc2,0xad,0x98}};
|
||||||
|
extern const GUID OLEDBDECLSPEC IID_ISchemaLock = {0x4c2389fb,0x2511,0x11d4,{0xb2,0x58,0x0,0xc0,0x4f,0x79,0x71,0xce}};
|
||||||
|
extern const GUID OLEDBDECLSPEC IID_ISQLXMLHelper = {0xd22a7678L,0xf860,0x40cd,{0xa5,0x67,0x15,0x63,0xde,0xb4,0x6d,0x49}};
|
||||||
|
#endif //_SQLOLEDB_H_
|
||||||
|
extern const GUID OLEDBDECLSPEC IID_ISSAbort = {0x5cf4ca15,0xef21,0x11d0,{0x97,0xe7,0x0,0xc0,0x4f,0xc2,0xad,0x98}};
|
||||||
|
extern const GUID OLEDBDECLSPEC IID_IBCPSession = {0x88352D80,0x42D1,0x42f0,{0xA1,0x70,0xAB,0x0F,0x8B,0x45,0xB9,0x39}};
|
||||||
|
extern const GUID OLEDBDECLSPEC IID_ISSCommandWithParameters = {0xeec30162,0x6087,0x467c,{0xb9,0x95,0x7c,0x52,0x3c,0xe9,0x65,0x61}};
|
||||||
|
extern const GUID OLEDBDECLSPEC IID_ISSAsynchStatus = {0x1FF1F743,0x8BB0, 0x4c00,{0xAC,0xC4,0xC1,0x0E,0x43,0xB0,0x8F,0xC1}};
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Provider-specific schema rowsets
|
||||||
|
//
|
||||||
|
#ifndef _SQLOLEDB_H_
|
||||||
|
extern const GUID OLEDBDECLSPEC DBSCHEMA_LINKEDSERVERS = {0x9093caf4,0x2eac,0x11d1,{0x98,0x9,0x0,0xc0,0x4f,0xc2,0xad,0x98}};
|
||||||
|
#endif //_SQLOLEDB_H_
|
||||||
|
extern const GUID OLEDBDECLSPEC DBSCHEMA_SQL_ASSEMBLIES = {0x7c1112c8, 0xc2d3, 0x4f6e, {0x94, 0x9a, 0x98, 0x3d, 0x38, 0xa5, 0x8f, 0x46}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBSCHEMA_SQL_ASSEMBLY_DEPENDENCIES = {0xcb0f837b, 0x974c, 0x41b8, {0x90, 0x9d, 0x64, 0x9c, 0xaf, 0x45, 0xad, 0x2f}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBSCHEMA_SQL_USER_TYPES = {0xf1198bd8, 0xa424, 0x4ea3, {0x8d, 0x4c, 0x60, 0x7e, 0xee, 0x2b, 0xab, 0x60}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBSCHEMA_XML_COLLECTIONS = {0x56bfad8c, 0x6e8f, 0x480d, {0x91, 0xde, 0x35, 0x16, 0xd9, 0x9a, 0x5d, 0x10}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBSCHEMA_SQL_TABLE_TYPES = {0x4e26cde7, 0xaaa4, 0x41ed, {0x93, 0xdd, 0x37, 0x6e, 0x6d, 0x40, 0x9c, 0x17}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBSCHEMA_SQL_TABLE_TYPE_PRIMARY_KEYS = {0x9738faea, 0x31e8, 0x4f63, {0xae, 0xd, 0x61, 0x33, 0x16, 0x41, 0x8c, 0xdd}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBSCHEMA_SQL_TABLE_TYPE_COLUMNS = {0xa663d94b, 0xddf7, 0x4a7f, {0xa5, 0x37, 0xd6, 0x1f, 0x12, 0x36, 0x5d, 0x7c}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBSCHEMA_COLUMNS_EXTENDED = {0x66462f01, 0x633a, 0x44d9, {0xb0, 0xd0, 0xfe, 0x66, 0xf2, 0x1a, 0x0d, 0x24}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBSCHEMA_SPARSE_COLUMN_SET = {0x31a4837c, 0xf9ff, 0x405f, {0x89, 0x82, 0x02, 0x19, 0xaa, 0xaa, 0x4a, 0x12}};
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CRESTRICTIONS_DBSCHEMA_LINKEDSERVERS
|
||||||
|
#define CRESTRICTIONS_DBSCHEMA_LINKEDSERVERS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CRESTRICTIONS_DBSCHEMA_ASSEMBLIES
|
||||||
|
#define CRESTRICTIONS_DBSCHEMA_SQL_ASSEMBLIES 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CRESTRICTIONS_DBSCHEMA_ASSEMBLY_DEPENDENCIES
|
||||||
|
#define CRESTRICTIONS_DBSCHEMA_SQL_ASSEMBLY_DEPENDENCIES 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CRESTRICTIONS_DBSCHEMA_USER_TYPES
|
||||||
|
#define CRESTRICTIONS_DBSCHEMA_SQL_USER_TYPES 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CRESTRICTIONS_DBSCHEMA_XML_COLLECTIONS
|
||||||
|
#define CRESTRICTIONS_DBSCHEMA_XML_COLLECTIONS 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CRESTRICTIONS_DBSCHEMA_SQL_TABLE_TYPES
|
||||||
|
#define CRESTRICTIONS_DBSCHEMA_SQL_TABLE_TYPES 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CRESTRICTIONS_DBSCHEMA_SQL_TABLE_TYPE_PRIMARY_KEYS
|
||||||
|
#define CRESTRICTIONS_DBSCHEMA_SQL_TABLE_TYPE_PRIMARY_KEYS 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CRESTRICTIONS_DBSCHEMA_SQL_TABLE_TYPE_COLUMNS
|
||||||
|
#define CRESTRICTIONS_DBSCHEMA_SQL_TABLE_TYPE_COLUMNS 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CRESTRICTIONS_DBSCHEMA_COLUMNS_EXTENDED
|
||||||
|
#define CRESTRICTIONS_DBSCHEMA_COLUMNS_EXTENDED 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CRESTRICTIONS_DBSCHEMA_SPARSE_COLUMN_SET
|
||||||
|
#define CRESTRICTIONS_DBSCHEMA_SPARSE_COLUMN_SET 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Provider-specific property sets
|
||||||
|
//
|
||||||
|
#ifndef _SQLOLEDB_H_
|
||||||
|
extern const GUID OLEDBDECLSPEC DBPROPSET_SQLSERVERDATASOURCE = {0x28efaee4,0x2d2c,0x11d1,{0x98,0x7,0x0,0xc0,0x4f,0xc2,0xad,0x98}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBPROPSET_SQLSERVERDATASOURCEINFO= {0xdf10cb94,0x35f6,0x11d2,{0x9c,0x54,0x0,0xc0,0x4f,0x79,0x71,0xd3}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBPROPSET_SQLSERVERDBINIT = {0x5cf4ca10,0xef21,0x11d0,{0x97,0xe7,0x0,0xc0,0x4f,0xc2,0xad,0x98}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBPROPSET_SQLSERVERROWSET = {0x5cf4ca11,0xef21,0x11d0,{0x97,0xe7,0x0,0xc0,0x4f,0xc2,0xad,0x98}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBPROPSET_SQLSERVERSESSION = {0x28efaee5,0x2d2c,0x11d1,{0x98,0x7,0x0,0xc0,0x4f,0xc2,0xad,0x98}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBPROPSET_SQLSERVERCOLUMN = {0x3b63fb5e,0x3fbb,0x11d3,{0x9f,0x29,0x0,0xc0,0x4f,0x8e,0xe9,0xdc}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBPROPSET_SQLSERVERSTREAM = {0x9f79c073,0x8a6d,0x4bca,{0xa8,0xa8,0xc9,0xb7,0x9a,0x9b,0x96,0x2d}};
|
||||||
|
#endif //_SQLOLEDB_H_
|
||||||
|
extern const GUID OLEDBDECLSPEC DBPROPSET_SQLSERVERPARAMETER = {0xfee09128,0xa67d,0x47ea,{0x8d,0x40,0x24,0xa1,0xd4,0x73,0x7e,0x8d}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBPROPSET_SQLSERVERINDEX = {0xE428B84E,0xA6B7,0x413a,{0x94,0x65,0x56,0x23,0x2E,0x0D,0x2B,0xEB}};
|
||||||
|
extern const GUID OLEDBDECLSPEC DBPROPSET_PARAMETERALL = {0x2cd2b7d8,0xe7c2,0x4f6c,{0x9b,0x30,0x75,0xe2,0x58,0x46,0x10,0x97}};
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Provider-specific columns for IColumnsRowset
|
||||||
|
//
|
||||||
|
#define DBCOLUMN_SS_X_GUID {0x627bd890,0xed54,0x11d2,{0xb9,0x94,0x0,0xc0,0x4f,0x8c,0xa8,0x2c}}
|
||||||
|
//
|
||||||
|
#ifndef _SQLOLEDB_H_
|
||||||
|
extern const DBID OLEDBDECLSPEC DBCOLUMN_SS_COMPFLAGS = {DBCOLUMN_SS_X_GUID, DBKIND_GUID_PROPID, (LPOLESTR)100};
|
||||||
|
extern const DBID OLEDBDECLSPEC DBCOLUMN_SS_SORTID = {DBCOLUMN_SS_X_GUID, DBKIND_GUID_PROPID, (LPOLESTR)101};
|
||||||
|
extern const DBID OLEDBDECLSPEC DBCOLUMN_BASETABLEINSTANCE = {DBCOLUMN_SS_X_GUID, DBKIND_GUID_PROPID, (LPOLESTR)102};
|
||||||
|
extern const DBID OLEDBDECLSPEC DBCOLUMN_SS_TDSCOLLATION = {DBCOLUMN_SS_X_GUID, DBKIND_GUID_PROPID, (LPOLESTR)103};
|
||||||
|
#endif //_SQLOLEDB_H_
|
||||||
|
extern const DBID OLEDBDECLSPEC DBCOLUMN_BASESERVERNAME = {DBCOLUMN_SS_X_GUID, DBKIND_GUID_PROPID, (LPOLESTR)104};
|
||||||
|
extern const DBID OLEDBDECLSPEC DBCOLUMN_SS_XML_SCHEMACOLLECTION_CATALOGNAME= {DBCOLUMN_SS_X_GUID, DBKIND_GUID_PROPID, (LPOLESTR)105};
|
||||||
|
extern const DBID OLEDBDECLSPEC DBCOLUMN_SS_XML_SCHEMACOLLECTION_SCHEMANAME = {DBCOLUMN_SS_X_GUID, DBKIND_GUID_PROPID, (LPOLESTR)106};
|
||||||
|
extern const DBID OLEDBDECLSPEC DBCOLUMN_SS_XML_SCHEMACOLLECTIONNAME = {DBCOLUMN_SS_X_GUID, DBKIND_GUID_PROPID, (LPOLESTR)107};
|
||||||
|
extern const DBID OLEDBDECLSPEC DBCOLUMN_SS_UDT_CATALOGNAME = {DBCOLUMN_SS_X_GUID, DBKIND_GUID_PROPID, (LPOLESTR)108};
|
||||||
|
extern const DBID OLEDBDECLSPEC DBCOLUMN_SS_UDT_SCHEMANAME = {DBCOLUMN_SS_X_GUID, DBKIND_GUID_PROPID, (LPOLESTR)109};
|
||||||
|
extern const DBID OLEDBDECLSPEC DBCOLUMN_SS_UDT_NAME = {DBCOLUMN_SS_X_GUID, DBKIND_GUID_PROPID, (LPOLESTR)110};
|
||||||
|
extern const DBID OLEDBDECLSPEC DBCOLUMN_SS_ASSEMBLY_TYPENAME= {DBCOLUMN_SS_X_GUID, DBKIND_GUID_PROPID, (LPOLESTR)111};
|
||||||
|
|
||||||
|
// OLEDB part of SQL Server Native Client header - end here!
|
||||||
|
#endif // defined(_SQLNCLI_OLEDB_) || !defined(_SQLNCLI_ODBC_)
|
||||||
|
|
||||||
|
// ODBC part of SQL Server Native Client header - begin here!
|
||||||
|
#if defined(_SQLNCLI_ODBC_) || !defined(_SQLNCLI_OLEDB_)
|
||||||
|
#ifdef ODBCVER
|
||||||
|
|
||||||
|
// max SQL Server identifier length
|
||||||
|
#define SQL_MAX_SQLSERVERNAME 128
|
||||||
|
|
||||||
|
// SQLSetConnectAttr driver specific defines.
|
||||||
|
// Microsoft has 1200 thru 1249 reserved for Microsoft SQL Server Native Client driver usage.
|
||||||
|
// Connection attributes
|
||||||
|
#define SQL_COPT_SS_BASE 1200
|
||||||
|
#define SQL_COPT_SS_REMOTE_PWD (SQL_COPT_SS_BASE+1) // dbrpwset SQLSetConnectOption only
|
||||||
|
#define SQL_COPT_SS_USE_PROC_FOR_PREP (SQL_COPT_SS_BASE+2) // Use create proc for SQLPrepare
|
||||||
|
#define SQL_COPT_SS_INTEGRATED_SECURITY (SQL_COPT_SS_BASE+3) // Force integrated security on login
|
||||||
|
#define SQL_COPT_SS_PRESERVE_CURSORS (SQL_COPT_SS_BASE+4) // Preserve server cursors after SQLTransact
|
||||||
|
#define SQL_COPT_SS_USER_DATA (SQL_COPT_SS_BASE+5) // dbgetuserdata/dbsetuserdata
|
||||||
|
#define SQL_COPT_SS_ENLIST_IN_DTC SQL_ATTR_ENLIST_IN_DTC // Enlist in a DTC transaction
|
||||||
|
#define SQL_COPT_SS_ENLIST_IN_XA SQL_ATTR_ENLIST_IN_XA // Enlist in a XA transaction
|
||||||
|
#define SQL_COPT_SS_FALLBACK_CONNECT (SQL_COPT_SS_BASE+10) // Enables FallBack connections
|
||||||
|
#define SQL_COPT_SS_PERF_DATA (SQL_COPT_SS_BASE+11) // Used to access SQL Server ODBC driver performance data
|
||||||
|
#define SQL_COPT_SS_PERF_DATA_LOG (SQL_COPT_SS_BASE+12) // Used to set the logfile name for the Performance data
|
||||||
|
#define SQL_COPT_SS_PERF_QUERY_INTERVAL (SQL_COPT_SS_BASE+13) // Used to set the query logging threshold in milliseconds.
|
||||||
|
#define SQL_COPT_SS_PERF_QUERY_LOG (SQL_COPT_SS_BASE+14) // Used to set the logfile name for saving queryies.
|
||||||
|
#define SQL_COPT_SS_PERF_QUERY (SQL_COPT_SS_BASE+15) // Used to start and stop query logging.
|
||||||
|
#define SQL_COPT_SS_PERF_DATA_LOG_NOW (SQL_COPT_SS_BASE+16) // Used to make a statistics log entry to disk.
|
||||||
|
#define SQL_COPT_SS_QUOTED_IDENT (SQL_COPT_SS_BASE+17) // Enable/Disable Quoted Identifiers
|
||||||
|
#define SQL_COPT_SS_ANSI_NPW (SQL_COPT_SS_BASE+18) // Enable/Disable ANSI NULL, Padding and Warnings
|
||||||
|
#define SQL_COPT_SS_BCP (SQL_COPT_SS_BASE+19) // Allow BCP usage on connection
|
||||||
|
#define SQL_COPT_SS_TRANSLATE (SQL_COPT_SS_BASE+20) // Perform code page translation
|
||||||
|
#define SQL_COPT_SS_ATTACHDBFILENAME (SQL_COPT_SS_BASE+21) // File name to be attached as a database
|
||||||
|
#define SQL_COPT_SS_CONCAT_NULL (SQL_COPT_SS_BASE+22) // Enable/Disable CONCAT_NULL_YIELDS_NULL
|
||||||
|
#define SQL_COPT_SS_ENCRYPT (SQL_COPT_SS_BASE+23) // Allow strong encryption for data
|
||||||
|
#define SQL_COPT_SS_MARS_ENABLED (SQL_COPT_SS_BASE+24) // Multiple active result set per connection
|
||||||
|
#define SQL_COPT_SS_FAILOVER_PARTNER (SQL_COPT_SS_BASE+25) // Failover partner server
|
||||||
|
#define SQL_COPT_SS_OLDPWD (SQL_COPT_SS_BASE+26) // Old Password, used when changing password during login
|
||||||
|
#define SQL_COPT_SS_TXN_ISOLATION (SQL_COPT_SS_BASE+27) // Used to set/get any driver-specific or ODBC-defined TXN iso level
|
||||||
|
#define SQL_COPT_SS_TRUST_SERVER_CERTIFICATE (SQL_COPT_SS_BASE+28) // Trust server certificate
|
||||||
|
#define SQL_COPT_SS_SERVER_SPN (SQL_COPT_SS_BASE+29) // Server SPN
|
||||||
|
#define SQL_COPT_SS_FAILOVER_PARTNER_SPN (SQL_COPT_SS_BASE+30) // Failover partner server SPN
|
||||||
|
#define SQL_COPT_SS_INTEGRATED_AUTHENTICATION_METHOD (SQL_COPT_SS_BASE+31) // The integrated authentication method used for the connection
|
||||||
|
#define SQL_COPT_SS_MUTUALLY_AUTHENTICATED (SQL_COPT_SS_BASE+32) // Used to decide if the connection is mutually authenticated
|
||||||
|
#define SQL_COPT_SS_MAX_USED SQL_COPT_SS_MUTUALLY_AUTHENTICATED
|
||||||
|
// Define old names
|
||||||
|
#define SQL_REMOTE_PWD SQL_COPT_SS_REMOTE_PWD
|
||||||
|
#define SQL_USE_PROCEDURE_FOR_PREPARE SQL_COPT_SS_USE_PROC_FOR_PREP
|
||||||
|
#define SQL_INTEGRATED_SECURITY SQL_COPT_SS_INTEGRATED_SECURITY
|
||||||
|
#define SQL_PRESERVE_CURSORS SQL_COPT_SS_PRESERVE_CURSORS
|
||||||
|
|
||||||
|
// SQLSetStmtAttr SQL Server Native Client driver specific defines.
|
||||||
|
// Statement attributes
|
||||||
|
#define SQL_SOPT_SS_BASE 1225
|
||||||
|
#define SQL_SOPT_SS_TEXTPTR_LOGGING (SQL_SOPT_SS_BASE+0) // Text pointer logging
|
||||||
|
#define SQL_SOPT_SS_CURRENT_COMMAND (SQL_SOPT_SS_BASE+1) // dbcurcmd SQLGetStmtOption only
|
||||||
|
#define SQL_SOPT_SS_HIDDEN_COLUMNS (SQL_SOPT_SS_BASE+2) // Expose FOR BROWSE hidden columns
|
||||||
|
#define SQL_SOPT_SS_NOBROWSETABLE (SQL_SOPT_SS_BASE+3) // Set NOBROWSETABLE option
|
||||||
|
#define SQL_SOPT_SS_REGIONALIZE (SQL_SOPT_SS_BASE+4) // Regionalize output character conversions
|
||||||
|
#define SQL_SOPT_SS_CURSOR_OPTIONS (SQL_SOPT_SS_BASE+5) // Server cursor options
|
||||||
|
#define SQL_SOPT_SS_NOCOUNT_STATUS (SQL_SOPT_SS_BASE+6) // Real vs. Not Real row count indicator
|
||||||
|
#define SQL_SOPT_SS_DEFER_PREPARE (SQL_SOPT_SS_BASE+7) // Defer prepare until necessary
|
||||||
|
#define SQL_SOPT_SS_QUERYNOTIFICATION_TIMEOUT (SQL_SOPT_SS_BASE+8) // Notification timeout
|
||||||
|
#define SQL_SOPT_SS_QUERYNOTIFICATION_MSGTEXT (SQL_SOPT_SS_BASE+9) // Notification message text
|
||||||
|
#define SQL_SOPT_SS_QUERYNOTIFICATION_OPTIONS (SQL_SOPT_SS_BASE+10)// SQL service broker name
|
||||||
|
#define SQL_SOPT_SS_PARAM_FOCUS (SQL_SOPT_SS_BASE+11)// Direct subsequent calls to parameter related methods to set properties on constituent columns/parameters of container types
|
||||||
|
#define SQL_SOPT_SS_NAME_SCOPE (SQL_SOPT_SS_BASE+12)// Sets name scope for subsequent catalog function calls
|
||||||
|
#define SQL_SOPT_SS_MAX_USED SQL_SOPT_SS_NAME_SCOPE
|
||||||
|
// Define old names
|
||||||
|
#define SQL_TEXTPTR_LOGGING SQL_SOPT_SS_TEXTPTR_LOGGING
|
||||||
|
#define SQL_COPT_SS_BASE_EX 1240
|
||||||
|
#define SQL_COPT_SS_BROWSE_CONNECT (SQL_COPT_SS_BASE_EX+1) // Browse connect mode of operation
|
||||||
|
#define SQL_COPT_SS_BROWSE_SERVER (SQL_COPT_SS_BASE_EX+2) // Single Server browse request.
|
||||||
|
#define SQL_COPT_SS_WARN_ON_CP_ERROR (SQL_COPT_SS_BASE_EX+3) // Issues warning when data from the server had a loss during code page conversion.
|
||||||
|
#define SQL_COPT_SS_CONNECTION_DEAD (SQL_COPT_SS_BASE_EX+4) // dbdead SQLGetConnectOption only. It will try to ping the server. Expensive connection check
|
||||||
|
#define SQL_COPT_SS_BROWSE_CACHE_DATA (SQL_COPT_SS_BASE_EX+5) // Determines if we should cache browse info. Used when returned buffer is greater then ODBC limit (32K)
|
||||||
|
#define SQL_COPT_SS_RESET_CONNECTION (SQL_COPT_SS_BASE_EX+6) // When this option is set, we will perform connection reset on next packet
|
||||||
|
#define SQL_COPT_SS_EX_MAX_USED SQL_COPT_SS_RESET_CONNECTION
|
||||||
|
|
||||||
|
// SQLColAttributes driver specific defines.
|
||||||
|
// SQLSetDescField/SQLGetDescField driver specific defines.
|
||||||
|
// Microsoft has 1200 thru 1249 reserved for Microsoft SQL Server Native Client driver usage.
|
||||||
|
#define SQL_CA_SS_BASE 1200
|
||||||
|
#define SQL_CA_SS_COLUMN_SSTYPE (SQL_CA_SS_BASE+0) // dbcoltype/dbalttype
|
||||||
|
#define SQL_CA_SS_COLUMN_UTYPE (SQL_CA_SS_BASE+1) // dbcolutype/dbaltutype
|
||||||
|
#define SQL_CA_SS_NUM_ORDERS (SQL_CA_SS_BASE+2) // dbnumorders
|
||||||
|
#define SQL_CA_SS_COLUMN_ORDER (SQL_CA_SS_BASE+3) // dbordercol
|
||||||
|
#define SQL_CA_SS_COLUMN_VARYLEN (SQL_CA_SS_BASE+4) // dbvarylen
|
||||||
|
#define SQL_CA_SS_NUM_COMPUTES (SQL_CA_SS_BASE+5) // dbnumcompute
|
||||||
|
#define SQL_CA_SS_COMPUTE_ID (SQL_CA_SS_BASE+6) // dbnextrow status return
|
||||||
|
#define SQL_CA_SS_COMPUTE_BYLIST (SQL_CA_SS_BASE+7) // dbbylist
|
||||||
|
#define SQL_CA_SS_COLUMN_ID (SQL_CA_SS_BASE+8) // dbaltcolid
|
||||||
|
#define SQL_CA_SS_COLUMN_OP (SQL_CA_SS_BASE+9) // dbaltop
|
||||||
|
#define SQL_CA_SS_COLUMN_SIZE (SQL_CA_SS_BASE+10) // dbcollen
|
||||||
|
#define SQL_CA_SS_COLUMN_HIDDEN (SQL_CA_SS_BASE+11) // Column is hidden (FOR BROWSE)
|
||||||
|
#define SQL_CA_SS_COLUMN_KEY (SQL_CA_SS_BASE+12) // Column is key column (FOR BROWSE)
|
||||||
|
//#define SQL_DESC_BASE_COLUMN_NAME_OLD (SQL_CA_SS_BASE+13) // This is defined at another location.
|
||||||
|
#define SQL_CA_SS_COLUMN_COLLATION (SQL_CA_SS_BASE+14) // Column collation (only for chars)
|
||||||
|
#define SQL_CA_SS_VARIANT_TYPE (SQL_CA_SS_BASE+15)
|
||||||
|
#define SQL_CA_SS_VARIANT_SQL_TYPE (SQL_CA_SS_BASE+16)
|
||||||
|
#define SQL_CA_SS_VARIANT_SERVER_TYPE (SQL_CA_SS_BASE+17)
|
||||||
|
|
||||||
|
// XML, CLR UDT, and table valued parameter related metadata
|
||||||
|
#define SQL_CA_SS_UDT_CATALOG_NAME (SQL_CA_SS_BASE+18) // UDT catalog name
|
||||||
|
#define SQL_CA_SS_UDT_SCHEMA_NAME (SQL_CA_SS_BASE+19) // UDT schema name
|
||||||
|
#define SQL_CA_SS_UDT_TYPE_NAME (SQL_CA_SS_BASE+20) // UDT type name
|
||||||
|
#define SQL_CA_SS_UDT_ASSEMBLY_TYPE_NAME (SQL_CA_SS_BASE+21) // Qualified name of the assembly containing the UDT class
|
||||||
|
#define SQL_CA_SS_XML_SCHEMACOLLECTION_CATALOG_NAME (SQL_CA_SS_BASE+22) // Name of the catalog that contains XML Schema collection
|
||||||
|
#define SQL_CA_SS_XML_SCHEMACOLLECTION_SCHEMA_NAME (SQL_CA_SS_BASE+23) // Name of the schema that contains XML Schema collection
|
||||||
|
#define SQL_CA_SS_XML_SCHEMACOLLECTION_NAME (SQL_CA_SS_BASE+24) // Name of the XML Schema collection
|
||||||
|
#define SQL_CA_SS_CATALOG_NAME (SQL_CA_SS_BASE+25) // Catalog name
|
||||||
|
#define SQL_CA_SS_SCHEMA_NAME (SQL_CA_SS_BASE+26) // Schema name
|
||||||
|
#define SQL_CA_SS_TYPE_NAME (SQL_CA_SS_BASE+27) // Type name
|
||||||
|
|
||||||
|
// table valued parameter related metadata
|
||||||
|
#define SQL_CA_SS_COLUMN_COMPUTED (SQL_CA_SS_BASE+29) // column is computed
|
||||||
|
#define SQL_CA_SS_COLUMN_IN_UNIQUE_KEY (SQL_CA_SS_BASE+30) // column is part of a unique key
|
||||||
|
#define SQL_CA_SS_COLUMN_SORT_ORDER (SQL_CA_SS_BASE+31) // column sort order
|
||||||
|
#define SQL_CA_SS_COLUMN_SORT_ORDINAL (SQL_CA_SS_BASE+32) // column sort ordinal
|
||||||
|
#define SQL_CA_SS_COLUMN_HAS_DEFAULT_VALUE (SQL_CA_SS_BASE+33) // column has default value for all rows of the table valued parameter
|
||||||
|
|
||||||
|
// sparse column related metadata
|
||||||
|
#define SQL_CA_SS_IS_COLUMN_SET (SQL_CA_SS_BASE+34) // column is a column-set column for sparse columns
|
||||||
|
|
||||||
|
// Legacy datetime related metadata
|
||||||
|
#define SQL_CA_SS_SERVER_TYPE (SQL_CA_SS_BASE+35) // column type to send on the wire for datetime types
|
||||||
|
|
||||||
|
#define SQL_CA_SS_MAX_USED (SQL_CA_SS_BASE+36)
|
||||||
|
|
||||||
|
// Defines returned by SQL_ATTR_CURSOR_TYPE/SQL_CURSOR_TYPE
|
||||||
|
#define SQL_CURSOR_FAST_FORWARD_ONLY 8 // Only returned by SQLGetStmtAttr/Option
|
||||||
|
// Defines for use with SQL_COPT_SS_USE_PROC_FOR_PREP
|
||||||
|
#define SQL_UP_OFF 0L // Procedures won't be used for prepare
|
||||||
|
#define SQL_UP_ON 1L // Procedures will be used for prepare
|
||||||
|
#define SQL_UP_ON_DROP 2L // Temp procedures will be explicitly dropped
|
||||||
|
#define SQL_UP_DEFAULT SQL_UP_ON
|
||||||
|
// Defines for use with SQL_COPT_SS_INTEGRATED_SECURITY - Pre-Connect Option only
|
||||||
|
#define SQL_IS_OFF 0L // Integrated security isn't used
|
||||||
|
#define SQL_IS_ON 1L // Integrated security is used
|
||||||
|
#define SQL_IS_DEFAULT SQL_IS_OFF
|
||||||
|
// Defines for use with SQL_COPT_SS_PRESERVE_CURSORS
|
||||||
|
#define SQL_PC_OFF 0L // Cursors are closed on SQLTransact
|
||||||
|
#define SQL_PC_ON 1L // Cursors remain open on SQLTransact
|
||||||
|
#define SQL_PC_DEFAULT SQL_PC_OFF
|
||||||
|
// Defines for use with SQL_COPT_SS_USER_DATA
|
||||||
|
#define SQL_UD_NOTSET NULL // No user data pointer set
|
||||||
|
// Defines for use with SQL_COPT_SS_TRANSLATE
|
||||||
|
#define SQL_XL_OFF 0L // Code page translation is not performed
|
||||||
|
#define SQL_XL_ON 1L // Code page translation is performed
|
||||||
|
#define SQL_XL_DEFAULT SQL_XL_ON
|
||||||
|
// Defines for use with SQL_COPT_SS_FALLBACK_CONNECT - Pre-Connect Option only
|
||||||
|
#define SQL_FB_OFF 0L // FallBack connections are disabled
|
||||||
|
#define SQL_FB_ON 1L // FallBack connections are enabled
|
||||||
|
#define SQL_FB_DEFAULT SQL_FB_OFF
|
||||||
|
// Defines for use with SQL_COPT_SS_BCP - Pre-Connect Option only
|
||||||
|
#define SQL_BCP_OFF 0L // BCP is not allowed on connection
|
||||||
|
#define SQL_BCP_ON 1L // BCP is allowed on connection
|
||||||
|
#define SQL_BCP_DEFAULT SQL_BCP_OFF
|
||||||
|
// Defines for use with SQL_COPT_SS_QUOTED_IDENT
|
||||||
|
#define SQL_QI_OFF 0L // Quoted identifiers are enable
|
||||||
|
#define SQL_QI_ON 1L // Quoted identifiers are disabled
|
||||||
|
#define SQL_QI_DEFAULT SQL_QI_ON
|
||||||
|
// Defines for use with SQL_COPT_SS_ANSI_NPW - Pre-Connect Option only
|
||||||
|
#define SQL_AD_OFF 0L // ANSI NULLs, Padding and Warnings are enabled
|
||||||
|
#define SQL_AD_ON 1L // ANSI NULLs, Padding and Warnings are disabled
|
||||||
|
#define SQL_AD_DEFAULT SQL_AD_ON
|
||||||
|
// Defines for use with SQL_COPT_SS_CONCAT_NULL - Pre-Connect Option only
|
||||||
|
#define SQL_CN_OFF 0L // CONCAT_NULL_YIELDS_NULL is off
|
||||||
|
#define SQL_CN_ON 1L // CONCAT_NULL_YIELDS_NULL is on
|
||||||
|
#define SQL_CN_DEFAULT SQL_CN_ON
|
||||||
|
// Defines for use with SQL_SOPT_SS_TEXTPTR_LOGGING
|
||||||
|
#define SQL_TL_OFF 0L // No logging on text pointer ops
|
||||||
|
#define SQL_TL_ON 1L // Logging occurs on text pointer ops
|
||||||
|
#define SQL_TL_DEFAULT SQL_TL_ON
|
||||||
|
// Defines for use with SQL_SOPT_SS_HIDDEN_COLUMNS
|
||||||
|
#define SQL_HC_OFF 0L // FOR BROWSE columns are hidden
|
||||||
|
#define SQL_HC_ON 1L // FOR BROWSE columns are exposed
|
||||||
|
#define SQL_HC_DEFAULT SQL_HC_OFF
|
||||||
|
// Defines for use with SQL_SOPT_SS_NOBROWSETABLE
|
||||||
|
#define SQL_NB_OFF 0L // NO_BROWSETABLE is off
|
||||||
|
#define SQL_NB_ON 1L // NO_BROWSETABLE is on
|
||||||
|
#define SQL_NB_DEFAULT SQL_NB_OFF
|
||||||
|
// Defines for use with SQL_SOPT_SS_REGIONALIZE
|
||||||
|
#define SQL_RE_OFF 0L // No regionalization occurs on output character conversions
|
||||||
|
#define SQL_RE_ON 1L // Regionalization occurs on output character conversions
|
||||||
|
#define SQL_RE_DEFAULT SQL_RE_OFF
|
||||||
|
// Defines for use with SQL_SOPT_SS_CURSOR_OPTIONS
|
||||||
|
#define SQL_CO_OFF 0L // Clear all cursor options
|
||||||
|
#define SQL_CO_FFO 1L // Fast-forward cursor will be used
|
||||||
|
#define SQL_CO_AF 2L // Autofetch on cursor open
|
||||||
|
#define SQL_CO_FFO_AF (SQL_CO_FFO|SQL_CO_AF) // Fast-forward cursor with autofetch
|
||||||
|
#define SQL_CO_FIREHOSE_AF 4L // Auto fetch on fire-hose cursors
|
||||||
|
#define SQL_CO_DEFAULT SQL_CO_OFF
|
||||||
|
//SQL_SOPT_SS_NOCOUNT_STATUS
|
||||||
|
#define SQL_NC_OFF 0L
|
||||||
|
#define SQL_NC_ON 1L
|
||||||
|
//SQL_SOPT_SS_DEFER_PREPARE
|
||||||
|
#define SQL_DP_OFF 0L
|
||||||
|
#define SQL_DP_ON 1L
|
||||||
|
//SQL_SOPT_SS_NAME_SCOPE
|
||||||
|
#define SQL_SS_NAME_SCOPE_TABLE 0L
|
||||||
|
#define SQL_SS_NAME_SCOPE_TABLE_TYPE 1L
|
||||||
|
#define SQL_SS_NAME_SCOPE_EXTENDED 2L
|
||||||
|
#define SQL_SS_NAME_SCOPE_SPARSE_COLUMN_SET 3L
|
||||||
|
#define SQL_SS_NAME_SCOPE_DEFAULT SQL_SS_NAME_SCOPE_TABLE
|
||||||
|
//SQL_COPT_SS_ENCRYPT
|
||||||
|
#define SQL_EN_OFF 0L
|
||||||
|
#define SQL_EN_ON 1L
|
||||||
|
//SQL_COPT_SS_TRUST_SERVER_CERTIFICATE
|
||||||
|
#define SQL_TRUST_SERVER_CERTIFICATE_NO 0L
|
||||||
|
#define SQL_TRUST_SERVER_CERTIFICATE_YES 1L
|
||||||
|
//SQL_COPT_SS_BROWSE_CONNECT
|
||||||
|
#define SQL_MORE_INFO_NO 0L
|
||||||
|
#define SQL_MORE_INFO_YES 1L
|
||||||
|
//SQL_COPT_SS_BROWSE_CACHE_DATA
|
||||||
|
#define SQL_CACHE_DATA_NO 0L
|
||||||
|
#define SQL_CACHE_DATA_YES 1L
|
||||||
|
//SQL_COPT_SS_RESET_CONNECTION
|
||||||
|
#define SQL_RESET_YES 1L
|
||||||
|
//SQL_COPT_SS_WARN_ON_CP_ERROR
|
||||||
|
#define SQL_WARN_NO 0L
|
||||||
|
#define SQL_WARN_YES 1L
|
||||||
|
//SQL_COPT_SS_MARS_ENABLED
|
||||||
|
#define SQL_MARS_ENABLED_NO 0L
|
||||||
|
#define SQL_MARS_ENABLED_YES 1L
|
||||||
|
/* SQL_TXN_ISOLATION_OPTION bitmasks */
|
||||||
|
#define SQL_TXN_SS_SNAPSHOT 0x00000020L
|
||||||
|
|
||||||
|
// The following are defines for SQL_CA_SS_COLUMN_SORT_ORDER
|
||||||
|
#define SQL_SS_ORDER_UNSPECIFIED 0L
|
||||||
|
#define SQL_SS_DESCENDING_ORDER 1L
|
||||||
|
#define SQL_SS_ASCENDING_ORDER 2L
|
||||||
|
#define SQL_SS_ORDER_DEFAULT SQL_SS_ORDER_UNSPECIFIED
|
||||||
|
|
||||||
|
// Driver specific SQL data type defines.
|
||||||
|
// Microsoft has -150 thru -199 reserved for Microsoft SQL Server Native Client driver usage.
|
||||||
|
#define SQL_SS_VARIANT (-150)
|
||||||
|
#define SQL_SS_UDT (-151)
|
||||||
|
#define SQL_SS_XML (-152)
|
||||||
|
#define SQL_SS_TABLE (-153)
|
||||||
|
#define SQL_SS_TIME2 (-154)
|
||||||
|
#define SQL_SS_TIMESTAMPOFFSET (-155)
|
||||||
|
|
||||||
|
// Local types to be used with SQL_CA_SS_SERVER_TYPE
|
||||||
|
#define SQL_SS_TYPE_DEFAULT 0L
|
||||||
|
#define SQL_SS_TYPE_SMALLDATETIME 1L
|
||||||
|
#define SQL_SS_TYPE_DATETIME 2L
|
||||||
|
|
||||||
|
#ifndef SQLNCLI_NO_BCP
|
||||||
|
// Define the symbol SQLNCLI_NO_BCP if you are not using BCP in your application
|
||||||
|
// and you want to exclude the BCP-related definitions in this header file.
|
||||||
|
|
||||||
|
// SQL Server Data Type defines.
|
||||||
|
// New types for SQL 6.0 and later servers
|
||||||
|
#define SQLTEXT 0x23
|
||||||
|
#define SQLVARBINARY 0x25
|
||||||
|
#define SQLINTN 0x26
|
||||||
|
#define SQLVARCHAR 0x27
|
||||||
|
#define SQLBINARY 0x2d
|
||||||
|
#define SQLIMAGE 0x22
|
||||||
|
#define SQLCHARACTER 0x2f
|
||||||
|
#define SQLINT1 0x30
|
||||||
|
#define SQLBIT 0x32
|
||||||
|
#define SQLINT2 0x34
|
||||||
|
#define SQLINT4 0x38
|
||||||
|
#define SQLMONEY 0x3c
|
||||||
|
#define SQLDATETIME 0x3d
|
||||||
|
#define SQLFLT8 0x3e
|
||||||
|
#define SQLFLTN 0x6d
|
||||||
|
#define SQLMONEYN 0x6e
|
||||||
|
#define SQLDATETIMN 0x6f
|
||||||
|
#define SQLFLT4 0x3b
|
||||||
|
#define SQLMONEY4 0x7a
|
||||||
|
#define SQLDATETIM4 0x3a
|
||||||
|
// New types for SQL 6.0 and later servers
|
||||||
|
#define SQLDECIMAL 0x6a
|
||||||
|
#define SQLNUMERIC 0x6c
|
||||||
|
// New types for SQL 7.0 and later servers
|
||||||
|
#define SQLUNIQUEID 0x24
|
||||||
|
#define SQLBIGCHAR 0xaf
|
||||||
|
#define SQLBIGVARCHAR 0xa7
|
||||||
|
#define SQLBIGBINARY 0xad
|
||||||
|
#define SQLBIGVARBINARY 0xa5
|
||||||
|
#define SQLBITN 0x68
|
||||||
|
#define SQLNCHAR 0xef
|
||||||
|
#define SQLNVARCHAR 0xe7
|
||||||
|
#define SQLNTEXT 0x63
|
||||||
|
// New types for SQL 2000 and later servers
|
||||||
|
#define SQLINT8 0x7f
|
||||||
|
#define SQLVARIANT 0x62
|
||||||
|
// New types for SQL 2005 and later servers
|
||||||
|
#define SQLUDT 0xf0
|
||||||
|
#define SQLXML 0xf1
|
||||||
|
// New types for SQL 2008 and later servers
|
||||||
|
#define SQLTABLE 0xf3
|
||||||
|
#define SQLDATEN 0x28
|
||||||
|
#define SQLTIMEN 0x29
|
||||||
|
#define SQLDATETIME2N 0x2a
|
||||||
|
#define SQLDATETIMEOFFSETN 0x2b
|
||||||
|
// Define old names
|
||||||
|
#define SQLDECIMALN 0x6a
|
||||||
|
#define SQLNUMERICN 0x6c
|
||||||
|
#endif // SQLNCLI_NO_BCP
|
||||||
|
|
||||||
|
// SQL_SS_LENGTH_UNLIMITED is used to describe the max length of
|
||||||
|
// VARCHAR(max), VARBINARY(max), NVARCHAR(max), and XML columns
|
||||||
|
#define SQL_SS_LENGTH_UNLIMITED 0
|
||||||
|
|
||||||
|
// User Data Type definitions.
|
||||||
|
// Returned by SQLColAttributes/SQL_CA_SS_COLUMN_UTYPE.
|
||||||
|
#define SQLudtBINARY 3
|
||||||
|
#define SQLudtBIT 16
|
||||||
|
#define SQLudtBITN 0
|
||||||
|
#define SQLudtCHAR 1
|
||||||
|
#define SQLudtDATETIM4 22
|
||||||
|
#define SQLudtDATETIME 12
|
||||||
|
#define SQLudtDATETIMN 15
|
||||||
|
#define SQLudtDECML 24
|
||||||
|
#define SQLudtDECMLN 26
|
||||||
|
#define SQLudtFLT4 23
|
||||||
|
#define SQLudtFLT8 8
|
||||||
|
#define SQLudtFLTN 14
|
||||||
|
#define SQLudtIMAGE 20
|
||||||
|
#define SQLudtINT1 5
|
||||||
|
#define SQLudtINT2 6
|
||||||
|
#define SQLudtINT4 7
|
||||||
|
#define SQLudtINTN 13
|
||||||
|
#define SQLudtMONEY 11
|
||||||
|
#define SQLudtMONEY4 21
|
||||||
|
#define SQLudtMONEYN 17
|
||||||
|
#define SQLudtNUM 10
|
||||||
|
#define SQLudtNUMN 25
|
||||||
|
#define SQLudtSYSNAME 18
|
||||||
|
#define SQLudtTEXT 19
|
||||||
|
#define SQLudtTIMESTAMP 80
|
||||||
|
#define SQLudtUNIQUEIDENTIFIER 0
|
||||||
|
#define SQLudtVARBINARY 4
|
||||||
|
#define SQLudtVARCHAR 2
|
||||||
|
#define MIN_USER_DATATYPE 256
|
||||||
|
// Aggregate operator types.
|
||||||
|
// Returned by SQLColAttributes/SQL_CA_SS_COLUMN_OP.
|
||||||
|
#define SQLAOPSTDEV 0x30 // Standard deviation
|
||||||
|
#define SQLAOPSTDEVP 0x31 // Standard deviation population
|
||||||
|
#define SQLAOPVAR 0x32 // Variance
|
||||||
|
#define SQLAOPVARP 0x33 // Variance population
|
||||||
|
#define SQLAOPCNT 0x4b // Count
|
||||||
|
#define SQLAOPSUM 0x4d // Sum
|
||||||
|
#define SQLAOPAVG 0x4f // Average
|
||||||
|
#define SQLAOPMIN 0x51 // Min
|
||||||
|
#define SQLAOPMAX 0x52 // Max
|
||||||
|
#define SQLAOPANY 0x53 // Any
|
||||||
|
#define SQLAOPNOOP 0x56 // None
|
||||||
|
// SQLGetInfo driver specific defines.
|
||||||
|
// Microsoft has 1151 thru 1200 reserved for Microsoft SQL Server Native Client driver usage.
|
||||||
|
#define SQL_INFO_SS_FIRST 1199
|
||||||
|
#define SQL_INFO_SS_NETLIB_NAMEW (SQL_INFO_SS_FIRST+0) // dbprocinfo
|
||||||
|
#define SQL_INFO_SS_NETLIB_NAMEA (SQL_INFO_SS_FIRST+1) // dbprocinfo
|
||||||
|
#define SQL_INFO_SS_MAX_USED SQL_INFO_SS_NETLIB_NAMEA
|
||||||
|
#ifdef UNICODE
|
||||||
|
#define SQL_INFO_SS_NETLIB_NAME SQL_INFO_SS_NETLIB_NAMEW
|
||||||
|
#else
|
||||||
|
#define SQL_INFO_SS_NETLIB_NAME SQL_INFO_SS_NETLIB_NAMEA
|
||||||
|
#endif
|
||||||
|
// SQLGetDiagField driver specific defines.
|
||||||
|
// Microsoft has -1150 thru -1199 reserved for Microsoft SQL Server Native Client driver usage.
|
||||||
|
#define SQL_DIAG_SS_BASE (-1150)
|
||||||
|
#define SQL_DIAG_SS_MSGSTATE (SQL_DIAG_SS_BASE)
|
||||||
|
#define SQL_DIAG_SS_SEVERITY (SQL_DIAG_SS_BASE-1)
|
||||||
|
#define SQL_DIAG_SS_SRVNAME (SQL_DIAG_SS_BASE-2)
|
||||||
|
#define SQL_DIAG_SS_PROCNAME (SQL_DIAG_SS_BASE-3)
|
||||||
|
#define SQL_DIAG_SS_LINE (SQL_DIAG_SS_BASE-4)
|
||||||
|
// SQLGetDiagField/SQL_DIAG_DYNAMIC_FUNCTION_CODE driver specific defines.
|
||||||
|
// Microsoft has -200 thru -299 reserved for Microsoft SQL Server Native Client driver usage.
|
||||||
|
#define SQL_DIAG_DFC_SS_BASE (-200)
|
||||||
|
#define SQL_DIAG_DFC_SS_ALTER_DATABASE (SQL_DIAG_DFC_SS_BASE-0)
|
||||||
|
#define SQL_DIAG_DFC_SS_CHECKPOINT (SQL_DIAG_DFC_SS_BASE-1)
|
||||||
|
#define SQL_DIAG_DFC_SS_CONDITION (SQL_DIAG_DFC_SS_BASE-2)
|
||||||
|
#define SQL_DIAG_DFC_SS_CREATE_DATABASE (SQL_DIAG_DFC_SS_BASE-3)
|
||||||
|
#define SQL_DIAG_DFC_SS_CREATE_DEFAULT (SQL_DIAG_DFC_SS_BASE-4)
|
||||||
|
#define SQL_DIAG_DFC_SS_CREATE_PROCEDURE (SQL_DIAG_DFC_SS_BASE-5)
|
||||||
|
#define SQL_DIAG_DFC_SS_CREATE_RULE (SQL_DIAG_DFC_SS_BASE-6)
|
||||||
|
#define SQL_DIAG_DFC_SS_CREATE_TRIGGER (SQL_DIAG_DFC_SS_BASE-7)
|
||||||
|
#define SQL_DIAG_DFC_SS_CURSOR_DECLARE (SQL_DIAG_DFC_SS_BASE-8)
|
||||||
|
#define SQL_DIAG_DFC_SS_CURSOR_OPEN (SQL_DIAG_DFC_SS_BASE-9)
|
||||||
|
#define SQL_DIAG_DFC_SS_CURSOR_FETCH (SQL_DIAG_DFC_SS_BASE-10)
|
||||||
|
#define SQL_DIAG_DFC_SS_CURSOR_CLOSE (SQL_DIAG_DFC_SS_BASE-11)
|
||||||
|
#define SQL_DIAG_DFC_SS_DEALLOCATE_CURSOR (SQL_DIAG_DFC_SS_BASE-12)
|
||||||
|
#define SQL_DIAG_DFC_SS_DBCC (SQL_DIAG_DFC_SS_BASE-13)
|
||||||
|
#define SQL_DIAG_DFC_SS_DISK (SQL_DIAG_DFC_SS_BASE-14)
|
||||||
|
#define SQL_DIAG_DFC_SS_DROP_DATABASE (SQL_DIAG_DFC_SS_BASE-15)
|
||||||
|
#define SQL_DIAG_DFC_SS_DROP_DEFAULT (SQL_DIAG_DFC_SS_BASE-16)
|
||||||
|
#define SQL_DIAG_DFC_SS_DROP_PROCEDURE (SQL_DIAG_DFC_SS_BASE-17)
|
||||||
|
#define SQL_DIAG_DFC_SS_DROP_RULE (SQL_DIAG_DFC_SS_BASE-18)
|
||||||
|
#define SQL_DIAG_DFC_SS_DROP_TRIGGER (SQL_DIAG_DFC_SS_BASE-19)
|
||||||
|
#define SQL_DIAG_DFC_SS_DUMP_DATABASE (SQL_DIAG_DFC_SS_BASE-20)
|
||||||
|
#define SQL_DIAG_DFC_SS_BACKUP_DATABASE (SQL_DIAG_DFC_SS_BASE-20)
|
||||||
|
#define SQL_DIAG_DFC_SS_DUMP_TABLE (SQL_DIAG_DFC_SS_BASE-21)
|
||||||
|
#define SQL_DIAG_DFC_SS_DUMP_TRANSACTION (SQL_DIAG_DFC_SS_BASE-22)
|
||||||
|
#define SQL_DIAG_DFC_SS_BACKUP_TRANSACTION (SQL_DIAG_DFC_SS_BASE-22)
|
||||||
|
#define SQL_DIAG_DFC_SS_GOTO (SQL_DIAG_DFC_SS_BASE-23)
|
||||||
|
#define SQL_DIAG_DFC_SS_INSERT_BULK (SQL_DIAG_DFC_SS_BASE-24)
|
||||||
|
#define SQL_DIAG_DFC_SS_KILL (SQL_DIAG_DFC_SS_BASE-25)
|
||||||
|
#define SQL_DIAG_DFC_SS_LOAD_DATABASE (SQL_DIAG_DFC_SS_BASE-26)
|
||||||
|
#define SQL_DIAG_DFC_SS_RESTORE_DATABASE (SQL_DIAG_DFC_SS_BASE-26)
|
||||||
|
#define SQL_DIAG_DFC_SS_LOAD_HEADERONLY (SQL_DIAG_DFC_SS_BASE-27)
|
||||||
|
#define SQL_DIAG_DFC_SS_RESTORE_HEADERONLY (SQL_DIAG_DFC_SS_BASE-27)
|
||||||
|
#define SQL_DIAG_DFC_SS_LOAD_TABLE (SQL_DIAG_DFC_SS_BASE-28)
|
||||||
|
#define SQL_DIAG_DFC_SS_LOAD_TRANSACTION (SQL_DIAG_DFC_SS_BASE-29)
|
||||||
|
#define SQL_DIAG_DFC_SS_RESTORE_TRANSACTION (SQL_DIAG_DFC_SS_BASE-29)
|
||||||
|
#define SQL_DIAG_DFC_SS_PRINT (SQL_DIAG_DFC_SS_BASE-30)
|
||||||
|
#define SQL_DIAG_DFC_SS_RAISERROR (SQL_DIAG_DFC_SS_BASE-31)
|
||||||
|
#define SQL_DIAG_DFC_SS_READTEXT (SQL_DIAG_DFC_SS_BASE-32)
|
||||||
|
#define SQL_DIAG_DFC_SS_RECONFIGURE (SQL_DIAG_DFC_SS_BASE-33)
|
||||||
|
#define SQL_DIAG_DFC_SS_RETURN (SQL_DIAG_DFC_SS_BASE-34)
|
||||||
|
#define SQL_DIAG_DFC_SS_SELECT_INTO (SQL_DIAG_DFC_SS_BASE-35)
|
||||||
|
#define SQL_DIAG_DFC_SS_SET (SQL_DIAG_DFC_SS_BASE-36)
|
||||||
|
#define SQL_DIAG_DFC_SS_SET_IDENTITY_INSERT (SQL_DIAG_DFC_SS_BASE-37)
|
||||||
|
#define SQL_DIAG_DFC_SS_SET_ROW_COUNT (SQL_DIAG_DFC_SS_BASE-38)
|
||||||
|
#define SQL_DIAG_DFC_SS_SET_STATISTICS (SQL_DIAG_DFC_SS_BASE-39)
|
||||||
|
#define SQL_DIAG_DFC_SS_SET_TEXTSIZE (SQL_DIAG_DFC_SS_BASE-40)
|
||||||
|
#define SQL_DIAG_DFC_SS_SETUSER (SQL_DIAG_DFC_SS_BASE-41)
|
||||||
|
#define SQL_DIAG_DFC_SS_SHUTDOWN (SQL_DIAG_DFC_SS_BASE-42)
|
||||||
|
#define SQL_DIAG_DFC_SS_TRANS_BEGIN (SQL_DIAG_DFC_SS_BASE-43)
|
||||||
|
#define SQL_DIAG_DFC_SS_TRANS_COMMIT (SQL_DIAG_DFC_SS_BASE-44)
|
||||||
|
#define SQL_DIAG_DFC_SS_TRANS_PREPARE (SQL_DIAG_DFC_SS_BASE-45)
|
||||||
|
#define SQL_DIAG_DFC_SS_TRANS_ROLLBACK (SQL_DIAG_DFC_SS_BASE-46)
|
||||||
|
#define SQL_DIAG_DFC_SS_TRANS_SAVE (SQL_DIAG_DFC_SS_BASE-47)
|
||||||
|
#define SQL_DIAG_DFC_SS_TRUNCATE_TABLE (SQL_DIAG_DFC_SS_BASE-48)
|
||||||
|
#define SQL_DIAG_DFC_SS_UPDATE_STATISTICS (SQL_DIAG_DFC_SS_BASE-49)
|
||||||
|
#define SQL_DIAG_DFC_SS_UPDATETEXT (SQL_DIAG_DFC_SS_BASE-50)
|
||||||
|
#define SQL_DIAG_DFC_SS_USE (SQL_DIAG_DFC_SS_BASE-51)
|
||||||
|
#define SQL_DIAG_DFC_SS_WAITFOR (SQL_DIAG_DFC_SS_BASE-52)
|
||||||
|
#define SQL_DIAG_DFC_SS_WRITETEXT (SQL_DIAG_DFC_SS_BASE-53)
|
||||||
|
#define SQL_DIAG_DFC_SS_DENY (SQL_DIAG_DFC_SS_BASE-54)
|
||||||
|
#define SQL_DIAG_DFC_SS_SET_XCTLVL (SQL_DIAG_DFC_SS_BASE-55)
|
||||||
|
#define SQL_DIAG_DFC_SS_MERGE (SQL_DIAG_DFC_SS_BASE-56)
|
||||||
|
|
||||||
|
// Severity codes for SQL_DIAG_SS_SEVERITY
|
||||||
|
#define EX_ANY 0
|
||||||
|
#define EX_INFO 10
|
||||||
|
#define EX_MAXISEVERITY EX_INFO
|
||||||
|
#define EX_MISSING 11
|
||||||
|
#define EX_TYPE 12
|
||||||
|
#define EX_DEADLOCK 13
|
||||||
|
#define EX_PERMIT 14
|
||||||
|
#define EX_SYNTAX 15
|
||||||
|
#define EX_USER 16
|
||||||
|
#define EX_RESOURCE 17
|
||||||
|
#define EX_INTOK 18
|
||||||
|
#define MAXUSEVERITY EX_INTOK
|
||||||
|
#define EX_LIMIT 19
|
||||||
|
#define EX_CMDFATAL 20
|
||||||
|
#define MINFATALERR EX_CMDFATAL
|
||||||
|
#define EX_DBFATAL 21
|
||||||
|
#define EX_TABCORRUPT 22
|
||||||
|
#define EX_DBCORRUPT 23
|
||||||
|
#define EX_HARDWARE 24
|
||||||
|
#define EX_CONTROL 25
|
||||||
|
// Internal server datatypes - used when binding to SQL_C_BINARY
|
||||||
|
#ifndef MAXNUMERICLEN // Resolve ODS/DBLib conflicts
|
||||||
|
// DB-Library datatypes
|
||||||
|
#define DBMAXCHAR (8000+1) // Max length of DBVARBINARY and DBVARCHAR, etc. +1 for zero byte
|
||||||
|
#define MAXNAME (SQL_MAX_SQLSERVERNAME+1) // Max server identifier length including zero byte
|
||||||
|
#ifdef UNICODE
|
||||||
|
typedef wchar_t DBCHAR;
|
||||||
|
#else
|
||||||
|
typedef char DBCHAR;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
typedef short SQLSMALLINT;
|
||||||
|
|
||||||
|
typedef unsigned short SQLUSMALLINT;
|
||||||
|
|
||||||
|
typedef long SQLINTEGER;
|
||||||
|
|
||||||
|
typedef unsigned long SQLUINTEGER;
|
||||||
|
|
||||||
|
typedef unsigned char DBBINARY;
|
||||||
|
|
||||||
|
typedef unsigned char DBTINYINT;
|
||||||
|
|
||||||
|
typedef short DBSMALLINT;
|
||||||
|
|
||||||
|
typedef unsigned short DBUSMALLINT;
|
||||||
|
|
||||||
|
typedef double DBFLT8;
|
||||||
|
|
||||||
|
typedef unsigned char DBBIT;
|
||||||
|
|
||||||
|
typedef unsigned char DBBOOL;
|
||||||
|
|
||||||
|
typedef float DBFLT4;
|
||||||
|
|
||||||
|
typedef DBFLT4 DBREAL;
|
||||||
|
|
||||||
|
typedef UINT DBUBOOL;
|
||||||
|
|
||||||
|
typedef struct dbmoney
|
||||||
|
{
|
||||||
|
LONG mnyhigh;
|
||||||
|
ULONG mnylow;
|
||||||
|
} DBMONEY;
|
||||||
|
|
||||||
|
typedef struct dbdatetime
|
||||||
|
{
|
||||||
|
LONG dtdays;
|
||||||
|
ULONG dttime;
|
||||||
|
} DBDATETIME;
|
||||||
|
|
||||||
|
typedef struct dbdatetime4
|
||||||
|
{
|
||||||
|
USHORT numdays;
|
||||||
|
USHORT nummins;
|
||||||
|
} DBDATETIM4;
|
||||||
|
|
||||||
|
typedef LONG DBMONEY4;
|
||||||
|
|
||||||
|
#include <pshpack8.h> // 8-byte structure packing
|
||||||
|
|
||||||
|
// New Date Time Structures
|
||||||
|
// New Structure for TIME2
|
||||||
|
typedef struct tagSS_TIME2_STRUCT
|
||||||
|
{
|
||||||
|
SQLUSMALLINT hour;
|
||||||
|
SQLUSMALLINT minute;
|
||||||
|
SQLUSMALLINT second;
|
||||||
|
SQLUINTEGER fraction;
|
||||||
|
} SQL_SS_TIME2_STRUCT;
|
||||||
|
|
||||||
|
// New Structure for TIMESTAMPOFFSET
|
||||||
|
typedef struct tagSS_TIMESTAMPOFFSET_STRUCT
|
||||||
|
{
|
||||||
|
SQLSMALLINT year;
|
||||||
|
SQLUSMALLINT month;
|
||||||
|
SQLUSMALLINT day;
|
||||||
|
SQLUSMALLINT hour;
|
||||||
|
SQLUSMALLINT minute;
|
||||||
|
SQLUSMALLINT second;
|
||||||
|
SQLUINTEGER fraction;
|
||||||
|
SQLSMALLINT timezone_hour;
|
||||||
|
SQLSMALLINT timezone_minute;
|
||||||
|
} SQL_SS_TIMESTAMPOFFSET_STRUCT;
|
||||||
|
|
||||||
|
#include <poppack.h> // restore original structure packing
|
||||||
|
|
||||||
|
// Money value *10,000
|
||||||
|
#define DBNUM_PREC_TYPE BYTE
|
||||||
|
#define DBNUM_SCALE_TYPE BYTE
|
||||||
|
#define DBNUM_VAL_TYPE BYTE
|
||||||
|
|
||||||
|
#if (ODBCVER < 0x0300)
|
||||||
|
#define MAXNUMERICLEN 16
|
||||||
|
typedef struct dbnumeric // Internal representation of NUMERIC data type
|
||||||
|
{
|
||||||
|
DBNUM_PREC_TYPE precision; // Precision
|
||||||
|
DBNUM_SCALE_TYPE scale; // Scale
|
||||||
|
BYTE sign; // Sign (1 if positive, 0 if negative)
|
||||||
|
DBNUM_VAL_TYPE val[MAXNUMERICLEN];// Value
|
||||||
|
} DBNUMERIC;
|
||||||
|
typedef DBNUMERIC DBDECIMAL;// Internal representation of DECIMAL data type
|
||||||
|
#else // Use ODBC 3.0 definitions since same as DBLib
|
||||||
|
#define MAXNUMERICLEN SQL_MAX_NUMERIC_LEN
|
||||||
|
typedef SQL_NUMERIC_STRUCT DBNUMERIC;
|
||||||
|
typedef SQL_NUMERIC_STRUCT DBDECIMAL;
|
||||||
|
#endif // ODCBVER
|
||||||
|
#endif // MAXNUMERICLEN
|
||||||
|
|
||||||
|
#ifndef INT
|
||||||
|
typedef int INT;
|
||||||
|
typedef long DBINT;
|
||||||
|
typedef DBINT * LPDBINT;
|
||||||
|
#ifndef _LPCBYTE_DEFINED
|
||||||
|
#define _LPCBYTE_DEFINED
|
||||||
|
typedef BYTE const* LPCBYTE;
|
||||||
|
#endif //_LPCBYTE_DEFINED
|
||||||
|
#endif // INT
|
||||||
|
/**************************************************************************
|
||||||
|
This struct is a global used for gathering statistical data on the driver.
|
||||||
|
Access to this structure is controlled via the pStatCrit;
|
||||||
|
***************************************************************************/
|
||||||
|
typedef struct sqlperf
|
||||||
|
{
|
||||||
|
// Application Profile Statistics
|
||||||
|
DWORD TimerResolution;
|
||||||
|
DWORD SQLidu;
|
||||||
|
DWORD SQLiduRows;
|
||||||
|
DWORD SQLSelects;
|
||||||
|
DWORD SQLSelectRows;
|
||||||
|
DWORD Transactions;
|
||||||
|
DWORD SQLPrepares;
|
||||||
|
DWORD ExecDirects;
|
||||||
|
DWORD SQLExecutes;
|
||||||
|
DWORD CursorOpens;
|
||||||
|
DWORD CursorSize;
|
||||||
|
DWORD CursorUsed;
|
||||||
|
LDOUBLE PercentCursorUsed;
|
||||||
|
LDOUBLE AvgFetchTime;
|
||||||
|
LDOUBLE AvgCursorSize;
|
||||||
|
LDOUBLE AvgCursorUsed;
|
||||||
|
DWORD SQLFetchTime;
|
||||||
|
DWORD SQLFetchCount;
|
||||||
|
DWORD CurrentStmtCount;
|
||||||
|
DWORD MaxOpenStmt;
|
||||||
|
DWORD SumOpenStmt;
|
||||||
|
// Connection Statistics
|
||||||
|
DWORD CurrentConnectionCount;
|
||||||
|
DWORD MaxConnectionsOpened;
|
||||||
|
DWORD SumConnectionsOpened;
|
||||||
|
DWORD SumConnectiontime;
|
||||||
|
LDOUBLE AvgTimeOpened;
|
||||||
|
// Network Statistics
|
||||||
|
DWORD ServerRndTrips;
|
||||||
|
DWORD BuffersSent;
|
||||||
|
DWORD BuffersRec;
|
||||||
|
DWORD BytesSent;
|
||||||
|
DWORD BytesRec;
|
||||||
|
// Time Statistics;
|
||||||
|
DWORD msExecutionTime;
|
||||||
|
DWORD msNetWorkServerTime;
|
||||||
|
} SQLPERF;
|
||||||
|
// The following are options for SQL_COPT_SS_PERF_DATA and SQL_COPT_SS_PERF_QUERY
|
||||||
|
#define SQL_PERF_START 1 // Starts the driver sampling performance data.
|
||||||
|
#define SQL_PERF_STOP 2 // Stops the counters from sampling performance data.
|
||||||
|
// The following are defines for SQL_COPT_SS_PERF_DATA_LOG
|
||||||
|
#define SQL_SS_DL_DEFAULT TEXT("STATS.LOG")
|
||||||
|
// The following are defines for SQL_COPT_SS_PERF_QUERY_LOG
|
||||||
|
#define SQL_SS_QL_DEFAULT TEXT("QUERY.LOG")
|
||||||
|
// The following are defines for SQL_COPT_SS_PERF_QUERY_INTERVAL
|
||||||
|
#define SQL_SS_QI_DEFAULT 30000 // 30,000 milliseconds
|
||||||
|
|
||||||
|
#ifndef SQLNCLI_NO_BCP
|
||||||
|
// Define the symbol SQLNCLI_NO_BCP if you are not using BCP in your application
|
||||||
|
// and you want to exclude the BCP-related definitions in this header file.
|
||||||
|
|
||||||
|
// ODBC BCP prototypes and defines
|
||||||
|
// Return codes
|
||||||
|
#define SUCCEED 1
|
||||||
|
#define FAIL 0
|
||||||
|
#define SUCCEED_ABORT 2
|
||||||
|
#define SUCCEED_ASYNC 3
|
||||||
|
// Transfer directions
|
||||||
|
#define DB_IN 1 // Transfer from client to server
|
||||||
|
#define DB_OUT 2 // Transfer from server to client
|
||||||
|
// bcp_control option
|
||||||
|
#define BCPMAXERRS 1 // Sets max errors allowed
|
||||||
|
#define BCPFIRST 2 // Sets first row to be copied out
|
||||||
|
#define BCPLAST 3 // Sets number of rows to be copied out
|
||||||
|
#define BCPBATCH 4 // Sets input batch size
|
||||||
|
#define BCPKEEPNULLS 5 // Sets to insert NULLs for empty input values
|
||||||
|
#define BCPABORT 6 // Sets to have bcpexec return SUCCEED_ABORT
|
||||||
|
#define BCPODBC 7 // Sets ODBC canonical character output
|
||||||
|
#define BCPKEEPIDENTITY 8 // Sets IDENTITY_INSERT on
|
||||||
|
#if SQLNCLI_VER < 1000
|
||||||
|
#define BCP6xFILEFMT 9 // DEPRECATED: Sets 6x file format on
|
||||||
|
#endif
|
||||||
|
#define BCPHINTSA 10 // Sets server BCP hints (ANSI string)
|
||||||
|
#define BCPHINTSW 11 // Sets server BCP hints (UNICODE string)
|
||||||
|
#define BCPFILECP 12 // Sets clients code page for the file
|
||||||
|
#define BCPUNICODEFILE 13 // Sets that the file contains unicode header
|
||||||
|
#define BCPTEXTFILE 14 // Sets BCP mode to expect a text file and to detect Unicode or ANSI automatically
|
||||||
|
#define BCPFILEFMT 15 // Sets file format version
|
||||||
|
#define BCPFMTXML 16 // Sets the format file type to xml
|
||||||
|
#define BCPFIRSTEX 17 // Starting Row for BCP operation (64 bit)
|
||||||
|
#define BCPLASTEX 18 // Ending Row for BCP operation (64 bit)
|
||||||
|
#define BCPROWCOUNT 19 // Total Number of Rows Copied (64 bit)
|
||||||
|
// BCPFILECP values
|
||||||
|
// Any valid code page that is installed on the client can be passed plus:
|
||||||
|
#define BCPFILECP_ACP 0 // Data in file is in Windows code page
|
||||||
|
#define BCPFILECP_OEMCP 1 // Data in file is in OEM code page (default)
|
||||||
|
#define BCPFILECP_RAW (-1)// Data in file is in Server code page (no conversion)
|
||||||
|
// bcp_collen definition
|
||||||
|
#define SQL_VARLEN_DATA (-10) // Use default length for column
|
||||||
|
// BCP column format properties
|
||||||
|
#define BCP_FMT_TYPE 0x01
|
||||||
|
#define BCP_FMT_INDICATOR_LEN 0x02
|
||||||
|
#define BCP_FMT_DATA_LEN 0x03
|
||||||
|
#define BCP_FMT_TERMINATOR 0x04
|
||||||
|
#define BCP_FMT_SERVER_COL 0x05
|
||||||
|
#define BCP_FMT_COLLATION 0x06
|
||||||
|
#define BCP_FMT_COLLATION_ID 0x07
|
||||||
|
// BCP functions
|
||||||
|
DBINT SQL_API bcp_batch (HDBC);
|
||||||
|
RETCODE SQL_API bcp_bind (HDBC, LPCBYTE, INT, DBINT, LPCBYTE, INT, INT, INT);
|
||||||
|
RETCODE SQL_API bcp_colfmt (HDBC, INT, BYTE, INT, DBINT, LPCBYTE, INT, INT);
|
||||||
|
RETCODE SQL_API bcp_collen (HDBC, DBINT, INT);
|
||||||
|
RETCODE SQL_API bcp_colptr (HDBC, LPCBYTE, INT);
|
||||||
|
RETCODE SQL_API bcp_columns (HDBC, INT);
|
||||||
|
RETCODE SQL_API bcp_control (HDBC, INT, void *);
|
||||||
|
DBINT SQL_API bcp_done (HDBC);
|
||||||
|
RETCODE SQL_API bcp_exec (HDBC, LPDBINT);
|
||||||
|
RETCODE SQL_API bcp_getcolfmt (HDBC, INT, INT, void *, INT, INT *);
|
||||||
|
RETCODE SQL_API bcp_initA (HDBC, LPCSTR, LPCSTR, LPCSTR, INT);
|
||||||
|
RETCODE SQL_API bcp_initW (HDBC, LPCWSTR, LPCWSTR, LPCWSTR, INT);
|
||||||
|
RETCODE SQL_API bcp_moretext (HDBC, DBINT, LPCBYTE);
|
||||||
|
RETCODE SQL_API bcp_readfmtA (HDBC, LPCSTR);
|
||||||
|
RETCODE SQL_API bcp_readfmtW (HDBC, LPCWSTR);
|
||||||
|
RETCODE SQL_API bcp_sendrow (HDBC);
|
||||||
|
RETCODE SQL_API bcp_setcolfmt (HDBC, INT, INT, void *, INT);
|
||||||
|
RETCODE SQL_API bcp_writefmtA (HDBC, LPCSTR);
|
||||||
|
RETCODE SQL_API bcp_writefmtW (HDBC, LPCWSTR);
|
||||||
|
CHAR* SQL_API dbprtypeA (INT);
|
||||||
|
WCHAR* SQL_API dbprtypeW (INT);
|
||||||
|
CHAR* SQL_API bcp_gettypenameA (INT, DBBOOL);
|
||||||
|
WCHAR* SQL_API bcp_gettypenameW (INT, DBBOOL);
|
||||||
|
#ifdef UNICODE
|
||||||
|
#define bcp_init bcp_initW
|
||||||
|
#define bcp_readfmt bcp_readfmtW
|
||||||
|
#define bcp_writefmt bcp_writefmtW
|
||||||
|
#define dbprtype dbprtypeW
|
||||||
|
#define bcp_gettypename bcp_gettypenameW
|
||||||
|
#define BCPHINTS BCPHINTSW
|
||||||
|
#else
|
||||||
|
#define bcp_init bcp_initA
|
||||||
|
#define bcp_readfmt bcp_readfmtA
|
||||||
|
#define bcp_writefmt bcp_writefmtA
|
||||||
|
#define dbprtype dbprtypeA
|
||||||
|
#define bcp_gettypename bcp_gettypenameA
|
||||||
|
#define BCPHINTS BCPHINTSA
|
||||||
|
#endif // UNICODE
|
||||||
|
|
||||||
|
#endif // SQLNCLI_NO_BCP
|
||||||
|
|
||||||
|
// The following options have been deprecated
|
||||||
|
#define SQL_FAST_CONNECT (SQL_COPT_SS_BASE+0)
|
||||||
|
// Defines for use with SQL_FAST_CONNECT - only useable before connecting
|
||||||
|
#define SQL_FC_OFF 0L // Fast connect is off
|
||||||
|
#define SQL_FC_ON 1L // Fast connect is on
|
||||||
|
#define SQL_FC_DEFAULT SQL_FC_OFF
|
||||||
|
#define SQL_COPT_SS_ANSI_OEM (SQL_COPT_SS_BASE+6)
|
||||||
|
#define SQL_AO_OFF 0L
|
||||||
|
#define SQL_AO_ON 1L
|
||||||
|
#define SQL_AO_DEFAULT SQL_AO_OFF
|
||||||
|
#define SQL_CA_SS_BASE_COLUMN_NAME SQL_DESC_BASE_COLUMN_NAME
|
||||||
|
|
||||||
|
#endif // ODBCVER
|
||||||
|
#endif // defined(_SQLNCLI_ODBC_) || !defined(_SQLNCLI_OLEDB_)
|
||||||
|
// ODBC part of SQL Server Native Client header - end here!
|
||||||
|
|
||||||
|
//The following facilitates opening a handle to a SQL filestream
|
||||||
|
typedef enum _SQL_FILESTREAM_DESIRED_ACCESS {
|
||||||
|
SQL_FILESTREAM_READ = 0,
|
||||||
|
SQL_FILESTREAM_WRITE = 1,
|
||||||
|
SQL_FILESTREAM_READWRITE = 2
|
||||||
|
} SQL_FILESTREAM_DESIRED_ACCESS;
|
||||||
|
#define SQL_FILESTREAM_OPEN_FLAG_ASYNC 0x00000001L
|
||||||
|
#define SQL_FILESTREAM_OPEN_FLAG_NO_BUFFERING 0x00000002L
|
||||||
|
#define SQL_FILESTREAM_OPEN_FLAG_NO_WRITE_THROUGH 0x00000004L
|
||||||
|
#define SQL_FILESTREAM_OPEN_FLAG_SEQUENTIAL_SCAN 0x00000008L
|
||||||
|
#define SQL_FILESTREAM_OPEN_FLAG_RANDOM_ACCESS 0x00000010L
|
||||||
|
HANDLE __stdcall OpenSqlFilestream (
|
||||||
|
LPCWSTR FilestreamPath,
|
||||||
|
SQL_FILESTREAM_DESIRED_ACCESS DesiredAccess,
|
||||||
|
ULONG OpenOptions,
|
||||||
|
LPBYTE FilestreamTransactionContext,
|
||||||
|
SSIZE_T FilestreamTransactionContextLength,
|
||||||
|
PLARGE_INTEGER AllocationSize);
|
||||||
|
#define FSCTL_SQL_FILESTREAM_FETCH_OLD_CONTENT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2392, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern RPC_IF_HANDLE __MIDL_itf_sqlncli_0000_0010_v0_0_c_ifspec;
|
||||||
|
extern RPC_IF_HANDLE __MIDL_itf_sqlncli_0000_0010_v0_0_s_ifspec;
|
||||||
|
|
||||||
|
/* Additional Prototypes for ALL interfaces */
|
||||||
|
|
||||||
|
/* end of Additional Prototypes */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
//
|
//
|
||||||
// Contents: Routines that use statement handles
|
// Contents: Routines that use statement handles
|
||||||
//
|
//
|
||||||
// Copyright 2010 Microsoft Corporation
|
// Copyright Microsoft Corporation
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -112,6 +112,18 @@ namespace SSCursorTypes {
|
||||||
const char QUERY_OPTION_SCROLLABLE_DYNAMIC[] = "dynamic";
|
const char QUERY_OPTION_SCROLLABLE_DYNAMIC[] = "dynamic";
|
||||||
const char QUERY_OPTION_SCROLLABLE_KEYSET[] = "keyset";
|
const char QUERY_OPTION_SCROLLABLE_KEYSET[] = "keyset";
|
||||||
const char QUERY_OPTION_SCROLLABLE_FORWARD[] = "forward";
|
const char QUERY_OPTION_SCROLLABLE_FORWARD[] = "forward";
|
||||||
|
const char QUERY_OPTION_SCROLLABLE_BUFFERED[] = "buffered";
|
||||||
|
}
|
||||||
|
|
||||||
|
ss_sqlsrv_stmt::ss_sqlsrv_stmt( sqlsrv_conn* c, SQLHANDLE handle, error_callback e, void* drv TSRMLS_DC ) :
|
||||||
|
sqlsrv_stmt( c, handle, e, drv TSRMLS_CC ),
|
||||||
|
prepared( false ),
|
||||||
|
conn_index( -1 ),
|
||||||
|
params_z( NULL ),
|
||||||
|
fetch_field_names( NULL ),
|
||||||
|
fetch_fields_count ( 0 )
|
||||||
|
{
|
||||||
|
core_sqlsrv_set_buffered_query_limit( this, SQLSRV_G( buffered_query_limit ) TSRMLS_CC );
|
||||||
}
|
}
|
||||||
|
|
||||||
ss_sqlsrv_stmt::~ss_sqlsrv_stmt( void )
|
ss_sqlsrv_stmt::~ss_sqlsrv_stmt( void )
|
||||||
|
@ -132,8 +144,8 @@ 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.
|
// execute or next_result. Resets the state variables and calls the subclass.
|
||||||
void ss_sqlsrv_stmt::new_result_set( void )
|
void ss_sqlsrv_stmt::new_result_set( TSRMLS_D )
|
||||||
{
|
{
|
||||||
if( fetch_field_names != NULL ) {
|
if( fetch_field_names != NULL ) {
|
||||||
|
|
||||||
|
@ -146,7 +158,7 @@ void ss_sqlsrv_stmt::new_result_set( void )
|
||||||
|
|
||||||
fetch_field_names = NULL;
|
fetch_field_names = NULL;
|
||||||
fetch_fields_count = 0;
|
fetch_fields_count = 0;
|
||||||
sqlsrv_stmt::new_result_set();
|
sqlsrv_stmt::new_result_set( TSRMLS_C );
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.
|
||||||
|
@ -164,6 +176,7 @@ sqlsrv_phptype ss_sqlsrv_stmt::sql_type_to_php_type( SQLINTEGER sql_type, SQLUIN
|
||||||
case SQL_GUID:
|
case SQL_GUID:
|
||||||
case SQL_NUMERIC:
|
case SQL_NUMERIC:
|
||||||
case SQL_WCHAR:
|
case SQL_WCHAR:
|
||||||
|
case SQL_SS_VARIANT:
|
||||||
ss_phptype.typeinfo.type = SQLSRV_PHPTYPE_STRING;
|
ss_phptype.typeinfo.type = SQLSRV_PHPTYPE_STRING;
|
||||||
ss_phptype.typeinfo.encoding = this->conn->encoding();
|
ss_phptype.typeinfo.encoding = this->conn->encoding();
|
||||||
break;
|
break;
|
||||||
|
@ -272,7 +285,7 @@ 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 );
|
core_sqlsrv_next_result( stmt TSRMLS_CC, false, false );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -597,11 +610,11 @@ PHP_FUNCTION( sqlsrv_rows_affected )
|
||||||
|
|
||||||
// make sure it is not scrollable. This function should only work for inserts, updates, and deletes,
|
// make sure it is not scrollable. This function should only work for inserts, updates, and deletes,
|
||||||
// but this is the best we can do to enforce that.
|
// but this is the best we can do to enforce that.
|
||||||
CHECK_CUSTOM_ERROR( stmt->scrollable, stmt, SS_SQLSRV_ERROR_STATEMENT_SCROLLABLE ) {
|
CHECK_CUSTOM_ERROR( stmt->cursor_type != SQL_CURSOR_FORWARD_ONLY, stmt, SS_SQLSRV_ERROR_STATEMENT_SCROLLABLE ) {
|
||||||
throw ss::SSException();
|
throw ss::SSException();
|
||||||
}
|
}
|
||||||
|
|
||||||
rows = core::SQLRowCount( stmt TSRMLS_CC );
|
rows = stmt->current_results->row_count( TSRMLS_C );
|
||||||
RETURN_LONG( rows );
|
RETURN_LONG( rows );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -645,11 +658,12 @@ PHP_FUNCTION( sqlsrv_num_rows )
|
||||||
|
|
||||||
// make sure that the statement is scrollable and the cursor is not dynamic.
|
// make sure that the statement is scrollable and the cursor is not dynamic.
|
||||||
// if the cursor is dynamic, then the number of rows returned is always -1.
|
// if the cursor is dynamic, then the number of rows returned is always -1.
|
||||||
CHECK_CUSTOM_ERROR( !stmt->scrollable || stmt->scroll_is_dynamic, stmt, SS_SQLSRV_ERROR_STATEMENT_NOT_SCROLLABLE ) {
|
CHECK_CUSTOM_ERROR( stmt->cursor_type == SQL_CURSOR_FORWARD_ONLY || stmt->cursor_type == SQL_CURSOR_DYNAMIC, stmt,
|
||||||
|
SS_SQLSRV_ERROR_STATEMENT_NOT_SCROLLABLE ) {
|
||||||
throw ss::SSException();
|
throw ss::SSException();
|
||||||
}
|
}
|
||||||
|
|
||||||
rows = core::SQLRowCount( stmt TSRMLS_CC );
|
rows = stmt->current_results->row_count( TSRMLS_C );
|
||||||
RETURN_LONG( rows );
|
RETURN_LONG( rows );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1259,7 +1273,7 @@ void bind_params( ss_sqlsrv_stmt* stmt TSRMLS_DC )
|
||||||
|
|
||||||
zval** var = NULL;
|
zval** var = NULL;
|
||||||
int zr = zend_hash_index_find( Z_ARRVAL_PP( param_z ), 0, reinterpret_cast<void**>( &var ));
|
int zr = zend_hash_index_find( Z_ARRVAL_PP( param_z ), 0, reinterpret_cast<void**>( &var ));
|
||||||
CHECK_CUSTOM_ERROR( zr == FAILURE, stmt, SS_SQLSRV_ERROR_VAR_REQUIRED, index ) {
|
CHECK_CUSTOM_ERROR( zr == FAILURE, stmt, SS_SQLSRV_ERROR_VAR_REQUIRED, index + 1 ) {
|
||||||
zval_ptr_dtor( ¶ms_z );
|
zval_ptr_dtor( ¶ms_z );
|
||||||
throw ss::SSException();
|
throw ss::SSException();
|
||||||
}
|
}
|
||||||
|
@ -1413,7 +1427,8 @@ 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( &stmt_r TSRMLS_CC, -1, ss_sqlsrv_stmt::resource_name, NULL, 1, ss_sqlsrv_stmt::descriptor ));
|
stmt = static_cast<ss_sqlsrv_stmt*>( zend_fetch_resource( &stmt_r TSRMLS_CC, -1, ss_sqlsrv_stmt::resource_name, NULL,
|
||||||
|
1, ss_sqlsrv_stmt::descriptor ));
|
||||||
|
|
||||||
if( stmt == NULL ) {
|
if( stmt == NULL ) {
|
||||||
|
|
||||||
|
@ -1472,6 +1487,11 @@ void stmt_option_scrollable:: operator()( sqlsrv_stmt* stmt, stmt_option const*
|
||||||
cursor_type = SQL_CURSOR_FORWARD_ONLY;
|
cursor_type = SQL_CURSOR_FORWARD_ONLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if( !stricmp( scroll_type, SSCursorTypes::QUERY_OPTION_SCROLLABLE_BUFFERED )) {
|
||||||
|
|
||||||
|
cursor_type = SQLSRV_CURSOR_BUFFERED;
|
||||||
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
|
|
||||||
THROW_SS_ERROR( stmt, SQLSRV_ERROR_INVALID_OPTION_SCROLLABLE );
|
THROW_SS_ERROR( stmt, SQLSRV_ERROR_INVALID_OPTION_SCROLLABLE );
|
||||||
|
@ -1534,6 +1554,11 @@ zval* convert_to_zval( SQLSRV_PHPTYPE sqlsrv_php_type, void** in_val, SQLLEN fie
|
||||||
out_zval = ( reinterpret_cast<zval*>( *in_val ));
|
out_zval = ( reinterpret_cast<zval*>( *in_val ));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SQLSRV_PHPTYPE_NULL:
|
||||||
|
ALLOC_INIT_ZVAL( out_zval );
|
||||||
|
ZVAL_NULL( out_zval );
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DIE( "Unknown php type" );
|
DIE( "Unknown php type" );
|
||||||
break;
|
break;
|
||||||
|
@ -1764,22 +1789,22 @@ void determine_stmt_has_rows( ss_sqlsrv_stmt* stmt TSRMLS_DC )
|
||||||
|
|
||||||
// if the statement is scrollable, our work is easier though less performant. We simply
|
// if the statement is scrollable, our work is easier though less performant. We simply
|
||||||
// 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->scrollable ) {
|
if( stmt->cursor_type != SQL_CURSOR_FORWARD_ONLY ) {
|
||||||
|
|
||||||
r = core::SQLFetchScroll( stmt, SQL_FETCH_FIRST, 0 TSRMLS_CC );
|
r = stmt->current_results->fetch( SQL_FETCH_FIRST, 0 TSRMLS_CC );
|
||||||
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 = SQLFetchScroll( stmt->handle(), SQL_FETCH_ABSOLUTE, 0 );
|
r = stmt->current_results->fetch( SQL_FETCH_ABSOLUTE, 0 TSRMLS_CC );
|
||||||
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." );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
// otherwise, we fetch the first row, but record that we di. sqlsrv_fetch checks this
|
// otherwise, we fetch the first row, but record that we did. sqlsrv_fetch checks this
|
||||||
// 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.
|
||||||
|
|
||||||
|
@ -1823,7 +1848,7 @@ void fetch_fields_common( __inout ss_sqlsrv_stmt* stmt, int fetch_type, __out zv
|
||||||
|
|
||||||
core::SQLColAttribute( stmt, i + 1, SQL_DESC_NAME, field_name_temp, SS_MAXCOLNAMELEN+1, &field_name_len, NULL
|
core::SQLColAttribute( stmt, i + 1, SQL_DESC_NAME, field_name_temp, SS_MAXCOLNAMELEN+1, &field_name_len, NULL
|
||||||
TSRMLS_CC );
|
TSRMLS_CC );
|
||||||
field_names[ i ].name = static_cast<char*>( sqlsrv_malloc( field_name_len + 1 ));
|
field_names[ i ].name = static_cast<char*>( sqlsrv_malloc( field_name_len, sizeof( char ), 1 ));
|
||||||
memcpy( (void*) field_names[ i ].name, field_name_temp, field_name_len );
|
memcpy( (void*) field_names[ i ].name, field_name_temp, field_name_len );
|
||||||
field_names[ i ].name[ field_name_len ] = '\0'; // null terminate the field name since SQLColAttribute doesn't.
|
field_names[ i ].name[ field_name_len ] = '\0'; // null terminate the field name since SQLColAttribute doesn't.
|
||||||
field_names[ i ].len = field_name_len + 1;
|
field_names[ i ].len = field_name_len + 1;
|
||||||
|
@ -1908,7 +1933,7 @@ void parse_param_array( ss_sqlsrv_stmt* stmt, __inout zval* param_array, unsigne
|
||||||
if( zend_hash_has_more_elements( param_ht ) == FAILURE ||
|
if( zend_hash_has_more_elements( param_ht ) == FAILURE ||
|
||||||
zend_hash_get_current_data( param_ht, (void**) &var_or_val ) == FAILURE ) {
|
zend_hash_get_current_data( param_ht, (void**) &var_or_val ) == FAILURE ) {
|
||||||
|
|
||||||
THROW_SS_ERROR( stmt, SS_SQLSRV_ERROR_VAR_REQUIRED, index );
|
THROW_SS_ERROR( stmt, SS_SQLSRV_ERROR_VAR_REQUIRED, index + 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the direction is included, then use what they gave, otherwise INPUT is assumed
|
// if the direction is included, then use what they gave, otherwise INPUT is assumed
|
||||||
|
@ -1921,7 +1946,7 @@ void parse_param_array( ss_sqlsrv_stmt* stmt, __inout zval* param_array, unsigne
|
||||||
}
|
}
|
||||||
direction = Z_LVAL_PP( temp );
|
direction = Z_LVAL_PP( temp );
|
||||||
CHECK_CUSTOM_ERROR( direction != SQL_PARAM_INPUT && direction != SQL_PARAM_OUTPUT && direction != SQL_PARAM_INPUT_OUTPUT,
|
CHECK_CUSTOM_ERROR( direction != SQL_PARAM_INPUT && direction != SQL_PARAM_OUTPUT && direction != SQL_PARAM_INPUT_OUTPUT,
|
||||||
stmt, SS_SQLSRV_ERROR_INVALID_PARAMETER_DIRECTION, index ) {
|
stmt, SS_SQLSRV_ERROR_INVALID_PARAMETER_DIRECTION, index + 1 ) {
|
||||||
throw ss::SSException();
|
throw ss::SSException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
//
|
//
|
||||||
// Contents: Version resource
|
// Contents: Version resource
|
||||||
//
|
//
|
||||||
// Copyright 2010 Microsoft Corporation
|
// Copyright Microsoft Corporation
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -65,7 +65,7 @@ BEGIN
|
||||||
VALUE "FileDescription", "Microsoft Drivers for PHP for SQL Server (SQLSRV Driver)\0"
|
VALUE "FileDescription", "Microsoft Drivers for PHP for SQL Server (SQLSRV Driver)\0"
|
||||||
VALUE "FileVersion", STRVER4(SQLVERSION_MAJOR,SQLVERSION_MINOR, SQLVERSION_MMDD, SQLVERSION_REVISION)
|
VALUE "FileVersion", STRVER4(SQLVERSION_MAJOR,SQLVERSION_MINOR, SQLVERSION_MMDD, SQLVERSION_REVISION)
|
||||||
VALUE "InternalName", FILE_NAME "\0"
|
VALUE "InternalName", FILE_NAME "\0"
|
||||||
VALUE "LegalCopyright", "Copyright 2010 Microsoft Corporation.\0"
|
VALUE "LegalCopyright", "Copyright Microsoft Corporation.\0"
|
||||||
VALUE "OriginalFilename", FILE_NAME "\0"
|
VALUE "OriginalFilename", FILE_NAME "\0"
|
||||||
VALUE "ProductName", "Microsoft Drivers for PHP for SQL Server\0"
|
VALUE "ProductName", "Microsoft Drivers for PHP for SQL Server\0"
|
||||||
VALUE "ProductVersion", STRVER3(SQLVERSION_MAJOR,SQLVERSION_MINOR, SQLVERSION_MMDD)
|
VALUE "ProductVersion", STRVER3(SQLVERSION_MAJOR,SQLVERSION_MINOR, SQLVERSION_MMDD)
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
//
|
//
|
||||||
// Comments: Mostly error handling and some type handling
|
// Comments: Mostly error handling and some type handling
|
||||||
//
|
//
|
||||||
// Copyright 2010 Microsoft Corporation
|
// Copyright Microsoft Corporation
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -218,8 +218,8 @@ ss_error SS_ERRORS[] = {
|
||||||
|
|
||||||
// these three errors are returned for invalid options, so they are given the same number for compatibility with 1.1
|
// these three errors are returned for invalid options, so they are given the same number for compatibility with 1.1
|
||||||
{
|
{
|
||||||
SQLSRV_ERROR_INVALID_OPTION_VALUE,
|
SQLSRV_ERROR_INVALID_QUERY_TIMEOUT_VALUE,
|
||||||
{ IMSSP, (SQLCHAR*) "Invalid value specified for option %1!s!.", -33, true }
|
{ IMSSP, (SQLCHAR*) "Invalid value %1!s! specified for option SQLSRV_QUERY_TIMEOUT.", -33, true }
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -301,9 +301,8 @@ ss_error SS_ERRORS[] = {
|
||||||
|
|
||||||
{
|
{
|
||||||
SQLSRV_ERROR_DRIVER_NOT_INSTALLED,
|
SQLSRV_ERROR_DRIVER_NOT_INSTALLED,
|
||||||
{ IMSSP, (SQLCHAR*) "This extension requires either the Microsoft SQL Server 2008 Native Client (SP1 or later) or the "
|
{ IMSSP, (SQLCHAR*) "This extension requires the Microsoft SQL Server 2011 Native Client. "
|
||||||
"Microsoft SQL Server 2008 R2 Native Client ODBC Driver to communicate with SQL Server. Neither of those ODBC Drivers are currently installed. "
|
"Access the following URL to download the Microsoft SQL Server 2011 Native Client ODBC driver for %1!s!: "
|
||||||
"Access the following URL to download the Microsoft SQL Server 2008 R2 Native Client ODBC driver for %1!s!: "
|
|
||||||
"http://go.microsoft.com/fwlink/?LinkId=163712", -49, true }
|
"http://go.microsoft.com/fwlink/?LinkId=163712", -49, true }
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -332,7 +331,7 @@ ss_error SS_ERRORS[] = {
|
||||||
{
|
{
|
||||||
SQLSRV_ERROR_INVALID_OPTION_SCROLLABLE,
|
SQLSRV_ERROR_INVALID_OPTION_SCROLLABLE,
|
||||||
{ IMSSP, (SQLCHAR*)"The value passed for the 'Scrollable' statement option is invalid. Please use 'static', 'dynamic', "
|
{ IMSSP, (SQLCHAR*)"The value passed for the 'Scrollable' statement option is invalid. Please use 'static', 'dynamic', "
|
||||||
"'keyset', or 'forward'.", -54, false }
|
"'keyset', 'forward', or 'buffered'.", -54, false }
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -354,6 +353,14 @@ ss_error SS_ERRORS[] = {
|
||||||
SQLSRV_ERROR_OUTPUT_PARAM_TRUNCATED,
|
SQLSRV_ERROR_OUTPUT_PARAM_TRUNCATED,
|
||||||
{ IMSSP, (SQLCHAR*) "String data, right truncated for output parameter %1!d!.", -58, true }
|
{ IMSSP, (SQLCHAR*) "String data, right truncated for output parameter %1!d!.", -58, true }
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
SQLSRV_ERROR_BUFFER_LIMIT_EXCEEDED,
|
||||||
|
{ IMSSP, (SQLCHAR*) "Memory limit of %1!d! KB exceeded for buffered query", -59, true }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
SQLSRV_ERROR_INVALID_BUFFER_LIMIT,
|
||||||
|
{ IMSSP, (SQLCHAR*) "Setting for " INI_BUFFERED_QUERY_LIMIT " was non-int or non-positive.", -60, false }
|
||||||
|
},
|
||||||
|
|
||||||
// internal warning definitions
|
// internal warning definitions
|
||||||
{
|
{
|
||||||
|
@ -402,7 +409,8 @@ bool ss_error_handler(sqlsrv_context& ctx, unsigned int sqlsrv_error_code, bool
|
||||||
severity = SEV_WARNING;
|
severity = SEV_WARNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
return handle_errors_and_warnings( ctx, &SQLSRV_G( errors ), &SQLSRV_G( warnings ), severity, sqlsrv_error_code, warning, print_args TSRMLS_CC );
|
return handle_errors_and_warnings( ctx, &SQLSRV_G( errors ), &SQLSRV_G( warnings ), severity, sqlsrv_error_code, warning,
|
||||||
|
print_args TSRMLS_CC );
|
||||||
}
|
}
|
||||||
|
|
||||||
// sqlsrv_errors( [int $errorsAndOrWarnings] )
|
// sqlsrv_errors( [int $errorsAndOrWarnings] )
|
||||||
|
@ -595,6 +603,25 @@ PHP_FUNCTION( sqlsrv_configure )
|
||||||
RETURN_TRUE;
|
RETURN_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if( !stricmp( option, INI_BUFFERED_QUERY_LIMIT )) {
|
||||||
|
|
||||||
|
CHECK_CUSTOM_ERROR(( Z_TYPE_P( value_z ) != IS_LONG ), error_ctx, SQLSRV_ERROR_INVALID_BUFFER_LIMIT, _FN_ ) {
|
||||||
|
|
||||||
|
throw ss::SSException();
|
||||||
|
}
|
||||||
|
|
||||||
|
long buffered_query_limit = Z_LVAL_P( value_z );
|
||||||
|
|
||||||
|
CHECK_CUSTOM_ERROR( buffered_query_limit < 0, error_ctx, SQLSRV_ERROR_INVALID_BUFFER_LIMIT, _FN_ ) {
|
||||||
|
|
||||||
|
throw ss::SSException();
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLSRV_G( buffered_query_limit ) = buffered_query_limit;
|
||||||
|
LOG( SEV_NOTICE, INI_PREFIX INI_BUFFERED_QUERY_LIMIT " = %1!d!", SQLSRV_G( buffered_query_limit ));
|
||||||
|
RETURN_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
|
|
||||||
THROW_CORE_ERROR( error_ctx, SS_SQLSRV_ERROR_INVALID_FUNCTION_PARAMETER, _FN_ );
|
THROW_CORE_ERROR( error_ctx, SS_SQLSRV_ERROR_INVALID_FUNCTION_PARAMETER, _FN_ );
|
||||||
|
@ -666,6 +693,11 @@ PHP_FUNCTION( sqlsrv_get_config )
|
||||||
ZVAL_LONG( return_value, SQLSRV_G( log_subsystems ));
|
ZVAL_LONG( return_value, SQLSRV_G( log_subsystems ));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if( !stricmp( option, INI_BUFFERED_QUERY_LIMIT )) {
|
||||||
|
|
||||||
|
ZVAL_LONG( return_value, SQLSRV_G( buffered_query_limit ));
|
||||||
|
return;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
THROW_CORE_ERROR( error_ctx, SS_SQLSRV_ERROR_INVALID_FUNCTION_PARAMETER, _FN_ );
|
THROW_CORE_ERROR( error_ctx, SS_SQLSRV_ERROR_INVALID_FUNCTION_PARAMETER, _FN_ );
|
||||||
|
@ -773,8 +805,6 @@ bool handle_errors_and_warnings( sqlsrv_context& ctx, zval** reported_chain, zva
|
||||||
zval* error_z = NULL;
|
zval* error_z = NULL;
|
||||||
sqlsrv_error_auto_ptr error;
|
sqlsrv_error_auto_ptr error;
|
||||||
|
|
||||||
error = new ( sqlsrv_malloc( sizeof( sqlsrv_error ))) sqlsrv_error;
|
|
||||||
|
|
||||||
// array of reported errors
|
// array of reported errors
|
||||||
if( Z_TYPE_P( *reported_chain ) == IS_NULL ) {
|
if( Z_TYPE_P( *reported_chain ) == IS_NULL ) {
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
//---------------------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------------------
|
||||||
// File: version.h
|
// File: version.h
|
||||||
//
|
//
|
||||||
// Contents: Version information for compile and resources
|
// Contents: Version number constants
|
||||||
//
|
//
|
||||||
// Copyright 2010 Microsoft Corporation
|
// Copyright Microsoft Corporation
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -16,11 +16,11 @@
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//---------------------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
#define VER_FILEVERSION_STR "2.0.0.200"
|
#define VER_FILEVERSION_STR "3.0.0.0"
|
||||||
#define _FILEVERSION 2,0,0,200
|
#define _FILEVERSION 3,0,0,0
|
||||||
#define SQLVERSION_MAJOR 2
|
#define SQLVERSION_MAJOR 3
|
||||||
#define SQLVERSION_MINOR 0
|
#define SQLVERSION_MINOR 0
|
||||||
#define SQLVERSION_MMDD 0
|
#define SQLVERSION_MMDD 0
|
||||||
#define SQLVERSION_REVISION 200
|
#define SQLVERSION_REVISION 0
|
||||||
|
|
Loading…
Reference in a new issue