Skip to content

Commit 82af24f

Browse files
BohwaZcmb69
BohwaZ
authored andcommitted
Implement SQLite3Stmt::getSQL method, returning the original statement SQL, eventually expanded
1 parent 3b0f051 commit 82af24f

File tree

5 files changed

+168
-0
lines changed

5 files changed

+168
-0
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ PHP NEWS
5353
. Lifted requirements to SQLite 3.7.4. (cmb)
5454
. Forbid (un)serialization of SQLite3, SQLite3Stmt and SQLite3Result. (cmb)
5555
. Added support for the SQLite @name notation. (cmb, BohwaZ)
56+
. Added SQLite3Stmt::getSQL() to retrieve the SQL of the statement. (Bohwaz)
5657

5758
- Standard:
5859
. Fixed bug #74764 (Bindto IPv6 works with file_get_contents but fails with

UPGRADING

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ PHP 7.4 UPGRADE NOTES
111111
OpenSSL's X509_verify() function.
112112
See <https://github.com/php/php-src/pull/3624>.
113113

114+
- SQLite3:
115+
. Added SQLite3Stmt::getSQL() to retrieve the SQL of the statement. If TRUE is
116+
passed as parameter, query parameters will be replaced in the return value
117+
by their currently bound value, if libsqlite ≥ 3.14 is used.
118+
114119
========================================
115120
7. New Classes and Interfaces
116121
========================================

ext/sqlite3/sqlite3.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1495,6 +1495,47 @@ static int php_sqlite3_bind_params(php_sqlite3_stmt *stmt_obj) /* {{{ */
14951495
}
14961496
/* }}} */
14971497

1498+
1499+
/* {{{ proto string SQLite3Stmt::getSQL([expanded = false])
1500+
Returns the SQL statement used to prepare the query. If expanded is true, binded parameters and values will be expanded. */
1501+
PHP_METHOD(sqlite3stmt, getSQL)
1502+
{
1503+
php_sqlite3_stmt *stmt_obj;
1504+
zend_bool expanded = 0;
1505+
zval *object = getThis();
1506+
stmt_obj = Z_SQLITE3_STMT_P(object);
1507+
int bind_rc;
1508+
1509+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &expanded) == FAILURE) {
1510+
return;
1511+
}
1512+
1513+
SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
1514+
SQLITE3_CHECK_INITIALIZED_STMT(stmt_obj->stmt, SQLite3Stmt);
1515+
1516+
bind_rc = php_sqlite3_bind_params(stmt_obj);
1517+
1518+
if (bind_rc == FAILURE) {
1519+
RETURN_FALSE;
1520+
}
1521+
1522+
if (expanded) {
1523+
#if SQLITE_VERSION_NUMBER >= 3014000
1524+
char *sql = sqlite3_expanded_sql(stmt_obj->stmt);
1525+
RETVAL_STRING(sql);
1526+
sqlite3_free(sql);
1527+
#else
1528+
php_sqlite3_error(stmt_obj->db_obj, "The expanded parameter requires SQLite3 >= 3.14 and %s is installed", sqlite3_libversion());
1529+
RETURN_FALSE;
1530+
#endif
1531+
} else {
1532+
const char *sql = sqlite3_sql(stmt_obj->stmt);
1533+
RETVAL_STRING(sql);
1534+
}
1535+
}
1536+
/* }}} */
1537+
1538+
14981539
static int register_bound_parameter_to_sqlite(struct php_sqlite3_bound_param *param, php_sqlite3_stmt *stmt) /* {{{ */
14991540
{
15001541
HashTable *hash;
@@ -2009,6 +2050,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3stmt_construct, 0, 0, 1)
20092050
ZEND_ARG_INFO(0, sqlite3)
20102051
ZEND_END_ARG_INFO()
20112052

