Commit f26217c8 authored by zYne's avatar zYne

DQL core refactored

parent b50aceec
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
*/ */
Doctrine::autoload('Doctrine_Hydrate'); Doctrine::autoload('Doctrine_Hydrate');
/** /**
* Doctrine_Query2 * Doctrine_Query
* *
* @package Doctrine * @package Doctrine
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
...@@ -30,7 +30,7 @@ Doctrine::autoload('Doctrine_Hydrate'); ...@@ -30,7 +30,7 @@ Doctrine::autoload('Doctrine_Hydrate');
* @version $Revision: 1296 $ * @version $Revision: 1296 $
* @author Konsta Vesterinen <kvesteri@cc.hut.fi> * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
*/ */
class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable class Doctrine_Query extends Doctrine_Hydrate2 implements Countable
{ {
/** /**
* @param array $subqueryAliases the table aliases needed in some LIMIT subqueries * @param array $subqueryAliases the table aliases needed in some LIMIT subqueries
...@@ -88,7 +88,7 @@ class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable ...@@ -88,7 +88,7 @@ class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable
*/ */
public static function create() public static function create()
{ {
return new Doctrine_Query2(); return new Doctrine_Query();
} }
/** /**
* isSubquery * isSubquery
...@@ -205,7 +205,7 @@ class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable ...@@ -205,7 +205,7 @@ class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable
*/ */
public function parseSelect($dql) public function parseSelect($dql)
{ {
$refs = Doctrine_Query::bracketExplode($dql, ','); $refs = Doctrine_Tokenizer::bracketExplode($dql, ',');
foreach ($refs as $reference) { foreach ($refs as $reference) {
if (strpos($reference, '(') !== false) { if (strpos($reference, '(') !== false) {
...@@ -237,7 +237,7 @@ class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable ...@@ -237,7 +237,7 @@ class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable
*/ */
public function parseSubselect($reference) public function parseSubselect($reference)
{ {
$e = Doctrine_Query::bracketExplode($reference, ' '); $e = Doctrine_Tokenizer::bracketExplode($reference, ' ');
$alias = $e[1]; $alias = $e[1];
if (count($e) > 2) { if (count($e) > 2) {
...@@ -253,7 +253,7 @@ class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable ...@@ -253,7 +253,7 @@ class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable
} }
public function parseAggregateFunction2($func) public function parseAggregateFunction2($func)
{ {
$e = Doctrine_Query::bracketExplode($func, ' '); $e = Doctrine_Tokenizer::bracketExplode($func, ' ');
$func = $e[0]; $func = $e[0];
$pos = strpos($func, '('); $pos = strpos($func, '(');
...@@ -1132,7 +1132,7 @@ class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable ...@@ -1132,7 +1132,7 @@ class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable
public function distinct($flag = true) public function distinct($flag = true)
{ {
$this->_parts['distinct'] = (bool) $flag; $this->_parts['distinct'] = (bool) $flag;
return $this; return $this;
} }
......
...@@ -87,30 +87,30 @@ class Doctrine_RawSql extends Doctrine_Hydrate ...@@ -87,30 +87,30 @@ class Doctrine_RawSql extends Doctrine_Hydrate
foreach ($e as $k => $part) { foreach ($e as $k => $part) {
$low = strtolower($part); $low = strtolower($part);
switch (strtolower($part)) { switch (strtolower($part)) {
case "select": case 'select':
case "from": case 'from':
case "where": case 'where':
case "limit": case 'limit':
case "offset": case 'offset':
case "having": case 'having':
$p = $low; $p = $low;
if ( ! isset($parts[$low])) { if ( ! isset($parts[$low])) {
$parts[$low] = array(); $parts[$low] = array();
} }
break; break;
case "order": case 'order':
case "group": case 'group':
$i = ($k + 1); $i = ($k + 1);
if (isset($e[$i]) && strtolower($e[$i]) === "by") { if (isset($e[$i]) && strtolower($e[$i]) === 'by') {
$p = $low; $p = $low;
$p .= "by"; $p .= 'by';
$parts[$low."by"] = array(); $parts[$low.'by'] = array();
} else { } else {
$parts[$p][] = $part; $parts[$p][] = $part;
} }
break; break;
case "by": case 'by':
continue; continue;
default: default:
if ( ! isset($parts[$p][0])) { if ( ! isset($parts[$p][0])) {
...@@ -118,11 +118,11 @@ class Doctrine_RawSql extends Doctrine_Hydrate ...@@ -118,11 +118,11 @@ class Doctrine_RawSql extends Doctrine_Hydrate
} else { } else {
$parts[$p][0] .= ' '.$part; $parts[$p][0] .= ' '.$part;
} }
}; }
}; }
$this->parts = $parts; $this->parts = $parts;
$this->parts["select"] = array(); $this->parts['select'] = array();
return $this; return $this;
} }
...@@ -149,12 +149,12 @@ class Doctrine_RawSql extends Doctrine_Hydrate ...@@ -149,12 +149,12 @@ class Doctrine_RawSql extends Doctrine_Hydrate
if ($e[1] == '*') { if ($e[1] == '*') {
foreach ($this->tables[$e[0]]->getColumnNames() as $name) { foreach ($this->tables[$e[0]]->getColumnNames() as $name) {
$field = $e[0].".".$name; $field = $e[0] . '.' . $name;
$this->parts["select"][$field] = $field." AS ".$e[0]."__".$name; $this->parts['select'][$field] = $field . ' AS ' . $e[0] . '__' . $name;
} }
} else { } else {
$field = $e[0].".".$e[1]; $field = $e[0] . '.' . $e[1];
$this->parts["select"][$field] = $field." AS ".$e[0]."__".$e[1]; $this->parts['select'][$field] = $field . ' AS ' . $e[0] . '__' . $e[1];
} }
} }
...@@ -163,13 +163,13 @@ class Doctrine_RawSql extends Doctrine_Hydrate ...@@ -163,13 +163,13 @@ class Doctrine_RawSql extends Doctrine_Hydrate
foreach ($this->tableAliases as $alias) { foreach ($this->tableAliases as $alias) {
foreach ($this->tables[$alias]->getPrimaryKeys() as $key) { foreach ($this->tables[$alias]->getPrimaryKeys() as $key) {
$field = $alias . '.' . $key; $field = $alias . '.' . $key;
if ( ! isset($this->parts["select"][$field])) { if ( ! isset($this->parts['select'][$field])) {
$this->parts["select"][$field] = $field." AS ".$alias."__".$key; $this->parts['select'][$field] = $field . ' AS ' . $alias . '__' . $key;
} }
} }
} }
$q = 'SELECT '.implode(', ', $this->parts['select']); $q = 'SELECT ' . implode(', ', $this->parts['select']);
$string = $this->applyInheritance(); $string = $this->applyInheritance();
if ( ! empty($string)) { if ( ! empty($string)) {
...@@ -183,8 +183,8 @@ class Doctrine_RawSql extends Doctrine_Hydrate ...@@ -183,8 +183,8 @@ class Doctrine_RawSql extends Doctrine_Hydrate
$q .= ( ! empty($this->parts['groupby']))? ' GROUP BY ' . implode(', ', $this->parts['groupby']) : ''; $q .= ( ! empty($this->parts['groupby']))? ' GROUP BY ' . implode(', ', $this->parts['groupby']) : '';
$q .= ( ! empty($this->parts['having']))? ' HAVING ' . implode(' ', $this->parts['having']) : ''; $q .= ( ! empty($this->parts['having']))? ' HAVING ' . implode(' ', $this->parts['having']) : '';
$q .= ( ! empty($this->parts['orderby']))? ' ORDER BY ' . implode(' ', $this->parts['orderby']) : ''; $q .= ( ! empty($this->parts['orderby']))? ' ORDER BY ' . implode(' ', $this->parts['orderby']) : '';
$q .= ( ! empty($this->parts['limit']))? ' LIMIT ' . implode(' ', $this->parts['limit']) : ''; $q .= ( ! empty($this->parts['limit']))? ' LIMIT ' . implode(' ', $this->parts['limit']) : '';
$q .= ( ! empty($this->parts['offset']))? ' OFFSET ' . implode(' ', $this->parts['offset']) : ''; $q .= ( ! empty($this->parts['offset']))? ' OFFSET ' . implode(' ', $this->parts['offset']) : '';
if ( ! empty($string)) { if ( ! empty($string)) {
array_pop($this->parts['where']); array_pop($this->parts['where']);
...@@ -216,8 +216,10 @@ class Doctrine_RawSql extends Doctrine_Hydrate ...@@ -216,8 +216,10 @@ class Doctrine_RawSql extends Doctrine_Hydrate
foreach ($e as $k => $component) { foreach ($e as $k => $component) {
$currPath .= '.' . $component; $currPath .= '.' . $component;
if ($k == 0)
if ($k == 0) {
$currPath = substr($currPath,1); $currPath = substr($currPath,1);
}
if (isset($this->tableAliases[$currPath])) { if (isset($this->tableAliases[$currPath])) {
$alias = $this->tableAliases[$currPath]; $alias = $this->tableAliases[$currPath];
...@@ -230,12 +232,12 @@ class Doctrine_RawSql extends Doctrine_Hydrate ...@@ -230,12 +232,12 @@ class Doctrine_RawSql extends Doctrine_Hydrate
} }
$table = $this->conn->getTable($component); $table = $this->conn->getTable($component);
$this->tables[$alias] = $table; $this->tables[$alias] = $table;
$this->fetchModes[$alias] = Doctrine::FETCH_IMMEDIATE;
$this->tableAliases[$currPath] = $alias; $this->tableAliases[$currPath] = $alias;
if ($k !== 0) { if ($k !== 0) {
$this->joins[$alias] = $prevAlias; $this->joins[$alias] = $prevAlias;
} }
$prevAlias = $alias; $prevAlias = $alias;
$prevPath = $currPath; $prevPath = $currPath;
} }
......
...@@ -19,9 +19,11 @@ ...@@ -19,9 +19,11 @@
* <http://www.phpdoctrine.com>. * <http://www.phpdoctrine.com>.
*/ */
/** /**
* Doctrine_Table represents a database table * Doctrine_Table
* each Doctrine_Table holds the information of foreignKeys and associations *
* * This class represents a database table.
* Each Doctrine_Table holds the information of foreignKeys and associations
* to other tables.
* *
* @author Konsta Vesterinen <kvesteri@cc.hut.fi> * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @package Doctrine * @package Doctrine
...@@ -54,10 +56,6 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -54,10 +56,6 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
* @var integer $identifierType the type of identifier this table uses * @var integer $identifierType the type of identifier this table uses
*/ */
private $identifierType; private $identifierType;
/**
* @var string $query cached simple query
*/
private $query;
/** /**
* @var Doctrine_Connection $conn Doctrine_Connection object that created this table * @var Doctrine_Connection $conn Doctrine_Connection object that created this table
*/ */
...@@ -150,18 +148,18 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -150,18 +148,18 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
* *
* -- treeOptions the tree options * -- treeOptions the tree options
*/ */
protected $options = array('name' => null, protected $options = array('name' => null,
'tableName' => null, 'tableName' => null,
'sequenceName' => null, 'sequenceName' => null,
'inheritanceMap' => array(), 'inheritanceMap' => array(),
'enumMap' => array(), 'enumMap' => array(),
'engine' => null, 'engine' => null,
'charset' => null, 'charset' => null,
'collation' => null, 'collation' => null,
'treeImpl' => null, 'treeImpl' => null,
'treeOptions' => null, 'treeOptions' => null,
'indexes' => array(), 'indexes' => array(),
); );
/** /**
* @var Doctrine_Tree $tree tree object associated with this table * @var Doctrine_Tree $tree tree object associated with this table
*/ */
...@@ -284,19 +282,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -284,19 +282,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
$this->identifier = $pk; $this->identifier = $pk;
} }
} }
}; }
/**
if ( ! isset($definition['values'])) {
throw new Doctrine_Table_Exception('No values set for enum column ' . $name);
}
if ( ! is_array($definition['values'])) {
throw new Doctrine_Table_Exception('Enum column values should be specified as an array.');
}
*/
} }
} else { } else {
throw new Doctrine_Table_Exception("Class '$name' has no table definition."); throw new Doctrine_Table_Exception("Class '$name' has no table definition.");
...@@ -313,9 +299,6 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -313,9 +299,6 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
array_pop($names); array_pop($names);
$this->options['parents'] = $names; $this->options['parents'] = $names;
$this->query = 'SELECT ' . implode(', ', array_keys($this->columns)) . ' FROM ' . $this->getTableName();
$this->repository = new Doctrine_Table_Repository($this); $this->repository = new Doctrine_Table_Repository($this);
} }
/** /**
...@@ -1043,7 +1026,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -1043,7 +1026,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
$id = array_values($id); $id = array_values($id);
} }
$query = $this->query . ' WHERE ' . implode(' = ? AND ', $this->primaryKeys) . ' = ?'; $query = 'SELECT ' . implode(', ', array_keys($this->columns)) . ' FROM ' . $this->getTableName() . ' WHERE ' . implode(' = ? AND ', $this->primaryKeys) . ' = ?';
$query = $this->applyInheritance($query); $query = $this->applyInheritance($query);
$params = array_merge($id, array_values($this->options['inheritanceMap'])); $params = array_merge($id, array_values($this->options['inheritanceMap']));
...@@ -1430,15 +1413,6 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -1430,15 +1413,6 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
$data = $stmt->fetch(PDO::FETCH_NUM); $data = $stmt->fetch(PDO::FETCH_NUM);
return isset($data[0])?$data[0]:1; return isset($data[0])?$data[0]:1;
} }
/**
* returns simple cached query
*
* @return string
*/
final public function getQuery()
{
return $this->query;
}
/** /**
* returns internal data, used by Doctrine_Record instances * returns internal data, used by Doctrine_Record instances
* when retrieving data from database * when retrieving data from database
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
* and is licensed under the LGPL. For more information, see * and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.com>. * <http://www.phpdoctrine.com>.
*/ */
Doctrine::autoload("Doctrine_Access"); Doctrine::autoload('Doctrine_Access');
/** /**
* Doctrine_Collection * Doctrine_Collection
* Collection of Doctrine_Record objects. * Collection of Doctrine_Record objects.
...@@ -34,33 +34,29 @@ Doctrine::autoload("Doctrine_Access"); ...@@ -34,33 +34,29 @@ Doctrine::autoload("Doctrine_Access");
class Doctrine_Collection extends Doctrine_Access implements Countable, IteratorAggregate, Serializable class Doctrine_Collection extends Doctrine_Access implements Countable, IteratorAggregate, Serializable
{ {
/** /**
* @var array $data an array containing the data access objects of this collection * @var array $data an array containing the records of this collection
*/ */
protected $data = array(); protected $data = array();
/** /**
* @var Doctrine_Table $table each collection has only records of specified table * @var Doctrine_Table $table each collection has only records of specified table
*/ */
protected $table; protected $_table;
/**
* @var array $_snapshot a snapshot of the fetched data
*/
protected $_snapshot = array();
/** /**
* @var Doctrine_Record $reference collection can belong to a record * @var Doctrine_Record $reference collection can belong to a record
*/ */
protected $reference; protected $reference;
/** /**
* @var string $reference_field the reference field of the collection * @var string $referenceField the reference field of the collection
*/ */
protected $reference_field; protected $referenceField;
/** /**
* @var Doctrine_Relation the record this collection is related to, if any * @var Doctrine_Relation the record this collection is related to, if any
*/ */
protected $relation; protected $relation;
/**
* @var boolean $expandable whether or not this collection has been expanded
*/
protected $expandable = true;
/**
* @var array $expanded
*/
protected $expanded = array();
/** /**
* @var string $keyColumn the name of the column that is used for collection key mapping * @var string $keyColumn the name of the column that is used for collection key mapping
*/ */
...@@ -70,7 +66,6 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -70,7 +66,6 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
*/ */
protected static $null; protected static $null;
protected $aggregateValues = array();
/** /**
* constructor * constructor
...@@ -83,7 +78,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -83,7 +78,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
$table = Doctrine_Manager::getInstance() $table = Doctrine_Manager::getInstance()
->getTable($table); ->getTable($table);
} }
$this->table = $table; $this->_table = $table;
$name = $table->getAttribute(Doctrine::ATTR_COLL_KEY); $name = $table->getAttribute(Doctrine::ATTR_COLL_KEY);
if ($name !== null) { if ($name !== null) {
...@@ -108,28 +103,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -108,28 +103,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
*/ */
public function getTable() public function getTable()
{ {
return $this->table; return $this->_table;
}
/**
* setAggregateValue
*
* @param string $name
* @param string $value
* @return void
*/
public function setAggregateValue($name, $value)
{
$this->aggregateValues[$name] = $value;
}
/**
* getAggregateValue
*
* @param string $name
* @return mixed
*/
public function getAggregateValue($name)
{
return $this->aggregateValues[$name];
} }
/** /**
* this method is automatically called when this Doctrine_Collection is serialized * this method is automatically called when this Doctrine_Collection is serialized
...@@ -168,45 +142,28 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -168,45 +142,28 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
$this->$name = $values; $this->$name = $values;
} }
$this->table = $connection->getTable($this->table); $this->_table = $connection->getTable($this->_table);
$this->expanded = array(); $this->expanded = array();
$this->expandable = true; $this->expandable = true;
$name = $this->table->getAttribute(Doctrine::ATTR_COLL_KEY); $name = $this->_table->getAttribute(Doctrine::ATTR_COLL_KEY);
if ($name !== null) { if ($name !== null) {
$this->keyColumn = $name; $this->keyColumn = $name;
} }
} }
/**
* isExpanded
*
* whether or not an offset batch has been expanded
* @return boolean
*/
public function isExpanded($offset)
{
return isset($this->expanded[$offset]);
}
/**
* isExpandable
*
* whether or not this collection is expandable
* @return boolean
*/
public function isExpandable()
{
return $this->expandable;
}
/** /**
* setKeyColumn * setKeyColumn
* sets the key column for this collection
* *
* @param string $column * @param string $column
* @return void * @return Doctrine_Collection
*/ */
public function setKeyColumn($column) public function setKeyColumn($column)
{ {
$this->keyColumn = $column; $this->keyColumn = $column;
return $this;
} }
/** /**
* getKeyColumn * getKeyColumn
...@@ -219,6 +176,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -219,6 +176,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
return $this->column; return $this->column;
} }
/** /**
* getData
* returns all the records as an array * returns all the records as an array
* *
* @return array * @return array
...@@ -227,13 +185,6 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -227,13 +185,6 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
{ {
return $this->data; return $this->data;
} }
/**
* @param array $data
*/
public function addData(array $data)
{
$this->data[] = $data;
}
/** /**
* getFirst * getFirst
* returns the first record in the collection * returns the first record in the collection
...@@ -269,15 +220,15 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -269,15 +220,15 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|| $relation instanceof Doctrine_Relation_LocalKey || $relation instanceof Doctrine_Relation_LocalKey
) { ) {
$this->reference_field = $relation->getForeign(); $this->referenceField = $relation->getForeign();
$value = $record->get($relation->getLocal()); $value = $record->get($relation->getLocal());
foreach ($this->getNormalIterator() as $record) { foreach ($this->getNormalIterator() as $record) {
if ($value !== null) { if ($value !== null) {
$record->set($this->reference_field, $value, false); $record->set($this->referenceField, $value, false);
} else { } else {
$record->set($this->reference_field, $this->reference, false); $record->set($this->referenceField, $this->reference, false);
} }
} }
} elseif ($relation instanceof Doctrine_Relation_Association) { } elseif ($relation instanceof Doctrine_Relation_Association) {
...@@ -293,127 +244,6 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -293,127 +244,6 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
{ {
return $this->reference; return $this->reference;
} }
/**
* expand
* expands the collection
*
* @return boolean
*/
public function expand($key)
{
$where = array();
$params = array();
$limit = null;
$offset = null;
switch (get_class($this)) {
case "Doctrine_Collection_Offset":
$limit = $this->getLimit();
$offset = (floor($key / $limit) * $limit);
if ( ! $this->expandable && isset($this->expanded[$offset])) {
return false;
}
$fields = implode(", ",$this->table->getColumnNames());
break;
default:
if ( ! $this->expandable) {
return false;
}
if ( ! isset($this->reference)) {
return false;
}
$id = $this->reference->obtainIdentifier();
if (empty($id)) {
return false;
}
switch (get_class($this)) {
case "Doctrine_Collection_Immediate":
$fields = implode(", ",$this->table->getColumnNames());
break;
default:
$fields = implode(", ",$this->table->getPrimaryKeys());
};
};
if (isset($this->relation)) {
if ($this->relation instanceof Doctrine_Relation_ForeignKey) {
$params[] = $this->reference->getIncremented();
$where[] = $this->reference_field." = ?";
if ( ! isset($offset)) {
$ids = $this->getPrimaryKeys();
if ( ! empty($ids)) {
$where[] = $this->table->getIdentifier()." NOT IN (".substr(str_repeat("?, ",count($ids)),0,-2).")";
$params = array_merge($params,$ids);
}
$this->expandable = false;
}
} elseif ($this->relation instanceof Doctrine_Relation_Association) {
$asf = $this->relation->getAssociationFactory();
$query = 'SELECT '.$foreign." FROM ".$asf->getTableName()." WHERE ".$local."=".$this->getIncremented();
$table = $fk->getTable();
$graph = new Doctrine_Query($table->getConnection());
$q = 'FROM ' . $table->getComponentName() . ' WHERE ' . $table->getComponentName() . '.' . $table->getIdentifier()." IN ($query)";
}
}
$query = "SELECT ".$fields." FROM ".$this->table->getTableName();
// apply column aggregation inheritance
$map = $this->table->inheritanceMap;
foreach ($map as $k => $v) {
$where[] = $k." = ?";
$params[] = $v;
}
if ( ! empty($where)) {
$query .= " WHERE ".implode(" AND ",$where);
}
$coll = $this->table->execute($query, $params, $limit, $offset);
if ( ! isset($offset)) {
foreach ($coll as $record) {
if (isset($this->reference_field)) {
$record->set($this->reference_field,$this->reference, false);
}
$this->reference->addReference($record, $this->relation);
}
} else {
$i = $offset;
foreach ($coll as $record) {
if (isset($this->reference)) {
$this->reference->addReference($record, $this->relation, $i);
} else {
$this->data[$i] = $record;
}
$i++;
}
$this->expanded[$offset] = true;
// check if the fetched collection's record count is smaller
// than the query limit, if so this collection has been expanded to its max size
if (count($coll) < $limit) {
$this->expandable = false;
}
}
return $coll;
}
/** /**
* remove * remove
* removes a specified collection element * removes a specified collection element
...@@ -464,11 +294,11 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -464,11 +294,11 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
*/ */
public function get($key) public function get($key)
{ {
if ($key === null) { if ($key === null || ! isset($this->data[$key])) {
$record = $this->table->create(); $record = $this->_table->create();
if (isset($this->reference_field)) { if (isset($this->referenceField)) {
$record->set($this->reference_field, $this->reference, false); $record->set($this->referenceField, $this->reference, false);
} }
$this->data[] = $record; $this->data[] = $record;
...@@ -476,25 +306,6 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -476,25 +306,6 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
return $record; return $record;
} }
if ( ! isset($this->data[$key])) {
$this->expand($key);
if ( ! isset($this->data[$key])) {
$this->data[$key] = $this->table->create();
}
if (isset($this->reference_field)) {
$value = $this->reference->get($this->relation->getLocal());
if ($value !== null) {
$this->data[$key]->set($this->reference_field, $value, false);
} else {
$this->data[$key]->set($this->reference_field, $this->reference, false);
}
}
}
return $this->data[$key]; return $this->data[$key];
} }
...@@ -504,7 +315,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -504,7 +315,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
public function getPrimaryKeys() public function getPrimaryKeys()
{ {
$list = array(); $list = array();
$name = $this->table->getIdentifier(); $name = $this->_table->getIdentifier();
foreach ($this->data as $record) { foreach ($this->data as $record) {
if (is_array($record) && isset($record[$name])) { if (is_array($record) && isset($record[$name])) {
...@@ -512,7 +323,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -512,7 +323,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
} else { } else {
$list[] = $record->getIncremented(); $list[] = $record->getIncremented();
} }
}; }
return $list; return $list;
} }
/** /**
...@@ -542,8 +353,8 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -542,8 +353,8 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
*/ */
public function set($key, Doctrine_Record $record) public function set($key, Doctrine_Record $record)
{ {
if (isset($this->reference_field)) { if (isset($this->referenceField)) {
$record->set($this->reference_field, $this->reference, false); $record->set($this->referenceField, $this->reference, false);
} }
$this->data[$key] = $record; $this->data[$key] = $record;
} }
...@@ -553,10 +364,10 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -553,10 +364,10 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
* @param string $key optional key for the record * @param string $key optional key for the record
* @return boolean * @return boolean
*/ */
public function add(Doctrine_Record $record,$key = null) public function add(Doctrine_Record $record, $key = null)
{ {
if (isset($this->reference_field)) { if (isset($this->referenceField)) {
$record->set($this->reference_field, $this->reference, false); $record->set($this->referenceField, $this->reference, false);
} }
/** /**
* for some weird reason in_array cannot be used here (php bug ?) * for some weird reason in_array cannot be used here (php bug ?)
...@@ -597,7 +408,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -597,7 +408,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
public function loadRelated($name = null) public function loadRelated($name = null)
{ {
$list = array(); $list = array();
$query = new Doctrine_Query($this->table->getConnection()); $query = new Doctrine_Query($this->_table->getConnection());
if ( ! isset($name)) { if ( ! isset($name)) {
foreach ($this->data as $record) { foreach ($this->data as $record) {
...@@ -606,13 +417,13 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -606,13 +417,13 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
$list[] = $value; $list[] = $value;
} }
}; };
$query->from($this->table->getComponentName() . '(' . implode(", ",$this->table->getPrimaryKeys()) . ')'); $query->from($this->_table->getComponentName() . '(' . implode(", ",$this->_table->getPrimaryKeys()) . ')');
$query->where($this->table->getComponentName() . '.id IN (' . substr(str_repeat("?, ", count($list)),0,-2) . ')'); $query->where($this->_table->getComponentName() . '.id IN (' . substr(str_repeat("?, ", count($list)),0,-2) . ')');
return $query; return $query;
} }
$rel = $this->table->getRelation($name); $rel = $this->_table->getRelation($name);
if ($rel instanceof Doctrine_Relation_LocalKey || $rel instanceof Doctrine_Relation_ForeignKey) { if ($rel instanceof Doctrine_Relation_LocalKey || $rel instanceof Doctrine_Relation_ForeignKey) {
foreach ($this->data as $record) { foreach ($this->data as $record) {
...@@ -642,7 +453,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -642,7 +453,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
*/ */
public function populateRelated($name, Doctrine_Collection $coll) public function populateRelated($name, Doctrine_Collection $coll)
{ {
$rel = $this->table->getRelation($name); $rel = $this->_table->getRelation($name);
$table = $rel->getTable(); $table = $rel->getTable();
$foreign = $rel->getForeign(); $foreign = $rel->getForeign();
$local = $rel->getLocal(); $local = $rel->getLocal();
...@@ -657,9 +468,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -657,9 +468,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
} }
} elseif ($rel instanceof Doctrine_Relation_ForeignKey) { } elseif ($rel instanceof Doctrine_Relation_ForeignKey) {
foreach ($this->data as $key => $record) { foreach ($this->data as $key => $record) {
if ($record->state() == Doctrine_Record::STATE_TCLEAN if ( ! $record->exists()) {
|| $record->state() == Doctrine_Record::STATE_TDIRTY
) {
continue; continue;
} }
$sub = new Doctrine_Collection($table); $sub = new Doctrine_Collection($table);
...@@ -674,14 +483,12 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -674,14 +483,12 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
$this->data[$key]->setRelated($name, $sub); $this->data[$key]->setRelated($name, $sub);
} }
} elseif ($rel instanceof Doctrine_Relation_Association) { } elseif ($rel instanceof Doctrine_Relation_Association) {
$identifier = $this->table->getIdentifier(); $identifier = $this->_table->getIdentifier();
$asf = $rel->getAssociationFactory(); $asf = $rel->getAssociationFactory();
$name = $table->getComponentName(); $name = $table->getComponentName();
foreach ($this->data as $key => $record) { foreach ($this->data as $key => $record) {
if ($record->state() == Doctrine_Record::STATE_TCLEAN if ( ! $record->exists()) {
|| $record->state() == Doctrine_Record::STATE_TDIRTY
) {
continue; continue;
} }
$sub = new Doctrine_Collection($table); $sub = new Doctrine_Collection($table);
...@@ -705,36 +512,93 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -705,36 +512,93 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
{ {
return new Doctrine_Collection_Iterator_Normal($this); return new Doctrine_Collection_Iterator_Normal($this);
} }
/**
* takeSnapshot
* takes a snapshot from this collection
*
* snapshots are used for diff processing, for example
* when a fetched collection has three elements, then two of those
* are being removed the diff would contain one element
*
* Doctrine_Collection::save() attaches the diff with the help of last
* snapshot.
*
* @return Doctrine_Collection
*/
public function takeSnapshot()
{
$this->_snapshot = $this->data;
return $this;
}
/**
* getSnapshot
* returns the data of the last snapshot
*
* @return array returns the data in last snapshot
*/
public function getSnapshot()
{
return $this->_snapshot;
}
/**
* processDiff
* processes the difference of the last snapshot and the current data
*
* an example:
* Snapshot with the objects 1, 2 and 4
* Current data with objects 2, 3 and 5
*
* The process would:
* 1. remove object 4
* 2. add objects 3 and 5
*
* @return Doctrine_Collection
*/
public function processDiff()
{
foreach (array_diff($this->snapshot, $this->data) as $record) {
$record->delete();
}
foreach (array_diff($this->data, $this->snapshot) as $record) {
$record->save();
}
return $this;
}
/** /**
* save * save
* saves all records of this collection * saves all records of this collection
* *
* @return void * @return Doctrine_Collection
*/ */
public function save(Doctrine_Connection $conn = null) public function save(Doctrine_Connection $conn = null)
{ {
if ($conn == null) { if ($conn == null) {
$conn = $this->table->getConnection(); $conn = $this->_table->getConnection();
} }
$conn->beginTransaction(); $conn->beginTransaction();
foreach ($this as $key => $record) { foreach ($this as $key => $record) {
$record->save($conn); $record->save($conn);
}; }
$conn->commit(); $conn->commit();
return $this;
} }
/** /**
* delete
* single shot delete * single shot delete
* deletes all records from this collection * deletes all records from this collection
* and uses only one database query to perform this operation * and uses only one database query to perform this operation
* *
* @return boolean * @return Doctrine_Collection
*/ */
public function delete(Doctrine_Connection $conn = null) public function delete(Doctrine_Connection $conn = null)
{ {
if ($conn == null) { if ($conn == null) {
$conn = $this->table->getConnection(); $conn = $this->_table->getConnection();
} }
$conn->beginTransaction(); $conn->beginTransaction();
...@@ -746,6 +610,8 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -746,6 +610,8 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
$conn->commit(); $conn->commit();
$this->data = array(); $this->data = array();
return $this;
} }
/** /**
* getIterator * getIterator
......
...@@ -999,7 +999,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun ...@@ -999,7 +999,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
case Doctrine_Record::STATE_TCLEAN: case Doctrine_Record::STATE_TCLEAN:
// do nothing // do nothing
break; break;
}; }
$record->getTable()->getAttribute(Doctrine::ATTR_LISTENER)->onSave($record); $record->getTable()->getAttribute(Doctrine::ATTR_LISTENER)->onSave($record);
} }
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
* and is licensed under the LGPL. For more information, see * and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.com>. * <http://www.phpdoctrine.com>.
*/ */
Doctrine::autoload('Doctrine_Access');
/** /**
* Doctrine_Hydrate is a base class for Doctrine_RawSql and Doctrine_Query. * Doctrine_Hydrate is a base class for Doctrine_RawSql and Doctrine_Query.
* Its purpose is to populate object graphs. * Its purpose is to populate object graphs.
...@@ -32,7 +32,7 @@ Doctrine::autoload('Doctrine_Access'); ...@@ -32,7 +32,7 @@ Doctrine::autoload('Doctrine_Access');
* @version $Revision$ * @version $Revision$
* @author Konsta Vesterinen <kvesteri@cc.hut.fi> * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
*/ */
abstract class Doctrine_Hydrate extends Doctrine_Access class Doctrine_Hydrate
{ {
/** /**
* QUERY TYPE CONSTANTS * QUERY TYPE CONSTANTS
...@@ -58,23 +58,7 @@ abstract class Doctrine_Hydrate extends Doctrine_Access ...@@ -58,23 +58,7 @@ abstract class Doctrine_Hydrate extends Doctrine_Access
* constant for CREATE queries * constant for CREATE queries
*/ */
const CREATE = 4; const CREATE = 4;
/**
* @var array $fetchmodes an array containing all fetchmodes
*/
protected $fetchModes = array();
/**
* @var array $tables an array containing all the tables used in the query
*/
protected $tables = array();
/**
* @var array $collections an array containing all collections
* this hydrater has created/will create
*/
protected $collections = array();
/**
* @var array $joins an array containing all table joins
*/
protected $joins = array();
/** /**
* @var array $params query input parameters * @var array $params query input parameters
*/ */
...@@ -88,28 +72,28 @@ abstract class Doctrine_Hydrate extends Doctrine_Access ...@@ -88,28 +72,28 @@ abstract class Doctrine_Hydrate extends Doctrine_Access
*/ */
protected $view; protected $view;
/** /**
* @var boolean $inheritanceApplied * @var array $_aliasMap two dimensional array containing the map for query aliases
*/ * Main keys are component aliases
protected $inheritanceApplied = false; *
/** * table table object associated with given alias
* @var boolean $aggregate *
*/ * relation the relation object owned by the parent
protected $aggregate = false; *
/** * parent the alias of the parent
* @var array $compAliases
*/ */
protected $compAliases = array(); protected $_aliasMap = array();
/** /**
* @var array $tableAliases * @var array $tableAliases
*/ */
protected $tableAliases = array(); protected $tableAliases = array();
/** /**
* @var array $tableIndexes *
*/ */
protected $tableIndexes = array();
protected $pendingAggregates = array(); protected $pendingAggregates = array();
/**
*
*/
protected $subqueryAggregates = array(); protected $subqueryAggregates = array();
/** /**
* @var array $aggregateMap an array containing all aggregate aliases, keys as dql aliases * @var array $aggregateMap an array containing all aggregate aliases, keys as dql aliases
...@@ -154,15 +138,6 @@ abstract class Doctrine_Hydrate extends Doctrine_Access ...@@ -154,15 +138,6 @@ abstract class Doctrine_Hydrate extends Doctrine_Access
$this->conn = $connection; $this->conn = $connection;
$this->aliasHandler = new Doctrine_Hydrate_Alias(); $this->aliasHandler = new Doctrine_Hydrate_Alias();
} }
/**
* getComponentAliases
*
* @return array
*/
public function getComponentAliases()
{
return $this->compAliases;
}
/** /**
* getTableAliases * getTableAliases
* *
...@@ -172,47 +147,52 @@ abstract class Doctrine_Hydrate extends Doctrine_Access ...@@ -172,47 +147,52 @@ abstract class Doctrine_Hydrate extends Doctrine_Access
{ {
return $this->tableAliases; return $this->tableAliases;
} }
/** public function setTableAliases(array $aliases)
* getTableIndexes
*
* @return array
*/
public function getTableIndexes()
{ {
return $this->tableIndexes; $this->tableAliases = $aliases;
} }
/** public function getTableAlias($componentAlias)
* getTables {
* return $this->aliasHandler->getShortAlias($componentAlias);
* @return array }
*/ public function addQueryPart($name, $part)
public function getTables() {
if ( ! isset($this->parts[$name])) {
throw new Doctrine_Hydrate_Exception('Unknown query part ' . $name);
}
$this->parts[$name][] = $part;
}
public function getDeclaration($name)
{ {
return $this->tables; if ( ! isset($this->_aliasMap[$name])) {
throw new Doctrine_Hydrate_Exception('Unknown component alias ' . $name);
}
return $this->_aliasMap[$name];
}
public function setQueryPart($name, $part)
{
if ( ! isset($this->parts[$name])) {
throw new Doctrine_Hydrate_Exception('Unknown query part ' . $name);
}
if ($name !== 'limit' && $name !== 'offset') {
$this->parts[$name] = array($part);
} else {
$this->parts[$name] = $part;
}
} }
/** /**
* copyAliases * copyAliases
* *
* @return void * @return void
*/ */
public function copyAliases(Doctrine_Hydrate $query) public function copyAliases($query)
{ {
$this->compAliases = $query->getComponentAliases();
$this->tableAliases = $query->getTableAliases();
$this->tableIndexes = $query->getTableIndexes();
$this->aliasHandler = $query->aliasHandler; $this->aliasHandler = $query->aliasHandler;
return $this; return $this;
} }
public function getPathAlias($path)
{
$s = array_search($path, $this->compAliases);
if ($s === false)
return $path;
return $s;
}
/** /**
* createSubquery * createSubquery
* *
...@@ -231,12 +211,6 @@ abstract class Doctrine_Hydrate extends Doctrine_Access ...@@ -231,12 +211,6 @@ abstract class Doctrine_Hydrate extends Doctrine_Access
return $obj; return $obj;
} }
/**
* getQuery
*
* @return string
*/
abstract public function getQuery();
/** /**
* limitSubqueryUsed * limitSubqueryUsed
* *
...@@ -246,7 +220,14 @@ abstract class Doctrine_Hydrate extends Doctrine_Access ...@@ -246,7 +220,14 @@ abstract class Doctrine_Hydrate extends Doctrine_Access
{ {
return false; return false;
} }
public function getQueryPart($part)
{
if ( ! isset($this->parts[$part])) {
throw new Doctrine_Hydrate_Exception('Unknown query part ' . $part);
}
return $this->parts[$part];
}
/** /**
* remove * remove
* *
...@@ -271,25 +252,20 @@ abstract class Doctrine_Hydrate extends Doctrine_Access ...@@ -271,25 +252,20 @@ abstract class Doctrine_Hydrate extends Doctrine_Access
*/ */
protected function clear() protected function clear()
{ {
$this->fetchModes = array();
$this->tables = array(); $this->tables = array();
$this->parts = array( $this->parts = array(
"select" => array(), 'select' => array(),
"from" => array(), 'from' => array(),
"join" => array(), 'set' => array(),
"where" => array(), 'join' => array(),
"groupby" => array(), 'where' => array(),
"having" => array(), 'groupby' => array(),
"orderby" => array(), 'having' => array(),
"limit" => false, 'orderby' => array(),
"offset" => false, 'limit' => false,
); 'offset' => false,
);
$this->inheritanceApplied = false; $this->inheritanceApplied = false;
$this->aggregate = false;
$this->collections = array();
$this->joins = array();
$this->tableIndexes = array();
$this->tableAliases = array(); $this->tableAliases = array();
$this->aliasHandler->clear(); $this->aliasHandler->clear();
} }
...@@ -333,56 +309,6 @@ abstract class Doctrine_Hydrate extends Doctrine_Access ...@@ -333,56 +309,6 @@ abstract class Doctrine_Hydrate extends Doctrine_Access
{ {
return $this->params; return $this->params;
} }
/**
* getTableAlias
*
* @param string $path
* @return string
*/
final public function getTableAlias($path)
{
if (isset($this->compAliases[$path])) {
$path = $this->compAliases[$path];
}
if ( ! isset($this->tableAliases[$path])) {
return false;
}
return $this->tableAliases[$path];
}
/**
* getCollection
*
* @parma string $name component name
* @param integer $index
*/
private function getCollection($name)
{
$table = $this->tables[$name];
if ( ! isset($this->fetchModes[$name])) {
return new Doctrine_Collection($table);
}
switch ($this->fetchModes[$name]) {
case Doctrine::FETCH_BATCH:
$coll = new Doctrine_Collection_Batch($table);
break;
case Doctrine::FETCH_LAZY:
$coll = new Doctrine_Collection_Lazy($table);
break;
case Doctrine::FETCH_OFFSET:
$coll = new Doctrine_Collection_Offset($table);
break;
case Doctrine::FETCH_IMMEDIATE:
$coll = new Doctrine_Collection_Immediate($table);
break;
case Doctrine::FETCH_LAZY_OFFSET:
$coll = new Doctrine_Collection_LazyOffset($table);
break;
default:
throw new Doctrine_Exception("Unknown fetchmode");
};
return $coll;
}
/** /**
* setParams * setParams
* *
...@@ -392,15 +318,14 @@ abstract class Doctrine_Hydrate extends Doctrine_Access ...@@ -392,15 +318,14 @@ abstract class Doctrine_Hydrate extends Doctrine_Access
$this->params = $params; $this->params = $params;
} }
/** /**
* execute * _fetch
* executes the dql query and populates all collections
* *
* @param string $params * @param array $params prepared statement parameters
* @return Doctrine_Collection the root collection * @param integer $fetchMode the fetchmode
* @see Doctrine::FETCH_* constants
*/ */
public function execute($params = array(), $return = Doctrine::FETCH_RECORD) { public function _fetch($params = array(), $fetchMode = Doctrine::FETCH_RECORD)
$this->collections = array(); {
$params = $this->conn->convertBooleans(array_merge($this->params, $params)); $params = $this->conn->convertBooleans(array_merge($this->params, $params));
if ( ! $this->view) { if ( ! $this->view) {
...@@ -409,246 +334,188 @@ abstract class Doctrine_Hydrate extends Doctrine_Access ...@@ -409,246 +334,188 @@ abstract class Doctrine_Hydrate extends Doctrine_Access
$query = $this->view->getSelectSql(); $query = $this->view->getSelectSql();
} }
if ($this->isLimitSubqueryUsed() && if ($this->isLimitSubqueryUsed() &&
$this->conn->getDBH()->getAttribute(Doctrine::ATTR_DRIVER_NAME) !== 'mysql') { $this->conn->getDBH()->getAttribute(Doctrine::ATTR_DRIVER_NAME) !== 'mysql') {
$params = array_merge($params, $params); $params = array_merge($params, $params);
} }
$stmt = $this->conn->execute($query, $params); $stmt = $this->conn->execute($query, $params);
if ($this->aggregate) { return $this->parseData($stmt);
return $stmt->fetchAll(Doctrine::FETCH_ASSOC); }
}
public function setAliasMap($map)
if (count($this->tables) == 0) { {
throw new Doctrine_Query_Exception('No components selected'); $this->_aliasMap = $map;
} }
public function getAliasMap()
$keys = array_keys($this->tables); {
$root = $keys[0]; return $this->_aliasMap;
}
$previd = array(); /**
* mapAggregateValues
$coll = $this->getCollection($root); * map the aggregate values of given dataset row to a given record
$prev[$root] = $coll; *
* @param Doctrine_Record $record
if ($this->aggregate) { * @param array $row
$return = Doctrine::FETCH_ARRAY; * @return Doctrine_Record
*/
public function mapAggregateValues($record, array $row, $alias)
{
$found = false;
// aggregate values have numeric keys
if (isset($row[0])) {
// map each aggregate value
foreach ($row as $index => $value) {
$agg = false;
if (isset($this->pendingAggregates[$alias][$index])) {
$agg = $this->pendingAggregates[$alias][$index][3];
} elseif (isset($this->subqueryAggregates[$alias][$index])) {
$agg = $this->subqueryAggregates[$alias][$index];
}
$record->mapValue($agg, $value);
$found = true;
}
} }
return $found;
}
/**
* execute
* executes the dql query and populates all collections
*
* @param string $params
* @return Doctrine_Collection the root collection
*/
public function execute($params = array(), $return = Doctrine::FETCH_RECORD)
{
$array = (array) $this->_fetch($params, $return = Doctrine::FETCH_RECORD);
$array = $this->parseData($stmt); if (empty($this->_aliasMap)) {
throw new Doctrine_Hydrate_Exception("Couldn't execute query. Component alias map was empty.");
if ($return == Doctrine::FETCH_ARRAY) {
return $array;
} }
// initialize some variables used within the main loop
reset($this->_aliasMap);
$rootMap = current($this->_aliasMap);
$rootAlias = key($this->_aliasMap);
$coll = new Doctrine_Collection2($rootMap['table']);
$prev[$rootAlias] = $coll;
$prevRow = array();
/**
* iterate over the fetched data
* here $data is a two dimensional array
*/
foreach ($array as $data) { foreach ($array as $data) {
/** /**
* remove duplicated data rows and map data into objects * remove duplicated data rows and map data into objects
*/ */
foreach ($data as $key => $row) { foreach ($data as $tableAlias => $row) {
// skip empty rows (not mappable)
if (empty($row)) { if (empty($row)) {
continue; continue;
} }
//$key = array_search($key, $this->shortAliases); $alias = $this->aliasHandler->getComponentAlias($tableAlias);
$map = $this->_aliasMap[$alias];
foreach ($this->tables as $k => $t) { // initialize previous row array if not set
if ( ! strcasecmp($key, $k)) { if ( ! isset($prevRow[$tableAlias])) {
$key = $k; $prevRow[$tableAlias] = array();
}
} }
if ( !isset($this->tables[$key]) ) { // don't map duplicate rows
throw new Doctrine_Exception('No table named ' . $key . ' found.'); if ($prevRow[$tableAlias] !== $row) {
} $identifiable = $this->isIdentifiable($row, $map['table']->getIdentifier());
$ids = $this->tables[$key]->getIdentifier();
$name = $key;
if ($this->isIdentifiable($row, $ids)) { if ($identifiable) {
if ($name !== $root) { // set internal data
$prev = $this->initRelated($prev, $name); $map['table']->setData($row);
} }
// aggregate values have numeric keys
if (isset($row[0])) {
$component = $this->tables[$name]->getComponentName();
// if the collection already has objects, get the last object
// otherwise create a new one where the aggregate values are being mapped
if ($prev[$name]->count() > 0) {
$record = $prev[$name]->getLast();
} else {
$record = new $component();
$prev[$name]->add($record);
}
$path = array_search($name, $this->tableAliases);
$alias = $this->getPathAlias($path);
// map each aggregate value // initialize a new record
foreach ($row as $index => $value) { $record = $map['table']->getRecord();
$agg = false;
if (isset($this->pendingAggregates[$alias][$index])) {
$agg = $this->pendingAggregates[$alias][$index][3];
} elseif (isset($this->subqueryAggregates[$alias][$index])) {
$agg = $this->subqueryAggregates[$alias][$index];
}
$record->mapValue($agg, $value); // map aggregate values (if any)
} if($this->mapAggregateValues($record, $row, $alias)) {
$identifiable = true;
} }
continue;
}
if ( ! isset($previd[$name])) {
$previd[$name] = array();
}
if ($previd[$name] !== $row) {
// set internal data
$this->tables[$name]->setData($row);
// initialize a new record
$record = $this->tables[$name]->getRecord();
// aggregate values have numeric keys if ($alias == $rootAlias) {
if (isset($row[0])) { // add record into root collection
$path = array_search($name, $this->tableAliases);
$alias = $this->getPathAlias($path); if ($identifiable) {
$coll->add($record);
unset($prevRow);
}
} else {
// map each aggregate value $relation = $map['relation'];
foreach ($row as $index => $value) { $parentAlias = $map['parent'];
$agg = false; $parentMap = $this->_aliasMap[$parentAlias];
$parent = $prev[$parentAlias]->getLast();
if (isset($this->pendingAggregates[$alias][$index])) { // check the type of the relation
$agg = $this->pendingAggregates[$alias][$index][3]; if ($relation->isOneToOne()) {
} elseif (isset($this->subqueryAggregates[$alias][$index])) { if ( ! $identifiable) {
$agg = $this->subqueryAggregates[$alias][$index]; continue;
}
$prev[$alias] = $record;
} else {
// one-to-many relation or many-to-many relation
if ( ! $prev[$parentAlias]->getLast()->hasReference($relation->getAlias())) {
// initialize a new collection
$prev[$alias] = new Doctrine_Collection($map['table']);
$prev[$alias]->setReference($parent, $relation);
} else {
// previous entry found from memory
$prev[$alias] = $prev[$parentAlias]->getLast()->get($relation->getAlias());
}
// add record to the current collection
if ($identifiable) {
$prev[$alias]->add($record);
} }
$record->mapValue($agg, $value);
} }
// initialize the relation from parent to the current collection/record
$parent->set($relation->getAlias(), $prev[$alias]);
} }
if ($name == $root) {
// add record into root collection
$coll->add($record);
unset($previd);
} else {
$prev = $this->addRelated($prev, $name, $record);
}
// following statement is needed to ensure that mappings // following statement is needed to ensure that mappings
// are being done properly when the result set doesn't // are being done properly when the result set doesn't
// contain the rows in 'right order' // contain the rows in 'right order'
if ($prev[$name] !== $record) { if ($prev[$alias] !== $record) {
$prev[$name] = $record; $prev[$alias] = $record;
} }
} }
$prevRow[$tableAlias] = $row;
$previd[$name] = $row;
} }
} }
return $coll; return $coll;
} }
/**
* initRelation
*
* @param array $prev
* @param string $name
* @return array
*/
public function initRelated(array $prev, $name)
{
$pointer = $this->joins[$name];
$path = array_search($name, $this->tableAliases);
$tmp = explode('.', $path);
$alias = end($tmp);
if ( ! isset($prev[$pointer]) ) {
return $prev;
}
$fk = $this->tables[$pointer]->getRelation($alias);
if ( ! $fk->isOneToOne()) {
if ($prev[$pointer]->getLast() instanceof Doctrine_Record) {
if ( ! $prev[$pointer]->getLast()->hasReference($alias)) {
$prev[$name] = $this->getCollection($name);
$prev[$pointer]->getLast()->initReference($prev[$name],$fk);
} else {
$prev[$name] = $prev[$pointer]->getLast()->get($alias);
}
}
}
return $prev;
}
/**
* addRelated
*
* @param array $prev
* @param string $name
* @return array
*/
public function addRelated(array $prev, $name, Doctrine_Record $record)
{
$pointer = $this->joins[$name];
$path = array_search($name, $this->tableAliases);
$tmp = explode('.', $path);
$alias = end($tmp);
$fk = $this->tables[$pointer]->getRelation($alias);
if ($fk->isOneToOne()) {
$prev[$pointer]->getLast()->set($fk->getAlias(), $record);
$prev[$name] = $record;
} else {
// one-to-many relation or many-to-many relation
if ( ! $prev[$pointer]->getLast()->hasReference($alias)) {
$prev[$name] = $this->getCollection($name);
$prev[$pointer]->getLast()->initReference($prev[$name], $fk);
} else {
// previous entry found from memory
$prev[$name] = $prev[$pointer]->getLast()->get($alias);
}
$prev[$pointer]->getLast()->addReference($record, $fk);
}
return $prev;
}
/** /**
* isIdentifiable * isIdentifiable
* returns whether or not a given data row is identifiable (it contains * returns whether or not a given data row is identifiable (it contains
* all id fields specified in the second argument) * all primary key fields specified in the second argument)
* *
* @param array $row * @param array $row
* @param mixed $ids * @param mixed $primaryKeys
* @return boolean * @return boolean
*/ */
public function isIdentifiable(array $row, $ids) public function isIdentifiable(array $row, $primaryKeys)
{ {
if (is_array($ids)) { if (is_array($primaryKeys)) {
foreach ($ids as $id) { foreach ($primaryKeys as $id) {
if ($row[$id] == null) if ($row[$id] == null) {
return true; return false;
}
} }
} else { } else {
if ( ! isset($row[$ids])) { if ( ! isset($row[$primaryKeys])) {
return true; return false;
} }
} }
return false; return true;
} }
/** /**
* getType * getType
...@@ -679,12 +546,13 @@ abstract class Doctrine_Hydrate extends Doctrine_Access ...@@ -679,12 +546,13 @@ abstract class Doctrine_Hydrate extends Doctrine_Access
// get the inheritance maps // get the inheritance maps
$array = array(); $array = array();
foreach ($this->tables as $alias => $table) { foreach ($this->_aliasMap as $componentAlias => $data) {
$array[$alias][] = $table->inheritanceMap; $tableAlias = $this->getTableAlias($componentAlias);
$array[$tableAlias][] = $data['table']->inheritanceMap;
} }
// apply inheritance maps // apply inheritance maps
$str = ""; $str = '';
$c = array(); $c = array();
$index = 0; $index = 0;
...@@ -742,32 +610,19 @@ abstract class Doctrine_Hydrate extends Doctrine_Access ...@@ -742,32 +610,19 @@ abstract class Doctrine_Hydrate extends Doctrine_Access
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)); $tableAlias = strtolower(implode('__', $e));
$data[$component][$field] = $value; $data[$tableAlias][$field] = $value;
unset($data[$key]); unset($data[$key]);
}; }
$array[] = $data; $array[] = $data;
}; }
$stmt->closeCursor(); $stmt->closeCursor();
return $array; return $array;
} }
/**
* returns a Doctrine_Table for given name
*
* @param string $name component name
* @return Doctrine_Table|boolean
*/
public function getTable($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
*/ */
......
...@@ -50,8 +50,9 @@ class Doctrine_Hydrate_Alias ...@@ -50,8 +50,9 @@ class Doctrine_Hydrate_Alias
$name = substr($alias, 0, 1); $name = substr($alias, 0, 1);
$i = ((int) substr($alias, 1)); $i = ((int) substr($alias, 1));
if ($i == 0) if ($i == 0) {
$i = 1; $i = 1;
}
$newIndex = ($this->shortAliasIndexes[$name] + $i); $newIndex = ($this->shortAliasIndexes[$name] + $i);
...@@ -65,6 +66,15 @@ class Doctrine_Hydrate_Alias ...@@ -65,6 +66,15 @@ class Doctrine_Hydrate_Alias
{ {
return (isset($this->shortAliases[$tableName])); return (isset($this->shortAliases[$tableName]));
} }
public function getComponentAlias($tableAlias)
{
if ( ! isset($this->shortAliases[$tableAlias])) {
throw new Doctrine_Hydrate_Exception('Unknown table alias ' . $tableAlias);
}
return $this->shortAliases[$tableAlias];
}
public function getShortAliasIndex($alias) public function getShortAliasIndex($alias)
{ {
if ( ! isset($this->shortAliasIndexes[$alias])) { if ( ! isset($this->shortAliasIndexes[$alias])) {
...@@ -72,7 +82,7 @@ class Doctrine_Hydrate_Alias ...@@ -72,7 +82,7 @@ class Doctrine_Hydrate_Alias
} }
return $this->shortAliasIndexes[$alias]; return $this->shortAliasIndexes[$alias];
} }
public function generateShortAlias($tableName) public function generateShortAlias($componentAlias, $tableName)
{ {
$char = strtolower(substr($tableName, 0, 1)); $char = strtolower(substr($tableName, 0, 1));
...@@ -84,18 +94,35 @@ class Doctrine_Hydrate_Alias ...@@ -84,18 +94,35 @@ class Doctrine_Hydrate_Alias
while (isset($this->shortAliases[$alias])) { while (isset($this->shortAliases[$alias])) {
$alias = $char . ++$this->shortAliasIndexes[$alias]; $alias = $char . ++$this->shortAliasIndexes[$alias];
} }
$this->shortAliases[$alias] = $tableName;
$this->shortAliases[$alias] = $componentAlias;
return $alias; return $alias;
} }
/**
public function getShortAlias($tableName) * getShortAlias
* some database such as Oracle need the identifier lengths to be < ~30 chars
* hence Doctrine creates as short identifier aliases as possible
*
* this method is used for the creation of short table aliases, its also
* smart enough to check if an alias already exists for given component (componentAlias)
*
* @param string $componentAlias the alias for the query component to search table alias for
* @param string $tableName the table name from which the table alias is being created
* @return string the generated / fetched short alias
*/
public function getShortAlias($componentAlias, $tableName = null)
{ {
$alias = array_search($tableName, $this->shortAliases); $alias = array_search($componentAlias, $this->shortAliases);
if ($alias !== false) { if ($alias !== false) {
return $alias; return $alias;
} }
return $this->generateShortAlias($tableName);
if ($tableName === null) {
throw new Doctrine_Hydrate_Exception("Couldn't get short alias for " . $componentAlias);
}
return $this->generateShortAlias($componentAlias, $tableName);
} }
} }
...@@ -63,13 +63,14 @@ class Doctrine_Lib ...@@ -63,13 +63,14 @@ class Doctrine_Lib
*/ */
public static function getRecordAsString(Doctrine_Record $record) public static function getRecordAsString(Doctrine_Record $record)
{ {
$r[] = "<pre>"; $r[] = '<pre>';
$r[] = "Component : ".$record->getTable()->getComponentName(); $r[] = 'Component : ' . $record->getTable()->getComponentName();
$r[] = "ID : ".$record->obtainIdentifier(); $r[] = 'ID : ' . $record->obtainIdentifier();
$r[] = "References : ".count($record->getReferences()); $r[] = 'References : ' . count($record->getReferences());
$r[] = "State : ".Doctrine_Lib::getRecordStateAsString($record->getState()); $r[] = 'State : ' . Doctrine_Lib::getRecordStateAsString($record->getState());
$r[] = "OID : ".$record->getOID(); $r[] = 'OID : ' . $record->getOID();
$r[] = "</pre>"; $r[] = 'data : ' . Doctrine::dump($record->getData(), false);
$r[] = '</pre>';
return implode("\n",$r)."<br />"; return implode("\n",$r)."<br />";
} }
/** /**
...@@ -84,12 +85,12 @@ class Doctrine_Lib ...@@ -84,12 +85,12 @@ class Doctrine_Lib
public static function getCollectionAsXml(Doctrine_Collection $collection, SimpleXMLElement $incomming_xml = null){ public static function getCollectionAsXml(Doctrine_Collection $collection, SimpleXMLElement $incomming_xml = null){
$collection_name = Doctrine_Lib::plurelize($collection->getTable()->name); $collectionName = Doctrine_Lib::plurelize($collection->getTable()->name);
if (!isset($incomming_xml)) { if ( ! isset($incomming_xml)) {
$xml = new SimpleXMLElement("<" . $collection_name . "></" . $collection_name . ">"); $xml = new SimpleXMLElement("<" . $collectionName . "></" . $collectionName . ">");
} else { } else {
$xml = $incomming_xml->addChild($collection_name); $xml = $incomming_xml->addChild($collectionName);
} }
foreach ($collection as $key => $record) { foreach ($collection as $key => $record) {
Doctrine_Lib::getRecordAsXml($record, $xml); Doctrine_Lib::getRecordAsXml($record, $xml);
......
...@@ -30,7 +30,8 @@ Doctrine::autoload('Doctrine_Hydrate'); ...@@ -30,7 +30,8 @@ Doctrine::autoload('Doctrine_Hydrate');
* @version $Revision$ * @version $Revision$
* @author Konsta Vesterinen <kvesteri@cc.hut.fi> * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
*/ */
class Doctrine_Query extends Doctrine_Hydrate implements Countable { class Doctrine_Query extends Doctrine_Hydrate2 implements Countable
{
/** /**
* @param array $subqueryAliases the table aliases needed in some LIMIT subqueries * @param array $subqueryAliases the table aliases needed in some LIMIT subqueries
*/ */
...@@ -43,20 +44,17 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { ...@@ -43,20 +44,17 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
* @param boolean $limitSubqueryUsed * @param boolean $limitSubqueryUsed
*/ */
private $limitSubqueryUsed = false; private $limitSubqueryUsed = false;
protected $_status = array('needsSubquery' => true);
/** /**
* @param boolean $isSubquery whether or not this query object is a subquery of another * @param boolean $isSubquery whether or not this query object is a subquery of another
* query object * query object
*/ */
private $isSubquery; private $isSubquery;
private $tableStack;
private $relationStack = array();
private $isDistinct = false; private $isDistinct = false;
protected $components = array();
private $neededTables = array(); private $neededTables = array();
/** /**
* @var array $pendingFields * @var array $pendingFields
...@@ -71,9 +69,15 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { ...@@ -71,9 +69,15 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
* @var boolean $subqueriesProcessed Whether or not pending subqueries have already been processed. * @var boolean $subqueriesProcessed Whether or not pending subqueries have already been processed.
* Consequent calls to getQuery would result badly constructed queries * Consequent calls to getQuery would result badly constructed queries
* without this variable * without this variable
*
* Since subqueries can be correlated, they can only be processed when
* the main query is fully constructed
*/ */
private $subqueriesProcessed = false; private $subqueriesProcessed = false;
/**
* @var array $_parsers an array of parser objects
*/
protected $_parsers = array();
/** /**
...@@ -123,16 +127,6 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { ...@@ -123,16 +127,6 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
return null; return null;
} }
public function getTableStack()
{
return $this->tableStack;
}
public function getRelationStack()
{
return $this->relationStack;
}
public function isDistinct($distinct = null) public function isDistinct($distinct = null)
{ {
if(isset($distinct)) if(isset($distinct))
...@@ -141,18 +135,48 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { ...@@ -141,18 +135,48 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
return $this->isDistinct; return $this->isDistinct;
} }
public function processPendingFields($componentAlias) /**
* getParser
* parser lazy-loader
*
* @throws Doctrine_Query_Exception if unknown parser name given
* @return Doctrine_Query_Part
*/
public function getParser($name)
{ {
$tableAlias = $this->getTableAlias($componentAlias); if ( ! isset($this->_parsers[$name])) {
$class = 'Doctrine_Query_' . ucwords(strtolower($name));
if ( ! isset($this->tables[$tableAlias])) Doctrine::autoload($class);
throw new Doctrine_Query_Exception('Unknown component path '.$componentAlias);
if ( ! class_exists($class)) {
throw new Doctrine_Query_Exception('Unknown parser ' . $name);
}
$table = $this->tables[$tableAlias]; $this->_parsers[$name] = new $class($this);
}
return $this->_parsers[$name];
}
/**
* processPendingFields
* the fields in SELECT clause cannot be parsed until the components
* in FROM clause are parsed, hence this method is called everytime a
* specific component is being parsed.
*
* @throws Doctrine_Query_Exception if unknown component alias has been given
* @param string $componentAlias the alias of the component
* @return void
*/
public function processPendingFields($componentAlias)
{
$tableAlias = $this->getTableAlias($componentAlias);
$table = $this->_aliasMap[$componentAlias]['table'];
if (isset($this->pendingFields[$componentAlias])) { if (isset($this->pendingFields[$componentAlias])) {
$fields = $this->pendingFields[$componentAlias]; $fields = $this->pendingFields[$componentAlias];
// check for wildcards
if (in_array('*', $fields)) { if (in_array('*', $fields)) {
$fields = $table->getColumnNames(); $fields = $table->getColumnNames();
} else { } else {
...@@ -251,9 +275,10 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { ...@@ -251,9 +275,10 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
$e2 = explode(' ', $args[0]); $e2 = explode(' ', $args[0]);
$distinct = ''; $distinct = '';
if(count($e2) > 1) { if (count($e2) > 1) {
if(strtoupper($e2[0]) == 'DISTINCT') if (strtoupper($e2[0]) == 'DISTINCT') {
$distinct = 'DISTINCT '; $distinct = 'DISTINCT ';
}
$args[0] = $e2[1]; $args[0] = $e2[1];
} }
...@@ -266,7 +291,7 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { ...@@ -266,7 +291,7 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
$e3 = explode('.', $alias); $e3 = explode('.', $alias);
if(count($e3) > 1) { if (count($e3) > 1) {
$alias = $e3[1]; $alias = $e3[1];
$owner = $e3[0]; $owner = $e3[0];
} }
...@@ -291,14 +316,12 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { ...@@ -291,14 +316,12 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
list($dql, $alias) = $value; list($dql, $alias) = $value;
$sql = $this->createSubquery()->parseQuery($dql, false)->getQuery(); $sql = $this->createSubquery()->parseQuery($dql, false)->getQuery();
reset($this->tableAliases);
$tableAlias = current($this->tableAliases);
reset($this->compAliases);
$componentAlias = key($this->compAliases); reset($this->_aliasMap);
$componentAlias = key($this->_aliasMap);
$tableAlias = $this->getTableAlias($componentAlias);
$sqlAlias = $tableAlias . '__' . count($this->aggregateMap); $sqlAlias = $tableAlias . '__' . count($this->aggregateMap);
...@@ -313,14 +336,12 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { ...@@ -313,14 +336,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);
$map = reset($this->_aliasMap);
$root = $map['table'];
$table = $this->_aliasMap[$componentAlias]['table'];
if ( ! isset($this->tables[$tableAlias])) {
throw new Doctrine_Query_Exception('Unknown component path ' . $componentAlias);
}
$root = current($this->tables);
$table = $this->tables[$tableAlias];
$aggregates = array(); $aggregates = array();
if(isset($this->pendingAggregates[$componentAlias])) { if(isset($this->pendingAggregates[$componentAlias])) {
...@@ -344,12 +365,12 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { ...@@ -344,12 +365,12 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
if (is_numeric($arg)) { if (is_numeric($arg)) {
$arglist[] = $arg; $arglist[] = $arg;
} elseif (count($e) > 1) { } elseif (count($e) > 1) {
//$tableAlias = $this->getTableAlias($e[0]); $map = $this->_aliasMap[$e[0]];
$table = $this->tables[$tableAlias]; $table = $map['table'];
$e[1] = $table->getColumnName($e[1]); $e[1] = $table->getColumnName($e[1]);
if( ! $table->hasColumn($e[1])) { if ( ! $table->hasColumn($e[1])) {
throw new Doctrine_Query_Exception('Unknown column ' . $e[1]); throw new Doctrine_Query_Exception('Unknown column ' . $e[1]);
} }
...@@ -361,7 +382,7 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { ...@@ -361,7 +382,7 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
$sqlAlias = $tableAlias . '__' . count($this->aggregateMap); $sqlAlias = $tableAlias . '__' . count($this->aggregateMap);
if(substr($name, 0, 1) !== '(') { if (substr($name, 0, 1) !== '(') {
$this->parts['select'][] = $name . '(' . $distinct . implode(', ', $arglist) . ') AS ' . $sqlAlias; $this->parts['select'][] = $name . '(' . $distinct . implode(', ', $arglist) . ') AS ' . $sqlAlias;
} else { } else {
$this->parts['select'][] = $name . ' AS ' . $sqlAlias; $this->parts['select'][] = $name . ' AS ' . $sqlAlias;
...@@ -370,358 +391,73 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { ...@@ -370,358 +391,73 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
$this->neededTables[] = $tableAlias; $this->neededTables[] = $tableAlias;
} }
} }
/**
* count
*
* @param array $params
* @return integer
*/
public function count($params = array())
{
$parts_old = $this->parts;
$this->remove('select');
$join = $this->join;
$where = $this->where;
$having = $this->having;
$table = reset($this->tables);
$q = 'SELECT COUNT(DISTINCT ' . $this->aliasHandler->getShortAlias($table->getTableName())
. '.' . $table->getIdentifier()
. ') FROM ' . $table->getTableName() . ' ' . $this->aliasHandler->getShortAlias($table->getTableName());
foreach($join as $j) {
$q .= ' '.implode(' ',$j);
}
$string = $this->applyInheritance();
if( ! empty($where)) {
$q .= ' WHERE ' . implode(' AND ', $where);
if( ! empty($string))
$q .= ' AND (' . $string . ')';
} else {
if( ! empty($string))
$q .= ' WHERE (' . $string . ')';
}
if( ! empty($having))
$q .= ' HAVING ' . implode(' AND ',$having);
if( ! is_array($params))
$params = array($params);
$params = array_merge($this->params, $params);
$this->parts = $parts_old;
return (int) $this->getConnection()->fetchOne($q, $params);
}
/** /**
* loadFields * getQueryBase
* loads fields for a given table and * returns the base of the generated sql query
* constructs a little bit of sql for every field * On mysql driver special strategy has to be used for DELETE statements
*
* fields of the tables become: [tablename].[fieldname] as [tablename]__[fieldname]
* *
* @access private * @return string the base of the generated sql query
* @param object Doctrine_Table $table a Doctrine_Table object
* @param integer $fetchmode fetchmode the table is using eg. Doctrine::FETCH_LAZY
* @param array $names fields to be loaded (only used in lazy property loading)
* @return void
*/ */
protected function loadFields(Doctrine_Table $table, $fetchmode, array $names, $cpath) public function getQueryBase()
{ {
$name = $table->getComponentName(); switch ($this->type) {
case self::DELETE:
switch($fetchmode): $q = 'DELETE FROM ';
case Doctrine::FETCH_OFFSET:
$this->limit = $table->getAttribute(Doctrine::ATTR_COLL_LIMIT);
case Doctrine::FETCH_IMMEDIATE:
if( ! empty($names)) {
// only auto-add the primary key fields if this query object is not
// a subquery of another query object
$names = array_unique(array_merge($table->getPrimaryKeys(), $names));
} else {
$names = $table->getColumnNames();
}
break; break;
case Doctrine::FETCH_LAZY_OFFSET: case self::UPDATE:
$this->limit = $table->getAttribute(Doctrine::ATTR_COLL_LIMIT); $q = 'UPDATE ';
case Doctrine::FETCH_LAZY:
case Doctrine::FETCH_BATCH:
$names = array_unique(array_merge($table->getPrimaryKeys(), $names));
break; break;
default: case self::SELECT:
throw new Doctrine_Exception("Unknown fetchmode."); $distinct = ($this->isDistinct()) ? 'DISTINCT ' : '';
endswitch;
$component = $table->getComponentName();
$tablename = $this->tableAliases[$cpath];
$this->fetchModes[$tablename] = $fetchmode;
$count = count($this->tables);
foreach($names as $name) {
if($count == 0) {
$this->parts['select'][] = $tablename . '.' . $name;
} else {
$this->parts['select'][] = $tablename . '.' . $name . ' AS ' . $tablename . '__' . $name;
}
}
}
/**
* addFrom
*
* @param strint $from
* @return Doctrine_Query
*/
public function addFrom($from)
{
$class = 'Doctrine_Query_From';
$parser = new $class($this);
$parser->parse($from);
return $this;
}
/**
* leftJoin
*
* @param strint $join
* @return Doctrine_Query
*/
public function leftJoin($join)
{
$class = 'Doctrine_Query_From';
$parser = new $class($this);
$parser->parse('LEFT JOIN ' . $join);
return $this;
}
/**
* innerJoin
*
* @param strint $join
* @return Doctrine_Query
*/
public function innerJoin($join)
{
$class = 'Doctrine_Query_From';
$parser = new $class($this);
$parser->parse('INNER JOIN ' . $join);
return $this;
}
/**
* addOrderBy
*
* @param strint $orderby
* @return Doctrine_Query
*/
public function addOrderBy($orderby)
{
if (empty($orderby)) {
return $this;
}
$class = 'Doctrine_Query_Orderby';
$parser = new $class($this);
$this->parts['orderby'][] = $parser->parse($orderby);
return $this;
}
/**
* addWhere
*
* @param string $where
* @param mixed $params
*/
public function addWhere($where, $params = array())
{
$class = 'Doctrine_Query_Where';
$parser = new $class($this);
$this->parts['where'][] = $parser->parse($where);
if(is_array($params)) { $q = 'SELECT ' . $distinct . implode(', ', $this->parts['select']) . ' FROM ';
$this->params = array_merge($this->params, $params); break;
} else {
$this->params[] = $params;
} }
return $q;
return $this;
}
/**
* addSelect
*
* @param string $select
*/
public function addSelect($select)
{
$this->type = self::SELECT;
$this->parseSelect($select);
return $this;
}
/**
* addHaving
*
* @param string $having
*/
public function addHaving($having)
{
$class = 'Doctrine_Query_Having';
$parser = new $class($this);
$this->parts['having'][] = $parser->parse($having);
return $this;
} }
/** /**
* sets a query part * buildFromPart
* *
* @param string $name * @return string
* @param array $args
* @return void
*/ */
public function __call($name, $args) public function buildFromPart()
{ {
$name = strtolower($name); $q = '';
foreach ($this->parts['from'] as $k => $part) {
$method = 'parse' . ucwords($name); if ($k === 0) {
$q .= $part;
switch($name) { continue;
case 'select': }
$this->type = self::SELECT; // preserve LEFT JOINs only if needed
if ( ! isset($args[0])) { if (substr($part, 0, 9) === 'LEFT JOIN') {
throw new Doctrine_Query_Exception('Empty select part'); $e = explode(' ', $part);
}
$this->parseSelect($args[0]);
break;
case 'delete':
$this->type = self::DELETE;
break;
case 'update':
$this->type = self::UPDATE;
$name = 'from';
case 'from':
$this->parts['from'] = array();
$this->parts['select'] = array();
$this->parts['join'] = array();
$this->joins = array();
$this->tables = array();
$this->fetchModes = array();
$this->tableIndexes = array();
$this->tableAliases = array();
$this->aliasHandler->clear();
$class = "Doctrine_Query_".ucwords($name);
$parser = new $class($this);
$parser->parse($args[0]);
break;
case 'where':
if(isset($args[1])) {
if(is_array($args[1])) {
$this->params = $args[1];
} else {
$this->params = array($args[1]);
}
}
case 'having':
case 'orderby':
case 'groupby':
if (empty($args[0])) {
return $this;
}
$class = 'Doctrine_Query_' . ucwords($name); $aliases = array_merge($this->subqueryAliases,
$parser = new $class($this); array_keys($this->neededTables));
$this->parts[$name] = array($parser->parse($args[0])); if( ! in_array($e[3], $aliases) &&
break; ! in_array($e[2], $aliases) &&
case 'limit':
case 'offset':
if($args[0] == null) {
$args[0] = false;
}
$this->parts[$name] = $args[0]; ! empty($this->pendingFields)) {
break; continue;
default:
$this->parts[$name] = array();
if (method_exists($this, $method)) {
$this->$method($args[0]);
} }
throw new Doctrine_Query_Exception("Unknown overload method"); }
}
return $this;
}
/**
* returns a query part
*
* @param $name query part name
* @return mixed
*/
public function get($name)
{
if( ! isset($this->parts[$name]))
return false;
return $this->parts[$name]; $e = explode(' ON ', $part);
}
/** // we can always be sure that the first join condition exists
* set $e2 = explode(' AND ', $e[1]);
* sets a query SET part
* this method should only be used with UPDATE queries
*
* @param $name name of the field
* @param $value field value
* @return Doctrine_Query
*/
public function set($name, $value)
{
$class = new Doctrine_Query_Set($this);
$this->parts['set'][] = $class->parse($name . ' = ' . $value);
return $this; $part = $e[0] . ' ON ' . array_shift($e2);
}
/**
* @return boolean
*/
public function isLimitSubqueryUsed() {
return $this->limitSubqueryUsed;
}
/**
* getQueryBase
* returns the base of the generated sql query
* On mysql driver special strategy has to be used for DELETE statements
*
* @return string the base of the generated sql query
*/
public function getQueryBase()
{
switch ($this->type) {
case self::DELETE:
/**
no longer needed?
if ($this->conn->getName() == 'Mysql') { if ( ! empty($e2)) {
$q = 'DELETE ' . end($this->tableAliases) . ' FROM '; $parser = new Doctrine_Query_JoinCondition($this);
} else { $part .= ' AND ' . $parser->_parse(implode(' AND ', $e2));
*/ }
$q = 'DELETE FROM ';
// }
break;
case self::UPDATE:
$q = 'UPDATE ';
break;
case self::SELECT:
$distinct = ($this->isDistinct()) ? 'DISTINCT ' : '';
$q = 'SELECT '.$distinct.implode(', ', $this->parts['select']).' FROM '; $q .= ' ' . $part;
break;
} }
return $q; return $q;
} }
...@@ -735,15 +471,17 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { ...@@ -735,15 +471,17 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
*/ */
public function getQuery($params = array()) public function getQuery($params = array())
{ {
if(empty($this->parts["select"]) || empty($this->parts["from"])) if (empty($this->parts['select']) || empty($this->parts['from'])) {
return false; return false;
}
$needsSubQuery = false; $needsSubQuery = false;
$subquery = ''; $subquery = '';
$k = array_keys($this->tables); $map = reset($this->_aliasMap);
$table = $this->tables[$k[0]]; $table = $map['table'];
$rootAlias = key($this->_aliasMap);
if( ! empty($this->parts['limit']) && $this->needsSubquery && $table->getAttribute(Doctrine::ATTR_QUERY_LIMIT) == Doctrine::LIMIT_RECORDS) { if ( ! empty($this->parts['limit']) && $this->needsSubquery && $table->getAttribute(Doctrine::ATTR_QUERY_LIMIT) == Doctrine::LIMIT_RECORDS) {
$needsSubQuery = true; $needsSubQuery = true;
$this->limitSubqueryUsed = true; $this->limitSubqueryUsed = true;
} }
...@@ -754,118 +492,74 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { ...@@ -754,118 +492,74 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
// build the basic query // build the basic query
$str = ''; $str = '';
if($this->isDistinct()) if ($this->isDistinct()) {
$str = 'DISTINCT '; $str = 'DISTINCT ';
$q = $this->getQueryBase();
$q .= $this->parts['from'];
/**
var_dump($this->pendingFields);
var_dump($this->subqueryAliases); */
//var_dump($this->parts['join']);
foreach($this->parts['join'] as $parts) {
foreach($parts as $part) {
// preserve LEFT JOINs only if needed
if(substr($part, 0,9) === 'LEFT JOIN') {
$e = explode(' ', $part);
$aliases = array_merge($this->subqueryAliases,
array_keys($this->neededTables));
if( ! in_array($e[3], $aliases) &&
! in_array($e[2], $aliases) &&
! empty($this->pendingFields)) {
continue;
}
}
$e = explode(' ON ', $part);
// we can always be sure that the first join condition exists
$e2 = explode(' AND ', $e[1]);
$part = $e[0] . ' ON '
. array_shift($e2);
if( ! empty($e2)) {
$parser = new Doctrine_Query_JoinCondition($this);
$part .= ' AND ' . $parser->parse(implode(' AND ', $e2));
}
$q .= ' ' . $part;
}
}
/**
if( ! empty($this->parts['join'])) {
foreach($this->parts['join'] as $part) {
$q .= ' '.implode(' ', $part);
}
} }
*/
if( ! empty($this->parts['set'])) { $q = $this->getQueryBase();
$q .= $this->buildFromPart();
if ( ! empty($this->parts['set'])) {
$q .= ' SET ' . implode(', ', $this->parts['set']); $q .= ' SET ' . implode(', ', $this->parts['set']);
} }
$string = $this->applyInheritance(); $string = $this->applyInheritance();
if( ! empty($string)) if ( ! empty($string)) {
$this->parts['where'][] = '('.$string.')'; $this->parts['where'][] = '(' . $string . ')';
}
$modifyLimit = true; $modifyLimit = true;
if( ! empty($this->parts["limit"]) || ! empty($this->parts["offset"])) { if ( ! empty($this->parts["limit"]) || ! empty($this->parts["offset"])) {
if($needsSubQuery) { if ($needsSubQuery) {
$subquery = $this->getLimitSubquery(); $subquery = $this->getLimitSubquery();
switch(strtolower($this->conn->getName())) { switch (strtolower($this->conn->getName())) {
case 'mysql': case 'mysql':
// mysql doesn't support LIMIT in subqueries // mysql doesn't support LIMIT in subqueries
$list = $this->conn->execute($subquery, $params)->fetchAll(PDO::FETCH_COLUMN); $list = $this->conn->execute($subquery, $params)->fetchAll(PDO::FETCH_COLUMN);
$subquery = implode(', ', $list); $subquery = implode(', ', $list);
break; break;
case 'pgsql': case 'pgsql':
// pgsql needs special nested LIMIT subquery // pgsql needs special nested LIMIT subquery
$subquery = 'SELECT doctrine_subquery_alias.' . $table->getIdentifier(). ' FROM (' . $subquery . ') AS doctrine_subquery_alias'; $subquery = 'SELECT doctrine_subquery_alias.' . $table->getIdentifier(). ' FROM (' . $subquery . ') AS doctrine_subquery_alias';
break; break;
} }
$field = $this->aliasHandler->getShortAlias($table->getTableName()) . '.' . $table->getIdentifier(); $field = $this->aliasHandler->getShortAlias($rootAlias) . '.' . $table->getIdentifier();
// only append the subquery if it actually contains something // only append the subquery if it actually contains something
if($subquery !== '') if ($subquery !== '') {
array_unshift($this->parts['where'], $field. ' IN (' . $subquery . ')'); array_unshift($this->parts['where'], $field. ' IN (' . $subquery . ')');
}
$modifyLimit = false; $modifyLimit = false;
} }
} }
$q .= ( ! empty($this->parts['where']))? ' WHERE ' . implode(' AND ', $this->parts['where']):''; $q .= ( ! empty($this->parts['where']))? ' WHERE ' . implode(' AND ', $this->parts['where']) : '';
$q .= ( ! empty($this->parts['groupby']))? ' GROUP BY ' . implode(', ', $this->parts['groupby']):''; $q .= ( ! empty($this->parts['groupby']))? ' GROUP BY ' . implode(', ', $this->parts['groupby']) : '';
$q .= ( ! empty($this->parts['having']))? ' HAVING ' . implode(' AND ', $this->parts['having']):''; $q .= ( ! empty($this->parts['having']))? ' HAVING ' . implode(' AND ', $this->parts['having']): '';
$q .= ( ! empty($this->parts['orderby']))? ' ORDER BY ' . implode(', ', $this->parts['orderby']):''; $q .= ( ! empty($this->parts['orderby']))? ' ORDER BY ' . implode(', ', $this->parts['orderby']) : '';
if($modifyLimit) if ($modifyLimit) {
$q = $this->conn->modifyLimitQuery($q, $this->parts['limit'], $this->parts['offset']); $q = $this->conn->modifyLimitQuery($q, $this->parts['limit'], $this->parts['offset']);
}
// return to the previous state // return to the previous state
if( ! empty($string)) if ( ! empty($string)) {
array_pop($this->parts['where']); array_pop($this->parts['where']);
if($needsSubQuery) }
if ($needsSubQuery) {
array_shift($this->parts['where']); array_shift($this->parts['where']);
}
return $q; return $q;
} }
/** /**
* getLimitSubquery
* this is method is used by the record limit algorithm * this is method is used by the record limit algorithm
* *
* when fetching one-to-many, many-to-many associated data with LIMIT clause * when fetching one-to-many, many-to-many associated data with LIMIT clause
...@@ -876,11 +570,12 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { ...@@ -876,11 +570,12 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
*/ */
public function getLimitSubquery() public function getLimitSubquery()
{ {
$k = array_keys($this->tables); $map = reset($this->_aliasMap);
$table = $this->tables[$k[0]]; $table = $map['table'];
$componentAlias = key($this->_aliasMap);
// get short alias // get short alias
$alias = $this->aliasHandler->getShortAlias($table->getTableName()); $alias = $this->aliasHandler->getShortAlias($componentAlias);
$primaryKey = $alias . '.' . $table->getIdentifier(); $primaryKey = $alias . '.' . $table->getIdentifier();
// initialize the base of the subquery // initialize the base of the subquery
...@@ -899,23 +594,20 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { ...@@ -899,23 +594,20 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
} }
} }
$subquery .= ' FROM ' . $this->conn->quoteIdentifier($table->getTableName()) . ' ' . $alias; $subquery .= ' FROM';
foreach ($this->parts['join'] as $parts) { foreach ($this->parts['from'] as $part) {
foreach ($parts as $part) { // preserve LEFT JOINs only if needed
// preserve LEFT JOINs only if needed if (substr($part,0,9) === 'LEFT JOIN') {
if (substr($part,0,9) === 'LEFT JOIN') { $e = explode(' ', $part);
$e = explode(' ', $part);
if ( ! in_array($e[3], $this->subqueryAliases) &&
! in_array($e[2], $this->subqueryAliases)) {
continue;
}
if ( ! in_array($e[3], $this->subqueryAliases) &&
! in_array($e[2], $this->subqueryAliases)) {
continue;
} }
$subquery .= ' '.$part;
} }
$subquery .= ' ' . $part;
} }
// all conditions must be preserved in subquery // all conditions must be preserved in subquery
...@@ -927,7 +619,7 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { ...@@ -927,7 +619,7 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
// add driver specific limit clause // add driver specific limit clause
$subquery = $this->conn->modifyLimitQuery($subquery, $this->parts['limit'], $this->parts['offset']); $subquery = $this->conn->modifyLimitQuery($subquery, $this->parts['limit'], $this->parts['offset']);
$parts = self::quoteExplode($subquery, ' ', "'", "'"); $parts = Doctrine_Tokenizer::quoteExplode($subquery, ' ', "'", "'");
foreach($parts as $k => $part) { foreach($parts as $k => $part) {
if(strpos($part, "'") !== false) { if(strpos($part, "'") !== false) {
...@@ -953,31 +645,7 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { ...@@ -953,31 +645,7 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
return $subquery; return $subquery;
} }
/** /**
* query the database with DQL (Doctrine Query Language) * tokenizeQuery
*
* @param string $query DQL query
* @param array $params parameters
*/
public function query($query,$params = array())
{
$this->parseQuery($query);
if($this->aggregate) {
$keys = array_keys($this->tables);
$query = $this->getQuery();
$stmt = $this->tables[$keys[0]]->getConnection()->select($query, $this->parts["limit"], $this->parts["offset"]);
$data = $stmt->fetch(PDO::FETCH_ASSOC);
if(count($data) == 1) {
return current($data);
} else {
return $data;
}
} else {
return $this->execute($params);
}
}
/**
* splitQuery
* splits the given dql query into an array where keys * splits the given dql query into an array where keys
* represent different query part names and values are * represent different query part names and values are
* arrays splitted using sqlExplode method * arrays splitted using sqlExplode method
...@@ -995,9 +663,9 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { ...@@ -995,9 +663,9 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
* @throws Doctrine_Query_Exception if some generic parsing error occurs * @throws Doctrine_Query_Exception if some generic parsing error occurs
* @return array an array containing the query string parts * @return array an array containing the query string parts
*/ */
public function splitQuery($query) public function tokenizeQuery($query)
{ {
$e = self::sqlExplode($query, ' '); $e = Doctrine_Tokenizer::sqlExplode($query, ' ');
foreach($e as $k=>$part) { foreach($e as $k=>$part) {
$part = trim($part); $part = trim($part);
...@@ -1047,60 +715,61 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { ...@@ -1047,60 +715,61 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
*/ */
public function parseQuery($query, $clear = true) public function parseQuery($query, $clear = true)
{ {
if($clear) if ($clear) {
$this->clear(); $this->clear();
}
$query = trim($query); $query = trim($query);
$query = str_replace("\n", ' ', $query); $query = str_replace("\n", ' ', $query);
$query = str_replace("\r", ' ', $query); $query = str_replace("\r", ' ', $query);
$parts = $this->splitQuery($query); $parts = $this->tokenizeQuery($query);
foreach($parts as $k => $part) { foreach($parts as $k => $part) {
$part = implode(' ', $part); $part = implode(' ', $part);
switch(strtoupper($k)) { switch(strtolower($k)) {
case 'CREATE': case 'create':
$this->type = self::CREATE; $this->type = self::CREATE;
break; break;
case 'INSERT': case 'insert':
$this->type = self::INSERT; $this->type = self::INSERT;
break; break;
case 'DELETE': case 'delete':
$this->type = self::DELETE; $this->type = self::DELETE;
break; break;
case 'SELECT': case 'select':
$this->type = self::SELECT; $this->type = self::SELECT;
$this->parseSelect($part); $this->parseSelect($part);
break; break;
case 'UPDATE': case 'update':
$this->type = self::UPDATE; $this->type = self::UPDATE;
$k = 'FROM'; $k = 'FROM';
case 'FROM': case 'from':
$class = 'Doctrine_Query_' . ucwords(strtolower($k)); $class = 'Doctrine_Query_' . ucwords(strtolower($k));
$parser = new $class($this); $parser = new $class($this);
$parser->parse($part); $parser->parse($part);
break; break;
case 'SET': case 'set':
$class = 'Doctrine_Query_' . ucwords(strtolower($k)); $class = 'Doctrine_Query_' . ucwords(strtolower($k));
$parser = new $class($this); $parser = new $class($this);
$this->parts['set'][] = $parser->parse($part); $parser->parse($part);
break; break;
case 'GROUP': case 'group':
case 'ORDER': case 'order':
$k .= 'by'; $k .= 'by';
case 'WHERE': case 'where':
case 'HAVING': case 'having':
$class = 'Doctrine_Query_' . ucwords(strtolower($k)); $class = 'Doctrine_Query_' . ucwords(strtolower($k));
$parser = new $class($this); $parser = new $class($this);
$name = strtolower($k); $name = strtolower($k);
$this->parts[$name][] = $parser->parse($part); $parser->parse($part);
break; break;
case 'LIMIT': case 'limit':
$this->parts['limit'] = trim($part); $this->parts['limit'] = trim($part);
break; break;
case 'OFFSET': case 'offset':
$this->parts['offset'] = trim($part); $this->parts['offset'] = trim($part);
break; break;
} }
...@@ -1108,573 +777,518 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { ...@@ -1108,573 +777,518 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
return $this; return $this;
} }
/** public function load($path, $loadFields = true)
* DQL ORDER BY PARSER
* parses the order by part of the query string
*
* @param string $str
* @return void
*/
final public function parseOrderBy($str)
{
$parser = new Doctrine_Query_Part_Orderby($this);
return $parser->parse($str);
}
/**
* returns Doctrine::FETCH_* constant
*
* @param string $mode
* @return integer
*/
final public function parseFetchMode($mode)
{
switch(strtolower($mode)):
case "i":
case "immediate":
$fetchmode = Doctrine::FETCH_IMMEDIATE;
break;
case "b":
case "batch":
$fetchmode = Doctrine::FETCH_BATCH;
break;
case "l":
case "lazy":
$fetchmode = Doctrine::FETCH_LAZY;
break;
case "o":
case "offset":
$fetchmode = Doctrine::FETCH_OFFSET;
break;
case "lo":
case "lazyoffset":
$fetchmode = Doctrine::FETCH_LAZYOFFSET;
default:
throw new Doctrine_Query_Exception("Unknown fetchmode '$mode'. The availible fetchmodes are 'i', 'b' and 'l'.");
endswitch;
return $fetchmode;
}
/**
* trims brackets
*
* @param string $str
* @param string $e1 the first bracket, usually '('
* @param string $e2 the second bracket, usually ')'
*/
public static function bracketTrim($str,$e1 = '(',$e2 = ')')
{
if(substr($str,0,1) == $e1 && substr($str,-1) == $e2)
return substr($str,1,-1);
else
return $str;
}
/**
* bracketExplode
*
* example:
*
* parameters:
* $str = (age < 20 AND age > 18) AND email LIKE 'John@example.com'
* $d = ' AND '
* $e1 = '('
* $e2 = ')'
*
* would return an array:
* array("(age < 20 AND age > 18)",
* "email LIKE 'John@example.com'")
*
* @param string $str
* @param string $d the delimeter which explodes the string
* @param string $e1 the first bracket, usually '('
* @param string $e2 the second bracket, usually ')'
*
*/
public static function bracketExplode($str, $d = ' ', $e1 = '(', $e2 = ')')
{
if(is_array($d)) {
$a = preg_split('/('.implode('|', $d).')/', $str);
$d = stripslashes($d[0]);
} else
$a = explode("$d",$str);
$i = 0;
$term = array();
foreach($a as $key=>$val) {
if (empty($term[$i])) {
$term[$i] = trim($val);
$s1 = substr_count($term[$i], "$e1");
$s2 = substr_count($term[$i], "$e2");
if($s1 == $s2) $i++;
} else {
$term[$i] .= "$d".trim($val);
$c1 = substr_count($term[$i], "$e1");
$c2 = substr_count($term[$i], "$e2");
if($c1 == $c2) $i++;
}
}
return $term;
}
/**
* quoteExplode
*
* example:
*
* parameters:
* $str = email LIKE 'John@example.com'
* $d = ' AND '
*
* would return an array:
* array("email", "LIKE", "'John@example.com'")
*
* @param string $str
* @param string $d the delimeter which explodes the string
*/
public static function quoteExplode($str, $d = ' ')
{
if(is_array($d)) {
$a = preg_split('/('.implode('|', $d).')/', $str);
$d = stripslashes($d[0]);
} else
$a = explode("$d",$str);
$i = 0;
$term = array();
foreach($a as $key => $val) {
if (empty($term[$i])) {
$term[$i] = trim($val);
if( ! (substr_count($term[$i], "'") & 1))
$i++;
} else {
$term[$i] .= "$d".trim($val);
if( ! (substr_count($term[$i], "'") & 1))
$i++;
}
}
return $term;
}
/**
* sqlExplode
*
* explodes a string into array using custom brackets and
* quote delimeters
*
*
* example:
*
* parameters:
* $str = "(age < 20 AND age > 18) AND name LIKE 'John Doe'"
* $d = ' '
* $e1 = '('
* $e2 = ')'
*
* would return an array:
* array('(age < 20 AND age > 18)',
* 'name',
* 'LIKE',
* 'John Doe')
*
* @param string $str
* @param string $d the delimeter which explodes the string
* @param string $e1 the first bracket, usually '('
* @param string $e2 the second bracket, usually ')'
*
* @return array
*/
public static function sqlExplode($str, $d = ' ', $e1 = '(', $e2 = ')')
{
if ($d == ' ') {
$d = array(' ', '\s');
}
if(is_array($d)) {
if (in_array(' ', $d)) {
$d[] = '\s';
}
$str = preg_split('/('.implode('|', $d).')/', $str);
$d = stripslashes($d[0]);
} else {
$str = explode("$d",$str);
}
$i = 0;
$term = array();
foreach($str as $key => $val) {
if (empty($term[$i])) {
$term[$i] = trim($val);
$s1 = substr_count($term[$i],"$e1");
$s2 = substr_count($term[$i],"$e2");
if (substr($term[$i],0,1) == "(") {
if($s1 == $s2) {
$i++;
}
} else {
if ( ! (substr_count($term[$i], "'") & 1) &&
! (substr_count($term[$i], "\"") & 1) &&
! (substr_count($term[$i], "�") & 1)
) { $i++; }
}
} else {
$term[$i] .= "$d".trim($val);
$c1 = substr_count($term[$i],"$e1");
$c2 = substr_count($term[$i],"$e2");
if(substr($term[$i],0,1) == "(") {
if($c1 == $c2) {
$i++;
}
} else {
if ( ! (substr_count($term[$i], "'") & 1) &&
! (substr_count($term[$i], "\"") & 1) &&
! (substr_count($term[$i], "�") & 1)
) { $i++; }
}
}
}
return $term;
}
/**
* generateAlias
*
* @param string $tableName
* @return string
*/
public function generateAlias($tableName)
{ {
if(isset($this->tableIndexes[$tableName])) {
return $tableName.++$this->tableIndexes[$tableName];
} else {
$this->tableIndexes[$tableName] = 1;
return $tableName;
}
}
/**
* loads a component
*
* @param string $path the path of the loadable component
* @param integer $fetchmode optional fetchmode, if not set the components default fetchmode will be used
* @throws Doctrine_Query_Exception
* @return Doctrine_Table
*/
final public function load($path, $loadFields = true)
{
// parse custom join conditions // parse custom join conditions
$e = explode(' ON ', $path); $e = explode(' ON ', $path);
$joinCondition = ''; $joinCondition = '';
if(count($e) > 1) {
if (count($e) > 1) {
$joinCondition = ' AND ' . $e[1]; $joinCondition = ' AND ' . $e[1];
$path = $e[0]; $path = $e[0];
} }
$tmp = explode(' ',$path); $tmp = explode(' ', $path);
$componentAlias = (count($tmp) > 1) ? end($tmp) : false; $originalAlias = (count($tmp) > 1) ? end($tmp) : null;
$e = preg_split("/[.:]/", $tmp[0], -1); $e = preg_split("/[.:]/", $tmp[0], -1);
$fullPath = $tmp[0];
$prevPath = '';
$fullLength = strlen($fullPath);
if(isset($this->compAliases[$e[0]])) { if (isset($this->_aliasMap[$e[0]])) {
$end = substr($tmp[0], strlen($e[0])); $table = $this->_aliasMap[$e[0]]['table'];
$path = $this->compAliases[$e[0]] . $end;
$e = preg_split("/[.:]/", $path, -1);
} else {
$path = $tmp[0];
}
$index = 0;
$currPath = '';
$this->tableStack = array();
foreach($e as $key => $fullname) {
try {
$e2 = preg_split("/[-(]/",$fullname);
$name = $e2[0];
$currPath .= '.' . $name;
if($key == 0) {
$currPath = substr($currPath,1);
$this->conn = Doctrine_Manager::getInstance()
->getConnectionForComponent($name);
$table = $this->conn->getTable($name);
$prevPath = $parent = array_shift($e);
}
$tname = $this->aliasHandler->getShortAlias($table->getTableName()); foreach ($e as $key => $name) {
// get length of the previous path
$length = strlen($prevPath);
if( ! isset($this->tableAliases[$currPath])) { // build the current component path
$this->tableIndexes[$tname] = 1; $prevPath = ($prevPath) ? $prevPath . '.' . $name : $name;
}
$this->parts['from'] = $this->conn->quoteIdentifier($table->getTableName()); $delimeter = substr($fullPath, $length, 1);
if ($this->type === self::SELECT) {
$this->parts['from'] .= ' ' . $tname;
}
$this->tableAliases[$currPath] = $tname; // if an alias is not given use the current path as an alias identifier
if (strlen($prevPath) === $fullLength && isset($originalAlias)) {
$componentAlias = $originalAlias;
} else {
$componentAlias = $prevPath;
}
$tableName = $tname; if ( ! isset($table)) {
} else { // process the root of the path
$index += strlen($e[($key - 1)]) + 1; $table = $this->loadRoot($name, $componentAlias);
// the mark here is either '.' or ':' } else {
$mark = substr($path, ($index - 1), 1); $join = ($delimeter == ':') ? 'INNER JOIN ' : 'LEFT JOIN ';
if(isset($this->tableAliases[$prevPath])) { $relation = $table->getRelation($name);
$tname = $this->tableAliases[$prevPath];
} else {
$tname = $this->aliasHandler->getShortAlias($table->getTableName());
}
$fk = $table->getRelation($name); $this->_aliasMap[$componentAlias] = array('table' => $relation->getTable(),
$name = $fk->getTable()->getComponentName(); 'parent' => $parent,
$original = $fk->getTable()->getTableName(); 'relation' => $relation);
if ( ! $relation->isOneToOne()) {
$this->needsSubquery = true;
}
$localAlias = $this->getShortAlias($parent, $table->getTableName());
$foreignAlias = $this->getShortAlias($componentAlias, $relation->getTable()->getTableName());
$localSql = $this->conn->quoteIdentifier($table->getTableName()) . ' ' . $localAlias;
$foreignSql = $this->conn->quoteIdentifier($relation->getTable()->getTableName()) . ' ' . $foreignAlias;
$map = $relation->getTable()->inheritanceMap;
if ( ! $loadFields || ! empty($map) || $joinCondition) {
$this->subqueryAliases[] = $foreignAlias;
}
if (isset($this->tableAliases[$currPath])) { if ($relation instanceof Doctrine_Relation_Association) {
$tname2 = $this->tableAliases[$currPath]; $asf = $relation->getAssociationFactory();
} else {
$tname2 = $this->aliasHandler->generateShortAlias($original); $assocTableName = $asf->getTableName();
if( ! $loadFields || ! empty($map) || $joinCondition) {
$this->subqueryAliases[] = $assocTableName;
} }
$aliasString = $this->conn->quoteIdentifier($original) . ' ' . $tname2; $assocPath = $prevPath . '.' . $asf->getComponentName();
$assocAlias = $this->getShortAlias($assocPath, $asf->getTableName());
switch ($mark) { $queryPart = $join . $assocTableName . ' ' . $assocAlias . ' ON ' . $localAlias . '.'
case ':': . $table->getIdentifier() . ' = '
$join = 'INNER JOIN '; . $assocAlias . '.' . $relation->getLocal();
break;
case '.':
$join = 'LEFT JOIN ';
break;
default:
throw new Doctrine_Query_Exception("Unknown operator '$mark'");
}
if( ! $fk->isOneToOne()) { if ($relation instanceof Doctrine_Relation_Association_Self) {
$this->needsSubquery = true; $queryPart .= ' OR ' . $localAlias . '.' . $table->getIdentifier() . ' = '
. $assocAlias . '.' . $relation->getForeign();
} }
$this->parts['from'][] = $queryPart;
$map = $fk->getTable()->inheritanceMap; $queryPart = $join . $foreignSql . ' ON ' . $foreignAlias . '.'
. $relation->getTable()->getIdentifier() . ' = '
. $assocAlias . '.' . $relation->getForeign()
. $joinCondition;
if( ! $loadFields || ! empty($map) || $joinCondition) { if ($relation instanceof Doctrine_Relation_Association_Self) {
$this->subqueryAliases[] = $tname2; $queryPart .= ' OR ' . $foreignAlias . '.' . $table->getIdentifier() . ' = '
} . $assocAlias . '.' . $relation->getLocal();
if ($fk instanceof Doctrine_Relation_Association) {
$asf = $fk->getAssociationFactory();
$assocTableName = $asf->getTableName();
if( ! $loadFields || ! empty($map) || $joinCondition) {
$this->subqueryAliases[] = $assocTableName;
}
$assocPath = $prevPath . '.' . $asf->getComponentName();
if (isset($this->tableAliases[$assocPath])) {
$assocAlias = $this->tableAliases[$assocPath];
} else {
$assocAlias = $this->aliasHandler->generateShortAlias($assocTableName);
}
$this->parts['join'][$tname][$assocTableName] = $join . $assocTableName . ' ' . $assocAlias . ' ON ' . $tname . '.'
. $table->getIdentifier() . ' = '
. $assocAlias . '.' . $fk->getLocal();
if ($fk instanceof Doctrine_Relation_Association_Self) {
$this->parts['join'][$tname][$assocTableName] .= ' OR ' . $tname . '.' . $table->getIdentifier() . ' = '
. $assocAlias . '.' . $fk->getForeign();
}
$this->parts['join'][$tname][$tname2] = $join . $aliasString . ' ON ' . $tname2 . '.'
. $fk->getTable()->getIdentifier() . ' = '
. $assocAlias . '.' . $fk->getForeign()
. $joinCondition;
if ($fk instanceof Doctrine_Relation_Association_Self) {
$this->parts['join'][$tname][$tname2] .= ' OR ' . $tname2 . '.' . $table->getIdentifier() . ' = '
. $assocAlias . '.' . $fk->getLocal();
}
} else {
$this->parts['join'][$tname][$tname2] = $join . $aliasString
. ' ON ' . $tname . '.'
. $fk->getLocal() . ' = ' . $tname2 . '.' . $fk->getForeign()
. $joinCondition;
} }
} else {
$this->joins[$tname2] = $prevTable; $queryPart = $join . $foreignSql
. ' ON ' . $localAlias . '.'
. $relation->getLocal() . ' = ' . $foreignAlias . '.' . $relation->getForeign()
$table = $fk->getTable(); . $joinCondition;
$this->tableAliases[$currPath] = $tname2;
$tableName = $tname2;
$this->relationStack[] = $fk;
} }
$this->parts['from'][] = $queryPart;
}
if ($loadFields) {
$restoreState = false;
// load fields if necessary
if ($loadFields && empty($this->pendingFields)
&& empty($this->pendingAggregates)
&& empty($this->pendingSubqueries)) {
$this->components[$currPath] = $table; $this->pendingFields[$componentAlias] = array('*');
$this->tableStack[] = $table;
if( ! isset($this->tables[$tableName])) {
$this->tables[$tableName] = $table;
if ($loadFields) {
$skip = false;
if ( ! empty($this->pendingFields) ||
! empty($this->pendingAggregates)) {
$skip = true;
}
if ($componentAlias) {
$this->compAliases[$componentAlias] = $currPath;
if(isset($this->pendingFields[$componentAlias])) { $restoreState = true;
$this->processPendingFields($componentAlias); }
$skip = true;
}
if(isset($this->pendingAggregates[$componentAlias]) ||
(current($this->tables) === $table && isset($this->pendingAggregates[0]))
) {
$this->processPendingAggregates($componentAlias);
$skip = true;
}
}
if ( ! $skip) { if(isset($this->pendingFields[$componentAlias])) {
$this->parseFields($fullname, $tableName, $e2, $currPath); $this->processPendingFields($componentAlias);
}
}
} }
if(isset($this->pendingAggregates[$componentAlias]) || isset($this->pendingAggregates[0])) {
$this->processPendingAggregates($componentAlias);
}
$prevPath = $currPath; if ($restoreState) {
$prevTable = $tableName; $this->pendingFields = array();
} catch(Exception $e) { $this->pendingAggregates = array();
throw new Doctrine_Query_Exception($e->__toString()); }
} }
$parent = $prevPath;
} }
return end($this->_aliasMap);
}
/**
* loadRoot
*
* @param string $name
* @param string $componentAlias
*/
public function loadRoot($name, $componentAlias)
{
// get the connection for the component
$this->conn = Doctrine_Manager::getInstance()
->getConnectionForComponent($name);
$table = $this->conn->getTable($name);
$tableName = $table->getTableName();
if($componentAlias !== false) { // get the short alias for this table
$this->compAliases[$componentAlias] = $currPath; $tableAlias = $this->aliasHandler->getShortAlias($componentAlias, $tableName);
// quote table name
$queryPart = $this->conn->quoteIdentifier($tableName);
if ($this->type === self::SELECT) {
$queryPart .= ' ' . $tableAlias;
} }
$this->parts['from'][] = $queryPart;
$this->tableAliases[$tableAlias] = $componentAlias;
$this->_aliasMap[$componentAlias] = array('table' => $table);
return $table; return $table;
} }
/** /**
* parseFields * count
* fetches the count of the query
*
* This method executes the main query without all the
* selected fields, ORDER BY part, LIMIT part and OFFSET part.
* *
* @param string $fullName * Example:
* @param string $tableName * Main query:
* @param array $exploded * SELECT u.*, p.phonenumber FROM User u
* @param string $currPath * LEFT JOIN u.Phonenumber p
* @return void * WHERE p.phonenumber = '123 123' LIMIT 10
*
* The query this method executes:
* SELECT COUNT(DISTINCT u.id) FROM User u
* LEFT JOIN u.Phonenumber p
* WHERE p.phonenumber = '123 123'
*
* @param array $params an array of prepared statement parameters
* @return integer the count of this query
*/ */
final public function parseFields($fullName, $tableName, array $exploded, $currPath) public function count($params = array())
{ {
$table = $this->tables[$tableName]; // initialize temporary variables
$where = $this->parts['where'];
$having = $this->parts['having'];
$map = reset($this->_aliasMap);
$componentAlias = key($this->_aliasMap);
$table = $map['table'];
// build the query base
$q = 'SELECT COUNT(DISTINCT ' . $this->aliasHandler->getShortAlias($table->getTableName())
. '.' . $table->getIdentifier()
. ') FROM ' . $this->buildFromPart();
$fields = array(); // append column aggregation inheritance (if needed)
$string = $this->applyInheritance();
if(strpos($fullName, '-') === false) { if ( ! empty($string)) {
$fetchmode = $table->getAttribute(Doctrine::ATTR_FETCHMODE); $where[] = $string;
}
// append conditions
$q .= ( ! empty($where)) ? ' WHERE ' . implode(' AND ', $where) : '';
$q .= ( ! empty($having)) ? ' HAVING ' . implode(' AND ', $having): '';
if(isset($exploded[1])) { if ( ! is_array($params)) {
if(count($exploded) > 2) { $params = array($params);
$fields = $this->parseAggregateValues($fullName, $tableName, $exploded, $currPath); }
} elseif(count($exploded) == 2) { // append parameters
$fields = explode(',',substr($exploded[1],0,-1)); $params = array_merge($this->params, $params);
}
}
} else {
if(isset($exploded[1])) {
$fetchmode = $this->parseFetchMode($exploded[1]);
} else
$fetchmode = $table->getAttribute(Doctrine::ATTR_FETCHMODE);
if(isset($exploded[2])) { return (int) $this->getConnection()->fetchOne($q, $params);
if(substr_count($exploded[2], ')') > 1) { }
/**
* isLimitSubqueryUsed
* whether or not limit subquery algorithm is used
*
* @return boolean
*/
public function isLimitSubqueryUsed() {
return $this->limitSubqueryUsed;
}
} else { /**
$fields = explode(',', substr($exploded[2],0,-1)); * query
} * query the database with DQL (Doctrine Query Language)
} *
* @param string $query DQL query
* @param array $params prepared statement parameters
* @see Doctrine::FETCH_* constants
* @return mixed
*/
public function query($query, $params = array())
{
$this->parseQuery($query);
return $this->execute($params);
}
/**
* getShortAlias
* some database such as Oracle need the identifier lengths to be < ~30 chars
* hence Doctrine creates as short identifier aliases as possible
*
* this method is used for the creation of short table aliases, its also
* smart enough to check if an alias already exists for given component (componentAlias)
*
* @param string $componentAlias the alias for the query component to search table alias for
* @param string $tableName the table name from which the table alias is being created
* @return string the generated / fetched short alias
*/
public function getShortAlias($componentAlias, $tableName)
{
return $this->aliasHandler->getShortAlias($componentAlias, $tableName);
}
/**
* addSelect
* adds fields to the SELECT part of the query
*
* @param string $select DQL SELECT part
* @return Doctrine_Query
*/
public function addSelect($select)
{
return $this->getParser('select')->parse($select, true);
}
/**
* addWhere
* adds conditions to the WHERE part of the query
*
* @param string $where DQL WHERE part
* @param mixed $params an array of parameters or a simple scalar
* @return Doctrine_Query
*/
public function addWhere($where, $params = array())
{
if (is_array($params)) {
$this->params = array_merge($this->params, $params);
} else {
$this->params[] = $params;
} }
if( ! $this->aggregate) return $this->getParser('where')->parse($where, true);
$this->loadFields($table, $fetchmode, $fields, $currPath);
} }
/** /**
* parseAggregateFunction * addGroupBy
* adds fields to the GROUP BY part of the query
* *
* @param string $func * @param string $groupby DQL GROUP BY part
* @param string $reference * @return Doctrine_Query
* @return string
*/ */
public function parseAggregateFunction($func,$reference) public function addGroupBy($groupby)
{ {
$pos = strpos($func, '('); return $this->getParser('groupby')->parse($groupby, true);
}
if($pos !== false) { /**
$funcs = array(); * addHaving
* adds conditions to the HAVING part of the query
$name = substr($func, 0, $pos); *
$func = substr($func, ($pos + 1), -1); * @param string $having DQL HAVING part
$params = Doctrine_Query::bracketExplode($func, ',', '(', ')'); * @param mixed $params an array of parameters or a simple scalar
* @return Doctrine_Query
foreach($params as $k => $param) { */
$params[$k] = $this->parseAggregateFunction($param,$reference); public function addHaving($having, $params = array())
} {
if (is_array($params)) {
$funcs = $name . '(' . implode(', ', $params). ')'; $this->params = array_merge($this->params, $params);
return $funcs;
} else { } else {
if( ! is_numeric($func)) { $this->params[] = $params;
}
return $this->getParser('having')->parse($having, true);
}
/**
* addOrderBy
* adds fields to the ORDER BY part of the query
*
* @param string $orderby DQL ORDER BY part
* @return Doctrine_Query
*/
public function addOrderBy($orderby)
{
return $this->getParser('orderby')->parse($orderby, true);
}
/**
* select
* sets the SELECT part of the query
*
* @param string $select DQL SELECT part
* @return Doctrine_Query
*/
public function select($select)
{
return $this->getParser('select')->parse($select);
}
/**
* distinct
* Makes the query SELECT DISTINCT.
*
* @param bool $flag Whether or not the SELECT is DISTINCT (default true).
* @return Doctrine_Query
*/
public function distinct($flag = true)
{
$this->_parts['distinct'] = (bool) $flag;
$func = $this->getTableAlias($reference).'.'.$func; return $this;
}
return $func; /**
} else { * forUpdate
* Makes the query SELECT FOR UPDATE.
*
* @param bool $flag Whether or not the SELECT is FOR UPDATE (default true).
* @return Doctrine_Query
*/
public function forUpdate($flag = true)
{
$this->_parts[self::FOR_UPDATE] = (bool) $flag;
return $func; return $this;
}
}
} }
/** /**
* parseAggregateValues * delete
* sets the query type to DELETE
*
* @return Doctrine_Query
*/ */
public function parseAggregateValues($fullName, $tableName, array $exploded, $currPath) public function delete()
{ {
$this->aggregate = true; $this->type = self::DELETE;
$pos = strpos($fullName, '(');
$name = substr($fullName, 0, $pos);
$string = substr($fullName, ($pos + 1), -1);
$exploded = Doctrine_Query::bracketExplode($string, ','); return $this;
foreach($exploded as $k => $value) { }
$func = $this->parseAggregateFunction($value, $currPath); /**
$exploded[$k] = $func; * update
* sets the UPDATE part of the query
*
* @param string $update DQL UPDATE part
* @return Doctrine_Query
*/
public function update($update)
{
$this->type = self::UPDATE;
$this->parts['select'][] = $exploded[$k]; return $this->getParser('from')->parse($update);
} }
/**
* set
* sets the SET part of the query
*
* @param string $update DQL UPDATE part
* @return Doctrine_Query
*/
public function set($key, $value)
{
return $this->getParser('set')->parse($key . ' = ' . $value);
}
/**
* from
* sets the FROM part of the query
*
* @param string $from DQL FROM part
* @return Doctrine_Query
*/
public function from($from)
{
return $this->getParser('from')->parse($from);
}
/**
* innerJoin
* appends an INNER JOIN to the FROM part of the query
*
* @param string $join DQL INNER JOIN
* @return Doctrine_Query
*/
public function innerJoin($join)
{
return $this->getParser('from')->parse('INNER JOIN ' . $join);
}
/**
* leftJoin
* appends a LEFT JOIN to the FROM part of the query
*
* @param string $join DQL LEFT JOIN
* @return Doctrine_Query
*/
public function leftJoin($join)
{
return $this->getParser('from')->parse('LEFT JOIN ' . $join);
}
/**
* groupBy
* sets the GROUP BY part of the query
*
* @param string $groupby DQL GROUP BY part
* @return Doctrine_Query
*/
public function groupBy($groupby)
{
return $this->getParser('groupby')->parse($groupby);
}
/**
* where
* sets the WHERE part of the query
*
* @param string $join DQL WHERE part
* @param mixed $params an array of parameters or a simple scalar
* @return Doctrine_Query
*/
public function where($where, $params = array())
{
$this->params = (array) $params;
return $this->getParser('where')->parse($where);
}
/**
* having
* sets the HAVING part of the query
*
* @param string $having DQL HAVING part
* @param mixed $params an array of parameters or a simple scalar
* @return Doctrine_Query
*/
public function having($having, $params)
{
$this->params = (array) $params;
return $this->getParser('having')->parse($having);
}
/**
* orderBy
* sets the ORDER BY part of the query
*
* @param string $orderby DQL ORDER BY part
* @return Doctrine_Query
*/
public function orderBy($orderby)
{
return $this->getParser('orderby')->parse($orderby);
}
/**
* limit
* sets the DQL query limit
*
* @param integer $limit limit to be used for limiting the query results
* @return Doctrine_Query
*/
public function limit($limit)
{
return $this->getParser('limit')->parse($limit);
}
/**
* offset
* sets the DQL query offset
*
* @param integer $offset offset to be used for paginating the query
* @return Doctrine_Query
*/
public function offset($offset)
{
return $this->getParser('offset')->parse($offset);
} }
} }
...@@ -39,32 +39,32 @@ abstract class Doctrine_Query_Condition extends Doctrine_Query_Part ...@@ -39,32 +39,32 @@ abstract class Doctrine_Query_Condition extends Doctrine_Query_Part
* @param string $str * @param string $str
* @return string * @return string
*/ */
final public function parse($str) public function _parse($str)
{ {
$tmp = trim($str); $tmp = trim($str);
$parts = Doctrine_Query::bracketExplode($str, array(' \&\& ', ' AND '), '(', ')'); $parts = Doctrine_Tokenizer::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_Tokenizer::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_Tokenizer::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_Tokenizer::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]);
} }
...@@ -73,6 +73,9 @@ abstract class Doctrine_Query_Condition extends Doctrine_Query_Part ...@@ -73,6 +73,9 @@ abstract class Doctrine_Query_Condition extends Doctrine_Query_Part
return '(' . $r . ')'; return '(' . $r . ')';
} }
/** /**
* parses a literal value and returns the parsed value * parses a literal value and returns the parsed value
* *
...@@ -88,7 +91,7 @@ abstract class Doctrine_Query_Condition extends Doctrine_Query_Part ...@@ -88,7 +91,7 @@ abstract class Doctrine_Query_Condition extends Doctrine_Query_Part
if (strpos($value, '\'') === false) { if (strpos($value, '\'') === false) {
// parse booleans // parse booleans
$value = $this->query->getConnection() $value = $this->query->getConnection()
->dataDict->parseBoolean($value); ->dataDict->parseBoolean($value);
$a = explode('.', $value); $a = explode('.', $value);
......
...@@ -31,7 +31,7 @@ Doctrine::autoload("Doctrine_Query_Part"); ...@@ -31,7 +31,7 @@ Doctrine::autoload("Doctrine_Query_Part");
* @author Konsta Vesterinen <kvesteri@cc.hut.fi> * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
*/ */
class Doctrine_Query_From extends Doctrine_Query_Part class Doctrine_Query_From extends Doctrine_Query_Part
{ {
/** /**
* DQL FROM PARSER * DQL FROM PARSER
* parses the from part of the query string * parses the from part of the query string
...@@ -39,11 +39,10 @@ class Doctrine_Query_From extends Doctrine_Query_Part ...@@ -39,11 +39,10 @@ class Doctrine_Query_From extends Doctrine_Query_Part
* @param string $str * @param string $str
* @return void * @return void
*/ */
final public function parse($str) public function parse($str)
{ {
$str = trim($str); $str = trim($str);
$parts = Doctrine_Query::bracketExplode($str, 'JOIN'); $parts = Doctrine_Tokenizer::bracketExplode($str, 'JOIN');
$operator = false; $operator = false;
...@@ -52,8 +51,10 @@ class Doctrine_Query_From extends Doctrine_Query_Part ...@@ -52,8 +51,10 @@ class Doctrine_Query_From extends Doctrine_Query_Part
$operator = ':'; $operator = ':';
case 'LEFT': case 'LEFT':
array_shift($parts); array_shift($parts);
break;
} }
$last = ''; $last = '';
foreach ($parts as $k => $part) { foreach ($parts as $k => $part) {
...@@ -70,7 +71,7 @@ class Doctrine_Query_From extends Doctrine_Query_Part ...@@ -70,7 +71,7 @@ class Doctrine_Query_From extends Doctrine_Query_Part
} }
$part = implode(' ', $e); $part = implode(' ', $e);
foreach (Doctrine_Query::bracketExplode($part, ',') as $reference) { foreach (Doctrine_Tokenizer::bracketExplode($part, ',') as $reference) {
$reference = trim($reference); $reference = trim($reference);
$e = explode('.', $reference); $e = explode('.', $reference);
...@@ -83,6 +84,7 @@ class Doctrine_Query_From extends Doctrine_Query_Part ...@@ -83,6 +84,7 @@ class Doctrine_Query_From extends Doctrine_Query_Part
$operator = ($last == 'INNER') ? ':' : '.'; $operator = ($last == 'INNER') ? ':' : '.';
} }
return $this->query;
} }
} }
...@@ -39,7 +39,7 @@ class Doctrine_Query_Groupby extends Doctrine_Query_Part ...@@ -39,7 +39,7 @@ class Doctrine_Query_Groupby extends Doctrine_Query_Part
* @param string $str * @param string $str
* @return void * @return void
*/ */
final public function parse($str) public function parse($str, $append = false)
{ {
$r = array(); $r = array();
foreach (explode(',', $str) as $reference) { foreach (explode(',', $str) as $reference) {
...@@ -47,10 +47,15 @@ class Doctrine_Query_Groupby extends Doctrine_Query_Part ...@@ -47,10 +47,15 @@ class Doctrine_Query_Groupby extends Doctrine_Query_Part
$e = explode('.', $reference); $e = explode('.', $reference);
$field = array_pop($e); $field = array_pop($e);
$ref = implode('.', $e); $ref = implode('.', $e);
$table = $this->query->load($ref); $this->query->load($ref);
$component = $table->getComponentName();
$r[] = $this->query->getTableAlias($ref).".".$field; $r[] = $this->query->getTableAlias($ref) . '.' . $field;
}
if ($append) {
$this->query->addQueryPart('groupby', implode(', ', $r));
} else {
$this->query->setQueryPart('groupby', implode(', ', $r));
} }
return implode(', ', $r); return $this->query;
} }
} }
...@@ -32,6 +32,15 @@ Doctrine::autoload('Doctrine_Query_Condition'); ...@@ -32,6 +32,15 @@ Doctrine::autoload('Doctrine_Query_Condition');
*/ */
class Doctrine_Query_Having extends Doctrine_Query_Condition class Doctrine_Query_Having extends Doctrine_Query_Condition
{ {
public function parse($str, $append = false)
{
if ($append) {
$this->query->addQueryPart('having', $this->_parse($str));
} else {
$this->query->setQueryPart('having', $this->_parse($str));
}
return $this->query;
}
/** /**
* DQL Aggregate Function parser * DQL Aggregate Function parser
* *
...@@ -47,7 +56,7 @@ class Doctrine_Query_Having extends Doctrine_Query_Condition ...@@ -47,7 +56,7 @@ class Doctrine_Query_Having extends Doctrine_Query_Condition
$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_Tokenizer::bracketExplode($func, ',', '(', ')');
foreach ($params as $k => $param) { foreach ($params as $k => $param) {
$params[$k] = $this->parseAggregateFunction($param); $params[$k] = $this->parseAggregateFunction($param);
...@@ -64,8 +73,8 @@ class Doctrine_Query_Having extends Doctrine_Query_Condition ...@@ -64,8 +73,8 @@ class Doctrine_Query_Having extends Doctrine_Query_Condition
if (count($a) > 1) { if (count($a) > 1) {
$field = array_pop($a); $field = array_pop($a);
$reference = implode('.', $a); $reference = implode('.', $a);
$table = $this->query->load($reference, false); $map = $this->query->load($reference, false);
$field = $table->getColumnName($field); $field = $map['table']->getColumnName($field);
$func = $this->query->getTableAlias($reference) . '.' . $field; $func = $this->query->getTableAlias($reference) . '.' . $field;
} else { } else {
$field = end($a); $field = end($a);
...@@ -86,7 +95,7 @@ class Doctrine_Query_Having extends Doctrine_Query_Condition ...@@ -86,7 +95,7 @@ class Doctrine_Query_Having extends Doctrine_Query_Condition
*/ */
final public function load($having) final public function load($having)
{ {
$e = Doctrine_Query::bracketExplode($having, ' ', '(', ')'); $e = Doctrine_Tokenizer::bracketExplode($having, ' ', '(', ')');
$r = array_shift($e); $r = array_shift($e);
$t = explode('(', $r); $t = explode('(', $r);
......
...@@ -36,7 +36,7 @@ class Doctrine_Query_JoinCondition extends Doctrine_Query_Condition ...@@ -36,7 +36,7 @@ class Doctrine_Query_JoinCondition extends Doctrine_Query_Condition
{ {
$condition = trim($condition); $condition = trim($condition);
$e = Doctrine_Query::sqlExplode($condition); $e = Doctrine_Tokenizer::sqlExplode($condition);
if(count($e) > 2) { if(count($e) > 2) {
$a = explode('.', $e[0]); $a = explode('.', $e[0]);
...@@ -46,15 +46,15 @@ class Doctrine_Query_JoinCondition extends Doctrine_Query_Condition ...@@ -46,15 +46,15 @@ class Doctrine_Query_JoinCondition extends Doctrine_Query_Condition
$value = $e[2]; $value = $e[2];
$alias = $this->query->getTableAlias($reference); $alias = $this->query->getTableAlias($reference);
$map = $this->query->getDeclaration($reference);
$table = $this->query->getTable($alias); $table = $map['table'];
// check if value is enumerated value // check if value is enumerated value
$enumIndex = $table->enumIndex($field, trim($value, "'")); $enumIndex = $table->enumIndex($field, trim($value, "'"));
if (substr($value, 0, 1) == '(') { if (substr($value, 0, 1) == '(') {
// trim brackets // trim brackets
$trimmed = Doctrine_Query::bracketTrim($value); $trimmed = Doctrine_Tokenizer::bracketTrim($value);
if (substr($trimmed, 0, 4) == 'FROM' || substr($trimmed, 0, 6) == 'SELECT') { if (substr($trimmed, 0, 4) == 'FROM' || substr($trimmed, 0, 6) == 'SELECT') {
// subquery found // subquery found
...@@ -64,7 +64,7 @@ class Doctrine_Query_JoinCondition extends Doctrine_Query_Condition ...@@ -64,7 +64,7 @@ class Doctrine_Query_JoinCondition extends Doctrine_Query_Condition
$value = '(' . substr($trimmed, 4) . ')'; $value = '(' . substr($trimmed, 4) . ')';
} else { } else {
// simple in expression found // simple in expression found
$e = Doctrine_Query::sqlExplode($trimmed, ','); $e = Doctrine_Tokenizer::sqlExplode($trimmed, ',');
$value = array(); $value = array();
foreach ($e as $part) { foreach ($e as $part) {
......
<?php
/*
* $Id: Where.php 1352 2007-05-15 10:07:05Z zYne $
*
* 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_Query_Limit
*
* @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: 1352 $
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
*/
class Doctrine_Query_Limit extends Doctrine_Query_Part
{
public function parse($limit)
{
$this->query->setQueryPart('limit', (int) $limit);
return $this->query;
}
}
<?php
/*
* $Id: Where.php 1352 2007-05-15 10:07:05Z zYne $
*
* 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_Query_Offset
*
* @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: 1352 $
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
*/
class Doctrine_Query_Offset extends Doctrine_Query_Part
{
public function parse($offset)
{
$this->query->setQueryPart('offset', (int) $offset);
return $this->query;
}
}
...@@ -39,7 +39,7 @@ class Doctrine_Query_Orderby extends Doctrine_Query_Part ...@@ -39,7 +39,7 @@ class Doctrine_Query_Orderby extends Doctrine_Query_Part
* @param string $str * @param string $str
* @return void * @return void
*/ */
public function parse($str) public function parse($str, $append = false)
{ {
$ret = array(); $ret = array();
...@@ -53,12 +53,10 @@ class Doctrine_Query_Orderby extends Doctrine_Query_Part ...@@ -53,12 +53,10 @@ class Doctrine_Query_Orderby extends Doctrine_Query_Part
$reference = implode('.', $a); $reference = implode('.', $a);
$name = end($a); $name = end($a);
$this->query->load($reference, false); $map = $this->query->load($reference, false);
$alias = $this->query->getTableAlias($reference); $tableAlias = $this->query->getTableAlias($reference);
$tname = $this->query->getTable($alias)->getTableName(); $r = $tableAlias . '.' . $field;
$r = $alias . '.' . $field;
} else { } else {
...@@ -72,6 +70,11 @@ class Doctrine_Query_Orderby extends Doctrine_Query_Part ...@@ -72,6 +70,11 @@ class Doctrine_Query_Orderby extends Doctrine_Query_Part
$ret[] = $r; $ret[] = $r;
} }
return implode(', ', $ret); if ($append) {
$this->query->addQueryPart('orderby', implode(', ', $ret));
} else {
$this->query->setQueryPart('orderby', implode(', ', $ret));
}
return $this->query;
} }
} }
...@@ -34,11 +34,11 @@ class Doctrine_Query_Set extends Doctrine_Query_Part ...@@ -34,11 +34,11 @@ class Doctrine_Query_Set extends Doctrine_Query_Part
{ {
public function parse($dql) public function parse($dql)
{ {
$parts = Doctrine_Query::sqlExplode($dql, ','); $parts = Doctrine_Tokenizer::sqlExplode($dql, ',');
$result = array(); $result = array();
foreach ($parts as $part) { foreach ($parts as $part) {
$set = Doctrine_Query::sqlExplode($part, '='); $set = Doctrine_Tokenizer::sqlExplode($part, '=');
$e = explode('.', trim($set[0])); $e = explode('.', trim($set[0]));
$field = array_pop($e); $field = array_pop($e);
...@@ -46,12 +46,15 @@ class Doctrine_Query_Set extends Doctrine_Query_Part ...@@ -46,12 +46,15 @@ class Doctrine_Query_Set extends Doctrine_Query_Part
$reference = implode('.', $e); $reference = implode('.', $e);
$alias = $this->query->getTableAlias($reference); $alias = $this->query->getTableAlias($reference);
$table = $this->query->getTable($alias);
$result[] = $table->getColumnName($field) . ' = ' . $set[1]; $map = $this->query->getDeclaration($reference);
$result[] = $map['table']->getColumnName($field) . ' = ' . $set[1];
} }
return implode(', ', $result); $this->query->addQueryPart('set', implode(', ', $result));
return $this->query;
} }
} }
...@@ -32,6 +32,15 @@ Doctrine::autoload('Doctrine_Query_Condition'); ...@@ -32,6 +32,15 @@ Doctrine::autoload('Doctrine_Query_Condition');
*/ */
class Doctrine_Query_Where extends Doctrine_Query_Condition class Doctrine_Query_Where extends Doctrine_Query_Condition
{ {
public function parse($str, $append = false)
{
if ($append) {
$this->query->addQueryPart('where', $this->_parse($str));
} else {
$this->query->setQueryPart('where', $this->_parse($str));
}
return $this->query;
}
/** /**
* load * load
* returns the parsed query part * returns the parsed query part
...@@ -43,7 +52,7 @@ class Doctrine_Query_Where extends Doctrine_Query_Condition ...@@ -43,7 +52,7 @@ class Doctrine_Query_Where extends Doctrine_Query_Condition
{ {
$where = trim($where); $where = trim($where);
$e = Doctrine_Query::sqlExplode($where); $e = Doctrine_Tokenizer::sqlExplode($where);
if (count($e) > 1) { if (count($e) > 1) {
$tmp = $e[0] . ' ' . $e[1]; $tmp = $e[0] . ' ' . $e[1];
...@@ -56,7 +65,7 @@ class Doctrine_Query_Where extends Doctrine_Query_Condition ...@@ -56,7 +65,7 @@ class Doctrine_Query_Where extends Doctrine_Query_Condition
} }
if (count($e) < 3) { if (count($e) < 3) {
$e = Doctrine_Query::sqlExplode($where, array('=', '<', '>', '!=')); $e = Doctrine_Tokenizer::sqlExplode($where, array('=', '<', '>', '!='));
} }
$r = array_shift($e); $r = array_shift($e);
...@@ -83,7 +92,6 @@ class Doctrine_Query_Where extends Doctrine_Query_Condition ...@@ -83,7 +92,6 @@ class Doctrine_Query_Where extends Doctrine_Query_Condition
$field = array_pop($a); $field = array_pop($a);
$reference = implode('.', $a); $reference = implode('.', $a);
$table = $this->query->load($reference, false); $table = $this->query->load($reference, false);
$field = $table->getColumnName($field); $field = $table->getColumnName($field);
array_pop($a); array_pop($a);
...@@ -119,20 +127,20 @@ class Doctrine_Query_Where extends Doctrine_Query_Condition ...@@ -119,20 +127,20 @@ class Doctrine_Query_Where extends Doctrine_Query_Condition
throw new Doctrine_Query_Exception('Unknown DQL function: '.$func); throw new Doctrine_Query_Exception('Unknown DQL function: '.$func);
} }
} else { } else {
$table = $this->query->load($reference, false); $map = $this->query->load($reference, false);
$alias = $this->query->getTableAlias($reference);
$table = $this->query->getTable($alias); $alias = $this->query->getTableAlias($reference);
$table = $map['table'];
$field = $table->getColumnName($field);
$field = $table->getColumnName($field);
// check if value is enumerated value // check if value is enumerated value
$enumIndex = $table->enumIndex($field, trim($value, "'")); $enumIndex = $table->enumIndex($field, trim($value, "'"));
if (substr($value, 0, 1) == '(') { if (substr($value, 0, 1) == '(') {
// trim brackets // trim brackets
$trimmed = Doctrine_Query::bracketTrim($value); $trimmed = Doctrine_Tokenizer::bracketTrim($value);
if (substr($trimmed, 0, 4) == 'FROM' || substr($trimmed, 0, 6) == 'SELECT') { if (substr($trimmed, 0, 4) == 'FROM' || substr($trimmed, 0, 6) == 'SELECT') {
// subquery found // subquery found
$q = new Doctrine_Query(); $q = new Doctrine_Query();
$value = '(' . $q->isSubquery(true)->parseQuery($trimmed)->getQuery() . ')'; $value = '(' . $q->isSubquery(true)->parseQuery($trimmed)->getQuery() . ')';
...@@ -141,11 +149,12 @@ class Doctrine_Query_Where extends Doctrine_Query_Condition ...@@ -141,11 +149,12 @@ class Doctrine_Query_Where extends Doctrine_Query_Condition
$value = '(' . substr($trimmed, 4) . ')'; $value = '(' . substr($trimmed, 4) . ')';
} else { } else {
// simple in expression found // simple in expression found
$e = Doctrine_Query::sqlExplode($trimmed, ','); $e = Doctrine_Tokenizer::sqlExplode($trimmed, ',');
$value = array(); $value = array();
foreach ($e as $part) { foreach ($e as $part) {
$index = $table->enumIndex($field, trim($part, "'")); $index = $table->enumIndex($field, trim($part, "'"));
if ($index !== false) { if ($index !== false) {
$value[] = $index; $value[] = $index;
} else { } else {
...@@ -198,10 +207,11 @@ class Doctrine_Query_Where extends Doctrine_Query_Condition ...@@ -198,10 +207,11 @@ class Doctrine_Query_Where extends Doctrine_Query_Condition
$pos = strpos($where, '('); $pos = strpos($where, '(');
if ($pos == false) if ($pos == false) {
throw new Doctrine_Query_Exception("Unknown expression, expected '('"); throw new Doctrine_Query_Exception("Unknown expression, expected '('");
}
$sub = Doctrine_Query::bracketTrim(substr($where, $pos)); $sub = Doctrine_Tokenizer::bracketTrim(substr($where, $pos));
return $operator . ' (' . $this->query->createSubquery()->parseQuery($sub, false)->getQuery() . ')'; return $operator . ' (' . $this->query->createSubquery()->parseQuery($sub, false)->getQuery() . ')';
} }
...@@ -226,14 +236,4 @@ class Doctrine_Query_Where extends Doctrine_Query_Condition ...@@ -226,14 +236,4 @@ class Doctrine_Query_Where extends Doctrine_Query_Condition
} }
return $operator; return $operator;
} }
/**
* __toString
* return string representation of this object
*
* @return string
*/
public function __toString()
{
return ( ! empty($this->parts))?implode(' AND ', $this->parts):'';
}
} }
...@@ -53,7 +53,7 @@ class Doctrine_Record_Filter ...@@ -53,7 +53,7 @@ class Doctrine_Record_Filter
*/ */
public function getRecord() public function getRecord()
{ {
return $this->_record; return $this->_record;
} }
/** /**
* cleanData * cleanData
...@@ -100,8 +100,9 @@ class Doctrine_Record_Filter ...@@ -100,8 +100,9 @@ class Doctrine_Record_Filter
if (is_string($tmp[$name])) { if (is_string($tmp[$name])) {
$value = unserialize($tmp[$name]); $value = unserialize($tmp[$name]);
if ($value === false) if ($value === false) {
throw new Doctrine_Record_Exception('Unserialization of ' . $name . ' failed.'); throw new Doctrine_Record_Exception('Unserialization of ' . $name . ' failed.');
}
} else { } else {
$value = $tmp[$name]; $value = $tmp[$name];
} }
...@@ -112,9 +113,10 @@ class Doctrine_Record_Filter ...@@ -112,9 +113,10 @@ class Doctrine_Record_Filter
if ($tmp[$name] !== self::$null) { if ($tmp[$name] !== self::$null) {
$value = gzuncompress($tmp[$name]); $value = gzuncompress($tmp[$name]);
if ($value === false) if ($value === false) {
throw new Doctrine_Record_Exception('Uncompressing of ' . $name . ' failed.'); throw new Doctrine_Record_Exception('Uncompressing of ' . $name . ' failed.');
}
$this->_data[$name] = $value; $this->_data[$name] = $value;
} }
break; break;
...@@ -212,8 +214,9 @@ class Doctrine_Record_Filter ...@@ -212,8 +214,9 @@ class Doctrine_Record_Filter
$a[$v] = $this->_table->enumIndex($v,$this->_data[$v]); $a[$v] = $this->_table->enumIndex($v,$this->_data[$v]);
break; break;
default: default:
if ($this->_data[$v] instanceof Doctrine_Record) if ($this->_data[$v] instanceof Doctrine_Record) {
$this->_data[$v] = $this->_data[$v]->getIncremented(); $this->_data[$v] = $this->_data[$v]->getIncremented();
}
$a[$v] = $this->_data[$v]; $a[$v] = $this->_data[$v];
} }
......
...@@ -126,7 +126,7 @@ class Doctrine_Relation_Association extends Doctrine_Relation ...@@ -126,7 +126,7 @@ class Doctrine_Relation_Association extends Doctrine_Relation
*/ */
public function fetchRelatedFor(Doctrine_Record $record) public function fetchRelatedFor(Doctrine_Record $record)
{ {
$id = $record->getIncremented(); $id = $record->getIncremented();
if (empty($id)) { if (empty($id)) {
$coll = new Doctrine_Collection($this->getTable()); $coll = new Doctrine_Collection($this->getTable());
} else { } else {
......
...@@ -792,7 +792,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -792,7 +792,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
$alias = $name; $alias = $name;
} }
$this->bound[$alias] = array('field' => $field, $this->bound[$alias] = array('field' => $field,
'type' => $type, 'type' => $type,
'class' => $name, 'class' => $name,
'alias' => $alias); 'alias' => $alias);
...@@ -1125,32 +1125,38 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -1125,32 +1125,38 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
*/ */
public function getRecord() public function getRecord()
{ {
$this->data = array_change_key_case($this->data, CASE_LOWER); if ( ! empty($this->data)) {
$this->data = array_change_key_case($this->data, CASE_LOWER);
$key = $this->getIdentifier();
$key = $this->getIdentifier();
if ( ! is_array($key)) {
$key = array($key); if ( ! is_array($key)) {
} $key = array($key);
foreach ($key as $k) {
if ( ! isset($this->data[$k])) {
throw new Doctrine_Table_Exception("Primary key value for $k wasn't found");
} }
$id[] = $this->data[$k];
} foreach ($key as $k) {
if ( ! isset($this->data[$k])) {
$id = implode(' ', $id); throw new Doctrine_Table_Exception("Primary key value for $k wasn't found");
}
if (isset($this->identityMap[$id])) { $id[] = $this->data[$k];
$record = $this->identityMap[$id]; }
$record->hydrate($this->data);
$id = implode(' ', $id);
if (isset($this->identityMap[$id])) {
$record = $this->identityMap[$id];
$record->hydrate($this->data);
} else {
$recordName = $this->getClassnameToReturn();
$record = new $recordName($this);
$this->identityMap[$id] = $record;
}
$this->data = array();
} else { } else {
$recordName = $this->getClassnameToReturn(); $recordName = $this->getClassnameToReturn();
$record = new $recordName($this); $record = new $recordName($this, true);
$this->identityMap[$id] = $record;
} }
$this->data = array();
return $record; return $record;
} }
......
...@@ -111,7 +111,7 @@ class Doctrine_Hydrate_TestCase extends Doctrine_UnitTestCase ...@@ -111,7 +111,7 @@ class Doctrine_Hydrate_TestCase extends Doctrine_UnitTestCase
} }
*/ */
} }
class Doctrine_Hydrate_Mock extends Doctrine_Hydrate2 class Doctrine_Hydrate_Mock extends Doctrine_Hydrate
{ {
protected $data; protected $data;
......
...@@ -77,7 +77,7 @@ class Doctrine_Query_AggregateValue_TestCase extends Doctrine_UnitTestCase ...@@ -77,7 +77,7 @@ class Doctrine_Query_AggregateValue_TestCase extends Doctrine_UnitTestCase
} }
public function testAggregateValueIsMappedToNewRecordOnEmptyResultSet() public function testAggregateValueIsMappedToNewRecordOnEmptyResultSet()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->select('COUNT(u.id) count')->from('User u'); $q->select('COUNT(u.id) count')->from('User u');
...@@ -88,7 +88,7 @@ class Doctrine_Query_AggregateValue_TestCase extends Doctrine_UnitTestCase ...@@ -88,7 +88,7 @@ class Doctrine_Query_AggregateValue_TestCase extends Doctrine_UnitTestCase
} }
public function testAggregateValueIsMappedToRecord() public function testAggregateValueIsMappedToRecord()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->select('u.name, COUNT(u.id) count')->from('User u')->groupby('u.name'); $q->select('u.name, COUNT(u.id) count')->from('User u')->groupby('u.name');
...@@ -105,7 +105,7 @@ class Doctrine_Query_AggregateValue_TestCase extends Doctrine_UnitTestCase ...@@ -105,7 +105,7 @@ class Doctrine_Query_AggregateValue_TestCase extends Doctrine_UnitTestCase
public function testAggregateValueMappingSupportsLeftJoins() public function testAggregateValueMappingSupportsLeftJoins()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->select('u.name, COUNT(p.id) count')->from('User u')->leftJoin('u.Phonenumber p')->groupby('u.id'); $q->select('u.name, COUNT(p.id) count')->from('User u')->leftJoin('u.Phonenumber p')->groupby('u.id');
...@@ -120,7 +120,7 @@ class Doctrine_Query_AggregateValue_TestCase extends Doctrine_UnitTestCase ...@@ -120,7 +120,7 @@ class Doctrine_Query_AggregateValue_TestCase extends Doctrine_UnitTestCase
} }
public function testAggregateValueMappingSupportsLeftJoins2() public function testAggregateValueMappingSupportsLeftJoins2()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->select('MAX(u.name)')->from('User u')->leftJoin('u.Phonenumber p')->groupby('u.id'); $q->select('MAX(u.name)')->from('User u')->leftJoin('u.Phonenumber p')->groupby('u.id');
...@@ -131,7 +131,7 @@ class Doctrine_Query_AggregateValue_TestCase extends Doctrine_UnitTestCase ...@@ -131,7 +131,7 @@ class Doctrine_Query_AggregateValue_TestCase extends Doctrine_UnitTestCase
} }
public function testAggregateValueMappingSupportsMultipleValues() public function testAggregateValueMappingSupportsMultipleValues()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->select('u.name, COUNT(p.id) count, MAX(p.id) max')->from('User u')->innerJoin('u.Phonenumber p')->groupby('u.id'); $q->select('u.name, COUNT(p.id) count, MAX(p.id) max')->from('User u')->innerJoin('u.Phonenumber p')->groupby('u.id');
...@@ -141,7 +141,7 @@ class Doctrine_Query_AggregateValue_TestCase extends Doctrine_UnitTestCase ...@@ -141,7 +141,7 @@ class Doctrine_Query_AggregateValue_TestCase extends Doctrine_UnitTestCase
} }
public function testAggregateValueMappingSupportsInnerJoins() public function testAggregateValueMappingSupportsInnerJoins()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->select('u.name, COUNT(p.id) count')->from('User u')->innerJoin('u.Phonenumber p')->groupby('u.id'); $q->select('u.name, COUNT(p.id) count')->from('User u')->innerJoin('u.Phonenumber p')->groupby('u.id');
......
...@@ -35,13 +35,13 @@ class Doctrine_Query_Delete_TestCase extends Doctrine_UnitTestCase ...@@ -35,13 +35,13 @@ class Doctrine_Query_Delete_TestCase extends Doctrine_UnitTestCase
{ {
public function testDeleteAllWithColumnAggregationInheritance() public function testDeleteAllWithColumnAggregationInheritance()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->parseQuery('DELETE FROM User'); $q->parseQuery('DELETE FROM User');
$this->assertEqual($q->getQuery(), 'DELETE FROM entity WHERE (type = 0)'); $this->assertEqual($q->getQuery(), 'DELETE FROM entity WHERE (type = 0)');
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->delete()->from('User'); $q->delete()->from('User');
...@@ -49,13 +49,13 @@ class Doctrine_Query_Delete_TestCase extends Doctrine_UnitTestCase ...@@ -49,13 +49,13 @@ class Doctrine_Query_Delete_TestCase extends Doctrine_UnitTestCase
} }
public function testDeleteAll() public function testDeleteAll()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->parseQuery('DELETE FROM Entity'); $q->parseQuery('DELETE FROM Entity');
$this->assertEqual($q->getQuery(), 'DELETE FROM entity'); $this->assertEqual($q->getQuery(), 'DELETE FROM entity');
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->delete()->from('Entity'); $q->delete()->from('Entity');
...@@ -63,13 +63,13 @@ class Doctrine_Query_Delete_TestCase extends Doctrine_UnitTestCase ...@@ -63,13 +63,13 @@ class Doctrine_Query_Delete_TestCase extends Doctrine_UnitTestCase
} }
public function testDeleteWithCondition() public function testDeleteWithCondition()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->parseQuery('DELETE FROM Entity WHERE id = 3'); $q->parseQuery('DELETE FROM Entity WHERE id = 3');
$this->assertEqual($q->getQuery(), 'DELETE FROM entity WHERE id = 3'); $this->assertEqual($q->getQuery(), 'DELETE FROM entity WHERE id = 3');
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->delete()->from('Entity')->where('id = 3'); $q->delete()->from('Entity')->where('id = 3');
...@@ -77,13 +77,13 @@ class Doctrine_Query_Delete_TestCase extends Doctrine_UnitTestCase ...@@ -77,13 +77,13 @@ class Doctrine_Query_Delete_TestCase extends Doctrine_UnitTestCase
} }
public function testDeleteWithLimit() public function testDeleteWithLimit()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->parseQuery('DELETE FROM Entity LIMIT 20'); $q->parseQuery('DELETE FROM Entity LIMIT 20');
$this->assertEqual($q->getQuery(), 'DELETE FROM entity LIMIT 20'); $this->assertEqual($q->getQuery(), 'DELETE FROM entity LIMIT 20');
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->delete()->from('Entity')->limit(20); $q->delete()->from('Entity')->limit(20);
...@@ -91,13 +91,13 @@ class Doctrine_Query_Delete_TestCase extends Doctrine_UnitTestCase ...@@ -91,13 +91,13 @@ class Doctrine_Query_Delete_TestCase extends Doctrine_UnitTestCase
} }
public function testDeleteWithLimitAndOffset() public function testDeleteWithLimitAndOffset()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->parseQuery('DELETE FROM Entity LIMIT 10 OFFSET 20'); $q->parseQuery('DELETE FROM Entity LIMIT 10 OFFSET 20');
$this->assertEqual($q->getQuery(), 'DELETE FROM entity LIMIT 10 OFFSET 20'); $this->assertEqual($q->getQuery(), 'DELETE FROM entity LIMIT 10 OFFSET 20');
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->delete()->from('Entity')->limit(10)->offset(20); $q->delete()->from('Entity')->limit(10)->offset(20);
......
...@@ -34,7 +34,7 @@ class Doctrine_Query_From_TestCase extends Doctrine_UnitTestCase ...@@ -34,7 +34,7 @@ class Doctrine_Query_From_TestCase extends Doctrine_UnitTestCase
{ {
public function testLeftJoin() public function testLeftJoin()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->from('User u LEFT JOIN u.Group'); $q->from('User u LEFT JOIN u.Group');
...@@ -43,7 +43,7 @@ class Doctrine_Query_From_TestCase extends Doctrine_UnitTestCase ...@@ -43,7 +43,7 @@ class Doctrine_Query_From_TestCase extends Doctrine_UnitTestCase
public function testDefaultJoinIsLeftJoin() public function testDefaultJoinIsLeftJoin()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->from('User u JOIN u.Group'); $q->from('User u JOIN u.Group');
...@@ -52,7 +52,7 @@ class Doctrine_Query_From_TestCase extends Doctrine_UnitTestCase ...@@ -52,7 +52,7 @@ class Doctrine_Query_From_TestCase extends Doctrine_UnitTestCase
public function testInnerJoin() public function testInnerJoin()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->from('User u INNER JOIN u.Group'); $q->from('User u INNER JOIN u.Group');
...@@ -61,7 +61,7 @@ class Doctrine_Query_From_TestCase extends Doctrine_UnitTestCase ...@@ -61,7 +61,7 @@ class Doctrine_Query_From_TestCase extends Doctrine_UnitTestCase
public function testMultipleLeftJoin() public function testMultipleLeftJoin()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->from('User u LEFT JOIN u.Group LEFT JOIN u.Phonenumber'); $q->from('User u LEFT JOIN u.Group LEFT JOIN u.Phonenumber');
...@@ -69,7 +69,7 @@ class Doctrine_Query_From_TestCase extends Doctrine_UnitTestCase ...@@ -69,7 +69,7 @@ class Doctrine_Query_From_TestCase extends Doctrine_UnitTestCase
} }
public function testMultipleLeftJoin2() public function testMultipleLeftJoin2()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->from('User u LEFT JOIN u.Group LEFT JOIN u.Phonenumber'); $q->from('User u LEFT JOIN u.Group LEFT JOIN u.Phonenumber');
...@@ -77,7 +77,7 @@ class Doctrine_Query_From_TestCase extends Doctrine_UnitTestCase ...@@ -77,7 +77,7 @@ class Doctrine_Query_From_TestCase extends Doctrine_UnitTestCase
} }
public function testMultipleInnerJoin() public function testMultipleInnerJoin()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->select('u.name')->from('User u INNER JOIN u.Group INNER JOIN u.Phonenumber'); $q->select('u.name')->from('User u INNER JOIN u.Group INNER JOIN u.Phonenumber');
...@@ -85,7 +85,7 @@ class Doctrine_Query_From_TestCase extends Doctrine_UnitTestCase ...@@ -85,7 +85,7 @@ class Doctrine_Query_From_TestCase extends Doctrine_UnitTestCase
} }
public function testMultipleInnerJoin2() public function testMultipleInnerJoin2()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->select('u.name')->from('User u INNER JOIN u.Group, u.Phonenumber'); $q->select('u.name')->from('User u INNER JOIN u.Group, u.Phonenumber');
...@@ -97,7 +97,7 @@ class Doctrine_Query_From_TestCase extends Doctrine_UnitTestCase ...@@ -97,7 +97,7 @@ class Doctrine_Query_From_TestCase extends Doctrine_UnitTestCase
} }
public function testMixingOfJoins() public function testMixingOfJoins()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->select('u.name, g.name, p.phonenumber')->from('User u INNER JOIN u.Group g LEFT JOIN u.Phonenumber p'); $q->select('u.name, g.name, p.phonenumber')->from('User u INNER JOIN u.Group g LEFT JOIN u.Phonenumber p');
......
...@@ -32,14 +32,14 @@ ...@@ -32,14 +32,14 @@
*/ */
class Doctrine_Query_Having_TestCase extends Doctrine_UnitTestCase { class Doctrine_Query_Having_TestCase extends Doctrine_UnitTestCase {
public function testAggregateFunctionsInHavingReturnValidSql() { public function testAggregateFunctionsInHavingReturnValidSql() {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->parseQuery('SELECT u.name FROM User u LEFT JOIN u.Phonenumber p HAVING COUNT(p.id) > 2'); $q->parseQuery('SELECT u.name FROM User u LEFT JOIN u.Phonenumber p HAVING COUNT(p.id) > 2');
$this->assertEqual($q->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.type = 0) HAVING COUNT(p.id) > 2'); $this->assertEqual($q->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.type = 0) HAVING COUNT(p.id) > 2');
} }
public function testAggregateFunctionsInHavingReturnValidSql2() { public function testAggregateFunctionsInHavingReturnValidSql2() {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->parseQuery("SELECT u.name FROM User u LEFT JOIN u.Phonenumber p HAVING MAX(u.name) = 'zYne'"); $q->parseQuery("SELECT u.name FROM User u LEFT JOIN u.Phonenumber p HAVING MAX(u.name) = 'zYne'");
......
...@@ -39,7 +39,7 @@ class Doctrine_Query_IdentifierQuoting_TestCase extends Doctrine_UnitTestCase { ...@@ -39,7 +39,7 @@ class Doctrine_Query_IdentifierQuoting_TestCase extends Doctrine_UnitTestCase {
public function testQuerySupportsIdentifierQuoting() { public function testQuerySupportsIdentifierQuoting() {
$this->connection->setAttribute(Doctrine::ATTR_QUOTE_IDENTIFIER, true); $this->connection->setAttribute(Doctrine::ATTR_QUOTE_IDENTIFIER, true);
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->parseQuery('SELECT MAX(u.id), MIN(u.name) FROM User u'); $q->parseQuery('SELECT MAX(u.id), MIN(u.name) FROM User u');
...@@ -47,7 +47,7 @@ class Doctrine_Query_IdentifierQuoting_TestCase extends Doctrine_UnitTestCase { ...@@ -47,7 +47,7 @@ class Doctrine_Query_IdentifierQuoting_TestCase extends Doctrine_UnitTestCase {
} }
public function testQuerySupportsIdentifierQuotingWithJoins() { public function testQuerySupportsIdentifierQuotingWithJoins() {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->parseQuery('SELECT u.name FROM User u LEFT JOIN u.Phonenumber p'); $q->parseQuery('SELECT u.name FROM User u LEFT JOIN u.Phonenumber p');
...@@ -55,7 +55,7 @@ class Doctrine_Query_IdentifierQuoting_TestCase extends Doctrine_UnitTestCase { ...@@ -55,7 +55,7 @@ class Doctrine_Query_IdentifierQuoting_TestCase extends Doctrine_UnitTestCase {
} }
public function testLimitSubqueryAlgorithmSupportsIdentifierQuoting() { public function testLimitSubqueryAlgorithmSupportsIdentifierQuoting() {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->parseQuery('SELECT u.name FROM User u INNER JOIN u.Phonenumber p')->limit(5); $q->parseQuery('SELECT u.name FROM User u INNER JOIN u.Phonenumber p')->limit(5);
......
...@@ -38,7 +38,7 @@ class Doctrine_Query_JoinCondition_TestCase extends Doctrine_UnitTestCase ...@@ -38,7 +38,7 @@ class Doctrine_Query_JoinCondition_TestCase extends Doctrine_UnitTestCase
{ } { }
public function testJoinConditionsAreSupportedForOneToManyLeftJoins() public function testJoinConditionsAreSupportedForOneToManyLeftJoins()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->parseQuery("SELECT u.name, p.id FROM User u LEFT JOIN u.Phonenumber p ON p.phonenumber = '123 123'"); $q->parseQuery("SELECT u.name, p.id FROM User u LEFT JOIN u.Phonenumber p ON p.phonenumber = '123 123'");
...@@ -46,7 +46,7 @@ class Doctrine_Query_JoinCondition_TestCase extends Doctrine_UnitTestCase ...@@ -46,7 +46,7 @@ class Doctrine_Query_JoinCondition_TestCase extends Doctrine_UnitTestCase
} }
public function testJoinConditionsAreSupportedForOneToManyInnerJoins() public function testJoinConditionsAreSupportedForOneToManyInnerJoins()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->parseQuery("SELECT u.name, p.id FROM User u INNER JOIN u.Phonenumber p ON p.phonenumber = '123 123'"); $q->parseQuery("SELECT u.name, p.id FROM User u INNER JOIN u.Phonenumber p ON p.phonenumber = '123 123'");
...@@ -54,7 +54,7 @@ class Doctrine_Query_JoinCondition_TestCase extends Doctrine_UnitTestCase ...@@ -54,7 +54,7 @@ class Doctrine_Query_JoinCondition_TestCase extends Doctrine_UnitTestCase
} }
public function testJoinConditionsAreSupportedForManyToManyLeftJoins() public function testJoinConditionsAreSupportedForManyToManyLeftJoins()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->parseQuery("SELECT u.name, g.id FROM User u LEFT JOIN u.Group g ON g.id > 2"); $q->parseQuery("SELECT u.name, g.id FROM User u LEFT JOIN u.Group g ON g.id > 2");
...@@ -62,7 +62,7 @@ class Doctrine_Query_JoinCondition_TestCase extends Doctrine_UnitTestCase ...@@ -62,7 +62,7 @@ class Doctrine_Query_JoinCondition_TestCase extends Doctrine_UnitTestCase
} }
public function testJoinConditionsAreSupportedForManyToManyInnerJoins() public function testJoinConditionsAreSupportedForManyToManyInnerJoins()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->parseQuery("SELECT u.name, g.id FROM User u INNER JOIN u.Group g ON g.id > 2"); $q->parseQuery("SELECT u.name, g.id FROM User u INNER JOIN u.Group g ON g.id > 2");
......
...@@ -58,7 +58,7 @@ class Doctrine_Query_Join_TestCase extends Doctrine_UnitTestCase ...@@ -58,7 +58,7 @@ class Doctrine_Query_Join_TestCase extends Doctrine_UnitTestCase
} }
public function testRecordHydrationWorksWithDeeplyNestedStructures() public function testRecordHydrationWorksWithDeeplyNestedStructures()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->select('c.*, c2.*, d.*') $q->select('c.*, c2.*, d.*')
->from('Record_Country c')->leftJoin('c.City c2')->leftJoin('c2.District d') ->from('Record_Country c')->leftJoin('c.City c2')->leftJoin('c2.District d')
...@@ -77,7 +77,7 @@ class Doctrine_Query_Join_TestCase extends Doctrine_UnitTestCase ...@@ -77,7 +77,7 @@ class Doctrine_Query_Join_TestCase extends Doctrine_UnitTestCase
} }
public function testManyToManyJoinUsesProperTableAliases() public function testManyToManyJoinUsesProperTableAliases()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->select('u.name')->from('User u INNER JOIN u.Group g'); $q->select('u.name')->from('User u INNER JOIN u.Group g');
...@@ -86,7 +86,7 @@ class Doctrine_Query_Join_TestCase extends Doctrine_UnitTestCase ...@@ -86,7 +86,7 @@ class Doctrine_Query_Join_TestCase extends Doctrine_UnitTestCase
public function testSelfReferentialAssociationJoinsAreSupported() public function testSelfReferentialAssociationJoinsAreSupported()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->select('e.name')->from('Entity e INNER JOIN e.Entity e2'); $q->select('e.name')->from('Entity e INNER JOIN e.Entity e2');
......
...@@ -45,7 +45,7 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase ...@@ -45,7 +45,7 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase
public function testLimitWithOneToOneLeftJoin() public function testLimitWithOneToOneLeftJoin()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->select('u.id, e.*')->from('User u, u.Email e')->limit(5); $q->select('u.id, e.*')->from('User u, u.Email e')->limit(5);
$users = $q->execute(); $users = $q->execute();
...@@ -55,7 +55,7 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase ...@@ -55,7 +55,7 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase
} }
public function testLimitWithOneToOneInnerJoin() public function testLimitWithOneToOneInnerJoin()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->select('u.id, e.*')->from('User u, u:Email e')->limit(5); $q->select('u.id, e.*')->from('User u, u:Email e')->limit(5);
$users = $q->execute(); $users = $q->execute();
...@@ -64,7 +64,7 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase ...@@ -64,7 +64,7 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase
} }
public function testLimitWithOneToManyLeftJoin() public function testLimitWithOneToManyLeftJoin()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->select('u.id, p.*')->from('User u, u.Phonenumber p')->limit(5); $q->select('u.id, p.*')->from('User u, u.Phonenumber p')->limit(5);
$sql = $q->getQuery(); $sql = $q->getQuery();
...@@ -91,7 +91,7 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase ...@@ -91,7 +91,7 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase
public function testLimitWithOneToManyLeftJoinAndCondition() public function testLimitWithOneToManyLeftJoinAndCondition()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->select('User.name')->from('User')->where("User.Phonenumber.phonenumber LIKE '%123%'")->limit(5); $q->select('User.name')->from('User')->where("User.Phonenumber.phonenumber LIKE '%123%'")->limit(5);
$users = $q->execute(); $users = $q->execute();
...@@ -111,7 +111,7 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase ...@@ -111,7 +111,7 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase
public function testLimitWithOneToManyLeftJoinAndOrderBy() public function testLimitWithOneToManyLeftJoinAndOrderBy()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->select('User.name')->from('User')->where("User.Phonenumber.phonenumber LIKE '%123%'")->orderby('User.Email.address')->limit(5); $q->select('User.name')->from('User')->where("User.Phonenumber.phonenumber LIKE '%123%'")->orderby('User.Email.address')->limit(5);
...@@ -128,7 +128,7 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase ...@@ -128,7 +128,7 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase
public function testLimitWithOneToManyInnerJoin() public function testLimitWithOneToManyInnerJoin()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->select('u.id, p.*')->from('User u INNER JOIN u.Phonenumber p'); $q->select('u.id, p.*')->from('User u INNER JOIN u.Phonenumber p');
$q->limit(5); $q->limit(5);
...@@ -156,7 +156,7 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase ...@@ -156,7 +156,7 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase
public function testLimitWithPreparedQueries() public function testLimitWithPreparedQueries()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->select('u.id, p.id')->from('User u LEFT JOIN u.Phonenumber p'); $q->select('u.id, p.id')->from('User u LEFT JOIN u.Phonenumber p');
$q->where('u.name = ?'); $q->where('u.name = ?');
$q->limit(5); $q->limit(5);
...@@ -170,7 +170,7 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase ...@@ -170,7 +170,7 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase
$this->assertEqual($q->getQuery(), $this->assertEqual($q->getQuery(),
'SELECT e.id AS e__id, p.id AS p__id FROM entity e LEFT JOIN phonenumber p ON e.id = p.entity_id WHERE e.id IN (SELECT DISTINCT e2.id FROM entity e2 WHERE e2.name = ? AND (e2.type = 0) LIMIT 5) AND e.name = ? AND (e.type = 0)'); 'SELECT e.id AS e__id, p.id AS p__id FROM entity e LEFT JOIN phonenumber p ON e.id = p.entity_id WHERE e.id IN (SELECT DISTINCT e2.id FROM entity e2 WHERE e2.name = ? AND (e2.type = 0) LIMIT 5) AND e.name = ? AND (e.type = 0)');
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->select('u.id, p.id')->from('User u LEFT JOIN u.Phonenumber p'); $q->select('u.id, p.id')->from('User u LEFT JOIN u.Phonenumber p');
$q->where("u.name LIKE ? || u.name LIKE ?"); $q->where("u.name LIKE ? || u.name LIKE ?");
$q->limit(5); $q->limit(5);
...@@ -188,7 +188,7 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase ...@@ -188,7 +188,7 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase
} }
public function testConnectionFlushing() public function testConnectionFlushing()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->from('User.Phonenumber'); $q->from('User.Phonenumber');
$q->where('User.name = ?'); $q->where('User.name = ?');
$q->limit(5); $q->limit(5);
...@@ -200,7 +200,7 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase ...@@ -200,7 +200,7 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase
} }
public function testLimitWithManyToManyColumnAggInheritanceLeftJoin() public function testLimitWithManyToManyColumnAggInheritanceLeftJoin()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->from('User.Group')->limit(5); $q->from('User.Group')->limit(5);
$users = $q->execute(); $users = $q->execute();
...@@ -227,7 +227,7 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase ...@@ -227,7 +227,7 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->from("User")->where("User.Group.id = ?")->orderby("User.id ASC")->limit(5); $q->from("User")->where("User.Group.id = ?")->orderby("User.id ASC")->limit(5);
...@@ -236,7 +236,7 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase ...@@ -236,7 +236,7 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase
$this->assertEqual($users->count(), 3); $this->assertEqual($users->count(), 3);
$this->connection->clear(); $this->connection->clear();
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->from('User')->where('User.Group.id = ?')->orderby('User.id DESC'); $q->from('User')->where('User.Group.id = ?')->orderby('User.id DESC');
$users = $q->execute(array($user->Group[1]->id)); $users = $q->execute(array($user->Group[1]->id));
...@@ -248,7 +248,7 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase ...@@ -248,7 +248,7 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase
$this->manager->setAttribute(Doctrine::ATTR_QUERY_LIMIT, Doctrine::LIMIT_ROWS); $this->manager->setAttribute(Doctrine::ATTR_QUERY_LIMIT, Doctrine::LIMIT_ROWS);
$this->connection->clear(); $this->connection->clear();
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->from("User")->where("User.Group.id = ?")->orderby("User.id DESC")->limit(5); $q->from("User")->where("User.Group.id = ?")->orderby("User.id DESC")->limit(5);
$users = $q->execute(array(3)); $users = $q->execute(array(3));
...@@ -260,7 +260,7 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase ...@@ -260,7 +260,7 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase
public function testLimitWithManyToManyAndColumnAggregationInheritance() public function testLimitWithManyToManyAndColumnAggregationInheritance()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->from('User u, u.Group g')->where('g.id > 1')->orderby('u.name DESC')->limit(10); $q->from('User u, u.Group g')->where('g.id > 1')->orderby('u.name DESC')->limit(10);
} }
...@@ -279,7 +279,7 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase ...@@ -279,7 +279,7 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase
$coll[3]->name = "photo 4"; $coll[3]->name = "photo 4";
$this->connection->flush(); $this->connection->flush();
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->from("Photo")->where("Photo.Tag.id = ?")->orderby("Photo.id DESC")->limit(100); $q->from("Photo")->where("Photo.Tag.id = ?")->orderby("Photo.id DESC")->limit(100);
$photos = $q->execute(array(1)); $photos = $q->execute(array(1));
......
...@@ -34,7 +34,7 @@ class Doctrine_Query_Orderby_TestCase extends Doctrine_UnitTestCase ...@@ -34,7 +34,7 @@ class Doctrine_Query_Orderby_TestCase extends Doctrine_UnitTestCase
{ {
public function testOrderByAggregateValueIsSupported() public function testOrderByAggregateValueIsSupported()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->select('u.name, COUNT(p.phonenumber) count') $q->select('u.name, COUNT(p.phonenumber) count')
->from('User u') ->from('User u')
...@@ -45,7 +45,7 @@ class Doctrine_Query_Orderby_TestCase extends Doctrine_UnitTestCase ...@@ -45,7 +45,7 @@ class Doctrine_Query_Orderby_TestCase extends Doctrine_UnitTestCase
} }
public function testOrderByRandomIsSupported() public function testOrderByRandomIsSupported()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->select('u.name, RANDOM() rand') $q->select('u.name, RANDOM() rand')
->from('User u') ->from('User u')
......
...@@ -34,7 +34,7 @@ class Doctrine_Query_Select_TestCase extends Doctrine_UnitTestCase ...@@ -34,7 +34,7 @@ class Doctrine_Query_Select_TestCase extends Doctrine_UnitTestCase
{ {
public function testAggregateFunctionWithDistinctKeyword() public function testAggregateFunctionWithDistinctKeyword()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->parseQuery('SELECT COUNT(DISTINCT u.name) FROM User u'); $q->parseQuery('SELECT COUNT(DISTINCT u.name) FROM User u');
...@@ -43,7 +43,7 @@ class Doctrine_Query_Select_TestCase extends Doctrine_UnitTestCase ...@@ -43,7 +43,7 @@ class Doctrine_Query_Select_TestCase extends Doctrine_UnitTestCase
public function testAggregateFunction() public function testAggregateFunction()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->parseQuery('SELECT COUNT(u.id) FROM User u'); $q->parseQuery('SELECT COUNT(u.id) FROM User u');
...@@ -52,7 +52,7 @@ class Doctrine_Query_Select_TestCase extends Doctrine_UnitTestCase ...@@ -52,7 +52,7 @@ class Doctrine_Query_Select_TestCase extends Doctrine_UnitTestCase
public function testSelectPartSupportsMultipleAggregateFunctions() public function testSelectPartSupportsMultipleAggregateFunctions()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->parseQuery('SELECT MAX(u.id), MIN(u.name) FROM User u'); $q->parseQuery('SELECT MAX(u.id), MIN(u.name) FROM User u');
...@@ -60,7 +60,7 @@ class Doctrine_Query_Select_TestCase extends Doctrine_UnitTestCase ...@@ -60,7 +60,7 @@ class Doctrine_Query_Select_TestCase extends Doctrine_UnitTestCase
} }
public function testMultipleAggregateFunctionsWithMultipleComponents() public function testMultipleAggregateFunctionsWithMultipleComponents()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->parseQuery('SELECT MAX(u.id), MIN(u.name), COUNT(p.id) FROM User u, u.Phonenumber p'); $q->parseQuery('SELECT MAX(u.id), MIN(u.name), COUNT(p.id) FROM User u, u.Phonenumber p');
...@@ -68,7 +68,7 @@ class Doctrine_Query_Select_TestCase extends Doctrine_UnitTestCase ...@@ -68,7 +68,7 @@ class Doctrine_Query_Select_TestCase extends Doctrine_UnitTestCase
} }
public function testEmptySelectPart() public function testEmptySelectPart()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
try { try {
$q->select(null); $q->select(null);
...@@ -80,7 +80,7 @@ class Doctrine_Query_Select_TestCase extends Doctrine_UnitTestCase ...@@ -80,7 +80,7 @@ class Doctrine_Query_Select_TestCase extends Doctrine_UnitTestCase
} }
public function testUnknownAggregateFunction() public function testUnknownAggregateFunction()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
try { try {
$q->parseQuery('SELECT UNKNOWN(u.id) FROM User'); $q->parseQuery('SELECT UNKNOWN(u.id) FROM User');
...@@ -91,7 +91,7 @@ class Doctrine_Query_Select_TestCase extends Doctrine_UnitTestCase ...@@ -91,7 +91,7 @@ class Doctrine_Query_Select_TestCase extends Doctrine_UnitTestCase
} }
public function testAggregateFunctionValueHydration() public function testAggregateFunctionValueHydration()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->parseQuery('SELECT u.id, COUNT(p.id) FROM User u, u.Phonenumber p GROUP BY u.id'); $q->parseQuery('SELECT u.id, COUNT(p.id) FROM User u, u.Phonenumber p GROUP BY u.id');
...@@ -107,7 +107,7 @@ class Doctrine_Query_Select_TestCase extends Doctrine_UnitTestCase ...@@ -107,7 +107,7 @@ class Doctrine_Query_Select_TestCase extends Doctrine_UnitTestCase
public function testSingleComponentWithAsterisk() public function testSingleComponentWithAsterisk()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->parseQuery('SELECT u.* FROM User u'); $q->parseQuery('SELECT u.* FROM User u');
...@@ -115,7 +115,7 @@ class Doctrine_Query_Select_TestCase extends Doctrine_UnitTestCase ...@@ -115,7 +115,7 @@ class Doctrine_Query_Select_TestCase extends Doctrine_UnitTestCase
} }
public function testSingleComponentWithMultipleColumns() public function testSingleComponentWithMultipleColumns()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->parseQuery('SELECT u.name, u.type FROM User u'); $q->parseQuery('SELECT u.name, u.type FROM User u');
...@@ -123,7 +123,7 @@ class Doctrine_Query_Select_TestCase extends Doctrine_UnitTestCase ...@@ -123,7 +123,7 @@ class Doctrine_Query_Select_TestCase extends Doctrine_UnitTestCase
} }
public function testMultipleComponentsWithAsterisk() public function testMultipleComponentsWithAsterisk()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->parseQuery('SELECT u.*, p.* FROM User u, u.Phonenumber p'); $q->parseQuery('SELECT u.*, p.* FROM User u, u.Phonenumber p');
...@@ -131,7 +131,7 @@ class Doctrine_Query_Select_TestCase extends Doctrine_UnitTestCase ...@@ -131,7 +131,7 @@ class Doctrine_Query_Select_TestCase extends Doctrine_UnitTestCase
} }
public function testMultipleComponentsWithMultipleColumns() public function testMultipleComponentsWithMultipleColumns()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->parseQuery('SELECT u.id, u.name, p.id FROM User u, u.Phonenumber p'); $q->parseQuery('SELECT u.id, u.name, p.id FROM User u, u.Phonenumber p');
...@@ -140,7 +140,7 @@ class Doctrine_Query_Select_TestCase extends Doctrine_UnitTestCase ...@@ -140,7 +140,7 @@ class Doctrine_Query_Select_TestCase extends Doctrine_UnitTestCase
public function testAggregateFunctionValueHydrationWithAliases() public function testAggregateFunctionValueHydrationWithAliases()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->parseQuery('SELECT u.id, COUNT(p.id) count FROM User u, u.Phonenumber p GROUP BY u.id'); $q->parseQuery('SELECT u.id, COUNT(p.id) count FROM User u, u.Phonenumber p GROUP BY u.id');
...@@ -154,7 +154,7 @@ class Doctrine_Query_Select_TestCase extends Doctrine_UnitTestCase ...@@ -154,7 +154,7 @@ class Doctrine_Query_Select_TestCase extends Doctrine_UnitTestCase
} }
public function testMultipleAggregateFunctionValueHydrationWithAliases() public function testMultipleAggregateFunctionValueHydrationWithAliases()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->parseQuery('SELECT u.id, COUNT(p.id) count, MAX(p.phonenumber) max FROM User u, u.Phonenumber p GROUP BY u.id'); $q->parseQuery('SELECT u.id, COUNT(p.id) count, MAX(p.phonenumber) max FROM User u, u.Phonenumber p GROUP BY u.id');
...@@ -175,7 +175,7 @@ class Doctrine_Query_Select_TestCase extends Doctrine_UnitTestCase ...@@ -175,7 +175,7 @@ class Doctrine_Query_Select_TestCase extends Doctrine_UnitTestCase
{ {
$this->connection->clear(); $this->connection->clear();
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->parseQuery('SELECT u.id, COUNT(p.id) count, MAX(p.phonenumber) max FROM User u, u.Phonenumber p GROUP BY u.id'); $q->parseQuery('SELECT u.id, COUNT(p.id) count, MAX(p.phonenumber) max FROM User u, u.Phonenumber p GROUP BY u.id');
......
...@@ -36,7 +36,7 @@ class Doctrine_Query_Subquery_TestCase extends Doctrine_UnitTestCase ...@@ -36,7 +36,7 @@ class Doctrine_Query_Subquery_TestCase extends Doctrine_UnitTestCase
public function testSubqueryWithWherePartAndInExpression() public function testSubqueryWithWherePartAndInExpression()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->from('User')->where("User.id NOT IN (SELECT User.id FROM User WHERE User.name = 'zYne')"); $q->from('User')->where("User.id NOT IN (SELECT User.id FROM User WHERE User.name = 'zYne')");
$this->assertEqual($q->getQuery(), $this->assertEqual($q->getQuery(),
...@@ -49,7 +49,7 @@ class Doctrine_Query_Subquery_TestCase extends Doctrine_UnitTestCase ...@@ -49,7 +49,7 @@ class Doctrine_Query_Subquery_TestCase extends Doctrine_UnitTestCase
} }
public function testSubqueryAllowsSelectingOfAnyField() public function testSubqueryAllowsSelectingOfAnyField()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->from('User u')->where('u.id NOT IN (SELECT g.user_id FROM Groupuser g)'); $q->from('User u')->where('u.id NOT IN (SELECT g.user_id FROM Groupuser g)');
$this->assertEqual($q->getQuery(), "SELECT e.id AS e__id, e.name AS e__name, e.loginname AS e__loginname, e.password AS e__password, e.type AS e__type, e.created AS e__created, e.updated AS e__updated, e.email_id AS e__email_id FROM entity e WHERE e.id NOT IN (SELECT g.user_id AS g__user_id FROM groupuser g) AND (e.type = 0)"); $this->assertEqual($q->getQuery(), "SELECT e.id AS e__id, e.name AS e__name, e.loginname AS e__loginname, e.password AS e__password, e.type AS e__type, e.created AS e__created, e.updated AS e__updated, e.email_id AS e__email_id FROM entity e WHERE e.id NOT IN (SELECT g.user_id AS g__user_id FROM groupuser g) AND (e.type = 0)");
...@@ -58,7 +58,7 @@ class Doctrine_Query_Subquery_TestCase extends Doctrine_UnitTestCase ...@@ -58,7 +58,7 @@ class Doctrine_Query_Subquery_TestCase extends Doctrine_UnitTestCase
public function testSubqueryInSelectPart() public function testSubqueryInSelectPart()
{ {
// ticket #307 // ticket #307
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->parseQuery("SELECT u.name, (SELECT COUNT(p.id) FROM Phonenumber p WHERE p.entity_id = u.id) pcount FROM User u WHERE u.name = 'zYne' LIMIT 1"); $q->parseQuery("SELECT u.name, (SELECT COUNT(p.id) FROM Phonenumber p WHERE p.entity_id = u.id) pcount FROM User u WHERE u.name = 'zYne' LIMIT 1");
...@@ -77,7 +77,7 @@ class Doctrine_Query_Subquery_TestCase extends Doctrine_UnitTestCase ...@@ -77,7 +77,7 @@ class Doctrine_Query_Subquery_TestCase extends Doctrine_UnitTestCase
public function testSubqueryInSelectPart2() public function testSubqueryInSelectPart2()
{ {
// ticket #307 // ticket #307
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->parseQuery("SELECT u.name, (SELECT COUNT(w.id) FROM User w WHERE w.id = u.id) pcount FROM User u WHERE u.name = 'zYne' LIMIT 1"); $q->parseQuery("SELECT u.name, (SELECT COUNT(w.id) FROM User w WHERE w.id = u.id) pcount FROM User u WHERE u.name = 'zYne' LIMIT 1");
......
...@@ -35,13 +35,13 @@ class Doctrine_Query_Update_TestCase extends Doctrine_UnitTestCase ...@@ -35,13 +35,13 @@ class Doctrine_Query_Update_TestCase extends Doctrine_UnitTestCase
{ {
public function testUpdateAllWithColumnAggregationInheritance() public function testUpdateAllWithColumnAggregationInheritance()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->parseQuery("UPDATE User u SET u.name = 'someone'"); $q->parseQuery("UPDATE User u SET u.name = 'someone'");
$this->assertEqual($q->getQuery(), "UPDATE entity SET name = 'someone' WHERE (type = 0)"); $this->assertEqual($q->getQuery(), "UPDATE entity SET name = 'someone' WHERE (type = 0)");
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->update('User u')->set('u.name', "'someone'"); $q->update('User u')->set('u.name', "'someone'");
...@@ -49,13 +49,13 @@ class Doctrine_Query_Update_TestCase extends Doctrine_UnitTestCase ...@@ -49,13 +49,13 @@ class Doctrine_Query_Update_TestCase extends Doctrine_UnitTestCase
} }
public function testUpdateWorksWithMultipleColumns() public function testUpdateWorksWithMultipleColumns()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->parseQuery("UPDATE User u SET u.name = 'someone', u.email_id = 5"); $q->parseQuery("UPDATE User u SET u.name = 'someone', u.email_id = 5");
$this->assertEqual($q->getQuery(), "UPDATE entity SET name = 'someone', email_id = 5 WHERE (type = 0)"); $this->assertEqual($q->getQuery(), "UPDATE entity SET name = 'someone', email_id = 5 WHERE (type = 0)");
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->update('User u')->set('u.name', "'someone'")->set('u.email_id', 5); $q->update('User u')->set('u.name', "'someone'")->set('u.email_id', 5);
...@@ -63,7 +63,7 @@ class Doctrine_Query_Update_TestCase extends Doctrine_UnitTestCase ...@@ -63,7 +63,7 @@ class Doctrine_Query_Update_TestCase extends Doctrine_UnitTestCase
} }
public function testUpdateSupportsConditions() public function testUpdateSupportsConditions()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->parseQuery("UPDATE User u SET u.name = 'someone' WHERE u.id = 5"); $q->parseQuery("UPDATE User u SET u.name = 'someone' WHERE u.id = 5");
......
...@@ -47,7 +47,7 @@ class Doctrine_Query_Where_TestCase extends Doctrine_UnitTestCase ...@@ -47,7 +47,7 @@ class Doctrine_Query_Where_TestCase extends Doctrine_UnitTestCase
$user->name = 'someone'; $user->name = 'someone';
$user->save(); $user->save();
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->from('User')->addWhere('User.id = ?',1); $q->from('User')->addWhere('User.id = ?',1);
...@@ -63,7 +63,7 @@ class Doctrine_Query_Where_TestCase extends Doctrine_UnitTestCase ...@@ -63,7 +63,7 @@ class Doctrine_Query_Where_TestCase extends Doctrine_UnitTestCase
$user->name = 'someone.2'; $user->name = 'someone.2';
$user->save(); $user->save();
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->from('User')->addWhere('User.id IN (?, ?)', array(1, 2)); $q->from('User')->addWhere('User.id IN (?, ?)', array(1, 2));
...@@ -75,7 +75,7 @@ class Doctrine_Query_Where_TestCase extends Doctrine_UnitTestCase ...@@ -75,7 +75,7 @@ class Doctrine_Query_Where_TestCase extends Doctrine_UnitTestCase
} }
public function testDirectMultipleParameterSetting2() public function testDirectMultipleParameterSetting2()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->from('User')->where('User.id IN (?, ?)', array(1, 2)); $q->from('User')->where('User.id IN (?, ?)', array(1, 2));
...@@ -98,7 +98,7 @@ class Doctrine_Query_Where_TestCase extends Doctrine_UnitTestCase ...@@ -98,7 +98,7 @@ class Doctrine_Query_Where_TestCase extends Doctrine_UnitTestCase
} }
public function testNotInExpression() public function testNotInExpression()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->from('User u')->addWhere('u.id NOT IN (?)', array(1)); $q->from('User u')->addWhere('u.id NOT IN (?)', array(1));
$users = $q->execute(); $users = $q->execute();
...@@ -108,7 +108,7 @@ class Doctrine_Query_Where_TestCase extends Doctrine_UnitTestCase ...@@ -108,7 +108,7 @@ class Doctrine_Query_Where_TestCase extends Doctrine_UnitTestCase
} }
public function testExistsExpression() public function testExistsExpression()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$user = new User(); $user = new User();
$user->name = 'someone with a group'; $user->name = 'someone with a group';
...@@ -129,7 +129,7 @@ class Doctrine_Query_Where_TestCase extends Doctrine_UnitTestCase ...@@ -129,7 +129,7 @@ class Doctrine_Query_Where_TestCase extends Doctrine_UnitTestCase
public function testNotExistsExpression() public function testNotExistsExpression()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
// find all users which don't have groups // find all users which don't have groups
try { try {
...@@ -145,7 +145,7 @@ class Doctrine_Query_Where_TestCase extends Doctrine_UnitTestCase ...@@ -145,7 +145,7 @@ class Doctrine_Query_Where_TestCase extends Doctrine_UnitTestCase
} }
public function testComponentAliases() public function testComponentAliases()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->from('User u')->addWhere('u.id IN (?, ?)', array(1,2)); $q->from('User u')->addWhere('u.id IN (?, ?)', array(1,2));
...@@ -158,7 +158,7 @@ class Doctrine_Query_Where_TestCase extends Doctrine_UnitTestCase ...@@ -158,7 +158,7 @@ class Doctrine_Query_Where_TestCase extends Doctrine_UnitTestCase
} }
public function testComponentAliases2() public function testComponentAliases2()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->from('User u')->addWhere('u.name = ?', array('someone')); $q->from('User u')->addWhere('u.name = ?', array('someone'));
...@@ -169,7 +169,7 @@ class Doctrine_Query_Where_TestCase extends Doctrine_UnitTestCase ...@@ -169,7 +169,7 @@ class Doctrine_Query_Where_TestCase extends Doctrine_UnitTestCase
} }
public function testOperatorWithNoTrailingSpaces() public function testOperatorWithNoTrailingSpaces()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->select('User.id')->from('User')->where("User.name='someone'"); $q->select('User.id')->from('User')->where("User.name='someone'");
...@@ -180,7 +180,7 @@ class Doctrine_Query_Where_TestCase extends Doctrine_UnitTestCase ...@@ -180,7 +180,7 @@ class Doctrine_Query_Where_TestCase extends Doctrine_UnitTestCase
} }
public function testOperatorWithNoTrailingSpaces2() public function testOperatorWithNoTrailingSpaces2()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->select('User.id')->from('User')->where("User.name='foo.bar'"); $q->select('User.id')->from('User')->where("User.name='foo.bar'");
...@@ -191,7 +191,7 @@ class Doctrine_Query_Where_TestCase extends Doctrine_UnitTestCase ...@@ -191,7 +191,7 @@ class Doctrine_Query_Where_TestCase extends Doctrine_UnitTestCase
} }
public function testOperatorWithSingleTrailingSpace() public function testOperatorWithSingleTrailingSpace()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->select('User.id')->from('User')->where("User.name= 'foo.bar'"); $q->select('User.id')->from('User')->where("User.name= 'foo.bar'");
...@@ -202,7 +202,7 @@ class Doctrine_Query_Where_TestCase extends Doctrine_UnitTestCase ...@@ -202,7 +202,7 @@ class Doctrine_Query_Where_TestCase extends Doctrine_UnitTestCase
} }
public function testOperatorWithSingleTrailingSpace2() public function testOperatorWithSingleTrailingSpace2()
{ {
$q = new Doctrine_Query2(); $q = new Doctrine_Query();
$q->select('User.id')->from('User')->where("User.name ='foo.bar'"); $q->select('User.id')->from('User')->where("User.name ='foo.bar'");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment