r86705 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r86704‎ | r86705 | r86706 >
Date:13:28, 22 April 2011
Author:nikerabbit
Status:resolved (Comments)
Tags:
Comment:
* Remove manual query building in search mysql
* Remove reference to mysql3, no longer supported
* Changed method signatures, I found no class extending this class in extensions
* Tested lightly and returns same results
Modified paths:
  • /trunk/phase3/includes/search/SearchMySQL.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/search/SearchMySQL.php
@@ -171,12 +171,24 @@
172172 protected function searchInternal( $term, $fulltext ) {
173173 global $wgCountTotalSearchHits;
174174
 175+ // This seems of place, why is this called with empty term?
 176+ if ( trim( $term ) === '' ) return null;
 177+
175178 $filteredTerm = $this->filter( $term );
176 - $resultSet = $this->db->query( $this->getQuery( $filteredTerm, $fulltext ) );
 179+ $query = $this->getQuery( $filteredTerm, $fulltext );
 180+ $resultSet = $this->db->select(
 181+ $query['tables'], $query['fields'], $query['conds'],
 182+ __METHOD__, $query['options'], $query['joins']
 183+ );
177184
178185 $total = null;
179186 if( $wgCountTotalSearchHits ) {
180 - $totalResult = $this->db->query( $this->getCountQuery( $filteredTerm, $fulltext ) );
 187+ $query = $this->getCountQuery( $filteredTerm, $fulltext );
 188+ $totalResult = $this->db->select(
 189+ $query['tables'], $query['fields'], $query['conds'],
 190+ __METHOD__, $query['options'], $query['joins']
 191+ );
 192+
181193 $row = $totalResult->fetchObject();
182194 if( $row ) {
183195 $total = intval( $row->c );
@@ -189,73 +201,62 @@
190202
191203
192204 /**
193 - * Return a partial WHERE clause to exclude redirects, if so set
194 - * @return String
 205+ * Add redirect conditions
 206+ * @param $query Array
 207+ * @since 1.18 (changed)
195208 */
196 - function queryRedirect() {
197 - if( $this->showRedirects ) {
198 - return '';
199 - } else {
200 - return 'page_is_redirect=0';
 209+ function queryRedirect( &$query ) {
 210+ if( !$this->showRedirects ) {
 211+ $query['conds']['page_is_redirect'] = 0;
201212 }
202213 }
203214
204215 /**
205 - * Return a partial WHERE clause to limit the search to the given namespaces
206 - * @return String
 216+ * Add namespace conditions
 217+ * @param $query Array
 218+ * @since 1.18 (changed)
207219 */
208 - function queryNamespaces() {
209 - if( is_null($this->namespaces) )
210 - return ''; # search all
211 - if ( !count( $this->namespaces ) ) {
212 - $namespaces = '0';
213 - } else {
214 - $namespaces = $this->db->makeList( $this->namespaces );
 220+ function queryNamespaces( &$query ) {
 221+ if ( is_array( $this->namespaces ) ) {
 222+ if ( count( $this->namespaces ) === 0 ) {
 223+ $this->namespaces[] = '0';
 224+ }
 225+ $query['conds']['page_namespace'] = $this->namespaces;
215226 }
216 - return 'page_namespace IN (' . $namespaces . ')';
217227 }
218228
219229 /**
220 - * Return a LIMIT clause to limit results on the query.
221 - * @return String
 230+ * Add limit options
 231+ * @param $query Array
 232+ * @since 1.18
222233 */
223 - function queryLimit() {
224 - return $this->db->limitResult( '', $this->limit, $this->offset );
 234+ protected function limitResult( &$query ) {
 235+ $query['options']['LIMIT'] = $this->limit;
 236+ $query['options']['OFFSET'] = $this->offset;
225237 }
226238
227239 /**
228 - * Does not do anything for generic search engine
229 - * subclasses may define this though
230 - * @return String
231 - */
232 - function queryRanking( $filteredTerm, $fulltext ) {
233 - return '';
234 - }
235 -
236 - /**
237 - * Construct the full SQL query to do the search.
 240+ * Construct the SQL query to do the search.
238241 * The guts shoulds be constructed in queryMain()
239242 * @param $filteredTerm String
240243 * @param $fulltext Boolean
 244+ * @return Array
 245+ * @since 1.18 (changed)
241246 */
242247 function getQuery( $filteredTerm, $fulltext ) {
243 - $query = $this->queryMain( $filteredTerm, $fulltext ) . ' ';
 248+ $query = array(
 249+ 'tables' => array(),
 250+ 'fields' => array(),
 251+ 'conds' => array(),
 252+ 'options' => array(),
 253+ 'joins' => array(),
 254+ );
244255
245 - $redir = $this->queryRedirect();
 256+ $this->queryMain( $query, $filteredTerm, $fulltext );
 257+ $this->queryRedirect( $query );
 258+ $this->queryNamespaces( $query );
 259+ $this->limitResult( $query );
246260
247 - if ( $redir ) {
248 - $query .= 'AND ' . $redir . ' ';
249 - }
250 -
251 - $namespace = $this->queryNamespaces();
252 -
253 - if ( $namespace ) {
254 - $query .= 'AND ' . $namespace . ' ';
255 - }
256 -
257 - $query .= $this->queryRanking( $filteredTerm, $fulltext ) . ' ' .
258 - $this->queryLimit();
259 -
260261 return $query;
261262 }
262263
@@ -270,40 +271,40 @@
271272
272273 /**
273274 * Get the base part of the search query.
274 - * The actual match syntax will depend on the server
275 - * version; MySQL 3 and MySQL 4 have different capabilities
276 - * in their fulltext search indexes.
277275 *
278276 * @param $filteredTerm String
279277 * @param $fulltext Boolean
280 - * @return String
 278+ * @since 1.18 (changed)
281279 */
282 - function queryMain( $filteredTerm, $fulltext ) {
 280+ function queryMain( &$query, $filteredTerm, $fulltext ) {
283281 $match = $this->parseQuery( $filteredTerm, $fulltext );
284 - $page = $this->db->tableName( 'page' );
285 - $searchindex = $this->db->tableName( 'searchindex' );
286 - return 'SELECT page_id, page_namespace, page_title ' .
287 - "FROM $page,$searchindex " .
288 - 'WHERE page_id=si_page AND ' . $match;
 282+ $query['tables'][] = 'page';
 283+ $query['tables'][] = 'searchindex';
 284+ $query['fields'][] = 'page_id';
 285+ $query['fields'][] = 'page_namespace';
 286+ $query['fields'][] = 'page_title';
 287+ $query['conds'][] = 'page_id=si_page';
 288+ $query['conds'][] = $match;
289289 }
290290
 291+ /**
 292+ * @since 1.18 (changed)
 293+ */
291294 function getCountQuery( $filteredTerm, $fulltext ) {
292295 $match = $this->parseQuery( $filteredTerm, $fulltext );
293296
294 - $redir = $this->queryRedirect();
295 - $namespaces = $this->queryNamespaces();
296 - $conditions = array( 'page_id=si_page', $match );
297 - if ( $redir !== '' ) {
298 - $conditions[] = $redir;
299 - }
300 - if ( $namespaces !== '' ) {
301 - $conditions[] = $namespaces;
302 - }
303 - return $this->db->selectSQLText( array( 'page', 'searchindex' ),
304 - 'COUNT(*) AS c',
305 - $conditions,
306 - __METHOD__
 297+ $query = array(
 298+ 'tables' => array( 'page', 'searchindex' ),
 299+ 'fields' => array( 'COUNT(*) as c' ),
 300+ 'conds' => array( 'page_id=si_page', $match ),
 301+ 'options' => array(),
 302+ 'joins' => array(),
307303 );
 304+
 305+ $this->queryRedirect( $query );
 306+ $this->queryNamespaces( $query );
 307+
 308+ return $query;
308309 }
309310
310311 /**

Follow-up revisions

RevisionCommit summaryAuthorDate
r86713Followup r86705 fix typo in commentnikerabbit15:16, 22 April 2011

Comments

#Comment by Reedy (talk | contribs)   13:44, 22 April 2011
+		// This seems of place, why is this called with empty term?

Think you missed a word - "This seems out of place"

#Comment by Nikerabbit (talk | contribs)   14:55, 22 April 2011

Yep

#Comment by Brion VIBBER (talk | contribs)   00:32, 15 June 2011

Major refactoring of class internals should be confirmed against the unit tests; it looks like the SearchEngine tests currently do not run:

$ php phpunit.php includes/search/SearchEngineTest.php 
PHPUnit 3.5.14 by Sebastian Bergmann.

Fatal error: Call to a member function getType() on a non-object in /Library/WebServer/Documents/trunk/tests/phpunit/includes/search/SearchEngineTest.php on line 19

So these'll need to be fixed before we can confirm this rev.

#Comment by Reedy (talk | contribs)   21:00, 16 June 2011

I can see why it seems to be failing, but it seems like SearchEngineTest is being wrongly called, "This class is not directly tested. Instead it is extended by SearchDbTest."

So it should work if started from the other file?

Can't actually test, my tests look teh broken



reedy@ubuntu64-esxi:~/mediawiki/trunk/phase3/tests/phpunit$ php phpunit.php includes/search/SearchDbTest.php

Warning: require_once(PHP/CodeCoverage/Filter.php): failed to open stream: No such file or directory in /usr/share/php/PHPUnit/Autoload.php on line 46

Call Stack:
    0.0003     657328   1. {main}() /home/reedy/mediawiki/trunk/phase3/tests/phpunit/phpunit.php:0
    0.5454   17283808   2. require_once('/usr/share/php/PHPUnit/Autoload.php') /home/reedy/mediawiki/trunk/phase3/tests/phpunit/phpunit.php:57


Fatal error: require_once(): Failed opening required 'PHP/CodeCoverage/Filter.php' (include_path='.:/usr/share/php:/usr/share/pear') in /usr/share/php/PHPUnit/Autoload.php on line 46

Call Stack:
    0.0003     657328   1. {main}() /home/reedy/mediawiki/trunk/phase3/tests/phpunit/phpunit.php:0
    0.5454   17283808   2. require_once('/usr/share/php/PHPUnit/Autoload.php') /home/reedy/mediawiki/trunk/phase3/tests/phpunit/phpunit.php:57

reedy@ubuntu64-esxi:~/mediawiki/trunk/phase3/tests/phpunit$ php phpunit.php includes/search/SearchEngineTest.php

Warning: require_once(PHP/CodeCoverage/Filter.php): failed to open stream: No such file or directory in /usr/share/php/PHPUnit/Autoload.php on line 46

Call Stack:
    0.0003     657328   1. {main}() /home/reedy/mediawiki/trunk/phase3/tests/phpunit/phpunit.php:0
    0.5430   17283808   2. require_once('/usr/share/php/PHPUnit/Autoload.php') /home/reedy/mediawiki/trunk/phase3/tests/phpunit/phpunit.php:57


Fatal error: require_once(): Failed opening required 'PHP/CodeCoverage/Filter.php' (include_path='.:/usr/share/php:/usr/share/pear') in /usr/share/php/PHPUnit/Autoload.php on line 46

Call Stack:
    0.0003     657328   1. {main}() /home/reedy/mediawiki/trunk/phase3/tests/phpunit/phpunit.php:0
    0.5430   17283808   2. require_once('/usr/share/php/PHPUnit/Autoload.php') /home/reedy/mediawiki/trunk/phase3/tests/phpunit/phpunit.php:57
#Comment by Nikerabbit (talk | contribs)   09:31, 20 June 2011

Weren't unit tests supposed to work already?

#Comment by 😂 (talk | contribs)   21:50, 28 June 2011

Sounds like you might be missing some files there in phpunit, not our suite.

#Comment by Nikerabbit (talk | contribs)   21:46, 28 June 2011

php phpunit.php includes/search/SearchDbTest.php PHPUnit 3.5.14 by Sebastian Bergmann.

.....

Time: 13 seconds, Memory: 75.00Mb

OK (5 tests, 16 assertions)

#Comment by 😂 (talk | contribs)   21:52, 28 June 2011

I've got the same failure as Brion, both Sqlite and Mysql. Problem is $this->db isn't defined until run(). Could possibly try moving that back into setUp() again, but it broke horribly last time I tried.

#Comment by 😂 (talk | contribs)   22:32, 28 June 2011

I've got all tests passing as of r91027. Reedy, I don't know what your problem is ;-)

#Comment by Reedy (talk | contribs)   22:32, 28 June 2011

Computers.

#Comment by 😂 (talk | contribs)   00:21, 13 July 2011

Search tests are all passing for me on Sqlite and Mysql, marking resolved.

Status & tagging log