From f5e54ad77c487e334eb6c0e859276f8a2585ad7e Mon Sep 17 00:00:00 2001 From: pookey Date: Tue, 15 Aug 2006 21:32:33 +0000 Subject: [PATCH] Doctrine_Session_Mssql::modifyLimitQuery() added --- Doctrine/Session/Common.php | 7 +++++ Doctrine/Session/Mssql.php | 54 +++++++++++++++++++++++++++++++++++++ Doctrine/Session/Oracle.php | 7 +++++ Doctrine/Tree/NestedSet.php | 14 ++++++++-- 4 files changed, 80 insertions(+), 2 deletions(-) diff --git a/Doctrine/Session/Common.php b/Doctrine/Session/Common.php index 6225ba8e1..070e51b5c 100644 --- a/Doctrine/Session/Common.php +++ b/Doctrine/Session/Common.php @@ -3,6 +3,13 @@ * standard session, the parent of pgsql, mysql and sqlite */ class Doctrine_Session_Common extends Doctrine_Session { + /** + * Adds an driver-specific LIMIT clause to the query + * + * @param string $query + * @param mixed $limit + * @param mixed $offset + */ public function modifyLimitQuery($query,$limit = false,$offset = false) { if($limit && $offset) { $query .= " LIMIT ".$limit." OFFSET ".$offset; diff --git a/Doctrine/Session/Mssql.php b/Doctrine/Session/Mssql.php index e372eab88..4c0c71cf0 100644 --- a/Doctrine/Session/Mssql.php +++ b/Doctrine/Session/Mssql.php @@ -14,5 +14,59 @@ class Doctrine_Session_Mssql extends Doctrine_Session { $data = $stmt->fetch(PDO::FETCH_NUM); return $data[0]; } + /** + * Adds an adapter-specific LIMIT clause to the SELECT statement. + * [ borrowed from Zend Framework ] + * + * @param string $query + * @param mixed $limit + * @param mixed $offset + * @link http://lists.bestpractical.com/pipermail/rt-devel/2005-June/007339.html + * @return string + */ + public function modifyLimitQuery($query, $limit, $offset) { + if ($limit) { + + // we need the starting SELECT clause for later + $select = 'SELECT '; + if (preg_match('/^[[:space:]*SELECT[[:space:]]*DISTINCT/i', $query, $matches) == 1) + $select .= 'DISTINCT '; + + $length = strlen($select); + + // is there an offset? + if (! $offset) { + // no offset, it's a simple TOP count + return "$select TOP $count" . substr($query, $length); + } + + // the total of the count **and** the offset, combined. + // this will be used in the "internal" portion of the + // hacked-up statement. + $total = $count + $offset; + + // build the "real" order for the external portion. + $order = implode(',', $parts['order']); + + // build a "reverse" order for the internal portion. + $reverse = $order; + $reverse = str_ireplace(" ASC", " \xFF", $reverse); + $reverse = str_ireplace(" DESC", " ASC", $reverse); + $reverse = str_ireplace(" \xFF", " DESC", $reverse); + + // create a main statement that replaces the SELECT + // with a SELECT TOP + $main = "\n$select TOP $total" . substr($query, $length) . "\n"; + + // build the hacked-up statement. + // do we really need the "as" aliases here? + $query = "SELECT * FROM (" + . "SELECT TOP $count * FROM ($main) AS select_limit_rev ORDER BY $reverse" + . ") AS select_limit ORDER BY $order"; + + } + + return $query; + } } ?> diff --git a/Doctrine/Session/Oracle.php b/Doctrine/Session/Oracle.php index f597071c7..b265225ab 100644 --- a/Doctrine/Session/Oracle.php +++ b/Doctrine/Session/Oracle.php @@ -3,6 +3,13 @@ * oracle driver */ class Doctrine_Session_Oracle extends Doctrine_Session { + /** + * Adds an driver-specific LIMIT clause to the query + * + * @param string $query + * @param mixed $limit + * @param mixed $offset + */ public function modifyLimitQuery($query,$limit,$offset) { $e = explode("select ",strtolower($query)); $e2 = explode(" from ",$e[1]); diff --git a/Doctrine/Tree/NestedSet.php b/Doctrine/Tree/NestedSet.php index 3131a1727..0b596d7f6 100644 --- a/Doctrine/Tree/NestedSet.php +++ b/Doctrine/Tree/NestedSet.php @@ -30,11 +30,21 @@ */ class Doctrine_Tree_NestedSet extends Doctrine_Record { - public function getLeafNodes() { } + public function getLeafNodes() { + $query = "SELECT ".implode(", ",$this->table->getColumnNames()). + " FROM ".$this->table->getTableName(). + " WHERE rgt = lft + 1"; + } public function getPath() { } - public function getDepth() { } + public function getDepth() { + $query = "SELECT (COUNT(parent.name) - 1) AS depth + FROM ".$this->table->getTableName()." AS node,". + $this->table->getTableName()." AS parent + WHERE node.lft BETWEEN parent.lft AND parent.rgt + GROUP BY node.name"; + } public function removeNode() { }