From 480cb5ac68b320d23156d6480810365fffdb28b1 Mon Sep 17 00:00:00 2001 From: zYne Date: Thu, 28 Dec 2006 11:56:24 +0000 Subject: [PATCH] better expression support --- lib/Doctrine/Lib.php | 26 +++++++------- lib/Doctrine/Query.php | 64 +++++++++++++++++++++++++---------- lib/Doctrine/Query/Having.php | 10 +++--- lib/Doctrine/Query/Where.php | 9 +++-- 4 files changed, 71 insertions(+), 38 deletions(-) diff --git a/lib/Doctrine/Lib.php b/lib/Doctrine/Lib.php index c77654921..a49362199 100644 --- a/lib/Doctrine/Lib.php +++ b/lib/Doctrine/Lib.php @@ -137,19 +137,19 @@ class Doctrine_Lib { $e = explode("\n",$sql); $color = "367FAC"; $l = $sql; - $l = str_replace("SELECT","SELECT
",$l); - $l = str_replace("FROM","FROM
",$l); - $l = str_replace("LEFT JOIN","
LEFT JOIN",$l); - $l = str_replace("INNER JOIN","
INNER JOIN",$l); - $l = str_replace("WHERE","
WHERE",$l); - $l = str_replace("GROUP BY","
GROUP BY",$l); - $l = str_replace("HAVING","
HAVING",$l); - $l = str_replace("AS","AS
",$l); - $l = str_replace("ON","ON",$l); - $l = str_replace("ORDER BY","ORDER BY
",$l); - $l = str_replace("LIMIT","LIMIT
",$l); - $l = str_replace("OFFSET","OFFSET
",$l); - $l = str_replace(" ","
",$l); + $l = str_replace("SELECT ", "SELECT
",$l); + $l = str_replace("FROM ", "FROM
",$l); + $l = str_replace(" LEFT JOIN ", "
LEFT JOIN ",$l); + $l = str_replace(" INNER JOIN ", "
INNER JOIN ",$l); + $l = str_replace(" WHERE ", "
WHERE ",$l); + $l = str_replace(" GROUP BY ", "
GROUP BY ",$l); + $l = str_replace(" HAVING ", "
HAVING ",$l); + $l = str_replace(" AS ", " AS
",$l); + $l = str_replace(" ON ", " ON ",$l); + $l = str_replace(" ORDER BY ", " ORDER BY
",$l); + $l = str_replace(" LIMIT ", " LIMIT
",$l); + $l = str_replace(" OFFSET ", " OFFSET
",$l); + $l = str_replace(" ", "
",$l); return $l; } diff --git a/lib/Doctrine/Query.php b/lib/Doctrine/Query.php index 99449c165..c5b33a4c7 100644 --- a/lib/Doctrine/Query.php +++ b/lib/Doctrine/Query.php @@ -144,31 +144,40 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { $pos = strpos($func, '('); $name = substr($func, 0, $pos); - switch($name) { - case 'MAX': - case 'MIN': - case 'COUNT': - case 'AVG': - case 'SUM': - $reference = substr($func, ($pos + 1), -1); - $e2 = explode(' ', $reference); + + + if(method_exists($this->conn->expression, $name)) { + + $argStr = substr($func, ($pos + 1), -1); + $args = explode(',', $argStr); + + $e2 = explode(' ', $args[0]); + $distinct = ''; if(count($e2) > 1) { if(strtoupper($e2[0]) == 'DISTINCT') $distinct = 'DISTINCT '; - - $reference = $e2[1]; + + $args[0] = $e2[1]; } + - $parts = explode('.', $reference); + $parts = explode('.', $args[0]); + $owner = $parts[0]; $alias = (isset($e[1])) ? $e[1] : $name; - $this->pendingAggregates[$parts[0]][] = array($name, $parts[1], $distinct, $alias); - break; - default: - throw new Doctrine_Query_Exception('Unknown aggregate function '.$name); + $e3 = explode('.', $alias); + + if(count($e3) > 1) { + $alias = $e3[1]; + $owner = $e3[0]; + } + + $this->pendingAggregates[$owner][] = array($name, $args, $distinct, $alias); + } else { + throw new Doctrine_Query_Exception('Unknown aggregate function '.$name); } } public function processPendingAggregates($componentAlias) { @@ -179,10 +188,29 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { $table = $this->tables[$tableAlias]; - foreach($this->pendingAggregates[$componentAlias] as $args) { - list($name, $arg, $distinct, $alias) = $args; + foreach($this->pendingAggregates[$componentAlias] as $parts) { + list($name, $args, $distinct, $alias) = $parts; + + $arglist = array(); + foreach($args as $arg) { + $e = explode('.', $arg); - $this->parts["select"][] = $name . '(' . $distinct . $tableAlias . '.' . $arg . ') AS ' . $tableAlias . '__' . count($this->aggregateMap); + + if(count($e) > 1) { + $tableAlias = $this->getTableAlias($e[0]); + $table = $this->tables[$tableAlias]; + + if( ! $table->hasColumn($e[1])) { + throw new Doctrine_Query_Exception('Unknown column ' . $e[1]); + } + + $arglist[] = $tableAlias . '.' . $e[1]; + } else { + $arglist[] = $e[0]; + } + } + + $this->parts['select'][] = $name . '(' . $distinct . implode(', ', $arglist) . ') AS ' . $tableAlias . '__' . count($this->aggregateMap); $this->aggregateMap[] = $table; } diff --git a/lib/Doctrine/Query/Having.php b/lib/Doctrine/Query/Having.php index 4ab4e08f7..989d0cbbd 100644 --- a/lib/Doctrine/Query/Having.php +++ b/lib/Doctrine/Query/Having.php @@ -49,16 +49,16 @@ class Doctrine_Query_Having extends Doctrine_Query_Condition { * @return string */ final public function load($having) { - $e = Doctrine_Query::bracketExplode($having," ","(",")"); + $e = Doctrine_Query::bracketExplode($having, ' ', '(', ')'); $r = array_shift($e); - $t = explode("(",$r); + $t = explode('(', $r); $count = count($t); $r = $this->parseAggregateFunction($r); $operator = array_shift($e); - $value = implode(" ",$e); - $r .= " ".$operator." ".$value; + $value = implode(' ', $e); + $r .= ' ' . $operator . ' ' . $value; return $r; } @@ -68,7 +68,7 @@ class Doctrine_Query_Having extends Doctrine_Query_Condition { * @return string */ public function __toString() { - return ( ! empty($this->parts))?implode(" AND ", $this->parts):''; + return ( ! empty($this->parts))?implode(' AND ', $this->parts):''; } } diff --git a/lib/Doctrine/Query/Where.php b/lib/Doctrine/Query/Where.php index cd448ddb1..05579dc61 100644 --- a/lib/Doctrine/Query/Where.php +++ b/lib/Doctrine/Query/Where.php @@ -42,7 +42,7 @@ class Doctrine_Query_Where extends Doctrine_Query_Condition { - $pos = strpos($field, "("); + $pos = strpos($field, '('); if($pos !== false) { $func = substr($field, 0, $pos); @@ -209,7 +209,12 @@ class Doctrine_Query_Where extends Doctrine_Query_Condition { } return $operator; } - + /** + * __toString + * return string representation of this object + * + * @return string + */ public function __toString() { return ( ! empty($this->parts))?implode(' AND ', $this->parts):''; }