mirror of
https://github.com/silverstripe/silverstripe-mssql
synced 2024-10-22 08:05:53 +02:00
FEATURE Microsoft Sequel Server fulltext searching.
FEATURE sqlsrv_num_rows emulation (set $query->forceNumRows = true;)
This commit is contained in:
parent
a2d2b73893
commit
3c1eed05ed
@ -32,7 +32,7 @@ class MSSQLDatabase extends Database {
|
|||||||
/**
|
/**
|
||||||
* Does this database have full-text index supprt
|
* Does this database have full-text index supprt
|
||||||
*/
|
*/
|
||||||
protected $fullTextEnabled = false;
|
protected $fullTextEnabled = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If true, use the mssql_... functions.
|
* If true, use the mssql_... functions.
|
||||||
@ -1109,27 +1109,36 @@ class MSSQLDatabase extends Database {
|
|||||||
* The core search engine, used by this class and its subclasses to do fun stuff.
|
* The core search engine, used by this class and its subclasses to do fun stuff.
|
||||||
* Searches both SiteTree and File.
|
* Searches both SiteTree and File.
|
||||||
*
|
*
|
||||||
* TODO: This is a really basic search system, provided purely so we have something...
|
|
||||||
*
|
|
||||||
* @param string $keywords Keywords as a string.
|
* @param string $keywords Keywords as a string.
|
||||||
*/
|
*/
|
||||||
public function searchEngine($classesToSearch, $keywords, $pageLength = null, $sortBy = "Relevance DESC", $extraFilter = "", $booleanSearch = false, $alternativeFileFilter = "", $invertedMatch = false) {
|
public function searchEngine($keywords, $pageLength = null, $sortBy = "Relevance DESC", $extraFilter = "", $booleanSearch = false, $alternativeFileFilter = "", $invertedMatch = false) {
|
||||||
if($this->fullTextEnabled) {
|
if($this->fullTextEnabled) {
|
||||||
$result=DB::query('EXEC sp_help_fulltext_columns;');
|
$start = isset($_GET['start']) ? (int)$_GET['start'] : 0;
|
||||||
|
|
||||||
//Get a list of all the tables and columns we'll be searching on:
|
//Get a list of all the tables and columns we'll be searching on:
|
||||||
$tables=Array();
|
$result=DB::query('EXEC sp_help_fulltext_columns');
|
||||||
|
if (!$result->numRecords()) throw Exception('there are no full text columns to search');
|
||||||
|
$tables= array();
|
||||||
|
|
||||||
foreach($result as $row){
|
foreach($result as $row){
|
||||||
if(substr($row['TABLE_NAME'], -5)!='_Live' && substr($row['TABLE_NAME'], -9)!='_versions')
|
if(substr($row['TABLE_NAME'], -5)!='_Live' && substr($row['TABLE_NAME'], -9)!='_versions')
|
||||||
$tables[]="SELECT ID, '{$row['TABLE_NAME']}' AS Source FROM \"{$row['TABLE_NAME']}\" WHERE CONTAINS(\"{$row['FULLTEXT_COLUMN_NAME']}\", N'$keywords')";
|
$tables[]="SELECT ID, '{$row['TABLE_NAME']}' AS Source FROM \"{$row['TABLE_NAME']}\" WHERE CONTAINS(\"{$row['FULLTEXT_COLUMN_NAME']}\", '$keywords')";
|
||||||
}
|
}
|
||||||
|
|
||||||
//We'll do a union query on all of these tables... it's easeier!
|
$totalCount = 0;
|
||||||
|
$this->forceNumRows = true;
|
||||||
|
foreach($tables as $q) {
|
||||||
|
$qR = DB::query($q);
|
||||||
|
$totalCount += $qR->numRecords();
|
||||||
|
}
|
||||||
|
$this->forceNumRows = false;
|
||||||
|
|
||||||
|
//We'll do a union query on all of these tables... it's easier!
|
||||||
$query=implode(' UNION ', $tables);
|
$query=implode(' UNION ', $tables);
|
||||||
|
|
||||||
$result=DB::query($query);
|
$result=DB::query($query);
|
||||||
|
|
||||||
$searchResults=new DataObjectSet();
|
$searchResults=new DataObjectSet();
|
||||||
|
|
||||||
foreach($result as $row){
|
foreach($result as $row){
|
||||||
$row_result=DataObject::get_by_id($row['Source'], $row['ID']);
|
$row_result=DataObject::get_by_id($row['Source'], $row['ID']);
|
||||||
$searchResults->push($row_result);
|
$searchResults->push($row_result);
|
||||||
@ -1233,7 +1242,8 @@ class MSSQLQuery extends Query {
|
|||||||
* is started on a recordset
|
* is started on a recordset
|
||||||
*
|
*
|
||||||
* If you are using SQLSRV, this functon will just return a true or false based on whether you got
|
* If you are using SQLSRV, this functon will just return a true or false based on whether you got
|
||||||
* /ANY/ rows.
|
* /ANY/ rows. UNLESS you set $this->forceNumRows to true, in which case, it will loop over the whole
|
||||||
|
* rowset, cache it, and then do the count on that. This is probably resource intensive.
|
||||||
*
|
*
|
||||||
* For this function, and seek() (above), we will be returning false.
|
* For this function, and seek() (above), we will be returning false.
|
||||||
*
|
*
|
||||||
@ -1242,8 +1252,30 @@ class MSSQLQuery extends Query {
|
|||||||
if($this->mssql) {
|
if($this->mssql) {
|
||||||
return mssql_num_rows($this->handle);
|
return mssql_num_rows($this->handle);
|
||||||
} else {
|
} else {
|
||||||
$this->firstRecord = $this->nextRecord();
|
// Setting forceNumRows to true will cache all records, but will
|
||||||
return count($this->firstRecord) ? true : false;
|
// be able to give a reliable number of results found.
|
||||||
|
if (isset($this->forceNumRows) && $this->forceNumRows) {
|
||||||
|
if (isset($this->numRecords)) return $this->numRecords;
|
||||||
|
|
||||||
|
$this->cachedRecords = array();
|
||||||
|
|
||||||
|
// We can't have nextRecord() return the row we just added =)
|
||||||
|
$this->cachingRows = true;
|
||||||
|
|
||||||
|
foreach($this as $record) {
|
||||||
|
$this->cachedRecords[] = $record;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->cachingRows = false;
|
||||||
|
|
||||||
|
// Assign it to a var, otherwise the value will change when
|
||||||
|
// something is shifted off the beginning.
|
||||||
|
$this->numRecords = count($this->cachedRecords);
|
||||||
|
return $this->numRecords;
|
||||||
|
} else {
|
||||||
|
$this->cachedRecords = array($this->nextRecord());
|
||||||
|
return count($this->cachedRecords[0]) ? true : false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1251,6 +1283,7 @@ class MSSQLQuery extends Query {
|
|||||||
// Coalesce rather than replace common fields.
|
// Coalesce rather than replace common fields.
|
||||||
if($this->mssql) {
|
if($this->mssql) {
|
||||||
if($data = mssql_fetch_row($this->handle)) {
|
if($data = mssql_fetch_row($this->handle)) {
|
||||||
|
|
||||||
foreach($data as $columnIdx => $value) {
|
foreach($data as $columnIdx => $value) {
|
||||||
$columnName = mssql_field_name($this->handle, $columnIdx);
|
$columnName = mssql_field_name($this->handle, $columnIdx);
|
||||||
// $value || !$ouput[$columnName] means that the *last* occurring value is shown
|
// $value || !$ouput[$columnName] means that the *last* occurring value is shown
|
||||||
@ -1266,10 +1299,11 @@ class MSSQLQuery extends Query {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (isset($this->firstRecord) && $this->firstRecord) {
|
// If we have cached rows (if numRecords as been called) and
|
||||||
$toReturn = $this->firstRecord;
|
// returning cached rows hasn't specifically been disabled,
|
||||||
$this->firstRecord = false;
|
// check for cached rows and return 'em.
|
||||||
return $toReturn;
|
if (isset($this->cachedRecords) && count($this->cachedRecords) && (!isset($this->cachingRows) || !$this->cachingRows)) {
|
||||||
|
return array_shift($this->cachedRecords);
|
||||||
}
|
}
|
||||||
if($data = sqlsrv_fetch_array($this->handle, SQLSRV_FETCH_NUMERIC)) {
|
if($data = sqlsrv_fetch_array($this->handle, SQLSRV_FETCH_NUMERIC)) {
|
||||||
$output = array();
|
$output = array();
|
||||||
|
Loading…
Reference in New Issue
Block a user