Commit f7602a3b authored by zYne's avatar zYne

DQL Limit rewrite

parent 2e0330bf
...@@ -243,6 +243,12 @@ class Doctrine_Query extends Doctrine_Hydrate { ...@@ -243,6 +243,12 @@ class Doctrine_Query extends Doctrine_Hydrate {
if(empty($this->parts["select"]) || empty($this->parts["from"])) if(empty($this->parts["select"]) || empty($this->parts["from"]))
return false; return false;
$needsSubQuery = false;
$subquery = '';
if( ! empty($this->parts['limit']))
$needsSubQuery = true;
// build the basic query // build the basic query
$q = "SELECT ".implode(", ",$this->parts["select"]). $q = "SELECT ".implode(", ",$this->parts["select"]).
" FROM "; " FROM ";
...@@ -251,31 +257,58 @@ class Doctrine_Query extends Doctrine_Hydrate { ...@@ -251,31 +257,58 @@ class Doctrine_Query extends Doctrine_Hydrate {
$a[] = $tname; $a[] = $tname;
} }
$q .= implode(", ",$a); $q .= implode(", ",$a);
$k = array_keys($this->tables);
$table = $this->tables[$k[0]];
if($needsSubQuery)
$subquery = 'SELECT '.$table->getTableName().".".$table->getIdentifier().
' FROM '.$table->getTableName();
if( ! empty($this->parts['join'])) { if( ! empty($this->parts['join'])) {
foreach($this->parts['join'] as $part) { foreach($this->parts['join'] as $part) {
$q .= " ".implode(' ', $part); $q .= " ".implode(' ', $part);
} }
if($needsSubQuery) {
foreach($this->parts['join'] as $parts) {
foreach($parts as $part) {
if(substr($part,0,9) !== 'LEFT JOIN')
$subquery .= " ".$part;
}
}
} }
}
$string = $this->applyInheritance(); $string = $this->applyInheritance();
if( ! empty($this->parts["where"])) {
$q .= " WHERE ".implode(" AND ",$this->parts["where"]);
if( ! empty($string)) if( ! empty($string))
$q .= " AND (".$string.")"; $this->parts['where'][] = '('.$string.')';
} else {
if( ! empty($string)) if($needsSubQuery) {
$q .= " WHERE (".$string.")"; $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"]):'';
} }
if( ! empty($this->parts["limit"]) || ! empty($this->parts["offset"]) && $needsSubQuery) {
$subquery = $this->session->modifyLimitQuery($subquery,$this->parts["limit"],$this->parts["offset"]);
$field = $table->getTableName().'.'.$table->getIdentifier();
array_unshift($this->parts['where'], $field.' IN ('.$subquery.')');
}
$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(" ",$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"]):'';
if( ! empty($this->parts["limit"]) || ! empty($this->offset)) // return to the previous state
$q = $this->session->modifyLimitQuery($q,$this->parts["limit"],$this->offset); if( ! empty($string))
array_pop($this->parts['where']);
if($needsSubQuery)
array_shift($this->parts['where']);
return $q; return $q;
} }
...@@ -294,7 +327,7 @@ class Doctrine_Query extends Doctrine_Hydrate { ...@@ -294,7 +327,7 @@ class Doctrine_Query extends Doctrine_Hydrate {
if($this->aggregate) { if($this->aggregate) {
$keys = array_keys($this->tables); $keys = array_keys($this->tables);
$query = $this->getQuery(); $query = $this->getQuery();
$stmt = $this->tables[$keys[0]]->getSession()->select($query,$this->parts["limit"],$this->offset); $stmt = $this->tables[$keys[0]]->getSession()->select($query,$this->parts["limit"],$this->parts["offset"]);
$data = $stmt->fetch(PDO::FETCH_ASSOC); $data = $stmt->fetch(PDO::FETCH_ASSOC);
if(count($data) == 1) { if(count($data) == 1) {
return current($data); return current($data);
...@@ -374,7 +407,7 @@ class Doctrine_Query extends Doctrine_Hydrate { ...@@ -374,7 +407,7 @@ class Doctrine_Query extends Doctrine_Hydrate {
$this->parts["limit"] = trim($part); $this->parts["limit"] = trim($part);
break; break;
case "OFFSET": case "OFFSET":
$this->offset = trim($part); $this->parts["offset"] = trim($part);
break; break;
endswitch; endswitch;
} }
......
...@@ -45,10 +45,10 @@ class Doctrine_Collection_OffsetTestCase extends Doctrine_UnitTestCase { ...@@ -45,10 +45,10 @@ class Doctrine_Collection_OffsetTestCase extends Doctrine_UnitTestCase {
$this->assertEqual(count($users), 1); $this->assertEqual(count($users), 1);
$coll = $users[0]->Phonenumber; $coll = $users[0]->Phonenumber;
$this->assertEqual(count($coll), 1); $this->assertEqual(count($coll), 3);
$coll[1]; $coll[1];
$this->assertEqual(count($coll), 2); $this->assertEqual(count($coll), 3);
$this->assertEqual($coll[1]->phonenumber, "456 456"); $this->assertEqual($coll[1]->phonenumber, "456 456");
} }
......
...@@ -2,7 +2,26 @@ ...@@ -2,7 +2,26 @@
class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase { class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase {
public function testLimit() { public function testLimit() {
$this->query->from("User.Phonenumber"); $this->query->from("User.Phonenumber");
$this->query->limit(20); $this->query->limit(5);
$sql = $this->query->getQuery();
$users = $this->query->execute();
$count = $this->dbh->count();
$this->assertEqual($users->count(), 5);
$users[0]->Phonenumber[0];
$this->assertEqual($count, $this->dbh->count());
$this->query->offset(2);
$users = $this->query->execute();
$count = $this->dbh->count();
$this->assertEqual($users->count(), 5);
$users[3]->Phonenumber[0];
$this->assertEqual($count, $this->dbh->count());
} }
} }
?> ?>
...@@ -34,6 +34,7 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase { ...@@ -34,6 +34,7 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase {
$this->assertEqual($users->count(), 8); $this->assertEqual($users->count(), 8);
} }
*/ */
public function testMultipleFetching() { public function testMultipleFetching() {
$count = $this->dbh->count(); $count = $this->dbh->count();
$this->session->getTable('User')->clear(); $this->session->getTable('User')->clear();
...@@ -990,7 +991,7 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase { ...@@ -990,7 +991,7 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase {
public function testLimit() { public function testLimit() {
$query = new Doctrine_Query($this->session); $query = new Doctrine_Query($this->session);
$coll = $query->query("FROM User LIMIT 3"); $coll = $query->query("FROM User(id) LIMIT 3");
$this->assertEqual($query->limit, 3); $this->assertEqual($query->limit, 3);
$this->assertEqual($coll->count(), 3); $this->assertEqual($coll->count(), 3);
} }
......
...@@ -53,7 +53,7 @@ $test->addTestCase(new Doctrine_ViewTestCase()); ...@@ -53,7 +53,7 @@ $test->addTestCase(new Doctrine_ViewTestCase());
$test->addTestCase(new Doctrine_Cache_Query_SqliteTestCase()); $test->addTestCase(new Doctrine_Cache_Query_SqliteTestCase());
$test->addTestCase(new Doctrine_QueryTestCase());
$test->addTestCase(new Doctrine_RawSql_TestCase()); $test->addTestCase(new Doctrine_RawSql_TestCase());
...@@ -67,6 +67,8 @@ $test->addTestCase(new Doctrine_ValidatorTestCase()); ...@@ -67,6 +67,8 @@ $test->addTestCase(new Doctrine_ValidatorTestCase());
$test->addTestCase(new Doctrine_CollectionTestCase()); $test->addTestCase(new Doctrine_CollectionTestCase());
$test->addTestCase(new Doctrine_QueryTestCase());
$test->addTestCase(new Doctrine_Query_Limit_TestCase()); $test->addTestCase(new Doctrine_Query_Limit_TestCase());
//$test->addTestCase(new Doctrine_Cache_FileTestCase()); //$test->addTestCase(new Doctrine_Cache_FileTestCase());
......
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