Thomas
2013-10-14 566747af00ae413c942a7c6702e24c044af36f17
program/lib/Roundcube/rcube_db_sqlsrv.php
@@ -29,29 +29,46 @@
    public $db_provider = 'mssql';
    /**
     * Driver initialization
     * Object constructor
     *
     * @param string $db_dsnw DSN for read/write operations
     * @param string $db_dsnr Optional DSN for read only operations
     * @param bool   $pconn   Enables persistent connections
     */
    protected function init()
    public function __construct($db_dsnw, $db_dsnr = '', $pconn = false)
    {
        parent::__construct($db_dsnw, $db_dsnr, $pconn);
        $this->options['identifier_start'] = '[';
        $this->options['identifier_end'] = ']';
    }
    /**
     * Database character set setting
     * Driver-specific configuration of database connection
     *
     * @param array $dsn DSN for DB connections
     * @param PDO   $dbh Connection handler
     */
    protected function set_charset($charset)
    protected function conn_configure($dsn, $dbh)
    {
        // UTF-8 is default
        // Set date format in case of non-default language (#1488918)
        $dbh->query("SET DATEFORMAT ymd");
    }
    /**
     * Return SQL function for current time and date
     *
     * @param int $interval Optional interval (in seconds) to add/subtract
     *
     * @return string SQL function to use in query
     */
    public function now()
    public function now($interval = 0)
    {
        if ($interval) {
            $interval = intval($interval);
            return "dateadd(second, $interval, getdate())";
        }
        return "getdate()";
    }
@@ -100,25 +117,29 @@
    {
        $limit  = intval($limit);
        $offset = intval($offset);
        $end    = $offset + $limit;
        // query without OFFSET
        if (!$offset) {
            $query = preg_replace('/^SELECT\s/i', "SELECT TOP $limit ", $query);
            return $query;
        }
        $orderby = stristr($query, 'ORDER BY');
        $offset += 1;
        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 = trim(substr($query, 0, -1 * strlen($orderby)));
        }
        else {
            // it shouldn't happen, paging without sorting has not much sense
            // @FIXME: I don't know how to build paging query without ORDER BY
            $orderby = "ORDER BY 1";
        }
        $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;
        }
        $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;
    }