From f7602a3bf502deb9eb9711e0a925dcc351b794e7 Mon Sep 17 00:00:00 2001 From: zYne Date: Tue, 15 Aug 2006 23:25:53 +0000 Subject: [PATCH] DQL Limit rewrite --- Doctrine/Query.php | 59 +++++++++++++++++++++++------- tests/CollectionOffsetTestCase.php | 4 +- tests/QueryLimitTestCase.php | 21 ++++++++++- tests/QueryTestCase.php | 3 +- tests/run.php | 4 +- 5 files changed, 73 insertions(+), 18 deletions(-) diff --git a/Doctrine/Query.php b/Doctrine/Query.php index dac76915b..edb099aab 100644 --- a/Doctrine/Query.php +++ b/Doctrine/Query.php @@ -242,40 +242,73 @@ class Doctrine_Query extends Doctrine_Hydrate { final public function getQuery() { if(empty($this->parts["select"]) || empty($this->parts["from"])) return false; + + $needsSubQuery = false; + $subquery = ''; + + if( ! empty($this->parts['limit'])) + $needsSubQuery = true; // build the basic query $q = "SELECT ".implode(", ",$this->parts["select"]). " FROM "; - + foreach($this->parts["from"] as $tname => $bool) { $a[] = $tname; } $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'])) { 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') + $subquery .= " ".$part; + } + } + } } + $string = $this->applyInheritance(); - if( ! empty($this->parts["where"])) { - $q .= " WHERE ".implode(" AND ",$this->parts["where"]); - if( ! empty($string)) - $q .= " AND (".$string.")"; - } else { - if( ! empty($string)) - $q .= " WHERE (".$string.")"; + if( ! empty($string)) + $this->parts['where'][] = '('.$string.')'; + + if($needsSubQuery) { + $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['having']))?" HAVING ".implode(" ",$this->parts["having"]):''; $q .= ( ! empty($this->parts['orderby']))?" ORDER BY ".implode(" ",$this->parts["orderby"]):''; - if( ! empty($this->parts["limit"]) || ! empty($this->offset)) - $q = $this->session->modifyLimitQuery($q,$this->parts["limit"],$this->offset); + // return to the previous state + if( ! empty($string)) + array_pop($this->parts['where']); + if($needsSubQuery) + array_shift($this->parts['where']); return $q; } @@ -294,7 +327,7 @@ class Doctrine_Query extends Doctrine_Hydrate { if($this->aggregate) { $keys = array_keys($this->tables); $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); if(count($data) == 1) { return current($data); @@ -374,7 +407,7 @@ class Doctrine_Query extends Doctrine_Hydrate { $this->parts["limit"] = trim($part); break; case "OFFSET": - $this->offset = trim($part); + $this->parts["offset"] = trim($part); break; endswitch; } diff --git a/tests/CollectionOffsetTestCase.php b/tests/CollectionOffsetTestCase.php index 3236a207d..50e45c1c6 100644 --- a/tests/CollectionOffsetTestCase.php +++ b/tests/CollectionOffsetTestCase.php @@ -45,10 +45,10 @@ class Doctrine_Collection_OffsetTestCase extends Doctrine_UnitTestCase { $this->assertEqual(count($users), 1); $coll = $users[0]->Phonenumber; - $this->assertEqual(count($coll), 1); + $this->assertEqual(count($coll), 3); $coll[1]; - $this->assertEqual(count($coll), 2); + $this->assertEqual(count($coll), 3); $this->assertEqual($coll[1]->phonenumber, "456 456"); } diff --git a/tests/QueryLimitTestCase.php b/tests/QueryLimitTestCase.php index a7bae0639..e4415137b 100644 --- a/tests/QueryLimitTestCase.php +++ b/tests/QueryLimitTestCase.php @@ -2,7 +2,26 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase { public function testLimit() { $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()); } } ?> diff --git a/tests/QueryTestCase.php b/tests/QueryTestCase.php index 437097b6c..71d976148 100644 --- a/tests/QueryTestCase.php +++ b/tests/QueryTestCase.php @@ -34,6 +34,7 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase { $this->assertEqual($users->count(), 8); } */ + public function testMultipleFetching() { $count = $this->dbh->count(); $this->session->getTable('User')->clear(); @@ -990,7 +991,7 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase { public function testLimit() { $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($coll->count(), 3); } diff --git a/tests/run.php b/tests/run.php index 885e32cfb..007cc8bf9 100644 --- a/tests/run.php +++ b/tests/run.php @@ -53,7 +53,7 @@ $test->addTestCase(new Doctrine_ViewTestCase()); $test->addTestCase(new Doctrine_Cache_Query_SqliteTestCase()); -$test->addTestCase(new Doctrine_QueryTestCase()); + $test->addTestCase(new Doctrine_RawSql_TestCase()); @@ -67,6 +67,8 @@ $test->addTestCase(new Doctrine_ValidatorTestCase()); $test->addTestCase(new Doctrine_CollectionTestCase()); +$test->addTestCase(new Doctrine_QueryTestCase()); + $test->addTestCase(new Doctrine_Query_Limit_TestCase()); //$test->addTestCase(new Doctrine_Cache_FileTestCase());