summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Machniak <alec@alec.pl>2012-06-28 09:38:26 +0200
committerAleksander Machniak <alec@alec.pl>2012-06-28 09:38:26 +0200
commit5354c5dac72c4213189eb65c1ad74ddd69059802 (patch)
tree832d396e467f3f3ba678266ba58ceb1a5fbb281c
parent1a2b50f1a0b97b62dc83350260450d744999fff9 (diff)
Implemented LIMIT/OFFSET for SQL Server
-rw-r--r--program/include/rcube_db_sqlsrv.php25
1 files changed, 19 insertions, 6 deletions
diff --git a/program/include/rcube_db_sqlsrv.php b/program/include/rcube_db_sqlsrv.php
index af97a819f..4ea7e7318 100644
--- a/program/include/rcube_db_sqlsrv.php
+++ b/program/include/rcube_db_sqlsrv.php
@@ -93,14 +93,27 @@ class rcube_db_sqlsrv extends rcube_db
*/
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;
}