Refactored DQL classes
This commit is contained in:
parent
4cd29eaf2c
commit
b014566eb8
@ -392,6 +392,8 @@ abstract class Doctrine_Hydrate extends Doctrine_Access {
|
||||
$alias = $this->getPathAlias($path);
|
||||
|
||||
//print_r($this->pendingAggregates);
|
||||
|
||||
// map each aggregate value
|
||||
foreach($row as $index => $value) {
|
||||
$agg = false;
|
||||
|
||||
|
@ -384,7 +384,7 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
|
||||
$this->parts[$name] = array($this->$method($value));
|
||||
break;
|
||||
case "limit":
|
||||
case "offset":
|
||||
case "offset":
|
||||
if($value == null)
|
||||
$value = false;
|
||||
|
||||
@ -458,10 +458,8 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
|
||||
if($this->isDistinct())
|
||||
$str = 'DISTINCT ';
|
||||
|
||||
|
||||
|
||||
$q = "SELECT ".$str.implode(", ",$this->parts["select"]).
|
||||
" FROM ";
|
||||
$q = 'SELECT '.$str.implode(", ",$this->parts["select"]).
|
||||
' FROM ';
|
||||
$q = $this->getQueryBase();
|
||||
|
||||
foreach($this->parts["from"] as $tname => $bool) {
|
||||
@ -469,31 +467,10 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
|
||||
}
|
||||
$q .= implode(", ",$a);
|
||||
|
||||
if($needsSubQuery)
|
||||
$subquery = 'SELECT DISTINCT ' . $table->getTableName()
|
||||
. '.' . $table->getIdentifier()
|
||||
. ' FROM '.$table->getTableName();
|
||||
|
||||
|
||||
if( ! empty($this->parts['join'])) {
|
||||
foreach($this->parts['join'] as $part) {
|
||||
$q .= " ".implode(' ', $part);
|
||||
}
|
||||
|
||||
if($needsSubQuery) {
|
||||
foreach($this->parts['join'] as $parts) {
|
||||
foreach($parts as $part) {
|
||||
if(substr($part,0,9) === 'LEFT JOIN') {
|
||||
$e = explode(' ', $part);
|
||||
|
||||
if( ! in_array($e[2],$this->subqueryAliases))
|
||||
continue;
|
||||
}
|
||||
|
||||
$subquery .= " ".$part;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$string = $this->applyInheritance();
|
||||
@ -501,18 +478,13 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
|
||||
if( ! empty($string))
|
||||
$this->parts['where'][] = '('.$string.')';
|
||||
|
||||
if($needsSubQuery) {
|
||||
// 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"]):'';
|
||||
}
|
||||
|
||||
|
||||
$modifyLimit = true;
|
||||
if( ! empty($this->parts["limit"]) || ! empty($this->parts["offset"])) {
|
||||
|
||||
if($needsSubQuery) {
|
||||
$subquery = $this->connection->modifyLimitQuery($subquery,$this->parts["limit"],$this->parts["offset"]);
|
||||
$subquery = $this->getLimitSubquery();
|
||||
$dbh = $this->connection->getDBH();
|
||||
|
||||
// mysql doesn't support LIMIT in subqueries
|
||||
@ -525,12 +497,13 @@ 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['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']):'';
|
||||
|
||||
if($modifyLimit)
|
||||
$q = $this->connection->modifyLimitQuery($q,$this->parts["limit"],$this->parts["offset"]);
|
||||
$q = $this->connection->modifyLimitQuery($q, $this->parts['limit'], $this->parts['offset']);
|
||||
|
||||
// return to the previous state
|
||||
if( ! empty($string))
|
||||
@ -540,6 +513,47 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
|
||||
|
||||
return $q;
|
||||
}
|
||||
/**
|
||||
* this is method is used by the record limit algorithm
|
||||
*
|
||||
* when fetching one-to-many, many-to-many associated data with LIMIT clause
|
||||
* an additional subquery is needed for limiting the number of returned records instead
|
||||
* of limiting the number of sql result set rows
|
||||
*
|
||||
* @return string the limit subquery
|
||||
*/
|
||||
public function getLimitSubquery() {
|
||||
$k = array_keys($this->tables);
|
||||
$table = $this->tables[$k[0]];
|
||||
|
||||
$subquery = 'SELECT DISTINCT ' . $table->getTableName()
|
||||
. '.' . $table->getIdentifier()
|
||||
. ' FROM '.$table->getTableName();
|
||||
|
||||
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);
|
||||
|
||||
if( ! in_array($e[2],$this->subqueryAliases))
|
||||
continue;
|
||||
}
|
||||
|
||||
$subquery .= ' '.$part;
|
||||
}
|
||||
}
|
||||
|
||||
// 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']):'';
|
||||
|
||||
// add driver specific limit clause
|
||||
$subquery = $this->connection->modifyLimitQuery($subquery, $this->parts['limit'], $this->parts['offset']);
|
||||
|
||||
return $subquery;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -135,6 +135,15 @@ class Doctrine_Query_Where extends Doctrine_Query_Condition {
|
||||
}
|
||||
return $where;
|
||||
}
|
||||
/**
|
||||
* parses a literal value and returns the parsed value
|
||||
*
|
||||
* boolean literals are parsed to integers
|
||||
* components are parsed to associated table aliases
|
||||
*
|
||||
* @param string $value literal value to be parsed
|
||||
* @return string
|
||||
*/
|
||||
public function parseLiteralValue($value) {
|
||||
// check that value isn't a string
|
||||
if(strpos($value, '\'') === false) {
|
||||
@ -161,6 +170,13 @@ class Doctrine_Query_Where extends Doctrine_Query_Condition {
|
||||
|
||||
return $value;
|
||||
}
|
||||
/**
|
||||
* parses an EXISTS expression
|
||||
*
|
||||
* @param string $where query where part to be parsed
|
||||
* @param boolean $negation whether or not to use the NOT keyword
|
||||
* @return string
|
||||
*/
|
||||
public function parseExists($where, $negation) {
|
||||
$operator = ($negation) ? 'EXISTS' : 'NOT EXISTS';
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user