From 73635271d4a02a95c7ec6fce79db8af6fd4baa39 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Wed, 20 Apr 2016 00:08:28 +0200 Subject: [PATCH] Allow arrays inside prepares for multiple equally named parameters --- .travis.yml | 8 ++++++-- lib/Stmt.php | 25 ++++++++++++++++--------- test/Mysql/ConnectionTest.php | 7 +++++-- 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index 52a0dd3..6a6602d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,15 +1,19 @@ language: php php: + - nightly - 7.0 - 5.6 - 5.5 - before_script: - composer install - mysqld --version - echo ' test/phpunit_bootstrap.php - mysql -u root -e "CREATE DATABASE connectiontest; CREATE TABLE connectiontest.main SELECT 1 AS a, 2 AS b; INSERT INTO connectiontest.main VALUES (5, 6);" -script: $(php -r 'if (PHP_MAJOR_VERSION >= 7) echo "phpdbg -qrr"; else echo "php";') vendor/bin/phpunit -c phpunit.xml --coverage-text \ No newline at end of file +script: $(php -r 'if (PHP_MAJOR_VERSION >= 7) echo "phpdbg -qrr"; else echo "php";') vendor/bin/phpunit -c phpunit.xml --coverage-text + +cache: + directories: + - $HOME/.composer/cache \ No newline at end of file diff --git a/lib/Stmt.php b/lib/Stmt.php index caecc9b..53fcb19 100644 --- a/lib/Stmt.php +++ b/lib/Stmt.php @@ -105,19 +105,26 @@ public function bind($paramId, $data) { } public function execute($data = []) { - if (count($data + $this->prebound) != $this->paramCount + count($this->named) - count($this->named, COUNT_RECURSIVE)) { - throw new \Exception("Required arguments for executing prepared statement mismatch"); - } - $prebound = $args = []; for ($unnamed = $i = 0; $i < $this->paramCount; $i++) { if (isset($this->named[$i])) { - if (array_key_exists($this->named[$i], $data)) { - $args[$i] = $data[$this->named[$i]]; - } elseif (!isset($this->prebound[$this->named[$i]])) { - throw new \Exception("Named parameter {$this->named[$i]} missing for executing prepared statement"); + $name = $this->named[$i]; + if (array_key_exists($name, $data) && $data[$name] !== []) { + if (\is_array($data[$name])) { + $args[$i] = reset($data[$name]); + unset($data[$name][key($data[$name])]); + } else { + $args[$i] = $data[$name]; + unset($data[$name]); + } + } elseif (!isset($this->prebound[$name])) { + if ($data[$name] === []) { + throw new \Exception("Named parameter $name is not providing enough elements"); + } else { + throw new \Exception("Named parameter $name missing for executing prepared statement"); + } } else { - $prebound[$i] = $this->prebound[$this->named[$i]]; + $prebound[$i] = $this->prebound[$name]; } } elseif (array_key_exists($unnamed, $data)) { $args[$i] = $data[$unnamed]; diff --git a/test/Mysql/ConnectionTest.php b/test/Mysql/ConnectionTest.php index f317a7b..cfc773f 100644 --- a/test/Mysql/ConnectionTest.php +++ b/test/Mysql/ConnectionTest.php @@ -62,7 +62,7 @@ function testQueryFetchRow() { $this->assertEquals($got, [[1], [2], [3]]); }); } - + function testMultiStmt() { \Amp\reactor(\Amp\driver()); \Amp\run(function() { @@ -102,7 +102,7 @@ function testPrepared() { $db->connect(); $db->query("CREATE TEMPORARY TABLE tmp SELECT 1 AS a, 2 AS b"); - $db->query("INSERT INTO tmp VALUES (5, 6), (8, 9)"); + $db->query("INSERT INTO tmp VALUES (5, 6), (8, 9), (10, 11), (12, 13)"); $stmt = (yield $db->prepare("SELECT * FROM tmp WHERE a = ? OR b = :num")); $base = [ @@ -123,6 +123,9 @@ function testPrepared() { $result = (yield $db->prepare("SELECT * FROM tmp WHERE a = ? OR b = ?", [5, 8])); $this->assertEquals((yield $result->rowCount()), 1); + $result = (yield $db->prepare("SELECT * FROM tmp WHERE a = :a OR b = ? OR a = :a", ["a" => [5, 10], 9])); + $this->assertEquals((yield $result->rowCount()), 3); + $stmt = (yield $db->prepare("INSERT INTO tmp VALUES (:foo, :bar)")); $stmt->bind("foo", 5); $result = (yield $stmt->execute(["bar" => 9]));