[2.0] Initial commit of a QueryBuilder class. Still needs a lot of work.
This commit is contained in:
parent
2ffc7f17db
commit
867a34d41b
483
lib/Doctrine/ORM/Query/Expr.php
Normal file
483
lib/Doctrine/ORM/Query/Expr.php
Normal file
@ -0,0 +1,483 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM\Query;
|
||||
|
||||
/**
|
||||
* This class is used to generate DQL expressions via a set of PHP static functions
|
||||
*
|
||||
* @author Jonathan H. Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link http://www.phpdoctrine.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
*/
|
||||
class Expr
|
||||
{
|
||||
private static $_methodMap = array(
|
||||
'avg' => '_avgExpr',
|
||||
'max' => '_maxExpr',
|
||||
'min' => '_minExpr',
|
||||
'count' => '_countExpr',
|
||||
'countDistinct' => '_countDistinctExpr',
|
||||
'exists' => '_existsExpr',
|
||||
'all' => '_allExpr',
|
||||
'some' => '_someExpr',
|
||||
'any' => '_anyExpr',
|
||||
'not' => '_notExpr',
|
||||
'and' => '_andExpr',
|
||||
'or' => '_orExpr',
|
||||
'abs' => '_absExpr',
|
||||
'prod' => '_prodExpr',
|
||||
'diff' => '_diffExpr',
|
||||
'sum' => '_sumExpr',
|
||||
'quot' => '_quotientExpr',
|
||||
'sqrt' => '_squareRootExpr',
|
||||
'eq' => '_equalExpr',
|
||||
'in' => '_inExpr',
|
||||
'notIn' => '_notInExpr',
|
||||
'notEqual' => '_notEqualExpr',
|
||||
'like' => '_likeExpr',
|
||||
'concat' => '_concatExpr',
|
||||
'substr' => '_substrExpr',
|
||||
'lower' => '_lowerExpr',
|
||||
'upper' => '_upperExpr',
|
||||
'length' => '_lengthExpr',
|
||||
'gt' => '_greaterThanExpr',
|
||||
'lt' => '_lessThanExpr',
|
||||
'path' => '_pathExpr',
|
||||
'literal' => '_literalExpr',
|
||||
'gtoet' => '_greaterThanOrEqualToExpr',
|
||||
'ltoet' => '_lessThanOrEqualToExpr',
|
||||
'between' => '_betweenExpr',
|
||||
'trim' => '_trimExpr'
|
||||
);
|
||||
|
||||
private $_type;
|
||||
private $_parts;
|
||||
|
||||
protected function __construct($type, array $parts)
|
||||
{
|
||||
$this->_type = $type;
|
||||
$this->_parts = $parts;
|
||||
}
|
||||
|
||||
public function getDql()
|
||||
{
|
||||
return $this->{self::$_methodMap[$this->_type]}();
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getDql();
|
||||
}
|
||||
|
||||
private function _avgExpr()
|
||||
{
|
||||
return 'AVG(' . $this->_parts[0] . ')';
|
||||
}
|
||||
|
||||
private function _maxExpr()
|
||||
{
|
||||
return 'MAX(' . $this->_parts[0] . ')';
|
||||
}
|
||||
|
||||
private function _minExpr()
|
||||
{
|
||||
return 'MIN(' . $this->_parts[0] . ')';
|
||||
}
|
||||
|
||||
private function _countExpr()
|
||||
{
|
||||
return 'COUNT(' . $this->_parts[0] . ')';
|
||||
}
|
||||
|
||||
private function _countDistinctExpr()
|
||||
{
|
||||
return 'COUNT(DISTINCT ' . $this->_parts[0] . ')';
|
||||
}
|
||||
|
||||
private function _existsExpr()
|
||||
{
|
||||
return 'EXISTS(' . $this->_parts[0] . ')';
|
||||
}
|
||||
|
||||
private function _allExpr()
|
||||
{
|
||||
return 'ALL(' . $this->_parts[0] . ')';
|
||||
}
|
||||
|
||||
private function _someExpr()
|
||||
{
|
||||
return 'SOME(' . $this->_parts[0] . ')';
|
||||
}
|
||||
|
||||
private function _anyExpr()
|
||||
{
|
||||
return 'ANY(' . $this->_parts[0] . ')';
|
||||
}
|
||||
|
||||
private function _notExpr()
|
||||
{
|
||||
return 'NOT(' . $this->_parts[0] . ')';
|
||||
}
|
||||
|
||||
private function _andExpr()
|
||||
{
|
||||
return '(' . $this->_parts[0] . ' AND ' . $this->_parts[1] . ')';
|
||||
}
|
||||
|
||||
private function _orExpr()
|
||||
{
|
||||
return '(' . $this->_parts[0] . ' OR ' . $this->_parts[1] . ')';
|
||||
}
|
||||
|
||||
private function _absExpr()
|
||||
{
|
||||
return 'ABS(' . $this->_parts[0] . ')';
|
||||
}
|
||||
|
||||
private function _prodExpr()
|
||||
{
|
||||
return '(' . $this->_parts[0] . ' * ' . $this->_parts[1] . ')';
|
||||
}
|
||||
|
||||
private function _diffExpr()
|
||||
{
|
||||
return '(' . $this->_parts[0] . ' - ' . $this->_parts[1] . ')';
|
||||
}
|
||||
|
||||
private function _sumExpr()
|
||||
{
|
||||
return '(' . $this->_parts[0] . ' + ' . $this->_parts[1] . ')';
|
||||
}
|
||||
|
||||
private function _quotientExpr()
|
||||
{
|
||||
return '(' . $this->_parts[0] . ' / ' . $this->_parts[1] . ')';
|
||||
}
|
||||
|
||||
private function _squareRootExpr()
|
||||
{
|
||||
return 'SQRT(' . $this->_parts[0] . ')';
|
||||
}
|
||||
|
||||
private function _equalExpr()
|
||||
{
|
||||
return $this->_parts[0] . ' = ' . $this->_parts[1];
|
||||
}
|
||||
|
||||
private function _inExpr()
|
||||
{
|
||||
return $this->_parts[0] . ' IN(' . implode(', ', $this->_parts[1]) . ')';
|
||||
}
|
||||
|
||||
private function _notInExpr()
|
||||
{
|
||||
return $this->_parts[0] . ' NOT IN(' . implode(', ', $this->_parts[1]) . ')';
|
||||
}
|
||||
|
||||
private function _notEqualExpr()
|
||||
{
|
||||
return $this->_parts[0] . ' != ' . $this->_parts[1];
|
||||
}
|
||||
|
||||
private function _likeExpr()
|
||||
{
|
||||
// TODO: How should we use $escapeChar which is in $this->_parts[2]
|
||||
return '(' . $this->_parts[0] . ' LIKE ' . $this->_parts[1] . ')';
|
||||
}
|
||||
|
||||
private function _concatExpr()
|
||||
{
|
||||
return 'CONCAT(' . $this->_parts[0] . ', ' . $this->_parts[1] . ')';
|
||||
}
|
||||
|
||||
private function _substrExpr()
|
||||
{
|
||||
return 'SUBSTR(' . $this->_parts[0] . ', ' . $this->_parts[1] . ', ' . $this->_parts[2] . ')';
|
||||
}
|
||||
|
||||
private function _lowerExpr()
|
||||
{
|
||||
return 'LOWER(' . $this->_parts[0] . ')';
|
||||
}
|
||||
|
||||
private function _upperExpr()
|
||||
{
|
||||
return 'UPPER(' . $this->_parts[0] . ')';
|
||||
}
|
||||
|
||||
private function _lengthExpr()
|
||||
{
|
||||
return 'LENGTH(' . $this->_parts[0] . ')';
|
||||
}
|
||||
|
||||
private function _greaterThanExpr()
|
||||
{
|
||||
return $this->_parts[0] . ' > ' . $this->_parts[1];
|
||||
}
|
||||
|
||||
private function _lessThanExpr()
|
||||
{
|
||||
return $this->_parts[0] . ' < ' . $this->_parts[1];
|
||||
}
|
||||
|
||||
private function _pathExpr()
|
||||
{
|
||||
// TODO: What is this?
|
||||
}
|
||||
|
||||
private function _literalExpr()
|
||||
{
|
||||
if (is_numeric($this->_parts[0])) {
|
||||
return (string) $this->_parts[0];
|
||||
} else {
|
||||
return "'" . $this->_parts[0] . "'";
|
||||
}
|
||||
}
|
||||
|
||||
private function _greaterThanOrEqualToExpr()
|
||||
{
|
||||
return $this->_parts[0] . ' >= ' . $this->_parts[1];
|
||||
}
|
||||
|
||||
private function _lessThanOrEqualToExpr()
|
||||
{
|
||||
return $this->_parts[0] . ' <= ' . $this->_parts[1];
|
||||
}
|
||||
|
||||
private function _betweenExpr()
|
||||
{
|
||||
return 'BETWEEN(' . $this->_parts[0] . ', ' . $this->_parts[1] . ', ' . $this->_parts[2] . ')';
|
||||
}
|
||||
|
||||
private function _ltExpr()
|
||||
{
|
||||
return '(' . $this->_parts[0] . ' < ' . $this->_parts[1] . ')';
|
||||
}
|
||||
|
||||
private function _trimExpr()
|
||||
{
|
||||
return 'TRIM(' . $this->_parts[0] . ')';
|
||||
}
|
||||
|
||||
public static function avg($x)
|
||||
{
|
||||
return new self('avg', array($x));
|
||||
}
|
||||
|
||||
public static function max($x)
|
||||
{
|
||||
return new self('max', array($x));
|
||||
}
|
||||
|
||||
public static function min($x)
|
||||
{
|
||||
return new self('min', array($x));
|
||||
}
|
||||
|
||||
public static function count($x)
|
||||
{
|
||||
return new self('count', array($x));
|
||||
}
|
||||
|
||||
public static function countDistinct($x)
|
||||
{
|
||||
return new self('countDistinct', array($x));
|
||||
}
|
||||
|
||||
public static function exists($subquery)
|
||||
{
|
||||
return new self('exists', array($subquery));
|
||||
}
|
||||
|
||||
public static function all($subquery)
|
||||
{
|
||||
return new self('all', array($subquery));
|
||||
}
|
||||
|
||||
public static function some($subquery)
|
||||
{
|
||||
return new self('some', array($subquery));
|
||||
}
|
||||
|
||||
public static function any($subquery)
|
||||
{
|
||||
return new self('any', array($subquery));
|
||||
}
|
||||
|
||||
public static function not($restriction)
|
||||
{
|
||||
return new self('not', array($restriction));
|
||||
}
|
||||
|
||||
public static function andx($x, $y)
|
||||
{
|
||||
return new self('and', array($x, $y));
|
||||
}
|
||||
|
||||
public static function orx($x, $y)
|
||||
{
|
||||
return new self('or', array($x, $y));
|
||||
}
|
||||
|
||||
public static function abs($x)
|
||||
{
|
||||
return new self('abs', array($x));
|
||||
}
|
||||
|
||||
public static function prod($x, $y)
|
||||
{
|
||||
return new self('prod', array($x, $y));
|
||||
}
|
||||
|
||||
public static function diff($x, $y)
|
||||
{
|
||||
return new self('diff', array($x, $y));
|
||||
}
|
||||
|
||||
public static function sum($x, $y)
|
||||
{
|
||||
return new self('sum', array($x, $y));
|
||||
}
|
||||
|
||||
public static function quot($x, $y)
|
||||
{
|
||||
return new self('quot', array($x, $y));
|
||||
}
|
||||
|
||||
public static function sqrt($x)
|
||||
{
|
||||
return new self('sqrt', array($x));
|
||||
}
|
||||
|
||||
public static function eq($x, $y)
|
||||
{
|
||||
return new self('eq', array($x, $y));
|
||||
}
|
||||
|
||||
public static function in($x, $y)
|
||||
{
|
||||
return new self('in', array($x, $y));
|
||||
}
|
||||
|
||||
public static function notIn($x, $y)
|
||||
{
|
||||
return new self('notIn', array($x, $y));
|
||||
}
|
||||
|
||||
public static function notEqual($x, $y)
|
||||
{
|
||||
return new self('notEqual', array($x, $y));
|
||||
}
|
||||
|
||||
public static function like($x, $pattern, $escapeChar = null)
|
||||
{
|
||||
return new self('like', array($x, $pattern, $escapeChar));
|
||||
}
|
||||
|
||||
public static function concat($x, $y)
|
||||
{
|
||||
return new self('concat', array($x, $y));
|
||||
}
|
||||
|
||||
public static function substr($x, $from = null, $len = null)
|
||||
{
|
||||
return new self('substr', array($x, $from, $len));
|
||||
}
|
||||
|
||||
public static function lower($x)
|
||||
{
|
||||
return new self('lower', array($x));
|
||||
}
|
||||
|
||||
public static function upper($x)
|
||||
{
|
||||
return new self('upper', array($x));
|
||||
}
|
||||
|
||||
public static function length($x)
|
||||
{
|
||||
return new self('length', array($x));
|
||||
}
|
||||
|
||||
public static function gt($x, $y)
|
||||
{
|
||||
return new self('gt', array($x, $y));
|
||||
}
|
||||
|
||||
public static function greaterThan($x, $y)
|
||||
{
|
||||
return new self('gt', array($x, $y));
|
||||
}
|
||||
|
||||
public static function lt($x, $y)
|
||||
{
|
||||
return new self('lt', array($x, $y));
|
||||
}
|
||||
|
||||
public static function lessThan($x, $y)
|
||||
{
|
||||
return new self('lt', array($x, $y));
|
||||
}
|
||||
|
||||
public static function path($path)
|
||||
{
|
||||
return new self('path', array($path));
|
||||
}
|
||||
|
||||
public static function literal($literal)
|
||||
{
|
||||
return new self('literal', array($literal));
|
||||
}
|
||||
|
||||
public static function greaterThanOrEqualTo($x, $y)
|
||||
{
|
||||
return new self('gtoet', array($x, $y));
|
||||
}
|
||||
|
||||
public static function gtoet($x, $y)
|
||||
{
|
||||
return new self('gtoet', array($x, $y));
|
||||
}
|
||||
|
||||
public static function lessThanOrEqualTo($x, $y)
|
||||
{
|
||||
return new self('ltoet', array($x, $y));
|
||||
}
|
||||
|
||||
public static function ltoet($x, $y)
|
||||
{
|
||||
return new self('ltoet', array($x, $y));
|
||||
}
|
||||
|
||||
public static function between($val, $x, $y)
|
||||
{
|
||||
return new self('between', array($val, $x, $y));
|
||||
}
|
||||
|
||||
public static function trim($val, $spec = null, $char = null)
|
||||
{
|
||||
return new self('trim', array($val, $spec, $char));
|
||||
}
|
||||
}
|
357
lib/Doctrine/ORM/QueryBuilder.php
Normal file
357
lib/Doctrine/ORM/QueryBuilder.php
Normal file
@ -0,0 +1,357 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM;
|
||||
|
||||
use Doctrine\ORM\Query\Expr;
|
||||
|
||||
/**
|
||||
* This class is responsible for building DQL query strings via a object oriented
|
||||
* PHP interface
|
||||
*
|
||||
* TODO: I don't like the API of using the Expr::*() syntax inside of the QueryBuilder
|
||||
* methods. What can we do to allow them to do it more fluently with the QueryBuilder.
|
||||
*
|
||||
* @author Jonathan H. Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link http://www.phpdoctrine.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
*/
|
||||
class QueryBuilder
|
||||
{
|
||||
const SELECT = 0;
|
||||
const DELETE = 1;
|
||||
const UPDATE = 2;
|
||||
|
||||
const STATE_DIRTY = 0;
|
||||
const STATE_CLEAN = 1;
|
||||
|
||||
protected $_entityManager;
|
||||
protected $_dqlParts = array(
|
||||
'select' => array(),
|
||||
'from' => array(),
|
||||
'where' => array(),
|
||||
'groupBy' => array(),
|
||||
'having' => array(),
|
||||
'orderBy' => array(),
|
||||
'limit' => array(),
|
||||
'offset' => array()
|
||||
);
|
||||
protected $_type = self::SELECT;
|
||||
protected $_state = self::STATE_CLEAN;
|
||||
protected $_dql;
|
||||
|
||||
public function __construct(EntityManager $entityManager)
|
||||
{
|
||||
$this->_entityManager = $entityManager;
|
||||
}
|
||||
|
||||
public static function create(EntityManager $entityManager)
|
||||
{
|
||||
return new self($entityManager);
|
||||
}
|
||||
|
||||
public function getType()
|
||||
{
|
||||
return $this->_type;
|
||||
}
|
||||
|
||||
public function getState()
|
||||
{
|
||||
return $this->_state;
|
||||
}
|
||||
|
||||
public function getDql()
|
||||
{
|
||||
if ($this->_dql !== null && self::STATE_CLEAN) {
|
||||
return $this->_dql;
|
||||
}
|
||||
|
||||
$dql = '';
|
||||
|
||||
switch ($this->_type) {
|
||||
case self::DELETE:
|
||||
$dql = $this->_getDqlForDelete();
|
||||
break;
|
||||
|
||||
case self::UPDATE:
|
||||
$dql = $this->_getDqlForUpdate();
|
||||
break;
|
||||
|
||||
case self::SELECT:
|
||||
default:
|
||||
$dql = $this->_getDqlForSelect();
|
||||
break;
|
||||
}
|
||||
|
||||
$this->_dql = $dql;
|
||||
|
||||
return $dql;
|
||||
}
|
||||
|
||||
public function getQuery()
|
||||
{
|
||||
$q = new Query($this->_entityManager);
|
||||
$q->setDql($this->getDql());
|
||||
|
||||
return $q;
|
||||
}
|
||||
|
||||
public function select($select = null)
|
||||
{
|
||||
$this->_type = self::SELECT;
|
||||
|
||||
if ( ! $select) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
return $this->_addDqlQueryPart('select', $select, true);
|
||||
}
|
||||
|
||||
public function delete($delete = null, $alias = null)
|
||||
{
|
||||
$this->_type = self::DELETE;
|
||||
|
||||
if ( ! $delete) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
return $this->_addDqlQueryPart('from', $delete . ' ' . $alias);
|
||||
}
|
||||
|
||||
public function update($update = null, $alias = null)
|
||||
{
|
||||
$this->_type = self::UPDATE;
|
||||
|
||||
if ( ! $update) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
return $this->_addDqlQueryPart('from', $update . ' ' . $alias);
|
||||
}
|
||||
|
||||
public function set($key, $value = null)
|
||||
{
|
||||
return $this->_addDqlQueryPart('set', $key . ' = ' . $value, true);
|
||||
}
|
||||
|
||||
public function from($from, $alias)
|
||||
{
|
||||
return $this->_addDqlQueryPart('from', $from . ' ' . $alias, true);
|
||||
}
|
||||
|
||||
public function join($join, $alias)
|
||||
{
|
||||
return $this->_addDqlQueryPart('from', 'INNER JOIN ' . $join . ' ' . $alias, true);
|
||||
}
|
||||
|
||||
public function innerJoin($join, $alias)
|
||||
{
|
||||
return $this->join($join, $alias);
|
||||
}
|
||||
|
||||
public function leftJoin($join, $alias)
|
||||
{
|
||||
return $this->_addDqlQueryPart('from', 'LEFT JOIN ' . $join . ' ' . $alias, true);
|
||||
}
|
||||
|
||||
public function where($where)
|
||||
{
|
||||
return $this->_addDqlQueryPart('where', $where, false);
|
||||
}
|
||||
|
||||
public function andWhere($where)
|
||||
{
|
||||
if (count($this->getDqlQueryPart('where')) > 0) {
|
||||
$this->_addDqlQueryPart('where', 'AND', true);
|
||||
}
|
||||
|
||||
return $this->_addDqlQueryPart('where', $where, true);
|
||||
}
|
||||
|
||||
public function orWhere($where)
|
||||
{
|
||||
if (count($this->getDqlQueryPart('where')) > 0) {
|
||||
$this->_addDqlQueryPart('where', 'OR', true);
|
||||
}
|
||||
|
||||
return $this->_addDqlQueryPart('where', $where, true);
|
||||
}
|
||||
|
||||
public function groupBy($groupBy)
|
||||
{
|
||||
return $this->_addDqlQueryPart('groupBy', $groupBy, false);
|
||||
}
|
||||
|
||||
public function having($having)
|
||||
{
|
||||
return $this->_addDqlQueryPart('having', $having, false);
|
||||
}
|
||||
|
||||
public function andHaving($having)
|
||||
{
|
||||
if (count($this->getDqlQueryPart('having')) > 0) {
|
||||
$this->_addDqlQueryPart('having', 'AND', true);
|
||||
}
|
||||
|
||||
return $this->_addDqlQueryPart('having', $having, true);
|
||||
}
|
||||
|
||||
public function orHaving($having)
|
||||
{
|
||||
if (count($this->getDqlQueryPart('having')) > 0) {
|
||||
$this->_addDqlQueryPart('having', 'OR', true);
|
||||
}
|
||||
|
||||
return $this->_addDqlQueryPart('having', $having, true);
|
||||
}
|
||||
|
||||
public function orderBy($sort, $order)
|
||||
{
|
||||
return $this->_addDqlQueryPart('orderBy', $sort . ' ' . $order, false);
|
||||
}
|
||||
|
||||
public function addOrderBy($sort, $order)
|
||||
{
|
||||
return $this->_addDqlQueryPart('orderBy', $sort . ' ' . $order, true);
|
||||
}
|
||||
|
||||
public function limit($limit)
|
||||
{
|
||||
return $this->_addDqlQueryPart('limit', $limit);
|
||||
}
|
||||
|
||||
public function offset($offset)
|
||||
{
|
||||
return $this->_addDqlQueryPart('offset', $offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the DQL query string for DELETE queries
|
||||
*
|
||||
* BNF:
|
||||
*
|
||||
* DeleteStatement = DeleteClause [WhereClause] [OrderByClause] [LimitClause] [OffsetClause]
|
||||
* DeleteClause = "DELETE" "FROM" RangeVariableDeclaration
|
||||
* WhereClause = "WHERE" ConditionalExpression
|
||||
* OrderByClause = "ORDER" "BY" OrderByItem {"," OrderByItem}
|
||||
* LimitClause = "LIMIT" integer
|
||||
* OffsetClause = "OFFSET" integer
|
||||
*
|
||||
* @return string $dql
|
||||
*/
|
||||
private function _getDqlForDelete()
|
||||
{
|
||||
return 'DELETE'
|
||||
. $this->_getReducedDqlQueryPart('from', array('pre' => ' ', 'separator' => ' '))
|
||||
. $this->_getReducedDqlQueryPart('where', array('pre' => ' WHERE ', 'separator' => ' '))
|
||||
. $this->_getReducedDqlQueryPart('orderBy', array('pre' => ' ORDER BY ', 'separator' => ', '))
|
||||
. $this->_getReducedDqlQueryPart('limit', array('pre' => ' LIMIT ', 'separator' => ' '))
|
||||
. $this->_getReducedDqlQueryPart('offset', array('pre' => ' OFFSET ', 'separator' => ' '));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the DQL query string for UPDATE queries
|
||||
*
|
||||
* BNF:
|
||||
*
|
||||
* UpdateStatement = UpdateClause [WhereClause] [OrderByClause] [LimitClause] [OffsetClause]
|
||||
* UpdateClause = "UPDATE" RangeVariableDeclaration "SET" UpdateItem {"," UpdateItem}
|
||||
* WhereClause = "WHERE" ConditionalExpression
|
||||
* OrderByClause = "ORDER" "BY" OrderByItem {"," OrderByItem}
|
||||
* LimitClause = "LIMIT" integer
|
||||
* OffsetClause = "OFFSET" integer
|
||||
*
|
||||
* @return string $dql
|
||||
*/
|
||||
private function _getDqlForUpdate()
|
||||
{
|
||||
return 'UPDATE'
|
||||
. $this->_getReducedDqlQueryPart('from', array('pre' => ' ', 'separator' => ' '))
|
||||
. $this->_getReducedDqlQueryPart('set', array('pre' => ' SET ', 'separator' => ', '))
|
||||
. $this->_getReducedDqlQueryPart('where', array('pre' => ' WHERE ', 'separator' => ' '))
|
||||
. $this->_getReducedDqlQueryPart('orderBy', array('pre' => ' ORDER BY ', 'separator' => ', '))
|
||||
. $this->_getReducedDqlQueryPart('limit', array('pre' => ' LIMIT ', 'separator' => ' '))
|
||||
. $this->_getReducedDqlQueryPart('offset', array('pre' => ' OFFSET ', 'separator' => ' '));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the DQL query string for SELECT queries
|
||||
*
|
||||
* BNF:
|
||||
*
|
||||
* SelectStatement = [SelectClause] FromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause] [LimitClause] [OffsetClause]
|
||||
* SelectClause = "SELECT" ["ALL" | "DISTINCT"] SelectExpression {"," SelectExpression}
|
||||
* FromClause = "FROM" IdentificationVariableDeclaration {"," IdentificationVariableDeclaration}
|
||||
* WhereClause = "WHERE" ConditionalExpression
|
||||
* GroupByClause = "GROUP" "BY" GroupByItem {"," GroupByItem}
|
||||
* HavingClause = "HAVING" ConditionalExpression
|
||||
* OrderByClause = "ORDER" "BY" OrderByItem {"," OrderByItem}
|
||||
* LimitClause = "LIMIT" integer
|
||||
* OffsetClause = "OFFSET" integer
|
||||
*
|
||||
* @return string $dql
|
||||
*/
|
||||
private function _getDqlForSelect()
|
||||
{
|
||||
return 'SELECT'
|
||||
. $this->_getReducedDqlQueryPart('select', array('pre' => ' ', 'separator' => ', '))
|
||||
. $this->_getReducedDqlQueryPart('from', array('pre' => ' FROM ', 'separator' => ' '))
|
||||
. $this->_getReducedDqlQueryPart('where', array('pre' => ' WHERE ', 'separator' => ' '))
|
||||
. $this->_getReducedDqlQueryPart('groupBy', array('pre' => ' GROUP BY ', 'separator' => ', '))
|
||||
. $this->_getReducedDqlQueryPart('having', array('pre' => ' HAVING ', 'separator' => ' '))
|
||||
. $this->_getReducedDqlQueryPart('orderBy', array('pre' => ' ORDER BY ', 'separator' => ', '))
|
||||
. $this->_getReducedDqlQueryPart('limit', array('pre' => ' LIMIT ', 'separator' => ' '))
|
||||
. $this->_getReducedDqlQueryPart('offset', array('pre' => ' OFFSET ', 'separator' => ' '));
|
||||
}
|
||||
|
||||
private function _getReducedDqlQueryPart($queryPartName, $options = array())
|
||||
{
|
||||
if (empty($this->_dqlParts[$queryPartName])) {
|
||||
return (isset($options['empty']) ? $options['empty'] : '');
|
||||
}
|
||||
|
||||
$str = (isset($options['pre']) ? $options['pre'] : '');
|
||||
$str .= implode($options['separator'], $this->getDqlQueryPart($queryPartName));
|
||||
$str .= (isset($options['post']) ? $options['post'] : '');
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
private function getDqlQueryPart($queryPartName)
|
||||
{
|
||||
return $this->_dqlParts[$queryPartName];
|
||||
}
|
||||
|
||||
private function _addDqlQueryPart($queryPartName, $queryPart, $append = false)
|
||||
{
|
||||
if ($append) {
|
||||
$this->_dqlParts[$queryPartName][] = $queryPart;
|
||||
} else {
|
||||
$this->_dqlParts[$queryPartName] = array($queryPart);
|
||||
}
|
||||
|
||||
$this->_state = self::STATE_DIRTY;
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -31,6 +31,7 @@ class AllTests
|
||||
$suite->addTestSuite('Doctrine\Tests\ORM\UnitOfWorkTest');
|
||||
$suite->addTestSuite('Doctrine\Tests\ORM\EntityManagerTest');
|
||||
$suite->addTestSuite('Doctrine\Tests\ORM\CommitOrderCalculatorTest');
|
||||
$suite->addTestSuite('Doctrine\Tests\ORM\QueryBuilderTest');
|
||||
|
||||
$suite->addTest(Query\AllTests::suite());
|
||||
$suite->addTest(Hydration\AllTests::suite());
|
||||
|
@ -24,6 +24,7 @@ class AllTests
|
||||
$suite->addTestSuite('Doctrine\Tests\ORM\Query\LexerTest');
|
||||
$suite->addTestSuite('Doctrine\Tests\ORM\Query\DeleteSqlGenerationTest');
|
||||
$suite->addTestSuite('Doctrine\Tests\ORM\Query\UpdateSqlGenerationTest');
|
||||
$suite->addTestSuite('Doctrine\Tests\ORM\Query\ExprTest');
|
||||
|
||||
return $suite;
|
||||
}
|
||||
|
231
tests/Doctrine/Tests/ORM/Query/ExprTest.php
Normal file
231
tests/Doctrine/Tests/ORM/Query/ExprTest.php
Normal file
@ -0,0 +1,231 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\Tests\ORM\Query;
|
||||
|
||||
use Doctrine\ORM\Query\Expr;
|
||||
use Doctrine\ORM\Query;
|
||||
|
||||
require_once __DIR__ . '/../../TestInit.php';
|
||||
|
||||
/**
|
||||
* Test case for the DQL Expr class used for generating DQL snippets through
|
||||
* a programmatic interface
|
||||
*
|
||||
* @author Jonathan H. Wage <jonwage@gmail.com>
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link http://www.phpdoctrine.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
*/
|
||||
class ExprTest extends \Doctrine\Tests\OrmTestCase
|
||||
{
|
||||
private $_em;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->_em = $this->_getTestEntityManager();
|
||||
}
|
||||
|
||||
public function testAvgExpr()
|
||||
{
|
||||
$this->assertEquals('AVG(u.id)', (string) Expr::avg('u.id'));
|
||||
}
|
||||
|
||||
public function testMaxExpr()
|
||||
{
|
||||
$this->assertEquals('MAX(u.id)', (string) Expr::max('u.id'));
|
||||
}
|
||||
|
||||
public function testMinExpr()
|
||||
{
|
||||
$this->assertEquals('MIN(u.id)', (string) Expr::min('u.id'));
|
||||
}
|
||||
|
||||
public function testCountExpr()
|
||||
{
|
||||
$this->assertEquals('MAX(u.id)', (string) Expr::max('u.id'));
|
||||
}
|
||||
|
||||
public function testCountDistinctExpr()
|
||||
{
|
||||
$this->assertEquals('COUNT(DISTINCT u.id)', (string) Expr::countDistinct('u.id'));
|
||||
}
|
||||
|
||||
public function testExistsExpr()
|
||||
{
|
||||
$this->assertEquals('EXISTS(SUBQUERY)', (string) Expr::exists('SUBQUERY'));
|
||||
}
|
||||
|
||||
public function testAllExpr()
|
||||
{
|
||||
$this->assertEquals('ALL(SUBQUERY)', (string) Expr::all('SUBQUERY'));
|
||||
}
|
||||
|
||||
public function testSomeExpr()
|
||||
{
|
||||
$this->assertEquals('SOME(SUBQUERY)', (string) Expr::some('SUBQUERY'));
|
||||
}
|
||||
|
||||
public function testAnyExpr()
|
||||
{
|
||||
$this->assertEquals('ANY(SUBQUERY)', (string) Expr::any('SUBQUERY'));
|
||||
}
|
||||
|
||||
public function testNotExpr()
|
||||
{
|
||||
$this->assertEquals('NOT(SUBQUERY)', (string) Expr::not('SUBQUERY'));
|
||||
}
|
||||
|
||||
public function testAndExpr()
|
||||
{
|
||||
$this->assertEquals('(1 = 1 AND 2 = 2)', (string) Expr::andx((string) Expr::eq(1, 1), (string) Expr::eq(2, 2)));
|
||||
}
|
||||
|
||||
public function testOrExpr()
|
||||
{
|
||||
$this->assertEquals('(1 = 1 OR 2 = 2)', (string) Expr::orx((string) Expr::eq(1, 1), (string) Expr::eq(2, 2)));
|
||||
}
|
||||
|
||||
public function testAbsExpr()
|
||||
{
|
||||
$this->assertEquals('ABS(1)', (string) Expr::abs(1));
|
||||
}
|
||||
|
||||
public function testProdExpr()
|
||||
{
|
||||
$this->assertEquals('(1 * 2)', (string) Expr::prod(1, 2));
|
||||
}
|
||||
|
||||
public function testDiffExpr()
|
||||
{
|
||||
$this->assertEquals('(1 - 2)', (string) Expr::diff(1, 2));
|
||||
}
|
||||
|
||||
public function testSumExpr()
|
||||
{
|
||||
$this->assertEquals('(1 + 2)', (string) Expr::sum(1, 2));
|
||||
}
|
||||
|
||||
public function testQuotientExpr()
|
||||
{
|
||||
$this->assertEquals('(10 / 2)', (string) Expr::quot(10, 2));
|
||||
}
|
||||
|
||||
public function testSquareRootExpr()
|
||||
{
|
||||
$this->assertEquals('SQRT(1)', (string) Expr::sqrt(1));
|
||||
}
|
||||
|
||||
public function testEqualExpr()
|
||||
{
|
||||
$this->assertEquals('1 = 1', (string) Expr::eq(1, 1));
|
||||
}
|
||||
|
||||
public function testNotEqualExpr()
|
||||
{
|
||||
$this->assertEquals('1 != 2', (string) Expr::notEqual(1, 2));
|
||||
}
|
||||
|
||||
public function testLikeExpr()
|
||||
{
|
||||
$this->assertEquals('(a.description LIKE :description)', (string) Expr::like('a.description', ':description'));
|
||||
}
|
||||
|
||||
public function testConcatExpr()
|
||||
{
|
||||
$this->assertEquals('CONCAT(u.first_name, u.last_name)', (string) Expr::concat('u.first_name', 'u.last_name'));
|
||||
}
|
||||
|
||||
public function testSubstrExpr()
|
||||
{
|
||||
$this->assertEquals('SUBSTR(a.title, 0, 25)', (string) Expr::substr('a.title', 0, 25));
|
||||
}
|
||||
|
||||
public function testLowerExpr()
|
||||
{
|
||||
$this->assertEquals('LOWER(u.first_name)', (string) Expr::lower('u.first_name'));
|
||||
}
|
||||
|
||||
public function testUpperExpr()
|
||||
{
|
||||
$this->assertEquals('UPPER(u.first_name)', (string) Expr::upper('u.first_name'));
|
||||
}
|
||||
|
||||
public function testLengthExpr()
|
||||
{
|
||||
$this->assertEquals('LENGTH(u.first_name)', (string) Expr::length('u.first_name'));
|
||||
}
|
||||
|
||||
public function testGreaterThanExpr()
|
||||
{
|
||||
$this->assertEquals('5 > 2', (string) Expr::gt(5, 2));
|
||||
$this->assertEquals('5 > 2', (string) Expr::greaterThan(5, 2));
|
||||
}
|
||||
|
||||
public function testLessThanExpr()
|
||||
{
|
||||
$this->assertEquals('2 < 5', (string) Expr::lt(2, 5));
|
||||
$this->assertEquals('2 < 5', (string) Expr::lessThan(2, 5));
|
||||
}
|
||||
|
||||
public function testPathExpr()
|
||||
{
|
||||
// TODO: This functionality still needs to be written and tested
|
||||
}
|
||||
|
||||
public function testStringLiteralExpr()
|
||||
{
|
||||
$this->assertEquals("'word'", (string) Expr::literal('word'));
|
||||
}
|
||||
|
||||
public function testNumericLiteralExpr()
|
||||
{
|
||||
$this->assertEquals(5, (string) Expr::literal(5));
|
||||
}
|
||||
|
||||
public function testGreaterThanOrEqualToExpr()
|
||||
{
|
||||
$this->assertEquals('5 >= 2', (string) Expr::gtoet(5, 2));
|
||||
$this->assertEquals('5 >= 2', (string) Expr::greaterThanOrEqualTo(5, 2));
|
||||
}
|
||||
|
||||
public function testLessThanOrEqualTo()
|
||||
{
|
||||
$this->assertEquals('2 <= 5', (string) Expr::ltoet(2, 5));
|
||||
$this->assertEquals('2 <= 5', (string) Expr::lessThanOrEqualTo(2, 5));
|
||||
}
|
||||
|
||||
public function testBetweenExpr()
|
||||
{
|
||||
$this->assertEquals('BETWEEN(u.id, 3, 6)', (string) Expr::between('u.id', 3, 6));
|
||||
}
|
||||
|
||||
public function testTrimExpr()
|
||||
{
|
||||
$this->assertEquals('TRIM(u.id)', (string) Expr::trim('u.id'));
|
||||
}
|
||||
|
||||
public function testInExpr()
|
||||
{
|
||||
$this->assertEquals('u.id IN(1, 2, 3)', (string) Expr::in('u.id', array(1, 2, 3)));
|
||||
}
|
||||
}
|
300
tests/Doctrine/Tests/ORM/QueryBuilderTest.php
Normal file
300
tests/Doctrine/Tests/ORM/QueryBuilderTest.php
Normal file
@ -0,0 +1,300 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\Tests\ORM;
|
||||
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Doctrine\ORM\Query\Expr;
|
||||
|
||||
require_once __DIR__ . '/../TestInit.php';
|
||||
|
||||
/**
|
||||
* Test case for the QueryBuilder class used to build DQL query string in a
|
||||
* object oriented way.
|
||||
*
|
||||
* @author Jonathan H. Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link http://www.phpdoctrine.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
*/
|
||||
class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase
|
||||
{
|
||||
private $_em;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->_em = $this->_getTestEntityManager();
|
||||
}
|
||||
|
||||
protected function assertValidQueryBuilder(QueryBuilder $qb, $expectedDql)
|
||||
{
|
||||
$dql = $qb->getDql();
|
||||
$q = $qb->getQuery();
|
||||
|
||||
try {
|
||||
$q->getSql();
|
||||
} catch (\Exception $e) {
|
||||
echo $dql . "\n";
|
||||
echo $e->getTraceAsString();
|
||||
$this->fail($e->getMessage());
|
||||
}
|
||||
|
||||
$this->assertEquals($expectedDql, $dql);
|
||||
}
|
||||
|
||||
public function testSimpleSelect()
|
||||
{
|
||||
$qb = QueryBuilder::create($this->_em)
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->select('u.id, u.username');
|
||||
|
||||
$this->assertValidQueryBuilder($qb, 'SELECT u.id, u.username FROM Doctrine\Tests\Models\CMS\CmsUser u');
|
||||
}
|
||||
|
||||
public function testSimpleDelete()
|
||||
{
|
||||
$qb = QueryBuilder::create($this->_em)
|
||||
->delete('Doctrine\Tests\Models\CMS\CmsUser', 'u');
|
||||
|
||||
$this->assertValidQueryBuilder($qb, 'DELETE Doctrine\Tests\Models\CMS\CmsUser u');
|
||||
}
|
||||
|
||||
public function testSimpleUpdate()
|
||||
{
|
||||
$qb = QueryBuilder::create($this->_em)
|
||||
->update('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->set('u.username', ':username', 'jonwage');
|
||||
|
||||
$this->assertValidQueryBuilder($qb, 'UPDATE Doctrine\Tests\Models\CMS\CmsUser u SET u.username = :username');
|
||||
}
|
||||
|
||||
public function testJoin()
|
||||
{
|
||||
$qb = QueryBuilder::create($this->_em)
|
||||
->select('u, a')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->join('u.articles', 'a');
|
||||
|
||||
$this->assertValidQueryBuilder($qb, 'SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.articles a');
|
||||
}
|
||||
|
||||
public function testInnerJoin()
|
||||
{
|
||||
$qb = QueryBuilder::create($this->_em)
|
||||
->select('u, a')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->innerJoin('u.articles', 'a');
|
||||
|
||||
$this->assertValidQueryBuilder($qb, 'SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.articles a');
|
||||
}
|
||||
|
||||
public function testLeftJoin()
|
||||
{
|
||||
$qb = QueryBuilder::create($this->_em)
|
||||
->select('u, a')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->leftJoin('u.articles', 'a');
|
||||
|
||||
$this->assertValidQueryBuilder($qb, 'SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a');
|
||||
}
|
||||
|
||||
public function testWhere()
|
||||
{
|
||||
$qb = QueryBuilder::create($this->_em)
|
||||
->select('u')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->where('u.id = :uid')
|
||||
->where('u.id = :id');
|
||||
|
||||
$this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = :id');
|
||||
}
|
||||
|
||||
public function testAndWhere()
|
||||
{
|
||||
$qb = QueryBuilder::create($this->_em)
|
||||
->select('u')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->where('u.id = :id')
|
||||
->andWhere('u.username = :username');
|
||||
|
||||
$this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = :id AND u.username = :username');
|
||||
}
|
||||
|
||||
public function testOrWhere()
|
||||
{
|
||||
$qb = QueryBuilder::create($this->_em)
|
||||
->select('u')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->where('u.id = :id')
|
||||
->orWhere('u.username = :username');
|
||||
|
||||
$this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = :id OR u.username = :username');
|
||||
}
|
||||
|
||||
/*
|
||||
public function testWhereIn()
|
||||
{
|
||||
$qb = QueryBuilder::create($this->_em)
|
||||
->select('u')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->whereIn('u.id', array(1));
|
||||
|
||||
$this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id IN(1)');
|
||||
}
|
||||
|
||||
public function testWhereNotIn()
|
||||
{
|
||||
$qb = QueryBuilder::create($this->_em)
|
||||
->select('u')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->whereNotIn('u.id', array(1));
|
||||
|
||||
$this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id NOT IN(1)');
|
||||
}
|
||||
|
||||
public function testAndWhereIn()
|
||||
{
|
||||
$qb = QueryBuilder::create($this->_em)
|
||||
->select('u')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->where('u.id = :id')
|
||||
->andWhereIn('u.id', array(1, 2, 3));
|
||||
|
||||
$this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = :id AND u.id IN(1, 2, 3)');
|
||||
}
|
||||
|
||||
public function testAndWhereNotIn()
|
||||
{
|
||||
$qb = QueryBuilder::create($this->_em)
|
||||
->select('u')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->where('u.id = :id')
|
||||
->andWhereNotIn('u.id', array(1, 2, 3));
|
||||
|
||||
$this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = :id AND u.id NOT IN(1, 2, 3)');
|
||||
}
|
||||
|
||||
public function testOrWhereIn()
|
||||
{
|
||||
$qb = QueryBuilder::create($this->_em)
|
||||
->select('u')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->where('u.id = :id')
|
||||
->orWhereIn('u.id', array(1, 2, 3));
|
||||
|
||||
$this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = :id OR u.id IN(1, 2, 3)');
|
||||
}
|
||||
|
||||
public function testOrWhereNotIn()
|
||||
{
|
||||
$qb = QueryBuilder::create($this->_em)
|
||||
->select('u')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->where('u.id = :id')
|
||||
->orWhereNotIn('u.id', array(1, 2, 3));
|
||||
|
||||
$this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = :id OR u.id NOT IN(1, 2, 3)');
|
||||
}
|
||||
*/
|
||||
|
||||
public function testGroupBy()
|
||||
{
|
||||
$qb = QueryBuilder::create($this->_em)
|
||||
->select('u')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->groupBy('u.id');
|
||||
|
||||
$this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u GROUP BY u.id');
|
||||
}
|
||||
|
||||
public function testHaving()
|
||||
{
|
||||
$qb = QueryBuilder::create($this->_em)
|
||||
->select('u')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->groupBy('u.id')
|
||||
->having('COUNT(u.id) > 1');
|
||||
|
||||
$this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u GROUP BY u.id HAVING COUNT(u.id) > 1');
|
||||
}
|
||||
|
||||
public function testAndHaving()
|
||||
{
|
||||
$qb = QueryBuilder::create($this->_em)
|
||||
->select('u')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->groupBy('u.id')
|
||||
->having('COUNT(u.id) > 1')
|
||||
->andHaving('COUNT(u.id) < 1');
|
||||
|
||||
$this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u GROUP BY u.id HAVING COUNT(u.id) > 1 AND COUNT(u.id) < 1');
|
||||
}
|
||||
|
||||
public function testOrHaving()
|
||||
{
|
||||
$qb = QueryBuilder::create($this->_em)
|
||||
->select('u')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->groupBy('u.id')
|
||||
->having('COUNT(u.id) > 1')
|
||||
->andHaving('COUNT(u.id) < 1')
|
||||
->orHaving('COUNT(u.id) > 1');
|
||||
|
||||
$this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u GROUP BY u.id HAVING COUNT(u.id) > 1 AND COUNT(u.id) < 1 OR COUNT(u.id) > 1');
|
||||
}
|
||||
|
||||
public function testOrderBy()
|
||||
{
|
||||
$qb = QueryBuilder::create($this->_em)
|
||||
->select('u')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->orderBy('u.username', 'ASC');
|
||||
|
||||
$this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY u.username ASC');
|
||||
}
|
||||
|
||||
public function testAddOrderBy()
|
||||
{
|
||||
$qb = QueryBuilder::create($this->_em)
|
||||
->select('u')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->orderBy('u.username', 'ASC')
|
||||
->addOrderBy('u.username', 'DESC');
|
||||
|
||||
$this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY u.username ASC, u.username DESC');
|
||||
}
|
||||
|
||||
public function testLimit()
|
||||
{
|
||||
/*
|
||||
TODO: Limit fails. Is this not implemented in the DQL parser? Will look tomorrow.
|
||||
$qb = QueryBuilder::create($this->_em)
|
||||
->select('u')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->limit(10)
|
||||
->offset(0);
|
||||
|
||||
$this->assertValidQueryBuilder($qb, 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u LIMIT 10');
|
||||
*/
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user