Browse Source

Merge pull request #8242 from CakeDC/3.2-indentifer-equals

Added identiferEquals method for expressions to use fields with quoti…
José Lorenzo Rodríguez 10 years ago
parent
commit
08e43f7cb8

+ 5 - 0
src/Database/Expression/CaseExpression.php

@@ -131,6 +131,11 @@ class CaseExpression implements ExpressionInterface
                 array_push($this->_values, $value);
                 continue;
             }
+            if ($value === 'identifier') {
+                $value = new IdentifierExpression($keyValues[$k]);
+                array_push($this->_values, $value);
+                continue;
+            }
             if ($value instanceof ExpressionInterface) {
                 array_push($this->_values, $value);
                 continue;

+ 5 - 0
src/Database/Expression/FunctionExpression.php

@@ -108,6 +108,11 @@ class FunctionExpression extends QueryExpression implements TypedResultInterface
                 continue;
             }
 
+            if ($p === 'identifier') {
+                $put($this->_conditions, new IdentifierExpression($k));
+                continue;
+            }
+
             if ($p instanceof ExpressionInterface) {
                 $put($this->_conditions, $p);
                 continue;

+ 18 - 0
src/Database/Expression/QueryExpression.php

@@ -439,6 +439,24 @@ class QueryExpression implements ExpressionInterface, Countable
     }
 
     /**
+     * Builds equal condition or assignment with identifier wrapping.
+     *
+     * @param string $left Left join condition field name.
+     * @param string $right Right join condition field name.
+     * @return $this
+     */
+    public function equalFields($left, $right)
+    {
+        $wrapIdentifier = function ($field) {
+            if ($field instanceof ExpressionInterface) {
+                return $field;
+            }
+            return new IdentifierExpression($field);
+        };
+        return $this->eq($wrapIdentifier($left), $wrapIdentifier($right));
+    }
+
+    /**
      * Returns the string representation of this object so that it can be used in a
      * SQL query. Note that values condition values are not included in the string,
      * in their place placeholders are put and can be replaced by the quoted values

+ 20 - 20
tests/TestCase/Database/QueryTest.php

@@ -196,7 +196,7 @@ class QueryTest extends TestCase
         $result = $query
             ->select(['title', 'name'])
             ->from('articles')
-            ->join(['table' => 'authors', 'alias' => 'a', 'conditions' => 'author_id = a.id'])
+            ->join(['table' => 'authors', 'alias' => 'a', 'conditions' => $query->newExpr()->equalFields('author_id', 'a.id')])
             ->order(['title' => 'asc'])
             ->execute();
 
@@ -208,7 +208,7 @@ class QueryTest extends TestCase
         $this->assertCount(12, $result, 'Cross join results in 12 records');
 
         $result = $query->join([
-            ['table' => 'authors', 'type' => 'INNER', 'conditions' => 'author_id = authors.id']
+            ['table' => 'authors', 'type' => 'INNER', 'conditions' => $query->newExpr()->equalFields('author_id', 'authors.id')]
         ], [], true)->execute();
         $this->assertCount(3, $result);
         $this->assertEquals(['title' => 'First Article', 'name' => 'mariano'], $result->fetch('assoc'));
@@ -226,14 +226,14 @@ class QueryTest extends TestCase
         $result = $query
             ->select(['title', 'name'])
             ->from('articles')
-            ->join(['table' => 'authors', 'alias' => 'a', 'conditions' => ['author_id = a.id']])
+            ->join(['table' => 'authors', 'alias' => 'a', 'conditions' => [$query->newExpr()->equalFields('author_id ', 'a.id')]])
             ->order(['title' => 'asc'])
             ->execute();
         $this->assertEquals(['title' => 'First Article', 'name' => 'mariano'], $result->fetch('assoc'));
         $this->assertEquals(['title' => 'Second Article', 'name' => 'larry'], $result->fetch('assoc'));
 
         $query = new Query($this->connection);
-        $conditions = $query->newExpr('author_id = a.id');
+        $conditions = $query->newExpr()->equalFields('author_id', 'a.id');
         $result = $query
             ->select(['title', 'name'])
             ->from('articles')
@@ -1296,7 +1296,7 @@ class QueryTest extends TestCase
             ->select(['id'])
             ->from('comments')
             ->where(function ($exp, $q) {
-                $field = $q->newExpr('COALESCE(id, 1)');
+                $field = $q->func()->coalesce([new IdentifierExpression('id'), 1 => 'literal']);
                 return $exp->between($field, 5, 6, 'integer');
             })
             ->execute();
@@ -1560,7 +1560,7 @@ class QueryTest extends TestCase
         $query = new Query($this->connection);
         $query->select(['id'])
             ->from('articles')
-            ->orderAsc($query->func()->concat(['id' => 'literal', '3']));
+            ->orderAsc($query->func()->concat(['id' => 'identifier', '3']));
 
         $result = $query->execute()->fetchAll('assoc');
         $expected = [
@@ -1599,7 +1599,7 @@ class QueryTest extends TestCase
         $query = new Query($this->connection);
         $query->select(['id'])
             ->from('articles')
-            ->orderDesc($query->func()->concat(['id' => 'literal', '3']));
+            ->orderDesc($query->func()->concat(['id' => 'identifier', '3']));
 
         $result = $query->execute()->fetchAll('assoc');
         $expected = [
@@ -1767,7 +1767,7 @@ class QueryTest extends TestCase
         $result = $query
             ->select(['total' => 'count(author_id)', 'author_id'])
             ->from('articles')
-            ->join(['table' => 'authors', 'alias' => 'a', 'conditions' => 'author_id = a.id'])
+            ->join(['table' => 'authors', 'alias' => 'a', 'conditions' => $query->newExpr()->equalFields('author_id', 'a.id')])
             ->group('author_id')
             ->having(['count(author_id) <' => 2], ['count(author_id)' => 'integer'])
             ->execute();
@@ -1799,7 +1799,7 @@ class QueryTest extends TestCase
         $result = $query
             ->select(['total' => 'count(author_id)', 'author_id'])
             ->from('articles')
-            ->join(['table' => 'authors', 'alias' => 'a', 'conditions' => 'author_id = a.id'])
+            ->join(['table' => 'authors', 'alias' => 'a', 'conditions' => $query->newExpr()->equalFields('author_id', 'a.id')])
             ->group('author_id')
             ->having(['count(author_id) >' => 2], ['count(author_id)' => 'integer'])
             ->orHaving(['count(author_id) <' => 2], ['count(author_id)' => 'integer'])
@@ -1811,7 +1811,7 @@ class QueryTest extends TestCase
         $result = $query
             ->select(['total' => 'count(author_id)', 'author_id'])
             ->from('articles')
-            ->join(['table' => 'authors', 'alias' => 'a', 'conditions' => 'author_id = a.id'])
+            ->join(['table' => 'authors', 'alias' => 'a', 'conditions' => $query->newExpr()->equalFields('author_id', 'a.id')])
             ->group('author_id')
             ->having(['count(author_id) >' => 2], ['count(author_id)' => 'integer'])
             ->orHaving(['count(author_id) <=' => 2], ['count(author_id)' => 'integer'])
@@ -1823,7 +1823,7 @@ class QueryTest extends TestCase
         $result = $query
             ->select(['total' => 'count(author_id)', 'author_id'])
             ->from('articles')
-            ->join(['table' => 'authors', 'alias' => 'a', 'conditions' => 'author_id = a.id'])
+            ->join(['table' => 'authors', 'alias' => 'a', 'conditions' => $query->newExpr()->equalFields('author_id', 'a.id')])
             ->group('author_id')
             ->having(['count(author_id) >' => 2], ['count(author_id)' => 'integer'])
             ->orHaving(function ($e) {
@@ -1846,7 +1846,7 @@ class QueryTest extends TestCase
         $result = $query
             ->select(['total' => 'count(author_id)', 'author_id'])
             ->from('articles')
-            ->join(['table' => 'authors', 'alias' => 'a', 'conditions' => 'author_id = a.id'])
+            ->join(['table' => 'authors', 'alias' => 'a', 'conditions' => $query->newExpr()->equalFields('author_id', 'a.id')])
             ->group('author_id')
             ->having(['count(author_id) >' => 2], ['count(author_id)' => 'integer'])
             ->andHaving(['count(author_id) <' => 2], ['count(author_id)' => 'integer'])
@@ -1857,7 +1857,7 @@ class QueryTest extends TestCase
         $result = $query
             ->select(['total' => 'count(author_id)', 'author_id'])
             ->from('articles')
-            ->join(['table' => 'authors', 'alias' => 'a', 'conditions' => 'author_id = a.id'])
+            ->join(['table' => 'authors', 'alias' => 'a', 'conditions' => $query->newExpr()->equalFields('author_id', 'a.id')])
             ->group('author_id')
             ->having(['count(author_id)' => 2], ['count(author_id)' => 'integer'])
             ->andHaving(['count(author_id) >' => 1], ['count(author_id)' => 'integer'])
@@ -1869,7 +1869,7 @@ class QueryTest extends TestCase
         $result = $query
             ->select(['total' => 'count(author_id)', 'author_id'])
             ->from('articles')
-            ->join(['table' => 'authors', 'alias' => 'a', 'conditions' => 'author_id = a.id'])
+            ->join(['table' => 'authors', 'alias' => 'a', 'conditions' => $query->newExpr()->equalFields('author_id', 'a.id')])
             ->group('author_id')
             ->andHaving(function ($e) {
                 return $e->add('count(author_id) = 2 - 1');
@@ -2005,7 +2005,7 @@ class QueryTest extends TestCase
         $subquery = (new Query($this->connection))
             ->select('name')
             ->from(['b' => 'authors'])
-            ->where(['b.id = a.id']);
+            ->where([$query->newExpr()->equalFields('b.id', 'a.id')]);
         $result = $query
             ->select(['id', 'name' => $subquery])
             ->from(['a' => 'comments'])->execute();
@@ -2113,7 +2113,7 @@ class QueryTest extends TestCase
      *
      * @return void
      */
