Skip to content

Commit

Permalink
Add PDOStatement::activeQueryString()
Browse files Browse the repository at this point in the history
  • Loading branch information
adambaratz committed Nov 15, 2016
1 parent ee38e01 commit 83086d9
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 8 deletions.
34 changes: 26 additions & 8 deletions ext/pdo/pdo_stmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,12 @@ static PHP_METHOD(PDOStatement, execute)
* quoted.
*/

/* string is leftover from previous calls so PDOStatement::activeQueryString() can access */
if (stmt->active_query_string && stmt->active_query_string != stmt->query_string) {
efree(stmt->active_query_string);
}
stmt->active_query_string = NULL;

ret = pdo_parse_params(stmt, stmt->query_string, stmt->query_stringlen,
&stmt->active_query_string, &stmt->active_query_stringlen);

Expand All @@ -504,10 +510,6 @@ static PHP_METHOD(PDOStatement, execute)
RETURN_FALSE;
}
if (stmt->methods->executer(stmt)) {
if (stmt->active_query_string && stmt->active_query_string != stmt->query_string) {
efree(stmt->active_query_string);
}
stmt->active_query_string = NULL;
if (!stmt->executed) {
/* this is the first execute */

Expand All @@ -526,10 +528,6 @@ static PHP_METHOD(PDOStatement, execute)

RETURN_BOOL(ret);
}
if (stmt->active_query_string && stmt->active_query_string != stmt->query_string) {
efree(stmt->active_query_string);
}
stmt->active_query_string = NULL;
PDO_HANDLE_STMT_ERR();
RETURN_FALSE;
}
Expand Down Expand Up @@ -2092,6 +2090,22 @@ static PHP_METHOD(PDOStatement, closeCursor)
}
/* }}} */

/* {{{ proto string PDOStatement::activeQueryString()
Fetch the last executed query string associated with the statement handle */
static PHP_METHOD(PDOStatement, activeQueryString)
{
PHP_STMT_GET_OBJ;

if (stmt->active_query_string) {
RETURN_STRING(stmt->active_query_string);
} else if (stmt->query_string) {
RETURN_STRING(stmt->query_string);
} else {
RETURN_FALSE;
}
}
/* }}} */

/* {{{ proto void PDOStatement::debugDumpParams()
A utility for internals hackers to debug parameter internals */
static PHP_METHOD(PDOStatement, debugDumpParams)
Expand Down Expand Up @@ -2170,6 +2184,7 @@ const zend_function_entry pdo_dbstmt_functions[] = {
PHP_ME(PDOStatement, setFetchMode, arginfo_pdostatement_setfetchmode, ZEND_ACC_PUBLIC)
PHP_ME(PDOStatement, nextRowset, arginfo_pdostatement__void, ZEND_ACC_PUBLIC)
PHP_ME(PDOStatement, closeCursor, arginfo_pdostatement__void, ZEND_ACC_PUBLIC)
PHP_ME(PDOStatement, activeQueryString, arginfo_pdostatement__void, ZEND_ACC_PUBLIC)
PHP_ME(PDOStatement, debugDumpParams, arginfo_pdostatement__void, ZEND_ACC_PUBLIC)
PHP_ME(PDOStatement, __wakeup, arginfo_pdostatement__void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(PDOStatement, __sleep, arginfo_pdostatement__void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
Expand Down Expand Up @@ -2317,6 +2332,9 @@ PDO_API void php_pdo_free_statement(pdo_stmt_t *stmt)
if (stmt->methods && stmt->methods->dtor) {
stmt->methods->dtor(stmt);
}
if (stmt->active_query_string && stmt->active_query_string != stmt->query_string) {
efree(stmt->active_query_string);
}
if (stmt->query_string) {
efree(stmt->query_string);
}
Expand Down
51 changes: 51 additions & 0 deletions ext/pdo/tests/active_query_string.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
--TEST--
PDO Common: PDOStatement::activeQueryString()
--SKIPIF--
<?php
if (!extension_loaded('pdo')) die('skip');
$dir = getenv('REDIR_TEST_DIR');
if (false == $dir) die('skip no driver');
require_once $dir . 'pdo_test.inc';
PDOTest::skip();

$db = PDOTest::factory();
if (!$db->getAttribute(PDO::ATTR_EMULATE_PREPARES) && !$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, true)) die('skip driver cannot emulate prepared statements');
?>
--FILE--
<?php
if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';

$db = PDOTest::factory();
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);

$stmt = $db->query('SELECT 1');
var_dump($stmt->activeQueryString()); // works with statements without bound values

$stmt = $db->prepare('SELECT :bool, :int, :string, :null');
$stmt->bindValue(':bool', true, PDO::PARAM_BOOL);
$stmt->bindValue(':int', 123, PDO::PARAM_INT);
$stmt->bindValue(':string', 'foo', PDO::PARAM_STR);
$stmt->bindValue(':null', null, PDO::PARAM_NULL);

var_dump($stmt->activeQueryString()); // will return unparsed query before execution

$stmt->execute();
var_dump($stmt->activeQueryString()); // will return parsed query after execution
var_dump($stmt->activeQueryString()); // can be called repeatedly

$stmt->execute();
var_dump($stmt->activeQueryString()); // works if the statement is executed again

$stmt->bindValue(':int', 456, PDO::PARAM_INT);
$stmt->execute();
var_dump($stmt->activeQueryString()); // works with altered values

?>
--EXPECT--
string(8) "SELECT 1"
string(34) "SELECT :bool, :int, :string, :null"
string(26) "SELECT 1, 123, 'foo', NULL"
string(26) "SELECT 1, 123, 'foo', NULL"
string(26) "SELECT 1, 123, 'foo', NULL"
string(26) "SELECT 1, 456, 'foo', NULL"
5 changes: 5 additions & 0 deletions ext/pdo_dblib/dblib_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,11 @@ static int dblib_set_attr(pdo_dbh_t *dbh, zend_long attr, zval *val)
static int dblib_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *return_value)
{
switch (attr) {
case PDO_ATTR_EMULATE_PREPARES:
/* this is the only option available, but expose it so common tests and whatever else can introspect */
ZVAL_TRUE(return_value);
break;

case PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER:
ZVAL_BOOL(return_value, ((pdo_dblib_db_handle *)dbh->driver_data)->stringify_uniqueidentifier);
break;
Expand Down

0 comments on commit 83086d9

Please sign in to comment.