Added $wgMaxBacklinksInvalidate to avoid massive html cache invalidation.
[lhc/web/wiklou.git] / includes / search / SearchSqlite.php
index 31981dc..e52e4fe 100644 (file)
@@ -1,22 +1,22 @@
 <?php
-# SQLite search backend, based upon SearchMysql
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-# http://www.gnu.org/copyleft/gpl.html
-
 /**
+ * SQLite search backend, based upon SearchMysql
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
  * @file
  * @ingroup Search
  */
  * @ingroup Search
  */
 class SearchSqlite extends SearchEngine {
-       var $strictMatching = true;
 
-       // Cached because SearchUpdate keeps recreating our class
-       private static $fulltextSupported = NULL;
+       /**
+        * @var DatabaseSqlite
+        */
+       protected $db;
 
        /**
         * Creates an instance of this class
         * @param $db DatabaseSqlite: database object
         */
        function __construct( $db ) {
-               $this->db = $db;
+               parent::__construct( $db );
        }
 
        /**
@@ -44,16 +45,14 @@ class SearchSqlite extends SearchEngine {
         * @return Boolean
         */
        function fulltextSearchSupported() {
-               if ( self::$fulltextSupported === NULL ) {
-                       $res = $this->db->selectField( 'updatelog', 'ul_key', array( 'ul_key' => 'fts3' ), __METHOD__ );
-                       self::$fulltextSupported = $res && $this->db->numRows( $res ) > 0;
-               }
-               return self::$fulltextSupported;
+               return $this->db->checkForEnabledSearch();
        }
 
-       /** 
-        * Parse the user's query and transform it into an SQL fragment which will 
+       /**
+        * Parse the user's query and transform it into an SQL fragment which will
         * become part of a WHERE clause
+        *
+        * @return string
         */
        function parseQuery( $filteredText, $fulltext ) {
                global $wgContLang;
@@ -61,13 +60,12 @@ class SearchSqlite extends SearchEngine {
                $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 $bits ) {
                                @list( /* all */, $modifier, $term, $nonQuoted, $wildcard ) = $bits;
-                               
+
                                if( $nonQuoted != '' ) {
                                        $term = $nonQuoted;
                                        $quote = '';
@@ -75,13 +73,11 @@ class SearchSqlite extends SearchEngine {
                                        $term = str_replace( '"', '', $term );
                                        $quote = '"';
                                }
-                       
-                               if( $searchon !== '' ) $searchon .= ' ';
-                               if( $this->strictMatching && ($modifier == '') ) {
-                                       // If we leave this out, boolean op defaults to OR which is rarely helpful.
-                                       $modifier = '+';
+
+                               if( $searchon !== '' ) {
+                                       $searchon .= ' ';
                                }
-                               
+
                                // Some languages such as Serbian store the input form in the search index,
                                // so we may need to search for matches in multiple writing system variants.
                                $convertedVariants = $wgContLang->autoConvertToAllVariants( $term );
@@ -90,27 +86,27 @@ class SearchSqlite extends SearchEngine {
                                } else {
                                        $variants = array( $term );
                                }
-                               
+
                                // The low-level search index does some processing on input to work
                                // around problems with minimum lengths and encoding in MySQL's
                                // fulltext engine.
                                // For Chinese this also inserts spaces between adjacent Han characters.
                                $strippedVariants = array_map(
-                                       array( $wgContLang, 'stripForSearch' ),
+                                       array( $wgContLang, 'normalizeForSearch' ),
                                        $variants );
-                               
+
                                // Some languages such as Chinese force all variants to a canonical
                                // form when stripping to the low-level search index, so to be sure
                                // let's check our variants list for unique items after stripping.
                                $strippedVariants = array_unique( $strippedVariants );
-                               
+
                                $searchon .= $modifier;
                                if( count( $strippedVariants) > 1 )
                                        $searchon .= '(';
                                foreach( $strippedVariants as $stripped ) {
                                        if( $nonQuoted && strpos( $stripped, ' ' ) !== false ) {
                                                // Hack for Chinese: we need to toss in quotes for
-                                               // multiple-character phrases since stripForSearch()
+                                               // multiple-character phrases since normalizeForSearch()
                                                // added spaces between them to make word breaks.
                                                $stripped = '"' . trim( $stripped ) . '"';
                                        }
@@ -118,14 +114,13 @@ class SearchSqlite extends SearchEngine {
                                }
                                if( count( $strippedVariants) > 1 )
                                        $searchon .= ')';
-                               
+
                                // Match individual terms or quoted phrase in result highlighting...
                                // Note that variants will be introduced in a later stage for highlighting!
                                $regexp = $this->regexTerm( $term, $wildcard );
                                $this->searchTerms[] = $regexp;
                        }
-                       wfDebug( __METHOD__ . ": Would search with '$searchon'\n" );
-                       wfDebug( __METHOD__ . ': Match with /' . implode( '|', $this->searchTerms ) . "/\n" );
+
                } else {
                        wfDebug( __METHOD__ . ": Can't understand search query '{$filteredText}'\n" );
                }
@@ -134,10 +129,10 @@ class SearchSqlite extends SearchEngine {
                $field = $this->getIndexField( $fulltext );
                return " $field MATCH '$searchon' ";
        }
-       
+
        function regexTerm( $string, $wildcard ) {
                global $wgContLang;
-               
+
                $regex = preg_quote( $string, '/' );
                if( $wgContLang->hasWordBreaks() ) {
                        if( $wildcard ) {
@@ -177,19 +172,19 @@ class SearchSqlite extends SearchEngine {
        function searchTitle( $term ) {
                return $this->searchInternal( $term, false );
        }
-       
+
        protected function searchInternal( $term, $fulltext ) {
-               global $wgSearchMySQLTotalHits;
+               global $wgCountTotalSearchHits, $wgContLang;
 
                if ( !$this->fulltextSearchSupported() ) {
                        return null;
                }
 
-               $filteredTerm = $this->filter( $term );
+               $filteredTerm = $this->filter( $wgContLang->lc( $term ) );
                $resultSet = $this->db->query( $this->getQuery( $filteredTerm, $fulltext ) );
-               
+
                $total = null;
-               if( $wgSearchMySQLTotalHits ) {
+               if( $wgCountTotalSearchHits ) {
                        $totalResult = $this->db->query( $this->getCountQuery( $filteredTerm, $fulltext ) );
                        $row = $totalResult->fetchObject();
                        if( $row ) {
@@ -197,7 +192,7 @@ class SearchSqlite extends SearchEngine {
                        }
                        $totalResult->free();
                }
-               
+
                return new SqliteSearchResultSet( $resultSet, $this->searchTerms, $total );
        }
 
@@ -231,37 +226,28 @@ class SearchSqlite extends SearchEngine {
 
        /**
         * Returns a query with limit for number of results set.
-        * @param $sql String: 
+        * @param $sql String:
         * @return String
         */
        function limitResult( $sql ) {
                return $this->db->limitResult( $sql, $this->limit, $this->offset );
        }
 
-       /**
-        * Does not do anything for generic search engine
-        * subclasses may define this though
-        * @return String
-        */
-       function queryRanking( $filteredTerm, $fulltext ) {
-               return '';
-       }
-
        /**
         * Construct the full SQL query to do the search.
         * The guts shoulds be constructed in queryMain()
         * @param $filteredTerm String
         * @param $fulltext Boolean
+        * @return String
         */
        function getQuery( $filteredTerm, $fulltext ) {
                return $this->limitResult(
                        $this->queryMain( $filteredTerm, $fulltext ) . ' ' .
                        $this->queryRedirect() . ' ' .
-                       $this->queryNamespaces() . ' ' .
-                       $this->queryRanking( $filteredTerm, $fulltext )
+                       $this->queryNamespaces()
                );
        }
-       
+
        /**
         * Picks which field to index on, depending on what type of query.
         * @param $fulltext Boolean
@@ -315,7 +301,7 @@ class SearchSqlite extends SearchEngine {
                $dbw = wfGetDB( DB_MASTER );
 
                $dbw->delete( 'searchindex', array( 'rowid' => $id ), __METHOD__ );
-               
+
                $dbw->insert( 'searchindex',
                        array(
                                'rowid' => $id,
@@ -338,8 +324,8 @@ class SearchSqlite extends SearchEngine {
                $dbw = wfGetDB( DB_MASTER );
 
                $dbw->update( 'searchindex',
-                       array( 'rowid'  => $id ),
                        array( 'si_title' => $title ),
+                       array( 'rowid'  => $id ),
                        __METHOD__ );
        }
 }
@@ -347,36 +333,13 @@ class SearchSqlite extends SearchEngine {
 /**
  * @ingroup Search
  */
-class SqliteSearchResultSet extends SearchResultSet {
-       function SqliteSearchResultSet( $resultSet, $terms, $totalHits=null ) {
-               $this->mResultSet = $resultSet;
-               $this->mTerms = $terms;
+class SqliteSearchResultSet extends SqlSearchResultSet {
+       function __construct( $resultSet, $terms, $totalHits=null ) {
+               parent::__construct( $resultSet, $terms );
                $this->mTotalHits = $totalHits;
        }
 
-       function termMatches() {
-               return $this->mTerms;
-       }
-
-       function numRows() {
-               return $this->mResultSet->numRows();
-       }
-
-       function next() {
-               $row = $this->mResultSet->fetchObject();
-               if( $row === false ) {
-                       return false;
-               } else {
-                       return new SearchResult( $row );
-               }
-       }
-
-       function free() {
-               $this->mResultSet->free();
-       }
-
-       
        function getTotalHits() {
                return $this->mTotalHits;
        }
-}
\ No newline at end of file
+}