]> granicus.if.org Git - php/commitdiff
Implement SQLite3Stmt::getSQL method, returning the original statement SQL, eventuall...
authorBohwaZ <bohwaz@github.com>
Thu, 18 Oct 2018 13:21:10 +0000 (15:21 +0200)
committerChristoph M. Becker <cmbecker69@gmx.de>
Sat, 15 Dec 2018 16:27:33 +0000 (17:27 +0100)
NEWS
UPGRADING
ext/sqlite3/sqlite3.c
ext/sqlite3/tests/sqlite3stmt_getsql.phpt [new file with mode: 0644]
ext/sqlite3/tests/sqlite3stmt_getsql_expanded.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 18ce3217c6819f973638e5a1add5c2adbdda84a0..e389e629f96d9b88fd3f6c8a6b0d3a5d1766d1fc 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -53,6 +53,7 @@ PHP                                                                        NEWS
   . Lifted requirements to SQLite 3.7.4. (cmb)
   . Forbid (un)serialization of SQLite3, SQLite3Stmt and SQLite3Result. (cmb)
   . Added support for the SQLite @name notation. (cmb, BohwaZ)
+  . Added SQLite3Stmt::getSQL() to retrieve the SQL of the statement. (Bohwaz)
 
 - Standard:
   . Fixed bug #74764 (Bindto IPv6 works with file_get_contents but fails with
index 5d6f22b961dfdf662e2ddf4d6b92acc66d4a3652..738c02c15c4537972271eb1893638cefbe2cbdc9 100644 (file)
--- a/UPGRADING
+++ b/UPGRADING
@@ -111,6 +111,11 @@ PHP 7.4 UPGRADE NOTES
     OpenSSL's X509_verify() function.
     See <https://github.com/php/php-src/pull/3624>.
 
+- SQLite3:
+  . Added SQLite3Stmt::getSQL() to retrieve the SQL of the statement. If TRUE is
+    passed as parameter, query parameters will be replaced in the return value
+    by their currently bound value, if libsqlite ≥ 3.14 is used.
+
 ========================================
 7. New Classes and Interfaces
 ========================================
index 27104a5807b6f9d80ae0f1aaebf823ec6739d292..dfe79be82d4825677a6968139e6a3053387d3d22 100644 (file)
@@ -1495,6 +1495,47 @@ static int php_sqlite3_bind_params(php_sqlite3_stmt *stmt_obj) /* {{{ */
 }
 /* }}} */
 
+
+/* {{{ proto string SQLite3Stmt::getSQL([expanded = false])
+   Returns the SQL statement used to prepare the query. If expanded is true, binded parameters and values will be expanded. */
+PHP_METHOD(sqlite3stmt, getSQL)
+{
+       php_sqlite3_stmt *stmt_obj;
+       zend_bool expanded = 0;
+       zval *object = getThis();
+       stmt_obj = Z_SQLITE3_STMT_P(object);
+       int bind_rc;
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &expanded) == FAILURE) {
+               return;
+       }
+
+       SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
+       SQLITE3_CHECK_INITIALIZED_STMT(stmt_obj->stmt, SQLite3Stmt);
+
+       bind_rc = php_sqlite3_bind_params(stmt_obj);
+
+       if (bind_rc == FAILURE) {
+               RETURN_FALSE;
+       }
+
+       if (expanded) {
+#if SQLITE_VERSION_NUMBER >= 3014000
+               char *sql = sqlite3_expanded_sql(stmt_obj->stmt);
+               RETVAL_STRING(sql);
+               sqlite3_free(sql);
+#else
+               php_sqlite3_error(stmt_obj->db_obj, "The expanded parameter requires SQLite3 >= 3.14 and %s is installed", sqlite3_libversion());
+               RETURN_FALSE;
+#endif
+       } else {
+               const char *sql = sqlite3_sql(stmt_obj->stmt);
+               RETVAL_STRING(sql);
+       }
+}
+/* }}} */
+
+
 static int register_bound_parameter_to_sqlite(struct php_sqlite3_bound_param *param, php_sqlite3_stmt *stmt) /* {{{ */
 {
        HashTable *hash;
@@ -2009,6 +2050,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3stmt_construct, 0, 0, 1)
        ZEND_ARG_INFO(0, sqlite3)
 ZEND_END_ARG_INFO()
 
+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3stmt_getsql, 0, 0, 0)
+       ZEND_ARG_INFO(0, expanded)
+ZEND_END_ARG_INFO()
+
 ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3result_columnname, 0, 0, 1)
        ZEND_ARG_INFO(0, column_number)
 ZEND_END_ARG_INFO()
