iliaa                                    Thu, 10 Jun 2010 12:11:19 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=300351

Log:
Added inTransaction() method to PDO, with specialized support for Postgres

Changed paths:
    U   php/php-src/branches/PHP_5_3/NEWS
    U   php/php-src/branches/PHP_5_3/ext/pdo/pdo_dbh.c
    U   php/php-src/branches/PHP_5_3/ext/pdo/php_pdo_driver.h
    U   php/php-src/branches/PHP_5_3/ext/pdo_pgsql/pdo_pgsql.c
    U   php/php-src/branches/PHP_5_3/ext/pdo_pgsql/pgsql_driver.c
    U   php/php-src/branches/PHP_5_3/ext/pdo_pgsql/php_pdo_pgsql_int.h
    A   php/php-src/branches/PHP_5_3/ext/pdo_pgsql/tests/is_in_transaction.phpt
    U   php/php-src/trunk/ext/pdo/pdo_dbh.c
    U   php/php-src/trunk/ext/pdo/php_pdo_driver.h
    U   php/php-src/trunk/ext/pdo_pgsql/pdo_pgsql.c
    U   php/php-src/trunk/ext/pdo_pgsql/pgsql_driver.c
    U   php/php-src/trunk/ext/pdo_pgsql/php_pdo_pgsql_int.h
    A   php/php-src/trunk/ext/pdo_pgsql/tests/is_in_transaction.phpt

Modified: php/php-src/branches/PHP_5_3/NEWS
===================================================================
--- php/php-src/branches/PHP_5_3/NEWS	2010-06-10 11:45:51 UTC (rev 300350)
+++ php/php-src/branches/PHP_5_3/NEWS	2010-06-10 12:11:19 UTC (rev 300351)
@@ -22,6 +22,8 @@
 - Added Berkeley DB 5 support to the DBA extension (Johannes, Chris Jones)
 - Added support for copy to/from array/file for pdo_pgsql extension.
   (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
   __construct now. (Stas)

Modified: php/php-src/branches/PHP_5_3/ext/pdo/pdo_dbh.c
===================================================================
--- php/php-src/branches/PHP_5_3/ext/pdo/pdo_dbh.c	2010-06-10 11:45:51 UTC (rev 300350)
+++ php/php-src/branches/PHP_5_3/ext/pdo/pdo_dbh.c	2010-06-10 12:11:19 UTC (rev 300351)
@@ -683,6 +683,25 @@
 }
 /* }}} */

+/* {{{ 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) /* {{{ */
 {

@@ -1246,6 +1265,7 @@
 	PHP_ME(PDO, beginTransaction,       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, inTransaction,          arginfo_pdo__void,         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, query,			NULL,					ZEND_ACC_PUBLIC)

Modified: php/php-src/branches/PHP_5_3/ext/pdo/php_pdo_driver.h
===================================================================
--- php/php-src/branches/PHP_5_3/ext/pdo/php_pdo_driver.h	2010-06-10 11:45:51 UTC (rev 300350)
+++ php/php-src/branches/PHP_5_3/ext/pdo/php_pdo_driver.h	2010-06-10 12:11:19 UTC (rev 300351)
@@ -310,6 +310,7 @@
 	pdo_dbh_check_liveness_func	check_liveness;
 	pdo_dbh_get_driver_methods_func get_driver_methods;
 	pdo_dbh_request_shutdown	persistent_shutdown;
+	pdo_dbh_txn_func		in_transaction;
 };

 /* }}} */

Modified: php/php-src/branches/PHP_5_3/ext/pdo_pgsql/pdo_pgsql.c
===================================================================
--- php/php-src/branches/PHP_5_3/ext/pdo_pgsql/pdo_pgsql.c	2010-06-10 11:45:51 UTC (rev 300350)
+++ php/php-src/branches/PHP_5_3/ext/pdo_pgsql/pdo_pgsql.c	2010-06-10 12:11:19 UTC (rev 300351)
@@ -86,6 +86,12 @@
 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_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);
 	return SUCCESS;
 }

Modified: php/php-src/branches/PHP_5_3/ext/pdo_pgsql/pgsql_driver.c
===================================================================
--- php/php-src/branches/PHP_5_3/ext/pdo_pgsql/pgsql_driver.c	2010-06-10 11:45:51 UTC (rev 300350)
+++ php/php-src/branches/PHP_5_3/ext/pdo_pgsql/pgsql_driver.c	2010-06-10 12:11:19 UTC (rev 300351)
@@ -497,6 +497,15 @@
 	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])
    Returns true if the copy worked fine or false if error */
 static PHP_METHOD(PDO, pgsqlCopyFromArray)
@@ -1020,7 +1029,9 @@
 	pdo_pgsql_fetch_error_func,
 	pdo_pgsql_get_attribute,
 	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) /* {{{ */

