BUGFIX Fixing MSSQLDatabase to work with latest SQLQuery changes in SS3

This commit is contained in:
Sean Harvey 2012-05-07 16:40:09 +12:00
parent 05d24b0843
commit f1daa29592

View File

@ -1184,22 +1184,31 @@ class MSSQLDatabase extends SS_Database {
/** /**
* Convert a SQLQuery object into a SQL statement. * Convert a SQLQuery object into a SQL statement.
*
* Needs to be overloaded from {@link Database} because MSSQL has
* a very specific way of limiting results from a query.
*
* @param SQLQuery
* @return string SQL text
*/ */
public function sqlQueryToString(SQLQuery $sqlQuery) { public function sqlQueryToString(SQLQuery $query) {
// get the limit and offset // get the limit and offset
$limit=''; $limit = '';
$offset='0'; $offset = '0';
if(is_array($sqlQuery->limit)){ $text = '';
$limit=$sqlQuery->limit['limit']; $suffixText = '';
if(isset($sqlQuery->limit['start'])) $nestedQuery = false;
$offset=$sqlQuery->limit['start'];
} else if(preg_match('/^([0-9]+) offset ([0-9]+)$/i', trim($sqlQuery->limit), $matches)) { if(is_array($query->getLimit())) {
$limitArr = $query->getLimit();
$limit = $limitArr['limit'];
if(isset($limitArr['start'])) $offset = $limitArr['start'];
} else if(preg_match('/^([0-9]+) offset ([0-9]+)$/i', trim($query->getLimit()), $matches)) {
$limit = $matches[1]; $limit = $matches[1];
$offset = $matches[2]; $offset = $matches[2];
} else { } else {
//could be a comma delimited string //could be a comma delimited string
$bits=explode(',', $sqlQuery->limit); $bits = explode(',', $query->getLimit());
if(sizeof($bits) > 1) { if(sizeof($bits) > 1) {
list($offset, $limit) = $bits; list($offset, $limit) = $bits;
} else { } else {
@ -1207,15 +1216,11 @@ class MSSQLDatabase extends SS_Database {
} }
} }
$text = '';
$suffixText = '';
$nestedQuery = false;
// DELETE queries // DELETE queries
if($sqlQuery->delete) { if($query->getDelete()) {
$text = 'DELETE '; $text = 'DELETE ';
} else { } else {
$distinct = $sqlQuery->distinct ? "DISTINCT " : ""; $distinct = $query->getDistinct() ? 'DISTINCT ' : '';
// If there's a limit but no offset, just use 'TOP X' // If there's a limit but no offset, just use 'TOP X'
// rather than the more complex sub-select method // rather than the more complex sub-select method
@ -1224,15 +1229,15 @@ class MSSQLDatabase extends SS_Database {
// If there's a limit and an offset, then we need to do a subselect // If there's a limit and an offset, then we need to do a subselect
} else if($limit && $offset) { } else if($limit && $offset) {
if($sqlQuery->orderby) { if($query->getOrderBy()) {
$orderByFields = $sqlQuery->prepareOrderBy(); $orderByClause = $this->sqlOrderByToString($query->getOrderBy());
$rowNumber = "ROW_NUMBER() OVER (ORDER BY $orderByFields) AS Number"; $rowNumber = "ROW_NUMBER() OVER ($orderByClause) AS Number";
} else { } else {
$selects = $sqlQuery->itemisedSelect(); $selects = $query->getSelect();
$firstCol = reset($selects); $firstCol = reset($selects);
$rowNumber = "ROW_NUMBER() OVER (ORDER BY $firstCol) AS Number"; $rowNumber = "ROW_NUMBER() OVER (ORDER BY $firstCol) AS Number";
} }
$text = "SELECT * FROM ( SELECT $distinct$rowNumber, "; $text = "SELECT * FROM (SELECT $distinct$rowNumber, ";
$suffixText .= ") AS Numbered WHERE Number BETWEEN " . ($offset+1) ." AND " . ($offset+$limit) $suffixText .= ") AS Numbered WHERE Number BETWEEN " . ($offset+1) ." AND " . ($offset+$limit)
. " ORDER BY Number"; . " ORDER BY Number";
$nestedQuery = true; $nestedQuery = true;
@ -1243,16 +1248,18 @@ class MSSQLDatabase extends SS_Database {
} }
// Now add the columns to be selected // Now add the columns to be selected
$text .= $sqlQuery->prepareSelect(); // strip off the SELECT text as it gets done above instead
$text .= trim(str_replace('SELECT' , '', $this->sqlSelectToString($query->getSelect())));
} }
if($sqlQuery->from) $text .= ' FROM ' . implode(' ', $sqlQuery->from); if($query->getFrom()) $text .= $this->sqlFromToString($query->getFrom());
if($sqlQuery->where) $text .= ' WHERE (' . $sqlQuery->prepareWhere() . ')'; if($query->getWhere()) $text .= $this->sqlWhereToString($query->getWhere(), $query->getConnective());
if($sqlQuery->groupby) $text .= ' GROUP BY ' . $sqlQuery->prepareGroupBy();
if($sqlQuery->having) $text .= ' HAVING ( ' . $sqlQuery->prepareHaving() . ' )';
if(!$nestedQuery && $sqlQuery->orderby) { // these clauses only make sense in SELECT queries, not DELETE
$text .= ' ORDER BY ' . $sqlQuery->prepareOrderBy(); if(!$query->getDelete()) {
if($query->getGroupBy()) $text .= $this->sqlGroupByToString($query->getGroupBy());
if($query->getHaving()) $text .= $this->sqlHavingToString($query->getHaving());
if($query->getOrderBy() && !$nestedQuery) $text .= $this->sqlOrderByToString($query->getOrderBy());
} }
// $suffixText is used by the nested queries to create an offset limit // $suffixText is used by the nested queries to create an offset limit
@ -1340,24 +1347,23 @@ class MSSQLDatabase extends SS_Database {
} }
$queries[$tableName] = DataList::create($tableName)->where($where, '')->dataQuery()->query(); $queries[$tableName] = DataList::create($tableName)->where($where, '')->dataQuery()->query();
$queries[$tableName]->orderby = null; $queries[$tableName]->setOrderBy(array());
// Join with CONTAINSTABLE, a full text searcher that includes relevance factor // Join with CONTAINSTABLE, a full text searcher that includes relevance factor
$queries[$tableName]->from = array("\"$tableName\" INNER JOIN $join AS \"ft\" ON \"$tableName\".\"ID\"=\"ft\".\"KEY\""); $queries[$tableName]->setFrom(array("\"$tableName\" INNER JOIN $join AS \"ft\" ON \"$tableName\".\"ID\"=\"ft\".\"KEY\""));
// Join with the base class if needed, as we want to test agains the ClassName // Join with the base class if needed, as we want to test agains the ClassName
if ($tableName != $baseClass) { if ($tableName != $baseClass) {
$queries[$tableName]->from[] = "INNER JOIN \"$baseClass\" ON \"$baseClass\".\"ID\"=\"$tableName\".\"ID\""; $queries[$tableName]->setFrom("INNER JOIN \"$baseClass\" ON \"$baseClass\".\"ID\"=\"$tableName\".\"ID\"");
} }
$queries[$tableName]->select(array()); $queries[$tableName]->setSelect(array("\"$tableName\".\"ID\""));
$queries[$tableName]->select(array("\"$tableName\".\"ID\""));
$queries[$tableName]->selectField("'$tableName'", 'Source'); $queries[$tableName]->selectField("'$tableName'", 'Source');
$queries[$tableName]->selectField('Rank', 'Relevance'); $queries[$tableName]->selectField('Rank', 'Relevance');
if ($extraFilter) { if ($extraFilter) {
$queries[$tableName]->where[] = $extraFilter; $queries[$tableName]->addWhere($extraFilter);
} }
if (count($allClassesToSearch)) { if (count($allClassesToSearch)) {
$queries[$tableName]->where[] = "\"$baseClass\".\"ClassName\" IN ('".implode($allClassesToSearch, "', '")."')"; $queries[$tableName]->addWhere("\"$baseClass\".\"ClassName\" IN ('".implode($allClassesToSearch, "', '")."')");
} }
// Reset the parameters that would get in the way // Reset the parameters that would get in the way
@ -1387,20 +1393,13 @@ class MSSQLDatabase extends SS_Database {
} }
} }
if(class_exists('PaginatedList')) { if(isset($objects)) $results = new ArrayList($objects);
if(isset($objects)) $results = new ArrayList($objects); else $results = new ArrayList();
else $results = new ArrayList(); $list = new PaginatedList($results);
$list = new PaginatedList($results); $list->setPageStart($start);
$list->setPageStart($start); $list->setPageLength($pageLength);
$list->setPageLength($pageLength); $list->setTotalItems($current+1);
$list->setTotalItems($current+1); return $list;
return $list;
} else {
if(isset($objects)) $results = new DataObjectSet($objects);
else $results = new DataObjectSet();
$results->setPageLimits($start, $pageLength, $current+1);
return $results;
}
} }
/** /**