* API query optimizations
authorYuri Astrakhan <yurik@users.mediawiki.org>
Sun, 15 Oct 2006 07:43:52 +0000 (07:43 +0000)
committerYuri Astrakhan <yurik@users.mediawiki.org>
Sun, 15 Oct 2006 07:43:52 +0000 (07:43 +0000)
* API allow modules to have custom printers

includes/api/ApiBase.php
includes/api/ApiFormatBase.php
includes/api/ApiFormatJson.php
includes/api/ApiFormatXml.php
includes/api/ApiFormatYaml.php
includes/api/ApiMain.php
includes/api/ApiOpenSearch.php
includes/api/ApiPageSet.php
includes/api/ApiQueryWatchlist.php
includes/api/ApiResult.php

index b4277c0..9e000a0 100644 (file)
@@ -90,6 +90,15 @@ abstract class ApiBase {
                return $this->getResult()->getData();
        }
 
+       /**
+        * If the module may only be used with a certain format module,
+        * it should override this method to return an instance of that formatter.
+        * A value of null means the default format will be used.  
+        */
+       public function getCustomFormatModule() {
+               return null;
+       }
+
        /**
         * Generates help message for this module, or false if there is no description
         */
index f87cd81..c886a15 100644 (file)
@@ -54,15 +54,6 @@ abstract class ApiFormatBase extends ApiBase {
         */
        public abstract function getMimeType();
 
-       public function execute() {
-               ApiBase :: dieDebug(__METHOD__, 'This is not an executable module');
-       }
-
-       /**
-        * Format modules must override this method to implement actual printing 
-        */
-       public abstract function executePrinter();
-
        public function getNeedsRawData() {
                return false;
        }
index 8942f1c..7949700 100644 (file)
@@ -39,7 +39,7 @@ class ApiFormatJson extends ApiFormatBase {
                return 'application/json';
        }
 
-       public function executePrinter() {
+       public function execute() {
                $json = new Services_JSON();
                $this->printText($json->encode($this->getResultData(), true));
        }
index f72c0d4..11efcf9 100644 (file)
@@ -43,7 +43,7 @@ class ApiFormatXml extends ApiFormatBase {
                return true;
        }
 
-       public function executePrinter() {
+       public function execute() {
                $xmlindent = null;
                extract($this->extractRequestParams());
 
index f031896..adb23cd 100644 (file)
@@ -39,7 +39,7 @@ class ApiFormatYaml extends ApiFormatBase {
                return 'application/yaml';
        }
 
-       public function executePrinter() {
+       public function execute() {
                $this->printText(Spyc :: YAMLDump($this->getResultData()));
        }
 
index 2c437f1..caf069b 100644 (file)
@@ -101,6 +101,10 @@ class ApiMain extends ApiBase {
                        $this->dieUsage('Editing of this site is disabled. Make sure the $wgEnableWriteAPI=true; ' .
                        'statement is included in the site\'s LocalSettings.php file', 'readonly');
        }
+       
+       public function createPrinterByName($format) {
+               return new $this->mFormats[$format] ($this, $format);
+       }
 
        public function execute() {
                $this->profileIn();
@@ -128,8 +132,7 @@ class ApiMain extends ApiBase {
                        
                        // Printer may not be initialized if the extractRequestParams() fails for the main module
                        if (!isset ($this->mPrinter)) {
-                               $format = self :: API_DEFAULT_FORMAT;
-                               $this->mPrinter = new $this->mFormats[$format] ($this, $format);
+                               $this->mPrinter = $this->createPrinterByName(self :: API_DEFAULT_FORMAT);
                        }
                        
                        if ($e instanceof UsageException) {
@@ -183,12 +186,13 @@ class ApiMain extends ApiBase {
                $module = new $this->mModules[$action] ($this, $action);
 
                if (!$this->mInternalMode) {
-                       if ($module instanceof ApiFormatBase) {
-                               // The requested module will print data in its own format
-                               $this->mPrinter = $module;                              
-                       } else {
+                       
+                       // See if custom printer is used
+                       $this->mPrinter = $module->getCustomFormatModule();                             
+                       
+                       if (is_null($this->mPrinter)) {
                                // Create an appropriate printer
-                               $this->mPrinter = new $this->mFormats[$format] ($this, $format);
+                               $this->mPrinter = $this->createPrinterByName($format);
                        }
                }
                
@@ -212,7 +216,7 @@ class ApiMain extends ApiBase {
                $printer->initPrinter($isError);
                if (!$printer->getNeedsRawData())
                        $this->getResult()->SanitizeData();
-               $printer->executePrinter();
+               $printer->execute();
                $printer->closePrinter();
                $printer->profileOut();
        }
@@ -268,9 +272,9 @@ class ApiMain extends ApiBase {
                }
 
                $msg .= "\n$astriks Formats  $astriks\n\n";
-               foreach ($this->mFormats as $moduleName => $moduleClass) {
-                       $msg .= "* format=$moduleName *";
-                       $module = new $this->mFormats[$moduleName] ($this, $moduleName);
+               foreach ($this->mFormats as $formatName => $moduleClass) {
+                       $msg .= "* format=$formatName *";
+                       $module = $this->createPrinterByName($formatName);
                        $msg2 = $module->makeHelpMsg();
                        if ($msg2 !== false)
                                $msg .= $msg2;
index f86467e..e3b8777 100644 (file)
@@ -29,16 +29,14 @@ if (!defined('MEDIAWIKI')) {
        require_once ("ApiFormatBase.php");
 }
 
-class ApiOpenSearch extends ApiFormatBase {
+class ApiOpenSearch extends ApiBase {
 
-       private $mResult = array();
-       
        public function __construct($main, $action) {
                parent :: __construct($main, $action);
        }
 
-       public function getMimeType() {
-               return 'application/json';
+       public function getCustomFormatModule() {
+               return $this->getMain()->createPrinterByName('json');
        }
 
        public function execute() {
@@ -63,20 +61,18 @@ class ApiOpenSearch extends ApiFormatBase {
                $result->SanitizeData();
                $data = $result->GetData();
                
-               // Reformat useful data for future printing
-               $result = array();
+               // Reformat useful data for future printing by JSON engine
+               $srchres = array();
                foreach ($data['query']['allpages'] as $pageid => &$pageinfo) {
-                       $result[] = $pageinfo['title'];
+                       $srchres[] = $pageinfo['title'];
                }
                
-               $this->mResult = array($command, $result);
+               // Set top level elements
+               $result = $this->getResult();
+               $result->addValue(null, 0, $command);
+               $result->addValue(null, 1, $srchres);
        }
        
-       public function executePrinter() {
-               $json = new Services_JSON();
-               $this->printText($json->encode($this->mResult, true));
-       }
-
        protected function GetAllowedParams() {
                return array (
                        'command' => null
index 53cd59a..ad3d804 100644 (file)
@@ -385,9 +385,9 @@ class ApiPageSet extends ApiQueryBase {
                $pageids = array();
                $remaining = array_flip($revids);
                
-               $tables = array('page', 'revision');
+               $tables = array('revision');
                $fields = array('rev_id','rev_page');
-               $where = array( 'rev_deleted' => 0, 'rev_id' => $revids );
+               $where = array('rev_deleted' => 0, 'rev_id' => $revids);
                
                // Get pageIDs data from the `page` table
                $this->profileDBIn();
index 0033d5c..af0b57f 100644 (file)
@@ -66,8 +66,7 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
 
                $options = array (
                        'LIMIT' => $limit +1,
-                       'ORDER BY' => 'rc_timestamp' . ($dirNewer ? '' : ' DESC'),
-                       'USE INDEX' => 'rc_timestamp');
+                       'ORDER BY' => 'rc_timestamp' . ($dirNewer ? '' : ' DESC'));
 
                if (is_null($resultPageSet)) {
                        $fields = array (
@@ -111,10 +110,15 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
                        $where[] = 'rc_this_oldid=page_latest';
                if (isset ($namespace))
                        $where['wl_namespace'] = $namespace;
+
                if (isset ($start))
-                       $where[] = 'rev_timestamp' . $after . $db->addQuotes($start);
+                       $where[] = 'rc_timestamp' . $after . $db->addQuotes($start);
+                       
                if (isset ($end))
-                       $where[] = 'rev_timestamp' . $before . $db->addQuotes($end);
+                       $where[] = 'rc_timestamp' . $before . $db->addQuotes($end);
+               
+               if (!isset ($start) && !isset ($end))
+                       $where[] = "rc_timestamp > ''";
 
                $this->profileDBIn();
                $res = $db->select($tables, $fields, $where, __METHOD__, $options);
index eff2055..8421afa 100644 (file)
@@ -105,7 +105,7 @@ class ApiResult extends ApiBase {
 
                $data = & $this->getData();
 
-               if (isset ($path)) {
+               if (!is_null($path)) {
                        if (is_array($path)) {
                                foreach ($path as $p) {
                                        if (!isset ($data[$p]))