Move limit/offset handling to Connection wrapper

This commit is contained in:
Bart Visscher 2013-02-25 21:46:03 +01:00
parent a48e9c488b
commit 1d5d23a1de
2 changed files with 8 additions and 67 deletions

View File

@ -213,16 +213,6 @@ class OC_DB {
* SQL query via Doctrine prepare(), needs to be execute()'d!
*/
static public function prepare( $query , $limit = null, $offset = null, $isManipulation = null) {
if (!is_null($limit) && $limit != -1) {
if ($limit === -1) {
$limit = null;
}
$platform = self::$connection->getDatabasePlatform();
$query = $platform->modifyLimitQuery($query, $limit, $offset);
}
}
// Optimize the query
$query = self::processQuery( $query );
if(OC_Config::getValue( "log_query", false)) {
@ -238,7 +228,7 @@ class OC_DB {
// return the result
if (self::$backend == self::BACKEND_DOCTRINE) {
try {
$result=self::$connection->prepare($query);
$result=self::$connection->prepare($query, $limit, $offset);
} catch(\Doctrine\DBAL\DBALException $e) {
throw new \DatabaseException($e->getMessage(), $query);
}
@ -493,64 +483,11 @@ class OC_DB {
$query = str_replace( 'LENGTH(', 'LEN(', $query );
$query = str_replace( 'SUBSTR(', 'SUBSTRING(', $query );
$query = str_ireplace( 'UNIX_TIMESTAMP()', 'DATEDIFF(second,{d \'1970-01-01\'},GETDATE())', $query );
$query = self::fixLimitClauseForMSSQL($query);
}
return $query;
}
private static function fixLimitClauseForMSSQL($query) {
$limitLocation = stripos ($query, "LIMIT");
if ( $limitLocation === false ) {
return $query;
}
// total == 0 means all results - not zero results
//
// First number is either total or offset, locate it by first space
//
$offset = substr ($query, $limitLocation + 5);
$offset = substr ($offset, 0, stripos ($offset, ' '));
$offset = trim ($offset);
// check for another parameter
if (stripos ($offset, ',') === false) {
// no more parameters
$offset = 0;
$total = intval ($offset);
} else {
// found another parameter
$offset = intval ($offset);
$total = substr ($query, $limitLocation + 5);
$total = substr ($total, stripos ($total, ','));
$total = substr ($total, 0, stripos ($total, ' '));
$total = intval ($total);
}
$query = trim (substr ($query, 0, $limitLocation));
if ($offset == 0 && $total !== 0) {
if (strpos($query, "SELECT") === false) {
$query = "TOP {$total} " . $query;
} else {
$query = preg_replace('/SELECT(\s*DISTINCT)?/Dsi', 'SELECT$1 TOP '.$total, $query);
}
} else if ($offset > 0) {
$query = preg_replace('/SELECT(\s*DISTINCT)?/Dsi', 'SELECT$1 TOP(10000000) ', $query);
$query = 'SELECT *
FROM (SELECT sub2.*, ROW_NUMBER() OVER(ORDER BY sub2.line2) AS line3
FROM (SELECT 1 AS line2, sub1.* FROM (' . $query . ') AS sub1) as sub2) AS sub3';
if ($total > 0) {
$query .= ' WHERE line3 BETWEEN ' . ($offset + 1) . ' AND ' . ($offset + $total);
} else {
$query .= ' WHERE line3 > ' . $offset;
}
}
return $query;
}

View File

@ -50,8 +50,12 @@ class Connection extends \Doctrine\DBAL\Connection {
*/
public function prepare( $statement, $limit=null, $offset=null ) {
$statement = $this->replaceTablePrefix($statement);
if (!is_null($limit) && $limit != -1) {
// TODO: limit & offset
if ($limit === -1) {
$limit = null;
}
if (!is_null($limit)) {
$platform = $this->getDatabasePlatform();
$statement = $platform->modifyLimitQuery($statement, $limit, $offset);
} else {
if (isset($this->preparedQueries[$statement]) && $this->cachingQueryStatementEnabled) {
return $this->preparedQueries[$statement];
@ -59,7 +63,7 @@ class Connection extends \Doctrine\DBAL\Connection {
}
$rawQuery = $statement;
$result = parent::prepare($statement);
if ((is_null($limit) || $limit == -1) && $this->cachingQueryStatementEnabled) {
if (is_null($limit) && $this->cachingQueryStatementEnabled) {
$this->preparedQueries[$rawQuery] = $result;
}
return $result;