Fix LIMIT/OFFSET queries handling on MS SQL Server (#1488984) - require version 2005+

pull/62/head
Aleksander Machniak 11 years ago
parent 65de0018c8
commit ec6a77bab2

@ -1,6 +1,7 @@
CHANGELOG Roundcube Webmail CHANGELOG Roundcube Webmail
=========================== ===========================
- Fix LIMIT/OFFSET queries handling on MS SQL Server (#1488984)
- Fix so task name can really contain all from a-z0-9_- characters (#1488941) - Fix so task name can really contain all from a-z0-9_- characters (#1488941)
- Support IMAP MOVE extension [RFC 6851] - Support IMAP MOVE extension [RFC 6851]
- Fix javascript errors when working in a page opened with taget="_blank" - Fix javascript errors when working in a page opened with taget="_blank"

@ -34,7 +34,7 @@ REQUIREMENTS
- magic_quotes_runtime disabled - magic_quotes_runtime disabled
- magic_quotes_sybase disabled - magic_quotes_sybase disabled
* PHP compiled with OpenSSL to connect to IMAPS and to use the spell checker * PHP compiled with OpenSSL to connect to IMAPS and to use the spell checker
* A MySQL (4.0.8 or newer), PostgreSQL, MSSQL database engine * A MySQL (4.0.8 or newer), PostgreSQL, MS SQL Server (2005 or newer) database engine
or SQLite support in PHP or SQLite support in PHP
* One of the above databases with permission to create tables * One of the above databases with permission to create tables
* An SMTP server (recommended) or PHP configured for mail delivery * An SMTP server (recommended) or PHP configured for mail delivery
@ -232,5 +232,3 @@ $HTTP["host"] == "www.example.com" {
compress.filetype = ("text/plain", "text/html", "text/javascript", "text/css", "text/xml", "image/gif", "image/png") compress.filetype = ("text/plain", "text/html", "text/javascript", "text/css", "text/xml", "image/gif", "image/png")
} }

@ -100,30 +100,30 @@ class rcube_db_mssql extends rcube_db
{ {
$limit = intval($limit); $limit = intval($limit);
$offset = intval($offset); $offset = intval($offset);
$end = $offset + $limit;
$orderby = stristr($query, 'ORDER BY'); // query without OFFSET
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));
}
$query = preg_replace('/^SELECT\s/i', 'SELECT TOP ' . ($limit + $offset) . ' ', $query);
if (!$offset) { if (!$offset) {
$query = preg_replace('/^SELECT\s/i', "SELECT TOP $limit ", $query);
return $query; return $query;
} }
$query = 'SELECT * FROM (SELECT TOP ' . $limit . ' * FROM (' . $query . ') AS inner_tbl'; $orderby = stristr($query, 'ORDER BY');
$offset += 1;
if ($orderby !== false) { if ($orderby !== false) {
$query .= ' ORDER BY ' . $order . ' '; $query = trim(substr($query, 0, -1 * strlen($orderby)));
$query .= (stripos($sort, 'asc') !== false) ? 'DESC' : 'ASC';
} }
$query .= ') AS outer_tbl'; else {
if ($orderby !== false) { // it shouldn't happen, paging without sorting has not much sense
$query .= ' ORDER BY ' . $order . ' ' . $sort; // @FIXME: I don't know how to build paging query without ORDER BY
$orderby = "ORDER BY 1";
} }
$query = preg_replace('/^SELECT\s/i', '', $query);
$query = "WITH paging AS (SELECT ROW_NUMBER() OVER ($orderby) AS [RowNumber], $query)"
. " SELECT * FROM paging WHERE [RowNumber] BETWEEN $offset AND $end ORDER BY [RowNumber]";
return $query; return $query;
} }

@ -100,26 +100,30 @@ class rcube_db_sqlsrv extends rcube_db
{ {
$limit = intval($limit); $limit = intval($limit);
$offset = intval($offset); $offset = intval($offset);
$end = $offset + $limit;
$orderby = stristr($query, 'ORDER BY'); // query without OFFSET
if ($orderby !== false) { if (!$offset) {
$sort = (stripos($orderby, ' desc') !== false) ? 'desc' : 'asc'; $query = preg_replace('/^SELECT\s/i', "SELECT TOP $limit ", $query);
$order = str_ireplace('ORDER BY', '', $orderby); return $query;
$order = trim(preg_replace('/\bASC\b|\bDESC\b/i', '', $order));
} }
$query = preg_replace('/^SELECT\s/i', 'SELECT TOP ' . ($limit + $offset) . ' ', $query); $orderby = stristr($query, 'ORDER BY');
$offset += 1;
$query = 'SELECT * FROM (SELECT TOP ' . $limit . ' * FROM (' . $query . ') AS inner_tbl';
if ($orderby !== false) { if ($orderby !== false) {
$query .= ' ORDER BY ' . $order . ' '; $query = trim(substr($query, 0, -1 * strlen($orderby)));
$query .= (stripos($sort, 'asc') !== false) ? 'DESC' : 'ASC';
} }
$query .= ') AS outer_tbl'; else {
if ($orderby !== false) { // it shouldn't happen, paging without sorting has not much sense
$query .= ' ORDER BY ' . $order . ' ' . $sort; // @FIXME: I don't know how to build paging query without ORDER BY
$orderby = "ORDER BY 1";
} }
$query = preg_replace('/^SELECT\s/i', '', $query);
$query = "WITH paging AS (SELECT ROW_NUMBER() OVER ($orderby) AS [RowNumber], $query)"
. " SELECT * FROM paging WHERE [RowNumber] BETWEEN $offset AND $end ORDER BY [RowNumber]";
return $query; return $query;
} }

Loading…
Cancel
Save