Modified: php/php-src/branches/PHP_5_3/ext/pdo_pgsql/php_pdo_pgsql_int.h
===================================================================
--- php/php-src/branches/PHP_5_3/ext/pdo_pgsql/php_pdo_pgsql_int.h	2010-06-10 11:45:51 UTC (rev 300350)
+++ php/php-src/branches/PHP_5_3/ext/pdo_pgsql/php_pdo_pgsql_int.h	2010-06-10 12:11:19 UTC (rev 300351)
@@ -102,6 +102,13 @@
 	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);
 extern php_stream_ops pdo_pgsql_lob_stream_ops;

Added: php/php-src/branches/PHP_5_3/ext/pdo_pgsql/tests/is_in_transaction.phpt
===================================================================
--- php/php-src/branches/PHP_5_3/ext/pdo_pgsql/tests/is_in_transaction.phpt	                        (rev 0)
+++ php/php-src/branches/PHP_5_3/ext/pdo_pgsql/tests/is_in_transaction.phpt	2010-06-10 12:11:19 UTC (rev 300351)
@@ -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)

Modified: php/php-src/trunk/ext/pdo/pdo_dbh.c
===================================================================
--- php/php-src/trunk/ext/pdo/pdo_dbh.c	2010-06-10 11:45:51 UTC (rev 300350)
+++ php/php-src/trunk/ext/pdo/pdo_dbh.c	2010-06-10 12:11:19 UTC (rev 300351)
@@ -683,6 +683,25 @@
 }
 /* }}} */

+/* {{{ 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) /* {{{ */
 {

@@ -1246,6 +1265,7 @@
 	PHP_ME(PDO, beginTransaction,       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, inTransaction,          arginfo_pdo__void,         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, query,			NULL,					ZEND_ACC_PUBLIC)

Modified: php/php-src/trunk/ext/pdo/php_pdo_driver.h
===================================================================
--- php/php-src/trunk/ext/pdo/php_pdo_driver.h	2010-06-10 11:45:51 UTC (rev 300350)
+++ php/php-src/trunk/ext/pdo/php_pdo_driver.h	2010-06-10 12:11:19 UTC (rev 300351)
@@ -310,6 +310,7 @@
 	pdo_dbh_check_liveness_func	check_liveness;
 	pdo_dbh_get_driver_methods_func get_driver_methods;
 	pdo_dbh_request_shutdown	persistent_shutdown;
+	pdo_dbh_txn_func		in_transaction;
 };

 /* }}} */

Modified: php/php-src/trunk/ext/pdo_pgsql/pdo_pgsql.c
===================================================================
--- php/php-src/trunk/ext/pdo_pgsql/pdo_pgsql.c	2010-06-10 11:45:51 UTC (rev 300350)
+++ php/php-src/trunk/ext/pdo_pgsql/pdo_pgsql.c	2010-06-10 12:11:19 UTC (rev 300351)
@@ -86,6 +86,12 @@
 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_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);
 	return SUCCESS;
 }

Modified: php/php-src/trunk/ext/pdo_pgsql/pgsql_driver.c
===================================================================
--- php/php-src/trunk/ext/pdo_pgsql/pgsql_driver.c	2010-06-10 11:45:51 UTC (rev 300350)
+++ php/php-src/trunk/ext/pdo_pgsql/pgsql_driver.c	2010-06-10 12:11:19 UTC (rev 300351)
@@ -497,6 +497,15 @@
 	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])
    Returns true if the copy worked fine or false if error */
 static PHP_METHOD(PDO, pgsqlCopyFromArray)
@@ -1020,7 +1029,9 @@
 	pdo_pgsql_fetch_error_func,
 	pdo_pgsql_get_attribute,
 	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) /* {{{ */

Modified: php/php-src/trunk/ext/pdo_pgsql/php_pdo_pgsql_int.h
===================================================================
--- php/php-src/trunk/ext/pdo_pgsql/php_pdo_pgsql_int.h	2010-06-10 11:45:51 UTC (rev 300350)
+++ php/php-src/trunk/ext/pdo_pgsql/php_pdo_pgsql_int.h	2010-06-10 12:11:19 UTC (rev 300351)
@@ -102,6 +102,13 @@
 	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);
 extern php_stream_ops pdo_pgsql_lob_stream_ops;

Added: php/php-src/trunk/ext/pdo_pgsql/tests/is_in_transaction.phpt
===================================================================
--- php/php-src/trunk/ext/pdo_pgsql/tests/is_in_transaction.phpt	                        (rev 0)
+++ php/php-src/trunk/ext/pdo_pgsql/tests/is_in_transaction.phpt	2010-06-10 12:11:19 UTC (rev 300351)
@@ -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)
-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to