-    public function testSubqueyInJoin()
+    public function testSubqueryInJoin()
     {
         $subquery = (new Query($this->connection))->select('*')->from('authors');
 
@@ -2129,7 +2129,7 @@ class QueryTest extends TestCase
         $result = $query->execute();
         $this->assertCount(3, $result);
 
-        $query->join(['b' => ['table' => $subquery, 'conditions' => ['b.id = articles.id']]], [], true);
+        $query->join(['b' => ['table' => $subquery, 'conditions' => [$query->newExpr()->equalFields('b.id', 'articles.id')]]], [], true);
         $result = $query->execute();
         $this->assertCount(1, $result);
     }
@@ -2437,7 +2437,7 @@ class QueryTest extends TestCase
     {
         $query = new Query($this->connection);
 
-        $expr = $query->newExpr('title = author_id');
+        $expr = $query->newExpr()->equalFields('title', 'author_id');
 
         $query->update('articles')
             ->set($expr)
@@ -2445,7 +2445,7 @@ class QueryTest extends TestCase
         $result = $query->sql();
 
         $this->assertQuotedQuery(
-            'UPDATE <articles> SET title = author_id WHERE <id> = :',
+            'UPDATE <articles> SET <title> = \(<author_id>\) WHERE <id> = :',
             $result,
             !$this->autoQuote
         );
@@ -2623,7 +2623,7 @@ class QueryTest extends TestCase
                 'published' => 'N',
             ]
         ];