2053+
ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3stmt_getsql, 0, 0, 0)
2054+
ZEND_ARG_INFO(0, expanded)
2055+
ZEND_END_ARG_INFO()
2056+
20122057
ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3result_columnname, 0, 0, 1)
20132058
ZEND_ARG_INFO(0, column_number)
20142059
ZEND_END_ARG_INFO()
@@ -2064,6 +2109,7 @@ static const zend_function_entry php_sqlite3_stmt_class_methods[] = {
20642109
PHP_ME(sqlite3stmt, bindParam, arginfo_sqlite3stmt_bindparam, ZEND_ACC_PUBLIC)
20652110
PHP_ME(sqlite3stmt, bindValue, arginfo_sqlite3stmt_bindvalue, ZEND_ACC_PUBLIC)
20662111
PHP_ME(sqlite3stmt, readOnly, arginfo_sqlite3_void, ZEND_ACC_PUBLIC)
2112+
PHP_ME(sqlite3stmt, getSQL, arginfo_sqlite3stmt_getsql, ZEND_ACC_PUBLIC)
20672113
PHP_ME(sqlite3stmt, __construct, arginfo_sqlite3stmt_construct, ZEND_ACC_PRIVATE)
20682114
PHP_FE_END
20692115
};
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
--TEST--
2+
SQLite3Stmt::getSQL test
3+
--SKIPIF--
4+
<?php require_once(__DIR__ . '/skipif.inc'); ?>
5+
--FILE--
6+
<?php
7+
8+
require_once(__DIR__ . '/new_db.inc');
9+
10+
$db->enableExceptions(true);
11+
12+
$stmt = $db->prepare('SELECT :a, :b, ?;');
13+
14+
$stmt->bindValue(':a', 42);
15+
$stmt->bindValue(':b', 'php');
16+
$stmt->bindValue(3, 43);
17+
18+
echo "Getting non-expanded SQL statement\n";
19+
var_dump($stmt->getSQL(false));
20+
21+
echo "Execute statement\n";
22+
var_dump($res = $stmt->execute());
23+
24+
echo "Statement result\n";
25+
var_dump($res->fetchArray(SQLITE3_NUM));
26+
27+
echo "Closing DB\n";
28+
var_dump($db->close());
29+
30+
echo "Done\n";
31+
?>
32+
--EXPECTF--
33+
Getting non-expanded SQL statement
34+
string(17) "SELECT :a, :b, ?;"
35+
Execute statement
36+
object(SQLite3Result)#3 (0) {
37+
}
38+
Statement result
39+
array(3) {
40+
[0]=>
41+
int(42)
42+
[1]=>
43+
string(3) "php"
44+
[2]=>
45+
int(43)
46+
}
47+
Closing DB
48+
bool(true)
49+
Done
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
--TEST--
2+
SQLite3Stmt::getSQL expanded test
3+
--SKIPIF--
4+
<?php require_once(__DIR__ . '/skipif.inc');
5+
6+
if (SQLite3::version()['versionNumber'] < 3014000) {
7+
die('skip SQLite < 3.14 installed, requires SQLite >= 3.14');
8+
}
9+
?>
10+
--FILE--
11+
<?php
12+
13+
require_once(__DIR__ . '/new_db.inc');
14+
15+
$db->enableExceptions(true);
16+
17+
$stmt = $db->prepare('SELECT :a, :b, ?;');
18+
19+
$stmt->bindValue(':a', 42);
20+
$stmt->bindValue(':b', 'php');
21+
$stmt->bindValue(3, 43);
22+
23+
echo "Getting expanded SQL statement\n";
24+
var_dump($stmt->getSQL(true));
25+
26+
echo "Execute statement\n";
27+
var_dump($res = $stmt->execute());
28+
29+
echo "Statement result\n";
30+
var_dump($res->fetchArray(SQLITE3_NUM));
31+
32+
$stmt->reset();
33+
34+
echo "Change binded values\n";
35+
$stmt->bindValue(':a', 'TEST');
36+
$stmt->bindValue(':b', '!!!');
37+
$stmt->bindValue(3, 40);
38+
39+
echo "Getting expanded SQL statement\n";
40+
var_dump($stmt->getSQL(true));
41+
42+
echo "Closing DB\n";
43+
var_dump($db->close());
44+
45+
echo "Done\n";
46+
?>
47+
--EXPECTF--
48+
Getting expanded SQL statement
49+
string(21) "SELECT 42, 'php', 43;"
50+
Execute statement
51+
object(SQLite3Result)#3 (0) {
52+
}
53+
Statement result
54+
array(3) {
55+
[0]=>
56+
int(42)
57+
[1]=>
58+
string(3) "php"
59+
[2]=>
60+
int(43)
61+
}
62+
Change binded values
63+
Getting expanded SQL statement
64+
string(25) "SELECT 'TEST', '!!!', 40;"
65+
Closing DB
66+
bool(true)
67+
Done

0 commit comments

Comments
 (0)