/**
  * Test that empty expressions don't emit invalid SQL.
  *
  * @return void
  */
 public function testSqlWhenEmpty()
 {
     $expr = new QueryExpression();
     $binder = new ValueBinder();
     $result = $expr->sql($binder);
     $this->assertEquals('', $result);
 }
 /**
  * Tests that the expression is correctly traversed
  *
  * @return void
  */
 public function testTraverse()
 {
     $count = 0;
     $visitor = function () use(&$count) {
         $count++;
     };
     $expr = new QueryExpression();
     $expr->eq('test', 'true');
     $expr2 = new QueryExpression();
     $expr2->eq('test', 'false');
     $caseExpression = new CaseExpression([$expr, $expr2]);
     $caseExpression->traverse($visitor);
     $this->assertSame(4, $count);
 }
Exemple #3
0
 /**
  * Tests that applying array options to a query will convert them
  * to equivalent function calls with the correspondent array values
  *
  * @return void
  */
 public function testApplyOptions()
 {
     $options = ['fields' => ['field_a', 'field_b'], 'conditions' => ['field_a' => 1, 'field_b' => 'something'], 'limit' => 1, 'order' => ['a' => 'ASC'], 'offset' => 5, 'group' => ['field_a'], 'having' => ['field_a >' => 100], 'contain' => ['table_a' => ['table_b']], 'join' => ['table_a' => ['conditions' => ['a > b']]]];
     $query = new Query($this->connection, $this->table);
     $query->applyOptions($options);
     $this->assertEquals(['field_a', 'field_b'], $query->clause('select'));
     $expected = new QueryExpression($options['conditions'], $this->fooTypeMap);
     $result = $query->clause('where');
     $this->assertEquals($expected, $result);
     $this->assertEquals(1, $query->clause('limit'));
     $expected = new QueryExpression(['a > b']);
     $expected->typeMap($this->fooTypeMap);
     $result = $query->clause('join');
     $this->assertEquals(['table_a' => ['alias' => 'table_a', 'type' => 'INNER', 'conditions' => $expected]], $result);
     $expected = new OrderByExpression(['a' => 'ASC']);
     $this->assertEquals($expected, $query->clause('order'));
     $this->assertEquals(5, $query->clause('offset'));
     $this->assertEquals(['field_a'], $query->clause('group'));
     $expected = new QueryExpression($options['having']);
     $expected->typeMap($this->fooTypeMap);
     $this->assertEquals($expected, $query->clause('having'));
     $expected = ['table_a' => ['table_b' => []]];
     $this->assertEquals($expected, $query->contain());
 }
 /**
  * Constructor. Takes a name for the function to be invoked and a list of params
  * to be passed into the function. Optionally you can pass a list of types to
  * be used for each bound param.
  *
  * By default, all params that are passed will be quoted. If you wish to use
  * literal arguments, you need to explicitly hint this function.
  *
  * ### Examples:
  *
  *  `$f = new FunctionExpression('CONCAT', ['CakePHP', ' rules']);`
  *
  * Previous line will generate `CONCAT('CakePHP', ' rules')`
  *
  * `$f = new FunctionExpression('CONCAT', ['name' => 'literal', ' rules']);`
  *
  * Will produce `CONCAT(name, ' rules')`
  *
  * @param string $name the name of the function to be constructed
  * @param array $params list of arguments to be passed to the function
  * If associative the key would be used as argument when value is 'literal'
  * @param array $types associative array of types to be associated with the
  * passed arguments
  * @param string $returnType The return type of this expression
  */
 public function __construct($name, $params = [], $types = [], $returnType = 'string')
 {
     $this->_name = $name;
     $this->_returnType = $returnType;
     parent::__construct($params, $types, ',');
 }
Exemple #5
0
 /**
  * Returns a new QueryExpression object. This is a handy function when
  * building complex queries using a fluent interface. You can also override
  * this function in subclasses to use a more specialized QueryExpression class
  * if required.
  *
  * You can optionally pass a single raw SQL string or an array or expressions in
  * any format accepted by \Cake\Database\Expression\QueryExpression:
  *
  * ```
  * $expression = $query->newExpr(); // Returns an empty expression object
  * $expression = $query->newExpr('Table.column = Table2.column'); // Return a raw SQL expression
  * ```
  *
  * @param mixed $rawExpression A string, array or anything you want wrapped in an expression object
  * @return \Cake\Database\Expression\QueryExpression
  */
 public function newExpr($rawExpression = null)
 {
     $expression = new QueryExpression([], $this->typeMap());
     if ($rawExpression !== null) {
         $expression->add($rawExpression);
     }
     return $expression;
 }
 /**
  * Constructor. Takes a name for the function to be invoked and a list of params
  * to be passed into the function. Optionally you can pass a list of types to
  * be used for each bound param.
  *
  * By default, all params that are passed will be quoted. If you wish to use
  * literal arguments, you need to explicitly hint this function.
  *
  * ### Examples:
  *
  *  ``$f = new FunctionExpression('CONCAT', ['CakePHP', ' rules']);``
  *
  * Previous line will generate ``CONCAT('CakePHP', ' rules')``
  *
  * ``$f = new FunctionExpression('CONCAT', ['name' => 'literal', ' rules']);``
  *
  * Will produce ``CONCAT(name, ' rules')``
  *
  * @param string $name the name of the function to be constructed
  * @param array $params list of arguments to be passed to the function
  * If associative the key would be used as argument when value is 'literal'
  * @param array $types associative array of types to be associated with the
  * passed arguments
  */
 public function __construct($name, $params = [], $types = [])
 {
     $this->_name = $name;
     parent::__construct($params, $types, ',');
 }