-        $this->assertTable('articles', 1, $expected, ['id >= 4']);
+        $this->assertTable('articles', 1, $expected, ['id >=' => 4]);
     }
 
     /**

+ 7 - 1
tests/TestCase/Database/Schema/TableTest.php

@@ -39,7 +39,13 @@ class FooType extends Type
 class TableTest extends TestCase
 {
 
-    public $fixtures = ['core.articles_tags', 'core.orders', 'core.products', 'core.tags'];
+    public $fixtures = [
+        'core.articles',
+        'core.tags',
+        'core.articles_tags',
+        'core.orders',
+        'core.products'
+    ];
 
     protected $_map;
 

+ 2 - 2
tests/TestCase/ORM/QueryRegressionTest.php

@@ -35,13 +35,13 @@ class QueryRegressionTest extends TestCase
      */
     public $fixtures = [
         'core.articles',
+        'core.tags',
         'core.articles_tags',
         'core.authors',
         'core.authors_tags',
         'core.comments',
         'core.featured_tags',
         'core.special_tags',
-        'core.tags',
         'core.tags_translations',
         'core.translates',
         'core.users'
@@ -978,7 +978,7 @@ class QueryRegressionTest extends TestCase
         $query->select([
             'id',
             'coalesced' => $query->func()->coalesce(
-                ['published' => 'literal', -1],
+                ['published' => 'identifier', -1],
                 ['integer']
             )
         ]);

+ 11 - 5
tests/TestCase/ORM/QueryTest.php

@@ -552,7 +552,10 @@ class QueryTest extends TestCase
         TableRegistry::get('ArticlesTags', [
             'table' => 'articles_tags'
         ]);
-        $table->belongsToMany('Tags', ['strategy' => $strategy]);
+        $table->belongsToMany('Tags', [
+            'strategy' => $strategy,
+            'sort' => 'tag_id'
+        ]);
         $query = new Query($this->connection, $table);
 
         $results = $query->select()->contain('Tags')->hydrate(false)->toArray();
@@ -1553,7 +1556,7 @@ class QueryTest extends TestCase
         $query = $table->find();
         $query->select([
             'title' => $query->func()->concat(
-                ['title' => 'literal', 'test'],
+                ['title' => 'identifier', 'test'],
                 ['string']
             ),
         ]);
@@ -2214,7 +2217,7 @@ class QueryTest extends TestCase
      *
      * @return void
      */
-    public function testFormatDeepAssocationRecords()
+    public function testFormatDeepAssociationRecords()
     {
         $table = TableRegistry::get('ArticlesTags');
         $table->belongsTo('Articles');
@@ -2479,12 +2482,13 @@ class QueryTest extends TestCase
     public function testColumnsFromJoin()
     {
         $table = TableRegistry::get('articles');
-        $results = $table->find()
+        $query = $table->find();
+        $results = $query
             ->select(['title', 'person.name'])
             ->join([
                 'person' => [
                     'table' => 'authors',
-                    'conditions' => ['person.id = articles.author_id']
+                    'conditions' => [$query->newExpr()->equalFields('person.id', 'articles.author_id')]
                 ]
             ])
             ->order(['articles.id' => 'ASC'])
@@ -3111,6 +3115,7 @@ class QueryTest extends TestCase
         $results = $table->find()
             ->hydrate(false)
             ->notMatching('articles')
+            ->order(['authors.id'])
             ->toArray();
 
         $expected = [
@@ -3124,6 +3129,7 @@ class QueryTest extends TestCase
             ->notMatching('articles', function ($q) {
                 return $q->where(['articles.author_id' => 1]);
             })
+            ->order(['authors.id'])
             ->toArray();
         $expected = [
             ['id' => 2, 'name' => 'nate'],

+ 1 - 1
tests/TestCase/ORM/TableTest.php

@@ -53,6 +53,7 @@ class TableTest extends TestCase
 
     public $fixtures = [
         'core.articles',
+        'core.tags',
         'core.articles_tags',
         'core.authors',
         'core.categories',
@@ -62,7 +63,6 @@ class TableTest extends TestCase
         'core.members',
         'core.polymorphic_tagged',
         'core.site_articles',
-        'core.tags',
         'core.users'
     ];