From f571c61ecf505e6e32507f37061c47c88ecdf65b Mon Sep 17 00:00:00 2001 From: zYne Date: Tue, 26 Dec 2006 20:33:40 +0000 Subject: [PATCH] --- lib/Doctrine/Hook.php | 89 +++++++++++++++++++++--------------------- lib/Doctrine/Query.php | 21 ++++++++-- tests/HookTestCase.php | 44 ++++++++++++++++++++- 3 files changed, 104 insertions(+), 50 deletions(-) diff --git a/lib/Doctrine/Hook.php b/lib/Doctrine/Hook.php index 7ed9e72dc..bdc479410 100644 --- a/lib/Doctrine/Hook.php +++ b/lib/Doctrine/Hook.php @@ -77,38 +77,6 @@ class Doctrine_Hook { $this->query = $query; } } - public function buildQuery() { - $where = array(); - $from = array(); - $params = array(); - - - $component = $this->table->getComponentName(); - - $data = self::makeFlat($this->where); - - foreach($data as $k => $v) { - if(trim($v) == '') { - unset($data[$k]); - } - } - - $orderby = array(); - - if(isset($this->hooks['orderby'])) { - $e = explode(" ",$this->hooks['orderby']); - - $orderComponent = $e[0]; - - if(in_array($orderComponent, $this->fields)) { - if(isset($e[1]) && ($e[1] == "ASC" || $e[1] == "DESC")) { - $orderby[] = $component.".".$e[0]." ".$e[1]; - } - } - - } - - } public function getQuery() { return $this->query; } @@ -120,19 +88,25 @@ class Doctrine_Hook { } /** * hookWhere + * builds DQL query where part from given parameter array * - * @param array $params an array of query where parameters + * @param array $params an associative array containing field + * names and their values + * @return boolean whether or not the hooking was */ - public function hookWhere(array $params) { + public function hookWhere($params) { + if( ! is_array($params)) + return false; + foreach($params as $name => $value) { $e = explode('.', $name); - + if(count($e) == 2) { list($alias, $column) = $e; $tableAlias = $this->query->getTableAlias($alias); $table = $this->query->getTable($tableAlias); - + if($def = $table->getDefinitionOf($column)) { if(isset($this->typeParsers[$def[0]])) { @@ -148,29 +122,54 @@ class Doctrine_Hook { } } $this->params += $params; + + return true; } /** - * @param integer $limit + * hookOrderBy + * builds DQL query orderby part from given parameter array + * + * @param array $params an array containing all fields which the built query + * should be ordered by + * @return boolean whether or not the hooking was */ public function hookOrderby($params) { + if( ! is_array($params)) + return false; + foreach($params as $name) { + $e = explode(' ', $name); + + $order = 'ASC'; + + if(count($e) > 1) { + $order = ($e[1] == 'DESC') ? 'DESC' : 'ASC'; + } + + $e = explode('.', $e[0]); + + if(count($e) == 2) { + list($alias, $column) = $e; + + $tableAlias = $this->query->getTableAlias($alias); + $table = $this->query->getTable($tableAlias); + + if($def = $table->getDefinitionOf($column)) { + $this->query->addOrderBy($alias . '.' . $column . ' ' . $order); + } + } + } } /** * @param integer $limit */ public function hookLimit($limit) { - + $this->query->limit((int) $limit); } /** * @param integer $offset */ public function hookOffset($offset) { - - } - public function setWhereHooks() { - - } - public function setOrderByHooks() { - + $this->query->offset((int) $offset); } } diff --git a/lib/Doctrine/Query.php b/lib/Doctrine/Query.php index 11aa35826..99449c165 100644 --- a/lib/Doctrine/Query.php +++ b/lib/Doctrine/Query.php @@ -318,6 +318,19 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { return $this; } + /** + * addOrderBy + * + * @param strint $orderby + * @return Doctrine_Query + */ + public function addOrderBy($orderby) { + $class = 'Doctrine_Query_Orderby'; + $parser = new $class($this); + $this->parts['orderby'][] = $parser->parse($orderby); + + return $this; + } /** * addWhere * @@ -555,8 +568,8 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { $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['having']))? ' HAVING ' . implode(' ', $this->parts['having']):''; - $q .= ( ! empty($this->parts['orderby']))? ' ORDER BY ' . implode(' ', $this->parts['orderby']):''; + $q .= ( ! empty($this->parts['having']))? ' HAVING ' . implode(' AND ', $this->parts['having']):''; + $q .= ( ! empty($this->parts['orderby']))? ' ORDER BY ' . implode(', ', $this->parts['orderby']):''; if($modifyLimit) $q = $this->conn->modifyLimitQuery($q, $this->parts['limit'], $this->parts['offset']); @@ -624,8 +637,8 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { // all conditions must be preserved in subquery $subquery .= ( ! empty($this->parts['where']))? ' WHERE ' . implode(' AND ',$this->parts['where']):''; $subquery .= ( ! empty($this->parts['groupby']))? ' GROUP BY ' . implode(', ',$this->parts['groupby']):''; - $subquery .= ( ! empty($this->parts['having']))? ' HAVING ' . implode(' ',$this->parts['having']):''; - $subquery .= ( ! empty($this->parts['orderby']))? ' ORDER BY ' . implode(' ', $this->parts['orderby']):''; + $subquery .= ( ! empty($this->parts['having']))? ' HAVING ' . implode(' AND ',$this->parts['having']):''; + $subquery .= ( ! empty($this->parts['orderby']))? ' ORDER BY ' . implode(', ', $this->parts['orderby']):''; // add driver specific limit clause $subquery = $this->conn->modifyLimitQuery($subquery, $this->parts['limit'], $this->parts['offset']); diff --git a/tests/HookTestCase.php b/tests/HookTestCase.php index f8ee0b9a9..c36344678 100644 --- a/tests/HookTestCase.php +++ b/tests/HookTestCase.php @@ -1,6 +1,39 @@ hookOrderBy($a['orderby']); + $this->assertEqual($hook->getQuery()->getQuery(), 'SELECT e.id AS e__id, e.name AS e__name FROM entity e LEFT JOIN phonenumber p ON e.id = p.entity_id WHERE (e.type = 0) ORDER BY e.name ASC'); + } + public function testHookOrderbyAcceptsDescendingOrder() { + $hook = new Doctrine_Hook('SELECT u.name FROM User u LEFT JOIN u.Phonenumber p'); + + $a['orderby'] = array('u.name DESC'); + + $hook->hookOrderBy($a['orderby']); + $this->assertEqual($hook->getQuery()->getQuery(), 'SELECT e.id AS e__id, e.name AS e__name FROM entity e LEFT JOIN phonenumber p ON e.id = p.entity_id WHERE (e.type = 0) ORDER BY e.name DESC'); + } + public function testHookOrderbyDoesntAcceptUnknownColumn() { + $hook = new Doctrine_Hook('SELECT u.name FROM User u LEFT JOIN u.Phonenumber p'); + + $a['orderby'] = array('u.unknown DESC'); + + $hook->hookOrderBy($a['orderby']); + $this->assertEqual($hook->getQuery()->getQuery(), 'SELECT e.id AS e__id, e.name AS e__name FROM entity e LEFT JOIN phonenumber p ON e.id = p.entity_id WHERE (e.type = 0)'); + } + public function testHookOrderbyAcceptsMultipleParameters() { + $hook = new Doctrine_Hook('SELECT u.name FROM User u LEFT JOIN u.Phonenumber p'); + + $a['orderby'] = array('u.name ASC', 'u.id DESC'); + + $hook->hookOrderBy($a['orderby']); + $this->assertEqual($hook->getQuery()->getQuery(), 'SELECT e.id AS e__id, e.name AS e__name FROM entity e LEFT JOIN phonenumber p ON e.id = p.entity_id WHERE (e.type = 0) ORDER BY e.name ASC, e.id DESC'); + + $users = $hook->getQuery()->execute(); + } public function testHookWhereAcceptsArrays() { $hook = new Doctrine_Hook('SELECT u.name FROM User u LEFT JOIN u.Phonenumber p'); @@ -9,7 +42,16 @@ class Doctrine_Hook_TestCase extends Doctrine_UnitTestCase { $hook->hookWhere($a['where']); $this->assertEqual($hook->getQuery()->getQuery(), 'SELECT e.id AS e__id, e.name AS e__name FROM entity e LEFT JOIN phonenumber p ON e.id = p.entity_id WHERE (e.name LIKE ? OR e.name LIKE ?) AND e.loginname LIKE ? AND (e.type = 0)'); - + + } + public function testHookWhereDoesntAcceptUnknownColumn() { + $hook = new Doctrine_Hook('SELECT u.name FROM User u LEFT JOIN u.Phonenumber p'); + + $a['where'] = array('u.unknown' => 'Jack Daniels'); + + $hook->hookWhere($a['where']); + $this->assertEqual($hook->getQuery()->getQuery(), 'SELECT e.id AS e__id, e.name AS e__name FROM entity e LEFT JOIN phonenumber p ON e.id = p.entity_id WHERE (e.type = 0)'); + } public function testEqualParserUsesEqualOperator() { $parser = new Doctrine_Hook_Equal();