# http://www.gnu.org/copyleft/gpl.html
/**
- * Search engine hook base class for MySQL.
- * Specific bits for MySQL 3 and 4 variants are in child classes.
- * @addtogroup Search
+ * @file
+ * @ingroup Search
+ */
+
+/**
+ * Search engine hook for MySQL 4+
+ * @ingroup Search
*/
class SearchMySQL extends SearchEngine {
+ var $strictMatching = true;
+
+ /** @todo document */
+ function __construct( $db ) {
+ $this->db = $db;
+ }
+
+ /**
+ * Parse the user's query and transform it into an SQL fragment which will
+ * become part of a WHERE clause
+ */
+ function parseQuery( $filteredText, $fulltext ) {
+ global $wgContLang;
+ $lc = SearchEngine::legalSearchChars(); // Minus format chars
+ $searchon = '';
+ $this->searchTerms = array();
+
+ # FIXME: This doesn't handle parenthetical expressions.
+ $m = array();
+ if( preg_match_all( '/([-+<>~]?)(([' . $lc . ']+)(\*?)|"[^"]*")/',
+ $filteredText, $m, PREG_SET_ORDER ) ) {
+ foreach( $m as $terms ) {
+ if( $searchon !== '' ) $searchon .= ' ';
+ if( $this->strictMatching && ($terms[1] == '') ) {
+ $terms[1] = '+';
+ }
+ $searchon .= $terms[1] . $wgContLang->stripForSearch( $terms[2] );
+ if( !empty( $terms[3] ) ) {
+ // Match individual terms in result highlighting...
+ $regexp = preg_quote( $terms[3], '/' );
+ if( $terms[4] ) {
+ $regexp = "\b$regexp"; // foo*
+ } else {
+ $regexp = "\b$regexp\b";
+ }
+ } else {
+ // Match the quoted term in result highlighting...
+ $regexp = preg_quote( str_replace( '"', '', $terms[2] ), '/' );
+ }
+ $this->searchTerms[] = $regexp;
+ }
+ wfDebug( "Would search with '$searchon'\n" );
+ wfDebug( 'Match with /' . implode( '|', $this->searchTerms ) . "/\n" );
+ } else {
+ wfDebug( "Can't understand search query '{$filteredText}'\n" );
+ }
+
+ $searchon = $this->db->strencode( $searchon );
+ $field = $this->getIndexField( $fulltext );
+ return " MATCH($field) AGAINST('$searchon' IN BOOLEAN MODE) ";
+ }
+
+ public static function legalSearchChars() {
+ return "\"*" . parent::legalSearchChars();
+ }
+
/**
* Perform a full text search query and return a result set.
*
* @private
*/
function queryNamespaces() {
- $namespaces = implode( ',', $this->namespaces );
- if ($namespaces == '') {
+ if( is_null($this->namespaces) )
+ return ''; # search all
+ if ( !count( $this->namespaces ) ) {
$namespaces = '0';
+ } else {
+ $namespaces = $this->db->makeList( $this->namespaces );
}
return 'AND page_namespace IN (' . $namespaces . ')';
}
'si_page' => $id,
'si_title' => $title,
'si_text' => $text
- ), 'SearchMySQL4::update' );
+ ), __METHOD__ );
}
/**
$dbw->update( 'searchindex',
array( 'si_title' => $title ),
array( 'si_page' => $id ),
- 'SearchMySQL4::updateTitle',
+ __METHOD__,
array( $dbw->lowPriorityOption() ) );
}
}
/**
- * @addtogroup Search
+ * @ingroup Search
*/
class MySQLSearchResultSet extends SearchResultSet {
function MySQLSearchResultSet( $resultSet, $terms ) {
return new SearchResult( $row );
}
}
-
+
function free() {
$this->mResultSet->free();
}
}
-
-?>