mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Implement PDO driver-specific subclasses
RFC: https://wiki.php.net/rfc/pdo_driver_specific_subclasses Closes GH-12804 Co-Authored-By: Danack <Danack@basereality.com>
This commit is contained in:
11
NEWS
11
NEWS
@@ -60,22 +60,33 @@ OpenSSL:
|
||||
|
||||
PDO:
|
||||
. Fixed setAttribute and getAttribute (SakiTakamachi)
|
||||
. Implement PDO driver-specific subclasses RFC (danack, kocsismate)
|
||||
|
||||
PDO_DBLIB:
|
||||
. Fixed setAttribute and getAttribute (SakiTakamachi)
|
||||
. Added class PdoDbLib (danack, kocsismate)
|
||||
|
||||
PDO_FIREBIRD:
|
||||
. Fixed setAttribute and getAttribute (SakiTakamachi)
|
||||
. Feature: Add transaction isolation level and mode settings to pdo_firebird
|
||||
(SakiTakamachi)
|
||||
. Added class PdoFirebird. (danack, kocsismate)
|
||||
|
||||
PDO_MYSQL:
|
||||
. Fixed setAttribute and getAttribute (SakiTakamachi)
|
||||
. Added class PdoMysql. (danack, kocsismate)
|
||||
|
||||
PDO_ODBC:
|
||||
. Added class PdoOdbc. (danack, kocsismate)
|
||||
|
||||
PDO_PGSQL:
|
||||
. Fixed GH-12423, DSN credentials being prioritized over the user/password
|
||||
PDO constructor arguments. (SakiTakamachi)
|
||||
. Fixed native float support with pdo_pgsql query results. (Yurunsoft)
|
||||
. Added class PdoPgsql. (danack, kocsismate)
|
||||
|
||||
PDO_SQLITE:
|
||||
. Added class PdoSqlite. (danack, kocsismate)
|
||||
|
||||
PGSQL:
|
||||
. Added the possibility to have no conditions for pg_select. (OmarEmaraDev)
|
||||
|
||||
27
UPGRADING
27
UPGRADING
@@ -152,6 +152,33 @@ PHP 8.4 UPGRADE NOTES
|
||||
- Phar:
|
||||
. Added support for the unix timestamp extension for zip archives.
|
||||
|
||||
- PDO:
|
||||
. Added support for driver-specific subclasses.
|
||||
RFC: https://wiki.php.net/rfc/pdo_driver_specific_subclasses
|
||||
This RFC adds subclasses for PDO in order to better support
|
||||
database-specific functionalities. The new classes are
|
||||
instantiatable either via calling the PDO::connect() method
|
||||
or by invoking their constructor directly.
|
||||
|
||||
PDO_DBLIB:
|
||||
. Fixed setAttribute and getAttribute (SakiTakamachi)
|
||||
. Added PdoDbLib class (danack, kocsismate)
|
||||
|
||||
PDO_FIREBIRD:
|
||||
. Added class PdoFirebird.
|
||||
|
||||
PDO_MYSQL:
|
||||
. Added class PdoMysql.
|
||||
|
||||
PDO_ODBC:
|
||||
. Added class PdoOdbc.
|
||||
|
||||
PDO_PGSQL:
|
||||
. Added class PdoPgsql.
|
||||
|
||||
PDO_SQLITE:
|
||||
. Added class PdoSqlite.
|
||||
|
||||
- POSIX:
|
||||
. Added constant POSIX_SC_CHILD_MAX
|
||||
. Added constant POSIX_SC_CLK_TCK
|
||||
|
||||
@@ -41,6 +41,9 @@ zend_class_entry *pdo_exception_ce;
|
||||
/* the registry of PDO drivers */
|
||||
HashTable pdo_driver_hash;
|
||||
|
||||
/* the registry of PDO driver specific class entries */
|
||||
HashTable pdo_driver_specific_ce_hash;
|
||||
|
||||
/* we use persistent resources for the driver connection stuff */
|
||||
static int le_ppdo;
|
||||
|
||||
@@ -115,7 +118,7 @@ PDO_API zend_result php_pdo_register_driver(const pdo_driver_t *driver) /* {{{ *
|
||||
return FAILURE;
|
||||
}
|
||||
if (!zend_hash_str_exists(&module_registry, "pdo", sizeof("pdo") - 1)) {
|
||||
zend_error_noreturn(E_ERROR, "You MUST load PDO before loading any PDO drivers");
|
||||
zend_error_noreturn(E_ERROR, "The PDO extension must be loaded first in order to load PDO drivers");
|
||||
return FAILURE; /* NOTREACHED */
|
||||
}
|
||||
|
||||
@@ -129,10 +132,22 @@ PDO_API void php_pdo_unregister_driver(const pdo_driver_t *driver) /* {{{ */
|
||||
return;
|
||||
}
|
||||
|
||||
zend_hash_str_del(&pdo_driver_specific_ce_hash, driver->driver_name, driver->driver_name_len);
|
||||
zend_hash_str_del(&pdo_driver_hash, driver->driver_name, driver->driver_name_len);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
PDO_API zend_result php_pdo_register_driver_specific_ce(const pdo_driver_t *driver, zend_class_entry *ce) /* {{{ */
|
||||
{
|
||||
if (!zend_hash_str_exists(&module_registry, "pdo", sizeof("pdo") - 1)) {
|
||||
zend_error_noreturn(E_ERROR, "The PDO extension must be loaded first in order to load PDO drivers");
|
||||
return FAILURE; /* NOTREACHED */
|
||||
}
|
||||
|
||||
return zend_hash_str_add_ptr(&pdo_driver_specific_ce_hash, driver->driver_name,
|
||||
driver->driver_name_len, (void*)ce) != NULL ? SUCCESS : FAILURE;
|
||||
}
|
||||
|
||||
pdo_driver_t *pdo_find_driver(const char *name, int namelen) /* {{{ */
|
||||
{
|
||||
return zend_hash_str_find_ptr(&pdo_driver_hash, name, namelen);
|
||||
@@ -246,6 +261,7 @@ PHP_MINIT_FUNCTION(pdo)
|
||||
pdo_sqlstate_init_error_table();
|
||||
|
||||
zend_hash_init(&pdo_driver_hash, 0, NULL, NULL, 1);
|
||||
zend_hash_init(&pdo_driver_specific_ce_hash, 0, NULL, NULL, 1);
|
||||
|
||||
le_ppdo = zend_register_list_destructors_ex(NULL, php_pdo_pdbh_dtor,
|
||||
"PDO persistent database", module_number);
|
||||
@@ -263,6 +279,7 @@ PHP_MINIT_FUNCTION(pdo)
|
||||
PHP_MSHUTDOWN_FUNCTION(pdo)
|
||||
{
|
||||
zend_hash_destroy(&pdo_driver_hash);
|
||||
zend_hash_destroy(&pdo_driver_specific_ce_hash);
|
||||
pdo_sqlstate_fini_error_table();
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@@ -221,10 +221,64 @@ static char *dsn_from_uri(char *uri, char *buf, size_t buflen) /* {{{ */
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ */
|
||||
PHP_METHOD(PDO, __construct)
|
||||
static bool create_driver_specific_pdo_object(pdo_driver_t *driver, zend_class_entry *called_scope, zval *new_object)
|
||||
{
|
||||
zend_class_entry *ce;
|
||||
zend_class_entry *ce_based_on_driver_name = NULL, *ce_based_on_called_object = NULL;
|
||||
|
||||
ce_based_on_driver_name = zend_hash_str_find_ptr(&pdo_driver_specific_ce_hash, driver->driver_name, driver->driver_name_len);
|
||||
|
||||
ZEND_HASH_MAP_FOREACH_PTR(&pdo_driver_specific_ce_hash, ce) {
|
||||
if (called_scope != pdo_dbh_ce && instanceof_function(called_scope, ce)) {
|
||||
ce_based_on_called_object = called_scope;
|
||||
break;
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
if (ce_based_on_called_object) {
|
||||
if (ce_based_on_driver_name) {
|
||||
if (instanceof_function(ce_based_on_called_object, ce_based_on_driver_name) == false) {
|
||||
zend_throw_exception_ex(pdo_exception_ce, 0,
|
||||
"%s::connect() cannot be called when connecting to the \"%s\" driver, "
|
||||
"either %s::connect() or PDO::connect() must be called instead",
|
||||
ZSTR_VAL(called_scope->name), driver->driver_name, ZSTR_VAL(ce_based_on_driver_name->name));
|
||||
return false;
|
||||
}
|
||||
|
||||
/* A driver-specific implementation was instantiated via the connect() method of the appropriate driver class */
|
||||
object_init_ex(new_object, ce_based_on_called_object);
|
||||
return true;
|
||||
} else {
|
||||
zend_throw_exception_ex(pdo_exception_ce, 0,
|
||||
"%s::connect() cannot be called when connecting to an unknown driver, "
|
||||
"PDO::connect() must be called instead",
|
||||
ZSTR_VAL(called_scope->name));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (ce_based_on_driver_name) {
|
||||
if (called_scope != pdo_dbh_ce) {
|
||||
/* A driver-specific implementation was instantiated via the connect method of a wrong driver class */
|
||||
zend_throw_exception_ex(pdo_exception_ce, 0,
|
||||
"%s::connect() cannot be called when connecting to the \"%s\" driver, "
|
||||
"either %s::connect() or PDO::connect() must be called instead",
|
||||
ZSTR_VAL(called_scope->name), driver->driver_name, ZSTR_VAL(ce_based_on_driver_name->name));
|
||||
return false;
|
||||
}
|
||||
|
||||
/* A driver-specific implementation was instantiated via PDO::__construct() */
|
||||
object_init_ex(new_object, ce_based_on_driver_name);
|
||||
} else {
|
||||
/* No driver-specific implementation found */
|
||||
object_init_ex(new_object, called_scope);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void internal_construct(INTERNAL_FUNCTION_PARAMETERS, zend_object *object, zend_class_entry *current_scope, zval *new_zval_object)
|
||||
{
|
||||
zval *object = ZEND_THIS;
|
||||
pdo_dbh_t *dbh = NULL;
|
||||
bool is_persistent = 0;
|
||||
char *data_source;
|
||||
@@ -291,7 +345,16 @@ PHP_METHOD(PDO, __construct)
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
dbh = Z_PDO_DBH_P(object);
|
||||
if (new_zval_object != NULL) {
|
||||
ZEND_ASSERT((driver->driver_name != NULL) && "PDO driver name is null");
|
||||
if (!create_driver_specific_pdo_object(driver, current_scope, new_zval_object)) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
dbh = Z_PDO_DBH_P(new_zval_object);
|
||||
} else {
|
||||
dbh = php_pdo_dbh_fetch_inner(object);
|
||||
}
|
||||
|
||||
/* is this supposed to be a persistent connection ? */
|
||||
if (options) {
|
||||
@@ -352,7 +415,7 @@ PHP_METHOD(PDO, __construct)
|
||||
if (pdbh) {
|
||||
efree(dbh);
|
||||
/* switch over to the persistent one */
|
||||
Z_PDO_OBJECT_P(object)->inner = pdbh;
|
||||
php_pdo_dbh_fetch_object(object)->inner = pdbh;
|
||||
pdbh->refcount++;
|
||||
dbh = pdbh;
|
||||
}
|
||||
@@ -432,6 +495,19 @@ options:
|
||||
zend_throw_exception(pdo_exception_ce, "Constructor failed", 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* {{{ */
|
||||
PHP_METHOD(PDO, __construct)
|
||||
{
|
||||
internal_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, Z_OBJ(EX(This)), EX(This).value.ce, NULL);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ */
|
||||
PHP_METHOD(PDO, connect)
|
||||
{
|
||||
internal_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, Z_OBJ(EX(This)), EX(This).value.ce, return_value);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zval *pdo_stmt_instantiate(pdo_dbh_t *dbh, zval *object, zend_class_entry *dbstmt_ce, zval *ctor_args) /* {{{ */
|
||||
@@ -1334,6 +1410,7 @@ static HashTable *dbh_get_gc(zend_object *object, zval **gc_data, int *gc_count)
|
||||
}
|
||||
|
||||
static zend_object_handlers pdo_dbh_object_handlers;
|
||||
|
||||
static void pdo_dbh_free_storage(zend_object *std);
|
||||
|
||||
void pdo_dbh_init(int module_number)
|
||||
|
||||
@@ -166,6 +166,13 @@ class PDO
|
||||
|
||||
public function __construct(string $dsn, ?string $username = null, #[\SensitiveParameter] ?string $password = null, ?array $options = null) {}
|
||||
|
||||
public static function connect(
|
||||
string $dsn,
|
||||
?string $username = null,
|
||||
#[\SensitiveParameter] ?string $password = null,
|
||||
?array $options = null
|
||||
): static {}
|
||||
|
||||
/** @tentative-return-type */
|
||||
public function beginTransaction(): bool {}
|
||||
|
||||
|
||||
13
ext/pdo/pdo_dbh_arginfo.h
generated
13
ext/pdo/pdo_dbh_arginfo.h
generated
@@ -1,5 +1,5 @@
|
||||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: acd95f74c8b95515d3177f55682f9ee50dd779e9 */
|
||||
* Stub hash: 006be61b2c519e7d9ca997a7f12135eb3e0f3500 */
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_PDO___construct, 0, 0, 1)
|
||||
ZEND_ARG_TYPE_INFO(0, dsn, IS_STRING, 0)
|
||||
@@ -8,6 +8,13 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_PDO___construct, 0, 0, 1)
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 1, "null")
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_PDO_connect, 0, 1, IS_STATIC, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, dsn, IS_STRING, 0)
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, username, IS_STRING, 1, "null")
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, password, IS_STRING, 1, "null")
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 1, "null")
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_PDO_beginTransaction, 0, 0, _IS_BOOL, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
@@ -60,6 +67,7 @@ ZEND_END_ARG_INFO()
|
||||
|
||||
|
||||
ZEND_METHOD(PDO, __construct);
|
||||
ZEND_METHOD(PDO, connect);
|
||||
ZEND_METHOD(PDO, beginTransaction);
|
||||
ZEND_METHOD(PDO, commit);
|
||||
ZEND_METHOD(PDO, errorCode);
|
||||
@@ -78,6 +86,7 @@ ZEND_METHOD(PDO, setAttribute);
|
||||
|
||||
static const zend_function_entry class_PDO_methods[] = {
|
||||
ZEND_ME(PDO, __construct, arginfo_class_PDO___construct, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(PDO, connect, arginfo_class_PDO_connect, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
|
||||
ZEND_ME(PDO, beginTransaction, arginfo_class_PDO_beginTransaction, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(PDO, commit, arginfo_class_PDO_commit, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(PDO, errorCode, arginfo_class_PDO_errorCode, ZEND_ACC_PUBLIC)
|
||||
@@ -557,5 +566,7 @@ static zend_class_entry *register_class_PDO(void)
|
||||
|
||||
zend_add_parameter_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "__construct", sizeof("__construct") - 1), 2, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0);
|
||||
|
||||
zend_add_parameter_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "connect", sizeof("connect") - 1), 2, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0);
|
||||
|
||||
return class_entry;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#define PHP_STMT_GET_OBJ \
|
||||
pdo_stmt_t *stmt = Z_PDO_STMT_P(ZEND_THIS); \
|
||||
if (!stmt->dbh) { \
|
||||
zend_throw_error(NULL, "PDO object is uninitialized"); \
|
||||
zend_throw_error(NULL, "%s object is uninitialized", ZSTR_VAL(Z_OBJ(EX(This))->ce->name)); \
|
||||
RETURN_THROWS(); \
|
||||
} \
|
||||
|
||||
@@ -2231,7 +2231,7 @@ zend_object_iterator *pdo_stmt_iter_get(zend_class_entry *ce, zval *object, int
|
||||
|
||||
pdo_stmt_t *stmt = Z_PDO_STMT_P(object);
|
||||
if (!stmt->dbh) {
|
||||
zend_throw_error(NULL, "PDO object is uninitialized");
|
||||
zend_throw_error(NULL, "%s object is uninitialized", ZSTR_VAL(ce->name));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,9 +19,12 @@
|
||||
|
||||
#include "zend.h"
|
||||
|
||||
extern zend_module_entry pdo_module_entry;
|
||||
PHPAPI extern zend_module_entry pdo_module_entry;
|
||||
#define phpext_pdo_ptr &pdo_module_entry
|
||||
|
||||
PHPAPI extern zend_class_entry *pdo_dbh_ce;
|
||||
PHPAPI extern zend_object *pdo_dbh_new(zend_class_entry *ce);
|
||||
|
||||
#include "php_version.h"
|
||||
#define PHP_PDO_VERSION PHP_VERSION
|
||||
|
||||
@@ -50,14 +53,11 @@ PHP_MINFO_FUNCTION(pdo);
|
||||
#define REGISTER_PDO_CLASS_CONST_LONG(const_name, value) \
|
||||
zend_declare_class_constant_long(php_pdo_get_dbh_ce(), const_name, sizeof(const_name)-1, (zend_long)value);
|
||||
|
||||
#define REGISTER_PDO_CLASS_CONST_STRING(const_name, value) \
|
||||
zend_declare_class_constant_stringl(php_pdo_get_dbh_ce(), const_name, sizeof(const_name)-1, value, sizeof(value)-1);
|
||||
|
||||
#define LONG_CONST(c) (zend_long) c
|
||||
|
||||
#define PDO_CONSTRUCT_CHECK \
|
||||
if (!dbh->driver) { \
|
||||
zend_throw_error(NULL, "PDO object is not initialized, constructor was not called"); \
|
||||
zend_throw_error(NULL, "%s object is uninitialized", ZSTR_VAL(Z_OBJ(EX(This))->ce->name)); \
|
||||
RETURN_THROWS(); \
|
||||
} \
|
||||
|
||||
|
||||
@@ -653,6 +653,11 @@ PDO_API zend_result php_pdo_register_driver(const pdo_driver_t *driver);
|
||||
/* call this in MSHUTDOWN to unregister your PDO driver */
|
||||
PDO_API void php_pdo_unregister_driver(const pdo_driver_t *driver);
|
||||
|
||||
/* Call this in MINIT to register the PDO driver specific class entry.
|
||||
* Registering the driver specific class entry might fail and should be reported accordingly in MINIT.
|
||||
* Unregistering the class entry is not necessary, since php_pdo_unregister_driver() takes care of it. */
|
||||
PDO_API zend_result php_pdo_register_driver_specific_ce(const pdo_driver_t *driver, zend_class_entry *ce);
|
||||
|
||||
/* For the convenience of drivers, this function will parse a data source
|
||||
* string, of the form "name=value; name2=value2" and populate variables
|
||||
* according to the data you pass in and array of pdo_data_src_parser structures */
|
||||
|
||||
@@ -22,15 +22,14 @@
|
||||
#include "php_pdo_error.h"
|
||||
|
||||
extern HashTable pdo_driver_hash;
|
||||
extern HashTable pdo_driver_specific_ce_hash;
|
||||
extern zend_class_entry *pdo_exception_ce;
|
||||
int php_pdo_list_entry(void);
|
||||
|
||||
void pdo_dbh_init(int module_number);
|
||||
void pdo_stmt_init(void);
|
||||
|
||||
extern zend_object *pdo_dbh_new(zend_class_entry *ce);
|
||||
extern const zend_function_entry pdo_dbh_functions[];
|
||||
extern zend_class_entry *pdo_dbh_ce;
|
||||
extern ZEND_RSRC_DTOR_FUNC(php_pdo_pdbh_dtor);
|
||||
|
||||
extern zend_object *pdo_dbstmt_new(zend_class_entry *ce);
|
||||
|
||||
@@ -18,7 +18,7 @@ if (getenv('PDOTEST_DSN') === false) {
|
||||
class PDOTest {
|
||||
// create an instance of the PDO driver, based on
|
||||
// the current environment
|
||||
static function factory($classname = 'PDO') {
|
||||
static function factory($classname = PDO::class) {
|
||||
$dsn = getenv('PDOTEST_DSN');
|
||||
$user = getenv('PDOTEST_USER');
|
||||
$pass = getenv('PDOTEST_PASS');
|
||||
@@ -54,12 +54,12 @@ class PDOTest {
|
||||
}
|
||||
}
|
||||
|
||||
static function test_factory($file) {
|
||||
static function test_factory($file, $classname = PDO::class) {
|
||||
$config = self::get_config($file);
|
||||
foreach ($config['ENV'] as $k => $v) {
|
||||
putenv("$k=$v");
|
||||
}
|
||||
return self::factory();
|
||||
return self::factory($classname);
|
||||
}
|
||||
|
||||
static function get_config($file) {
|
||||
|
||||
@@ -34,6 +34,6 @@ try {
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
PDO object is not initialized, constructor was not called
|
||||
PDO object is uninitialized
|
||||
PDO object is uninitialized
|
||||
MyPDO object is uninitialized
|
||||
MyPDOStatement object is uninitialized
|
||||
MyPDOStatement object is uninitialized
|
||||
|
||||
@@ -27,10 +27,13 @@
|
||||
#include "php_pdo_dblib.h"
|
||||
#include "php_pdo_dblib_int.h"
|
||||
#include "zend_exceptions.h"
|
||||
#include "pdo_dblib_arginfo.h"
|
||||
|
||||
ZEND_DECLARE_MODULE_GLOBALS(dblib)
|
||||
static PHP_GINIT_FUNCTION(dblib);
|
||||
|
||||
static zend_class_entry *PdoDblib_ce;
|
||||
|
||||
static const zend_module_dep pdo_dblib_deps[] = {
|
||||
ZEND_MOD_REQUIRED("pdo")
|
||||
ZEND_MOD_END
|
||||
@@ -201,6 +204,9 @@ PHP_MINIT_FUNCTION(pdo_dblib)
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
PdoDblib_ce = register_class_PdoDblib(pdo_dbh_ce);
|
||||
PdoDblib_ce->create_object = pdo_dbh_new;
|
||||
|
||||
if (FAILURE == php_pdo_register_driver(&pdo_dblib_driver)) {
|
||||
return FAILURE;
|
||||
}
|
||||
@@ -210,7 +216,7 @@ PHP_MINIT_FUNCTION(pdo_dblib)
|
||||
dbmsghandle((MHANDLEFUNC) pdo_dblib_msg_handler);
|
||||
#endif
|
||||
|
||||
return SUCCESS;
|
||||
return php_pdo_register_driver_specific_ce(&pdo_dblib_driver, PdoDblib_ce);
|
||||
}
|
||||
|
||||
PHP_MSHUTDOWN_FUNCTION(pdo_dblib)
|
||||
|
||||
31
ext/pdo_dblib/pdo_dblib.stub.php
Normal file
31
ext/pdo_dblib/pdo_dblib.stub.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/** @generate-class-entries */
|
||||
|
||||
/**
|
||||
* @strict-properties
|
||||
* @not-serializable
|
||||
*/
|
||||
class PdoDblib extends PDO
|
||||
{
|
||||
/** @cvalue PDO_DBLIB_ATTR_CONNECTION_TIMEOUT */
|
||||
public const int ATTR_CONNECTION_TIMEOUT = UNKNOWN;
|
||||
|
||||
/** @cvalue PDO_DBLIB_ATTR_QUERY_TIMEOUT */
|
||||
public const int ATTR_QUERY_TIMEOUT = UNKNOWN;
|
||||
|
||||
/** @cvalue PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER */
|
||||
public const int ATTR_STRINGIFY_UNIQUEIDENTIFIER = UNKNOWN;
|
||||
|
||||
/** @cvalue PDO_DBLIB_ATTR_VERSION */
|
||||
public const int ATTR_VERSION = UNKNOWN;
|
||||
|
||||
/** @cvalue PDO_DBLIB_ATTR_TDS_VERSION */
|
||||
public const int ATTR_TDS_VERSION = UNKNOWN;
|
||||
|
||||
/** @cvalue PDO_DBLIB_ATTR_SKIP_EMPTY_ROWSETS */
|
||||
public const int ATTR_SKIP_EMPTY_ROWSETS = UNKNOWN;
|
||||
|
||||
/** @cvalue PDO_DBLIB_ATTR_DATETIME_CONVERT */
|
||||
public const int ATTR_DATETIME_CONVERT = UNKNOWN;
|
||||
}
|
||||
62
ext/pdo_dblib/pdo_dblib_arginfo.h
generated
Normal file
62
ext/pdo_dblib/pdo_dblib_arginfo.h
generated
Normal file
@@ -0,0 +1,62 @@
|
||||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: d2a7022c8e6e259b452786e00867b4a167d58277 */
|
||||
|
||||
|
||||
|
||||
|
||||
static const zend_function_entry class_PdoDblib_methods[] = {
|
||||
ZEND_FE_END
|
||||
};
|
||||
|
||||
static zend_class_entry *register_class_PdoDblib(zend_class_entry *class_entry_PDO)
|
||||
{
|
||||
zend_class_entry ce, *class_entry;
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "PdoDblib", class_PdoDblib_methods);
|
||||
class_entry = zend_register_internal_class_ex(&ce, class_entry_PDO);
|
||||
class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE;
|
||||
|
||||
zval const_ATTR_CONNECTION_TIMEOUT_value;
|
||||
ZVAL_LONG(&const_ATTR_CONNECTION_TIMEOUT_value, PDO_DBLIB_ATTR_CONNECTION_TIMEOUT);
|
||||
zend_string *const_ATTR_CONNECTION_TIMEOUT_name = zend_string_init_interned("ATTR_CONNECTION_TIMEOUT", sizeof("ATTR_CONNECTION_TIMEOUT") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_CONNECTION_TIMEOUT_name, &const_ATTR_CONNECTION_TIMEOUT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_CONNECTION_TIMEOUT_name);
|
||||
|
||||
zval const_ATTR_QUERY_TIMEOUT_value;
|
||||
ZVAL_LONG(&const_ATTR_QUERY_TIMEOUT_value, PDO_DBLIB_ATTR_QUERY_TIMEOUT);
|
||||
zend_string *const_ATTR_QUERY_TIMEOUT_name = zend_string_init_interned("ATTR_QUERY_TIMEOUT", sizeof("ATTR_QUERY_TIMEOUT") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_QUERY_TIMEOUT_name, &const_ATTR_QUERY_TIMEOUT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_QUERY_TIMEOUT_name);
|
||||
|
||||
zval const_ATTR_STRINGIFY_UNIQUEIDENTIFIER_value;
|
||||
ZVAL_LONG(&const_ATTR_STRINGIFY_UNIQUEIDENTIFIER_value, PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER);
|
||||
zend_string *const_ATTR_STRINGIFY_UNIQUEIDENTIFIER_name = zend_string_init_interned("ATTR_STRINGIFY_UNIQUEIDENTIFIER", sizeof("ATTR_STRINGIFY_UNIQUEIDENTIFIER") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_STRINGIFY_UNIQUEIDENTIFIER_name, &const_ATTR_STRINGIFY_UNIQUEIDENTIFIER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_STRINGIFY_UNIQUEIDENTIFIER_name);
|
||||
|
||||
zval const_ATTR_VERSION_value;
|
||||
ZVAL_LONG(&const_ATTR_VERSION_value, PDO_DBLIB_ATTR_VERSION);
|
||||
zend_string *const_ATTR_VERSION_name = zend_string_init_interned("ATTR_VERSION", sizeof("ATTR_VERSION") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_VERSION_name, &const_ATTR_VERSION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_VERSION_name);
|
||||
|
||||
zval const_ATTR_TDS_VERSION_value;
|
||||
ZVAL_LONG(&const_ATTR_TDS_VERSION_value, PDO_DBLIB_ATTR_TDS_VERSION);
|
||||
zend_string *const_ATTR_TDS_VERSION_name = zend_string_init_interned("ATTR_TDS_VERSION", sizeof("ATTR_TDS_VERSION") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_TDS_VERSION_name, &const_ATTR_TDS_VERSION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_TDS_VERSION_name);
|
||||
|
||||
zval const_ATTR_SKIP_EMPTY_ROWSETS_value;
|
||||
ZVAL_LONG(&const_ATTR_SKIP_EMPTY_ROWSETS_value, PDO_DBLIB_ATTR_SKIP_EMPTY_ROWSETS);
|
||||
zend_string *const_ATTR_SKIP_EMPTY_ROWSETS_name = zend_string_init_interned("ATTR_SKIP_EMPTY_ROWSETS", sizeof("ATTR_SKIP_EMPTY_ROWSETS") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_SKIP_EMPTY_ROWSETS_name, &const_ATTR_SKIP_EMPTY_ROWSETS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_SKIP_EMPTY_ROWSETS_name);
|
||||
|
||||
zval const_ATTR_DATETIME_CONVERT_value;
|
||||
ZVAL_LONG(&const_ATTR_DATETIME_CONVERT_value, PDO_DBLIB_ATTR_DATETIME_CONVERT);
|
||||
zend_string *const_ATTR_DATETIME_CONVERT_name = zend_string_init_interned("ATTR_DATETIME_CONVERT", sizeof("ATTR_DATETIME_CONVERT") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_DATETIME_CONVERT_name, &const_ATTR_DATETIME_CONVERT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_DATETIME_CONVERT_name);
|
||||
|
||||
return class_entry;
|
||||
}
|
||||
@@ -5,13 +5,14 @@ pdo_dblib
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$db = getDbConnection();
|
||||
if (!driver_supports_batch_statements_without_select($db)) die('xfail test will fail with this version of FreeTDS');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$db = getDbConnection();
|
||||
// creating a proc need to be a statement in it's own batch, so we need to do a little setup first
|
||||
$db->query("create table #test_batch_stmt_ins_exec(id int); ");
|
||||
$db->query(
|
||||
|
||||
@@ -5,13 +5,15 @@ pdo_dblib
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$db = getDbConnection();
|
||||
if (!driver_supports_batch_statements_without_select($db)) die('xfail test will fail with this version of FreeTDS');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$db = getDbConnection();
|
||||
|
||||
$stmt = $db->query(
|
||||
"create table #test_batch_stmt_ins_sel_up_del(id int);" .
|
||||
"insert into #test_batch_stmt_ins_sel_up_del values(1), (2), (3);" .
|
||||
|
||||
@@ -5,13 +5,14 @@ pdo_dblib
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$db = getDbConnection();
|
||||
if (!driver_supports_batch_statements_without_select($db)) die('xfail test will fail with this version of FreeTDS');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$db = getDbConnection();
|
||||
$stmt = $db->query(
|
||||
"create table #test_batch_stmt_ins_up(id int);" .
|
||||
"insert into #test_batch_stmt_ins_up values(1), (2), (3);" .
|
||||
|
||||
@@ -5,13 +5,14 @@ pdo_dblib
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$db = getDbConnection();
|
||||
if (!driver_supports_batch_statements_without_select($db)) die('xfail test will fail with this version of FreeTDS');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$db = getDbConnection();
|
||||
$stmt = $db->query(
|
||||
"create table #test_batch_stmt_rowcount(id int); " .
|
||||
"set rowcount 2; " .
|
||||
|
||||
@@ -5,13 +5,14 @@ pdo_dblib
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$db = getDbConnection();
|
||||
if (!driver_supports_batch_statements_without_select($db)) die('xfail test will fail with this version of FreeTDS');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$db = getDbConnection();
|
||||
$stmt = $db->query(
|
||||
"create table #test_batch_stmt_transaction(id int);" .
|
||||
"insert into #test_batch_stmt_transaction values(1), (2), (3);" .
|
||||
|
||||
@@ -5,13 +5,14 @@ pdo_dblib
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$db = getDbConnection();
|
||||
if (!driver_supports_batch_statements_without_select($db)) die('xfail test will fail with this version of FreeTDS');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$db = getDbConnection();
|
||||
$stmt = $db->query(
|
||||
"create table #test_batch_stmt_try(id int);" .
|
||||
"insert into #test_batch_stmt_try values(1), (2), (3);" .
|
||||
|
||||
@@ -5,11 +5,14 @@ pdo_dblib
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
getDbConnection();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$db = getDbConnection();
|
||||
|
||||
/*We see these rows */
|
||||
$db->query("CREATE table test38955(val int)");
|
||||
$db->beginTransaction();
|
||||
@@ -34,6 +37,7 @@ var_dump($rows);
|
||||
--CLEAN--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
$db = getDbConnection();
|
||||
$db->exec("DROP TABLE IF EXISTS test38955");
|
||||
?>
|
||||
--EXPECT--
|
||||
|
||||
@@ -5,6 +5,7 @@ pdo_dblib
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
getDbConnection();
|
||||
?>
|
||||
--CONFLICTS--
|
||||
all
|
||||
@@ -12,6 +13,7 @@ all
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$db = getDbConnection();
|
||||
$stmt = $db->prepare("select top 1 ic1.* from information_schema.columns ic1");
|
||||
$stmt->execute();
|
||||
var_dump($stmt->getColumnMeta(0));
|
||||
|
||||
@@ -5,11 +5,13 @@ pdo_dblib
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
getDbConnection();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$db = getDbConnection();
|
||||
$db->query('CREATE TABLE "Test Table47588" ("My Field" int, "Another Field" varchar(32) not null default \'test_string\')');
|
||||
$db->query('INSERT INTO "Test Table47588" ("My Field") values(1), (2), (3)');
|
||||
$rs = $db->query('SELECT * FROM "Test Table47588"');
|
||||
@@ -19,6 +21,7 @@ echo "Done.\n";
|
||||
--CLEAN--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
$db = getDbConnection();
|
||||
$db->exec('DROP TABLE IF EXISTS "Test Table47588"');
|
||||
?>
|
||||
--EXPECT--
|
||||
|
||||
@@ -6,6 +6,7 @@ pdo_dblib
|
||||
<?php
|
||||
if (getenv('SKIP_REPEAT')) die('skip May fail on repeat');
|
||||
require __DIR__ . '/config.inc';
|
||||
getDbConnection();
|
||||
?>
|
||||
--CONFLICTS--
|
||||
all
|
||||
@@ -13,6 +14,8 @@ all
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$db = getDbConnection();
|
||||
|
||||
/* This should be sufficient to overflow any buffers */
|
||||
$stmt = $db->prepare("select *
|
||||
from information_schema.columns ic1
|
||||
|
||||
@@ -5,10 +5,12 @@ pdo_dblib
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
getDbConnection();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
$db = getDbConnection();
|
||||
$db->query('set dateformat ymd');
|
||||
$rs = $db->query("select cast('1950-01-18 23:00:00' as smalldatetime) as sdt, cast('2030-01-01 23:59:59' as datetime) as dt");
|
||||
var_dump($rs->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
@@ -5,11 +5,14 @@ pdo_dblib
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
getDbConnection();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$db = getDbConnection();
|
||||
|
||||
$stmt = $db->query('SELECT 1; SELECT 2; SELECT 3;');
|
||||
var_dump($stmt->fetch());
|
||||
var_dump($stmt->fetch());
|
||||
|
||||
@@ -5,11 +5,14 @@ pdo_dblib
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
getDbConnection();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$db = getDbConnection();
|
||||
|
||||
$query = "declare @myInt int = 1; select @myInt;";
|
||||
$stmt = $db->query($query);
|
||||
$stmt->nextRowset(); // Added line
|
||||
|
||||
@@ -5,11 +5,14 @@ pdo_dblib
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
getDbConnection();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$db = getDbConnection();
|
||||
|
||||
$sql = '
|
||||
SET NOCOUNT ON
|
||||
SELECT 0 AS [result]
|
||||
|
||||
@@ -5,11 +5,14 @@ pdo_dblib
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
getDbConnection();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$db = getDbConnection();
|
||||
|
||||
$sql = "
|
||||
exec dbo.sp_executesql N'
|
||||
SELECT TOP 1 * FROM sysobjects
|
||||
|
||||
@@ -5,11 +5,14 @@ pdo_dblib
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
getDbConnection();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$db = getDbConnection();
|
||||
|
||||
$stmt = $db->prepare("SELECT 1, 2 AS named, 3");
|
||||
$stmt->execute();
|
||||
var_dump($stmt->fetchAll());
|
||||
|
||||
@@ -5,12 +5,15 @@ pdo_dblib
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
$db = getDbConnection();
|
||||
if (in_array($db->getAttribute(PDO::DBLIB_ATTR_TDS_VERSION), ['4.2', '4.6', '5.0', '6.0', '7.0'])) die('skip bigint type is unsupported by active TDS version');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$db = getDbConnection();
|
||||
|
||||
// on 64-bit machines, these columns should come back as ints
|
||||
// on 32-bit machines, they will come back as strings because zend_long isn't big enough
|
||||
$expected = PHP_INT_SIZE == 8 ? 1 : '1';
|
||||
|
||||
@@ -13,30 +13,59 @@ function strstartswith($haystack, $needle) {
|
||||
return $needle === "" || strrpos($haystack, $needle, -strlen($haystack)) !== false;
|
||||
}
|
||||
|
||||
if (false !== getenv('PDO_DBLIB_TEST_DSN')) {
|
||||
$dsn = getenv('PDO_DBLIB_TEST_DSN');
|
||||
} else {
|
||||
$dsn = 'dblib:host=localhost;dbname=test';
|
||||
function getCredentials() {
|
||||
if (false !== getenv('PDO_DBLIB_TEST_DSN')) {
|
||||
$dsn = getenv('PDO_DBLIB_TEST_DSN');
|
||||
} else {
|
||||
$dsn = 'dblib:host=localhost;dbname=test';
|
||||
}
|
||||
|
||||
if (false !== getenv('PDO_DBLIB_TEST_USER')) {
|
||||
$user = getenv('PDO_DBLIB_TEST_USER');
|
||||
} else {
|
||||
$user = 'php';
|
||||
}
|
||||
|
||||
if (false !== getenv('PDO_DBLIB_TEST_PASS')) {
|
||||
$pass = getenv('PDO_DBLIB_TEST_PASS');
|
||||
} else {
|
||||
$pass = 'password';
|
||||
}
|
||||
|
||||
return [$dsn, $user, $pass];
|
||||
}
|
||||
|
||||
if (false !== getenv('PDO_DBLIB_TEST_USER')) {
|
||||
$user = getenv('PDO_DBLIB_TEST_USER');
|
||||
} else {
|
||||
$user = 'php';
|
||||
}
|
||||
|
||||
if (false !== getenv('PDO_DBLIB_TEST_PASS')) {
|
||||
$pass = getenv('PDO_DBLIB_TEST_PASS');
|
||||
} else {
|
||||
$pass = 'password';
|
||||
}
|
||||
|
||||
try {
|
||||
$db = new PDO($dsn, $user, $pass);
|
||||
function setAttributes(PDO $db) {
|
||||
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);
|
||||
} catch (PDOException $e) {
|
||||
die('skip ' . $e->getMessage());
|
||||
}
|
||||
|
||||
function getDbConnection(string $class = PDO::class, ?array $attributes = null) {
|
||||
[$dsn, $user, $pass] = getCredentials();
|
||||
|
||||
try {
|
||||
$db = new $class($dsn, $user, $pass, $attributes);
|
||||
if ($attributes === null) {
|
||||
setAttributes($db);
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
die('skip ' . $e->getMessage());
|
||||
}
|
||||
|
||||
return $db;
|
||||
}
|
||||
|
||||
function connectToDb() {
|
||||
[$dsn, $user, $pass] = getCredentials();
|
||||
|
||||
try {
|
||||
$db = PDO::connect($dsn, $user, $pass);
|
||||
setAttributes($db);
|
||||
} catch (PDOException $e) {
|
||||
die('skip ' . $e->getMessage());
|
||||
}
|
||||
|
||||
return $db;
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -5,12 +5,15 @@ pdo_dblib
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
$db = getDbConnection();
|
||||
if (in_array($db->getAttribute(PDO::DBLIB_ATTR_TDS_VERSION), ['4.2', '4.6', '5.0', '6.0', '7.0', '7.1', '7.2'])) die('skip feature unsupported by this TDS version');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$db = getDbConnection();
|
||||
|
||||
$sql = "SELECT convert(datetime2, '10231017 10:22:44.1355318') AS [d]";
|
||||
|
||||
var_dump($db->getAttribute(PDO::DBLIB_ATTR_DATETIME_CONVERT));
|
||||
|
||||
@@ -5,11 +5,14 @@ pdo_dblib
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
getDbConnection();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$db = getDbConnection();
|
||||
|
||||
$sql = "SELECT convert(datetime, '20171027 10:22:44.135') AS [d]";
|
||||
|
||||
var_dump($db->getAttribute(PDO::DBLIB_ATTR_DATETIME_CONVERT));
|
||||
|
||||
@@ -5,11 +5,14 @@ pdo_dblib
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
getDbConnection();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$db = getDbConnection();
|
||||
|
||||
$version = $db->getAttribute(PDO::DBLIB_ATTR_TDS_VERSION);
|
||||
var_dump((is_string($version) && strlen($version)) || $version === false);
|
||||
|
||||
|
||||
@@ -5,11 +5,14 @@ pdo_dblib
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
getDbConnection();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$db = getDbConnection();
|
||||
|
||||
$version = $db->getAttribute(PDO::DBLIB_ATTR_VERSION);
|
||||
var_dump(is_string($version) && strlen($version));
|
||||
|
||||
|
||||
@@ -5,11 +5,14 @@ pdo_dblib
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
getDbConnection();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$db = getDbConnection();
|
||||
|
||||
$stmt = $db->prepare('SELECT :value');
|
||||
$stmt->bindValue(':value', 'foo', PDO::PARAM_STR | PDO::PARAM_STR_NATL);
|
||||
$stmt->execute();
|
||||
|
||||
@@ -5,10 +5,12 @@ pdo_dblib
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
getDbConnection();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
$db = getDbConnection();
|
||||
var_dump($db->quote(true, PDO::PARAM_BOOL));
|
||||
var_dump($db->quote(false, PDO::PARAM_BOOL));
|
||||
var_dump($db->quote(42, PDO::PARAM_INT));
|
||||
@@ -26,7 +28,7 @@ var_dump($db->quote('foo', PDO::PARAM_STR | PDO::PARAM_STR_CHAR));
|
||||
var_dump($db->quote('über', PDO::PARAM_STR));
|
||||
var_dump($db->quote('über', PDO::PARAM_STR | PDO::PARAM_STR_NATL));
|
||||
|
||||
$db = new PDO($dsn, $user, $pass, [PDO::ATTR_DEFAULT_STR_PARAM => PDO::PARAM_STR_NATL]);
|
||||
$db = getDbConnection(PDO::class, [PDO::ATTR_DEFAULT_STR_PARAM => PDO::PARAM_STR_NATL]);
|
||||
var_dump($db->getAttribute(PDO::ATTR_DEFAULT_STR_PARAM) === PDO::PARAM_STR_NATL);
|
||||
|
||||
?>
|
||||
|
||||
44
ext/pdo_dblib/tests/pdodblib_001.phpt
Normal file
44
ext/pdo_dblib/tests/pdodblib_001.phpt
Normal file
@@ -0,0 +1,44 @@
|
||||
--TEST--
|
||||
PdoDblib basic
|
||||
--EXTENSIONS--
|
||||
pdo_dblib
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
getDbConnection();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require __DIR__ . '/config.inc';
|
||||
$db = getDbConnection(PdoDblib::class);
|
||||
|
||||
$db->query("CREATE TABLE #pdo_dblib_001(name VARCHAR(32)); ");
|
||||
$db->query("INSERT INTO #pdo_dblib_001 VALUES('PHP'), ('PHP6');");
|
||||
|
||||
foreach ($db->query('SELECT name FROM #pdo_dblib_001') as $row) {
|
||||
var_dump($row);
|
||||
}
|
||||
|
||||
echo "Fin.";
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
$db = getDbConnection();
|
||||
$db->query('DROP TABLE IF EXISTS #pdo_dblib_001');
|
||||
?>
|
||||
--EXPECT--
|
||||
array(2) {
|
||||
["name"]=>
|
||||
string(3) "PHP"
|
||||
[0]=>
|
||||
string(3) "PHP"
|
||||
}
|
||||
array(2) {
|
||||
["name"]=>
|
||||
string(4) "PHP6"
|
||||
[0]=>
|
||||
string(4) "PHP6"
|
||||
}
|
||||
Fin.
|
||||
48
ext/pdo_dblib/tests/pdodblib_002.phpt
Normal file
48
ext/pdo_dblib/tests/pdodblib_002.phpt
Normal file
@@ -0,0 +1,48 @@
|
||||
--TEST--
|
||||
PdoDblib create through PDO::connect
|
||||
--EXTENSIONS--
|
||||
pdo_dblib
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
getDbConnection();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$db = connectToDb();
|
||||
if (!$db instanceof PdoDblib) {
|
||||
echo "Wrong class type. Should be PdoDblib but is " . get_class($db) . "\n";
|
||||
}
|
||||
|
||||
$db->query("CREATE TABLE #pdo_dblib_002(name VARCHAR(32))");
|
||||
$db->query("INSERT INTO #pdo_dblib_002 VALUES('PHP'), ('PHP6')");
|
||||
|
||||
foreach ($db->query('SELECT name FROM #pdo_dblib_002') as $row) {
|
||||
var_dump($row);
|
||||
}
|
||||
|
||||
echo "Fin.";
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
$db = getDbConnection();
|
||||
$db->query('DROP TABLE IF EXISTS #pdo_dblib_002');
|
||||
?>
|
||||
--EXPECT--
|
||||
array(2) {
|
||||
["name"]=>
|
||||
string(3) "PHP"
|
||||
[0]=>
|
||||
string(3) "PHP"
|
||||
}
|
||||
array(2) {
|
||||
["name"]=>
|
||||
string(4) "PHP6"
|
||||
[0]=>
|
||||
string(4) "PHP6"
|
||||
}
|
||||
Fin.
|
||||
@@ -5,12 +5,14 @@ pdo_dblib
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
$db = getDbConnection();
|
||||
if (in_array($db->getAttribute(PDO::DBLIB_ATTR_TDS_VERSION), ['4.2', '4.6'])) die('skip feature unsupported by this TDS version');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$db = getDbConnection();
|
||||
|
||||
$testGUID = '82A88958-672B-4C22-842F-216E2B88E72A';
|
||||
$testGUIDBinary = base64_decode('WImogitnIkyELyFuK4jnKg==');
|
||||
|
||||
@@ -6,15 +6,18 @@ pdo_dblib
|
||||
<?php
|
||||
if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
|
||||
require __DIR__ . '/config.inc';
|
||||
getDbConnection();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$db = getDbConnection();
|
||||
|
||||
$sql = 'WAITFOR DELAY \'00:00:02\'';
|
||||
|
||||
// regular timeout attribute, set after instance created, will affect query timeout, causing this query to fail
|
||||
$db = new PDO($dsn, $user, $pass);
|
||||
$db = getDbConnection();
|
||||
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
|
||||
$db->setAttribute(PDO::ATTR_TIMEOUT, 1);
|
||||
$stmt = $db->prepare($sql);
|
||||
@@ -28,7 +31,7 @@ if (!$stmt->execute()) {
|
||||
}
|
||||
|
||||
// pdo_dblib-specific timeout attribute, set after instance created, will control query timeout, causing this query to fail
|
||||
$db = new PDO($dsn, $user, $pass);
|
||||
$db = getDbConnection();
|
||||
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
|
||||
$db->setAttribute(PDO::DBLIB_ATTR_QUERY_TIMEOUT, 1);
|
||||
$stmt = $db->prepare($sql);
|
||||
@@ -42,7 +45,7 @@ if (!$stmt->execute()) {
|
||||
}
|
||||
|
||||
// regular timeout attribute will affect query timeout, causing this query to fail
|
||||
$db = new PDO($dsn, $user, $pass, [PDO::ATTR_ERRMODE => PDO::ERRMODE_SILENT, PDO::ATTR_TIMEOUT => 1]);
|
||||
$db = getDbConnection(PDO::class, [PDO::ATTR_ERRMODE => PDO::ERRMODE_SILENT, PDO::ATTR_TIMEOUT => 1]);
|
||||
$stmt = $db->prepare($sql);
|
||||
if (!$stmt->execute()) {
|
||||
echo "OK\n";
|
||||
@@ -54,7 +57,7 @@ if (!$stmt->execute()) {
|
||||
}
|
||||
|
||||
// pdo_dblib-specific timeout attribute will control query timeout, causing this query to fail
|
||||
$db = new PDO($dsn, $user, $pass, [PDO::ATTR_ERRMODE => PDO::ERRMODE_SILENT, PDO::DBLIB_ATTR_QUERY_TIMEOUT => 1]);
|
||||
$db = getDbConnection(PDO::class, [PDO::ATTR_ERRMODE => PDO::ERRMODE_SILENT, PDO::DBLIB_ATTR_QUERY_TIMEOUT => 1]);
|
||||
$stmt = $db->prepare($sql);
|
||||
if (!$stmt->execute()) {
|
||||
echo "OK\n";
|
||||
|
||||
@@ -5,11 +5,14 @@ pdo_dblib
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
getDbConnection();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
$db = getDbConnection();
|
||||
|
||||
function get_expected_float_string() {
|
||||
global $db;
|
||||
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
#include "pdo/php_pdo_driver.h"
|
||||
#include "php_pdo_firebird.h"
|
||||
#include "php_pdo_firebird_int.h"
|
||||
#include "pdo_firebird_arginfo.h"
|
||||
|
||||
static zend_class_entry *PdoFirebird_ce;
|
||||
|
||||
/* {{{ pdo_firebird_deps */
|
||||
static const zend_module_dep pdo_firebird_deps[] = {
|
||||
@@ -67,12 +70,15 @@ PHP_MINIT_FUNCTION(pdo_firebird) /* {{{ */
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
PdoFirebird_ce = register_class_PdoFirebird(pdo_dbh_ce);
|
||||
PdoFirebird_ce->create_object = pdo_dbh_new;
|
||||
|
||||
#ifdef ZEND_SIGNALS
|
||||
/* firebird replaces some signals at runtime, suppress warnings. */
|
||||
SIGG(check) = 0;
|
||||
#endif
|
||||
|
||||
return SUCCESS;
|
||||
return php_pdo_register_driver_specific_ce(&pdo_firebird_driver, PdoFirebird_ce);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
34
ext/pdo_firebird/pdo_firebird.stub.php
Normal file
34
ext/pdo_firebird/pdo_firebird.stub.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/** @generate-class-entries */
|
||||
|
||||
/**
|
||||
* @strict-properties
|
||||
* @not-serializable
|
||||
*/
|
||||
class PdoFirebird extends PDO
|
||||
{
|
||||
/** @cvalue PDO_FB_ATTR_DATE_FORMAT */
|
||||
public const int ATTR_DATE_FORMAT = UNKNOWN;
|
||||
|
||||
/** @cvalue PDO_FB_ATTR_TIME_FORMAT */
|
||||
public const int ATTR_TIME_FORMAT = UNKNOWN;
|
||||
|
||||
/** @cvalue PDO_FB_ATTR_TIMESTAMP_FORMAT */
|
||||
public const int ATTR_TIMESTAMP_FORMAT = UNKNOWN;
|
||||
|
||||
/** @cvalue PDO_FB_TRANSACTION_ISOLATION_LEVEL */
|
||||
public const int TRANSACTION_ISOLATION_LEVEL = UNKNOWN;
|
||||
|
||||
/** @cvalue PDO_FB_READ_COMMITTED */
|
||||
public const int READ_COMMITTED = UNKNOWN;
|
||||
|
||||
/** @cvalue PDO_FB_REPEATABLE_READ */
|
||||
public const int REPEATABLE_READ = UNKNOWN;
|
||||
|
||||
/** @cvalue PDO_FB_SERIALIZABLE */
|
||||
public const int SERIALIZABLE = UNKNOWN;
|
||||
|
||||
/** @cvalue PDO_FB_WRITABLE_TRANSACTION */
|
||||
public const int WRITABLE_TRANSACTION = UNKNOWN;
|
||||
}
|
||||
68
ext/pdo_firebird/pdo_firebird_arginfo.h
generated
Normal file
68
ext/pdo_firebird/pdo_firebird_arginfo.h
generated
Normal file
@@ -0,0 +1,68 @@
|
||||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: 037c073de9e3e3593c62cb7da8ee7202c38c2723 */
|
||||
|
||||
|
||||
|
||||
|
||||
static const zend_function_entry class_PdoFirebird_methods[] = {
|
||||
ZEND_FE_END
|
||||
};
|
||||
|
||||
static zend_class_entry *register_class_PdoFirebird(zend_class_entry *class_entry_PDO)
|
||||
{
|
||||
zend_class_entry ce, *class_entry;
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "PdoFirebird", class_PdoFirebird_methods);
|
||||
class_entry = zend_register_internal_class_ex(&ce, class_entry_PDO);
|
||||
class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE;
|
||||
|
||||
zval const_ATTR_DATE_FORMAT_value;
|
||||
ZVAL_LONG(&const_ATTR_DATE_FORMAT_value, PDO_FB_ATTR_DATE_FORMAT);
|
||||
zend_string *const_ATTR_DATE_FORMAT_name = zend_string_init_interned("ATTR_DATE_FORMAT", sizeof("ATTR_DATE_FORMAT") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_DATE_FORMAT_name, &const_ATTR_DATE_FORMAT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_DATE_FORMAT_name);
|
||||
|
||||
zval const_ATTR_TIME_FORMAT_value;
|
||||
ZVAL_LONG(&const_ATTR_TIME_FORMAT_value, PDO_FB_ATTR_TIME_FORMAT);
|
||||
zend_string *const_ATTR_TIME_FORMAT_name = zend_string_init_interned("ATTR_TIME_FORMAT", sizeof("ATTR_TIME_FORMAT") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_TIME_FORMAT_name, &const_ATTR_TIME_FORMAT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_TIME_FORMAT_name);
|
||||
|
||||
zval const_ATTR_TIMESTAMP_FORMAT_value;
|
||||
ZVAL_LONG(&const_ATTR_TIMESTAMP_FORMAT_value, PDO_FB_ATTR_TIMESTAMP_FORMAT);
|
||||
zend_string *const_ATTR_TIMESTAMP_FORMAT_name = zend_string_init_interned("ATTR_TIMESTAMP_FORMAT", sizeof("ATTR_TIMESTAMP_FORMAT") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_TIMESTAMP_FORMAT_name, &const_ATTR_TIMESTAMP_FORMAT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_TIMESTAMP_FORMAT_name);
|
||||
|
||||
zval const_TRANSACTION_ISOLATION_LEVEL_value;
|
||||
ZVAL_LONG(&const_TRANSACTION_ISOLATION_LEVEL_value, PDO_FB_TRANSACTION_ISOLATION_LEVEL);
|
||||
zend_string *const_TRANSACTION_ISOLATION_LEVEL_name = zend_string_init_interned("TRANSACTION_ISOLATION_LEVEL", sizeof("TRANSACTION_ISOLATION_LEVEL") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_TRANSACTION_ISOLATION_LEVEL_name, &const_TRANSACTION_ISOLATION_LEVEL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_TRANSACTION_ISOLATION_LEVEL_name);
|
||||
|
||||
zval const_READ_COMMITTED_value;
|
||||
ZVAL_LONG(&const_READ_COMMITTED_value, PDO_FB_READ_COMMITTED);
|
||||
zend_string *const_READ_COMMITTED_name = zend_string_init_interned("READ_COMMITTED", sizeof("READ_COMMITTED") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_READ_COMMITTED_name, &const_READ_COMMITTED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_READ_COMMITTED_name);
|
||||
|
||||
zval const_REPEATABLE_READ_value;
|
||||
ZVAL_LONG(&const_REPEATABLE_READ_value, PDO_FB_REPEATABLE_READ);
|
||||
zend_string *const_REPEATABLE_READ_name = zend_string_init_interned("REPEATABLE_READ", sizeof("REPEATABLE_READ") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_REPEATABLE_READ_name, &const_REPEATABLE_READ_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_REPEATABLE_READ_name);
|
||||
|
||||
zval const_SERIALIZABLE_value;
|
||||
ZVAL_LONG(&const_SERIALIZABLE_value, PDO_FB_SERIALIZABLE);
|
||||
zend_string *const_SERIALIZABLE_name = zend_string_init_interned("SERIALIZABLE", sizeof("SERIALIZABLE") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_SERIALIZABLE_name, &const_SERIALIZABLE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_SERIALIZABLE_name);
|
||||
|
||||
zval const_WRITABLE_TRANSACTION_value;
|
||||
ZVAL_LONG(&const_WRITABLE_TRANSACTION_value, PDO_FB_WRITABLE_TRANSACTION);
|
||||
zend_string *const_WRITABLE_TRANSACTION_name = zend_string_init_interned("WRITABLE_TRANSACTION", sizeof("WRITABLE_TRANSACTION") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_WRITABLE_TRANSACTION_name, &const_WRITABLE_TRANSACTION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_WRITABLE_TRANSACTION_name);
|
||||
|
||||
return class_entry;
|
||||
}
|
||||
@@ -17,6 +17,7 @@ $table = "autocommit_pdo_firebird";
|
||||
|
||||
echo "========== in auto commit mode ==========\n";
|
||||
echo "auto commit mode ON\n";
|
||||
$dbh = getDbConnection();
|
||||
$dbh->setAttribute(PDO::ATTR_AUTOCOMMIT, true);
|
||||
|
||||
echo "create table and insert\n";
|
||||
@@ -53,6 +54,7 @@ echo "done!";
|
||||
--CLEAN--
|
||||
<?php
|
||||
require 'testdb.inc';
|
||||
$dbh = getDbConnection();
|
||||
@$dbh->exec("DROP TABLE autocommit_pdo_firebird");
|
||||
?>
|
||||
--EXPECTF--
|
||||
|
||||
@@ -10,6 +10,7 @@ See https://github.com/FirebirdSQL/firebird/issues/7849
|
||||
--FILE--
|
||||
<?php
|
||||
require("testdb.inc");
|
||||
$dbh = getDbConnection();
|
||||
$dbh->setAttribute(PDO::ATTR_AUTOCOMMIT, true);
|
||||
|
||||
echo "========== not in manually transaction ==========\n";
|
||||
|
||||
@@ -11,6 +11,7 @@ See https://github.com/FirebirdSQL/firebird/issues/7849
|
||||
<?php
|
||||
require 'testdb.inc';
|
||||
|
||||
$dbh = getDbConnection();
|
||||
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
|
||||
|
||||
$dbh->exec('CREATE TABLE test47415 (idx int NOT NULL PRIMARY KEY, txt VARCHAR(20))');
|
||||
@@ -36,6 +37,7 @@ unset($dbh);
|
||||
--CLEAN--
|
||||
<?php
|
||||
require 'testdb.inc';
|
||||
$dbh = getDbConnection();
|
||||
@$dbh->exec("DROP TABLE test47415");
|
||||
unset($dbh);
|
||||
?>
|
||||
|
||||
@@ -14,6 +14,7 @@ require("testdb.inc");
|
||||
|
||||
$value = '2';
|
||||
|
||||
$dbh = getDbConnection();
|
||||
$dbh->exec('CREATE TABLE test48877 (A integer)');
|
||||
$dbh->exec("INSERT INTO test48877 VALUES ('1')");
|
||||
$dbh->exec("INSERT INTO test48877 VALUES ('2')");
|
||||
@@ -39,6 +40,7 @@ unset($dbh);
|
||||
--CLEAN--
|
||||
<?php
|
||||
require 'testdb.inc';
|
||||
$dbh = getDbConnection();
|
||||
@$dbh->exec("DROP TABLE test48877");
|
||||
unset($dbh);
|
||||
?>
|
||||
|
||||
@@ -12,6 +12,7 @@ See https://github.com/FirebirdSQL/firebird/issues/7849
|
||||
|
||||
require("testdb.inc");
|
||||
|
||||
$dbh = getDbConnection();
|
||||
$dbh->exec('CREATE TABLE test53280(A VARCHAR(30), B VARCHAR(30), C VARCHAR(30))');
|
||||
$dbh->exec("INSERT INTO test53280 VALUES ('A', 'B', 'C')");
|
||||
|
||||
@@ -37,6 +38,7 @@ unset($dbh);
|
||||
--CLEAN--
|
||||
<?php
|
||||
require 'testdb.inc';
|
||||
$dbh = getDbConnection();
|
||||
@$dbh->exec("DROP TABLE test53280");
|
||||
unset($dbh);
|
||||
?>
|
||||
|
||||
@@ -12,6 +12,7 @@ See https://github.com/FirebirdSQL/firebird/issues/7849
|
||||
|
||||
require("testdb.inc");
|
||||
|
||||
$dbh = getDbConnection();
|
||||
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
|
||||
$dbh->exec("CREATE TABLE test62024 (ID INTEGER NOT NULL, TEXT VARCHAR(10))");
|
||||
|
||||
@@ -41,6 +42,7 @@ unset($dbh);
|
||||
--CLEAN--
|
||||
<?php
|
||||
require 'testdb.inc';
|
||||
$dbh = getDbConnection();
|
||||
@$dbh->exec("DROP TABLE test62024");
|
||||
unset($dbh);
|
||||
?>
|
||||
|
||||
@@ -12,6 +12,7 @@ See https://github.com/FirebirdSQL/firebird/issues/7849
|
||||
|
||||
require("testdb.inc");
|
||||
|
||||
$dbh = getDbConnection();
|
||||
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
|
||||
$dbh->exec("CREATE TABLE test64037 (ID INTEGER NOT NULL, TEXT VARCHAR(10), COST NUMERIC(15, 2))");
|
||||
$dbh->exec("INSERT INTO test64037 (ID, TEXT, COST) VALUES (1, 'test', -1.0)");
|
||||
@@ -37,6 +38,7 @@ unset($dbh);
|
||||
--CLEAN--
|
||||
<?php
|
||||
require 'testdb.inc';
|
||||
$dbh = getDbConnection();
|
||||
@$dbh->exec("DROP TABLE test64037");
|
||||
unset($dbh);
|
||||
?>
|
||||
|
||||
@@ -11,6 +11,7 @@ See https://github.com/FirebirdSQL/firebird/issues/7849
|
||||
<?php
|
||||
require 'testdb.inc';
|
||||
|
||||
$dbh = getDbConnection();
|
||||
$dbh->exec('recreate table test72583 (aint integer, asmi smallint)');
|
||||
$dbh->exec('insert into test72583 values (1, -1)');
|
||||
$S = $dbh->prepare('select aint, asmi from test72583');
|
||||
@@ -23,6 +24,7 @@ unset($dbh);
|
||||
--CLEAN--
|
||||
<?php
|
||||
require 'testdb.inc';
|
||||
$dbh = getDbConnection();
|
||||
@$dbh->exec("DROP TABLE test72583");
|
||||
unset($dbh);
|
||||
?>
|
||||
|
||||
@@ -11,6 +11,7 @@ See https://github.com/FirebirdSQL/firebird/issues/7849
|
||||
<?php
|
||||
require 'testdb.inc';
|
||||
|
||||
$dbh = getDbConnection();
|
||||
$dbh->exec('recreate table test72931 (id integer)');
|
||||
$S = $dbh->prepare('insert into test72931 (id) values (1) returning id');
|
||||
$S->execute();
|
||||
@@ -22,6 +23,7 @@ unset($dbh);
|
||||
--CLEAN--
|
||||
<?php
|
||||
require 'testdb.inc';
|
||||
$dbh = getDbConnection();
|
||||
@$dbh->exec("DROP TABLE test72931");
|
||||
unset($dbh);
|
||||
?>
|
||||
|
||||
@@ -11,6 +11,7 @@ See https://github.com/FirebirdSQL/firebird/issues/7849
|
||||
<?php
|
||||
require 'testdb.inc';
|
||||
|
||||
$dbh = getDbConnection();
|
||||
$dbh->exec('recreate table test73087 (id integer not null, content blob sub_type 1 segment size 80)');
|
||||
$S = $dbh->prepare('insert into test73087 (id, content) values (:id, :content)');
|
||||
for ($I = 1; $I < 10; $I++) {
|
||||
@@ -29,6 +30,7 @@ echo 'OK';
|
||||
--CLEAN--
|
||||
<?php
|
||||
require 'testdb.inc';
|
||||
$dbh = getDbConnection();
|
||||
@$dbh->exec("DROP TABLE test73087");
|
||||
unset($dbh);
|
||||
?>
|
||||
|
||||
@@ -11,6 +11,7 @@ See https://github.com/FirebirdSQL/firebird/issues/7849
|
||||
<?php
|
||||
require 'testdb.inc';
|
||||
|
||||
$dbh = getDbConnection();
|
||||
$dbh->exec('recreate table test74462 (id integer not null, abool boolean)');
|
||||
$dbh->exec('insert into test74462 (id, abool) values (1, true)');
|
||||
$dbh->exec('insert into test74462 (id, abool) values (2, false)');
|
||||
@@ -24,6 +25,7 @@ var_dump($D);
|
||||
--CLEAN--
|
||||
<?php
|
||||
require 'testdb.inc';
|
||||
$dbh = getDbConnection();
|
||||
@$dbh->exec("DROP TABLE test74462");
|
||||
unset($dbh);
|
||||
?>
|
||||
|
||||
@@ -22,15 +22,17 @@ select n,
|
||||
from r
|
||||
';
|
||||
|
||||
for ($i = 0; $i < 10; $i++) {
|
||||
$sth = $dbh->prepare($sql);
|
||||
$sth->execute();
|
||||
$rows = $sth->fetchAll();
|
||||
unset($rows);
|
||||
unset($sth);
|
||||
}
|
||||
unset($dbh);
|
||||
echo "OK";
|
||||
$dbh = getDbConnection();
|
||||
|
||||
for ($i = 0; $i < 10; $i++) {
|
||||
$sth = $dbh->prepare($sql);
|
||||
$sth->execute();
|
||||
$rows = $sth->fetchAll();
|
||||
unset($rows);
|
||||
unset($sth);
|
||||
}
|
||||
unset($dbh);
|
||||
echo "OK";
|
||||
?>
|
||||
--EXPECT--
|
||||
OK
|
||||
|
||||
@@ -24,6 +24,7 @@ select trim(s) as s from t where b is not distinct from :p
|
||||
SQL;
|
||||
|
||||
try {
|
||||
$dbh = getDbConnection();
|
||||
$query = $dbh->prepare($sql);
|
||||
|
||||
// PDO::PARAM_BOOL
|
||||
|
||||
@@ -11,6 +11,7 @@ See https://github.com/FirebirdSQL/firebird/issues/7849
|
||||
<?php
|
||||
require 'testdb.inc';
|
||||
|
||||
$dbh = getDbConnection();
|
||||
$dbh->exec("CREATE TABLE bug80521 (foo INTEGER)");
|
||||
var_dump($dbh->prepare("SELECT foo FROM bug80521 WHERE foo = :foo_bar"));
|
||||
?>
|
||||
@@ -22,6 +23,7 @@ object(PDOStatement)#%d (1) {
|
||||
--CLEAN--
|
||||
<?php
|
||||
require 'testdb.inc';
|
||||
$dbh = getDbConnection();
|
||||
@$dbh->exec("DROP TABLE bug80521");
|
||||
unset($dbh);
|
||||
?>
|
||||
|
||||
@@ -11,6 +11,7 @@ See https://github.com/FirebirdSQL/firebird/issues/7849
|
||||
<?php
|
||||
require 'testdb.inc';
|
||||
|
||||
$dbh = getDbConnection();
|
||||
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
|
||||
$dbh->exec('create table test_aaa (id integer)');
|
||||
$S = $dbh->prepare('insert into test_aaa (id) values (:id) returning id');
|
||||
@@ -23,6 +24,7 @@ echo 'OK';
|
||||
--CLEAN--
|
||||
<?php
|
||||
require 'testdb.inc';
|
||||
$dbh = getDbConnection();
|
||||
@$dbh->exec("DROP TABLE test_aaa");
|
||||
unset($dbh);
|
||||
?>
|
||||
|
||||
@@ -11,6 +11,7 @@ See https://github.com/FirebirdSQL/firebird/issues/7849
|
||||
<?php
|
||||
require("testdb.inc");
|
||||
|
||||
$dbh = getDbConnection();
|
||||
unset($dbh);
|
||||
echo "done\n";
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ See https://github.com/FirebirdSQL/firebird/issues/7849
|
||||
|
||||
require("testdb.inc");
|
||||
|
||||
$dbh = getDbConnection();
|
||||
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
|
||||
@$dbh->exec('DROP TABLE test_ddl');
|
||||
@$dbh->exec('DROP GENERATOR gen_test_ddl_id');
|
||||
|
||||
@@ -11,6 +11,7 @@ See https://github.com/FirebirdSQL/firebird/issues/7849
|
||||
<?php
|
||||
require("testdb.inc");
|
||||
|
||||
$dbh = getDbConnection();
|
||||
$dbh->exec("CREATE TABLE test_ddl2 (val int)");
|
||||
|
||||
$dbh->beginTransaction();
|
||||
@@ -27,6 +28,7 @@ echo "done\n";
|
||||
--CLEAN--
|
||||
<?php
|
||||
require("testdb.inc");
|
||||
$dbh = getDbConnection();
|
||||
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
|
||||
@$dbh->exec('DROP TABLE test_ddl2');
|
||||
@$dbh->exec('DROP TABLE test_ddl2_2');
|
||||
|
||||
@@ -15,6 +15,7 @@ See https://github.com/FirebirdSQL/firebird/issues/7849
|
||||
<?php
|
||||
require("testdb.inc");
|
||||
|
||||
$dbh = getDbConnection();
|
||||
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
|
||||
$dbh->setAttribute(PDO::FB_ATTR_TIMESTAMP_FORMAT, '%Y-%m-%d %H:%M:%S');
|
||||
|
||||
@@ -56,6 +57,7 @@ echo "done\n";
|
||||
--CLEAN--
|
||||
<?php
|
||||
require 'testdb.inc';
|
||||
$dbh = getDbConnection();
|
||||
@$dbh->exec('DROP TABLE test_dialect_1');
|
||||
unset($dbh);
|
||||
--EXPECT--
|
||||
|
||||
@@ -11,6 +11,7 @@ See https://github.com/FirebirdSQL/firebird/issues/7849
|
||||
<?php
|
||||
|
||||
require("testdb.inc");
|
||||
$dbh = getDbConnection();
|
||||
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
|
||||
|
||||
$table = 'error_handle';
|
||||
@@ -30,12 +31,13 @@ unset($dbh);
|
||||
--CLEAN--
|
||||
<?php
|
||||
require 'testdb.inc';
|
||||
$dbh = getDbConnection();
|
||||
@$dbh->exec('DROP TABLE error_handle');
|
||||
unset($dbh);
|
||||
?>
|
||||
--EXPECTF--
|
||||
dbh error
|
||||
Warning: PDO::query(): SQLSTATE[22018]: Invalid character value for cast specification: -413 conversion error from string "str" in %s on line 10
|
||||
Warning: PDO::query(): SQLSTATE[22018]: Invalid character value for cast specification: -413 conversion error from string "str" in %s on line %d
|
||||
|
||||
stmt error
|
||||
Warning: PDOStatement::execute(): SQLSTATE[22018]: Invalid character value for cast specification: -413 conversion error from string "str" in %s on line 16
|
||||
Warning: PDOStatement::execute(): SQLSTATE[22018]: Invalid character value for cast specification: -413 conversion error from string "str" in %s on line %d
|
||||
|
||||
@@ -11,6 +11,7 @@ See https://github.com/FirebirdSQL/firebird/issues/7849
|
||||
<?php
|
||||
require("testdb.inc");
|
||||
|
||||
$dbh = getDbConnection();
|
||||
var_dump($dbh->getAttribute(PDO::ATTR_CONNECTION_STATUS));
|
||||
|
||||
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
|
||||
@@ -47,6 +48,7 @@ echo "done\n";
|
||||
--CLEAN--
|
||||
<?php
|
||||
require 'testdb.inc';
|
||||
$dbh = getDbConnection();
|
||||
@$dbh->exec('DROP TABLE test_execute');
|
||||
unset($dbh);
|
||||
--EXPECT--
|
||||
|
||||
@@ -10,9 +10,10 @@ A bug in firebird causes a memory leak when calling `isc_attach_database()`.
|
||||
See https://github.com/FirebirdSQL/firebird/issues/7849
|
||||
--FILE--
|
||||
<?php
|
||||
require("testdb.inc");
|
||||
require("testdb.inc");
|
||||
|
||||
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
|
||||
$dbh = getDbConnection();
|
||||
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
|
||||
|
||||
$sql = '
|
||||
execute block (a int = :e, b int = :d)
|
||||
@@ -29,16 +30,16 @@ begin
|
||||
suspend;
|
||||
end
|
||||
';
|
||||
$query = $dbh->prepare($sql);
|
||||
$query->execute(['d' => 1, 'e' => 2]);
|
||||
$row = $query->fetch(\PDO::FETCH_OBJ);
|
||||
var_dump($row->N);
|
||||
var_dump($row->M);
|
||||
|
||||
unset($query);
|
||||
unset($dbh);
|
||||
echo "done\n";
|
||||
$query = $dbh->prepare($sql);
|
||||
$query->execute(['d' => 1, 'e' => 2]);
|
||||
$row = $query->fetch(\PDO::FETCH_OBJ);
|
||||
var_dump($row->N);
|
||||
var_dump($row->M);
|
||||
|
||||
unset($query);
|
||||
unset($dbh);
|
||||
echo "done\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
int(13)
|
||||
|
||||
@@ -29,6 +29,7 @@ CREATE TABLE gh10908(
|
||||
MYBOOL BOOLEAN
|
||||
);
|
||||
EOT;
|
||||
$dbh = getDbConnection();
|
||||
$dbh->exec($sql);
|
||||
$dbh->exec("INSERT INTO gh10908 VALUES(1, 'ABC', 12.34, 1.0, 2.0, '2023-03-24 17:39', '2023-03-24', '17:39', 'abcdefg', 32767, 200000, 'azertyuiop', false);");
|
||||
|
||||
@@ -57,6 +58,7 @@ echo "Did not crash\n";
|
||||
--CLEAN--
|
||||
<?php
|
||||
require 'testdb.inc';
|
||||
$dbh = getDbConnection();
|
||||
@$dbh->exec("DROP TABLE gh10908");
|
||||
unset($dbh);
|
||||
?>
|
||||
|
||||
@@ -11,6 +11,7 @@ See https://github.com/FirebirdSQL/firebird/issues/7849
|
||||
<?php
|
||||
require 'testdb.inc';
|
||||
|
||||
$dbh = getDbConnection();
|
||||
$dbh->exec("CREATE TABLE gh8576 (name CHAR(1) CHARACTER SET UTF8)");
|
||||
$dbh->exec("INSERT INTO gh8576 VALUES ('A')");
|
||||
$stmt = $dbh->query("SELECT * FROM gh8576");
|
||||
@@ -29,6 +30,7 @@ array(1) {
|
||||
--CLEAN--
|
||||
<?php
|
||||
require 'testdb.inc';
|
||||
$dbh = getDbConnection();
|
||||
@$dbh->exec("DROP TABLE gh8576");
|
||||
unset($dbh);
|
||||
?>
|
||||
|
||||
@@ -10,11 +10,12 @@ A bug in firebird causes a memory leak when calling `isc_attach_database()`.
|
||||
See https://github.com/FirebirdSQL/firebird/issues/7849
|
||||
--FILE--
|
||||
<?php
|
||||
require("testdb.inc");
|
||||
require("testdb.inc");
|
||||
|
||||
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
|
||||
$dbh = getDbConnection();
|
||||
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
|
||||
|
||||
$sql = '
|
||||
$sql = '
|
||||
select 1 as n
|
||||
-- :f
|
||||
from rdb$database
|
||||
@@ -31,15 +32,14 @@ select 1 as n
|
||||
from rdb$database
|
||||
where 1=:d /* and :f = 5 */ and 2=:e
|
||||
';
|
||||
$query = $dbh->prepare($sql);
|
||||
$query->execute(['d' => 1, 'e' => 2]);
|
||||
$row = $query->fetch(\PDO::FETCH_OBJ);
|
||||
var_dump($row->N);
|
||||
unset($query);
|
||||
|
||||
unset($dbh);
|
||||
echo "done\n";
|
||||
$query = $dbh->prepare($sql);
|
||||
$query->execute(['d' => 1, 'e' => 2]);
|
||||
$row = $query->fetch(\PDO::FETCH_OBJ);
|
||||
var_dump($row->N);
|
||||
unset($query);
|
||||
|
||||
unset($dbh);
|
||||
echo "done\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
int(1)
|
||||
|
||||
44
ext/pdo_firebird/tests/pdofirebird_001.phpt
Normal file
44
ext/pdo_firebird/tests/pdofirebird_001.phpt
Normal file
@@ -0,0 +1,44 @@
|
||||
--TEST--
|
||||
PDO_firebird subclass basic
|
||||
--EXTENSIONS--
|
||||
pdo_firebird
|
||||
--SKIPIF--
|
||||
<?php require(__DIR__ . '/skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . "/testdb.inc";
|
||||
|
||||
$db = getDbConnection();
|
||||
|
||||
$db->query('CREATE TABLE pdofirebird_001 (idx INT NOT NULL PRIMARY KEY, name VARCHAR(20))');
|
||||
$db->query("INSERT INTO pdofirebird_001 VALUES (1, 'PHP')");
|
||||
$db->query("INSERT INTO pdofirebird_001 VALUES (2, 'PHP6')");
|
||||
|
||||
foreach ($db->query('SELECT name FROM pdofirebird_001') as $row) {
|
||||
var_dump($row);
|
||||
}
|
||||
|
||||
echo "Fin.";
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once __DIR__ . '/testdb.inc';
|
||||
$dbh = getDbConnection();
|
||||
@$dbh->exec("DROP TABLE pdofirebird_001");
|
||||
unset($dbh);
|
||||
?>
|
||||
--EXPECT--
|
||||
array(2) {
|
||||
["NAME"]=>
|
||||
string(3) "PHP"
|
||||
[0]=>
|
||||
string(3) "PHP"
|
||||
}
|
||||
array(2) {
|
||||
["NAME"]=>
|
||||
string(4) "PHP6"
|
||||
[0]=>
|
||||
string(4) "PHP6"
|
||||
}
|
||||
Fin.
|
||||
55
ext/pdo_firebird/tests/pdofirebird_002.phpt
Normal file
55
ext/pdo_firebird/tests/pdofirebird_002.phpt
Normal file
@@ -0,0 +1,55 @@
|
||||
--TEST--
|
||||
PDO_firebird connect through PDO::connect
|
||||
--EXTENSIONS--
|
||||
pdo_firebird
|
||||
--SKIPIF--
|
||||
<?php require(__DIR__ . '/skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . "/testdb.inc";
|
||||
|
||||
$db = connectToDb();
|
||||
if (!$db instanceof PdoFirebird) {
|
||||
echo "Wrong class type. Should be PdoFirebird but is " . get_class($db) . "\n";
|
||||
}
|
||||
|
||||
$db->query('CREATE TABLE pdofirebird_002 (idx INT NOT NULL PRIMARY KEY, name VARCHAR(20))');
|
||||
|
||||
$db->exec("INSERT INTO pdofirebird_002 VALUES(1, 'A')");
|
||||
$db->exec("INSERT INTO pdofirebird_002 VALUES(2, 'B')");
|
||||
$db->exec("INSERT INTO pdofirebird_002 VALUES(3, 'C')");
|
||||
|
||||
foreach ($db->query('SELECT name FROM pdofirebird_002') as $row) {
|
||||
var_dump($row);
|
||||
}
|
||||
|
||||
echo "Fin.";
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once __DIR__ . "/testdb.inc";
|
||||
$dbh = getDbConnection();
|
||||
@$dbh->exec("DROP TABLE pdofirebird_002");
|
||||
unset($dbh);
|
||||
?>
|
||||
--EXPECT--
|
||||
array(2) {
|
||||
["NAME"]=>
|
||||
string(1) "A"
|
||||
[0]=>
|
||||
string(1) "A"
|
||||
}
|
||||
array(2) {
|
||||
["NAME"]=>
|
||||
string(1) "B"
|
||||
[0]=>
|
||||
string(1) "B"
|
||||
}
|
||||
array(2) {
|
||||
["NAME"]=>
|
||||
string(1) "C"
|
||||
[0]=>
|
||||
string(1) "C"
|
||||
}
|
||||
Fin.
|
||||
@@ -12,6 +12,7 @@ See https://github.com/FirebirdSQL/firebird/issues/7849
|
||||
|
||||
require("testdb.inc");
|
||||
|
||||
$dbh = getDbConnection();
|
||||
$dbh->exec('CREATE TABLE test_rowcount (A VARCHAR(10))');
|
||||
$dbh->exec("INSERT INTO test_rowcount VALUES ('A')");
|
||||
$dbh->exec("INSERT INTO test_rowcount VALUES ('A')");
|
||||
@@ -41,6 +42,7 @@ unset($dbh);
|
||||
--CLEAN--
|
||||
<?php
|
||||
require 'testdb.inc';
|
||||
$dbh = getDbConnection();
|
||||
@$dbh->exec('DROP TABLE test_rowcount');
|
||||
unset($dbh);
|
||||
--EXPECT--
|
||||
|
||||
@@ -17,5 +17,12 @@ if(!PDO_FIREBIRD_TEST_DSN)
|
||||
die('Error: PDO_FIREBIRD_TEST_DSN must be set');
|
||||
}
|
||||
|
||||
$dbh = new PDO(PDO_FIREBIRD_TEST_DSN, PDO_FIREBIRD_TEST_USER, PDO_FIREBIRD_TEST_PASS) or die;
|
||||
function getDbConnection($class = PDO::class): PDO {
|
||||
return new $class(PDO_FIREBIRD_TEST_DSN, PDO_FIREBIRD_TEST_USER, PDO_FIREBIRD_TEST_PASS);
|
||||
}
|
||||
|
||||
function connectToDb(): PdoFirebird {
|
||||
return PdoFirebird::connect(PDO_FIREBIRD_TEST_DSN, PDO_FIREBIRD_TEST_USER, PDO_FIREBIRD_TEST_PASS);
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -11,6 +11,7 @@ See https://github.com/FirebirdSQL/firebird/issues/7849
|
||||
<?php
|
||||
|
||||
require("testdb.inc");
|
||||
$dbh = getDbConnection();
|
||||
unset($dbh);
|
||||
|
||||
$table = 'transaction_access_mode';
|
||||
@@ -130,6 +131,7 @@ unset($dbh);
|
||||
--CLEAN--
|
||||
<?php
|
||||
require 'testdb.inc';
|
||||
$dbh = getDbConnection();
|
||||
@$dbh->exec('DROP TABLE transaction_access_mode');
|
||||
unset($dbh);
|
||||
?>
|
||||
|
||||
@@ -11,6 +11,7 @@ See https://github.com/FirebirdSQL/firebird/issues/7849
|
||||
<?php
|
||||
|
||||
require("testdb.inc");
|
||||
$dbh = getDbConnection();
|
||||
unset($dbh);
|
||||
|
||||
$levelStrs = [
|
||||
|
||||
@@ -11,6 +11,7 @@ See https://github.com/FirebirdSQL/firebird/issues/7849
|
||||
<?php
|
||||
|
||||
require("testdb.inc");
|
||||
$dbh = getDbConnection();
|
||||
unset($dbh);
|
||||
|
||||
$table = 'txn_isolation_level_behavior';
|
||||
@@ -127,6 +128,7 @@ echo "done!";
|
||||
--CLEAN--
|
||||
<?php
|
||||
require 'testdb.inc';
|
||||
$dbh = getDbConnection();
|
||||
@$dbh->exec('DROP TABLE txn_isolation_level_behavior');
|
||||
unset($dbh);
|
||||
?>
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
#include "pdo/php_pdo_driver.h"
|
||||
#include "php_pdo_mysql.h"
|
||||
#include "php_pdo_mysql_int.h"
|
||||
#include "pdo_mysql_arginfo.h"
|
||||
|
||||
static zend_class_entry *pdo_mysql_ce;
|
||||
|
||||
#ifdef COMPILE_DL_PDO_MYSQL
|
||||
#ifdef ZTS
|
||||
@@ -81,6 +84,22 @@ static const MYSQLND_REVERSE_API pdo_mysql_reverse_api = {
|
||||
};
|
||||
#endif
|
||||
|
||||
/* proto string PDO::mysqlGetWarningCount()
|
||||
* Returns the number of SQL warnings during the execution of the last statement
|
||||
*/
|
||||
PHP_METHOD(PdoMysql, getWarningCount)
|
||||
{
|
||||
pdo_dbh_t *dbh;
|
||||
pdo_mysql_db_handle *H;
|
||||
|
||||
ZEND_PARSE_PARAMETERS_NONE();
|
||||
|
||||
dbh = Z_PDO_DBH_P(ZEND_THIS);
|
||||
PDO_CONSTRUCT_CHECK;
|
||||
|
||||
H = (pdo_mysql_db_handle *)dbh->driver_data;
|
||||
RETURN_LONG(mysql_warning_count(H->server));
|
||||
}
|
||||
|
||||
/* {{{ PHP_INI_BEGIN */
|
||||
PHP_INI_BEGIN()
|
||||
@@ -118,7 +137,7 @@ static PHP_MINIT_FUNCTION(pdo_mysql)
|
||||
REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_SSL_CAPATH", (zend_long)PDO_MYSQL_ATTR_SSL_CAPATH);
|
||||
REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_SSL_CIPHER", (zend_long)PDO_MYSQL_ATTR_SSL_CIPHER);
|
||||
#if MYSQL_VERSION_ID > 50605 || defined(PDO_USE_MYSQLND)
|
||||
REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_SERVER_PUBLIC_KEY", (zend_long)PDO_MYSQL_ATTR_SERVER_PUBLIC_KEY);
|
||||
REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_SERVER_PUBLIC_KEY", (zend_long)PDO_MYSQL_ATTR_SERVER_PUBLIC_KEY);
|
||||
#endif
|
||||
REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_MULTI_STATEMENTS", (zend_long)PDO_MYSQL_ATTR_MULTI_STATEMENTS);
|
||||
#ifdef PDO_USE_MYSQLND
|
||||
@@ -132,7 +151,14 @@ static PHP_MINIT_FUNCTION(pdo_mysql)
|
||||
mysqlnd_reverse_api_register_api(&pdo_mysql_reverse_api);
|
||||
#endif
|
||||
|
||||
return php_pdo_register_driver(&pdo_mysql_driver);
|
||||
pdo_mysql_ce = register_class_PdoMysql(pdo_dbh_ce);
|
||||
pdo_mysql_ce->create_object = pdo_dbh_new;
|
||||
|
||||
if (php_pdo_register_driver(&pdo_mysql_driver) == FAILURE) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return php_pdo_register_driver_specific_ce(&pdo_mysql_driver, pdo_mysql_ce);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
75
ext/pdo_mysql/pdo_mysql.stub.php
Normal file
75
ext/pdo_mysql/pdo_mysql.stub.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
/** @generate-class-entries */
|
||||
|
||||
/**
|
||||
* @strict-properties
|
||||
* @not-serializable
|
||||
*/
|
||||
class PdoMysql extends PDO
|
||||
{
|
||||
/** @cvalue PDO_MYSQL_ATTR_USE_BUFFERED_QUERY */
|
||||
public const int ATTR_USE_BUFFERED_QUERY = UNKNOWN;
|
||||
|
||||
/** @cvalue PDO_MYSQL_ATTR_LOCAL_INFILE */
|
||||
public const int ATTR_LOCAL_INFILE = UNKNOWN;
|
||||
|
||||
/** @cvalue PDO_MYSQL_ATTR_INIT_COMMAND */
|
||||
public const int ATTR_INIT_COMMAND = UNKNOWN;
|
||||
|
||||
#ifndef PDO_USE_MYSQLND
|
||||
/** @cvalue PDO_MYSQL_ATTR_MAX_BUFFER_SIZE */
|
||||
public const int ATTR_MAX_BUFFER_SIZE = UNKNOWN;
|
||||
|
||||
/** @cvalue PDO_MYSQL_ATTR_READ_DEFAULT_FILE */
|
||||
public const int ATTR_READ_DEFAULT_FILE = UNKNOWN;
|
||||
|
||||
/** @cvalue PDO_MYSQL_ATTR_READ_DEFAULT_GROUP */
|
||||
public const int ATTR_READ_DEFAULT_GROUP = UNKNOWN;
|
||||
#endif
|
||||
|
||||
/** @cvalue PDO_MYSQL_ATTR_COMPRESS */
|
||||
public const int ATTR_COMPRESS = UNKNOWN;
|
||||
|
||||
/** @cvalue PDO_MYSQL_ATTR_DIRECT_QUERY */
|
||||
public const int ATTR_DIRECT_QUERY = UNKNOWN;
|
||||
|
||||
/** @cvalue PDO_MYSQL_ATTR_FOUND_ROWS */
|
||||
public const int ATTR_FOUND_ROWS = UNKNOWN;
|
||||
|
||||
/** @cvalue PDO_MYSQL_ATTR_IGNORE_SPACE */
|
||||
public const int ATTR_IGNORE_SPACE = UNKNOWN;
|
||||
|
||||
/** @cvalue PDO_MYSQL_ATTR_SSL_KEY */
|
||||
public const int ATTR_SSL_KEY = UNKNOWN;
|
||||
|
||||
/** @cvalue PDO_MYSQL_ATTR_SSL_CERT */
|
||||
public const int ATTR_SSL_CERT = UNKNOWN;
|
||||
|
||||
/** @cvalue PDO_MYSQL_ATTR_SSL_CA */
|
||||
public const int ATTR_SSL_CA = UNKNOWN;
|
||||
|
||||
/** @cvalue PDO_MYSQL_ATTR_SSL_CAPATH */
|
||||
public const int ATTR_SSL_CAPATH = UNKNOWN;
|
||||
|
||||
/** @cvalue PDO_MYSQL_ATTR_SSL_CIPHER */
|
||||
public const int ATTR_SSL_CIPHER = UNKNOWN;
|
||||
|
||||
#if MYSQL_VERSION_ID > 50605 || defined(PDO_USE_MYSQLND)
|
||||
/** @cvalue PDO_MYSQL_ATTR_SERVER_PUBLIC_KEY */
|
||||
public const int ATTR_SERVER_PUBLIC_KEY = UNKNOWN;
|
||||
#endif
|
||||
|
||||
/** @cvalue PDO_MYSQL_ATTR_MULTI_STATEMENTS */
|
||||
public const int ATTR_MULTI_STATEMENTS = UNKNOWN;
|
||||
|
||||
/** @cvalue PDO_MYSQL_ATTR_SSL_VERIFY_SERVER_CERT */
|
||||
public const int ATTR_SSL_VERIFY_SERVER_CERT = UNKNOWN;
|
||||
|
||||
#if MYSQL_VERSION_ID >= 80021 || defined(PDO_USE_MYSQLND)
|
||||
/** @cvalue PDO_MYSQL_ATTR_LOCAL_INFILE_DIRECTORY */
|
||||
public const int ATTR_LOCAL_INFILE_DIRECTORY = UNKNOWN;
|
||||
#endif
|
||||
|
||||
public function getWarningCount(): int {}
|
||||
}
|
||||
149
ext/pdo_mysql/pdo_mysql_arginfo.h
generated
Normal file
149
ext/pdo_mysql/pdo_mysql_arginfo.h
generated
Normal file
@@ -0,0 +1,149 @@
|
||||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: 3e797a44fc026ab43bf4bec26cf6fe492116cb25 */
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_PdoMysql_getWarningCount, 0, 0, IS_LONG, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
|
||||
ZEND_METHOD(PdoMysql, getWarningCount);
|
||||
|
||||
|
||||
static const zend_function_entry class_PdoMysql_methods[] = {
|
||||
ZEND_ME(PdoMysql, getWarningCount, arginfo_class_PdoMysql_getWarningCount, ZEND_ACC_PUBLIC)
|
||||
ZEND_FE_END
|
||||
};
|
||||
|
||||
static zend_class_entry *register_class_PdoMysql(zend_class_entry *class_entry_PDO)
|
||||
{
|
||||
zend_class_entry ce, *class_entry;
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "PdoMysql", class_PdoMysql_methods);
|
||||
class_entry = zend_register_internal_class_ex(&ce, class_entry_PDO);
|
||||
class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE;
|
||||
|
||||
zval const_ATTR_USE_BUFFERED_QUERY_value;
|
||||
ZVAL_LONG(&const_ATTR_USE_BUFFERED_QUERY_value, PDO_MYSQL_ATTR_USE_BUFFERED_QUERY);
|
||||
zend_string *const_ATTR_USE_BUFFERED_QUERY_name = zend_string_init_interned("ATTR_USE_BUFFERED_QUERY", sizeof("ATTR_USE_BUFFERED_QUERY") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_USE_BUFFERED_QUERY_name, &const_ATTR_USE_BUFFERED_QUERY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_USE_BUFFERED_QUERY_name);
|
||||
|
||||
zval const_ATTR_LOCAL_INFILE_value;
|
||||
ZVAL_LONG(&const_ATTR_LOCAL_INFILE_value, PDO_MYSQL_ATTR_LOCAL_INFILE);
|
||||
zend_string *const_ATTR_LOCAL_INFILE_name = zend_string_init_interned("ATTR_LOCAL_INFILE", sizeof("ATTR_LOCAL_INFILE") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_LOCAL_INFILE_name, &const_ATTR_LOCAL_INFILE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_LOCAL_INFILE_name);
|
||||
|
||||
zval const_ATTR_INIT_COMMAND_value;
|
||||
ZVAL_LONG(&const_ATTR_INIT_COMMAND_value, PDO_MYSQL_ATTR_INIT_COMMAND);
|
||||
zend_string *const_ATTR_INIT_COMMAND_name = zend_string_init_interned("ATTR_INIT_COMMAND", sizeof("ATTR_INIT_COMMAND") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_INIT_COMMAND_name, &const_ATTR_INIT_COMMAND_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_INIT_COMMAND_name);
|
||||
#if !defined(PDO_USE_MYSQLND)
|
||||
|
||||
zval const_ATTR_MAX_BUFFER_SIZE_value;
|
||||
ZVAL_LONG(&const_ATTR_MAX_BUFFER_SIZE_value, PDO_MYSQL_ATTR_MAX_BUFFER_SIZE);
|
||||
zend_string *const_ATTR_MAX_BUFFER_SIZE_name = zend_string_init_interned("ATTR_MAX_BUFFER_SIZE", sizeof("ATTR_MAX_BUFFER_SIZE") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_MAX_BUFFER_SIZE_name, &const_ATTR_MAX_BUFFER_SIZE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_MAX_BUFFER_SIZE_name);
|
||||
#endif
|
||||
#if !defined(PDO_USE_MYSQLND)
|
||||
|
||||
zval const_ATTR_READ_DEFAULT_FILE_value;
|
||||
ZVAL_LONG(&const_ATTR_READ_DEFAULT_FILE_value, PDO_MYSQL_ATTR_READ_DEFAULT_FILE);
|
||||
zend_string *const_ATTR_READ_DEFAULT_FILE_name = zend_string_init_interned("ATTR_READ_DEFAULT_FILE", sizeof("ATTR_READ_DEFAULT_FILE") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_READ_DEFAULT_FILE_name, &const_ATTR_READ_DEFAULT_FILE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_READ_DEFAULT_FILE_name);
|
||||
#endif
|
||||
#if !defined(PDO_USE_MYSQLND)
|
||||
|
||||
zval const_ATTR_READ_DEFAULT_GROUP_value;
|
||||
ZVAL_LONG(&const_ATTR_READ_DEFAULT_GROUP_value, PDO_MYSQL_ATTR_READ_DEFAULT_GROUP);
|
||||
zend_string *const_ATTR_READ_DEFAULT_GROUP_name = zend_string_init_interned("ATTR_READ_DEFAULT_GROUP", sizeof("ATTR_READ_DEFAULT_GROUP") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_READ_DEFAULT_GROUP_name, &const_ATTR_READ_DEFAULT_GROUP_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_READ_DEFAULT_GROUP_name);
|
||||
#endif
|
||||
|
||||
zval const_ATTR_COMPRESS_value;
|
||||
ZVAL_LONG(&const_ATTR_COMPRESS_value, PDO_MYSQL_ATTR_COMPRESS);
|
||||
zend_string *const_ATTR_COMPRESS_name = zend_string_init_interned("ATTR_COMPRESS", sizeof("ATTR_COMPRESS") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_COMPRESS_name, &const_ATTR_COMPRESS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_COMPRESS_name);
|
||||
|
||||
zval const_ATTR_DIRECT_QUERY_value;
|
||||
ZVAL_LONG(&const_ATTR_DIRECT_QUERY_value, PDO_MYSQL_ATTR_DIRECT_QUERY);
|
||||
zend_string *const_ATTR_DIRECT_QUERY_name = zend_string_init_interned("ATTR_DIRECT_QUERY", sizeof("ATTR_DIRECT_QUERY") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_DIRECT_QUERY_name, &const_ATTR_DIRECT_QUERY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_DIRECT_QUERY_name);
|
||||
|
||||
zval const_ATTR_FOUND_ROWS_value;
|
||||
ZVAL_LONG(&const_ATTR_FOUND_ROWS_value, PDO_MYSQL_ATTR_FOUND_ROWS);
|
||||
zend_string *const_ATTR_FOUND_ROWS_name = zend_string_init_interned("ATTR_FOUND_ROWS", sizeof("ATTR_FOUND_ROWS") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_FOUND_ROWS_name, &const_ATTR_FOUND_ROWS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_FOUND_ROWS_name);
|
||||
|
||||
zval const_ATTR_IGNORE_SPACE_value;
|
||||
ZVAL_LONG(&const_ATTR_IGNORE_SPACE_value, PDO_MYSQL_ATTR_IGNORE_SPACE);
|
||||
zend_string *const_ATTR_IGNORE_SPACE_name = zend_string_init_interned("ATTR_IGNORE_SPACE", sizeof("ATTR_IGNORE_SPACE") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_IGNORE_SPACE_name, &const_ATTR_IGNORE_SPACE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_IGNORE_SPACE_name);
|
||||
|
||||
zval const_ATTR_SSL_KEY_value;
|
||||
ZVAL_LONG(&const_ATTR_SSL_KEY_value, PDO_MYSQL_ATTR_SSL_KEY);
|
||||
zend_string *const_ATTR_SSL_KEY_name = zend_string_init_interned("ATTR_SSL_KEY", sizeof("ATTR_SSL_KEY") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_SSL_KEY_name, &const_ATTR_SSL_KEY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_SSL_KEY_name);
|
||||
|
||||
zval const_ATTR_SSL_CERT_value;
|
||||
ZVAL_LONG(&const_ATTR_SSL_CERT_value, PDO_MYSQL_ATTR_SSL_CERT);
|
||||
zend_string *const_ATTR_SSL_CERT_name = zend_string_init_interned("ATTR_SSL_CERT", sizeof("ATTR_SSL_CERT") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_SSL_CERT_name, &const_ATTR_SSL_CERT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_SSL_CERT_name);
|
||||
|
||||
zval const_ATTR_SSL_CA_value;
|
||||
ZVAL_LONG(&const_ATTR_SSL_CA_value, PDO_MYSQL_ATTR_SSL_CA);
|
||||
zend_string *const_ATTR_SSL_CA_name = zend_string_init_interned("ATTR_SSL_CA", sizeof("ATTR_SSL_CA") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_SSL_CA_name, &const_ATTR_SSL_CA_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_SSL_CA_name);
|
||||
|
||||
zval const_ATTR_SSL_CAPATH_value;
|
||||
ZVAL_LONG(&const_ATTR_SSL_CAPATH_value, PDO_MYSQL_ATTR_SSL_CAPATH);
|
||||
zend_string *const_ATTR_SSL_CAPATH_name = zend_string_init_interned("ATTR_SSL_CAPATH", sizeof("ATTR_SSL_CAPATH") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_SSL_CAPATH_name, &const_ATTR_SSL_CAPATH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_SSL_CAPATH_name);
|
||||
|
||||
zval const_ATTR_SSL_CIPHER_value;
|
||||
ZVAL_LONG(&const_ATTR_SSL_CIPHER_value, PDO_MYSQL_ATTR_SSL_CIPHER);
|
||||
zend_string *const_ATTR_SSL_CIPHER_name = zend_string_init_interned("ATTR_SSL_CIPHER", sizeof("ATTR_SSL_CIPHER") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_SSL_CIPHER_name, &const_ATTR_SSL_CIPHER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_SSL_CIPHER_name);
|
||||
#if MYSQL_VERSION_ID > 50605 || defined(PDO_USE_MYSQLND)
|
||||
|
||||
zval const_ATTR_SERVER_PUBLIC_KEY_value;
|
||||
ZVAL_LONG(&const_ATTR_SERVER_PUBLIC_KEY_value, PDO_MYSQL_ATTR_SERVER_PUBLIC_KEY);
|
||||
zend_string *const_ATTR_SERVER_PUBLIC_KEY_name = zend_string_init_interned("ATTR_SERVER_PUBLIC_KEY", sizeof("ATTR_SERVER_PUBLIC_KEY") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_SERVER_PUBLIC_KEY_name, &const_ATTR_SERVER_PUBLIC_KEY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_SERVER_PUBLIC_KEY_name);
|
||||
#endif
|
||||
|
||||
zval const_ATTR_MULTI_STATEMENTS_value;
|
||||
ZVAL_LONG(&const_ATTR_MULTI_STATEMENTS_value, PDO_MYSQL_ATTR_MULTI_STATEMENTS);
|
||||
zend_string *const_ATTR_MULTI_STATEMENTS_name = zend_string_init_interned("ATTR_MULTI_STATEMENTS", sizeof("ATTR_MULTI_STATEMENTS") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_MULTI_STATEMENTS_name, &const_ATTR_MULTI_STATEMENTS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_MULTI_STATEMENTS_name);
|
||||
|
||||
zval const_ATTR_SSL_VERIFY_SERVER_CERT_value;
|
||||
ZVAL_LONG(&const_ATTR_SSL_VERIFY_SERVER_CERT_value, PDO_MYSQL_ATTR_SSL_VERIFY_SERVER_CERT);
|
||||
zend_string *const_ATTR_SSL_VERIFY_SERVER_CERT_name = zend_string_init_interned("ATTR_SSL_VERIFY_SERVER_CERT", sizeof("ATTR_SSL_VERIFY_SERVER_CERT") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_SSL_VERIFY_SERVER_CERT_name, &const_ATTR_SSL_VERIFY_SERVER_CERT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_SSL_VERIFY_SERVER_CERT_name);
|
||||
#if MYSQL_VERSION_ID >= 80021 || defined(PDO_USE_MYSQLND)
|
||||
|
||||
zval const_ATTR_LOCAL_INFILE_DIRECTORY_value;
|
||||
ZVAL_LONG(&const_ATTR_LOCAL_INFILE_DIRECTORY_value, PDO_MYSQL_ATTR_LOCAL_INFILE_DIRECTORY);
|
||||
zend_string *const_ATTR_LOCAL_INFILE_DIRECTORY_name = zend_string_init_interned("ATTR_LOCAL_INFILE_DIRECTORY", sizeof("ATTR_LOCAL_INFILE_DIRECTORY") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_LOCAL_INFILE_DIRECTORY_name, &const_ATTR_LOCAL_INFILE_DIRECTORY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_LOCAL_INFILE_DIRECTORY_name);
|
||||
#endif
|
||||
|
||||
return class_entry;
|
||||
}
|
||||
@@ -8,7 +8,7 @@ foreach ($env as $k => $v) {
|
||||
|
||||
class MySQLPDOTest extends PDOTest {
|
||||
|
||||
static function factory($classname = 'PDO', $mydsn = null, $myAttr = null) {
|
||||
static function factory($classname = PDO::class, $mydsn = null, $myAttr = null) {
|
||||
$dsn = self::getDSN($mydsn);
|
||||
$user = PDO_MYSQL_TEST_USER;
|
||||
$pass = PDO_MYSQL_TEST_PASS;
|
||||
|
||||
@@ -14,6 +14,7 @@ MySQLPDOTest::skipNotTransactionalEngine();
|
||||
|
||||
$expected = [
|
||||
'__construct' => true,
|
||||
'connect' => true,
|
||||
'prepare' => true,
|
||||
'beginTransaction' => true,
|
||||
'commit' => true,
|
||||
|
||||
47
ext/pdo_mysql/tests/pdomysql_001.phpt
Normal file
47
ext/pdo_mysql/tests/pdomysql_001.phpt
Normal file
@@ -0,0 +1,47 @@
|
||||
--TEST--
|
||||
PDO_mysql subclass basic
|
||||
--EXTENSIONS--
|
||||
pdo_mysql
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once __DIR__ . '/inc/mysql_pdo_test.inc';
|
||||
MySQLPDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/inc/mysql_pdo_test.inc';
|
||||
|
||||
$db = MySQLPDOTest::factory(PdoMysql::class);
|
||||
|
||||
$db->query('CREATE TABLE pdomysql_001 (id INT, name TEXT)');
|
||||
|
||||
$db->query('INSERT INTO pdomysql_001 VALUES (NULL, "PHP")');
|
||||
$db->query('INSERT INTO pdomysql_001 VALUES (NULL, "PHP6")');
|
||||
|
||||
foreach ($db->query('SELECT name FROM pdomysql_001') as $row) {
|
||||
var_dump($row);
|
||||
}
|
||||
|
||||
echo "Fin.";
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once __DIR__ . '/inc/mysql_pdo_test.inc';
|
||||
$db = MySQLPDOTest::factory();
|
||||
$db->exec('DROP TABLE IF EXISTS pdomysql_001');
|
||||
?>
|
||||
--EXPECT--
|
||||
array(2) {
|
||||
["name"]=>
|
||||
string(3) "PHP"
|
||||
[0]=>
|
||||
string(3) "PHP"
|
||||
}
|
||||
array(2) {
|
||||
["name"]=>
|
||||
string(4) "PHP6"
|
||||
[0]=>
|
||||
string(4) "PHP6"
|
||||
}
|
||||
Fin.
|
||||
54
ext/pdo_mysql/tests/pdomysql_002.phpt
Normal file
54
ext/pdo_mysql/tests/pdomysql_002.phpt
Normal file
@@ -0,0 +1,54 @@
|
||||
--TEST--
|
||||
PDO_mysql connect through PDO::connect
|
||||
--EXTENSIONS--
|
||||
pdo_mysql
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once __DIR__ . '/inc/mysql_pdo_test.inc';
|
||||
MySQLPDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/inc/mysql_pdo_test.inc';
|
||||
|
||||
$db = Pdo::connect(PDO_MYSQL_TEST_DSN, PDO_MYSQL_TEST_USER, PDO_MYSQL_TEST_PASS);
|
||||
if (!$db instanceof PdoMysql) {
|
||||
echo "Wrong class type. Should be PdoMysql but is " . get_class($db) . "\n";
|
||||
}
|
||||
|
||||
$db->exec('CREATE TABLE pdomysql_002(id INT NOT NULL PRIMARY KEY, name VARCHAR(10))');
|
||||
$db->exec("INSERT INTO pdomysql_002 VALUES(1, 'A'), (2, 'B'), (3, 'C')");
|
||||
|
||||
foreach ($db->query('SELECT name FROM pdomysql_002') as $row) {
|
||||
var_dump($row);
|
||||
}
|
||||
|
||||
echo "Fin.";
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once __DIR__ . '/inc/mysql_pdo_test.inc';
|
||||
$db = MySQLPDOTest::factory();
|
||||
$db->query('DROP TABLE pdomysql_002');
|
||||
?>
|
||||
--EXPECT--
|
||||
array(2) {
|
||||
["name"]=>
|
||||
string(1) "A"
|
||||
[0]=>
|
||||
string(1) "A"
|
||||
}
|
||||
array(2) {
|
||||
["name"]=>
|
||||
string(1) "B"
|
||||
[0]=>
|
||||
string(1) "B"
|
||||
}
|
||||
array(2) {
|
||||
["name"]=>
|
||||
string(1) "C"
|
||||
[0]=>
|
||||
string(1) "C"
|
||||
}
|
||||
Fin.
|
||||
29
ext/pdo_mysql/tests/pdomysql_003.phpt
Normal file
29
ext/pdo_mysql/tests/pdomysql_003.phpt
Normal file
@@ -0,0 +1,29 @@
|
||||
--TEST--
|
||||
PDO_mysql getWarningCount
|
||||
--EXTENSIONS--
|
||||
pdo_mysql
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once __DIR__ . '/inc/mysql_pdo_test.inc';
|
||||
MySQLPDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/inc/mysql_pdo_test.inc';
|
||||
|
||||
$db = Pdo::connect(PDO_MYSQL_TEST_DSN, PDO_MYSQL_TEST_USER, PDO_MYSQL_TEST_PASS);
|
||||
if (!$db instanceof PdoMysql) {
|
||||
echo "Wrong class type. Should be PdoMysql but is " . get_class($db) . "\n";
|
||||
}
|
||||
|
||||
$assertWarnings = function ($db, $q, $count) {
|
||||
$db->query($q);
|
||||
printf("Query %s produced %d warnings\n", $q, $db->getWarningCount());
|
||||
};
|
||||
$assertWarnings($db, 'SELECT 1 = 1', 0);
|
||||
$assertWarnings($db, 'SELECT 1 = "A"', 1);
|
||||
|
||||
--EXPECT--
|
||||
Query SELECT 1 = 1 produced 0 warnings
|
||||
Query SELECT 1 = "A" produced 1 warnings
|
||||
@@ -27,6 +27,8 @@
|
||||
#include "php_pdo_odbc_int.h"
|
||||
#include "pdo_odbc_arginfo.h"
|
||||
|
||||
static zend_class_entry *pdo_odbc_ce;
|
||||
|
||||
/* {{{ pdo_odbc_deps[] */
|
||||
static const zend_module_dep pdo_odbc_deps[] = {
|
||||
ZEND_MOD_REQUIRED("pdo")
|
||||
@@ -105,7 +107,10 @@ PHP_MINIT_FUNCTION(pdo_odbc)
|
||||
REGISTER_PDO_CLASS_CONST_LONG("ODBC_SQL_USE_DRIVER", SQL_CUR_USE_DRIVER);
|
||||
REGISTER_PDO_CLASS_CONST_LONG("ODBC_SQL_USE_ODBC", SQL_CUR_USE_ODBC);
|
||||
|
||||
return SUCCESS;
|
||||
pdo_odbc_ce = register_class_PdoOdbc(pdo_dbh_ce);
|
||||
pdo_odbc_ce->create_object = pdo_dbh_new;
|
||||
|
||||
return php_pdo_register_driver_specific_ce(&pdo_odbc_driver, pdo_odbc_ce);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
@@ -7,3 +7,25 @@
|
||||
* @cvalue PDO_ODBC_TYPE
|
||||
*/
|
||||
const PDO_ODBC_TYPE = UNKNOWN;
|
||||
|
||||
/**
|
||||
* @strict-properties
|
||||
* @not-serializable
|
||||
*/
|
||||
class PdoOdbc extends PDO
|
||||
{
|
||||
/** @cvalue PDO_ODBC_ATTR_USE_CURSOR_LIBRARY */
|
||||
public const int ATTR_USE_CURSOR_LIBRARY = UNKNOWN;
|
||||
|
||||
/** @cvalue PDO_ODBC_ATTR_ASSUME_UTF8 */
|
||||
public const int ATTR_ASSUME_UTF8 = UNKNOWN;
|
||||
|
||||
/** @cvalue SQL_CUR_USE_IF_NEEDED */
|
||||
public const int SQL_USE_IF_NEEDED = UNKNOWN;
|
||||
|
||||
/** @cvalue SQL_CUR_USE_DRIVER */
|
||||
public const int SQL_USE_DRIVER = UNKNOWN;
|
||||
|
||||
/** @cvalue SQL_CUR_USE_ODBC */
|
||||
public const int SQL_USE_ODBC = UNKNOWN;
|
||||
}
|
||||
|
||||
48
ext/pdo_odbc/pdo_odbc_arginfo.h
generated
48
ext/pdo_odbc/pdo_odbc_arginfo.h
generated
@@ -1,9 +1,55 @@
|
||||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: 7927099133bf60cab0464aae8c9de8f7ef2732bd */
|
||||
* Stub hash: 3cc19acf5943c09a011f15d9ef6d0f443d4b8a71 */
|
||||
|
||||
|
||||
|
||||
|
||||
static const zend_function_entry class_PdoOdbc_methods[] = {
|
||||
ZEND_FE_END
|
||||
};
|
||||
|
||||
static void register_pdo_odbc_symbols(int module_number)
|
||||
{
|
||||
REGISTER_STRING_CONSTANT("PDO_ODBC_TYPE", PDO_ODBC_TYPE, CONST_PERSISTENT);
|
||||
}
|
||||
|
||||
static zend_class_entry *register_class_PdoOdbc(zend_class_entry *class_entry_PDO)
|
||||
{
|
||||
zend_class_entry ce, *class_entry;
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "PdoOdbc", class_PdoOdbc_methods);
|
||||
class_entry = zend_register_internal_class_ex(&ce, class_entry_PDO);
|
||||
class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE;
|
||||
|
||||
zval const_ATTR_USE_CURSOR_LIBRARY_value;
|
||||
ZVAL_LONG(&const_ATTR_USE_CURSOR_LIBRARY_value, PDO_ODBC_ATTR_USE_CURSOR_LIBRARY);
|
||||
zend_string *const_ATTR_USE_CURSOR_LIBRARY_name = zend_string_init_interned("ATTR_USE_CURSOR_LIBRARY", sizeof("ATTR_USE_CURSOR_LIBRARY") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_USE_CURSOR_LIBRARY_name, &const_ATTR_USE_CURSOR_LIBRARY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_USE_CURSOR_LIBRARY_name);
|
||||
|
||||
zval const_ATTR_ASSUME_UTF8_value;
|
||||
ZVAL_LONG(&const_ATTR_ASSUME_UTF8_value, PDO_ODBC_ATTR_ASSUME_UTF8);
|
||||
zend_string *const_ATTR_ASSUME_UTF8_name = zend_string_init_interned("ATTR_ASSUME_UTF8", sizeof("ATTR_ASSUME_UTF8") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_ASSUME_UTF8_name, &const_ATTR_ASSUME_UTF8_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_ASSUME_UTF8_name);
|
||||
|
||||
zval const_SQL_USE_IF_NEEDED_value;
|
||||
ZVAL_LONG(&const_SQL_USE_IF_NEEDED_value, SQL_CUR_USE_IF_NEEDED);
|
||||
zend_string *const_SQL_USE_IF_NEEDED_name = zend_string_init_interned("SQL_USE_IF_NEEDED", sizeof("SQL_USE_IF_NEEDED") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_SQL_USE_IF_NEEDED_name, &const_SQL_USE_IF_NEEDED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_SQL_USE_IF_NEEDED_name);
|
||||
|
||||
zval const_SQL_USE_DRIVER_value;
|
||||
ZVAL_LONG(&const_SQL_USE_DRIVER_value, SQL_CUR_USE_DRIVER);
|
||||
zend_string *const_SQL_USE_DRIVER_name = zend_string_init_interned("SQL_USE_DRIVER", sizeof("SQL_USE_DRIVER") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_SQL_USE_DRIVER_name, &const_SQL_USE_DRIVER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_SQL_USE_DRIVER_name);
|
||||
|
||||
zval const_SQL_USE_ODBC_value;
|
||||
ZVAL_LONG(&const_SQL_USE_ODBC_value, SQL_CUR_USE_ODBC);
|
||||
zend_string *const_SQL_USE_ODBC_name = zend_string_init_interned("SQL_USE_ODBC", sizeof("SQL_USE_ODBC") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_SQL_USE_ODBC_name, &const_SQL_USE_ODBC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_SQL_USE_ODBC_name);
|
||||
|
||||
return class_entry;
|
||||
}
|
||||
|
||||
45
ext/pdo_odbc/tests/pdoodbc_001.phpt
Normal file
45
ext/pdo_odbc/tests/pdoodbc_001.phpt
Normal file
@@ -0,0 +1,45 @@
|
||||
--TEST--
|
||||
PDO_odbc subclass basic
|
||||
--EXTENSIONS--
|
||||
pdo_odbc
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require 'ext/pdo/tests/pdo_test.inc';
|
||||
PDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require 'ext/pdo/tests/pdo_test.inc';
|
||||
$config = PDOTest::get_config(__DIR__ . "/common.phpt");
|
||||
$db = new PdoOdbc($config['ENV']['PDOTEST_DSN'], $config['ENV']['PDOTEST_USER'], $config['ENV']['PDOTEST_PASS']);
|
||||
|
||||
$db->query("CREATE TABLE pdoodbc_001 (id INT, name TEXT)");
|
||||
$db->query("INSERT INTO pdoodbc_001 VALUES (NULL, 'PHP'), (NULL, 'PHP6')");
|
||||
|
||||
foreach ($db->query('SELECT name FROM pdoodbc_001') as $row) {
|
||||
var_dump($row);
|
||||
}
|
||||
|
||||
echo "Fin.";
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php
|
||||
require 'ext/pdo/tests/pdo_test.inc';
|
||||
$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
|
||||
$db->exec("DROP TABLE IF EXISTS pdoodbc_001");
|
||||
?>
|
||||
--EXPECT--
|
||||
array(2) {
|
||||
["name"]=>
|
||||
string(3) "PHP"
|
||||
[0]=>
|
||||
string(3) "PHP"
|
||||
}
|
||||
array(2) {
|
||||
["name"]=>
|
||||
string(4) "PHP6"
|
||||
[0]=>
|
||||
string(4) "PHP6"
|
||||
}
|
||||
Fin.
|
||||
54
ext/pdo_odbc/tests/pdoodbc_002.phpt
Normal file
54
ext/pdo_odbc/tests/pdoodbc_002.phpt
Normal file
@@ -0,0 +1,54 @@
|
||||
--TEST--
|
||||
PDO_mysql connect through PDO::connect
|
||||
--EXTENSIONS--
|
||||
PDO_odbc
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require 'ext/pdo/tests/pdo_test.inc';
|
||||
PDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require 'ext/pdo/tests/pdo_test.inc';
|
||||
$config = PDOTest::get_config(__DIR__ . "/common.phpt");
|
||||
$db = PdoOdbc::connect($config['ENV']['PDOTEST_DSN'], $config['ENV']['PDOTEST_USER'], $config['ENV']['PDOTEST_PASS']);
|
||||
if (!$db instanceof PdoOdbc) {
|
||||
echo "Wrong class type. Should be PdoOdbc but is " . get_class($db) . "\n";
|
||||
}
|
||||
|
||||
$db->exec('CREATE TABLE pdoodbc_002(id INT NOT NULL PRIMARY KEY, name VARCHAR(10))');
|
||||
$db->exec("INSERT INTO pdoodbc_002 VALUES(1, 'A'), (2, 'B'), (3, 'C')");
|
||||
|
||||
foreach ($db->query('SELECT name FROM pdoodbc_002') as $row) {
|
||||
var_dump($row);
|
||||
}
|
||||
|
||||
echo "Fin.";
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php
|
||||
require 'ext/pdo/tests/pdo_test.inc';
|
||||
$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
|
||||
$db->exec("DROP TABLE IF EXISTS pdoodbc_002");
|
||||
?>
|
||||
--EXPECT--
|
||||
array(2) {
|
||||
["name"]=>
|
||||
string(1) "A"
|
||||
[0]=>
|
||||
string(1) "A"
|
||||
}
|
||||
array(2) {
|
||||
["name"]=>
|
||||
string(1) "B"
|
||||
[0]=>
|
||||
string(1) "B"
|
||||
}
|
||||
array(2) {
|
||||
["name"]=>
|
||||
string(1) "C"
|
||||
[0]=>
|
||||
string(1) "C"
|
||||
}
|
||||
Fin.
|
||||
@@ -22,9 +22,13 @@
|
||||
#include "php_ini.h"
|
||||
#include "ext/standard/info.h"
|
||||
#include "pdo/php_pdo.h"
|
||||
#include "pdo/php_pdo_int.h"
|
||||
#include "pdo/php_pdo_driver.h"
|
||||
#include "php_pdo_pgsql.h"
|
||||
#include "php_pdo_pgsql_int.h"
|
||||
#include "pdo_pgsql_arginfo.h"
|
||||
|
||||
static zend_class_entry *PdoPgsql_ce;
|
||||
|
||||
/* {{{ pdo_sqlite_deps */
|
||||
static const zend_module_dep pdo_pgsql_deps[] = {
|
||||
@@ -53,6 +57,94 @@ zend_module_entry pdo_pgsql_module_entry = {
|
||||
ZEND_GET_MODULE(pdo_pgsql)
|
||||
#endif
|
||||
|
||||
/* Escape an identifier for insertion into a text field */
|
||||
PHP_METHOD(PdoPgsql, escapeIdentifier)
|
||||
{
|
||||
zend_string *from = NULL;
|
||||
char *tmp;
|
||||
pdo_dbh_t *dbh;
|
||||
pdo_pgsql_db_handle *H;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &from) == FAILURE) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
dbh = Z_PDO_DBH_P(ZEND_THIS);
|
||||
PDO_CONSTRUCT_CHECK;
|
||||
PDO_DBH_CLEAR_ERR();
|
||||
|
||||
/* Obtain db Handle */
|
||||
H = (pdo_pgsql_db_handle *)dbh->driver_data;
|
||||
if (H->server == NULL) {
|
||||
zend_throw_error(NULL, "PostgreSQL connection has already been closed");
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
tmp = PQescapeIdentifier(H->server, ZSTR_VAL(from), ZSTR_LEN(from));
|
||||
if (!tmp) {
|
||||
pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL);
|
||||
PDO_HANDLE_DBH_ERR();
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
RETVAL_STRING(tmp);
|
||||
PQfreemem(tmp);
|
||||
}
|
||||
|
||||
/* Returns true if the copy worked fine or false if error */
|
||||
PHP_METHOD(PdoPgsql, copyFromArray)
|
||||
{
|
||||
pgsqlCopyFromArray_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||
}
|
||||
|
||||
/* Returns true if the copy worked fine or false if error */
|
||||
PHP_METHOD(PdoPgsql, copyFromFile)
|
||||
{
|
||||
pgsqlCopyFromFile_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||
}
|
||||
|
||||
/* Returns true if the copy worked fine or false if error */
|
||||
PHP_METHOD(PdoPgsql, copyToFile)
|
||||
{
|
||||
pgsqlCopyToFile_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||
}
|
||||
|
||||
/* Returns true if the copy worked fine or false if error */
|
||||
PHP_METHOD(PdoPgsql, copyToArray)
|
||||
{
|
||||
pgsqlCopyToArray_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||
}
|
||||
|
||||
/* Creates a new large object, returning its identifier. Must be called inside a transaction. */
|
||||
PHP_METHOD(PdoPgsql, lobCreate)
|
||||
{
|
||||
pgsqlLOBCreate_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||
}
|
||||
|
||||
/* Opens an existing large object stream. Must be called inside a transaction. */
|
||||
PHP_METHOD(PdoPgsql, lobOpen)
|
||||
{
|
||||
pgsqlLOBOpen_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||
}
|
||||
|
||||
/* Deletes the large object identified by oid. Must be called inside a transaction. */
|
||||
PHP_METHOD(PdoPgsql, lobUnlink)
|
||||
{
|
||||
pgsqlLOBUnlink_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||
}
|
||||
|
||||
/* Get asynchronous notification */
|
||||
PHP_METHOD(PdoPgsql, getNotify)
|
||||
{
|
||||
pgsqlGetNotify_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||
}
|
||||
|
||||
/* Get backend(server) pid */
|
||||
PHP_METHOD(PdoPgsql, getPid)
|
||||
{
|
||||
pgsqlGetPid_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||
}
|
||||
|
||||
/* true global environment */
|
||||
|
||||
/* {{{ PHP_MINIT_FUNCTION */
|
||||
@@ -65,7 +157,14 @@ PHP_MINIT_FUNCTION(pdo_pgsql)
|
||||
REGISTER_PDO_CLASS_CONST_LONG("PGSQL_TRANSACTION_INERROR", (zend_long)PGSQL_TRANSACTION_INERROR);
|
||||
REGISTER_PDO_CLASS_CONST_LONG("PGSQL_TRANSACTION_UNKNOWN", (zend_long)PGSQL_TRANSACTION_UNKNOWN);
|
||||
|
||||
return php_pdo_register_driver(&pdo_pgsql_driver);
|
||||
PdoPgsql_ce = register_class_PdoPgsql(pdo_dbh_ce);
|
||||
PdoPgsql_ce->create_object = pdo_dbh_new;
|
||||
|
||||
if (php_pdo_register_driver(&pdo_pgsql_driver) == FAILURE) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return php_pdo_register_driver_specific_ce(&pdo_pgsql_driver, PdoPgsql_ce);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
50
ext/pdo_pgsql/pdo_pgsql.stub.php
Normal file
50
ext/pdo_pgsql/pdo_pgsql.stub.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/** @generate-class-entries */
|
||||
|
||||
/**
|
||||
* @strict-properties
|
||||
* @not-serializable
|
||||
*/
|
||||
class PdoPgsql extends PDO
|
||||
{
|
||||
/** @cvalue PDO_PGSQL_ATTR_DISABLE_PREPARES */
|
||||
public const int ATTR_DISABLE_PREPARES = UNKNOWN;
|
||||
|
||||
/** @cvalue PGSQL_TRANSACTION_IDLE */
|
||||
public const int TRANSACTION_IDLE = UNKNOWN;
|
||||
|
||||
/** @cvalue PGSQL_TRANSACTION_ACTIVE */
|
||||
public const int TRANSACTION_ACTIVE = UNKNOWN;
|
||||
|
||||
/** @cvalue PGSQL_TRANSACTION_INTRANS */
|
||||
public const int TRANSACTION_INTRANS = UNKNOWN;
|
||||
|
||||
/** @cvalue PGSQL_TRANSACTION_INERROR */
|
||||
public const int TRANSACTION_INERROR = UNKNOWN;
|
||||
|
||||
/** @cvalue PGSQL_TRANSACTION_UNKNOWN */
|
||||
public const int TRANSACTION_UNKNOWN = UNKNOWN;
|
||||
|
||||
public function escapeIdentifier(string $input): string {}
|
||||
|
||||
public function copyFromArray(string $tableName, array $rows, string $separator = "\t", string $nullAs = "\\\\N", ?string $fields = null): bool {}
|
||||
|
||||
public function copyFromFile(string $tableName, string $filename, string $separator = "\t", string $nullAs = "\\\\N", ?string $fields = null): bool {}
|
||||
|
||||
public function copyToArray(string $tableName, string $separator = "\t", string $nullAs = "\\\\N", ?string $fields = null): array|false {}
|
||||
|
||||
public function copyToFile(string $tableName, string $filename, string $separator = "\t", string $nullAs = "\\\\N", ?string $fields = null): bool {}
|
||||
|
||||
public function lobCreate(): string|false {}
|
||||
|
||||
// Opens an existing large object stream. Must be called inside a transaction.
|
||||
/** @return resource|false */
|
||||
public function lobOpen(string $oid, string $mode = "rb"){}
|
||||
|
||||
public function lobUnlink(string $oid): bool {}
|
||||
|
||||
public function getNotify(int $fetchMode = PDO::FETCH_DEFAULT, int $timeoutMilliseconds = 0): array|false {}
|
||||
|
||||
public function getPid(): int {}
|
||||
}
|
||||
125
ext/pdo_pgsql/pdo_pgsql_arginfo.h
generated
Normal file
125
ext/pdo_pgsql/pdo_pgsql_arginfo.h
generated
Normal file
@@ -0,0 +1,125 @@
|
||||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: 2be4e9679d29fcbc3330b78f9e63c4c6e1284f19 */
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_PdoPgsql_escapeIdentifier, 0, 1, IS_STRING, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, input, IS_STRING, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_PdoPgsql_copyFromArray, 0, 2, _IS_BOOL, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, tableName, IS_STRING, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, rows, IS_ARRAY, 0)
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, separator, IS_STRING, 0, "\"\\t\"")
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, nullAs, IS_STRING, 0, "\"\\\\\\\\N\"")
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, fields, IS_STRING, 1, "null")
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_PdoPgsql_copyFromFile, 0, 2, _IS_BOOL, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, tableName, IS_STRING, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0)
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, separator, IS_STRING, 0, "\"\\t\"")
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, nullAs, IS_STRING, 0, "\"\\\\\\\\N\"")
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, fields, IS_STRING, 1, "null")
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_PdoPgsql_copyToArray, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE)
|
||||
ZEND_ARG_TYPE_INFO(0, tableName, IS_STRING, 0)
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, separator, IS_STRING, 0, "\"\\t\"")
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, nullAs, IS_STRING, 0, "\"\\\\\\\\N\"")
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, fields, IS_STRING, 1, "null")
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_PdoPgsql_copyToFile arginfo_class_PdoPgsql_copyFromFile
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_PdoPgsql_lobCreate, 0, 0, MAY_BE_STRING|MAY_BE_FALSE)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_PdoPgsql_lobOpen, 0, 0, 1)
|
||||
ZEND_ARG_TYPE_INFO(0, oid, IS_STRING, 0)
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_STRING, 0, "\"rb\"")
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_PdoPgsql_lobUnlink, 0, 1, _IS_BOOL, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, oid, IS_STRING, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_PdoPgsql_getNotify, 0, 0, MAY_BE_ARRAY|MAY_BE_FALSE)
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, fetchMode, IS_LONG, 0, "PDO::FETCH_DEFAULT")
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, timeoutMilliseconds, IS_LONG, 0, "0")
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_PdoPgsql_getPid, 0, 0, IS_LONG, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
|
||||
ZEND_METHOD(PdoPgsql, escapeIdentifier);
|
||||
ZEND_METHOD(PdoPgsql, copyFromArray);
|
||||
ZEND_METHOD(PdoPgsql, copyFromFile);
|
||||
ZEND_METHOD(PdoPgsql, copyToArray);
|
||||
ZEND_METHOD(PdoPgsql, copyToFile);
|
||||
ZEND_METHOD(PdoPgsql, lobCreate);
|
||||
ZEND_METHOD(PdoPgsql, lobOpen);
|
||||
ZEND_METHOD(PdoPgsql, lobUnlink);
|
||||
ZEND_METHOD(PdoPgsql, getNotify);
|
||||
ZEND_METHOD(PdoPgsql, getPid);
|
||||
|
||||
|
||||
static const zend_function_entry class_PdoPgsql_methods[] = {
|
||||
ZEND_ME(PdoPgsql, escapeIdentifier, arginfo_class_PdoPgsql_escapeIdentifier, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(PdoPgsql, copyFromArray, arginfo_class_PdoPgsql_copyFromArray, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(PdoPgsql, copyFromFile, arginfo_class_PdoPgsql_copyFromFile, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(PdoPgsql, copyToArray, arginfo_class_PdoPgsql_copyToArray, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(PdoPgsql, copyToFile, arginfo_class_PdoPgsql_copyToFile, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(PdoPgsql, lobCreate, arginfo_class_PdoPgsql_lobCreate, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(PdoPgsql, lobOpen, arginfo_class_PdoPgsql_lobOpen, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(PdoPgsql, lobUnlink, arginfo_class_PdoPgsql_lobUnlink, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(PdoPgsql, getNotify, arginfo_class_PdoPgsql_getNotify, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(PdoPgsql, getPid, arginfo_class_PdoPgsql_getPid, ZEND_ACC_PUBLIC)
|
||||
ZEND_FE_END
|
||||
};
|
||||
|
||||
static zend_class_entry *register_class_PdoPgsql(zend_class_entry *class_entry_PDO)
|
||||
{
|
||||
zend_class_entry ce, *class_entry;
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "PdoPgsql", class_PdoPgsql_methods);
|
||||
class_entry = zend_register_internal_class_ex(&ce, class_entry_PDO);
|
||||
class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE;
|
||||
|
||||
zval const_ATTR_DISABLE_PREPARES_value;
|
||||
ZVAL_LONG(&const_ATTR_DISABLE_PREPARES_value, PDO_PGSQL_ATTR_DISABLE_PREPARES);
|
||||
zend_string *const_ATTR_DISABLE_PREPARES_name = zend_string_init_interned("ATTR_DISABLE_PREPARES", sizeof("ATTR_DISABLE_PREPARES") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_ATTR_DISABLE_PREPARES_name, &const_ATTR_DISABLE_PREPARES_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_ATTR_DISABLE_PREPARES_name);
|
||||
|
||||
zval const_TRANSACTION_IDLE_value;
|
||||
ZVAL_LONG(&const_TRANSACTION_IDLE_value, PGSQL_TRANSACTION_IDLE);
|
||||
zend_string *const_TRANSACTION_IDLE_name = zend_string_init_interned("TRANSACTION_IDLE", sizeof("TRANSACTION_IDLE") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_TRANSACTION_IDLE_name, &const_TRANSACTION_IDLE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_TRANSACTION_IDLE_name);
|
||||
|
||||
zval const_TRANSACTION_ACTIVE_value;
|
||||
ZVAL_LONG(&const_TRANSACTION_ACTIVE_value, PGSQL_TRANSACTION_ACTIVE);
|
||||
zend_string *const_TRANSACTION_ACTIVE_name = zend_string_init_interned("TRANSACTION_ACTIVE", sizeof("TRANSACTION_ACTIVE") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_TRANSACTION_ACTIVE_name, &const_TRANSACTION_ACTIVE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_TRANSACTION_ACTIVE_name);
|
||||
|
||||
zval const_TRANSACTION_INTRANS_value;
|
||||
ZVAL_LONG(&const_TRANSACTION_INTRANS_value, PGSQL_TRANSACTION_INTRANS);
|
||||
zend_string *const_TRANSACTION_INTRANS_name = zend_string_init_interned("TRANSACTION_INTRANS", sizeof("TRANSACTION_INTRANS") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_TRANSACTION_INTRANS_name, &const_TRANSACTION_INTRANS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_TRANSACTION_INTRANS_name);
|
||||
|
||||
zval const_TRANSACTION_INERROR_value;
|
||||
ZVAL_LONG(&const_TRANSACTION_INERROR_value, PGSQL_TRANSACTION_INERROR);
|
||||
zend_string *const_TRANSACTION_INERROR_name = zend_string_init_interned("TRANSACTION_INERROR", sizeof("TRANSACTION_INERROR") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_TRANSACTION_INERROR_name, &const_TRANSACTION_INERROR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_TRANSACTION_INERROR_name);
|
||||
|
||||
zval const_TRANSACTION_UNKNOWN_value;
|
||||
ZVAL_LONG(&const_TRANSACTION_UNKNOWN_value, PGSQL_TRANSACTION_UNKNOWN);
|
||||
zend_string *const_TRANSACTION_UNKNOWN_name = zend_string_init_interned("TRANSACTION_UNKNOWN", sizeof("TRANSACTION_UNKNOWN") - 1, 1);
|
||||
zend_declare_typed_class_constant(class_entry, const_TRANSACTION_UNKNOWN_name, &const_TRANSACTION_UNKNOWN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
zend_string_release(const_TRANSACTION_UNKNOWN_name);
|
||||
|
||||
return class_entry;
|
||||
}
|
||||
@@ -588,8 +588,7 @@ static bool pgsql_handle_rollback(pdo_dbh_t *dbh)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* {{{ Returns true if the copy worked fine or false if error */
|
||||
PHP_METHOD(PDO_PGSql_Ext, pgsqlCopyFromArray)
|
||||
void pgsqlCopyFromArray_internal(INTERNAL_FUNCTION_PARAMETERS)
|
||||
{
|
||||
pdo_dbh_t *dbh;
|
||||
pdo_pgsql_db_handle *H;
|
||||
@@ -604,8 +603,8 @@ PHP_METHOD(PDO_PGSql_Ext, pgsqlCopyFromArray)
|
||||
ExecStatusType status;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "sa|sss!",
|
||||
&table_name, &table_name_len, &pg_rows,
|
||||
&pg_delim, &pg_delim_len, &pg_null_as, &pg_null_as_len, &pg_fields, &pg_fields_len) == FAILURE) {
|
||||
&table_name, &table_name_len, &pg_rows,
|
||||
&pg_delim, &pg_delim_len, &pg_null_as, &pg_null_as_len, &pg_fields, &pg_fields_len) == FAILURE) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
@@ -699,10 +698,15 @@ PHP_METHOD(PDO_PGSql_Ext, pgsqlCopyFromArray)
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Returns true if the copy worked fine or false if error */
|
||||
PHP_METHOD(PDO_PGSql_Ext, pgsqlCopyFromFile)
|
||||
PHP_METHOD(PDO_PGSql_Ext, pgsqlCopyFromArray)
|
||||
{
|
||||
pgsqlCopyFromArray_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void pgsqlCopyFromFile_internal(INTERNAL_FUNCTION_PARAMETERS)
|
||||
{
|
||||
pdo_dbh_t *dbh;
|
||||
pdo_pgsql_db_handle *H;
|
||||
@@ -715,8 +719,8 @@ PHP_METHOD(PDO_PGSql_Ext, pgsqlCopyFromFile)
|
||||
php_stream *stream;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "sp|sss!",
|
||||
&table_name, &table_name_len, &filename, &filename_len,
|
||||
&pg_delim, &pg_delim_len, &pg_null_as, &pg_null_as_len, &pg_fields, &pg_fields_len) == FAILURE) {
|
||||
&table_name, &table_name_len, &filename, &filename_len,
|
||||
&pg_delim, &pg_delim_len, &pg_null_as, &pg_null_as_len, &pg_fields, &pg_fields_len) == FAILURE) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
@@ -796,11 +800,15 @@ PHP_METHOD(PDO_PGSql_Ext, pgsqlCopyFromFile)
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ Returns true if the copy worked fine or false if error */
|
||||
PHP_METHOD(PDO_PGSql_Ext, pgsqlCopyToFile)
|
||||
PHP_METHOD(PDO_PGSql_Ext, pgsqlCopyFromFile)
|
||||
{
|
||||
pgsqlCopyFromFile_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void pgsqlCopyToFile_internal(INTERNAL_FUNCTION_PARAMETERS)
|
||||
{
|
||||
pdo_dbh_t *dbh;
|
||||
pdo_pgsql_db_handle *H;
|
||||
@@ -891,10 +899,16 @@ PHP_METHOD(PDO_PGSql_Ext, pgsqlCopyToFile)
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Returns true if the copy worked fine or false if error */
|
||||
PHP_METHOD(PDO_PGSql_Ext, pgsqlCopyToArray)
|
||||
PHP_METHOD(PDO_PGSql_Ext, pgsqlCopyToFile)
|
||||
{
|
||||
pgsqlCopyToFile_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void pgsqlCopyToArray_internal(INTERNAL_FUNCTION_PARAMETERS)
|
||||
{
|
||||
pdo_dbh_t *dbh;
|
||||
pdo_pgsql_db_handle *H;
|
||||
@@ -966,11 +980,15 @@ PHP_METHOD(PDO_PGSql_Ext, pgsqlCopyToArray)
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* {{{ Returns true if the copy worked fine or false if error */
|
||||
PHP_METHOD(PDO_PGSql_Ext, pgsqlCopyToArray)
|
||||
{
|
||||
pgsqlCopyToArray_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ Creates a new large object, returning its identifier. Must be called inside a transaction. */
|
||||
PHP_METHOD(PDO_PGSql_Ext, pgsqlLOBCreate)
|
||||
void pgsqlLOBCreate_internal(INTERNAL_FUNCTION_PARAMETERS)
|
||||
{
|
||||
pdo_dbh_t *dbh;
|
||||
pdo_pgsql_db_handle *H;
|
||||
@@ -995,10 +1013,15 @@ PHP_METHOD(PDO_PGSql_Ext, pgsqlLOBCreate)
|
||||
PDO_HANDLE_DBH_ERR();
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
/* {{{ Creates a new large object, returning its identifier. Must be called inside a transaction. */
|
||||
PHP_METHOD(PDO_PGSql_Ext, pgsqlLOBCreate)
|
||||
{
|
||||
pgsqlLOBCreate_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Opens an existing large object stream. Must be called inside a transaction. */
|
||||
PHP_METHOD(PDO_PGSql_Ext, pgsqlLOBOpen)
|
||||
void pgsqlLOBOpen_internal(INTERNAL_FUNCTION_PARAMETERS)
|
||||
{
|
||||
pdo_dbh_t *dbh;
|
||||
pdo_pgsql_db_handle *H;
|
||||
@@ -1046,10 +1069,15 @@ PHP_METHOD(PDO_PGSql_Ext, pgsqlLOBOpen)
|
||||
PDO_HANDLE_DBH_ERR();
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
/* {{{ Opens an existing large object stream. Must be called inside a transaction. */
|
||||
PHP_METHOD(PDO_PGSql_Ext, pgsqlLOBOpen)
|
||||
{
|
||||
pgsqlLOBOpen_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Deletes the large object identified by oid. Must be called inside a transaction. */
|
||||
PHP_METHOD(PDO_PGSql_Ext, pgsqlLOBUnlink)
|
||||
void pgsqlLOBUnlink_internal(INTERNAL_FUNCTION_PARAMETERS)
|
||||
{
|
||||
pdo_dbh_t *dbh;
|
||||
pdo_pgsql_db_handle *H;
|
||||
@@ -1081,10 +1109,15 @@ PHP_METHOD(PDO_PGSql_Ext, pgsqlLOBUnlink)
|
||||
PDO_HANDLE_DBH_ERR();
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
/* {{{ Deletes the large object identified by oid. Must be called inside a transaction. */
|
||||
PHP_METHOD(PDO_PGSql_Ext, pgsqlLOBUnlink)
|
||||
{
|
||||
pgsqlLOBUnlink_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Get asynchronous notification */
|
||||
PHP_METHOD(PDO_PGSql_Ext, pgsqlGetNotify)
|
||||
void pgsqlGetNotify_internal(INTERNAL_FUNCTION_PARAMETERS)
|
||||
{
|
||||
pdo_dbh_t *dbh;
|
||||
pdo_pgsql_db_handle *H;
|
||||
@@ -1161,10 +1194,15 @@ PHP_METHOD(PDO_PGSql_Ext, pgsqlGetNotify)
|
||||
|
||||
PQfreemem(pgsql_notify);
|
||||
}
|
||||
|
||||
/* {{{ Get asynchronous notification */
|
||||
PHP_METHOD(PDO_PGSql_Ext, pgsqlGetNotify)
|
||||
{
|
||||
pgsqlGetNotify_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Get backend(server) pid */
|
||||
PHP_METHOD(PDO_PGSql_Ext, pgsqlGetPid)
|
||||
void pgsqlGetPid_internal(INTERNAL_FUNCTION_PARAMETERS)
|
||||
{
|
||||
pdo_dbh_t *dbh;
|
||||
pdo_pgsql_db_handle *H;
|
||||
@@ -1178,6 +1216,12 @@ PHP_METHOD(PDO_PGSql_Ext, pgsqlGetPid)
|
||||
|
||||
RETURN_LONG(PQbackendPID(H->server));
|
||||
}
|
||||
|
||||
/* {{{ Get backend(server) pid */
|
||||
PHP_METHOD(PDO_PGSql_Ext, pgsqlGetPid)
|
||||
{
|
||||
pgsqlGetPid_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static const zend_function_entry *pdo_pgsql_get_driver_methods(pdo_dbh_t *dbh, int kind)
|
||||
|
||||
@@ -109,4 +109,14 @@ extern const php_stream_ops pdo_pgsql_lob_stream_ops;
|
||||
void pdo_libpq_version(char *buf, size_t len);
|
||||
void pdo_pgsql_close_lob_streams(pdo_dbh_t *dbh);
|
||||
|
||||
void pgsqlCopyFromArray_internal(INTERNAL_FUNCTION_PARAMETERS);
|
||||
void pgsqlCopyFromFile_internal(INTERNAL_FUNCTION_PARAMETERS);
|
||||
void pgsqlCopyToArray_internal(INTERNAL_FUNCTION_PARAMETERS);
|
||||
void pgsqlCopyToFile_internal(INTERNAL_FUNCTION_PARAMETERS);
|
||||
void pgsqlLOBCreate_internal(INTERNAL_FUNCTION_PARAMETERS);
|
||||
void pgsqlLOBOpen_internal(INTERNAL_FUNCTION_PARAMETERS);
|
||||
void pgsqlLOBUnlink_internal(INTERNAL_FUNCTION_PARAMETERS);
|
||||
void pgsqlGetNotify_internal(INTERNAL_FUNCTION_PARAMETERS);
|
||||
void pgsqlGetPid_internal(INTERNAL_FUNCTION_PARAMETERS);
|
||||
|
||||
#endif /* PHP_PDO_PGSQL_INT_H */
|
||||
|
||||
47
ext/pdo_pgsql/tests/pdopgsql_001.phpt
Normal file
47
ext/pdo_pgsql/tests/pdopgsql_001.phpt
Normal file
@@ -0,0 +1,47 @@
|
||||
--TEST--
|
||||
PdoPgsql subclass basic
|
||||
--EXTENSIONS--
|
||||
pdo
|
||||
pdo_pgsql
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
require dirname(__DIR__, 2) . '/pdo/tests/pdo_test.inc';
|
||||
PDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . "/config.inc";
|
||||
|
||||
$db = new PdoPgsql($config['ENV']['PDOTEST_DSN']);
|
||||
|
||||
$db->query('CREATE TABLE pdopgsql_001 (id INT, name TEXT)');
|
||||
$db->query("INSERT INTO pdopgsql_001 VALUES (NULL, 'PHP'), (NULL, 'PHP6')");
|
||||
|
||||
foreach ($db->query('SELECT name FROM pdopgsql_001') as $row) {
|
||||
var_dump($row);
|
||||
}
|
||||
|
||||
echo "Fin.";
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php
|
||||
require __DIR__ . '/../../pdo/tests/pdo_test.inc';
|
||||
$pdo = PDOTest::test_factory(__DIR__ . '/common.phpt');
|
||||
$pdo->query("DROP TABLE IF EXISTS pdopgsql_001");
|
||||
?>
|
||||
--EXPECT--
|
||||
array(2) {
|
||||
["name"]=>
|
||||
string(3) "PHP"
|
||||
[0]=>
|
||||
string(3) "PHP"
|
||||
}
|
||||
array(2) {
|
||||
["name"]=>
|
||||
string(4) "PHP6"
|
||||
[0]=>
|
||||
string(4) "PHP6"
|
||||
}
|
||||
Fin.
|
||||
56
ext/pdo_pgsql/tests/pdopgsql_002.phpt
Normal file
56
ext/pdo_pgsql/tests/pdopgsql_002.phpt
Normal file
@@ -0,0 +1,56 @@
|
||||
--TEST--
|
||||
PdoPgsql connect through PDO::connect
|
||||
--EXTENSIONS--
|
||||
pdo
|
||||
pdo_pgsql
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
require dirname(__DIR__, 2) . '/pdo/tests/pdo_test.inc';
|
||||
PDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . "/config.inc";
|
||||
|
||||
$db = Pdo::connect($config['ENV']['PDOTEST_DSN']);
|
||||
if (!$db instanceof PdoPgsql) {
|
||||
echo "Wrong class type. Should be PdoPgsql but is " . get_class($db) . "\n";
|
||||
}
|
||||
|
||||
$db->exec('CREATE TABLE pdopgsql_002(id INT NOT NULL PRIMARY KEY, name VARCHAR(10))');
|
||||
$db->exec("INSERT INTO pdopgsql_002 VALUES(1, 'A'), (2, 'B'), (3, 'C')");
|
||||
|
||||
foreach ($db->query('SELECT name FROM pdopgsql_002') as $row) {
|
||||
var_dump($row);
|
||||
}
|
||||
|
||||
echo "Fin.";
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php
|
||||
require __DIR__ . '/../../pdo/tests/pdo_test.inc';
|
||||
$pdo = PDOTest::test_factory(__DIR__ . '/common.phpt');
|
||||
$pdo->query("DROP TABLE IF EXISTS pdopgsql_002");
|
||||
?>
|
||||
--EXPECT--
|
||||
array(2) {
|
||||
["name"]=>
|
||||
string(1) "A"
|
||||
[0]=>
|
||||
string(1) "A"
|
||||
}
|
||||
array(2) {
|
||||
["name"]=>
|
||||
string(1) "B"
|
||||
[0]=>
|
||||
string(1) "B"
|
||||
}
|
||||
array(2) {
|
||||
["name"]=>
|
||||
string(1) "C"
|
||||
[0]=>
|
||||
string(1) "C"
|
||||
}
|
||||
Fin.
|
||||
32
ext/pdo_pgsql/tests/pdopgsql_003.phpt
Normal file
32
ext/pdo_pgsql/tests/pdopgsql_003.phpt
Normal file
@@ -0,0 +1,32 @@
|
||||
--TEST--
|
||||
PdoPgsql getWarningCount
|
||||
--EXTENSIONS--
|
||||
pdo
|
||||
pdo_pgsql
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
require dirname(__DIR__, 2) . '/pdo/tests/pdo_test.inc';
|
||||
PDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . "/config.inc";
|
||||
|
||||
$db = Pdo::connect($config['ENV']['PDOTEST_DSN']);
|
||||
if (!$db instanceof PdoPgsql) {
|
||||
echo "Wrong class type. Should be PdoPgsql but is " . get_class($db) . "\n";
|
||||
}
|
||||
|
||||
echo $db->escapeIdentifier("This is a quote\"") . "\n";
|
||||
|
||||
try {
|
||||
$db->escapeIdentifier("aa\xC3\xC3\xC3");
|
||||
} catch (PDOException $e) {
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
|
||||
--EXPECT--
|
||||
"This is a quote"""
|
||||
SQLSTATE[HY000]: General error: 7 incomplete multibyte character
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user