mirror of
https://github.com/php/php-src.git
synced 2024-11-28 12:26:37 +08:00
Added inTransaction() method to PDO, with specialized support for Postgres
This commit is contained in:
parent
748dd20476
commit
90906a91e9
2
NEWS
2
NEWS
@ -22,6 +22,8 @@ PHP NEWS
|
|||||||
- Added Berkeley DB 5 support to the DBA extension (Johannes, Chris Jones)
|
- Added Berkeley DB 5 support to the DBA extension (Johannes, Chris Jones)
|
||||||
- Added support for copy to/from array/file for pdo_pgsql extension.
|
- Added support for copy to/from array/file for pdo_pgsql extension.
|
||||||
(Denis Gasparin, Ilia)
|
(Denis Gasparin, Ilia)
|
||||||
|
- Added inTransaction() method to PDO, with specialized support for Postgres
|
||||||
|
(Ilia, Denis Gasparin)
|
||||||
|
|
||||||
- Changed namespaced classes so that the ctor can only be named
|
- Changed namespaced classes so that the ctor can only be named
|
||||||
__construct now. (Stas)
|
__construct now. (Stas)
|
||||||
|
@ -683,6 +683,25 @@ static PHP_METHOD(PDO, rollBack)
|
|||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
/* {{{ proto bool PDO::inTransaction()
|
||||||
|
determine if inside a transaction */
|
||||||
|
static PHP_METHOD(PDO, inTransaction)
|
||||||
|
{
|
||||||
|
pdo_dbh_t *dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||||
|
|
||||||
|
if (zend_parse_parameters_none() == FAILURE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PDO_CONSTRUCT_CHECK;
|
||||||
|
|
||||||
|
if (!dbh->methods->in_transaction) {
|
||||||
|
RETURN_BOOL(dbh->in_txn);
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURN_LONG(dbh->methods->in_transaction(dbh TSRMLS_CC));
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
static int pdo_dbh_attribute_set(pdo_dbh_t *dbh, long attr, zval *value TSRMLS_DC) /* {{{ */
|
static int pdo_dbh_attribute_set(pdo_dbh_t *dbh, long attr, zval *value TSRMLS_DC) /* {{{ */
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -1246,6 +1265,7 @@ const zend_function_entry pdo_dbh_functions[] = {
|
|||||||
PHP_ME(PDO, beginTransaction, arginfo_pdo__void, ZEND_ACC_PUBLIC)
|
PHP_ME(PDO, beginTransaction, arginfo_pdo__void, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(PDO, commit, arginfo_pdo__void, ZEND_ACC_PUBLIC)
|
PHP_ME(PDO, commit, arginfo_pdo__void, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(PDO, rollBack, arginfo_pdo__void, ZEND_ACC_PUBLIC)
|
PHP_ME(PDO, rollBack, arginfo_pdo__void, ZEND_ACC_PUBLIC)
|
||||||
|
PHP_ME(PDO, inTransaction, arginfo_pdo__void, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(PDO, setAttribute, arginfo_pdo_setattribute, ZEND_ACC_PUBLIC)
|
PHP_ME(PDO, setAttribute, arginfo_pdo_setattribute, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(PDO, exec, arginfo_pdo_exec, ZEND_ACC_PUBLIC)
|
PHP_ME(PDO, exec, arginfo_pdo_exec, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(PDO, query, NULL, ZEND_ACC_PUBLIC)
|
PHP_ME(PDO, query, NULL, ZEND_ACC_PUBLIC)
|
||||||
|
@ -310,6 +310,7 @@ struct pdo_dbh_methods {
|
|||||||
pdo_dbh_check_liveness_func check_liveness;
|
pdo_dbh_check_liveness_func check_liveness;
|
||||||
pdo_dbh_get_driver_methods_func get_driver_methods;
|
pdo_dbh_get_driver_methods_func get_driver_methods;
|
||||||
pdo_dbh_request_shutdown persistent_shutdown;
|
pdo_dbh_request_shutdown persistent_shutdown;
|
||||||
|
pdo_dbh_txn_func in_transaction;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
@ -86,6 +86,12 @@ ZEND_GET_MODULE(pdo_pgsql)
|
|||||||
PHP_MINIT_FUNCTION(pdo_pgsql)
|
PHP_MINIT_FUNCTION(pdo_pgsql)
|
||||||
{
|
{
|
||||||
REGISTER_PDO_CLASS_CONST_LONG("PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT", PDO_PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT);
|
REGISTER_PDO_CLASS_CONST_LONG("PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT", PDO_PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT);
|
||||||
|
REGISTER_PDO_CLASS_CONST_LONG("PGSQL_TRANSACTION_IDLE", (long)PGSQL_TRANSACTION_IDLE);
|
||||||
|
REGISTER_PDO_CLASS_CONST_LONG("PGSQL_TRANSACTION_ACTIVE", (long)PGSQL_TRANSACTION_ACTIVE);
|
||||||
|
REGISTER_PDO_CLASS_CONST_LONG("PGSQL_TRANSACTION_INTRANS", (long)PGSQL_TRANSACTION_INTRANS);
|
||||||
|
REGISTER_PDO_CLASS_CONST_LONG("PGSQL_TRANSACTION_INERROR", (long)PGSQL_TRANSACTION_INERROR);
|
||||||
|
REGISTER_PDO_CLASS_CONST_LONG("PGSQL_TRANSACTION_UNKNOWN", (long)PGSQL_TRANSACTION_UNKNOWN);
|
||||||
|
|
||||||
php_pdo_register_driver(&pdo_pgsql_driver);
|
php_pdo_register_driver(&pdo_pgsql_driver);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -497,6 +497,15 @@ static int pgsql_handle_rollback(pdo_dbh_t *dbh TSRMLS_DC)
|
|||||||
return pdo_pgsql_transaction_cmd("ROLLBACK", dbh TSRMLS_CC);
|
return pdo_pgsql_transaction_cmd("ROLLBACK", dbh TSRMLS_CC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int pgsql_handle_in_transaction(pdo_dbh_t *dbh TSRMLS_DC)
|
||||||
|
{
|
||||||
|
pdo_pgsql_db_handle *H;
|
||||||
|
|
||||||
|
H = (pdo_pgsql_db_handle *)dbh->driver_data;
|
||||||
|
|
||||||
|
return PQtransactionStatus(H->server);
|
||||||
|
}
|
||||||
|
|
||||||
/* {{{ proto string PDO::pgsqlCopyFromArray(string $table_name , array $rows [, string $delimiter [, string $null_as ] [, string $fields])
|
/* {{{ proto string PDO::pgsqlCopyFromArray(string $table_name , array $rows [, string $delimiter [, string $null_as ] [, string $fields])
|
||||||
Returns true if the copy worked fine or false if error */
|
Returns true if the copy worked fine or false if error */
|
||||||
static PHP_METHOD(PDO, pgsqlCopyFromArray)
|
static PHP_METHOD(PDO, pgsqlCopyFromArray)
|
||||||
@ -1020,7 +1029,9 @@ static struct pdo_dbh_methods pgsql_methods = {
|
|||||||
pdo_pgsql_fetch_error_func,
|
pdo_pgsql_fetch_error_func,
|
||||||
pdo_pgsql_get_attribute,
|
pdo_pgsql_get_attribute,
|
||||||
pdo_pgsql_check_liveness, /* check_liveness */
|
pdo_pgsql_check_liveness, /* check_liveness */
|
||||||
pdo_pgsql_get_driver_methods /* get_driver_methods */
|
pdo_pgsql_get_driver_methods, /* get_driver_methods */
|
||||||
|
NULL,
|
||||||
|
pgsql_handle_in_transaction,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */
|
static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */
|
||||||
|
@ -102,6 +102,13 @@ struct pdo_pgsql_lob_self {
|
|||||||
Oid oid;
|
Oid oid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum pdo_pgsql_specific_constants {
|
||||||
|
PGSQL_TRANSACTION_IDLE = PQTRANS_IDLE,
|
||||||
|
PGSQL_TRANSACTION_ACTIVE = PQTRANS_ACTIVE,
|
||||||
|
PGSQL_TRANSACTION_INTRANS = PQTRANS_INTRANS,
|
||||||
|
PGSQL_TRANSACTION_INERROR = PQTRANS_INERROR,
|
||||||
|
PGSQL_TRANSACTION_UNKNOWN = PQTRANS_UNKNOWN
|
||||||
|
};
|
||||||
|
|
||||||
php_stream *pdo_pgsql_create_lob_stream(pdo_dbh_t *stmt, int lfd, Oid oid TSRMLS_DC);
|
php_stream *pdo_pgsql_create_lob_stream(pdo_dbh_t *stmt, int lfd, Oid oid TSRMLS_DC);
|
||||||
extern php_stream_ops pdo_pgsql_lob_stream_ops;
|
extern php_stream_ops pdo_pgsql_lob_stream_ops;
|
||||||
|
66
ext/pdo_pgsql/tests/is_in_transaction.phpt
Normal file
66
ext/pdo_pgsql/tests/is_in_transaction.phpt
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
--TEST--
|
||||||
|
PDO PgSQL isInTransaction
|
||||||
|
--SKIPIF--
|
||||||
|
<?php # vim:se ft=php:
|
||||||
|
if (!extension_loaded('pdo') || !extension_loaded('pdo_pgsql')) die('skip not loaded');
|
||||||
|
require dirname(__FILE__) . '/config.inc';
|
||||||
|
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||||
|
PDOTest::skip();
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||||
|
$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
|
||||||
|
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||||
|
$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);
|
||||||
|
|
||||||
|
$db->exec('CREATE TABLE test (a integer not null primary key, b text)');
|
||||||
|
|
||||||
|
$db->beginTransaction();
|
||||||
|
try {
|
||||||
|
echo "Test PDO::PGSQL_TRANSACTION_INTRANS\n";
|
||||||
|
var_dump($db->inTransaction());
|
||||||
|
|
||||||
|
$stmt = $db->prepare("INSERT INTO test (a, b) values (?, ?)");
|
||||||
|
$stmt->bindValue(1, 1);
|
||||||
|
$stmt->bindValue(2, "test insert");
|
||||||
|
$stmt->execute();
|
||||||
|
|
||||||
|
$db->commit();
|
||||||
|
|
||||||
|
echo "Test PDO::PGSQL_TRANSACTION_IDLE\n";
|
||||||
|
var_dump($db->inTransaction());
|
||||||
|
|
||||||
|
$db->beginTransaction();
|
||||||
|
|
||||||
|
try {
|
||||||
|
$stmt = $db->prepare("INSERT INTO test (a, b) values (?, ?)");
|
||||||
|
$stmt->bindValue(1, "error");
|
||||||
|
$stmt->bindValue(2, "test insert");
|
||||||
|
$stmt->execute();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
/* We catch the exception because the execute will give error and we must test the PDO::PGSQL_TRANSACTION_ERROR */
|
||||||
|
echo "Test PDO::PGSQL_TRANSACTION_INERROR\n";
|
||||||
|
var_dump($db->inTransaction());
|
||||||
|
$db->rollBack();
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Test PDO::PGSQL_TRANSACTION_IDLE\n";
|
||||||
|
var_dump($db->inTransaction());
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
/* catch exceptions so that we can show the relative error */
|
||||||
|
echo "Exception! at line ", $e->getLine(), "\n";
|
||||||
|
var_dump($e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
Test PDO::PGSQL_TRANSACTION_INTRANS
|
||||||
|
int(2)
|
||||||
|
Test PDO::PGSQL_TRANSACTION_IDLE
|
||||||
|
int(0)
|
||||||
|
Test PDO::PGSQL_TRANSACTION_INERROR
|
||||||
|
int(3)
|
||||||
|
Test PDO::PGSQL_TRANSACTION_IDLE
|
||||||
|
int(0)
|
Loading…
Reference in New Issue
Block a user