Exemple #7
0
 /**
  * Constructor
  *
  * @param array $conditions The sort columns
  * @param array $types The types for each column.
  * @param string $conjunction The glue used to join conditions together.
  */
 public function __construct($conditions = [], $types = [], $conjunction = '')
 {
     parent::__construct($conditions, $types, $conjunction);
 }
 /**
  * Test magic findAllByXX method.
  *
  * @return void
  */
 public function testMagicFindAllOr()
 {
     $table = TableRegistry::get('Users');
     $result = $table->findAllByAuthorIdOrPublished(1, 'Y');
     $this->assertInstanceOf('Cake\\ORM\\Query', $result);
     $this->assertNull($result->clause('limit'));
     $expected = new QueryExpression();
     $expected->typeMap()->defaults($this->usersTypeMap->toArray());
     $expected->add(['or' => ['Users.author_id' => 1, 'Users.published' => 'Y']]);
     $this->assertEquals($expected, $result->clause('where'));
     $this->assertNull($result->clause('order'));
 }
Exemple #9
0
 /**
  * Test magic findAllByXX method.
  *
  * @return void
  */
 public function testMagicFindAllOr()
 {
     $table = TableRegistry::get('Users');
     $result = $table->findAllByAuthorIdOrPublished(1, 'Y');
     $this->assertInstanceOf('Cake\\ORM\\Query', $result);
     $this->assertNull($result->clause('limit'));
     $expected = new QueryExpression();
     $expected->typeMap()->defaults(['Users.id' => 'integer', 'id' => 'integer', 'Users.username' => 'string', 'username' => 'string', 'Users.password' => 'string', 'password' => 'string', 'Users.created' => 'timestamp', 'created' => 'timestamp', 'Users.updated' => 'timestamp', 'updated' => 'timestamp']);
     $expected->add(['or' => ['Users.author_id' => 1, 'Users.published' => 'Y']]);
     $this->assertEquals($expected, $result->clause('where'));
     $this->assertNull($result->clause('order'));
 }
 /**
  * Tests the hasNestedExpression() function
  *
  * @return void
  */
 public function testHasNestedExpression()
 {
     $expr = new QueryExpression();
     $this->assertFalse($expr->hasNestedExpression());
     $expr->add(['a' => 'b']);
     $this->assertTrue($expr->hasNestedExpression());
     $expr = new QueryExpression();
     $expr->add('a = b');
     $this->assertFalse($expr->hasNestedExpression());
     $expr->add(new QueryExpression('1 = 1'));
     $this->assertTrue($expr->hasNestedExpression());
 }
 /**
  * Test cloning
  *
  * @return void
  */
 public function testClone()
 {
     $expr = new QueryExpression();
     $expr->eq('test', 'true');
     $expr2 = new QueryExpression();
     $expr2->eq('test2', 'false');
     $caseExpression = new CaseExpression([$expr, $expr2], 'foobar');
     $dupe = clone $caseExpression;
     $dupe->elseValue('nope');
     $this->assertNotEquals($caseExpression, $dupe);
     $this->assertNotSame($caseExpression, $dupe);
 }
 /**
  * Tests that the query expression uses the type map when the
  * specific comparison functions are used.
  *
  * @dataProvider methodsProvider
  * @return void
  */
 public function testTypeMapUsage($method)
 {
     $expr = new QueryExpression([], ['created' => 'date']);
     $expr->{$method}('created', 'foo');
     $binder = new ValueBinder();
     $expr->sql($binder);
     $bindings = $binder->bindings();
     $type = current($bindings)['type'];
     $this->assertEquals('date', $type);
 }
Exemple #13
0
 /**
  * Deletes/sets null the related objects matching $conditions.
  * The action which is taken depends on the dependency between source and targets and also on foreign key nullability
  *
  * @param array $foreignKey array of foreign key properties
  * @param \Cake\ORM\Table $target The associated table
  * @param array $conditions The conditions that specifies what are the objects to be unlinked
  * @param array $options list of options accepted by `Table::delete()`
  * @return bool success
  */
 protected function _unlink(array $foreignKey, Table $target, array $conditions = [], array $options = [])
 {
     $mustBeDependent = !$this->_foreignKeyAcceptsNull($target, $foreignKey) || $this->dependent();
     if ($mustBeDependent) {
         if ($this->_cascadeCallbacks) {
             $conditions = new QueryExpression($conditions);
             $conditions->traverse(function ($entry) use($target) {
                 if ($entry instanceof FieldInterface) {
                     $entry->setField($target->aliasField($entry->getField()));
                 }
             });
             $query = $this->find('all')->where($conditions);
             $ok = true;
             foreach ($query as $assoc) {
                 $ok = $ok && $target->delete($assoc, $options);
             }
             return $ok;
         }
         $target->deleteAll($conditions);
         return true;
     }
     $updateFields = array_fill_keys($foreignKey, null);
     $target->updateAll($updateFields, $conditions);
     return true;
 }
 /**
  * Tests that it is possible to bind arguments to a query and it will return the right
  * results
  *
  * @return void
  */
 public function testCustomBindings()
 {
     $table = TableRegistry::get('Articles');
     $query = $table->find()->where(['id >' => 1]);
     $query->where(function ($exp) {
         $e = new QueryExpression();
         return $exp->add($e->eq(new IdentifierExpression('author_id'), new IdentifierExpression(':author')));
     });
     $query->bind(':author', 1, 'integer');
     $this->assertEquals(1, $query->count());
     $this->assertEquals(3, $query->first()->id);
 }