From fcb764c45569ba11fb1b816d804805ac2b1db0f4 Mon Sep 17 00:00:00 2001 From: "Paul M. Jones" Date: Tue, 21 Mar 2017 14:26:44 -0500 Subject: [PATCH 01/10] remove addWhere() in favor of addClauseCondWithBind() --- src/AbstractQuery.php | 22 ---------------------- src/Common/WhereTrait.php | 20 ++------------------ 2 files changed, 2 insertions(+), 40 deletions(-) diff --git a/src/AbstractQuery.php b/src/AbstractQuery.php index f404b95..c877d50 100644 --- a/src/AbstractQuery.php +++ b/src/AbstractQuery.php @@ -270,28 +270,6 @@ public function resetFlags() return $this; } - /** - * - * Adds a WHERE condition to the query by AND or OR. If the condition has - * ?-placeholders, additional arguments to the method will be bound to - * those placeholders sequentially. - * - * @param string $andor Add the condition using this operator, typically - * 'AND' or 'OR'. - * - * @param string $cond The WHERE condition. - * - * @param array ...$bind arguments to bind to placeholders - * - * @return $this - * - */ - protected function addWhere($andor, $cond, ...$bind) - { - $this->addClauseCondWithBind('where', $andor, $cond, $bind); - return $this; - } - /** * * Adds conditions and binds values to a clause. diff --git a/src/Common/WhereTrait.php b/src/Common/WhereTrait.php index 512d0bb..cb5ddf0 100644 --- a/src/Common/WhereTrait.php +++ b/src/Common/WhereTrait.php @@ -31,7 +31,7 @@ trait WhereTrait */ public function where($cond, ...$bind) { - $this->addWhere('AND', $cond, ...$bind); + $this->addClauseCondWithBind('where', 'AND', $cond, $bind); return $this; } @@ -51,23 +51,7 @@ public function where($cond, ...$bind) */ public function orWhere($cond, ...$bind) { - $this->addWhere('OR', $cond, ...$bind); + $this->addClauseCondWithBind('where', 'OR', $cond, $bind); return $this; } - - /** - * - * Adds a WHERE condition to the query by AND or OR. If the condition has - * ?-placeholders, additional arguments to the method will be bound to - * those placeholders sequentially. - * - * @param string $andor Add the condition using this operator, typically - * 'AND' or 'OR'. - * @param string $cond The WHERE condition. - * @param mixed ...$bind arguments to bind to placeholders - * - * @return $this - * - */ - abstract protected function addWhere($andor, $cond, ...$bind); } From 6a3d98e2bb6a4f790b130aa2ed033dde2814434b Mon Sep 17 00:00:00 2001 From: "Paul M. Jones" Date: Tue, 21 Mar 2017 15:07:25 -0500 Subject: [PATCH 02/10] where() and having() now support only named binding --- src/AbstractQuery.php | 9 ++++-- src/Common/Select.php | 16 ++++------ src/Common/SelectInterface.php | 29 ++++-------------- src/Common/WhereInterface.php | 10 +++--- src/Common/WhereTrait.php | 14 ++++----- tests/Common/DeleteTest.php | 4 +-- tests/Common/SelectTest.php | 56 ++++++++++++++++++---------------- tests/Common/UpdateTest.php | 6 ++-- tests/Mysql/DeleteTest.php | 12 ++++---- tests/Mysql/UpdateTest.php | 8 ++--- tests/Pgsql/DeleteTest.php | 4 +-- tests/Pgsql/UpdateTest.php | 4 +-- tests/Sqlite/DeleteTest.php | 4 +-- tests/Sqlite/UpdateTest.php | 26 ++++++++-------- 14 files changed, 95 insertions(+), 107 deletions(-) diff --git a/src/AbstractQuery.php b/src/AbstractQuery.php index c877d50..06ef30e 100644 --- a/src/AbstractQuery.php +++ b/src/AbstractQuery.php @@ -281,7 +281,7 @@ public function resetFlags() * 'AND' or 'OR'. * * @param string $cond The WHERE condition. - + * * @param array $bind arguments to bind to placeholders * * @return null @@ -289,15 +289,18 @@ public function resetFlags() */ protected function addClauseCondWithBind($clause, $andor, $cond, $bind) { - $cond = $this->rebuildCondAndBindValues($cond, $bind); + $cond = $this->quoter->quoteNamesIn($cond); - // add condition to clause; eg $this->where or $this->having $clause =& $this->$clause; if ($clause) { $clause[] = "$andor $cond"; } else { $clause[] = $cond; } + + foreach ($bind as $key => $val) { + $this->bindValue($key, $val); + } } /** diff --git a/src/Common/Select.php b/src/Common/Select.php index 4734f36..192532d 100644 --- a/src/Common/Select.php +++ b/src/Common/Select.php @@ -635,18 +635,16 @@ public function groupBy(array $spec) /** * - * Adds a HAVING condition to the query by AND. If the condition has - * ?-placeholders, additional arguments to the method will be bound to - * those placeholders sequentially. + * Adds a HAVING condition to the query by AND. * * @param string $cond The HAVING condition. * - * @param array ...$bind arguments to bind to placeholders + * @param array $bind arguments to bind to placeholders * * @return $this * */ - public function having($cond, ...$bind) + public function having($cond, array $bind = []) { $this->addClauseCondWithBind('having', 'AND', $cond, $bind); return $this; @@ -654,20 +652,18 @@ public function having($cond, ...$bind) /** * - * Adds a HAVING condition to the query by AND. If the condition has - * ?-placeholders, additional arguments to the method will be bound to - * those placeholders sequentially. + * Adds a HAVING condition to the query by OR. * * @param string $cond The HAVING condition. * - * @param array ...$bind arguments to bind to placeholders + * @param array $bind arguments to bind to placeholders * * @return $this * * @see having() * */ - public function orHaving($cond, ...$bind) + public function orHaving($cond, array $bind = []) { $this->addClauseCondWithBind('having', 'OR', $cond, $bind); return $this; diff --git a/src/Common/SelectInterface.php b/src/Common/SelectInterface.php index d7e9ac5..e18c367 100644 --- a/src/Common/SelectInterface.php +++ b/src/Common/SelectInterface.php @@ -244,48 +244,31 @@ public function groupBy(array $spec); /** * - * Adds a HAVING condition to the query by AND; if a value is passed as - * the second param, it will be quoted and replaced into the condition - * wherever a question-mark appears. - * - * Array values are quoted and comma-separated. - * - * {{code: php - * // simplest but non-secure - * $select->having("COUNT(id) = $count"); - * - * // secure - * $select->having('COUNT(id) = ?', $count); - * - * // equivalent security with named binding - * $select->having('COUNT(id) = :count'); - * $select->bind('count', $count); - * }} + * Adds a HAVING condition to the query by AND. * * @param string $cond The HAVING condition. * - * @param array ...$bind arguments to bind to placeholders + * @param array $bind Values to be bound to placeholders. * * @return $this * */ - public function having($cond, ...$bind); + public function having($cond, array $bind = []); /** * - * Adds a HAVING condition to the query by AND; otherwise identical to - * `having()`. + * Adds a HAVING condition to the query by OR. * * @param string $cond The HAVING condition. * - * @param array ...$bind arguments to bind to placeholders + * @param array $bind Values to be bound to placeholders. * * @return $this * * @see having() * */ - public function orHaving($cond, ...$bind); + public function orHaving($cond, array $bind = []); /** * diff --git a/src/Common/WhereInterface.php b/src/Common/WhereInterface.php index 680ba21..236e3be 100644 --- a/src/Common/WhereInterface.php +++ b/src/Common/WhereInterface.php @@ -24,12 +24,13 @@ interface WhereInterface * those placeholders sequentially. * * @param string $cond The WHERE condition. - * @param mixed ...$bind arguments to be bound to placeholders + * + * @param array $bind Values to be bound to placeholders. * * @return $this * */ - public function where($cond, ...$bind); + public function where($cond, array $bind = []); /** * @@ -38,12 +39,13 @@ public function where($cond, ...$bind); * those placeholders sequentially. * * @param string $cond The WHERE condition. - * @param mixed ...$bind arguments to be bound to placeholders + * + * @param array $bind Values to be bound to placeholders. * * @return $this * * @see where() * */ - public function orWhere($cond, ...$bind); + public function orWhere($cond, array $bind = []); } diff --git a/src/Common/WhereTrait.php b/src/Common/WhereTrait.php index cb5ddf0..5c4fde0 100644 --- a/src/Common/WhereTrait.php +++ b/src/Common/WhereTrait.php @@ -19,17 +19,16 @@ trait WhereTrait { /** * - * Adds a WHERE condition to the query by AND. If the condition has - * ?-placeholders, additional arguments to the method will be bound to - * those placeholders sequentially. + * Adds a WHERE condition to the query by AND. * * @param string $cond The WHERE condition. - * @param mixed ...$bind arguments to be bound to placeholders + * + * @param array $bind Values to be bound to placeholders * * @return $this * */ - public function where($cond, ...$bind) + public function where($cond, array $bind = []) { $this->addClauseCondWithBind('where', 'AND', $cond, $bind); return $this; @@ -42,14 +41,15 @@ public function where($cond, ...$bind) * those placeholders sequentially. * * @param string $cond The WHERE condition. - * @param mixed ...$bind arguments to be bound to placeholders + * + * @param array $bind Values to be bound to placeholders * * @return $this * * @see where() * */ - public function orWhere($cond, ...$bind) + public function orWhere($cond, array $bind = []) { $this->addClauseCondWithBind('where', 'OR', $cond, $bind); return $this; diff --git a/tests/Common/DeleteTest.php b/tests/Common/DeleteTest.php index 94bab92..1b3fa51 100644 --- a/tests/Common/DeleteTest.php +++ b/tests/Common/DeleteTest.php @@ -10,8 +10,8 @@ class DeleteTest extends AbstractQueryTest public function testCommon() { $this->query->from('t1') - ->where('foo = ?', 'bar') - ->where('baz = ?', 'dib') + ->where('foo = :_1_', ['_1_' => 'bar']) + ->where('baz = :_2_', ['_2_' => 'dib']) ->orWhere('zim = gir'); $actual = $this->query->__toString(); diff --git a/tests/Common/SelectTest.php b/tests/Common/SelectTest.php index 84a28e9..a834c08 100644 --- a/tests/Common/SelectTest.php +++ b/tests/Common/SelectTest.php @@ -204,11 +204,11 @@ public function testFromSubSelectObject() $sub = $this->newQuery(); $sub->cols(array('*')) ->from('t2') - ->where('foo = ?', 'bar'); + ->where('foo = :foo', ['foo' => 'bar']); $this->query->cols(array('*')) ->fromSubSelect($sub, 'a2') - ->where('a2.baz = ?', 'dib'); + ->where('a2.baz = :baz', ['baz' => 'dib']); $expect = ' SELECT @@ -220,10 +220,10 @@ public function testFromSubSelectObject() FROM <> WHERE - foo = :_1_1_ + foo = :foo ) AS <> WHERE - <>.<> = :_2_ + <>.<> = :baz '; $actual = $this->query->__toString(); @@ -419,12 +419,12 @@ public function testDuplicateJoinSubSelectRef() public function testJoinSubSelectObject() { $sub = $this->newQuery(); - $sub->cols(array('*'))->from('t2')->where('foo = ?', 'bar'); + $sub->cols(array('*'))->from('t2')->where('foo = :foo', ['foo' => 'bar']); $this->query->cols(array('*')); $this->query->from('t1'); $this->query->joinSubSelect('left', $sub, 'a3', 't2.c1 = a3.c1'); - $this->query->where('baz = ?', 'dib'); + $this->query->where('baz = :baz', ['baz' => 'dib']); $expect = ' SELECT @@ -437,10 +437,10 @@ public function testJoinSubSelectObject() FROM <> WHERE - foo = :_1_1_ + foo = :foo ) AS <> ON <>.<> = <>.<> WHERE - baz = :_2_ + baz = :baz '; $actual = $this->query->__toString(); $this->assertSameSql($expect, $actual); @@ -492,20 +492,20 @@ public function testWhere() { $this->query->cols(array('*')); $this->query->where('c1 = c2') - ->where('c3 = ?', 'foo'); + ->where('c3 = :c3', ['c3' => 'foo']); $expect = ' SELECT * WHERE c1 = c2 - AND c3 = :_1_ + AND c3 = :c3 '; $actual = $this->query->__toString(); $this->assertSameSql($expect, $actual); $actual = $this->query->getBindValues(); - $expect = array('_1_' => 'foo'); + $expect = ['c3' => 'foo']; $this->assertSame($expect, $actual); } @@ -513,21 +513,21 @@ public function testOrWhere() { $this->query->cols(array('*')); $this->query->orWhere('c1 = c2') - ->orWhere('c3 = ?', 'foo'); + ->orWhere('c3 = :c3', ['c3' => 'foo']); $expect = ' SELECT * WHERE c1 = c2 - OR c3 = :_1_ + OR c3 = :c3 '; $actual = $this->query->__toString(); $this->assertSameSql($expect, $actual); $actual = $this->query->getBindValues(); - $expect = array('_1_' => 'foo'); + $expect = ['c3' => 'foo']; $this->assertSame($expect, $actual); } @@ -551,20 +551,20 @@ public function testHaving() { $this->query->cols(array('*')); $this->query->having('c1 = c2') - ->having('c3 = ?', 'foo'); + ->having('c3 = :c3', ['c3' => 'foo']); $expect = ' SELECT * HAVING c1 = c2 - AND c3 = :_1_ + AND c3 = :c3 '; $actual = $this->query->__toString(); $this->assertSameSql($expect, $actual); $actual = $this->query->getBindValues(); - $expect = array('_1_' => 'foo'); + $expect = ['c3' => 'foo']; $this->assertSame($expect, $actual); } @@ -572,20 +572,20 @@ public function testOrHaving() { $this->query->cols(array('*')); $this->query->orHaving('c1 = c2') - ->orHaving('c3 = ?', 'foo'); + ->orHaving('c3 = :c3', ['c3' => 'foo']); $expect = ' SELECT * HAVING c1 = c2 - OR c3 = :_1_ + OR c3 = :c3 '; $actual = $this->query->__toString(); $this->assertSameSql($expect, $actual); $actual = $this->query->getBindValues(); - $expect = array('_1_' => 'foo'); + $expect = ['c3' => 'foo']; $this->assertSame($expect, $actual); } @@ -712,24 +712,24 @@ public function testUnionAll() public function testAutobind() { // do these out of order - $this->query->having('baz IN (?)', array('dib', 'zim', 'gir')); - $this->query->where('foo = ?', 'bar'); + $this->query->having('baz IN (:baz)', ['baz' => ['dib', 'zim', 'gir']]); + $this->query->where('foo = :foo', ['foo' => 'bar']); $this->query->cols(array('*')); $expect = ' SELECT * WHERE - foo = :_2_ + foo = :foo HAVING - baz IN (:_1_) + baz IN (:baz) '; $actual = $this->query->__toString(); $this->assertSameSql($expect, $actual); $expect = array( - '_1_' => array('dib', 'zim', 'gir'), - '_2_' => 'bar', + 'baz' => array('dib', 'zim', 'gir'), + 'foo' => 'bar', ); $actual = $this->query->getBindValues(); $this->assertSame($expect, $actual); @@ -813,6 +813,8 @@ public function testRemoveColsNotFound() public function testIssue47() { + $this->markTestIncomplete("Finish subselect-as-condition."); + // sub select $sub = $this->newQuery() ->cols(array('*')) @@ -882,6 +884,8 @@ public function testIssue49() public function testWhereSubSelectImportsBoundValues() { + $this->markTestIncomplete("Finish subselect-as-condition."); + // sub select $sub = $this->newQuery() ->cols(array('*')) diff --git a/tests/Common/UpdateTest.php b/tests/Common/UpdateTest.php index 9b40919..aa85718 100644 --- a/tests/Common/UpdateTest.php +++ b/tests/Common/UpdateTest.php @@ -10,12 +10,12 @@ class UpdateTest extends AbstractQueryTest public function testCommon() { $this->query->table('t1') - ->cols(array('c1', 'c2')) + ->cols(['c1', 'c2']) ->col('c3') ->set('c4', null) ->set('c5', 'NOW()') - ->where('foo = ?', 'bar') - ->where('baz = ?', 'dib') + ->where('foo = :_1_', ['_1_' => 'bar']) + ->where('baz = :_2_', ['_2_' => 'dib']) ->orWhere('zim = gir'); $actual = $this->query->__toString(); diff --git a/tests/Mysql/DeleteTest.php b/tests/Mysql/DeleteTest.php index c405f20..b6599eb 100644 --- a/tests/Mysql/DeleteTest.php +++ b/tests/Mysql/DeleteTest.php @@ -36,8 +36,8 @@ public function testLowPriority() { $this->query->lowPriority() ->from('t1') - ->where('foo = ?', 'bar') - ->where('baz = ?', 'dib') + ->where('foo = :_1_', ['_1_' => 'bar']) + ->where('baz = :_2_', ['_2_' => 'dib']) ->orWhere('zim = gir'); $actual = $this->query->__toString(); @@ -56,8 +56,8 @@ public function testQuick() { $this->query->quick() ->from('t1') - ->where('foo = ?', 'bar') - ->where('baz = ?', 'dib') + ->where('foo = :_1_', ['_1_' => 'bar']) + ->where('baz = :_2_', ['_2_' => 'dib']) ->orWhere('zim = gir'); $actual = $this->query->__toString(); @@ -76,8 +76,8 @@ public function testIgnore() { $this->query->ignore() ->from('t1') - ->where('foo = ?', 'bar') - ->where('baz = ?', 'dib') + ->where('foo = :_1_', ['_1_' => 'bar']) + ->where('baz = :_2_', ['_2_' => 'dib']) ->orWhere('zim = gir'); $actual = $this->query->__toString(); diff --git a/tests/Mysql/UpdateTest.php b/tests/Mysql/UpdateTest.php index d8cb7f2..9794382 100644 --- a/tests/Mysql/UpdateTest.php +++ b/tests/Mysql/UpdateTest.php @@ -49,8 +49,8 @@ public function testLowPriority() ->cols(array('c1', 'c2', 'c3')) ->set('c4', null) ->set('c5', 'NOW()') - ->where('foo = ?', 'bar') - ->where('baz = ?', 'dib') + ->where('foo = :_1_', ['_1_' => 'bar']) + ->where('baz = :_2_', ['_2_' => 'dib']) ->orWhere('zim = gir') ->limit(5); @@ -73,8 +73,8 @@ public function testIgnore() ->cols(array('c1', 'c2', 'c3')) ->set('c4', null) ->set('c5', 'NOW()') - ->where('foo = ?', 'bar') - ->where('baz = ?', 'dib') + ->where('foo = :_1_', ['_1_' => 'bar']) + ->where('baz = :_2_', ['_2_' => 'dib']) ->orWhere('zim = gir') ->limit(5); diff --git a/tests/Pgsql/DeleteTest.php b/tests/Pgsql/DeleteTest.php index 19f1cd3..2f9fdce 100644 --- a/tests/Pgsql/DeleteTest.php +++ b/tests/Pgsql/DeleteTest.php @@ -10,8 +10,8 @@ class DeleteTest extends Common\DeleteTest public function testReturning() { $this->query->from('t1') - ->where('foo = ?', 'bar') - ->where('baz = ?', 'dib') + ->where('foo = :_1_', ['_1_' => 'bar']) + ->where('baz = :_2_', ['_2_' => 'dib']) ->orWhere('zim = gir') ->returning(array('foo', 'baz', 'zim')); diff --git a/tests/Pgsql/UpdateTest.php b/tests/Pgsql/UpdateTest.php index 0fb2637..057cf10 100644 --- a/tests/Pgsql/UpdateTest.php +++ b/tests/Pgsql/UpdateTest.php @@ -13,8 +13,8 @@ public function testReturning() ->cols(array('c1', 'c2', 'c3')) ->set('c4', null) ->set('c5', 'NOW()') - ->where('foo = ?', 'bar') - ->where('baz = ?', 'dib') + ->where('foo = :_1_', ['_1_' => 'bar']) + ->where('baz = :_2_', ['_2_' => 'dib']) ->orWhere('zim = gir') ->returning(array('c1', 'c2')) ->returning(array('c3')); diff --git a/tests/Sqlite/DeleteTest.php b/tests/Sqlite/DeleteTest.php index f66f066..2dae9db 100644 --- a/tests/Sqlite/DeleteTest.php +++ b/tests/Sqlite/DeleteTest.php @@ -10,8 +10,8 @@ class DeleteTest extends Common\DeleteTest public function testOrderLimit() { $this->query->from('t1') - ->where('foo = ?', 'bar') - ->where('baz = ?', 'dib') + ->where('foo = :_1_', ['_1_' => 'bar']) + ->where('baz = :_2_', ['_2_' => 'dib']) ->orWhere('zim = gir') ->orderBy(array('zim DESC')) ->limit(5) diff --git a/tests/Sqlite/UpdateTest.php b/tests/Sqlite/UpdateTest.php index df5392f..4f841c2 100644 --- a/tests/Sqlite/UpdateTest.php +++ b/tests/Sqlite/UpdateTest.php @@ -29,8 +29,8 @@ public function testOrderLimit() ->cols(array('c1', 'c2', 'c3')) ->set('c4', null) ->set('c5', 'NOW()') - ->where('foo = ?', 'bar') - ->where('baz = ?', 'dib') + ->where('foo = :_1_', ['_1_' => 'bar']) + ->where('baz = :_2_', ['_2_' => 'dib']) ->orWhere('zim = gir') ->orderBy(array('zim DESC', 'baz ASC')) ->limit(5) @@ -71,8 +71,8 @@ public function testOrAbort() ->cols(array('c1', 'c2', 'c3')) ->set('c4', null) ->set('c5', 'NOW()') - ->where('foo = ?', 'bar') - ->where('baz = ?', 'dib') + ->where('foo = :_1_', ['_1_' => 'bar']) + ->where('baz = :_2_', ['_2_' => 'dib']) ->orWhere('zim = gir') ->limit(5); @@ -95,8 +95,8 @@ public function testOrFail() ->cols(array('c1', 'c2', 'c3')) ->set('c4', null) ->set('c5', 'NOW()') - ->where('foo = ?', 'bar') - ->where('baz = ?', 'dib') + ->where('foo = :_1_', ['_1_' => 'bar']) + ->where('baz = :_2_', ['_2_' => 'dib']) ->orWhere('zim = gir') ->limit(5); @@ -119,8 +119,8 @@ public function testOrIgnore() ->cols(array('c1', 'c2', 'c3')) ->set('c4', null) ->set('c5', 'NOW()') - ->where('foo = ?', 'bar') - ->where('baz = ?', 'dib') + ->where('foo = :_1_', ['_1_' => 'bar']) + ->where('baz = :_2_', ['_2_' => 'dib']) ->orWhere('zim = gir') ->limit(5); @@ -143,8 +143,8 @@ public function testOrReplace() ->cols(array('c1', 'c2', 'c3')) ->set('c4', null) ->set('c5', 'NOW()') - ->where('foo = ?', 'bar') - ->where('baz = ?', 'dib') + ->where('foo = :_1_', ['_1_' => 'bar']) + ->where('baz = :_2_', ['_2_' => 'dib']) ->orWhere('zim = gir') ->limit(5); @@ -167,8 +167,8 @@ public function testOrRollback() ->cols(array('c1', 'c2', 'c3')) ->set('c4', null) ->set('c5', 'NOW()') - ->where('foo = ?', 'bar') - ->where('baz = ?', 'dib') + ->where('foo = :_1_', ['_1_' => 'bar']) + ->where('baz = :_2_', ['_2_' => 'dib']) ->orWhere('zim = gir') ->limit(5); @@ -206,7 +206,7 @@ public function testActual() $this->query->table('test') ->cols(array('name')) - ->where('id = ?', 1) + ->where('id = :id', ['id' => 1]) ->bindValues(array('name' => 'Annabelle')); $stm = $this->query->__toString(); From 8920d820f05d515f2ff68558a3b7126550464bbe Mon Sep 17 00:00:00 2001 From: "Paul M. Jones" Date: Tue, 21 Mar 2017 15:11:35 -0500 Subject: [PATCH 03/10] move method to only place it is used --- src/AbstractQuery.php | 46 ------------------------------------------- src/Common/Select.php | 46 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/src/AbstractQuery.php b/src/AbstractQuery.php index 06ef30e..8a9e17f 100644 --- a/src/AbstractQuery.php +++ b/src/AbstractQuery.php @@ -303,52 +303,6 @@ protected function addClauseCondWithBind($clause, $andor, $cond, $bind) } } - /** - * - * Rebuilds a condition string, replacing sequential placeholders with - * named placeholders, and binding the sequential values to the named - * placeholders. - * - * @param string $cond The condition with sequential placeholders. - * - * @param array $bind_values The values to bind to the sequential - * placeholders under their named versions. - * - * @return string The rebuilt condition string. - * - */ - protected function rebuildCondAndBindValues($cond, array $bind_values) - { - $cond = $this->quoter->quoteNamesIn($cond); - - // bind values against ?-mark placeholders, but because PDO is finicky - // about the numbering of sequential placeholders, convert each ?-mark - // to a named placeholder - $parts = preg_split('/(\?)/', $cond, null, PREG_SPLIT_DELIM_CAPTURE); - foreach ($parts as $key => $val) { - if ($val != '?') { - continue; - } - - $bind_value = array_shift($bind_values); - if ($bind_value instanceof SubselectInterface) { - $parts[$key] = $bind_value->getStatement(); - $this->bind_values = array_merge( - $this->bind_values, - $bind_value->getBindValues() - ); - continue; - } - - $placeholder = $this->getSeqPlaceholder(); - $parts[$key] = ':' . $placeholder; - $this->bind_values[$placeholder] = $bind_value; - } - - $cond = implode('', $parts); - return $cond; - } - /** * * Gets the current sequential placeholder name. diff --git a/src/Common/Select.php b/src/Common/Select.php index 192532d..10ce15c 100644 --- a/src/Common/Select.php +++ b/src/Common/Select.php @@ -525,6 +525,52 @@ protected function fixJoinCondition($cond, array $bind) return 'ON ' . $cond; } + /** + * + * Rebuilds a condition string, replacing sequential placeholders with + * named placeholders, and binding the sequential values to the named + * placeholders. + * + * @param string $cond The condition with sequential placeholders. + * + * @param array $bind_values The values to bind to the sequential + * placeholders under their named versions. + * + * @return string The rebuilt condition string. + * + */ + protected function rebuildCondAndBindValues($cond, array $bind_values) + { + $cond = $this->quoter->quoteNamesIn($cond); + + // bind values against ?-mark placeholders, but because PDO is finicky + // about the numbering of sequential placeholders, convert each ?-mark + // to a named placeholder + $parts = preg_split('/(\?)/', $cond, null, PREG_SPLIT_DELIM_CAPTURE); + foreach ($parts as $key => $val) { + if ($val != '?') { + continue; + } + + $bind_value = array_shift($bind_values); + if ($bind_value instanceof SubselectInterface) { + $parts[$key] = $bind_value->getStatement(); + $this->bind_values = array_merge( + $this->bind_values, + $bind_value->getBindValues() + ); + continue; + } + + $placeholder = $this->getSeqPlaceholder(); + $parts[$key] = ':' . $placeholder; + $this->bind_values[$placeholder] = $bind_value; + } + + $cond = implode('', $parts); + return $cond; + } + /** * * Adds a INNER JOIN table and columns to the query. From 913a85ebf7bf05e91cc7b7a01717d966737a3b4a Mon Sep 17 00:00:00 2001 From: "Paul M. Jones" Date: Tue, 21 Mar 2017 15:22:44 -0500 Subject: [PATCH 04/10] join*() now support only named binding --- src/Common/Select.php | 51 +++---------------------------------- tests/Common/SelectTest.php | 8 +++--- 2 files changed, 8 insertions(+), 51 deletions(-) diff --git a/src/Common/Select.php b/src/Common/Select.php index 10ce15c..4110504 100644 --- a/src/Common/Select.php +++ b/src/Common/Select.php @@ -512,7 +512,10 @@ protected function fixJoinCondition($cond, array $bind) } $cond = $this->quoter->quoteNamesIn($cond); - $cond = $this->rebuildCondAndBindValues($cond, $bind); + + foreach ($bind as $key => $val) { + $this->bindValue($key, $val); + } if (strtoupper(substr(ltrim($cond), 0, 3)) == 'ON ') { return $cond; @@ -525,52 +528,6 @@ protected function fixJoinCondition($cond, array $bind) return 'ON ' . $cond; } - /** - * - * Rebuilds a condition string, replacing sequential placeholders with - * named placeholders, and binding the sequential values to the named - * placeholders. - * - * @param string $cond The condition with sequential placeholders. - * - * @param array $bind_values The values to bind to the sequential - * placeholders under their named versions. - * - * @return string The rebuilt condition string. - * - */ - protected function rebuildCondAndBindValues($cond, array $bind_values) - { - $cond = $this->quoter->quoteNamesIn($cond); - - // bind values against ?-mark placeholders, but because PDO is finicky - // about the numbering of sequential placeholders, convert each ?-mark - // to a named placeholder - $parts = preg_split('/(\?)/', $cond, null, PREG_SPLIT_DELIM_CAPTURE); - foreach ($parts as $key => $val) { - if ($val != '?') { - continue; - } - - $bind_value = array_shift($bind_values); - if ($bind_value instanceof SubselectInterface) { - $parts[$key] = $bind_value->getStatement(); - $this->bind_values = array_merge( - $this->bind_values, - $bind_value->getBindValues() - ); - continue; - } - - $placeholder = $this->getSeqPlaceholder(); - $parts[$key] = ':' . $placeholder; - $this->bind_values[$placeholder] = $bind_value; - } - - $cond = implode('', $parts); - return $cond; - } - /** * * Adds a INNER JOIN table and columns to the query. diff --git a/tests/Common/SelectTest.php b/tests/Common/SelectTest.php index a834c08..4d4ac10 100644 --- a/tests/Common/SelectTest.php +++ b/tests/Common/SelectTest.php @@ -293,8 +293,8 @@ public function testJoinAndBind() $this->query->join( 'left', 't2', - 't1.id = t2.id AND t1.foo = ?', - array('bar') + 't1.id = t2.id AND t1.foo = :_1_', + ['_1_' => 'bar'] ); $expect = ' @@ -336,8 +336,8 @@ public function testLeftAndInnerJoinWithBind() { $this->query->cols(array('*')); $this->query->from('t1'); - $this->query->leftJoin('t2', 't2.id = ?', array('foo')); - $this->query->innerJoin('t3 AS a3', 'a3.id = ?', array('bar')); + $this->query->leftJoin('t2', 't2.id = :_1_', ['_1_' => 'foo']); + $this->query->innerJoin('t3 AS a3', 'a3.id = :_2_', ['_2_' => 'bar']); $expect = ' SELECT * From bc794818a6c09bc84ba585c934b17bff4af0b057 Mon Sep 17 00:00:00 2001 From: "Paul M. Jones" Date: Tue, 21 Mar 2017 15:42:53 -0500 Subject: [PATCH 05/10] add back subselects as join conditions --- src/AbstractQuery.php | 24 +++++++++++++++++++++++- src/Common/Select.php | 5 +---- tests/Common/SelectTest.php | 22 +++++++++------------- 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/AbstractQuery.php b/src/AbstractQuery.php index 8a9e17f..0e3a962 100644 --- a/src/AbstractQuery.php +++ b/src/AbstractQuery.php @@ -290,6 +290,7 @@ public function resetFlags() protected function addClauseCondWithBind($clause, $andor, $cond, $bind) { $cond = $this->quoter->quoteNamesIn($cond); + $cond = $this->fixCondWithBind($cond, $bind); $clause =& $this->$clause; if ($clause) { @@ -298,9 +299,30 @@ protected function addClauseCondWithBind($clause, $andor, $cond, $bind) $clause[] = $cond; } + } + + protected function fixCondWithBind($cond, array $bind) + { + $selects = []; + foreach ($bind as $key => $val) { - $this->bindValue($key, $val); + if ($val instanceof SubselectInterface) { + $selects[":{$key}"] = $val; + } else { + $this->bindValue($key, $val); + } + } + + foreach ($selects as $key => $select) { + $selects[$key] = $select->getStatement(); + $this->bind_values = array_merge( + $this->bind_values, + $select->getBindValues() + ); } + + $cond = strtr($cond, $selects); + return $cond; } /** diff --git a/src/Common/Select.php b/src/Common/Select.php index 4110504..d9bea8d 100644 --- a/src/Common/Select.php +++ b/src/Common/Select.php @@ -512,10 +512,7 @@ protected function fixJoinCondition($cond, array $bind) } $cond = $this->quoter->quoteNamesIn($cond); - - foreach ($bind as $key => $val) { - $this->bindValue($key, $val); - } + $cond = $this->fixCondWithBind($cond, $bind); if (strtoupper(substr(ltrim($cond), 0, 3)) == 'ON ') { return $cond; diff --git a/tests/Common/SelectTest.php b/tests/Common/SelectTest.php index 4d4ac10..6681fb4 100644 --- a/tests/Common/SelectTest.php +++ b/tests/Common/SelectTest.php @@ -813,8 +813,6 @@ public function testRemoveColsNotFound() public function testIssue47() { - $this->markTestIncomplete("Finish subselect-as-condition."); - // sub select $sub = $this->newQuery() ->cols(array('*')) @@ -832,7 +830,7 @@ public function testIssue47() $select = $this->newQuery() ->cols(array('*')) ->from('table2 AS t2') - ->where("field IN (?)", $sub); + ->where("field IN (:field)", ['field' => $sub]); $expect = ' SELECT @@ -884,13 +882,11 @@ public function testIssue49() public function testWhereSubSelectImportsBoundValues() { - $this->markTestIncomplete("Finish subselect-as-condition."); - // sub select $sub = $this->newQuery() ->cols(array('*')) ->from('table1 AS t1') - ->where('t1.foo = ?', 'bar'); + ->where('t1.foo = :foo', ['foo' => 'bar']); $expect = ' SELECT @@ -898,7 +894,7 @@ public function testWhereSubSelectImportsBoundValues() FROM <> AS <> WHERE - <>.<> = :_1_1_ + <>.<> = :foo '; $actual = $sub->getStatement(); $this->assertSameSql($expect, $actual); @@ -907,8 +903,8 @@ public function testWhereSubSelectImportsBoundValues() $select = $this->newQuery() ->cols(array('*')) ->from('table2 AS t2') - ->where("field IN (?)", $sub) - ->where("t2.baz = ?", 'dib'); + ->where("field IN (:field)", ['field' => $sub]) + ->where("t2.baz = :baz", ['baz' => 'dib']); $expect = ' SELECT @@ -921,8 +917,8 @@ public function testWhereSubSelectImportsBoundValues() FROM <> AS <> WHERE - <>.<> = :_1_1_) - AND <>.<> = :_2_2_ + <>.<> = :foo) + AND <>.<> = :baz '; // B.b.: The _2_2_ means "2nd query, 2nd sequential bound value". It's @@ -933,8 +929,8 @@ public function testWhereSubSelectImportsBoundValues() $this->assertSameSql($expect, $actual); $expect = array( - '_1_1_' => 'bar', - '_2_2_' => 'dib', + 'foo' => 'bar', + 'baz' => 'dib', ); $actual = $select->getBindValues(); $this->assertSame($expect, $actual); From 4af5995ebff4637223550d1398f26e64a029c533 Mon Sep 17 00:00:00 2001 From: "Paul M. Jones" Date: Tue, 21 Mar 2017 15:51:13 -0500 Subject: [PATCH 06/10] in tests, change :_?_ to :named placeholder --- tests/Common/DeleteTest.php | 12 ++++---- tests/Common/SelectTest.php | 18 ++++++------ tests/Common/UpdateTest.php | 12 ++++---- tests/Mysql/DeleteTest.php | 28 +++++++++---------- tests/Mysql/UpdateTest.php | 20 ++++++------- tests/Pgsql/DeleteTest.php | 12 ++++---- tests/Pgsql/UpdateTest.php | 12 ++++---- tests/Sqlite/DeleteTest.php | 12 ++++---- tests/Sqlite/UpdateTest.php | 56 ++++++++++++++++++------------------- 9 files changed, 91 insertions(+), 91 deletions(-) diff --git a/tests/Common/DeleteTest.php b/tests/Common/DeleteTest.php index 1b3fa51..6f4816a 100644 --- a/tests/Common/DeleteTest.php +++ b/tests/Common/DeleteTest.php @@ -10,16 +10,16 @@ class DeleteTest extends AbstractQueryTest public function testCommon() { $this->query->from('t1') - ->where('foo = :_1_', ['_1_' => 'bar']) - ->where('baz = :_2_', ['_2_' => 'dib']) + ->where('foo = :foo', ['foo' => 'bar']) + ->where('baz = :baz', ['baz' => 'dib']) ->orWhere('zim = gir'); $actual = $this->query->__toString(); $expect = " DELETE FROM <> WHERE - foo = :_1_ - AND baz = :_2_ + foo = :foo + AND baz = :baz OR zim = gir "; @@ -27,8 +27,8 @@ public function testCommon() $actual = $this->query->getBindValues(); $expect = array( - '_1_' => 'bar', - '_2_' => 'dib', + 'foo' => 'bar', + 'baz' => 'dib', ); $this->assertSame($expect, $actual); } diff --git a/tests/Common/SelectTest.php b/tests/Common/SelectTest.php index 6681fb4..77619dc 100644 --- a/tests/Common/SelectTest.php +++ b/tests/Common/SelectTest.php @@ -293,8 +293,8 @@ public function testJoinAndBind() $this->query->join( 'left', 't2', - 't1.id = t2.id AND t1.foo = :_1_', - ['_1_' => 'bar'] + 't1.id = t2.id AND t1.foo = :foo', + ['foo' => 'bar'] ); $expect = ' @@ -302,12 +302,12 @@ public function testJoinAndBind() * FROM <> - LEFT JOIN <> ON <>.<> = <>.<> AND <>.<> = :_1_ + LEFT JOIN <> ON <>.<> = <>.<> AND <>.<> = :foo '; $actual = $this->query->__toString(); $this->assertSameSql($expect, $actual); - $expect = array('_1_' => 'bar'); + $expect = array('foo' => 'bar'); $actual = $this->query->getBindValues(); $this->assertSame($expect, $actual); } @@ -336,20 +336,20 @@ public function testLeftAndInnerJoinWithBind() { $this->query->cols(array('*')); $this->query->from('t1'); - $this->query->leftJoin('t2', 't2.id = :_1_', ['_1_' => 'foo']); - $this->query->innerJoin('t3 AS a3', 'a3.id = :_2_', ['_2_' => 'bar']); + $this->query->leftJoin('t2', 't2.id = :t2_id', ['t2_id' => 'foo']); + $this->query->innerJoin('t3 AS a3', 'a3.id = :a3_id', ['a3_id' => 'bar']); $expect = ' SELECT * FROM <> - LEFT JOIN <> ON <>.<> = :_1_ - INNER JOIN <> AS <> ON <>.<> = :_2_ + LEFT JOIN <> ON <>.<> = :t2_id + INNER JOIN <> AS <> ON <>.<> = :a3_id '; $actual = $this->query->__toString(); $this->assertSameSql($expect, $actual); - $expect = array('_1_' => 'foo', '_2_' => 'bar'); + $expect = array('t2_id' => 'foo', 'a3_id' => 'bar'); $actual = $this->query->getBindValues(); $this->assertSame($expect, $actual); } diff --git a/tests/Common/UpdateTest.php b/tests/Common/UpdateTest.php index aa85718..5eccbc9 100644 --- a/tests/Common/UpdateTest.php +++ b/tests/Common/UpdateTest.php @@ -14,8 +14,8 @@ public function testCommon() ->col('c3') ->set('c4', null) ->set('c5', 'NOW()') - ->where('foo = :_1_', ['_1_' => 'bar']) - ->where('baz = :_2_', ['_2_' => 'dib']) + ->where('foo = :foo', ['foo' => 'bar']) + ->where('baz = :baz', ['baz' => 'dib']) ->orWhere('zim = gir'); $actual = $this->query->__toString(); @@ -28,8 +28,8 @@ public function testCommon() <> = NULL, <> = NOW() WHERE - foo = :_1_ - AND baz = :_2_ + foo = :foo + AND baz = :baz OR zim = gir "; @@ -37,8 +37,8 @@ public function testCommon() $actual = $this->query->getBindValues(); $expect = array( - '_1_' => 'bar', - '_2_' => 'dib', + 'foo' => 'bar', + 'baz' => 'dib', ); $this->assertSame($expect, $actual); } diff --git a/tests/Mysql/DeleteTest.php b/tests/Mysql/DeleteTest.php index b6599eb..59cd434 100644 --- a/tests/Mysql/DeleteTest.php +++ b/tests/Mysql/DeleteTest.php @@ -10,8 +10,8 @@ class DeleteTest extends Common\DeleteTest protected $expected_sql_with_flag = " DELETE %s FROM <> WHERE - foo = :_1_ - AND baz = :_2_ + foo = :foo + AND baz = :baz OR zim = gir "; @@ -36,8 +36,8 @@ public function testLowPriority() { $this->query->lowPriority() ->from('t1') - ->where('foo = :_1_', ['_1_' => 'bar']) - ->where('baz = :_2_', ['_2_' => 'dib']) + ->where('foo = :foo', ['foo' => 'bar']) + ->where('baz = :baz', ['baz' => 'dib']) ->orWhere('zim = gir'); $actual = $this->query->__toString(); @@ -46,8 +46,8 @@ public function testLowPriority() $actual = $this->query->getBindValues(); $expect = array( - '_1_' => 'bar', - '_2_' => 'dib', + 'foo' => 'bar', + 'baz' => 'dib', ); $this->assertSame($expect, $actual); } @@ -56,8 +56,8 @@ public function testQuick() { $this->query->quick() ->from('t1') - ->where('foo = :_1_', ['_1_' => 'bar']) - ->where('baz = :_2_', ['_2_' => 'dib']) + ->where('foo = :foo', ['foo' => 'bar']) + ->where('baz = :baz', ['baz' => 'dib']) ->orWhere('zim = gir'); $actual = $this->query->__toString(); @@ -66,8 +66,8 @@ public function testQuick() $actual = $this->query->getBindValues(); $expect = array( - '_1_' => 'bar', - '_2_' => 'dib', + 'foo' => 'bar', + 'baz' => 'dib', ); $this->assertSame($expect, $actual); } @@ -76,8 +76,8 @@ public function testIgnore() { $this->query->ignore() ->from('t1') - ->where('foo = :_1_', ['_1_' => 'bar']) - ->where('baz = :_2_', ['_2_' => 'dib']) + ->where('foo = :foo', ['foo' => 'bar']) + ->where('baz = :baz', ['baz' => 'dib']) ->orWhere('zim = gir'); $actual = $this->query->__toString(); @@ -86,8 +86,8 @@ public function testIgnore() $actual = $this->query->getBindValues(); $expect = array( - '_1_' => 'bar', - '_2_' => 'dib', + 'foo' => 'bar', + 'baz' => 'dib', ); $this->assertSame($expect, $actual); } diff --git a/tests/Mysql/UpdateTest.php b/tests/Mysql/UpdateTest.php index 9794382..0f00977 100644 --- a/tests/Mysql/UpdateTest.php +++ b/tests/Mysql/UpdateTest.php @@ -16,8 +16,8 @@ class UpdateTest extends Common\UpdateTest <> = NULL, <> = NOW() WHERE - foo = :_1_ - AND baz = :_2_ + foo = :foo + AND baz = :baz OR zim = gir LIMIT 5 "; @@ -49,8 +49,8 @@ public function testLowPriority() ->cols(array('c1', 'c2', 'c3')) ->set('c4', null) ->set('c5', 'NOW()') - ->where('foo = :_1_', ['_1_' => 'bar']) - ->where('baz = :_2_', ['_2_' => 'dib']) + ->where('foo = :foo', ['foo' => 'bar']) + ->where('baz = :baz', ['baz' => 'dib']) ->orWhere('zim = gir') ->limit(5); @@ -60,8 +60,8 @@ public function testLowPriority() $actual = $this->query->getBindValues(); $expect = array( - '_1_' => 'bar', - '_2_' => 'dib', + 'foo' => 'bar', + 'baz' => 'dib', ); $this->assertSame($expect, $actual); } @@ -73,8 +73,8 @@ public function testIgnore() ->cols(array('c1', 'c2', 'c3')) ->set('c4', null) ->set('c5', 'NOW()') - ->where('foo = :_1_', ['_1_' => 'bar']) - ->where('baz = :_2_', ['_2_' => 'dib']) + ->where('foo = :foo', ['foo' => 'bar']) + ->where('baz = :baz', ['baz' => 'dib']) ->orWhere('zim = gir') ->limit(5); @@ -84,8 +84,8 @@ public function testIgnore() $actual = $this->query->getBindValues(); $expect = array( - '_1_' => 'bar', - '_2_' => 'dib', + 'foo' => 'bar', + 'baz' => 'dib', ); $this->assertSame($expect, $actual); } diff --git a/tests/Pgsql/DeleteTest.php b/tests/Pgsql/DeleteTest.php index 2f9fdce..c738fa9 100644 --- a/tests/Pgsql/DeleteTest.php +++ b/tests/Pgsql/DeleteTest.php @@ -10,8 +10,8 @@ class DeleteTest extends Common\DeleteTest public function testReturning() { $this->query->from('t1') - ->where('foo = :_1_', ['_1_' => 'bar']) - ->where('baz = :_2_', ['_2_' => 'dib']) + ->where('foo = :foo', ['foo' => 'bar']) + ->where('baz = :baz', ['baz' => 'dib']) ->orWhere('zim = gir') ->returning(array('foo', 'baz', 'zim')); @@ -19,8 +19,8 @@ public function testReturning() $expect = " DELETE FROM <> WHERE - foo = :_1_ - AND baz = :_2_ + foo = :foo + AND baz = :baz OR zim = gir RETURNING foo, @@ -31,8 +31,8 @@ public function testReturning() $actual = $this->query->getBindValues(); $expect = array( - '_1_' => 'bar', - '_2_' => 'dib', + 'foo' => 'bar', + 'baz' => 'dib', ); $this->assertSame($expect, $actual); } diff --git a/tests/Pgsql/UpdateTest.php b/tests/Pgsql/UpdateTest.php index 057cf10..3d009c2 100644 --- a/tests/Pgsql/UpdateTest.php +++ b/tests/Pgsql/UpdateTest.php @@ -13,8 +13,8 @@ public function testReturning() ->cols(array('c1', 'c2', 'c3')) ->set('c4', null) ->set('c5', 'NOW()') - ->where('foo = :_1_', ['_1_' => 'bar']) - ->where('baz = :_2_', ['_2_' => 'dib']) + ->where('foo = :foo', ['foo' => 'bar']) + ->where('baz = :baz', ['baz' => 'dib']) ->orWhere('zim = gir') ->returning(array('c1', 'c2')) ->returning(array('c3')); @@ -29,8 +29,8 @@ public function testReturning() <> = NULL, <> = NOW() WHERE - foo = :_1_ - AND baz = :_2_ + foo = :foo + AND baz = :baz OR zim = gir RETURNING c1, @@ -41,8 +41,8 @@ public function testReturning() $actual = $this->query->getBindValues(); $expect = array( - '_1_' => 'bar', - '_2_' => 'dib', + 'foo' => 'bar', + 'baz' => 'dib', ); $this->assertSame($expect, $actual); } diff --git a/tests/Sqlite/DeleteTest.php b/tests/Sqlite/DeleteTest.php index 2dae9db..7b84f83 100644 --- a/tests/Sqlite/DeleteTest.php +++ b/tests/Sqlite/DeleteTest.php @@ -10,8 +10,8 @@ class DeleteTest extends Common\DeleteTest public function testOrderLimit() { $this->query->from('t1') - ->where('foo = :_1_', ['_1_' => 'bar']) - ->where('baz = :_2_', ['_2_' => 'dib']) + ->where('foo = :foo', ['foo' => 'bar']) + ->where('baz = :baz', ['baz' => 'dib']) ->orWhere('zim = gir') ->orderBy(array('zim DESC')) ->limit(5) @@ -21,8 +21,8 @@ public function testOrderLimit() $expect = " DELETE FROM <> WHERE - foo = :_1_ - AND baz = :_2_ + foo = :foo + AND baz = :baz OR zim = gir ORDER BY zim DESC @@ -32,8 +32,8 @@ public function testOrderLimit() $actual = $this->query->getBindValues(); $expect = array( - '_1_' => 'bar', - '_2_' => 'dib', + 'foo' => 'bar', + 'baz' => 'dib', ); $this->assertSame($expect, $actual); } diff --git a/tests/Sqlite/UpdateTest.php b/tests/Sqlite/UpdateTest.php index 4f841c2..7a5df30 100644 --- a/tests/Sqlite/UpdateTest.php +++ b/tests/Sqlite/UpdateTest.php @@ -17,8 +17,8 @@ class UpdateTest extends Common\UpdateTest <> = NULL, <> = NOW() WHERE - foo = :_1_ - AND baz = :_2_ + foo = :foo + AND baz = :baz OR zim = gir LIMIT 5 "; @@ -29,8 +29,8 @@ public function testOrderLimit() ->cols(array('c1', 'c2', 'c3')) ->set('c4', null) ->set('c5', 'NOW()') - ->where('foo = :_1_', ['_1_' => 'bar']) - ->where('baz = :_2_', ['_2_' => 'dib']) + ->where('foo = :foo', ['foo' => 'bar']) + ->where('baz = :baz', ['baz' => 'dib']) ->orWhere('zim = gir') ->orderBy(array('zim DESC', 'baz ASC')) ->limit(5) @@ -46,8 +46,8 @@ public function testOrderLimit() <> = NULL, <> = NOW() WHERE - foo = :_1_ - AND baz = :_2_ + foo = :foo + AND baz = :baz OR zim = gir ORDER BY zim DESC, @@ -58,8 +58,8 @@ public function testOrderLimit() $actual = $this->query->getBindValues(); $expect = array( - '_1_' => 'bar', - '_2_' => 'dib', + 'foo' => 'bar', + 'baz' => 'dib', ); $this->assertSame($expect, $actual); } @@ -71,8 +71,8 @@ public function testOrAbort() ->cols(array('c1', 'c2', 'c3')) ->set('c4', null) ->set('c5', 'NOW()') - ->where('foo = :_1_', ['_1_' => 'bar']) - ->where('baz = :_2_', ['_2_' => 'dib']) + ->where('foo = :foo', ['foo' => 'bar']) + ->where('baz = :baz', ['baz' => 'dib']) ->orWhere('zim = gir') ->limit(5); @@ -82,8 +82,8 @@ public function testOrAbort() $actual = $this->query->getBindValues(); $expect = array( - '_1_' => 'bar', - '_2_' => 'dib', + 'foo' => 'bar', + 'baz' => 'dib', ); $this->assertSame($expect, $actual); } @@ -95,8 +95,8 @@ public function testOrFail() ->cols(array('c1', 'c2', 'c3')) ->set('c4', null) ->set('c5', 'NOW()') - ->where('foo = :_1_', ['_1_' => 'bar']) - ->where('baz = :_2_', ['_2_' => 'dib']) + ->where('foo = :foo', ['foo' => 'bar']) + ->where('baz = :baz', ['baz' => 'dib']) ->orWhere('zim = gir') ->limit(5); @@ -106,8 +106,8 @@ public function testOrFail() $actual = $this->query->getBindValues(); $expect = array( - '_1_' => 'bar', - '_2_' => 'dib', + 'foo' => 'bar', + 'baz' => 'dib', ); $this->assertSame($expect, $actual); } @@ -119,8 +119,8 @@ public function testOrIgnore() ->cols(array('c1', 'c2', 'c3')) ->set('c4', null) ->set('c5', 'NOW()') - ->where('foo = :_1_', ['_1_' => 'bar']) - ->where('baz = :_2_', ['_2_' => 'dib']) + ->where('foo = :foo', ['foo' => 'bar']) + ->where('baz = :baz', ['baz' => 'dib']) ->orWhere('zim = gir') ->limit(5); @@ -130,8 +130,8 @@ public function testOrIgnore() $actual = $this->query->getBindValues(); $expect = array( - '_1_' => 'bar', - '_2_' => 'dib', + 'foo' => 'bar', + 'baz' => 'dib', ); $this->assertSame($expect, $actual); } @@ -143,8 +143,8 @@ public function testOrReplace() ->cols(array('c1', 'c2', 'c3')) ->set('c4', null) ->set('c5', 'NOW()') - ->where('foo = :_1_', ['_1_' => 'bar']) - ->where('baz = :_2_', ['_2_' => 'dib']) + ->where('foo = :foo', ['foo' => 'bar']) + ->where('baz = :baz', ['baz' => 'dib']) ->orWhere('zim = gir') ->limit(5); @@ -154,8 +154,8 @@ public function testOrReplace() $actual = $this->query->getBindValues(); $expect = array( - '_1_' => 'bar', - '_2_' => 'dib', + 'foo' => 'bar', + 'baz' => 'dib', ); $this->assertSame($expect, $actual); } @@ -167,8 +167,8 @@ public function testOrRollback() ->cols(array('c1', 'c2', 'c3')) ->set('c4', null) ->set('c5', 'NOW()') - ->where('foo = :_1_', ['_1_' => 'bar']) - ->where('baz = :_2_', ['_2_' => 'dib']) + ->where('foo = :foo', ['foo' => 'bar']) + ->where('baz = :baz', ['baz' => 'dib']) ->orWhere('zim = gir') ->limit(5); @@ -178,8 +178,8 @@ public function testOrRollback() $actual = $this->query->getBindValues(); $expect = array( - '_1_' => 'bar', - '_2_' => 'dib', + 'foo' => 'bar', + 'baz' => 'dib', ); $this->assertSame($expect, $actual); } From 33ccf7af7e094592ff5c06e41f23f9edea236b6f Mon Sep 17 00:00:00 2001 From: "Paul M. Jones" Date: Tue, 21 Mar 2017 15:59:57 -0500 Subject: [PATCH 07/10] remove seq-bind prefixing methods --- src/AbstractQuery.php | 42 +------------------------------------- tests/QueryFactoryTest.php | 11 ---------- 2 files changed, 1 insertion(+), 52 deletions(-) diff --git a/src/AbstractQuery.php b/src/AbstractQuery.php index 0e3a962..45180c2 100644 --- a/src/AbstractQuery.php +++ b/src/AbstractQuery.php @@ -65,44 +65,17 @@ abstract class AbstractQuery */ protected $quoter; - /** - * - * Prefix to use on placeholders for "sequential" bound values; used for - * deconfliction when merging bound values from sub-selects, etc. - * - * @var mixed - * - */ - protected $seq_bind_prefix = ''; - /** * * Constructor. * * @param Quoter $quoter A helper for quoting identifier names. * - * @param string $seq_bind_prefix A prefix for rewritten sequential-binding - * placeholders (@see getSeqPlaceholder()). - * */ - public function __construct(QuoterInterface $quoter, $builder, $seq_bind_prefix = '') + public function __construct(QuoterInterface $quoter, $builder) { $this->quoter = $quoter; $this->builder = $builder; - $this->seq_bind_prefix = $seq_bind_prefix; - } - - /** - * - * Returns the prefix for rewritten sequential-binding placeholders - * (@see getSeqPlaceholder()). - * - * @return string - * - */ - public function getSeqBindPrefix() - { - return $this->seq_bind_prefix; } /** @@ -325,19 +298,6 @@ protected function fixCondWithBind($cond, array $bind) return $cond; } - /** - * - * Gets the current sequential placeholder name. - * - * @return string - * - */ - protected function getSeqPlaceholder() - { - $i = count($this->bind_values) + 1; - return $this->seq_bind_prefix . "_{$i}_"; - } - /** * * Adds a column order to the query. diff --git a/tests/QueryFactoryTest.php b/tests/QueryFactoryTest.php index a5ca3cb..12bde34 100644 --- a/tests/QueryFactoryTest.php +++ b/tests/QueryFactoryTest.php @@ -62,15 +62,4 @@ public function provider() array('Sqlsrv', QueryFactory::COMMON, 'Delete', 'Aura\SqlQuery\Common\Delete'), ); } - - public function testSeqBindPrefix() - { - $query_factory = new QueryFactory('sqlite'); - - $first = $query_factory->newSelect(); - $this->assertSame('', $first->getSeqBindPrefix()); - - $again = $query_factory->newSelect(); - $this->assertSame('_1', $again->getSeqBindPrefix()); - } } From b88cbedee47e8e9eedf5d7cd8a58b2e3bc5b6553 Mon Sep 17 00:00:00 2001 From: "Paul M. Jones" Date: Tue, 21 Mar 2017 16:01:16 -0500 Subject: [PATCH 08/10] whitespace --- src/AbstractQuery.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/AbstractQuery.php b/src/AbstractQuery.php index 45180c2..39c7da1 100644 --- a/src/AbstractQuery.php +++ b/src/AbstractQuery.php @@ -271,7 +271,6 @@ protected function addClauseCondWithBind($clause, $andor, $cond, $bind) } else { $clause[] = $cond; } - } protected function fixCondWithBind($cond, array $bind) From 93047d3d3af21530ff2126babf4645eaaeab2e10 Mon Sep 17 00:00:00 2001 From: "Paul M. Jones" Date: Tue, 21 Mar 2017 16:03:00 -0500 Subject: [PATCH 09/10] no more need to track instance counts now that seq prefixes are not used --- src/QueryFactory.php | 32 +------------------------------- 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/src/QueryFactory.php b/src/QueryFactory.php index b71ef53..5f31f97 100644 --- a/src/QueryFactory.php +++ b/src/QueryFactory.php @@ -55,15 +55,6 @@ class QueryFactory */ protected $quoter; - /** - * - * A count of Query instances, used for determining $seq_bind_prefix. - * - * @var int - * - */ - protected $instance_count = 0; - /** * * Constructor. @@ -168,8 +159,7 @@ protected function newInstance($query) return new $queryClass( $this->getQuoter(), - $this->newBuilder($query), - $this->newSeqBindPrefix() + $this->newBuilder($query) ); } @@ -205,24 +195,4 @@ protected function newQuoter() } return new $quoterClass(); } - - /** - * - * Returns a new sequential-placeholder prefix for a query object. - * - * We need these to deconflict between bound values in subselect queries. - * - * @return string - * - */ - protected function newSeqBindPrefix() - { - $seq_bind_prefix = ''; - if ($this->instance_count) { - $seq_bind_prefix = '_' . $this->instance_count; - } - - $this->instance_count ++; - return $seq_bind_prefix; - } } From b69470237a01865d2260532d4a3ac438cd164a7c Mon Sep 17 00:00:00 2001 From: "Paul M. Jones" Date: Tue, 21 Mar 2017 16:05:46 -0500 Subject: [PATCH 10/10] clean up diff --- src/AbstractQuery.php | 20 +++++++++++++++++--- src/Common/Select.php | 2 +- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/AbstractQuery.php b/src/AbstractQuery.php index 39c7da1..cd4bc63 100644 --- a/src/AbstractQuery.php +++ b/src/AbstractQuery.php @@ -263,7 +263,7 @@ public function resetFlags() protected function addClauseCondWithBind($clause, $andor, $cond, $bind) { $cond = $this->quoter->quoteNamesIn($cond); - $cond = $this->fixCondWithBind($cond, $bind); + $cond = $this->rebuildCondAndBindValues($cond, $bind); $clause =& $this->$clause; if ($clause) { @@ -273,11 +273,25 @@ protected function addClauseCondWithBind($clause, $andor, $cond, $bind) } } - protected function fixCondWithBind($cond, array $bind) + /** + * + * Rebuilds a condition string, replacing sequential placeholders with + * named placeholders, and binding the sequential values to the named + * placeholders. + * + * @param string $cond The condition with sequential placeholders. + * + * @param array $bind_values The values to bind to the sequential + * placeholders under their named versions. + * + * @return string The rebuilt condition string. + * + */ + protected function rebuildCondAndBindValues($cond, array $bind_values) { $selects = []; - foreach ($bind as $key => $val) { + foreach ($bind_values as $key => $val) { if ($val instanceof SubselectInterface) { $selects[":{$key}"] = $val; } else { diff --git a/src/Common/Select.php b/src/Common/Select.php index d9bea8d..192532d 100644 --- a/src/Common/Select.php +++ b/src/Common/Select.php @@ -512,7 +512,7 @@ protected function fixJoinCondition($cond, array $bind) } $cond = $this->quoter->quoteNamesIn($cond); - $cond = $this->fixCondWithBind($cond, $bind); + $cond = $this->rebuildCondAndBindValues($cond, $bind); if (strtoupper(substr(ltrim($cond), 0, 3)) == 'ON ') { return $cond;