PHP Linux 4.0.5 Commit

This commit is contained in:
Meet Bhagdev 2016-10-03 13:19:15 -07:00
parent 5bef0b8dd2
commit 779f65360f
28 changed files with 637 additions and 185 deletions

View file

@ -25,7 +25,9 @@ You can install both the unixODBC driver manager and the ODBC driver using the s
[![pic1](https://msdnshared.blob.core.windows.net/media/2016/07/image1101.png)](https://msdnshared.blob.core.windows.net/media/2016/07/image1101.png)
###Install Apache: You are now ready to install Apache. You can install from source, or you can use your package manager. ###
###Install Apache
You are now ready to install Apache. You can install from source, or you can use your package manager.
To install from source, follow these instructions.
1. From the Apache web site, download the Apache source. Go to [http://httpd.apache.org/download.cgi#apache24](http://httpd.apache.org/download.cgi) and click on the link to the tar.gz file. In what follows, we'll assume it is `httpd-2.4.20.tar.gz`. Take note of the directory to which it is downloaded.
@ -131,6 +133,7 @@ Follow these steps to install from the package manager on Red Hat/CentOS:
`yum-config-manager --enable remi-php70`
3. Run `sudo yum install php php-pdo` to install both PHP and the Apache module.
4. Run `sudo yum update`.
Remi RPM repository also provides a package to install Microsoft PHP drivers for SQLServer in Red Hat/CentOS. After following the steps above, all you need to do is
@ -139,7 +142,7 @@ Remi RPM repository also provides a package to install Microsoft PHP drivers for
To confirm that the drivers have been installed, run `php -m` and you should find both `sqlsrv` and `pdo_sqlsrv` amongst the list of modules.
###Compiling and installing Microsoft PHP drivers for SQLServer from source:
###Compiling and installing Microsoft PHP drivers for SQL Server from source:
Instead of using the precompiled binaries, you can compile your own when compiling PHP. To compile the binaries yourself, follow these steps:
@ -158,9 +161,8 @@ Instead of using the precompiled binaries, you can compile your own when compili
a. `CXXFLAGS=-std=c++11` to ensure your compiler uses the C++11 standard.
b. `--enable-sqlsrv=shared`
c. `--with-pdo_sqlsrv=shared`
d. `--with-odbcver=0x0380`. This option has no practical effect as the drivers use ODBC version 3.52, but it suppresses compilation warnings arising from the fact that PHP's default setting of version 3.00 is different from unixODBC's setting of 3.80.
Thus your `./configure` command should look like `./configure --with-apxs2=<path-to-apxs-executable> --disable-maintainer-zts CXXFLAGS=-std=c++11 --enable-sqlsrv=shared --with-pdo_sqlsrv=shared --with-odbcver=0x0380`.
Thus your `./configure` command should look like `./configure --with-apxs2=<path-to-apxs-executable> --disable-maintainer-zts CXXFLAGS=-std=c++11 --enable-sqlsrv=shared --with-pdo_sqlsrv=shared`.
Note: if you get a message saying `WARNING: unrecognized options: --enable-sqlsrv, --with-pdo_sqlsrv`, run `touch ext/*/config.m4` and then `./buildconf --force` before trying `./configure` again.
@ -170,8 +172,32 @@ Instead of using the precompiled binaries, you can compile your own when compili
6. Edit your apache configuration file as described in step 6 above.
###Installing Microsoft PHP drivers for SQL Server using PECL packages:
Now edit your `php.ini` file to load the PHP drivers when PHP starts.
You can install the SQL Server drivers using PHP's PECL package system. This can be done after having installed PHP from source or from package.
1. If installing PHP from source, download the PHP sources and run `./buildconf` as described above. Run `./configure` (without extra options), `make`, and `sudo make install` to install PHP.
If installing PHP from package, install php as described above. In addition, on Ubuntu install php-pear and php-dev using `sudo apt-get install php-pear php-dev`.
2. Verify that `pear` and `pecl` are installed by running `pear version` and `pecl version`. If they are not, go to step 4.
3. Run `sudo pecl search sqlsrv` to list the available sqlsrv and pdo_sqlsrv extensions. Take note of the version number and run `sudo pecl install sqlsrv-<version-number>` and `sudo pecl install pdo_sqlsrv-<version-number>` to install the drivers. If you do not include the version number, you will install the latest 'stable' release, which does not work with PHP 7.
4. If `pear` and `pecl` are not installed, you can download the [SQLSRV](http://pecl.php.net/package/sqlsrv) and [PDO_SQLSRV](http://pecl.php.net/package/pdo_sqlsrv) PECL packages from pecl.php.net (click on 'Latest Tarball' to download). You can then install the SQLSRV driver as follows:
`tar xvzf sqlsrv-<version-number>.tgz`
`cd sqlsrv-<version-number>/`
`phpize`
`./configure`
`make`
`sudo make install`
and similarly for the PDO_SQLSRV driver.
###Loading the drivers
Finally, edit your `php.ini` file to load the PHP drivers when PHP starts.
1. To find the location of your `php.ini` file, run `php --ini` to find the directory PHP searches for `php.ini`. You will see output similar to the following:
@ -179,7 +205,10 @@ Now edit your `php.ini` file to load the PHP drivers when PHP starts.
If you installed PHP from package, the output will be slightly different and will probably list more .ini files, but you will likely need to edit only the `php.ini` file listed under `Loaded Configuration File`.
2. If `Loaded Configuration File` shows that a `php.ini` is loaded, edit that file. Otherwise go to the PHP directory in your home directory, run `cp php.ini-development php.ini` and copy the newly created `php.ini` file to the `Configuration File (php.ini) Path` indicated when running `php --ini`. If using the SQLSRV driver, add the following lines to your php.ini: `extension=php_sqlsrv_7_ts.so` or `extension=php_sqlsrv_7_nts.so` If using the PDO_SQLSRV driver, add `extension=php_pdo_sqlsrv_7_ts.so` or `extension=php_pdo_sqlsrv_7_nts.so`. Change the names of the drivers accordingly if you have compiled them from source and they have different names. If necessary, specify the extension directory using extension_dir, for example: `extension_dir = “/usr/local/lib/php/extensions/”`. To find the default extension directory, run `php -i | grep extension_dir`.
2. If `Loaded Configuration File` shows that a `php.ini` is loaded, edit that file. Otherwise go to the PHP directory in your home directory, run `cp php.ini-development php.ini` and copy the newly created `php.ini` file to the `Configuration File (php.ini) Path` indicated when running `php --ini`. If using the SQLSRV driver, add the following lines to your php.ini: `extension=php_sqlsrv_7_ts.so` or `extension=php_sqlsrv_7_nts.so`. If using the PDO_SQLSRV driver, add `extension=php_pdo_sqlsrv_7_ts.so` or `extension=php_pdo_sqlsrv_7_nts.so`. Change the names of the drivers accordingly if you have compiled them from source and they have different names. If necessary, specify the extension directory using extension_dir, for example: `extension_dir = “/usr/local/lib/php/extensions/”`. To find the default extension directory, run `php -i | grep extension_dir`.
Note that you can add lines to php.ini from the command line as follows:
`echo "extension=sqlsrv.so" | sudo tee --append <path-to-php.ini>`
3. Stop and restart the Apache web server.
@ -205,3 +234,5 @@ Apache Portable Runtime (APR): [http://apr.apache.org/download.cgi](http://apr.a
PHP source download page: [http://php.net/downloads.php](http://php.net/downloads.php)
Ondrej PPA repository: [https://launchpad.net/~ondrej/+archive/ubuntu/php](https://launchpad.net/~ondrej/+archive/ubuntu/php)
Remi RPM repository: [http://blog.remirepo.net/post/2016/02/14/Install-PHP-7-on-CentOS-RHEL-Fedora](http://blog.remirepo.net/post/2016/02/14/Install-PHP-7-on-CentOS-RHEL-Fedora)
PECL SQLSRV package: [http://pecl.php.net/package/sqlsrv](http://pecl.php.net/package/sqlsrv)
PECL PDO_SQLSRV package: [http://pecl.php.net/package/pdo_sqlsrv](http://pecl.php.net/package/pdo_sqlsrv)

View file

@ -10,6 +10,12 @@ SQL Server Team
##Announcements
**October 4, 2016**: We are excited to announce that PECL packages for Linux SQLSRV and PDO_SQLSRV drivers (4.0.5) are available. You can also find pre-compiled binaries (4.0.5) with PHP 7.0.11 for Ubuntu 15.04, Ubuntu 16.04, and RedHat 7.2 [here](https://github.com/Microsoft/msphpsql/releases). This release includes the following fixes:
- Fixed segmentation fault when calling PDOStatement::getColumnMeta on RedHat 7.2.
- Fixed segmentation fault when fetch mode is set to ATTR_EMULATE_PREPARES on RedHat 7.2.
- Fixed [issue #139](https://github.com/Microsoft/msphpsql/issues/139) : sqlsrv_fetch_object calls custom class constructor in static context and outputs an error.
**September 9, 2016**: Linux drivers (4.0.4) compiled with PHP 7.0.10 are available for Ubuntu 15.04, Ubuntu 16.04, and RedHat 7.2. This release includes the following fixes:
- Fixed undefined symbols at SQL* error when loading the drivers.
@ -57,16 +63,19 @@ SQL Server Team
June 20, 2016 (4.0.0): The early technical preview (ETP) for SQLSRV and PDO_SQLSRV drivers for Linux with basic functionalities is now available. The SQLSRV driver has been built and tested on Ubuntu 15.04, Ubuntu 16.04, and RedHat 7.2, and PDO_SQLSRV driver has been built and tested on Ubuntu 15.04, Ubuntu 16.04.
####Prerequisites
- A Web server such as Apache is required. Your Web server must be configured to run PHP. See below for information on installing Apache to work with the drivers.
- [Microsoft ODBC Driver 13 for Linux][odbcLinux]
- 64-bit [UnixODBC 2.3.1 driver manager][LinuxDM], built for 64-bit SQLLEN/SQLULEN.
- If building PHP from source, you need libraries required to [build PHP][PHPMan].
## Install
For detailed instructions please review the tutorial [here](https://github.com/Azure/msphpsql/blob/PHP-7.0-Linux/LinuxTutorial.md).
####Prerequisites
- A Web server such as Apache is required. Your Web server must be configured to run PHP. See below for information on installing Apache to work with the drivers.
- [Microsoft ODBC Driver 13 for Linux][odbcLinux], you can install ODBC drivers using [ODBC command line installers][ODBCinstallers], or [ODBC install scripts](https://github.com/Microsoft/msphpsql/tree/PHP-7.0-Linux/ODBC%20install%20scripts).
- 64-bit [UnixODBC 2.3.1 driver manager][LinuxDM], built for 64-bit SQLLEN/SQLULEN.
- If building PHP from source, you need libraries required to [build PHP][PHPMan].
####Tutorial
- For detailed instructions please review the tutorial [here](https://github.com/Azure/msphpsql/blob/PHP-7.0-Linux/LinuxTutorial.md).
The drivers are distributed as shared binary extensions for PHP. They are available in thread safe (*_ts.so) and-non thread safe (*_nts.so) versions. The source code for the drivers is also available, and you can choose whether to compile them as thread safe or non-thread safe versions. The thread safety configuration of your web server will determine which version you need. If you wish to install Apache from source, follow these instructions:
@ -87,7 +96,7 @@ Now you are ready to install PHP.
Make sure the packaged PHP version is PHP 7. You may need to add repositories to obtain PHP 7 as described in the [tutorial]((https://github.com/Azure/msphpsql/blob/PHP-7.0-Linux/LinuxTutorial.md)).
1. Use your package manager to install the php package and if you are installing SQLSRV_PDO drivers install the php-pdo package.
1. Use your package manager to install the php package and if you are installing PDO_SQLSRV drivers install the php-pdo package.
2. Copy the precompiled binaries into the extensions directory (likely in /usr/lib/php).
3. Edit the php.ini file as indicated in the "Enable the drivers" section.
@ -118,11 +127,12 @@ Now you are ready to install PHP.
2. Run `./configure` with the same options listed above, in addition to the following:
(i) `--enable-sqlsrv=shared`
(ii) `--with-pdo_sqlsrv=shared`
(iii) `--with-odbcver=0x0380`. This option has no practical effect as the drivers use ODBC version 3.52, but it suppresses compilation warnings arising from the fact that PHP's default setting of version 3.00 is different from unixODBC's setting of 3.80.
(i) `CXXFLAGS=-std=c++11` to ensure your compiler uses the C++11 standard.
(ii) `--enable-sqlsrv=shared `
(iii)`--with-pdo_sqlsrv=shared`
Thus your `./configure` command should look like `./configure --with-apxs2=<path-to-apxs-executable> --enable-sqlsrv=shared --with-pdo_sqlsrv=shared --with-odbcver=0x0380`.
Thus your `./configure` command should look like `./configure --with-apxs2=<path-to-apxs-executable> CXXFLAGS=-std=c++11 --enable-sqlsrv=shared --with-pdo_sqlsrv=shared`.
3. Run `make`. The compiled drivers will be located in the `modules/` directory, and are named `sqlsrv.so` and `pdo_sqlsrv.so`.
@ -134,10 +144,20 @@ Now you are ready to install PHP.
1. Switch to the source directory of the extension you want to install, e.g. `source/sqlsrv` or `source/pdo_sqlsrv`.
2. Run `phpize && ./configure && make` to compile the extension.
2. Run `phpize && ./configure CXXFLAGS=-std=c++11 && make` to compile the extension.
3. Run `sudo make install` to install the binaries into the default php extensions directory.
- Method 5: install the drivers with PECL:
1. Use your package manager to install the php package and if you are installing PDO_SQLSRV drivers install the php-pdo package. Make sure the packaged PHP version is PHP 7. You may need to add repositories to obtain PHP 7 as described in the [tutorial]((https://github.com/Azure/msphpsql/blob/PHP-7.0-Linux/LinuxTutorial.md)).
2. Use your package manager and install `php-pear` and `php-dev`.
3. Run `pecl search sqlsrv`, you should get the list of sqlsrv and pdo_sqlsrv packages with their associated version. For example, `pdo_sqlsrv 4.0.5 (devel) 4.0.5 Microsoft Drivers for PHP for SQL Server (PDO_SQLSRV)`.
4. Run `sudo pecl install pdo_sqlsrv-4.0.5` .
####Enable the drivers
1. Make sure that the driver is in your PHP extensions directory.
@ -166,9 +186,8 @@ The following items have known issues:
- Integrated authentication is not supported.
- Buffered cursors are not supported.
- Fetch object and fetch array have issues.
- lastInsertId().
- Query from large column name.
- Binary column binding with emulate prepare ([issue#140](https://github.com/Microsoft/msphpsql/issues/140) )
- Binary column binding with emulate prepare ([issue#140](https://github.com/Microsoft/msphpsql/issues/140))
@ -248,3 +267,5 @@ This project has adopted the Microsoft Open Source Code of Conduct. For more inf
[apr_source]: http://apr.apache.org/
[httpdconf]: http://php.net/manual/en/install.unix.apache2.php
[ODBCinstallers]: https://blogs.msdn.microsoft.com/sqlnativeclient/2016/09/06/preview-release-of-the-sql-server-cc-odbc-driver-13-0-0-for-linux

BIN
pear_pecl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 KiB

14
source/pdo_sqlsrv/LICENSE Normal file
View file

@ -0,0 +1,14 @@
Copyright(c) 2016 Microsoft Corporation
All rights reserved.
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.

View file

@ -38,8 +38,7 @@ if test "$PHP_PDO_SQLSRV" != "no"; then
FormattedPrint.cpp \
localizationimpl.cpp \
"
PHP_ADD_INCLUDE($PDO_SQLSRV_DIR/include)
PHP_REQUIRE_CXX()
PHP_ADD_LIBRARY(stdc++, 1, PDO_SQLSRV_SHARED_LIBADD)
PHP_ADD_LIBRARY(odbc, 1, PDO_SQLSRV_SHARED_LIBADD)

View file

@ -112,7 +112,6 @@ sqlsrv_conn* core_sqlsrv_connect( sqlsrv_context& henv_cp, sqlsrv_context& henv_
if( options_ht && zend_hash_num_elements( options_ht ) > 0 ) {
zval* option_z = NULL;
int zr = SUCCESS;
option_z = zend_hash_index_find(options_ht, SQLSRV_CONN_OPTION_CONN_POOLING);
if (option_z) {
@ -557,10 +556,8 @@ void build_connection_string_and_set_conn_attr( sqlsrv_conn* conn, const char* s
HashTable* options, const connection_option valid_conn_opts[],
void* driver,_Inout_ std::string& connection_string TSRMLS_DC )
{
bool credentials_mentioned = false;
bool mars_mentioned = false;
connection_option const* conn_opt;
int zr = SUCCESS;
try {

View file

@ -34,7 +34,9 @@ namespace {
// *** internal types ***
#if defined(_MSC_VER)
#pragma warning(disable:4200)
#endif
// *** internal constants ***
@ -515,7 +517,6 @@ sqlsrv_buffered_result_set::sqlsrv_buffered_result_set( sqlsrv_stmt* stmt TSRMLS
}
if( *out_buffer_length == SQL_NULL_DATA ) {
unsigned char* null_bits = reinterpret_cast<unsigned char*>( row );
set_bit( row, i );
}
}
@ -1137,9 +1138,6 @@ SQLRETURN sqlsrv_buffered_result_set::wide_to_system_string( SQLSMALLINT field_i
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)));
@ -1147,6 +1145,9 @@ SQLRETURN sqlsrv_buffered_result_set::wide_to_system_string( SQLSMALLINT field_i
temp_length = SystemLocale::FromUtf16( CP_ACP, (LPCWSTR) field_data, static_cast<int>(field_len / sizeof(WCHAR)),
(LPSTR) temp_string.get(), static_cast<int>(field_len) );
#else
BOOL default_char_used = FALSE;
char default_char = '?';
temp_length = WideCharToMultiByte( CP_ACP, 0, (LPCWSTR) field_data, static_cast<int>(field_len / sizeof(WCHAR)),
(LPSTR) temp_string.get(), static_cast<int>(field_len), &default_char, &default_char_used );
#endif

View file

@ -93,8 +93,10 @@ OACR_WARNING_DISABLE( ALLOC_SIZE_OVERFLOW_WITH_ACCESS, "Third party code." )
extern "C" {
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning( disable: 4005 4100 4127 4142 4244 4505 4530 )
#endif
#ifdef ZTS
#include "TSRM.h"
@ -110,7 +112,10 @@ typedef int socklen_t;
#define HAVE_SOCKLEN_T
#endif
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
#if ZEND_DEBUG
// debug build causes warning C4505 to pop up from the Zend header files
@ -831,8 +836,8 @@ class sqlsrv_context {
sqlsrv_context( SQLSMALLINT type, error_callback e, void* drv, SQLSRV_ENCODING encoding = SQLSRV_ENCODING_INVALID ) :
handle_( SQL_NULL_HANDLE ),
handle_type_( type ),
err_( e ),
name_( NULL ),
err_( e ),
driver_( drv ),
last_error_(),
encoding_( encoding )
@ -842,8 +847,8 @@ class sqlsrv_context {
sqlsrv_context( SQLHANDLE h, SQLSMALLINT t, error_callback e, void* drv, SQLSRV_ENCODING encoding = SQLSRV_ENCODING_INVALID ) :
handle_( h ),
handle_type_( t ),
err_( e ),
name_( NULL ),
err_( e ),
driver_( drv ),
last_error_(),
encoding_( encoding )
@ -853,8 +858,8 @@ class sqlsrv_context {
sqlsrv_context( sqlsrv_context const& ctx ) :
handle_( ctx.handle_ ),
handle_type_( ctx.handle_type_ ),
err_( ctx.err_ ),
name_( ctx.name_ ),
err_( ctx.err_ ),
driver_( ctx.driver_ ),
last_error_( ctx.last_error_ )
{
@ -1237,8 +1242,8 @@ struct sqlsrv_output_param {
// every other type output parameter constructor
sqlsrv_output_param( zval* p_z, int num, bool is_bool ) :
param_z( p_z ),
param_num( num ),
encoding( SQLSRV_ENCODING_INVALID ),
param_num( num ),
original_buffer_len( -1 ),
is_bool( is_bool )
{

View file

@ -126,12 +126,12 @@ sqlsrv_stmt::sqlsrv_stmt( sqlsrv_conn* c, SQLHANDLE handle, error_callback e, vo
fetch_called( false ),
last_field_index( -1 ),
past_next_result_end( false ),
query_timeout( QUERY_TIMEOUT_INVALID ),
buffered_query_limit( sqlsrv_buffered_result_set::BUFFERED_QUERY_LIMIT_INVALID ),
param_ind_ptrs( 10 ), // initially hold 10 elements, which should cover 90% of the cases and only take < 100 byte
send_streams_at_exec( true ),
current_stream( NULL, SQLSRV_ENCODING_DEFAULT ),
current_stream_read( 0 ),
query_timeout( QUERY_TIMEOUT_INVALID ),
buffered_query_limit( sqlsrv_buffered_result_set::BUFFERED_QUERY_LIMIT_INVALID )
current_stream_read( 0 )
{
ZVAL_UNDEF( &active_stream );
// initialize the input string parameters array (which holds zvals)
@ -237,6 +237,7 @@ sqlsrv_stmt* core_sqlsrv_create_stmt( sqlsrv_conn* conn, driver_stmt_factory stm
{
sqlsrv_malloc_auto_ptr<sqlsrv_stmt> stmt;
SQLHANDLE stmt_h = SQL_NULL_HANDLE;
sqlsrv_stmt* return_stmt;
try {
@ -274,10 +275,8 @@ sqlsrv_stmt* core_sqlsrv_create_stmt( sqlsrv_conn* conn, driver_stmt_factory stm
} ZEND_HASH_FOREACH_END();
}
sqlsrv_stmt* return_stmt = stmt;
return_stmt = stmt;
stmt.transferred();
return return_stmt;
}
catch( core::CoreException& )
{
@ -298,6 +297,8 @@ sqlsrv_stmt* core_sqlsrv_create_stmt( sqlsrv_conn* conn, driver_stmt_factory stm
DIE( "core_sqlsrv_allocate_stmt: Unknown exception caught." );
}
return return_stmt;
}
@ -1218,8 +1219,6 @@ 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 )
{
SQLRETURN r = SQL_SUCCESS;
// if there no current parameter to process, get the next one
// (probably because this is the first call to sqlsrv_send_stream_data)
if( stmt->current_stream.stream_z == NULL ) {
@ -1954,8 +1953,8 @@ void default_sql_size_and_scale( sqlsrv_stmt* stmt, unsigned int paramno, zval*
break;
case IS_STRING:
{
size_t char_size = (encoding == SQLSRV_ENCODING_UTF8 ) ? sizeof( SQLWCHAR ) : sizeof( char );
SQLULEN byte_len = Z_STRLEN_P(param_z) * char_size;
size_t char_size = (encoding == SQLSRV_ENCODING_UTF8 ) ? sizeof( SQLWCHAR ) : sizeof( char );
SQLULEN byte_len = Z_STRLEN_P(param_z) * char_size;
if( byte_len > SQL_SERVER_MAX_FIELD_SIZE ) {
column_size = SQL_SERVER_MAX_TYPE_SIZE;
}
@ -2008,7 +2007,6 @@ void finalize_output_parameters( sqlsrv_stmt* stmt TSRMLS_DC )
if( Z_ISUNDEF(stmt->output_params) )
return;
bool converted = true;
HashTable* params_ht = Z_ARRVAL( stmt->output_params );
zend_ulong index = -1;
zend_string* key = NULL;

View file

@ -146,10 +146,11 @@ size_t sqlsrv_stream_read( php_stream* stream, _Out_writes_bytes_(count) char* b
// flags set to 0 by default, which means that any invalid characters are dropped rather than causing
// an error. This happens only on XP.
DWORD flags = 0;
// convert to UTF-8
#ifndef __linux__
DWORD flags = 0;
if (g_osversion.dwMajorVersion >= SQLSRV_OS_VISTA_OR_LATER) {
// Vista (and later) will detect invalid UTF-16 characters and raise an error.
flags = WC_ERR_INVALID_CHARS;

View file

@ -157,7 +157,7 @@ bool convert_string_from_utf16( SQLSRV_ENCODING encoding, const SQLWCHAR* inStri
// calculate the number of characters needed
#ifdef __linux__
cchOutLen = SystemLocale::FromUtf16( encoding, inString, cchInLen, NULL, 0 );
cchOutLen = SystemLocale::FromUtf16( encoding, inString, cchInLen, NULL, 0 );
#else
cchOutLen = WideCharToMultiByte( encoding, flags,
inString, cchInLen,
@ -172,7 +172,7 @@ bool convert_string_from_utf16( SQLSRV_ENCODING encoding, const SQLWCHAR* inStri
char* newString = reinterpret_cast<char*>( sqlsrv_malloc( cchOutLen + 1 /* NULL char*/ ));
#ifdef __linux__
int rc = SystemLocale::FromUtf16( encoding, inString, cchInLen, newString, static_cast<int>(cchOutLen));
int rc = SystemLocale::FromUtf16( encoding, inString, cchInLen, newString, static_cast<int>(cchOutLen));
#else
int rc = WideCharToMultiByte( encoding, flags,
inString, cchInLen,
@ -228,9 +228,6 @@ bool core_sqlsrv_get_odbc_error( sqlsrv_context& ctx, int record_number, sqlsrv_
return false;
}
zval* ssphp_z = NULL;
int zr = SUCCESS;
zval* temp = NULL;
SQLRETURN r = SQL_SUCCESS;
SQLSMALLINT wmessage_len = 0;
SQLWCHAR wsqlstate[ SQL_SQLSTATE_BUFSIZE ];
@ -397,7 +394,7 @@ unsigned int convert_string_from_default_encoding( unsigned int php_encoding, _I
break;
}
#ifdef __linux__
unsigned int required_len = SystemLocale::ToUtf16( win_encoding, mbcs_in_string, mbcs_len, utf16_out_string, utf16_len );
unsigned int required_len = SystemLocale::ToUtf16( win_encoding, mbcs_in_string, mbcs_len, utf16_out_string, utf16_len );
#else
unsigned int required_len = MultiByteToWideChar( win_encoding, MB_ERR_INVALID_CHARS, mbcs_in_string, mbcs_len,
utf16_out_string, utf16_len );

View file

@ -381,8 +381,10 @@ typedef struct AEKeystoreProvider
This is accepted by MSVC, GCC, and C99 standard but former emits
unnecessary warning, hence it has to be disabled.
*/
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable:4200)
#endif
typedef struct AEKeystoreData
{
@ -391,7 +393,9 @@ typedef struct AEKeystoreData
char Data[];
} AEKEYSTOREPROVIDERDATA;
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
/* The following constants are for the Azure Key Vault configuration interface */
#define AKV_CONFIG_FLAGS 0

View file

@ -17,7 +17,7 @@
// IN THE SOFTWARE.
//---------------------------------------------------------------------------------------------------------------------------------
#include "pdo_sqlsrv.h"
#include "php_pdo_sqlsrv.h"
#ifndef __linux__
#include <psapi.h>
@ -361,9 +361,9 @@ struct pdo_dbh_methods pdo_sqlsrv_dbh_methods = {
{ \
pdo_sqlsrv_dbh* driver_dbh = reinterpret_cast<pdo_sqlsrv_dbh*>( dbh->driver_data ); \
driver_dbh->set_func( __FUNCTION__ ); \
int length = strlen(__FUNCTION__)+strlen(": entering"); \
int length = strlen( __FUNCTION__ ) + strlen( ": entering" ); \
char func[length+1]; \
LOG( SEV_NOTICE, strcat(strcpy(func, __FUNCTION__), ": entering")); \
LOG( SEV_NOTICE, strcat( strcpy( func, __FUNCTION__ ), ": entering" )); \
}
#else
#define PDO_LOG_DBH_ENTRY \
@ -1216,77 +1216,72 @@ int pdo_sqlsrv_dbh_quote( pdo_dbh_t* dbh, const char* unquoted, size_t unquoted_
PDO_VALIDATE_CONN;
PDO_LOG_DBH_ENTRY;
pdo_sqlsrv_dbh* driver_dbh = reinterpret_cast<pdo_sqlsrv_dbh*>( dbh->driver_data );
SQLSRV_ENCODING encoding = driver_dbh->bind_param_encoding;
pdo_sqlsrv_dbh* driver_dbh = reinterpret_cast<pdo_sqlsrv_dbh*>( dbh->driver_data );
SQLSRV_ENCODING encoding = driver_dbh->bind_param_encoding;
if ( encoding == SQLSRV_ENCODING_BINARY ) {
// convert from char* to hex digits using os
std::basic_ostringstream<char> os;
for ( size_t index = 0; index < unquoted_len && unquoted[ index ] != '\0'; ++index ) {
os << std::hex << ( int )unquoted[ index ];
}
std::basic_string<char> str_hex = os.str();
// each character is represented by 2 digits of hex
size_t unquoted_str_len = unquoted_len * 2; // length returned should not account for null terminator
char* unquoted_str = reinterpret_cast<char*>( sqlsrv_malloc( unquoted_str_len, sizeof( char ), 1 )); // include space for null terminator
strcpy_s( unquoted_str, unquoted_str_len + 1 /* include null terminator*/, str_hex.c_str() );
// include length of '0x' in the binary string
*quoted_len = unquoted_str_len + 2;
*quoted = reinterpret_cast<char*>( sqlsrv_malloc( *quoted_len, sizeof( char ), 1 ));
unsigned int out_current = 0;
// insert '0x'
( *quoted )[ out_current++ ] = '0';
( *quoted )[ out_current++ ] = 'x';
for ( size_t index = 0; index < unquoted_str_len && unquoted_str[ index ] != '\0'; ++index ) {
( *quoted )[ out_current++ ] = unquoted_str[ index ];
}
// null terminator
( *quoted )[ out_current ] = '\0';
sqlsrv_free( unquoted_str );
return 1;
}
else {
// count the number of quotes needed
unsigned int quotes_needed = 2; // the initial start and end quotes of course
// include the N proceeding the initial quote if encoding is UTF8
if ( encoding == SQLSRV_ENCODING_UTF8 ) {
quotes_needed = 3;
}
for ( size_t index = 0; index < unquoted_len && unquoted[ index ] != '\0'; ++index ) {
if ( unquoted[ index ] == '\'' ) {
++quotes_needed;
}
}
if ( encoding == SQLSRV_ENCODING_BINARY ) {
// convert from char* to hex digits using os
std::basic_ostringstream<char> os;
for ( size_t index = 0; index < unquoted_len && unquoted[ index ] != '\0'; ++index ) {
os << std::hex << ( int )unquoted[ index ];
}
std::basic_string<char> str_hex = os.str();
// each character is represented by 2 digits of hex
size_t unquoted_str_len = unquoted_len * 2; // length returned should not account for null terminator
char* unquoted_str = reinterpret_cast<char*>( sqlsrv_malloc( unquoted_str_len, sizeof( char ), 1 )); // include space for null terminator
strcpy_s( unquoted_str, unquoted_str_len + 1 /* include null terminator*/, str_hex.c_str() );
// include length of '0x' in the binary string
*quoted_len = unquoted_str_len + 2;
*quoted = reinterpret_cast<char*>( sqlsrv_malloc( *quoted_len, sizeof( char ), 1 ));
unsigned int out_current = 0;
// insert '0x'
( *quoted )[ out_current++ ] = '0';
( *quoted )[ out_current++ ] = 'x';
for ( size_t index = 0; index < unquoted_str_len && unquoted_str[ index ] != '\0'; ++index ) {
( *quoted )[ out_current++ ] = unquoted_str[ index ];
}
// null terminator
( *quoted )[ out_current ] = '\0';
sqlsrv_free( unquoted_str );
return 1;
}
else {
// count the number of quotes needed
unsigned int quotes_needed = 2; // the initial start and end quotes of course
// include the N proceeding the initial quote if encoding is UTF8
if ( encoding == SQLSRV_ENCODING_UTF8 ) {
quotes_needed = 3;
}
for ( size_t index = 0; index < unquoted_len && unquoted[ index ] != '\0'; ++index ) {
if ( unquoted[ index ] == '\'' ) {
++quotes_needed;
}
}
*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, sizeof( char ), 1 )); // include space for null terminator.
unsigned int out_current = 0;
*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, sizeof( char ), 1 )); // include space for null terminator.
unsigned int out_current = 0;
// insert N if the encoding is UTF8
if ( encoding == SQLSRV_ENCODING_UTF8 ) {
( *quoted )[ out_current++ ] = 'N';
}
// insert initial quote
( *quoted )[ out_current++ ] = '\'';
for ( size_t index = 0; index < unquoted_len && unquoted[ index ] != '\0'; ++index ) {
if ( unquoted[ index ] == '\'' ) {
( *quoted )[ out_current++ ] = '\'';
( *quoted )[ out_current++ ] = '\'';
}
else {
( *quoted )[ out_current++ ] = unquoted[ index ];
}
}
// trailing quote and null terminator
( *quoted )[ out_current++ ] = '\'';
( *quoted )[ out_current ] = '\0';
return 1;
}
// insert N if the encoding is UTF8
if ( encoding == SQLSRV_ENCODING_UTF8 ) {
( *quoted )[ out_current++ ] = 'N';
}
// insert initial quote
( *quoted )[ out_current++ ] = '\'';
for ( size_t index = 0; index < unquoted_len && unquoted[ index ] != '\0'; ++index ) {
if ( unquoted[ index ] == '\'' ) {
( *quoted )[ out_current++ ] = '\'';
( *quoted )[ out_current++ ] = '\'';
}
else {
( *quoted )[ out_current++ ] = unquoted[ index ];
}
}
// trailing quote and null terminator
( *quoted )[ out_current++ ] = '\'';
( *quoted )[ out_current ] = '\0';
return 1;
}
}
// This method is not implemented by this driver.

View file

@ -17,7 +17,7 @@
// IN THE SOFTWARE.
//---------------------------------------------------------------------------------------------------------------------------------
#include "pdo_sqlsrv.h"
#include "php_pdo_sqlsrv.h"
#ifdef __linux__
#include <iostream>
#include <dlfcn.h>

View file

@ -19,7 +19,7 @@
// IN THE SOFTWARE.
//---------------------------------------------------------------------------------------------------------------------------------
#include "pdo_sqlsrv.h"
#include "php_pdo_sqlsrv.h"
// Constructor
conn_string_parser:: conn_string_parser( sqlsrv_context& ctx, const char* dsn, int len, _Inout_ HashTable* conn_options_ht )

View file

@ -17,7 +17,7 @@
// IN THE SOFTWARE.
//---------------------------------------------------------------------------------------------------------------------------------
#include "pdo_sqlsrv.h"
#include "php_pdo_sqlsrv.h"
// *** internal variables and constants ***
@ -339,9 +339,9 @@ void stmt_option_emulate_prepares:: operator()( sqlsrv_stmt* stmt, stmt_option c
{ \
pdo_sqlsrv_stmt* driver_stmt = reinterpret_cast<pdo_sqlsrv_stmt*>( stmt->driver_data ); \
driver_stmt->set_func( __FUNCTION__ ); \
int length = strlen(__FUNCTION__)+strlen(": entering"); \
int length = strlen( __FUNCTION__ ) + strlen( ": entering" ); \
char func[length+1]; \
LOG( SEV_NOTICE, strcat(strcpy(func, __FUNCTION__), ": entering")); \
LOG( SEV_NOTICE, strcat( strcpy( func, __FUNCTION__ ), ": entering" )); \
}
#else
#define PDO_LOG_STMT_ENTRY \
@ -1077,12 +1077,12 @@ int pdo_sqlsrv_stmt_param_hook(pdo_stmt_t *stmt,
// since the param isn't reliable, we don't do anything here
case PDO_PARAM_EVT_ALLOC:
// if emulate prepare is on, set the bind_param_encoding so it can be used in PDO::quote when binding parameters on the client side
if ( stmt->supports_placeholders == PDO_PLACEHOLDER_NONE ) {
pdo_sqlsrv_dbh* driver_dbh = reinterpret_cast<pdo_sqlsrv_dbh*>( stmt->dbh->driver_data );
driver_dbh->bind_param_encoding = static_cast<SQLSRV_ENCODING>( Z_LVAL( param->driver_params ));
}
break;
// if emulate prepare is on, set the bind_param_encoding so it can be used in PDO::quote when binding parameters on the client side
if ( stmt->supports_placeholders == PDO_PLACEHOLDER_NONE ) {
pdo_sqlsrv_dbh* driver_dbh = reinterpret_cast<pdo_sqlsrv_dbh*>( stmt->dbh->driver_data );
driver_dbh->bind_param_encoding = static_cast<SQLSRV_ENCODING>( Z_LVAL( param->driver_params ));
}
break;
case PDO_PARAM_EVT_FREE:
break;
// bind the parameter in the core layer

View file

@ -17,7 +17,7 @@
// IN THE SOFTWARE.
//---------------------------------------------------------------------------------------------------------------------------------
#include "pdo_sqlsrv.h"
#include "php_pdo_sqlsrv.h"
#include "zend_exceptions.h"

View file

@ -0,0 +1,400 @@
#ifndef PHP_PDO_SQLSRV_H
#define PHP_PDO_SQLSRV_H
//---------------------------------------------------------------------------------------------------------------------------------
// File: php_pdo_sqlsrv.h
//
// Contents: Declarations for the extension
//
// Microsoft Drivers 4.0 for PHP for SQL Server
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the ""Software""),
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//---------------------------------------------------------------------------------------------------------------------------------
#include "core_sqlsrv.h"
#include "version.h"
#define PHP_PDO_SQLSRV_VERSION "4.0.5"
extern "C" {
#include "pdo/php_pdo.h"
#include "pdo/php_pdo_driver.h"
}
#include <vector>
#include <map>
#ifdef __linux__
#include <string.h>
#endif
//*********************************************************************************************************************************
// Constants and Types
//*********************************************************************************************************************************
// sqlsrv driver specific PDO attributes
enum PDO_SQLSRV_ATTR {
// Currently there are only three custom attributes for this driver.
SQLSRV_ATTR_ENCODING = PDO_ATTR_DRIVER_SPECIFIC,
SQLSRV_ATTR_QUERY_TIMEOUT,
SQLSRV_ATTR_DIRECT_QUERY,
SQLSRV_ATTR_CURSOR_SCROLL_TYPE,
SQLSRV_ATTR_CLIENT_BUFFER_MAX_KB_SIZE,
};
// valid set of values for TransactionIsolation connection option
namespace PDOTxnIsolationValues {
const char READ_UNCOMMITTED[] = "READ_UNCOMMITTED";
const char READ_COMMITTED[] = "READ_COMMITTED";
const char REPEATABLE_READ[] = "REPEATABLE_READ";
const char SERIALIZABLE[] = "SERIALIZABLE";
const char SNAPSHOT[] = "SNAPSHOT";
}
//*********************************************************************************************************************************
// Global variables
//*********************************************************************************************************************************
extern "C" {
// request level variables
ZEND_BEGIN_MODULE_GLOBALS(pdo_sqlsrv)
unsigned int log_severity;
zend_long client_buffer_max_size;
ZEND_END_MODULE_GLOBALS(pdo_sqlsrv)
ZEND_EXTERN_MODULE_GLOBALS(pdo_sqlsrv);
}
// macros used to access the global variables. Use these to make global variable access agnostic to threads
#ifdef ZTS
#define PDO_SQLSRV_G(v) TSRMG(pdo_sqlsrv_globals_id, zend_pdo_sqlsrv_globals *, v)
#else
#define PDO_SQLSRV_G(v) pdo_sqlsrv_globals.v
#endif
// INI settings and constants
// (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_PREFIX "pdo_sqlsrv."
PHP_INI_BEGIN()
STD_PHP_INI_ENTRY( INI_PREFIX INI_PDO_SQLSRV_LOG , "0", PHP_INI_ALL, OnUpdateLong, log_severity,
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()
// henv context for creating connections
extern sqlsrv_context* g_henv_cp;
extern sqlsrv_context* g_henv_ncp;
//*********************************************************************************************************************************
// Initialization
//*********************************************************************************************************************************
// module global variables (initialized in minit and freed in mshutdown)
extern HashTable* g_pdo_errors_ht;
#define phpext_pdo_sqlsrv_ptr &g_pdo_sqlsrv_module_entry
// module initialization
PHP_MINIT_FUNCTION(pdo_sqlsrv);
// module shutdown function
PHP_MSHUTDOWN_FUNCTION(pdo_sqlsrv);
// request initialization function
PHP_RINIT_FUNCTION(pdo_sqlsrv);
// request shutdown function
PHP_RSHUTDOWN_FUNCTION(pdo_sqlsrv);
// module info function (info returned by phpinfo())
PHP_MINFO_FUNCTION(pdo_sqlsrv);
extern zend_module_entry g_pdo_sqlsrv_module_entry; // describes the extension to PHP
//*********************************************************************************************************************************
// PDO DSN Parser
//*********************************************************************************************************************************
// Parser class used to parse DSN connection string.
class conn_string_parser
{
enum States
{
FirstKeyValuePair,
Key,
Value,
ValueContent1,
ValueContent2,
RCBEncountered,
NextKeyValuePair,
};
private:
const char* conn_str;
sqlsrv_context* ctx;
int len;
int pos;
unsigned int current_key;
const char* current_key_name;
HashTable* conn_options_ht;
inline bool next( void );
inline bool is_eos( void );
inline bool is_white_space( char c );
bool discard_white_spaces( void );
int discard_trailing_white_spaces( const char* str, int len );
void validate_key( const char *key, int key_len TSRMLS_DC );
void add_key_value_pair( const char* value, int len TSRMLS_DC );
public:
conn_string_parser( sqlsrv_context& ctx, const char* dsn, int len, _Inout_ HashTable* conn_options_ht );
void parse_conn_string( TSRMLS_D );
};
//*********************************************************************************************************************************
// Connection
//*********************************************************************************************************************************
extern const connection_option PDO_CONN_OPTS[];
int pdo_sqlsrv_db_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC);
// a core layer pdo dbh object. This object inherits and overrides the statement factory
struct pdo_sqlsrv_dbh : public sqlsrv_conn {
zval* stmts;
bool direct_query;
long query_timeout;
zend_long client_buffer_max_size;
SQLSRV_ENCODING bind_param_encoding;
pdo_sqlsrv_dbh( SQLHANDLE h, error_callback e, void* driver TSRMLS_DC );
};
//*********************************************************************************************************************************
// Statement
//*********************************************************************************************************************************
struct stmt_option_encoding : public stmt_option_functor {
virtual void operator()( sqlsrv_stmt* stmt, stmt_option const* /*opt*/, zval* value_z TSRMLS_DC );
};
struct stmt_option_scrollable : public stmt_option_functor {
virtual void operator()( sqlsrv_stmt* stmt, stmt_option const* /*opt*/, zval* value_z TSRMLS_DC );
};
struct stmt_option_direct_query : public stmt_option_functor {
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;
// a core layer pdo stmt object. This object inherits and overrides the callbacks necessary
struct pdo_sqlsrv_stmt : public sqlsrv_stmt {
pdo_sqlsrv_stmt( sqlsrv_conn* c, SQLHANDLE handle, error_callback e, void* drv TSRMLS_DC ) :
sqlsrv_stmt( c, handle, e, drv TSRMLS_CC ),
direct_query( false ),
direct_query_subst_string( NULL ),
direct_query_subst_string_len( 0 ),
bound_column_param_types( NULL )
{
pdo_sqlsrv_dbh* db = static_cast<pdo_sqlsrv_dbh*>( c );
direct_query = db->direct_query;
}
virtual ~pdo_sqlsrv_stmt( void );
// 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
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
const char* direct_query_subst_string; // if the query is direct, hold the substitution string if using named parameters
size_t direct_query_subst_string_len; // length of query string used for direct queries
// meta data for current result set
std::vector<field_meta_data*, sqlsrv_allocator< field_meta_data* > > current_meta_data;
pdo_param_type* bound_column_param_types;
};
//*********************************************************************************************************************************
// Error Handling Functions
//*********************************************************************************************************************************
// represents the mapping between an error_code and the corresponding error message.
struct pdo_error {
unsigned int error_code;
sqlsrv_error_const sqlsrv_error;
};
// called when an error occurs in the core layer. These routines are set as the error_callback in a
// context. The context is passed to this function since it contains the function
bool pdo_sqlsrv_handle_env_error( sqlsrv_context& ctx, unsigned int sqlsrv_error_code, bool warning TSRMLS_DC,
va_list* print_args );
bool pdo_sqlsrv_handle_dbh_error( sqlsrv_context& ctx, unsigned int sqlsrv_error_code, bool warning TSRMLS_DC,
va_list* print_args );
bool pdo_sqlsrv_handle_stmt_error( sqlsrv_context& ctx, unsigned int sqlsrv_error_code, bool warning TSRMLS_DC,
va_list* print_args );
// pointer to the function to return the class entry for the PDO exception Set in MINIT
extern zend_class_entry* (*pdo_get_exception_class)( void );
// common routine to transfer a sqlsrv_context's error to a PDO zval
void pdo_sqlsrv_retrieve_context_error( sqlsrv_error const* last_error, zval* pdo_zval );
// reset the errors from the last operation
inline void pdo_reset_dbh_error( pdo_dbh_t* dbh TSRMLS_DC )
{
strcpy_s( dbh->error_code, sizeof( dbh->error_code ), "00000" ); // 00000 means no error
// release the last statement from the dbh so that error handling won't have a statement passed to it
if( dbh->query_stmt ) {
dbh->query_stmt = NULL;
zend_objects_store_del( Z_OBJ_P(&dbh->query_stmt_zval TSRMLS_CC) );
}
// if the driver isn't valid, just return (PDO calls close sometimes more than once?)
if( dbh->driver_data == NULL ) {
return;
}
// reset the last error on the sqlsrv_context
sqlsrv_context* ctx = static_cast<sqlsrv_conn*>( dbh->driver_data );
if( ctx->last_error() ) {
ctx->last_error().reset();
}
}
#define PDO_RESET_DBH_ERROR pdo_reset_dbh_error( dbh TSRMLS_CC );
inline void pdo_reset_stmt_error( pdo_stmt_t* stmt )
{
strcpy_s( stmt->error_code, sizeof( stmt->error_code ), "00000" ); // 00000 means no error
// if the driver isn't valid, just return (PDO calls close sometimes more than once?)
if( stmt->driver_data == NULL ) {
return;
}
// reset the last error on the sqlsrv_context
sqlsrv_context* ctx = static_cast<sqlsrv_stmt*>( stmt->driver_data );
if( ctx->last_error() ) {
ctx->last_error().reset();
}
}
#define PDO_RESET_STMT_ERROR pdo_reset_stmt_error( stmt );
// validate the driver objects
#define PDO_VALIDATE_CONN if( dbh->driver_data == NULL ) { DIE( "Invalid driver data in PDO object." ); }
#define PDO_VALIDATE_STMT if( stmt->driver_data == NULL ) { DIE( "Invalid driver data in PDOStatement object." ); }
//*********************************************************************************************************************************
// Utility Functions
//*********************************************************************************************************************************
// List of PDO specific error messages.
enum PDO_ERROR_CODES {
PDO_SQLSRV_ERROR_INVALID_DBH_ATTR = SQLSRV_ERROR_DRIVER_SPECIFIC,
PDO_SQLSRV_ERROR_INVALID_STMT_ATTR,
PDO_SQLSRV_ERROR_INVALID_ENCODING,
PDO_SQLSRV_ERROR_INVALID_DRIVER_PARAM,
PDO_SQLSRV_ERROR_PDO_STMT_UNSUPPORTED,
PDO_SQLSRV_ERROR_UNSUPPORTED_DBH_ATTR,
PDO_SQLSRV_ERROR_STMT_LEVEL_ATTR,
PDO_SQLSRV_ERROR_READ_ONLY_DBH_ATTR,
PDO_SQLSRV_ERROR_INVALID_STMT_OPTION,
PDO_SQLSRV_ERROR_INVALID_CURSOR_TYPE,
PDO_SQLSRV_ERROR_FUNCTION_NOT_IMPLEMENTED,
PDO_SQLSRV_ERROR_PARAM_PARSE,
PDO_SQLSRV_ERROR_LAST_INSERT_ID,
PDO_SQLSRV_ERROR_INVALID_COLUMN_DRIVER_DATA,
PDO_SQLSRV_ERROR_COLUMN_TYPE_DOES_NOT_SUPPORT_ENCODING,
PDO_SQLSRV_ERROR_INVALID_DRIVER_COLUMN_ENCODING,
PDO_SQLSRV_ERROR_INVALID_DRIVER_PARAM_TYPE,
PDO_SQLSRV_ERROR_INVALID_DRIVER_PARAM_ENCODING,
PDO_SQLSRV_ERROR_INVALID_PARAM_DIRECTION,
PDO_SQLSRV_ERROR_INVALID_OUTPUT_STRING_SIZE,
PDO_SQLSRV_ERROR_CURSOR_ATTR_AT_PREPARE_ONLY,
PDO_SQLSRV_ERROR_INVALID_DSN_STRING,
PDO_SQLSRV_ERROR_INVALID_DSN_KEY,
PDO_SQLSRV_ERROR_INVALID_DSN_VALUE,
PDO_SQLSRV_ERROR_SERVER_NOT_SPECIFIED,
PDO_SQLSRV_ERROR_DSN_STRING_ENDED_UNEXPECTEDLY,
PDO_SQLSRV_ERROR_EXTRA_SEMI_COLON_IN_DSN_STRING,
SQLSRV_ERROR_UNESCAPED_RIGHT_BRACE_IN_DSN,
PDO_SQLSRV_ERROR_RCB_MISSING_IN_DSN_VALUE,
PDO_SQLSRV_ERROR_DQ_ATTR_AT_PREPARE_ONLY,
PDO_SQLSRV_ERROR_INVALID_COLUMN_INDEX,
PDO_SQLSRV_ERROR_INVALID_OUTPUT_PARAM_TYPE,
PDO_SQLSRV_ERROR_INVALID_CURSOR_WITH_SCROLL_TYPE,
};
extern pdo_error PDO_ERRORS[];
#define THROW_PDO_ERROR( ctx, custom, ... ) \
call_error_handler( ctx, custom TSRMLS_CC, false, ## __VA_ARGS__ ); \
throw pdo::PDOException();
namespace pdo {
// an error which occurred in our PDO driver, NOT an exception thrown by PDO
struct PDOException : public core::CoreException {
PDOException() : CoreException()
{
}
};
} // namespace pdo
// 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
// 2) this is a more precise name
extern int (*pdo_subst_named_params)(pdo_stmt_t *stmt, char *inquery, size_t inquery_len,
char **outquery, size_t *outquery_len TSRMLS_DC);
// logger for pdo_sqlsrv called by the core layer when it wants to log something with the LOG macro
void pdo_sqlsrv_log( unsigned int severity TSRMLS_DC, const char* msg, va_list* print_args );
#endif /* PHP_PDO_SQLSRV_H */

View file

@ -16,11 +16,11 @@
// IN THE SOFTWARE.
//---------------------------------------------------------------------------------------------------------------------------------
#define VER_FILEVERSION_STR "4.0.0.0"
#define _FILEVERSION 4,0,0,0
#define VER_FILEVERSION_STR "4.0.5.0"
#define _FILEVERSION 4,0,5,0
#define SQLVERSION_MAJOR 4
#define SQLVERSION_MINOR 0
#define SQLVERSION_MMDD 0
#define SQLVERSION_MMDD 5
#define SQLVERSION_REVISION 0

View file

@ -266,25 +266,12 @@ typedef void* SQLHWND;
// End definitions for UnixODBC SQL headers
// ----------------------------------------------------------------------------
#define UNREFERENCED_PARAMETER(arg)
// From share.h
#define _SH_DENYNO 0x40 /* deny none mode */
// WinNT.h
#define CONST const
#define VOID void

14
source/sqlsrv/LICENSE Normal file
View file

@ -0,0 +1,14 @@
Copyright(c) 2016 Microsoft Corporation
All rights reserved.
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.

View file

@ -1953,8 +1953,8 @@ void default_sql_size_and_scale( sqlsrv_stmt* stmt, unsigned int paramno, zval*
break;
case IS_STRING:
{
size_t char_size = (encoding == SQLSRV_ENCODING_UTF8 ) ? sizeof( SQLWCHAR ) : sizeof( char );
SQLULEN byte_len = Z_STRLEN_P(param_z) * char_size;
size_t char_size = (encoding == SQLSRV_ENCODING_UTF8 ) ? sizeof( SQLWCHAR ) : sizeof( char );
SQLULEN byte_len = Z_STRLEN_P(param_z) * char_size;
if( byte_len > SQL_SERVER_MAX_FIELD_SIZE ) {
column_size = SQL_SERVER_MAX_TYPE_SIZE;
}

View file

@ -157,7 +157,7 @@ bool convert_string_from_utf16( SQLSRV_ENCODING encoding, const SQLWCHAR* inStri
// calculate the number of characters needed
#ifdef __linux__
cchOutLen = SystemLocale::FromUtf16( encoding, inString, cchInLen, NULL, 0 );
cchOutLen = SystemLocale::FromUtf16( encoding, inString, cchInLen, NULL, 0 );
#else
cchOutLen = WideCharToMultiByte( encoding, flags,
inString, cchInLen,
@ -172,7 +172,7 @@ bool convert_string_from_utf16( SQLSRV_ENCODING encoding, const SQLWCHAR* inStri
char* newString = reinterpret_cast<char*>( sqlsrv_malloc( cchOutLen + 1 /* NULL char*/ ));
#ifdef __linux__
int rc = SystemLocale::FromUtf16( encoding, inString, cchInLen, newString, static_cast<int>(cchOutLen));
int rc = SystemLocale::FromUtf16( encoding, inString, cchInLen, newString, static_cast<int>(cchOutLen));
#else
int rc = WideCharToMultiByte( encoding, flags,
inString, cchInLen,
@ -394,7 +394,7 @@ unsigned int convert_string_from_default_encoding( unsigned int php_encoding, _I
break;
}
#ifdef __linux__
unsigned int required_len = SystemLocale::ToUtf16( win_encoding, mbcs_in_string, mbcs_len, utf16_out_string, utf16_len );
unsigned int required_len = SystemLocale::ToUtf16( win_encoding, mbcs_in_string, mbcs_len, utf16_out_string, utf16_len );
#else
unsigned int required_len = MultiByteToWideChar( win_encoding, MB_ERR_INVALID_CHARS, mbcs_in_string, mbcs_len,
utf16_out_string, utf16_len );

View file

@ -388,16 +388,16 @@ PHP_MINIT_FUNCTION(sqlsrv)
constant_type.typeinfo.scale = 7;
REGISTER_LONG_CONSTANT( "SQLSRV_SQLTYPE_DATETIME2", constant_type.value, CONST_PERSISTENT | CONST_CS );
// These constant are defined to provide type checking (type ==SQLSRV_SQLTYPE_DECIMAL).
// There are functions with the same name which accept parameters and is used in binding paramters.
REGISTER_LONG_CONSTANT("SQLSRV_SQLTYPE_DECIMAL", SQL_DECIMAL, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT("SQLSRV_SQLTYPE_NUMERIC", SQL_NUMERIC, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT("SQLSRV_SQLTYPE_CHAR", SQL_CHAR, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT("SQLSRV_SQLTYPE_NCHAR", SQL_WCHAR, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT("SQLSRV_SQLTYPE_VARCHAR", SQL_VARCHAR, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT("SQLSRV_SQLTYPE_NVARCHAR", SQL_WVARCHAR, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT("SQLSRV_SQLTYPE_BINARY", SQL_BINARY, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT("SQLSRV_SQLTYPE_VARBINARY", SQL_VARBINARY, CONST_PERSISTENT | CONST_CS);
// These constant are defined to provide type checking (type ==SQLSRV_SQLTYPE_DECIMAL).
// There are functions with the same name which accept parameters and is used in binding paramters.
REGISTER_LONG_CONSTANT("SQLSRV_SQLTYPE_DECIMAL", SQL_DECIMAL, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT("SQLSRV_SQLTYPE_NUMERIC", SQL_NUMERIC, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT("SQLSRV_SQLTYPE_CHAR", SQL_CHAR, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT("SQLSRV_SQLTYPE_NCHAR", SQL_WCHAR, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT("SQLSRV_SQLTYPE_VARCHAR", SQL_VARCHAR, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT("SQLSRV_SQLTYPE_NVARCHAR", SQL_WVARCHAR, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT("SQLSRV_SQLTYPE_BINARY", SQL_BINARY, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT("SQLSRV_SQLTYPE_VARBINARY", SQL_VARBINARY, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT( "SQLSRV_PARAM_IN", SQL_PARAM_INPUT, CONST_PERSISTENT | CONST_CS );
REGISTER_LONG_CONSTANT( "SQLSRV_PARAM_OUT", SQL_PARAM_OUTPUT, CONST_PERSISTENT | CONST_CS );

View file

@ -25,6 +25,8 @@
#include "core_sqlsrv.h"
#include "version.h"
#define PHP_SQLSRV_VERSION "4.0.5"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

View file

@ -794,7 +794,6 @@ PHP_FUNCTION( sqlsrv_fetch_object )
}
class_name = Z_STRVAL( *class_name_z );
class_name_len = Z_STRLEN( *class_name_z );
//zend_str_tolower( class_name, class_name_len );
}
if( ctor_params_z && Z_TYPE_P( ctor_params_z ) != IS_ARRAY ) {
@ -887,14 +886,14 @@ PHP_FUNCTION( sqlsrv_fetch_object )
fci.param_count = num_params;
fci.params = params_m; // purposefully not transferred since ownership isn't actually transferred.
fci.object = reinterpret_cast<zend_object*>( &retval_z );
fci.object = Z_OBJ_P( &retval_z );
memset( &fcic, 0, sizeof( fcic ));
fcic.initialized = 1;
fcic.function_handler = class_entry->constructor;
fcic.calling_scope = class_entry;
fci.object = reinterpret_cast<zend_object*>( &retval_z );
fcic.object = Z_OBJ_P( &retval_z );
zr = zend_call_function( &fci, &fcic TSRMLS_CC );
CHECK_ZEND_ERROR( zr, stmt, SS_SQLSRV_ERROR_ZEND_OBJECT_FAILED, class_name ) {

View file

@ -16,11 +16,11 @@
// IN THE SOFTWARE.
//---------------------------------------------------------------------------------------------------------------------------------
#define VER_FILEVERSION_STR "4.0.0.0"
#define _FILEVERSION 4,0,0,0
#define VER_FILEVERSION_STR "4.0.5.0"
#define _FILEVERSION 4,0,5,0
#define SQLVERSION_MAJOR 4
#define SQLVERSION_MINOR 0
#define SQLVERSION_MMDD 0
#define SQLVERSION_MMDD 5
#define SQLVERSION_REVISION 0

View file

@ -266,25 +266,12 @@ typedef void* SQLHWND;
// End definitions for UnixODBC SQL headers
// ----------------------------------------------------------------------------
#define UNREFERENCED_PARAMETER(arg)
// From share.h
#define _SH_DENYNO 0x40 /* deny none mode */
// WinNT.h
#define CONST const
#define VOID void