562 lines
16 KiB
PHP
562 lines
16 KiB
PHP
<?php
|
|
/**
|
|
* Author: Nil Portugués Calderó <contact@nilportugues.com>
|
|
* Date: 9/13/14
|
|
* Time: 12:46 AM.
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace NilPortugues\Tests\Sql\QueryBuilder\Builder\Syntax;
|
|
|
|
use NilPortugues\Sql\QueryBuilder\Builder\GenericBuilder;
|
|
use NilPortugues\Sql\QueryBuilder\Manipulation\Select;
|
|
|
|
/**
|
|
* Class WhereWriterTest.
|
|
*/
|
|
class WhereWriterTest extends \PHPUnit_Framework_TestCase
|
|
{
|
|
/**
|
|
* @var GenericBuilder
|
|
*/
|
|
private $writer;
|
|
|
|
/**
|
|
* @var Select
|
|
*/
|
|
private $query;
|
|
|
|
/**
|
|
*
|
|
*/
|
|
protected function setUp()
|
|
{
|
|
$this->writer = new GenericBuilder();
|
|
$this->query = new Select();
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function itShouldAllowWhereConditions()
|
|
{
|
|
$this->query
|
|
->setTable('user')
|
|
->where()
|
|
->equals('user_id', 1)
|
|
->like('name', '%N%');
|
|
|
|
$expected = 'SELECT user.* FROM user WHERE (user.user_id = :v1) AND (user.name LIKE :v2)';
|
|
$this->assertSame($expected, $this->writer->write($this->query));
|
|
|
|
$expected = array(':v1' => 1, ':v2' => '%N%');
|
|
$this->assertEquals($expected, $this->writer->getValues());
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function itShouldAllowWhereOrConditions()
|
|
{
|
|
$this->query
|
|
->setTable('user')
|
|
->where('OR')
|
|
->equals('user_id', 1)
|
|
->like('name', '%N%');
|
|
|
|
$this->assertSame('OR', $this->query->getWhereOperator());
|
|
|
|
$expected = 'SELECT user.* FROM user WHERE (user.user_id = :v1) OR (user.name LIKE :v2)';
|
|
$this->assertSame($expected, $this->writer->write($this->query));
|
|
|
|
$expected = array(':v1' => 1, ':v2' => '%N%');
|
|
$this->assertEquals($expected, $this->writer->getValues());
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function itShouldBeAbleToLetWhereStatementNotBeEqualTo()
|
|
{
|
|
$column = 'user_id';
|
|
$value = 1;
|
|
|
|
$this->query
|
|
->setTable('user')
|
|
->where()
|
|
->notEquals($column, $value);
|
|
|
|
$expected = 'SELECT user.* FROM user WHERE (user.user_id <> :v1)';
|
|
$this->assertSame($expected, $this->writer->write($this->query));
|
|
|
|
$expected = array(':v1' => 1);
|
|
$this->assertEquals($expected, $this->writer->getValues());
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function itShouldBeAbleToLetWhereStatementBeGreaterThan()
|
|
{
|
|
$column = 'user_id';
|
|
$value = 1;
|
|
|
|
$this->query
|
|
->setTable('user')
|
|
->where()
|
|
->greaterThan($column, $value);
|
|
|
|
$expected = 'SELECT user.* FROM user WHERE (user.user_id > :v1)';
|
|
$this->assertSame($expected, $this->writer->write($this->query));
|
|
|
|
$expected = array(':v1' => 1);
|
|
$this->assertEquals($expected, $this->writer->getValues());
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function itShouldBeAbleToLetWhereStatementBeGreaterThanOrEqual()
|
|
{
|
|
$column = 'user_id';
|
|
$value = 1;
|
|
|
|
$this->query
|
|
->setTable('user')
|
|
->where()
|
|
->greaterThanOrEqual($column, $value);
|
|
|
|
$expected = 'SELECT user.* FROM user WHERE (user.user_id >= :v1)';
|
|
$this->assertSame($expected, $this->writer->write($this->query));
|
|
|
|
$expected = array(':v1' => 1);
|
|
$this->assertEquals($expected, $this->writer->getValues());
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function itShouldBeAbleToLetWhereStatementBeLessThan()
|
|
{
|
|
$column = 'user_id';
|
|
$value = 1;
|
|
|
|
$this->query
|
|
->setTable('user')
|
|
->where()
|
|
->lessThan($column, $value);
|
|
|
|
$expected = 'SELECT user.* FROM user WHERE (user.user_id < :v1)';
|
|
$this->assertSame($expected, $this->writer->write($this->query));
|
|
|
|
$expected = array(':v1' => 1);
|
|
$this->assertEquals($expected, $this->writer->getValues());
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function itShouldBeAbleToLetWhereStatementBeLessThanOrEqual()
|
|
{
|
|
$column = 'user_id';
|
|
$value = 1;
|
|
|
|
$this->query
|
|
->setTable('user')
|
|
->where()
|
|
->lessThanOrEqual($column, $value);
|
|
|
|
$expected = 'SELECT user.* FROM user WHERE (user.user_id <= :v1)';
|
|
$this->assertSame($expected, $this->writer->write($this->query));
|
|
|
|
$expected = array(':v1' => 1);
|
|
$this->assertEquals($expected, $this->writer->getValues());
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function itShouldBeAbleToLetWhereStatementBeLike()
|
|
{
|
|
$column = 'user_id';
|
|
$value = 1;
|
|
|
|
$this->query
|
|
->setTable('user')
|
|
->where()
|
|
->like($column, $value);
|
|
|
|
$expected = 'SELECT user.* FROM user WHERE (user.user_id LIKE :v1)';
|
|
$this->assertSame($expected, $this->writer->write($this->query));
|
|
|
|
$expected = array(':v1' => 1);
|
|
$this->assertEquals($expected, $this->writer->getValues());
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function itShouldBeAbleToLetWhereStatementBeNotLike()
|
|
{
|
|
$column = 'user_id';
|
|
$value = 1;
|
|
|
|
$this->query
|
|
->setTable('user')
|
|
->where()
|
|
->notLike($column, $value);
|
|
|
|
$expected = 'SELECT user.* FROM user WHERE (user.user_id NOT LIKE :v1)';
|
|
$this->assertSame($expected, $this->writer->write($this->query));
|
|
|
|
$expected = array(':v1' => 1);
|
|
$this->assertEquals($expected, $this->writer->getValues());
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function itShouldBeAbleToLetWhereStatementAccumulateInConditions()
|
|
{
|
|
$column = 'user_id';
|
|
|
|
$this->query
|
|
->setTable('user')
|
|
->where()
|
|
->in($column, array(1, 2, 3));
|
|
|
|
$expected = 'SELECT user.* FROM user WHERE (user.user_id IN (:v1, :v2, :v3))';
|
|
$this->assertSame($expected, $this->writer->write($this->query));
|
|
|
|
$expected = array(':v1' => 1, ':v2' => 2, ':v3' => 3);
|
|
$this->assertEquals($expected, $this->writer->getValues());
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function itShouldBeAbleToLetWhereStatementAccumulateNotInConditions()
|
|
{
|
|
$column = 'user_id';
|
|
|
|
$this->query
|
|
->setTable('user')
|
|
->where()
|
|
->notIn($column, array(1, 2, 3));
|
|
|
|
$expected = 'SELECT user.* FROM user WHERE (user.user_id NOT IN (:v1, :v2, :v3))';
|
|
$this->assertSame($expected, $this->writer->write($this->query));
|
|
|
|
$expected = array(':v1' => 1, ':v2' => 2, ':v3' => 3);
|
|
$this->assertEquals($expected, $this->writer->getValues());
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function itShouldBeAbleToLetWhereStatementWriteBetweenConditions()
|
|
{
|
|
$column = 'user_id';
|
|
|
|
$this->query
|
|
->setTable('user')
|
|
->where()
|
|
->between($column, 1, 2);
|
|
|
|
$expected = 'SELECT user.* FROM user WHERE (user.user_id BETWEEN :v1 AND :v2)';
|
|
$this->assertSame($expected, $this->writer->write($this->query));
|
|
|
|
$expected = array(':v1' => 1, ':v2' => 2);
|
|
$this->assertEquals($expected, $this->writer->getValues());
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function itShouldBeAbleToLetWhereStatementWriteNotBetweenConditions()
|
|
{
|
|
$column = 'user_id';
|
|
|
|
$this->query
|
|
->setTable('user')
|
|
->where()
|
|
->notBetween($column, 1, 2);
|
|
|
|
$expected = 'SELECT user.* FROM user WHERE (user.user_id NOT BETWEEN :v1 AND :v2)';
|
|
$this->assertSame($expected, $this->writer->write($this->query));
|
|
|
|
$expected = array(':v1' => 1, ':v2' => 2);
|
|
$this->assertEquals($expected, $this->writer->getValues());
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function itShouldBeAbleToLetWhereStatementSetNullValueCondition()
|
|
{
|
|
$column = 'user_id';
|
|
|
|
$this->query
|
|
->setTable('user')
|
|
->where()
|
|
->isNull($column);
|
|
|
|
$expected = 'SELECT user.* FROM user WHERE (user.user_id IS NULL)';
|
|
$this->assertSame($expected, $this->writer->write($this->query));
|
|
|
|
$expected = array();
|
|
$this->assertEquals($expected, $this->writer->getValues());
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function itShouldBeAbleToLetWhereStatementSetIsNotNullValueCondition()
|
|
{
|
|
$column = 'user_id';
|
|
|
|
$this->query
|
|
->setTable('user')
|
|
->where()
|
|
->isNotNull($column);
|
|
|
|
$expected = 'SELECT user.* FROM user WHERE (user.user_id IS NOT NULL)';
|
|
$this->assertSame($expected, $this->writer->write($this->query));
|
|
|
|
$expected = array();
|
|
$this->assertEquals($expected, $this->writer->getValues());
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function itShouldBeAbleToLetWhereStatementSetBitClauseValueCondition()
|
|
{
|
|
$column = 'user_id';
|
|
|
|
$this->query
|
|
->setTable('user')
|
|
->where()
|
|
->addBitClause($column, 1);
|
|
|
|
$expected = 'SELECT user.* FROM user WHERE (ISNULL(user.user_id, 0) = :v1)';
|
|
$this->assertSame($expected, $this->writer->write($this->query));
|
|
|
|
$expected = array(':v1' => 1);
|
|
$this->assertEquals($expected, $this->writer->getValues());
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function itShouldBeAbleToLetWhereStatementSubconditions()
|
|
{
|
|
$column = 'user_id';
|
|
|
|
$this->query
|
|
->setTable('user')
|
|
->where()
|
|
->equals($column, 1)
|
|
->equals($column, 2)
|
|
->subWhere('OR')
|
|
->lessThan($column, 10)
|
|
->greaterThan($column, 100);
|
|
|
|
$expected = 'SELECT user.* FROM user WHERE (user.user_id = :v1) AND (user.user_id = :v2) '.
|
|
'AND ((user.user_id < :v3) OR (user.user_id > :v4))';
|
|
|
|
$this->assertSame($expected, $this->writer->write($this->query));
|
|
|
|
$expected = array(':v1' => 1, ':v2' => 2, ':v3' => 10, ':v4' => 100);
|
|
$this->assertEquals($expected, $this->writer->getValues());
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function itShouldAllowSelectWhereButNotWriteCondition()
|
|
{
|
|
$table1 = new Select('Table1');
|
|
$table1
|
|
->where();
|
|
|
|
$expected = 'SELECT Table1.* FROM Table1';
|
|
$this->assertSame($expected, $this->writer->write($table1));
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function itShouldAllowHavingConditions()
|
|
{
|
|
$this->query
|
|
->setTable('user')
|
|
->having()
|
|
->greaterThan('user_id', 1)
|
|
->like('name', '%N%');
|
|
|
|
$expected = 'SELECT user.* FROM user HAVING (user.user_id > :v1) AND (user.name LIKE :v2)';
|
|
$this->assertSame($expected, $this->writer->write($this->query));
|
|
|
|
$expected = array(':v1' => 1, ':v2' => '%N%');
|
|
$this->assertEquals($expected, $this->writer->getValues());
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function itShouldBeAbleToUseSelectStatementsInWhere()
|
|
{
|
|
$selectRole = new Select();
|
|
$selectRole
|
|
->setTable('role')
|
|
->setColumns(array('role_name'))
|
|
->limit(1)
|
|
->where()
|
|
->equals('role_id', 3);
|
|
|
|
$this->query
|
|
->setTable('user')
|
|
->setColumns(array('user_id', 'role_id'))
|
|
->where()
|
|
->equals('role_id', $selectRole);
|
|
|
|
$expected = 'SELECT user.user_id, user.role_id FROM user WHERE '.
|
|
'(user.role_id = (SELECT role.role_name FROM role WHERE (role.role_id = :v1) LIMIT :v2, :v3))';
|
|
|
|
$this->assertSame($expected, $this->writer->write($this->query));
|
|
|
|
$expected = array(':v1' => 3, ':v2' => 1, ':v3' => 0);
|
|
$this->assertEquals($expected, $this->writer->getValues());
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function itShouldBeAbleToSelectWithFullMatchSearchUsingMatchInNaturalMode()
|
|
{
|
|
$this->query
|
|
->setTable('user')
|
|
->setColumns(array('user_id', 'role_id'))
|
|
->where()
|
|
->match(array('username', 'email'), array('Nil'));
|
|
|
|
$expected = 'SELECT user.user_id, user.role_id FROM user '.
|
|
'WHERE (MATCH(user.username, user.email) AGAINST(:v1))';
|
|
|
|
$this->assertSame($expected, $this->writer->write($this->query));
|
|
|
|
$expected = array(':v1' => 'Nil');
|
|
$this->assertEquals($expected, $this->writer->getValues());
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function itShouldBeAbleToSelectWithFullMatchSearchUsingMatchInBooleanMode()
|
|
{
|
|
$this->query
|
|
->setTable('user')
|
|
->setColumns(array('user_id', 'role_id'))
|
|
->where()
|
|
->matchBoolean(array('username', 'email'), array('Nil'));
|
|
|
|
$expected = 'SELECT user.user_id, user.role_id FROM user '.
|
|
'WHERE (MATCH(user.username, user.email) AGAINST(:v1 IN BOOLEAN MODE))';
|
|
|
|
$this->assertSame($expected, $this->writer->write($this->query));
|
|
|
|
$expected = array(':v1' => 'Nil');
|
|
$this->assertEquals($expected, $this->writer->getValues());
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function itShouldBeAbleToSelectWithFullMatchSearchUsingMatchInQueryExpansionMode()
|
|
{
|
|
$this->query
|
|
->setTable('user')
|
|
->setColumns(array('user_id', 'role_id'))
|
|
->where()
|
|
->matchWithQueryExpansion(array('username', 'email'), array('Nil'));
|
|
|
|
$expected = 'SELECT user.user_id, user.role_id FROM user '.
|
|
'WHERE (MATCH(user.username, user.email) AGAINST(:v1 WITH QUERY EXPANSION))';
|
|
|
|
$this->assertSame($expected, $this->writer->write($this->query));
|
|
|
|
$expected = array(':v1' => 'Nil');
|
|
$this->assertEquals($expected, $this->writer->getValues());
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function itShouldBeAbleToDoWhereExists()
|
|
{
|
|
$select = new Select('banned_user');
|
|
$select->where()->equals('user_id', 1);
|
|
|
|
$this->query
|
|
->setTable('user')
|
|
->setColumns(array('user_id', 'role_id'))
|
|
->where()
|
|
->exists($select)
|
|
->equals('user', 'Nil');
|
|
|
|
$expected = 'SELECT user.user_id, user.role_id FROM user WHERE (user.user = :v1) AND '.
|
|
'EXISTS (SELECT banned_user.* FROM banned_user WHERE (banned_user.user_id = :v2))';
|
|
|
|
$this->assertSame($expected, $this->writer->write($this->query));
|
|
|
|
$expected = array(':v1' => 'Nil', ':v2' => 1);
|
|
$this->assertEquals($expected, $this->writer->getValues());
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function itShouldBeAbleToDoWhereNotExists()
|
|
{
|
|
$select = new Select('banned_user');
|
|
$select->where()->equals('user_id', 1);
|
|
|
|
$this->query
|
|
->setTable('user')
|
|
->setColumns(array('user_id', 'role_id'))
|
|
->where()
|
|
->notExists($select)
|
|
->equals('user', 'Nil');
|
|
|
|
$expected = 'SELECT user.user_id, user.role_id FROM user WHERE (user.user = :v1) AND '.
|
|
'NOT EXISTS (SELECT banned_user.* FROM banned_user WHERE (banned_user.user_id = :v2))';
|
|
|
|
$this->assertSame($expected, $this->writer->write($this->query));
|
|
|
|
$expected = array(':v1' => 'Nil', ':v2' => 1);
|
|
$this->assertEquals($expected, $this->writer->getValues());
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function itShouldAllowWhereConditionAsLiteral()
|
|
{
|
|
$this->query
|
|
->setTable('user')
|
|
->where()
|
|
->asLiteral('(username is not null and status=:status)')
|
|
->notEquals('name', '%N%');
|
|
|
|
$expected = 'SELECT user.* FROM user WHERE (username is not null and status=:status) AND (user.name <> :v1)';
|
|
|
|
$this->assertSame($expected, $this->writer->write($this->query));
|
|
|
|
$expected = array(':v1' => '%N%');
|
|
$this->assertEquals($expected, $this->writer->getValues());
|
|
}
|
|
}
|