From f19f683e38109c1517f399c7f90950e1aaaac9c4 Mon Sep 17 00:00:00 2001 From: "J. King" Date: Wed, 1 Mar 2017 23:12:42 -0500 Subject: [PATCH] Make it possible to redefine Statement type binds --- lib/Db/Statement.php | 8 ++- lib/Db/StatementSQLite3.php | 66 ++++++++++++--------- tests/Db/SQLite3/TestDbStatementSQLite3.php | 18 ++++++ 3 files changed, 62 insertions(+), 30 deletions(-) diff --git a/lib/Db/Statement.php b/lib/Db/Statement.php index a127a89..0b028a5 100644 --- a/lib/Db/Statement.php +++ b/lib/Db/Statement.php @@ -3,7 +3,9 @@ declare(strict_types=1); namespace JKingWeb\NewsSync\Db; interface Statement { - function __invoke(&...$values); // alias of run() - function run(&...$values): Result; - function runArray(array &$values): Result; + function __invoke(...$values); // alias of run() + function run(...$values): Result; + function runArray(array $values): Result; + function rebind(...$bindings): bool; + function rebindArray(array $bindings): bool; } \ No newline at end of file diff --git a/lib/Db/StatementSQLite3.php b/lib/Db/StatementSQLite3.php index 50aa40a..006b83e 100644 --- a/lib/Db/StatementSQLite3.php +++ b/lib/Db/StatementSQLite3.php @@ -10,9 +10,47 @@ class StatementSQLite3 implements Statement { public function __construct($db, $st, array $bindings = []) { $this->db = $db; $this->st = $st; + $this->rebindArray($bindings); + } + + public function __destruct() { + $this->st->close(); + unset($this->st); + } + + public function __invoke(...$values) { + return $this->runArray($values); + } + + public function run(...$values): Result { + return $this->runArray($values); + } + + public function runArray(array $values = null): Result { + $this->st->clear(); + $l = sizeof($values); + for($a = 0; $a < $l; $a++) { + if($values[$a]===null) { + $type = \SQLITE3_NULL; + } else { + $type = (array_key_exists($a,$this->types)) ? $this->types[$a] : \SQLITE3_TEXT; + } + $this->st->bindParam($a+1, $values[$a], $type); + } + return new ResultSQLite3($this->st->execute(), $this->db->changes(), $this); + } + + public function rebind(...$bindings): bool { + return $this->rebindArray($bindings); + } + + public function rebindArray(array $bindings): bool { $this->types = []; foreach($bindings as $binding) { switch(trim(strtolower($binding))) { + case "null": + case "nil": + $this->types[] = \SQLITE3_NULL; break; case "int": case "integer": $this->types[] = \SQLITE3_INTEGER; break; @@ -42,32 +80,6 @@ class StatementSQLite3 implements Statement { $this->types[] = \SQLITE3_TEXT; break; } } - } - - public function __destruct() { - $this->st->close(); - unset($this->st); - } - - public function __invoke(&...$values) { - return $this->runArray($values); - } - - public function run(&...$values): Result { - return $this->runArray($values); - } - - public function runArray(array &$values = null): Result { - $this->st->clear(); - $l = sizeof($values); - for($a = 0; $a < $l; $a++) { - if($values[$a]===null) { - $type = \SQLITE3_NULL; - } else { - $type = (array_key_exists($a,$this->types)) ? $this->types[$a] : \SQLITE3_TEXT; - } - $this->st->bindParam($a+1, $values[$a], $type); - } - return new ResultSQLite3($this->st->execute(), $this->db->changes(), $this); + return true; } } \ No newline at end of file diff --git a/tests/Db/SQLite3/TestDbStatementSQLite3.php b/tests/Db/SQLite3/TestDbStatementSQLite3.php index 2bba457..3254b09 100644 --- a/tests/Db/SQLite3/TestDbStatementSQLite3.php +++ b/tests/Db/SQLite3/TestDbStatementSQLite3.php @@ -28,4 +28,22 @@ class TestDbStatementSQLite3 extends \PHPUnit\Framework\TestCase { function testConstructStatement() { $this->assertInstanceOf(Db\StatementSQLite3::class, new Db\StatementSQLite3($this->c, $this->s)); } + + function testBindMissingValue() { + $s = new Db\StatementSQLite3($this->c, $this->s); + $val = $s->runArray()->get()['value']; + $this->assertSame(null, $val); + } + + function testBindNull() { + $s = new Db\StatementSQLite3($this->c, $this->s); + $val = $s->runArray([null])->get()['value']; + $this->assertSame(null, $val); + } + + function testBindInteger() { + $s = new Db\StatementSQLite3($this->c, $this->s, ["int"]); + $val = $s->runArray([2112])->get()['value']; + $this->assertSame(2112, $val); + } } \ No newline at end of file