MediaWiki  REL1_24
SearchMssql.php
Go to the documentation of this file.
00001 <?php
00028 class SearchMssql extends SearchDatabase {
00036     function searchText( $term ) {
00037         $resultSet = $this->db->query( $this->getQuery( $this->filter( $term ), true ) );
00038         return new SqlSearchResultSet( $resultSet, $this->searchTerms );
00039     }
00040 
00048     function searchTitle( $term ) {
00049         $resultSet = $this->db->query( $this->getQuery( $this->filter( $term ), false ) );
00050         return new SqlSearchResultSet( $resultSet, $this->searchTerms );
00051     }
00052 
00059     function queryNamespaces() {
00060         $namespaces = implode( ',', $this->namespaces );
00061         if ( $namespaces == '' ) {
00062             $namespaces = '0';
00063         }
00064         return 'AND page_namespace IN (' . $namespaces . ')';
00065     }
00066 
00074     function queryLimit( $sql ) {
00075         return $this->db->limitResult( $sql, $this->limit, $this->offset );
00076     }
00077 
00086     function queryRanking( $filteredTerm, $fulltext ) {
00087         return ' ORDER BY ftindex.[RANK] DESC'; // return ' ORDER BY score(1)';
00088     }
00089 
00098     function getQuery( $filteredTerm, $fulltext ) {
00099         return $this->queryLimit( $this->queryMain( $filteredTerm, $fulltext ) . ' ' .
00100             $this->queryNamespaces() . ' ' .
00101             $this->queryRanking( $filteredTerm, $fulltext ) . ' ' );
00102     }
00103 
00110     function getIndexField( $fulltext ) {
00111         return $fulltext ? 'si_text' : 'si_title';
00112     }
00113 
00122     function queryMain( $filteredTerm, $fulltext ) {
00123         $match = $this->parseQuery( $filteredTerm, $fulltext );
00124         $page = $this->db->tableName( 'page' );
00125         $searchindex = $this->db->tableName( 'searchindex' );
00126 
00127         return 'SELECT page_id, page_namespace, page_title, ftindex.[RANK]' .
00128             "FROM $page,FREETEXTTABLE($searchindex , $match, LANGUAGE 'English') as ftindex " .
00129             'WHERE page_id=ftindex.[KEY] ';
00130     }
00131 
00137     function parseQuery( $filteredText, $fulltext ) {
00138         global $wgContLang;
00139         $lc = $this->legalSearchChars();
00140         $this->searchTerms = array();
00141 
00142         # @todo FIXME: This doesn't handle parenthetical expressions.
00143         $m = array();
00144         $q = array();
00145 
00146         if ( preg_match_all( '/([-+<>~]?)(([' . $lc . ']+)(\*?)|"[^"]*")/',
00147             $filteredText, $m, PREG_SET_ORDER ) ) {
00148             foreach ( $m as $terms ) {
00149                 $q[] = $terms[1] . $wgContLang->normalizeForSearch( $terms[2] );
00150 
00151                 if ( !empty( $terms[3] ) ) {
00152                     $regexp = preg_quote( $terms[3], '/' );
00153                     if ( $terms[4] ) {
00154                         $regexp .= "[0-9A-Za-z_]+";
00155                     }
00156                 } else {
00157                     $regexp = preg_quote( str_replace( '"', '', $terms[2] ), '/' );
00158                 }
00159                 $this->searchTerms[] = $regexp;
00160             }
00161         }
00162 
00163         $searchon = $this->db->addQuotes( join( ',', $q ) );
00164         $field = $this->getIndexField( $fulltext );
00165         return "$field, $searchon";
00166     }
00167 
00177     function update( $id, $title, $text ) {
00178         // We store the column data as UTF-8 byte order marked binary stream
00179         // because we are invoking the plain text IFilter on it so that, and we want it
00180         // to properly decode the stream as UTF-8.  SQL doesn't support UTF8 as a data type
00181         // but the indexer will correctly handle it by this method.  Since all we are doing
00182         // is passing this data to the indexer and never retrieving it via PHP, this will save space
00183         $table = $this->db->tableName( 'searchindex' );
00184         $utf8bom = '0xEFBBBF';
00185         $si_title = $utf8bom . bin2hex( $title );
00186         $si_text = $utf8bom . bin2hex( $text );
00187         $sql = "DELETE FROM $table WHERE si_page = $id;";
00188         $sql .= "INSERT INTO $table (si_page, si_title, si_text) VALUES ($id, $si_title, $si_text)";
00189         return $this->db->query( $sql, 'SearchMssql::update' );
00190     }
00191 
00200     function updateTitle( $id, $title ) {
00201         $table = $this->db->tableName( 'searchindex' );
00202 
00203         // see update for why we are using the utf8bom
00204         $utf8bom = '0xEFBBBF';
00205         $si_title = $utf8bom . bin2hex( $title );
00206         $sql = "DELETE FROM $table WHERE si_page = $id;";
00207         $sql .= "INSERT INTO $table (si_page, si_title, si_text) VALUES ($id, $si_title, 0x00)";
00208         return $this->db->query( $sql, 'SearchMssql::updateTitle' );
00209     }
00210 }