Move limit/offset handling to Connection wrapper
This commit is contained in:
parent
a48e9c488b
commit
1d5d23a1de
65
lib/db.php
65
lib/db.php
|
@ -213,16 +213,6 @@ class OC_DB {
|
||||||
* SQL query via Doctrine prepare(), needs to be execute()'d!
|
* SQL query via Doctrine prepare(), needs to be execute()'d!
|
||||||
*/
|
*/
|
||||||
static public function prepare( $query , $limit = null, $offset = null, $isManipulation = null) {
|
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
|
// Optimize the query
|
||||||
$query = self::processQuery( $query );
|
$query = self::processQuery( $query );
|
||||||
if(OC_Config::getValue( "log_query", false)) {
|
if(OC_Config::getValue( "log_query", false)) {
|
||||||
|
@ -238,7 +228,7 @@ class OC_DB {
|
||||||
// return the result
|
// return the result
|
||||||
if (self::$backend == self::BACKEND_DOCTRINE) {
|
if (self::$backend == self::BACKEND_DOCTRINE) {
|
||||||
try {
|
try {
|
||||||
$result=self::$connection->prepare($query);
|
$result=self::$connection->prepare($query, $limit, $offset);
|
||||||
} catch(\Doctrine\DBAL\DBALException $e) {
|
} catch(\Doctrine\DBAL\DBALException $e) {
|
||||||
throw new \DatabaseException($e->getMessage(), $query);
|
throw new \DatabaseException($e->getMessage(), $query);
|
||||||
}
|
}
|
||||||
|
@ -493,64 +483,11 @@ class OC_DB {
|
||||||
$query = str_replace( 'LENGTH(', 'LEN(', $query );
|
$query = str_replace( 'LENGTH(', 'LEN(', $query );
|
||||||
$query = str_replace( 'SUBSTR(', 'SUBSTRING(', $query );
|
$query = str_replace( 'SUBSTR(', 'SUBSTRING(', $query );
|
||||||
$query = str_ireplace( 'UNIX_TIMESTAMP()', 'DATEDIFF(second,{d \'1970-01-01\'},GETDATE())', $query );
|
$query = str_ireplace( 'UNIX_TIMESTAMP()', 'DATEDIFF(second,{d \'1970-01-01\'},GETDATE())', $query );
|
||||||
|
|
||||||
$query = self::fixLimitClauseForMSSQL($query);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $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;
|
return $query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,8 +50,12 @@ class Connection extends \Doctrine\DBAL\Connection {
|
||||||
*/
|
*/
|
||||||
public function prepare( $statement, $limit=null, $offset=null ) {
|
public function prepare( $statement, $limit=null, $offset=null ) {
|
||||||
$statement = $this->replaceTablePrefix($statement);
|
$statement = $this->replaceTablePrefix($statement);
|
||||||
if (!is_null($limit) && $limit != -1) {
|
if ($limit === -1) {
|
||||||
// TODO: limit & offset
|
$limit = null;
|
||||||
|
}
|
||||||
|
if (!is_null($limit)) {
|
||||||
|
$platform = $this->getDatabasePlatform();
|
||||||
|
$statement = $platform->modifyLimitQuery($statement, $limit, $offset);
|
||||||
} else {
|
} else {
|
||||||
if (isset($this->preparedQueries[$statement]) && $this->cachingQueryStatementEnabled) {
|
if (isset($this->preparedQueries[$statement]) && $this->cachingQueryStatementEnabled) {
|
||||||
return $this->preparedQueries[$statement];
|
return $this->preparedQueries[$statement];
|
||||||
|
@ -59,7 +63,7 @@ class Connection extends \Doctrine\DBAL\Connection {
|
||||||
}
|
}
|
||||||
$rawQuery = $statement;
|
$rawQuery = $statement;
|
||||||
$result = parent::prepare($statement);
|
$result = parent::prepare($statement);
|
||||||
if ((is_null($limit) || $limit == -1) && $this->cachingQueryStatementEnabled) {
|
if (is_null($limit) && $this->cachingQueryStatementEnabled) {
|
||||||
$this->preparedQueries[$rawQuery] = $result;
|
$this->preparedQueries[$rawQuery] = $result;
|
||||||
}
|
}
|
||||||
return $result;
|
return $result;
|
||||||
|
|
Loading…
Reference in New Issue