From 5354c5dac72c4213189eb65c1ad74ddd69059802 Mon Sep 17 00:00:00 2001
From: Aleksander Machniak <alec@alec.pl>
Date: Thu, 28 Jun 2012 03:38:26 -0400
Subject: [PATCH] Implemented LIMIT/OFFSET for SQL Server

---
 program/include/rcube_db_sqlsrv.php |   25 +++++++++++++++++++------
 1 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/program/include/rcube_db_sqlsrv.php b/program/include/rcube_db_sqlsrv.php
index af97a81..4ea7e73 100644
--- a/program/include/rcube_db_sqlsrv.php
+++ b/program/include/rcube_db_sqlsrv.php
@@ -93,14 +93,27 @@
      */
     protected function set_limit($query, $limit = 0, $offset = 0)
     {
-        // code from MDB2 package
-        if ($limit > 0) {
-            $fetch = $offset + $limit;
-            return preg_replace('/^([\s(])*SELECT( DISTINCT)?(?!\s*TOP\s*\()/i',
-                "\\1SELECT\\2 TOP $fetch", $query);
+        $limit  = intval($limit);
+        $offset = intval($offset);
+
+        $orderby = stristr($query, 'ORDER BY');
+        if ($orderby !== false) {
+            $sort  = (stripos($orderby, ' desc') !== false) ? 'desc' : 'asc';
+            $order = str_ireplace('ORDER BY', '', $orderby);
+            $order = trim(preg_replace('/\bASC\b|\bDESC\b/i', '', $order));
         }
 
-// @TODO: proper OFFSET handling i _fetch_row()
+        $query = preg_replace('/^SELECT\s/i', 'SELECT TOP ' . ($limit + $offset) . ' ', $query);
+
+        $query = 'SELECT * FROM (SELECT TOP ' . $limit . ' * FROM (' . $query . ') AS inner_tbl';
+        if ($orderby !== false) {
+            $query .= ' ORDER BY ' . $order . ' ';
+            $query .= (stripos($sort, 'asc') !== false) ? 'DESC' : 'ASC';
+        }
+        $query .= ') AS outer_tbl';
+        if ($orderby !== false) {
+            $query .= ' ORDER BY ' . $order . ' ' . $sort;
+        }
 
         return $query;
     }

--
Gitblit v1.9.1