Doctrine_Hook first draft + test cases
This commit is contained in:
parent
aa349ecb74
commit
cf939c6d3a
@ -34,11 +34,37 @@ class Doctrine_Hook {
|
|||||||
/**
|
/**
|
||||||
* @var Doctrine_Query $query the base query
|
* @var Doctrine_Query $query the base query
|
||||||
*/
|
*/
|
||||||
private $query;
|
protected $query;
|
||||||
/**
|
/**
|
||||||
* @var array $joins the optional joins of the base query
|
* @var array $joins the optional joins of the base query
|
||||||
*/
|
*/
|
||||||
private $joins;
|
protected $joins;
|
||||||
|
/**
|
||||||
|
* @var array $hooks hooks array
|
||||||
|
*/
|
||||||
|
protected $hooks = array(
|
||||||
|
'where',
|
||||||
|
'orderby',
|
||||||
|
'limit',
|
||||||
|
'offset'
|
||||||
|
);
|
||||||
|
/**
|
||||||
|
* @var array $params query parameters
|
||||||
|
*/
|
||||||
|
protected $params = array();
|
||||||
|
/**
|
||||||
|
* @var array $fieldParsers
|
||||||
|
*/
|
||||||
|
protected $fieldParsers = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array $typeParsers
|
||||||
|
*/
|
||||||
|
protected $typeParsers = array(
|
||||||
|
'char' => 'Doctrine_Hook_WordLike',
|
||||||
|
'string' => 'Doctrine_Hook_WordLike',
|
||||||
|
'integer' => 'Doctrine_Hook_Integer',
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Doctrine_Query $query the base query
|
* @param Doctrine_Query $query the base query
|
||||||
@ -51,16 +77,82 @@ class Doctrine_Hook {
|
|||||||
$this->query = $query;
|
$this->query = $query;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public function buildQuery() {
|
||||||
|
$where = array();
|
||||||
|
$from = array();
|
||||||
|
$params = array();
|
||||||
|
|
||||||
|
|
||||||
|
$component = $this->table->getComponentName();
|
||||||
|
|
||||||
|
$data = self::makeFlat($this->where);
|
||||||
|
|
||||||
|
foreach($data as $k => $v) {
|
||||||
|
if(trim($v) == '') {
|
||||||
|
unset($data[$k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$orderby = array();
|
||||||
|
|
||||||
|
if(isset($this->hooks['orderby'])) {
|
||||||
|
$e = explode(" ",$this->hooks['orderby']);
|
||||||
|
|
||||||
|
$orderComponent = $e[0];
|
||||||
|
|
||||||
|
if(in_array($orderComponent, $this->fields)) {
|
||||||
|
if(isset($e[1]) && ($e[1] == "ASC" || $e[1] == "DESC")) {
|
||||||
|
$orderby[] = $component.".".$e[0]." ".$e[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public function getQuery() {
|
||||||
|
return $this->query;
|
||||||
|
}
|
||||||
public function leftJoin($dql) {
|
public function leftJoin($dql) {
|
||||||
|
|
||||||
}
|
}
|
||||||
public function innerJoin($dql) {
|
public function innerJoin($dql) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* hookWhere
|
||||||
|
*
|
||||||
|
* @param array $params an array of query where parameters
|
||||||
|
*/
|
||||||
public function hookWhere(array $params) {
|
public function hookWhere(array $params) {
|
||||||
|
foreach($params as $name => $value) {
|
||||||
|
$e = explode('.', $name);
|
||||||
|
|
||||||
|
if(count($e) == 2) {
|
||||||
|
list($alias, $column) = $e;
|
||||||
|
|
||||||
|
$tableAlias = $this->query->getTableAlias($alias);
|
||||||
|
$table = $this->query->getTable($tableAlias);
|
||||||
|
|
||||||
|
if($def = $table->getDefinitionOf($column)) {
|
||||||
|
|
||||||
|
if(isset($this->typeParsers[$def[0]])) {
|
||||||
|
$name = $this->typeParsers[$def[0]];
|
||||||
|
$parser = new $name;
|
||||||
|
}
|
||||||
|
|
||||||
|
$parser->parse($alias, $column, $value);
|
||||||
|
|
||||||
|
$this->query->addWhere($parser->getCondition());
|
||||||
|
$this->params += $parser->getParams();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->params += $params;
|
||||||
}
|
}
|
||||||
public function hookOrderby(array $params) {
|
/**
|
||||||
|
* @param integer $limit
|
||||||
|
*/
|
||||||
|
public function hookOrderby($params) {
|
||||||
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -73,7 +165,7 @@ class Doctrine_Hook {
|
|||||||
* @param integer $offset
|
* @param integer $offset
|
||||||
*/
|
*/
|
||||||
public function hookOffset($offset) {
|
public function hookOffset($offset) {
|
||||||
|
|
||||||
}
|
}
|
||||||
public function setWhereHooks() {
|
public function setWhereHooks() {
|
||||||
|
|
||||||
|
50
lib/Doctrine/Hook/Equal.php
Normal file
50
lib/Doctrine/Hook/Equal.php
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<?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.phpdoctrine.com>.
|
||||||
|
*/
|
||||||
|
Doctrine::autoload('Doctrine_Hook_Parser');
|
||||||
|
/**
|
||||||
|
* Doctrine_Hook_Equal
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @category Object Relational Mapping
|
||||||
|
* @link www.phpdoctrine.com
|
||||||
|
* @since 1.0
|
||||||
|
* @version $Revision$
|
||||||
|
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||||
|
*/
|
||||||
|
class Doctrine_Hook_Equal extends Doctrine_Hook_Parser {
|
||||||
|
/**
|
||||||
|
* parse
|
||||||
|
* Parses given field and field value to DQL condition
|
||||||
|
* and parameters. This method should always return
|
||||||
|
* prepared statement conditions (conditions that use
|
||||||
|
* placeholders instead of literal values).
|
||||||
|
*
|
||||||
|
* @param string $alias component alias
|
||||||
|
* @param string $field the field name
|
||||||
|
* @param mixed $value the value of the field
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function parse($alias, $field, $value) {
|
||||||
|
$this->params = (array) $value;
|
||||||
|
$this->condition = $alias . '.' . $field . ' = ?';
|
||||||
|
}
|
||||||
|
}
|
73
lib/Doctrine/Hook/Integer.php
Normal file
73
lib/Doctrine/Hook/Integer.php
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
<?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.phpdoctrine.com>.
|
||||||
|
*/
|
||||||
|
Doctrine::autoload('Doctrine_Hook_Parser_Complex');
|
||||||
|
/**
|
||||||
|
* Doctrine_Hook_Integer
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @category Object Relational Mapping
|
||||||
|
* @link www.phpdoctrine.com
|
||||||
|
* @since 1.0
|
||||||
|
* @version $Revision$
|
||||||
|
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||||
|
*/
|
||||||
|
class Doctrine_Hook_Integer extends Doctrine_Hook_Parser_Complex {
|
||||||
|
/**
|
||||||
|
* parse
|
||||||
|
* Parses given field and field value to DQL condition
|
||||||
|
* and parameters. This method should always return
|
||||||
|
* prepared statement conditions (conditions that use
|
||||||
|
* placeholders instead of literal values).
|
||||||
|
*
|
||||||
|
* @param string $alias component alias
|
||||||
|
* @param string $field the field name
|
||||||
|
* @param mixed $value the value of the field
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function parseSingle($alias, $field, $value) {
|
||||||
|
$e = explode(' ', $value);
|
||||||
|
|
||||||
|
foreach($e as $v) {
|
||||||
|
$v = trim($v);
|
||||||
|
|
||||||
|
$e2 = explode('-', $v);
|
||||||
|
|
||||||
|
$name = $alias. '.' . $field;
|
||||||
|
|
||||||
|
if(count($e2) == 1) {
|
||||||
|
// one '-' found
|
||||||
|
|
||||||
|
$a[] = $name . ' = ?';
|
||||||
|
|
||||||
|
$this->params[] = $v;
|
||||||
|
} else {
|
||||||
|
// more than one '-' found
|
||||||
|
|
||||||
|
$a[] = '(' . $name . ' > ? AND ' . $name . ' < ?)';
|
||||||
|
|
||||||
|
$this->params += array($e2[0], $e2[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return implode(' OR ', $a);
|
||||||
|
}
|
||||||
|
}
|
57
lib/Doctrine/Hook/Parser.php
Normal file
57
lib/Doctrine/Hook/Parser.php
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<?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.phpdoctrine.com>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Doctrine_Hook_Parser
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @category Object Relational Mapping
|
||||||
|
* @link www.phpdoctrine.com
|
||||||
|
* @since 1.0
|
||||||
|
* @version $Revision$
|
||||||
|
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||||
|
*/
|
||||||
|
abstract class Doctrine_Hook_Parser {
|
||||||
|
protected $condition;
|
||||||
|
protected $params = array();
|
||||||
|
|
||||||
|
public function getCondition() {
|
||||||
|
return $this->condition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParams() {
|
||||||
|
return $this->params;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* parse
|
||||||
|
* Parses given field and field value to DQL condition
|
||||||
|
* and parameters. This method should always return
|
||||||
|
* prepared statement conditions (conditions that use
|
||||||
|
* placeholders instead of literal values).
|
||||||
|
*
|
||||||
|
* @param string $alias component alias
|
||||||
|
* @param string $field the field name
|
||||||
|
* @param mixed $value the value of the field
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
abstract public function parse($alias, $field, $value);
|
||||||
|
}
|
98
lib/Doctrine/Hook/Parser/Complex.php
Normal file
98
lib/Doctrine/Hook/Parser/Complex.php
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
<?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.phpdoctrine.com>.
|
||||||
|
*/
|
||||||
|
Doctrine::autoload('Doctrine_Hook_Parser');
|
||||||
|
/**
|
||||||
|
* Doctrine_Hook_Parser_Complex
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @category Object Relational Mapping
|
||||||
|
* @link www.phpdoctrine.com
|
||||||
|
* @since 1.0
|
||||||
|
* @version $Revision$
|
||||||
|
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||||
|
*/
|
||||||
|
abstract class Doctrine_Hook_Parser_Complex extends Doctrine_Hook_Parser {
|
||||||
|
/**
|
||||||
|
* parse
|
||||||
|
* Parses given field and field value to DQL condition
|
||||||
|
* and parameters. This method should always return
|
||||||
|
* prepared statement conditions (conditions that use
|
||||||
|
* placeholders instead of literal values).
|
||||||
|
*
|
||||||
|
* @param string $alias component alias
|
||||||
|
* @param string $field the field name
|
||||||
|
* @param mixed $value the value of the field
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function parse($alias, $field, $value) {
|
||||||
|
$this->condition = $this->parseClause($alias, $field, $value);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* parseClause
|
||||||
|
*
|
||||||
|
* @param string $alias component alias
|
||||||
|
* @param string $field the field name
|
||||||
|
* @param mixed $value the value of the field
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function parseClause($alias, $field, $value) {
|
||||||
|
$parts = Doctrine_Query::bracketExplode($value, ' AND ', '(', ')');
|
||||||
|
|
||||||
|
if(count($parts) > 1) {
|
||||||
|
$ret = array();
|
||||||
|
foreach($parts as $part) {
|
||||||
|
$part = Doctrine_Query::bracketTrim($part, '(', ')');
|
||||||
|
$ret[] = $this->parseSingle($alias, $field, $part);
|
||||||
|
}
|
||||||
|
|
||||||
|
$r = implode(' AND ', $ret);
|
||||||
|
} else {
|
||||||
|
$parts = Doctrine_Query::bracketExplode($value, ' OR ', '(', ')');
|
||||||
|
if(count($parts) > 1) {
|
||||||
|
$ret = array();
|
||||||
|
foreach($parts as $part) {
|
||||||
|
$part = Doctrine_Query::bracketTrim($part, '(', ')');
|
||||||
|
$ret[] = $this->parseClause($alias, $field, $part);
|
||||||
|
}
|
||||||
|
|
||||||
|
$r = implode(' OR ', $ret);
|
||||||
|
} else {
|
||||||
|
if(substr($parts[0],0,1) == '(' && substr($parts[0],-1) == ')') {
|
||||||
|
return $this->parseClause(substr($parts[0],1,-1));
|
||||||
|
} else {
|
||||||
|
$ret = $this->parseSingle($alias, $field, $parts[0]);
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return '(' . $r . ')';
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* parseSingle
|
||||||
|
*
|
||||||
|
* @param string $alias component alias
|
||||||
|
* @param string $field the field name
|
||||||
|
* @param mixed $value the value of the field
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
abstract public function parseSingle($alias, $field, $value);
|
||||||
|
}
|
56
lib/Doctrine/Hook/WordLike.php
Normal file
56
lib/Doctrine/Hook/WordLike.php
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
<?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.phpdoctrine.com>.
|
||||||
|
*/
|
||||||
|
Doctrine::autoload('Doctrine_Hook_Parser');
|
||||||
|
/**
|
||||||
|
* Doctrine_Hook_WordLike
|
||||||
|
*
|
||||||
|
* @package Doctrine
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @category Object Relational Mapping
|
||||||
|
* @link www.phpdoctrine.com
|
||||||
|
* @since 1.0
|
||||||
|
* @version $Revision$
|
||||||
|
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||||
|
*/
|
||||||
|
class Doctrine_Hook_WordLike extends Doctrine_Hook_Parser_Complex {
|
||||||
|
/**
|
||||||
|
* parse
|
||||||
|
* Parses given field and field value to DQL condition
|
||||||
|
* and parameters. This method should always return
|
||||||
|
* prepared statement conditions (conditions that use
|
||||||
|
* placeholders instead of literal values).
|
||||||
|
*
|
||||||
|
* @param string $alias component alias
|
||||||
|
* @param string $field the field name
|
||||||
|
* @param mixed $value the value of the field
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function parseSingle($alias, $field, $value) {
|
||||||
|
$e2 = explode(' ',$value);
|
||||||
|
|
||||||
|
foreach($e2 as $v) {
|
||||||
|
$v = trim($v);
|
||||||
|
$a[] = $alias. '.' . $field . ' LIKE ?';
|
||||||
|
$this->params[] = $v . '%';
|
||||||
|
}
|
||||||
|
return implode(' OR ', $a);
|
||||||
|
}
|
||||||
|
}
|
@ -82,9 +82,7 @@ abstract class Doctrine_Hydrate extends Doctrine_Access {
|
|||||||
* @var array $tableIndexes
|
* @var array $tableIndexes
|
||||||
*/
|
*/
|
||||||
protected $tableIndexes = array();
|
protected $tableIndexes = array();
|
||||||
|
|
||||||
protected $components = array();
|
|
||||||
|
|
||||||
protected $pendingAggregates = array();
|
protected $pendingAggregates = array();
|
||||||
|
|
||||||
protected $aggregateMap = array();
|
protected $aggregateMap = array();
|
||||||
@ -143,6 +141,14 @@ abstract class Doctrine_Hydrate extends Doctrine_Access {
|
|||||||
public function getTableIndexes() {
|
public function getTableIndexes() {
|
||||||
return $this->tableIndexes;
|
return $this->tableIndexes;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* getTables
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getTables() {
|
||||||
|
return $this->tables;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* copyAliases
|
* copyAliases
|
||||||
*
|
*
|
||||||
@ -160,7 +166,7 @@ abstract class Doctrine_Hydrate extends Doctrine_Access {
|
|||||||
$s = array_search($path, $this->compAliases);
|
$s = array_search($path, $this->compAliases);
|
||||||
if($s === false)
|
if($s === false)
|
||||||
return $path;
|
return $path;
|
||||||
|
|
||||||
return $s;
|
return $s;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -256,8 +262,9 @@ abstract class Doctrine_Hydrate extends Doctrine_Access {
|
|||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* getView
|
* getView
|
||||||
|
* returns the view associated with this query object (if any)
|
||||||
*
|
*
|
||||||
* @return Doctrine_View
|
* @return Doctrine_View the view associated with this query object
|
||||||
*/
|
*/
|
||||||
public function getView() {
|
public function getView() {
|
||||||
return $this->view;
|
return $this->view;
|
||||||
@ -637,10 +644,10 @@ abstract class Doctrine_Hydrate extends Doctrine_Access {
|
|||||||
* parse the data into two-dimensional array
|
* parse the data into two-dimensional array
|
||||||
*/
|
*/
|
||||||
foreach($data as $key => $value):
|
foreach($data as $key => $value):
|
||||||
$e = explode("__",$key);
|
$e = explode('__', $key);
|
||||||
|
|
||||||
$field = strtolower( array_pop($e) );
|
$field = strtolower(array_pop($e));
|
||||||
$component = strtolower( implode("__",$e) );
|
$component = strtolower(implode('__', $e));
|
||||||
|
|
||||||
$data[$component][$field] = $value;
|
$data[$component][$field] = $value;
|
||||||
|
|
||||||
@ -656,10 +663,13 @@ abstract class Doctrine_Hydrate extends Doctrine_Access {
|
|||||||
* returns a Doctrine_Table for given name
|
* returns a Doctrine_Table for given name
|
||||||
*
|
*
|
||||||
* @param string $name component name
|
* @param string $name component name
|
||||||
* @return Doctrine_Table
|
* @return Doctrine_Table|boolean
|
||||||
*/
|
*/
|
||||||
public function getTable($name) {
|
public function getTable($name) {
|
||||||
return $this->tables[$name];
|
if(isset($this->tables[$name]))
|
||||||
|
return $this->tables[$name];
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @return string returns a string representation of this object
|
* @return string returns a string representation of this object
|
||||||
|
@ -65,7 +65,9 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
|
|||||||
private $relationStack = array();
|
private $relationStack = array();
|
||||||
|
|
||||||
private $isDistinct = false;
|
private $isDistinct = false;
|
||||||
|
/**
|
||||||
|
* @var array $pendingFields
|
||||||
|
*/
|
||||||
private $pendingFields = array();
|
private $pendingFields = array();
|
||||||
/**
|
/**
|
||||||
* @var integer $type the query type
|
* @var integer $type the query type
|
||||||
@ -102,13 +104,10 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
|
|||||||
public function processPendingFields($componentAlias) {
|
public function processPendingFields($componentAlias) {
|
||||||
$tableAlias = $this->getTableAlias($componentAlias);
|
$tableAlias = $this->getTableAlias($componentAlias);
|
||||||
|
|
||||||
|
if( ! isset($this->tables[$tableAlias]))
|
||||||
$componentPath = $this->compAliases[$componentAlias];
|
|
||||||
|
|
||||||
if( ! isset($this->components[$componentPath]))
|
|
||||||
throw new Doctrine_Query_Exception('Unknown component path '.$componentPath);
|
throw new Doctrine_Query_Exception('Unknown component path '.$componentPath);
|
||||||
|
|
||||||
$table = $this->components[$componentPath];
|
$table = $this->tables[$tableAlias];
|
||||||
|
|
||||||
if(isset($this->pendingFields[$componentAlias])) {
|
if(isset($this->pendingFields[$componentAlias])) {
|
||||||
$fields = $this->pendingFields[$componentAlias];
|
$fields = $this->pendingFields[$componentAlias];
|
||||||
@ -173,14 +172,12 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
public function processPendingAggregates($componentAlias) {
|
public function processPendingAggregates($componentAlias) {
|
||||||
$tableAlias = $this->getTableAlias($componentAlias);
|
$tableAlias = $this->getTableAlias($componentAlias);
|
||||||
|
|
||||||
$componentPath = $this->compAliases[$componentAlias];
|
|
||||||
|
|
||||||
if( ! isset($this->components[$componentPath]))
|
if( ! isset($this->tables[$tableAlias]))
|
||||||
throw new Doctrine_Query_Exception('Unknown component path '.$componentPath);
|
throw new Doctrine_Query_Exception('Unknown component path '.$componentPath);
|
||||||
|
|
||||||
$table = $this->components[$componentPath];
|
$table = $this->tables[$tableAlias];
|
||||||
|
|
||||||
foreach($this->pendingAggregates[$componentAlias] as $args) {
|
foreach($this->pendingAggregates[$componentAlias] as $args) {
|
||||||
list($name, $arg, $distinct, $alias) = $args;
|
list($name, $arg, $distinct, $alias) = $args;
|
||||||
@ -1145,7 +1142,7 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
|
|||||||
. $assocTableName . '.' . $fk->getLocal();
|
. $assocTableName . '.' . $fk->getLocal();
|
||||||
|
|
||||||
$this->parts["join"][$tname][$tname2] = $join . $aliasString . ' ON ' . $tname2 . '.'
|
$this->parts["join"][$tname][$tname2] = $join . $aliasString . ' ON ' . $tname2 . '.'
|
||||||
. $table->getIdentifier() . ' = '
|
. $fk->getTable()->getIdentifier() . ' = '
|
||||||
. $assocTableName . '.' . $fk->getForeign();
|
. $assocTableName . '.' . $fk->getForeign();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -1227,14 +1224,14 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
|
|||||||
|
|
||||||
$fields = array();
|
$fields = array();
|
||||||
|
|
||||||
if(strpos($fullName, "-") === false) {
|
if(strpos($fullName, '-') === false) {
|
||||||
$fetchmode = $table->getAttribute(Doctrine::ATTR_FETCHMODE);
|
$fetchmode = $table->getAttribute(Doctrine::ATTR_FETCHMODE);
|
||||||
|
|
||||||
if(isset($exploded[1])) {
|
if(isset($exploded[1])) {
|
||||||
if(count($exploded) > 2) {
|
if(count($exploded) > 2) {
|
||||||
$fields = $this->parseAggregateValues($fullName, $tableName, $exploded, $currPath);
|
$fields = $this->parseAggregateValues($fullName, $tableName, $exploded, $currPath);
|
||||||
} elseif(count($exploded) == 2) {
|
} elseif(count($exploded) == 2) {
|
||||||
$fields = explode(",",substr($exploded[1],0,-1));
|
$fields = explode(',',substr($exploded[1],0,-1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1244,10 +1241,10 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
|
|||||||
$fetchmode = $table->getAttribute(Doctrine::ATTR_FETCHMODE);
|
$fetchmode = $table->getAttribute(Doctrine::ATTR_FETCHMODE);
|
||||||
|
|
||||||
if(isset($exploded[2])) {
|
if(isset($exploded[2])) {
|
||||||
if(substr_count($exploded[2], ")") > 1) {
|
if(substr_count($exploded[2], ')') > 1) {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$fields = explode(",",substr($exploded[2],0,-1));
|
$fields = explode(',', substr($exploded[2],0,-1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1263,27 +1260,27 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
|
|||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function parseAggregateFunction($func,$reference) {
|
public function parseAggregateFunction($func,$reference) {
|
||||||
$pos = strpos($func,"(");
|
$pos = strpos($func, '(');
|
||||||
|
|
||||||
if($pos !== false) {
|
if($pos !== false) {
|
||||||
$funcs = array();
|
$funcs = array();
|
||||||
|
|
||||||
$name = substr($func, 0, $pos);
|
$name = substr($func, 0, $pos);
|
||||||
$func = substr($func, ($pos + 1), -1);
|
$func = substr($func, ($pos + 1), -1);
|
||||||
$params = Doctrine_Query::bracketExplode($func, ",", "(", ")");
|
$params = Doctrine_Query::bracketExplode($func, ',', '(', ')');
|
||||||
|
|
||||||
foreach($params as $k => $param) {
|
foreach($params as $k => $param) {
|
||||||
$params[$k] = $this->parseAggregateFunction($param,$reference);
|
$params[$k] = $this->parseAggregateFunction($param,$reference);
|
||||||
}
|
}
|
||||||
|
|
||||||
$funcs = $name."(".implode(", ", $params).")";
|
$funcs = $name . '(' . implode(', ', $params). ')';
|
||||||
|
|
||||||
return $funcs;
|
return $funcs;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if( ! is_numeric($func)) {
|
if( ! is_numeric($func)) {
|
||||||
|
|
||||||
$func = $this->getTableAlias($reference).".".$func;
|
$func = $this->getTableAlias($reference).'.'.$func;
|
||||||
|
|
||||||
return $func;
|
return $func;
|
||||||
} else {
|
} else {
|
||||||
@ -1297,7 +1294,7 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
|
|||||||
*/
|
*/
|
||||||
public function parseAggregateValues($fullName, $tableName, array $exploded, $currPath) {
|
public function parseAggregateValues($fullName, $tableName, array $exploded, $currPath) {
|
||||||
$this->aggregate = true;
|
$this->aggregate = true;
|
||||||
$pos = strpos($fullName,"(");
|
$pos = strpos($fullName, '(');
|
||||||
$name = substr($fullName, 0, $pos);
|
$name = substr($fullName, 0, $pos);
|
||||||
$string = substr($fullName, ($pos + 1), -1);
|
$string = substr($fullName, ($pos + 1), -1);
|
||||||
|
|
||||||
@ -1306,7 +1303,7 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
|
|||||||
$func = $this->parseAggregateFunction($value, $currPath);
|
$func = $this->parseAggregateFunction($value, $currPath);
|
||||||
$exploded[$k] = $func;
|
$exploded[$k] = $func;
|
||||||
|
|
||||||
$this->parts["select"][] = $exploded[$k];
|
$this->parts['select'][] = $exploded[$k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,33 +13,34 @@ abstract class Doctrine_Query_Condition extends Doctrine_Query_Part {
|
|||||||
final public function parse($str) {
|
final public function parse($str) {
|
||||||
$tmp = trim($str);
|
$tmp = trim($str);
|
||||||
|
|
||||||
$parts = Doctrine_Query::bracketExplode($str, array(' \&\& ', ' AND '), "(", ")");
|
$parts = Doctrine_Query::bracketExplode($str, array(' \&\& ', ' AND '), '(', ')');
|
||||||
|
|
||||||
if(count($parts) > 1) {
|
if(count($parts) > 1) {
|
||||||
$ret = array();
|
$ret = array();
|
||||||
foreach($parts as $part) {
|
foreach($parts as $part) {
|
||||||
$part = Doctrine_Query::bracketTrim($part, "(", ")");
|
$part = Doctrine_Query::bracketTrim($part, '(', ')');
|
||||||
$ret[] = $this->parse($part);
|
$ret[] = $this->parse($part);
|
||||||
}
|
}
|
||||||
$r = implode(" AND ",$ret);
|
$r = implode(' AND ',$ret);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
$parts = Doctrine_Query::bracketExplode($str, array(' \|\| ', ' OR '), "(", ")");
|
$parts = Doctrine_Query::bracketExplode($str, array(' \|\| ', ' OR '), '(', ')');
|
||||||
if(count($parts) > 1) {
|
if(count($parts) > 1) {
|
||||||
$ret = array();
|
$ret = array();
|
||||||
foreach($parts as $part) {
|
foreach($parts as $part) {
|
||||||
$part = Doctrine_Query::bracketTrim($part, "(", ")");
|
$part = Doctrine_Query::bracketTrim($part, '(', ')');
|
||||||
$ret[] = $this->parse($part);
|
$ret[] = $this->parse($part);
|
||||||
}
|
}
|
||||||
$r = implode(" OR ",$ret);
|
$r = implode(' OR ',$ret);
|
||||||
} else {
|
} else {
|
||||||
if(substr($parts[0],0,1) == "(" && substr($parts[0],-1) == ")")
|
if(substr($parts[0],0,1) == '(' && substr($parts[0],-1) == ')')
|
||||||
return $this->parse(substr($parts[0],1,-1));
|
return $this->parse(substr($parts[0],1,-1));
|
||||||
else
|
else
|
||||||
return $this->load($parts[0]);
|
return $this->load($parts[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "(".$r.")";
|
return '(' . $r . ')';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,6 +327,12 @@ $menu = array('Getting started' =>
|
|||||||
'Planned',
|
'Planned',
|
||||||
'Technical Details',
|
'Technical Details',
|
||||||
'Maintainer'),
|
'Maintainer'),
|
||||||
|
'Hook' => array(
|
||||||
|
'Introduction',
|
||||||
|
'Building queries',
|
||||||
|
'List of parsers',
|
||||||
|
|
||||||
|
),
|
||||||
/**
|
/**
|
||||||
'Debugger' => array(
|
'Debugger' => array(
|
||||||
'Introduction',
|
'Introduction',
|
||||||
|
19
tests/ExportReporterTestCase.php
Normal file
19
tests/ExportReporterTestCase.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
class BadLyNamed__Class extends Doctrine_Record {
|
||||||
|
public function setTableDefinition() {
|
||||||
|
|
||||||
|
}
|
||||||
|
public function setUp() { }
|
||||||
|
}
|
||||||
|
class Doctrine_Export_Reporter_TestCase extends Doctrine_Driver_UnitTestCase {
|
||||||
|
public function __construct() {
|
||||||
|
parent::__construct('sqlite');
|
||||||
|
}
|
||||||
|
public function testExportChecksClassNaming() {
|
||||||
|
$reporter = $this->export->export('BadLyNamed__Class');
|
||||||
|
|
||||||
|
// Class name is not valid. Double underscores are not allowed
|
||||||
|
|
||||||
|
$this->assertEqual($reporter->pop(), array(E_WARNING, Doctrine::ERR_CLASS_NAME));
|
||||||
|
}
|
||||||
|
}
|
57
tests/HookTestCase.php
Normal file
57
tests/HookTestCase.php
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
class Doctrine_Hook_TestCase extends Doctrine_UnitTestCase {
|
||||||
|
|
||||||
|
public function testHookWhereAcceptsArrays() {
|
||||||
|
$hook = new Doctrine_Hook('SELECT u.name FROM User u LEFT JOIN u.Phonenumber p');
|
||||||
|
|
||||||
|
$a['where'] = array('u.name' => 'Jack Daniels',
|
||||||
|
'u.loginname' => 'TheMan');
|
||||||
|
|
||||||
|
$hook->hookWhere($a['where']);
|
||||||
|
$this->assertEqual($hook->getQuery()->getQuery(), 'SELECT e.id AS e__id, e.name AS e__name FROM entity e LEFT JOIN phonenumber p ON e.id = p.entity_id WHERE (e.name LIKE ? OR e.name LIKE ?) AND e.loginname LIKE ? AND (e.type = 0)');
|
||||||
|
|
||||||
|
}
|
||||||
|
public function testEqualParserUsesEqualOperator() {
|
||||||
|
$parser = new Doctrine_Hook_Equal();
|
||||||
|
|
||||||
|
$parser->parse('u', 'name', 'zYne');
|
||||||
|
|
||||||
|
$this->assertEqual($parser->getCondition(), 'u.name = ?');
|
||||||
|
$this->assertEqual($parser->getParams(), array('zYne'));
|
||||||
|
}
|
||||||
|
public function testWordLikeParserUsesLikeOperator() {
|
||||||
|
$parser = new Doctrine_Hook_WordLike();
|
||||||
|
|
||||||
|
$parser->parse('u', 'name', 'zYne');
|
||||||
|
|
||||||
|
$this->assertEqual($parser->getCondition(), 'u.name LIKE ?');
|
||||||
|
$this->assertEqual($parser->getParams(), array('zYne%'));
|
||||||
|
}
|
||||||
|
public function testIntegerParserSupportsIntervals() {
|
||||||
|
$parser = new Doctrine_Hook_Integer();
|
||||||
|
|
||||||
|
$parser->parse('m', 'year', '1998-2000');
|
||||||
|
|
||||||
|
$this->assertEqual($parser->getCondition(), '(m.year > ? AND m.year < ?)');
|
||||||
|
$this->assertEqual($parser->getParams(), array('1998', '2000'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testIntegerParserSupportsEqualOperator() {
|
||||||
|
$parser = new Doctrine_Hook_Integer();
|
||||||
|
|
||||||
|
$parser->parse('m', 'year', '1998');
|
||||||
|
|
||||||
|
$this->assertEqual($parser->getCondition(), 'm.year = ?');
|
||||||
|
$this->assertEqual($parser->getParams(), array('1998'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testIntegerParserSupportsNestingConditions() {
|
||||||
|
$parser = new Doctrine_Hook_Integer();
|
||||||
|
|
||||||
|
$parser->parse('m', 'year', '1998-2000 OR 2001');
|
||||||
|
|
||||||
|
$this->assertEqual($parser->getCondition(), '((m.year > ? AND m.year < ?) OR m.year = ?)');
|
||||||
|
$this->assertEqual($parser->getParams(), array('1998', '2000', '2001'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
95
tests/QueryAggregateValueTestCase.php
Normal file
95
tests/QueryAggregateValueTestCase.php
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
<?php
|
||||||
|
class Doctrine_Query_AggregateValue_TestCase extends Doctrine_UnitTestCase {
|
||||||
|
public function prepareData() { }
|
||||||
|
|
||||||
|
|
||||||
|
public function testInitData() {
|
||||||
|
$users = new Doctrine_Collection('User');
|
||||||
|
|
||||||
|
$users[0]->name = 'John';
|
||||||
|
$users[0]->Phonenumber[0]->phonenumber = '123 123';
|
||||||
|
$users[0]->Phonenumber[1]->phonenumber = '222 222';
|
||||||
|
$users[0]->Phonenumber[2]->phonenumber = '333 333';
|
||||||
|
|
||||||
|
$users[1]->name = 'John';
|
||||||
|
$users[2]->name = 'James';
|
||||||
|
$users[2]->Phonenumber[0]->phonenumber = '222 344';
|
||||||
|
$users[2]->Phonenumber[1]->phonenumber = '222 344';
|
||||||
|
$users[3]->name = 'James';
|
||||||
|
$users[3]->Phonenumber[0]->phonenumber = '123 123';
|
||||||
|
|
||||||
|
$users->save();
|
||||||
|
}
|
||||||
|
public function testRecordSupportsValueMapping() {
|
||||||
|
$record = new User();
|
||||||
|
|
||||||
|
try {
|
||||||
|
$record->get('count');
|
||||||
|
$this->fail();
|
||||||
|
} catch(Doctrine_Exception $e) {
|
||||||
|
$this->pass();
|
||||||
|
}
|
||||||
|
|
||||||
|
$record->mapValue('count', 3);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$i = $record->get('count');
|
||||||
|
} catch(Doctrine_Exception $e) {
|
||||||
|
$this->fail();
|
||||||
|
}
|
||||||
|
$this->assertEqual($i, 3);
|
||||||
|
}
|
||||||
|
public function testAggregateValueIsMappedToNewRecordOnEmptyResultSet() {
|
||||||
|
$q = new Doctrine_Query();
|
||||||
|
|
||||||
|
$q->select('COUNT(u.id) count')->from('User u');
|
||||||
|
|
||||||
|
$users = $q->execute();
|
||||||
|
|
||||||
|
$this->assertEqual($users->count(), 1);
|
||||||
|
$this->assertEqual($users[0]->state(), Doctrine_Record::STATE_TCLEAN);
|
||||||
|
}
|
||||||
|
public function testAggregateValueIsMappedToRecord() {
|
||||||
|
$q = new Doctrine_Query();
|
||||||
|
|
||||||
|
$q->select('u.name, COUNT(u.id) count')->from('User u')->groupby('u.name');
|
||||||
|
|
||||||
|
$users = $q->execute();
|
||||||
|
|
||||||
|
$this->assertEqual($users->count(), 2);
|
||||||
|
|
||||||
|
$this->assertEqual($users[0]->state(), Doctrine_Record::STATE_PROXY);
|
||||||
|
$this->assertEqual($users[1]->state(), Doctrine_Record::STATE_PROXY);
|
||||||
|
|
||||||
|
$this->assertEqual($users[0]->count, 2);
|
||||||
|
$this->assertEqual($users[1]->count, 2);
|
||||||
|
}
|
||||||
|
public function testAggregateValueMappingSupportsLeftJoins() {
|
||||||
|
$q = new Doctrine_Query();
|
||||||
|
|
||||||
|
$q->select('u.name, COUNT(p.id) count')->from('User u')->leftJoin('u.Phonenumber p')->groupby('u.id');
|
||||||
|
|
||||||
|
$users = $q->execute();
|
||||||
|
|
||||||
|
$this->assertEqual($users->count(), 4);
|
||||||
|
|
||||||
|
$this->assertEqual($users[0]->Phonenumber[0]->count, 3);
|
||||||
|
$this->assertEqual($users[1]->Phonenumber[0]->count, 0);
|
||||||
|
$this->assertEqual($users[2]->Phonenumber[0]->count, 2);
|
||||||
|
$this->assertEqual($users[3]->Phonenumber[0]->count, 1);
|
||||||
|
}
|
||||||
|
public function testAggregateValueMappingSupportsInnerJoins() {
|
||||||
|
$q = new Doctrine_Query();
|
||||||
|
|
||||||
|
$q->select('u.name, COUNT(p.id) count')->from('User u')->innerJoin('u.Phonenumber p')->groupby('u.id');
|
||||||
|
|
||||||
|
$users = $q->execute();
|
||||||
|
|
||||||
|
$this->assertEqual($users->count(), 3);
|
||||||
|
|
||||||
|
$this->assertEqual($users[0]->Phonenumber[0]->count, 3);
|
||||||
|
$this->assertEqual($users[1]->Phonenumber[0]->count, 2);
|
||||||
|
$this->assertEqual($users[2]->Phonenumber[0]->count, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
@ -29,6 +29,7 @@ require_once('ViewTestCase.php');
|
|||||||
require_once('RawSqlTestCase.php');
|
require_once('RawSqlTestCase.php');
|
||||||
require_once('CustomPrimaryKeyTestCase.php');
|
require_once('CustomPrimaryKeyTestCase.php');
|
||||||
require_once('FilterTestCase.php');
|
require_once('FilterTestCase.php');
|
||||||
|
require_once('HookTestCase.php');
|
||||||
|
|
||||||
require_once('QueryTestCase.php');
|
require_once('QueryTestCase.php');
|
||||||
require_once('QueryLimitTestCase.php');
|
require_once('QueryLimitTestCase.php');
|
||||||
@ -155,6 +156,7 @@ $test->addTestCase(new Doctrine_Configurable_TestCase());
|
|||||||
$test->addTestCase(new Doctrine_Export_Sqlite_TestCase());
|
$test->addTestCase(new Doctrine_Export_Sqlite_TestCase());
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$test->addTestCase(new Doctrine_Export_Reporter_TestCase());
|
$test->addTestCase(new Doctrine_Export_Reporter_TestCase());
|
||||||
|
|
||||||
$test->addTestCase(new Doctrine_Transaction_TestCase());
|
$test->addTestCase(new Doctrine_Transaction_TestCase());
|
||||||
@ -189,7 +191,6 @@ $test->addTestCase(new Doctrine_Db_TestCase());
|
|||||||
|
|
||||||
$test->addTestCase(new Doctrine_Db_Profiler_TestCase());
|
$test->addTestCase(new Doctrine_Db_Profiler_TestCase());
|
||||||
|
|
||||||
$test->addTestCase(new Doctrine_Query_MultiJoin_TestCase());
|
|
||||||
|
|
||||||
$test->addTestCase(new Doctrine_Record_TestCase());
|
$test->addTestCase(new Doctrine_Record_TestCase());
|
||||||
|
|
||||||
@ -223,7 +224,6 @@ $test->addTestCase(new Doctrine_RawSql_TestCase());
|
|||||||
|
|
||||||
$test->addTestCase(new Doctrine_CollectionTestCase());
|
$test->addTestCase(new Doctrine_CollectionTestCase());
|
||||||
|
|
||||||
$test->addTestCase(new Doctrine_Query_ReferenceModel_TestCase());
|
|
||||||
|
|
||||||
$test->addTestCase(new Doctrine_DataDict_Sqlite_TestCase());
|
$test->addTestCase(new Doctrine_DataDict_Sqlite_TestCase());
|
||||||
|
|
||||||
@ -235,35 +235,26 @@ $test->addTestCase(new Doctrine_CustomResultSetOrderTestCase());
|
|||||||
|
|
||||||
//$test->addTestCase(new Doctrine_Record_Filter_TestCase());
|
//$test->addTestCase(new Doctrine_Record_Filter_TestCase());
|
||||||
|
|
||||||
$test->addTestCase(new Doctrine_Query_Condition_TestCase());
|
|
||||||
|
|
||||||
$test->addTestCase(new Doctrine_Query_ComponentAlias_TestCase());
|
|
||||||
|
|
||||||
$test->addTestCase(new Doctrine_Query_Subquery_TestCase());
|
|
||||||
|
|
||||||
$test->addTestCase(new Doctrine_EnumTestCase());
|
$test->addTestCase(new Doctrine_EnumTestCase());
|
||||||
|
|
||||||
|
$test->addTestCase(new Doctrine_Query_MultiJoin_TestCase());
|
||||||
|
$test->addTestCase(new Doctrine_Query_ReferenceModel_TestCase());
|
||||||
|
$test->addTestCase(new Doctrine_Query_Condition_TestCase());
|
||||||
|
$test->addTestCase(new Doctrine_Query_ComponentAlias_TestCase());
|
||||||
|
$test->addTestCase(new Doctrine_Query_Subquery_TestCase());
|
||||||
$test->addTestCase(new Doctrine_Query_TestCase());
|
$test->addTestCase(new Doctrine_Query_TestCase());
|
||||||
|
|
||||||
$test->addTestCase(new Doctrine_Query_ShortAliases_TestCase());
|
$test->addTestCase(new Doctrine_Query_ShortAliases_TestCase());
|
||||||
|
|
||||||
$test->addTestCase(new Doctrine_Query_From_TestCase());
|
$test->addTestCase(new Doctrine_Query_From_TestCase());
|
||||||
|
|
||||||
$test->addTestCase(new Doctrine_Query_Delete_TestCase());
|
$test->addTestCase(new Doctrine_Query_Delete_TestCase());
|
||||||
|
|
||||||
$test->addTestCase(new Doctrine_Query_Where_TestCase());
|
$test->addTestCase(new Doctrine_Query_Where_TestCase());
|
||||||
|
|
||||||
$test->addTestCase(new Doctrine_Query_Limit_TestCase());
|
$test->addTestCase(new Doctrine_Query_Limit_TestCase());
|
||||||
|
|
||||||
$test->addTestCase(new Doctrine_Query_IdentifierQuoting_TestCase());
|
$test->addTestCase(new Doctrine_Query_IdentifierQuoting_TestCase());
|
||||||
|
|
||||||
$test->addTestCase(new Doctrine_Query_Update_TestCase());
|
$test->addTestCase(new Doctrine_Query_Update_TestCase());
|
||||||
|
|
||||||
$test->addTestCase(new Doctrine_Query_AggregateValue_TestCase());
|
$test->addTestCase(new Doctrine_Query_AggregateValue_TestCase());
|
||||||
|
|
||||||
|
|
||||||
$test->addTestCase(new Doctrine_Query_Select_TestCase());
|
$test->addTestCase(new Doctrine_Query_Select_TestCase());
|
||||||
|
|
||||||
|
$test->addTestCase(new Doctrine_Hook_TestCase());
|
||||||
|
|
||||||
//$test->addTestCase(new Doctrine_Cache_Query_SqliteTestCase());
|
//$test->addTestCase(new Doctrine_Cache_Query_SqliteTestCase());
|
||||||
//$test->addTestCase(new Doctrine_Cache_FileTestCase());
|
//$test->addTestCase(new Doctrine_Cache_FileTestCase());
|
||||||
//$test->addTestCase(new Doctrine_Cache_SqliteTestCase());
|
//$test->addTestCase(new Doctrine_Cache_SqliteTestCase());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user