@@ -2064,6 +2109,7 @@ static const zend_function_entry php_sqlite3_stmt_class_methods[] = {
        PHP_ME(sqlite3stmt, bindParam,  arginfo_sqlite3stmt_bindparam, ZEND_ACC_PUBLIC)
        PHP_ME(sqlite3stmt, bindValue,  arginfo_sqlite3stmt_bindvalue, ZEND_ACC_PUBLIC)
        PHP_ME(sqlite3stmt, readOnly,   arginfo_sqlite3_void, ZEND_ACC_PUBLIC)
+       PHP_ME(sqlite3stmt, getSQL,             arginfo_sqlite3stmt_getsql, ZEND_ACC_PUBLIC)
        PHP_ME(sqlite3stmt, __construct, arginfo_sqlite3stmt_construct, ZEND_ACC_PRIVATE)
        PHP_FE_END
 };
diff --git a/ext/sqlite3/tests/sqlite3stmt_getsql.phpt b/ext/sqlite3/tests/sqlite3stmt_getsql.phpt
new file mode 100644 (file)
index 0000000..ef9e76b
--- /dev/null
@@ -0,0 +1,49 @@
+--TEST--
+SQLite3Stmt::getSQL test
+--SKIPIF--
+<?php require_once(__DIR__ . '/skipif.inc'); ?>
+--FILE--
+<?php
+
+require_once(__DIR__ . '/new_db.inc');
+
+$db->enableExceptions(true);
+
+$stmt = $db->prepare('SELECT :a, :b, ?;');
+
+$stmt->bindValue(':a', 42);
+$stmt->bindValue(':b', 'php');
+$stmt->bindValue(3, 43);
+
+echo "Getting non-expanded SQL statement\n";
+var_dump($stmt->getSQL(false));
+
+echo "Execute statement\n";
+var_dump($res = $stmt->execute());
+
+echo "Statement result\n";
+var_dump($res->fetchArray(SQLITE3_NUM));
+
+echo "Closing DB\n";
+var_dump($db->close());
+
+echo "Done\n";
+?>
+--EXPECTF--
+Getting non-expanded SQL statement
+string(17) "SELECT :a, :b, ?;"
+Execute statement
+object(SQLite3Result)#3 (0) {
+}
+Statement result
+array(3) {
+  [0]=>
+  int(42)
+  [1]=>
+  string(3) "php"
+  [2]=>
+  int(43)
+}
+Closing DB
+bool(true)
+Done
diff --git a/ext/sqlite3/tests/sqlite3stmt_getsql_expanded.phpt b/ext/sqlite3/tests/sqlite3stmt_getsql_expanded.phpt
new file mode 100644 (file)
index 0000000..3f9fe84
--- /dev/null
@@ -0,0 +1,67 @@
+--TEST--
+SQLite3Stmt::getSQL expanded test
+--SKIPIF--
+<?php require_once(__DIR__ . '/skipif.inc');
+
+if (SQLite3::version()['versionNumber'] < 3014000) {
+       die('skip SQLite < 3.14 installed, requires SQLite >= 3.14');
+}
+?>
+--FILE--
+<?php
+
+require_once(__DIR__ . '/new_db.inc');
+
+$db->enableExceptions(true);
+
+$stmt = $db->prepare('SELECT :a, :b, ?;');
+
+$stmt->bindValue(':a', 42);
+$stmt->bindValue(':b', 'php');
+$stmt->bindValue(3, 43);
+
+echo "Getting expanded SQL statement\n";
+var_dump($stmt->getSQL(true));
+
+echo "Execute statement\n";
+var_dump($res = $stmt->execute());
+
+echo "Statement result\n";
+var_dump($res->fetchArray(SQLITE3_NUM));
+
+$stmt->reset();
+
+echo "Change binded values\n";
+$stmt->bindValue(':a', 'TEST');
+$stmt->bindValue(':b', '!!!');
+$stmt->bindValue(3, 40);
+
+echo "Getting expanded SQL statement\n";
+var_dump($stmt->getSQL(true));
+
+echo "Closing DB\n";
+var_dump($db->close());
+
+echo "Done\n";
+?>
+--EXPECTF--
+Getting expanded SQL statement
+string(21) "SELECT 42, 'php', 43;"
+Execute statement
+object(SQLite3Result)#3 (0) {
+}
+Statement result
+array(3) {
+  [0]=>
+  int(42)
+  [1]=>
+  string(3) "php"
+  [2]=>
+  int(43)
+}
+Change binded values
+Getting expanded SQL statement
+string(25) "SELECT 'TEST', '!!!', 40;"
+Closing DB
+bool(true)
+Done