Allow aliased field names with separated syntax
authorumherirrender <umherirrender_de.wp@web.de>
Wed, 15 Aug 2012 13:16:09 +0000 (15:16 +0200)
committerumherirrender <umherirrender_de.wp@web.de>
Wed, 15 Aug 2012 13:16:09 +0000 (15:16 +0200)
This introduce the syntax from aliased table names for aliased field
names into the abstract database layer:

array( 'alias' => 'field' ) gives 'field AS alias'

This patch also includes changes to query pages, api and some more
places to show, how the new syntax looks in "production".

This allow us to remove the "AS" for Non-PostgreSQL databases, if we
want that.

Change-Id: I5f0de1c2f29092c173aec3de93ffdef436799e8d

49 files changed:
includes/Category.php
includes/QueryPage.php
includes/Revision.php
includes/WikiPage.php
includes/api/ApiQueryAllCategories.php
includes/api/ApiQueryAllUsers.php
includes/api/ApiQueryCategoryInfo.php
includes/api/ApiQueryLinks.php
includes/api/ApiQueryTags.php
includes/db/Database.php
includes/db/ORMTable.php
includes/job/Job.php
includes/specials/SpecialActiveusers.php
includes/specials/SpecialAncientpages.php
includes/specials/SpecialBlockList.php
includes/specials/SpecialBrokenRedirects.php
includes/specials/SpecialDeadendpages.php
includes/specials/SpecialDisambiguations.php
includes/specials/SpecialDoubleRedirects.php
includes/specials/SpecialExport.php
includes/specials/SpecialFewestrevisions.php
includes/specials/SpecialFileDuplicateSearch.php
includes/specials/SpecialLinkSearch.php
includes/specials/SpecialListredirects.php
includes/specials/SpecialLonelypages.php
includes/specials/SpecialMIMEsearch.php
includes/specials/SpecialMostcategories.php
includes/specials/SpecialMostimages.php
includes/specials/SpecialMostlinked.php
includes/specials/SpecialMostlinkedcategories.php
includes/specials/SpecialMostlinkedtemplates.php
includes/specials/SpecialNewpages.php
includes/specials/SpecialPopularpages.php
includes/specials/SpecialShortpages.php
includes/specials/SpecialTags.php
includes/specials/SpecialUncategorizedimages.php
includes/specials/SpecialUncategorizedpages.php
includes/specials/SpecialUndelete.php
includes/specials/SpecialUnusedcategories.php
includes/specials/SpecialUnusedimages.php
includes/specials/SpecialUnusedtemplates.php
includes/specials/SpecialUnwatchedpages.php
includes/specials/SpecialWantedcategories.php
includes/specials/SpecialWantedfiles.php
includes/specials/SpecialWantedpages.php
includes/specials/SpecialWantedtemplates.php
includes/specials/SpecialWatchlist.php
includes/specials/SpecialWithoutinterwiki.php
tests/phpunit/includes/db/DatabaseSQLTest.php [new file with mode: 0644]

index 7987069..d9ca234 100644 (file)
@@ -301,9 +301,9 @@ class Category {
                $cond2 = $dbw->conditional( 'page_namespace=' . NS_FILE, 1, 'NULL' );
                $result = $dbw->selectRow(
                        array( 'categorylinks', 'page' ),
-                       array( 'COUNT(*) AS pages',
-                                  "COUNT($cond1) AS subcats",
-                                  "COUNT($cond2) AS files"
+                       array( 'pages' => 'COUNT(*)',
+                                  'subcats' => "COUNT($cond1)",
+                                  'files' => "COUNT($cond2)"
                        ),
                        array( 'cl_to' => $this->mName, 'page_id = cl_from' ),
                        __METHOD__,
index 501fd2f..076b1b5 100644 (file)
@@ -432,9 +432,9 @@ abstract class QueryPage extends SpecialPage {
                        $options['ORDER BY'] = 'qc_value ASC';
                }
                $res = $dbr->select( 'querycache', array( 'qc_type',
-                               'qc_namespace AS namespace',
-                               'qc_title AS title',
-                               'qc_value AS value' ),
+                               'namespace' => 'qc_namespace',
+                               'title' => 'qc_title',
+                               'value' => 'qc_value' ),
                                array( 'qc_type' => $this->getName() ),
                                __METHOD__, $options
                );
index 731a5f2..e7ddf3c 100644 (file)
@@ -1268,7 +1268,7 @@ class Revision implements IDBAccessObject {
         * @return Integer
         */
        static function countByPageId( $db, $id ) {
-               $row = $db->selectRow( 'revision', 'COUNT(*) AS revCount',
+               $row = $db->selectRow( 'revision', array( 'revCount' => 'COUNT(*)' ),
                        array( 'rev_page' => $id ), __METHOD__ );
                if( $row ) {
                        return $row->revCount;
index f4ed70d..5ec5819 100644 (file)
@@ -891,10 +891,10 @@ class WikiPage extends Page implements IDBAccessObject {
                $tables = array( 'revision', 'user' );
 
                $fields = array(
-                       'rev_user as user_id',
-                       'rev_user_text AS user_name',
+                       'user_id' => 'rev_user',
+                       'user_name' => 'rev_user_text',
                        $realNameField,
-                       'MAX(rev_timestamp) AS timestamp',
+                       'timestamp' => 'MAX(rev_timestamp)',
                );
 
                $conds = array( 'rev_page' => $this->getId() );
index 09f6edb..4f4c77f 100644 (file)
@@ -103,7 +103,7 @@ class ApiQueryAllCategories extends ApiQueryGeneratorBase {
                                        'pp_page=page_id',
                                        'pp_propname' => 'hiddencat' ) ),
                        ) );
-                       $this->addFields( 'pp_propname AS cat_hidden' );
+                       $this->addFields( array( 'cat_hidden' => 'pp_propname' ) );
                }
 
                $res = $this->select( __METHOD__ );
index 1e29a64..1325662 100644 (file)
@@ -152,7 +152,7 @@ class ApiQueryAllUsers extends ApiQueryBase {
                                'INNER JOIN', 'rc_user_text=user_name'
                        ) ) );
 
-                       $this->addFields( 'COUNT(*) AS recentedits' );
+                       $this->addFields( array( 'recentedits' => 'COUNT(*)' ) );
 
                        $this->addWhere( 'rc_log_type IS NULL OR rc_log_type != ' . $db->addQuotes( 'newusers' ) );
                        $timestamp = $db->timestamp( wfTimestamp( TS_UNIX ) - $wgActiveUserDays*24*3600 );
index 76246a2..31517fa 100644 (file)
@@ -62,7 +62,7 @@ class ApiQueryCategoryInfo extends ApiQueryBase {
                                'pp_propname' => 'hiddencat' ) ),
                ) );
 
-               $this->addFields( array( 'cat_title', 'cat_pages', 'cat_subcats', 'cat_files', 'pp_propname AS cat_hidden' ) );
+               $this->addFields( array( 'cat_title', 'cat_pages', 'cat_subcats', 'cat_files', 'cat_hidden' => 'pp_propname' ) );
                $this->addWhere( array( 'cat_title' => $cattitles ) );
 
                if ( !is_null( $params['continue'] ) ) {
index e54e2e8..9e4b7eb 100644 (file)
@@ -85,9 +85,9 @@ class ApiQueryLinks extends ApiQueryGeneratorBase {
                $params = $this->extractRequestParams();
 
                $this->addFields( array(
-                       $this->prefix . '_from AS pl_from',
-                       $this->prefix . '_namespace AS pl_namespace',
-                       $this->prefix . '_title AS pl_title'
+                       'pl_from' => $this->prefix . '_from',
+                       'pl_namespace' => $this->prefix . '_namespace',
+                       'pl_title' => $this->prefix . '_title'
                ) );
 
                $this->addTables( $this->table );
index edd1553..eb679e0 100644 (file)
@@ -59,7 +59,7 @@ class ApiQueryTags extends ApiQueryBase {
                $this->addTables( 'change_tag' );
                $this->addFields( 'ct_tag' );
 
-               $this->addFieldsIf( 'count(*) AS hitcount', $this->fld_hitcount );
+               $this->addFieldsIf( array( 'hitcount' => 'COUNT(*)' ), $this->fld_hitcount );
 
                $this->addOption( 'LIMIT', $this->limit + 1 );
                $this->addOption( 'GROUP BY', 'ct_tag' );
index 3bf0588..61061b2 100644 (file)
@@ -1202,10 +1202,12 @@ abstract class DatabaseBase implements DatabaseType {
         * @param $vars string|array
         *
         * May be either a field name or an array of field names. The field names
-        * here are complete fragments of SQL, for direct inclusion into the SELECT
-        * query. Expressions and aliases may be specified as in SQL, for example:
+        * can be complete fragments of SQL, for direct inclusion into the SELECT
+        * query. If an array is given, field aliases can be specified, for example:
         *
-        *   array( 'MAX(rev_id) AS maxrev' )
+        *   array( 'maxrev' => 'MAX(rev_id)' )
+        *
+        * This includes an expression with the alias "maxrev" in the query.
         *
         * If an expression is given, care must be taken to ensure that it is
         * DBMS-independent.
@@ -1335,7 +1337,7 @@ abstract class DatabaseBase implements DatabaseType {
                $options = array(), $join_conds = array() )
        {
                if ( is_array( $vars ) ) {
-                       $vars = implode( ',', $vars );
+                       $vars = implode( ',', $this->fieldNamesWithAlias( $vars ) );
                }
 
                $options = (array)$options;
@@ -1442,7 +1444,7 @@ abstract class DatabaseBase implements DatabaseType {
                $fname = 'DatabaseBase::estimateRowCount', $options = array() )
        {
                $rows = 0;
-               $res = $this->select( $table, 'COUNT(*) AS rowcount', $conds, $fname, $options );
+               $res = $this->select( $table, array( 'rowcount' => 'COUNT(*)' ), $conds, $fname, $options );
 
                if ( $res ) {
                        $row = $this->fetchRow( $res );
@@ -2044,6 +2046,39 @@ abstract class DatabaseBase implements DatabaseType {
                return $retval;
        }
 
+       /**
+        * Get an aliased field name
+        * e.g. fieldName AS newFieldName
+        *
+        * @param $name string Field name
+        * @param $alias string|bool Alias (optional)
+        * @return string SQL name for aliased field. Will not alias a field to its own name
+        */
+       public function fieldNameWithAlias( $name, $alias = false ) {
+               if ( !$alias || (string)$alias === (string)$name ) {
+                       return $name;
+               } else {
+                       return $name . ' AS ' . $alias; //PostgreSQL needs AS
+               }
+       }
+
+       /**
+        * Gets an array of aliased field names
+        *
+        * @param $fields array( [alias] => field )
+        * @return array of strings, see fieldNameWithAlias()
+        */
+       public function fieldNamesWithAlias( $fields ) {
+               $retval = array();
+               foreach ( $fields as $alias => $field ) {
+                       if ( is_numeric( $alias ) ) {
+                               $alias = $field;
+                       }
+                       $retval[] = $this->fieldNameWithAlias( $field, $alias );
+               }
+               return $retval;
+       }
+
        /**
         * Get the aliased table name clause for a FROM clause
         * which might have a JOIN and/or USE INDEX clause
index bd6bf0b..a77074f 100644 (file)
@@ -308,7 +308,7 @@ abstract class ORMTable implements IORMTable {
         */
        public function count( array $conditions = array(), array $options = array() ) {
                $res = $this->rawSelectRow(
-                       array( 'COUNT(*) AS rowcount' ),
+                       array( 'rowcount' => 'COUNT(*)' ),
                        $this->getPrefixedValues( $conditions ),
                        $options
                );
index fcf5ca8..d7c9563 100644 (file)
@@ -158,8 +158,8 @@ abstract class Job {
                if ( !$affected ) {
                        // Failed, someone else beat us to it
                        // Try getting a random row
-                       $row = $dbw->selectRow( 'job', array( 'MIN(job_id) as minjob',
-                               'MAX(job_id) as maxjob' ), '1=1', __METHOD__ );
+                       $row = $dbw->selectRow( 'job', array( 'minjob' => 'MIN(job_id)',
+                               'maxjob' => 'MAX(job_id)' ), '1=1', __METHOD__ );
                        if ( $row === false || is_null( $row->minjob ) || is_null( $row->maxjob ) ) {
                                // No jobs to get
                                wfProfileOut( __METHOD__ );
index 156b5f2..aefa6cc 100644 (file)
@@ -103,11 +103,11 @@ class ActiveUsersPager extends UsersPager {
 
                $query = array(
                        'tables' => array( 'recentchanges', 'user', 'ipblocks' ),
-                       'fields' => array( 'rc_user_text AS user_name', // inheritance
+                       'fields' => array( 'user_name' => 'rc_user_text', // inheritance
                                'rc_user_text', // for Pager
                                'user_id',
-                               'COUNT(*) AS recentedits',
-                               'MAX(ipb_user) AS blocked'
+                               'recentedits' => 'COUNT(*)',
+                               'blocked' => 'MAX(ipb_user)'
                        ),
                        'options' => array(
                                'GROUP BY' => array( 'rc_user_text', 'user_id' ),
index 1203e1f..6e3d49b 100644 (file)
@@ -41,9 +41,9 @@ class AncientPagesPage extends QueryPage {
        function getQueryInfo() {
                return array(
                        'tables' => array( 'page', 'revision' ),
-                       'fields' => array( 'page_namespace AS namespace',
-                                       'page_title AS title',
-                                       'rev_timestamp AS value' ),
+                       'fields' => array( 'namespace' => 'page_namespace',
+                                       'title' => 'page_title',
+                                       'value' => 'rev_timestamp' ),
                        'conds' => array( 'page_namespace' => MWNamespace::getContentNamespaces(),
                                        'page_is_redirect' => 0,
                                        'page_latest=rev_id' )
index 0a3a28f..7143d5b 100644 (file)
@@ -372,7 +372,7 @@ class BlockListPager extends TablePager {
                                'ipb_user',
                                'ipb_by',
                                'ipb_by_text',
-                               'user_name AS by_user_name',
+                               'by_user_name' => 'user_name',
                                'ipb_reason',
                                'ipb_timestamp',
                                'ipb_auto',
index d624430..8119e6d 100644 (file)
@@ -45,9 +45,9 @@ class BrokenRedirectsPage extends QueryPage {
                return array(
                        'tables' => array( 'redirect', 'p1' => 'page',
                                        'p2' => 'page' ),
-                       'fields' => array( 'p1.page_namespace AS namespace',
-                                       'p1.page_title AS title',
-                                       'p1.page_title AS value',
+                       'fields' => array( 'namespace' => 'p1.page_namespace',
+                                       'title' => 'p1.page_title',
+                                       'value' => 'p1.page_title',
                                        'rd_namespace',
                                        'rd_title'
                        ),
index 75818c9..f4904a5 100644 (file)
@@ -59,9 +59,9 @@ class DeadendPagesPage extends PageQueryPage {
        function getQueryInfo() {
                return array(
                        'tables' => array( 'page', 'pagelinks' ),
-                       'fields' => array( 'page_namespace AS namespace',
-                                       'page_title AS title',
-                                       'page_title AS value'
+                       'fields' => array( 'namespace' => 'page_namespace',
+                                       'title' => 'page_title',
+                                       'value' => 'page_title'
                        ),
                        'conds' => array( 'pl_from IS NULL',
                                        'page_namespace' => MWNamespace::getContentNamespaces(),
index e7606c6..48180a7 100644 (file)
@@ -99,9 +99,9 @@ class DisambiguationsPage extends QueryPage {
                                'p2' => 'page'
                        ),
                        'fields' => array(
-                               'p1.page_namespace AS namespace',
-                               'p1.page_title AS title',
-                               'pl_from AS value'
+                               'namespace' => 'p1.page_namespace',
+                               'title' => 'p1.page_title',
+                               'value' => 'pl_from'
                        ),
                        'conds' => array(
                                $this->getQueryFromLinkBatch(),
index 51cb08a..5864ca9 100644 (file)
@@ -47,13 +47,13 @@ class DoubleRedirectsPage extends QueryPage {
                        'tables' => array ( 'ra' => 'redirect',
                                        'rb' => 'redirect', 'pa' => 'page',
                                        'pb' => 'page', 'pc' => 'page' ),
-                       'fields' => array ( 'pa.page_namespace AS namespace',
-                                       'pa.page_title AS title',
-                                       'pa.page_title AS value',
-                                       'pb.page_namespace AS nsb',
-                                       'pb.page_title AS tb',
-                                       'pc.page_namespace AS nsc',
-                                       'pc.page_title AS tc' ),
+                       'fields' => array ( 'namespace' => 'pa.page_namespace',
+                                       'title' => 'pa.page_title',
+                                       'value' => 'pa.page_title',
+                                       'nsb' => 'pb.page_namespace',
+                                       'tb' => 'pb.page_title',
+                                       'nsc' => 'pc.page_namespace',
+                                       'tc' => 'pc.page_title' ),
                        'conds' => array ( 'ra.rd_from = pa.page_id',
                                        'pb.page_namespace = ra.rd_namespace',
                                        'pb.page_title = ra.rd_title',
index b00eec8..b4294b3 100644 (file)
@@ -455,7 +455,7 @@ class SpecialExport extends SpecialPage {
        private function getTemplates( $inputPages, $pageSet ) {
                return $this->getLinks( $inputPages, $pageSet,
                        'templatelinks',
-                       array( 'tl_namespace AS namespace', 'tl_title AS title' ),
+                       array( 'namespace' => 'tl_namespace', 'title' => 'tl_title' ),
                        array( 'page_id=tl_from' )
                );
        }
@@ -497,7 +497,7 @@ class SpecialExport extends SpecialPage {
                for( ; $depth > 0; --$depth ) {
                        $pageSet = $this->getLinks(
                                $inputPages, $pageSet, 'pagelinks',
-                               array( 'pl_namespace AS namespace', 'pl_title AS title' ),
+                               array( 'namespace' => 'pl_namespace', 'title' => 'pl_title' ),
                                array( 'page_id=pl_from' )
                        );
                        $inputPages = array_keys( $pageSet );
@@ -519,7 +519,7 @@ class SpecialExport extends SpecialPage {
                        $inputPages,
                        $pageSet,
                        'imagelinks',
-                       array( NS_FILE . ' AS namespace', 'il_to AS title' ),
+                       array( 'namespace' => NS_FILE, 'title' => 'il_to' ),
                        array( 'page_id=il_from' )
                );
        }
index 5610cc2..7e4bc9c 100644 (file)
@@ -44,10 +44,10 @@ class FewestrevisionsPage extends QueryPage {
        function getQueryInfo() {
                return array (
                        'tables' => array ( 'revision', 'page' ),
-                       'fields' => array ( 'page_namespace AS namespace',
-                                       'page_title AS title',
-                                       'COUNT(*) AS value',
-                                       'page_is_redirect AS redirect' ),
+                       'fields' => array ( 'namespace' => 'page_namespace',
+                                       'title' => 'page_title',
+                                       'value' => 'COUNT(*)',
+                                       'redirect' => 'page_is_redirect' ),
                        'conds' => array ( 'page_namespace' => MWNamespace::getContentNamespaces(),
                                        'page_id = rev_page' ),
                        'options' => array ( 'HAVING' => 'COUNT(*) > 1',
index f8e40e0..ccf8ba1 100644 (file)
@@ -78,8 +78,8 @@ class FileDuplicateSearchPage extends QueryPage {
                return array(
                        'tables' => array( 'image' ),
                        'fields' => array(
-                               'img_name AS title',
-                               'img_sha1 AS value',
+                               'title' => 'img_name',
+                               'value' => 'img_sha1',
                                'img_user_text',
                                'img_timestamp'
                        ),
index 0628269..0810ee7 100644 (file)
@@ -171,9 +171,9 @@ class LinkSearchPage extends QueryPage {
                $like = $dbr->buildLike( $stripped );
                $retval = array (
                        'tables' => array ( 'page', 'externallinks' ),
-                       'fields' => array ( 'page_namespace AS namespace',
-                                       'page_title AS title',
-                                       'el_index AS value', 'el_to AS url' ),
+                       'fields' => array ( 'namespace' => 'page_namespace',
+                                       'title' => 'page_title',
+                                       'value' => 'el_index', 'url' => 'el_to' ),
                        'conds' => array ( 'page_id = el_from',
                                        "$clause $like" ),
                        'options' => array( 'USE INDEX' => $clause )
index f9cf3e6..fe338a0 100644 (file)
@@ -41,14 +41,14 @@ class ListredirectsPage extends QueryPage {
        function getQueryInfo() {
                return array(
                        'tables' => array( 'p1' => 'page', 'redirect', 'p2' => 'page' ),
-                       'fields' => array( 'p1.page_namespace AS namespace',
-                                       'p1.page_title AS title',
-                                       'p1.page_title AS value',
+                       'fields' => array( 'namespace' => 'p1.page_namespace',
+                                       'title' => 'p1.page_title',
+                                       'value' => 'p1.page_title',
                                        'rd_namespace',
                                        'rd_title',
                                        'rd_fragment',
                                        'rd_interwiki',
-                                       'p2.page_id AS redirid' ),
+                                       'redirid' => 'p2.page_id' ),
                        'conds' => array( 'p1.page_is_redirect' => 1 ),
                        'join_conds' => array( 'redirect' => array(
                                        'LEFT JOIN', 'rd_from=p1.page_id' ),
index 0c86163..763bbdb 100644 (file)
@@ -50,9 +50,9 @@ class LonelyPagesPage extends PageQueryPage {
                return array (
                        'tables' => array ( 'page', 'pagelinks',
                                        'templatelinks' ),
-                       'fields' => array ( 'page_namespace AS namespace',
-                                       'page_title AS title',
-                                       'page_title AS value' ),
+                       'fields' => array ( 'namespace' => 'page_namespace',
+                                       'title' => 'page_title',
+                                       'value' => 'page_title' ),
                        'conds' => array ( 'pl_namespace IS NULL',
                                        'page_namespace' => MWNamespace::getContentNamespaces(),
                                        'page_is_redirect' => 0,
index 46a35c4..104c653 100644 (file)
@@ -45,9 +45,9 @@ class MIMEsearchPage extends QueryPage {
        public function getQueryInfo() {
                return array(
                        'tables' => array( 'image' ),
-                       'fields' => array( "'" . NS_FILE . "' AS namespace",
-                                       'img_name AS title',
-                                       'img_major_mime AS value',
+                       'fields' => array( 'namespace' => NS_FILE,
+                                       'title' => 'img_name',
+                                       'value' => 'img_major_mime',
                                        'img_size',
                                        'img_width',
                                        'img_height',
index 6de4840..3f0bafa 100644 (file)
@@ -41,9 +41,9 @@ class MostcategoriesPage extends QueryPage {
        function getQueryInfo() {
                return array (
                        'tables' => array ( 'categorylinks', 'page' ),
-                       'fields' => array ( 'page_namespace AS namespace',
-                                       'page_title AS title',
-                                       'COUNT(*) AS value' ),
+                       'fields' => array ( 'namespace' => 'page_namespace',
+                                       'title' => 'page_title',
+                                       'value' => 'COUNT(*)' ),
                        'conds' => array ( 'page_namespace' => MWNamespace::getContentNamespaces() ),
                        'options' => array ( 'HAVING' => 'COUNT(*) > 1',
                                'GROUP BY' => array( 'page_namespace', 'page_title' ) ),
index 7805e53..3d79790 100644 (file)
@@ -41,9 +41,9 @@ class MostimagesPage extends ImageQueryPage {
        function getQueryInfo() {
                return array (
                        'tables' => array ( 'imagelinks' ),
-                       'fields' => array ( "'" . NS_FILE . "' AS namespace",
-                                       'il_to AS title',
-                                       'COUNT(*) AS value' ),
+                       'fields' => array ( 'namespace' => NS_FILE,
+                                       'title' => 'il_to',
+                                       'value' => 'COUNT(*)' ),
                        'options' => array ( 'GROUP BY' => 'il_to',
                                        'HAVING' => 'COUNT(*) > 1' )
                );
index 3c3ab36..89c4350 100644 (file)
@@ -42,9 +42,9 @@ class MostlinkedPage extends QueryPage {
        function getQueryInfo() {
                return array (
                        'tables' => array ( 'pagelinks', 'page' ),
-                       'fields' => array ( 'pl_namespace AS namespace',
-                                       'pl_title AS title',
-                                       'COUNT(*) AS value',
+                       'fields' => array ( 'namespace' => 'pl_namespace',
+                                       'title' => 'pl_title',
+                                       'value' => 'COUNT(*)',
                                        'page_namespace' ),
                        'options' => array ( 'HAVING' => 'COUNT(*) > 1',
                                'GROUP BY' => array( 'pl_namespace', 'pl_title',
index 408d791..dadef8b 100644 (file)
@@ -40,9 +40,9 @@ class MostlinkedCategoriesPage extends QueryPage {
        function getQueryInfo() {
                return array (
                        'tables' => array ( 'category' ),
-                       'fields' => array ( 'cat_title AS title',
-                                       NS_CATEGORY . ' AS namespace',
-                                       'cat_pages AS value' ),
+                       'fields' => array ( 'title' => 'cat_title',
+                                       'namespace' => NS_CATEGORY,
+                                       'value' => 'cat_pages' ),
                );
        }
 
index 0b587dc..22932e5 100644 (file)
@@ -64,9 +64,9 @@ class MostlinkedTemplatesPage extends QueryPage {
        public function getQueryInfo() {
                return array (
                        'tables' => array ( 'templatelinks' ),
-                       'fields' => array ( 'tl_namespace AS namespace',
-                                       'tl_title AS title',
-                                       'COUNT(*) AS value' ),
+                       'fields' => array ( 'namespace' => 'tl_namespace',
+                                       'title' => 'tl_title',
+                                       'value' => 'COUNT(*)' ),
                        'conds' => array ( 'tl_namespace' => NS_TEMPLATE ),
                        'options' => array( 'GROUP BY' => array( 'tl_namespace', 'tl_title' ) )
                );
index 1798e8f..19ea171 100644 (file)
@@ -530,7 +530,7 @@ class NewPagesPager extends ReverseChronologicalPager {
                $fields = array(
                        'rc_namespace', 'rc_title', 'rc_cur_id', 'rc_user', 'rc_user_text',
                        'rc_comment', 'rc_timestamp', 'rc_patrolled','rc_id', 'rc_deleted',
-                       'page_len AS length', 'page_latest AS rev_id', 'ts_tags', 'rc_this_oldid',
+                       'length' => 'page_len', 'rev_id' => 'page_latest', 'ts_tags', 'rc_this_oldid',
                        'page_namespace', 'page_title'
                );
                $join_conds = array( 'page' => array( 'INNER JOIN', 'page_id=rc_cur_id' ) );
index 9f84804..448d179 100644 (file)
@@ -42,9 +42,9 @@ class PopularPagesPage extends QueryPage {
        function getQueryInfo() {
                return array (
                        'tables' => array( 'page' ),
-                       'fields' => array( 'page_namespace AS namespace',
-                                       'page_title AS title',
-                                       'page_counter AS value'),
+                       'fields' => array( 'namespace' => 'page_namespace',
+                                       'title' => 'page_title',
+                                       'value' => 'page_counter'),
                        'conds' => array( 'page_is_redirect' => 0,
                                        'page_namespace' => MWNamespace::getContentNamespaces() ) );
        }
index ee04574..5a4e8f0 100644 (file)
@@ -40,9 +40,9 @@ class ShortPagesPage extends QueryPage {
        function getQueryInfo() {
                return array (
                        'tables' => array ( 'page' ),
-                       'fields' => array ( 'page_namespace AS namespace',
-                                       'page_title AS title',
-                                       'page_len AS value' ),
+                       'fields' => array ( 'namespace' => 'page_namespace',
+                                       'title' => 'page_title',
+                                       'value' => 'page_len' ),
                        'conds' => array ( 'page_namespace' =>
                                        MWNamespace::getContentNamespaces(),
                                        'page_is_redirect' => 0 ),
index df720a1..c895dae 100644 (file)
@@ -47,7 +47,7 @@ class SpecialTags extends SpecialPage {
                                Xml::tags( 'th', null, $this->msg( 'tags-hitcount-header' )->parse() )
                        );
                $dbr = wfGetDB( DB_SLAVE );
-               $res = $dbr->select( 'change_tag', array( 'ct_tag', 'count(*) AS hitcount' ),
+               $res = $dbr->select( 'change_tag', array( 'ct_tag', 'hitcount' => 'count(*)' ),
                        array(), __METHOD__, array( 'GROUP BY' => 'ct_tag', 'ORDER BY' => 'hitcount DESC' ) );
 
                foreach ( $res as $row ) {
index 3efed74..5865bf6 100644 (file)
@@ -49,9 +49,9 @@ class UncategorizedImagesPage extends ImageQueryPage {
        function getQueryInfo() {
                return array (
                        'tables' => array( 'page', 'categorylinks' ),
-                       'fields' => array( 'page_namespace AS namespace',
-                                       'page_title AS title',
-                                       'page_title AS value' ),
+                       'fields' => array( 'namespace' => 'page_namespace',
+                                       'title' => 'page_title',
+                                       'value' => 'page_title' ),
                        'conds' => array( 'cl_from IS NULL',
                                        'page_namespace' => NS_FILE,
                                        'page_is_redirect' => 0 ),
index 08a6944..1226a6c 100644 (file)
@@ -46,9 +46,9 @@ class UncategorizedPagesPage extends PageQueryPage {
        function getQueryInfo() {
                return array (
                        'tables' => array ( 'page', 'categorylinks' ),
-                       'fields' => array ( 'page_namespace AS namespace',
-                                       'page_title AS title',
-                                       'page_title AS value' ),
+                       'fields' => array ( 'namespace' => 'page_namespace',
+                                       'title' => 'page_title',
+                                       'value' => 'page_title' ),
                        // default for page_namespace is all content namespaces (if requestedNamespace is false)
                        // otherwise, page_namespace is requestedNamespace
                        'conds' => array ( 'cl_from IS NULL',
index 611b3b9..dfdd08e 100644 (file)
@@ -92,7 +92,7 @@ class PageArchive {
                                array(
                                        'ar_namespace',
                                        'ar_title',
-                                       'COUNT(*) AS count'
+                                       'count' => 'COUNT(*)'
                                ),
                                $condition,
                                __METHOD__,
index 611a33c..1bd38e1 100644 (file)
@@ -39,9 +39,9 @@ class UnusedCategoriesPage extends QueryPage {
        function getQueryInfo() {
                return array (
                        'tables' => array ( 'page', 'categorylinks' ),
-                       'fields' => array ( 'page_namespace AS namespace',
-                                       'page_title AS title',
-                                       'page_title AS value' ),
+                       'fields' => array ( 'namespace' => 'page_namespace',
+                                       'title' => 'page_title',
+                                       'value' => 'page_title' ),
                        'conds' => array ( 'cl_from IS NULL',
                                        'page_namespace' => NS_CATEGORY,
                                        'page_is_redirect' => 0 ),
index 9c8ccfa..cdab557 100644 (file)
@@ -47,9 +47,9 @@ class UnusedimagesPage extends ImageQueryPage {
                global $wgCountCategorizedImagesAsUsed;
                $retval = array (
                        'tables' => array ( 'image', 'imagelinks' ),
-                       'fields' => array ( "'" . NS_FILE . "' AS namespace",
-                                       'img_name AS title',
-                                       'img_timestamp AS value',
+                       'fields' => array ( 'namespace' => NS_FILE,
+                                       'title' => 'img_name',
+                                       'value' => 'img_timestamp',
                                        'img_user', 'img_user_text',
                                        'img_description' ),
                        'conds' => array ( 'il_to IS NULL' ),
index 0928e26..06077d1 100644 (file)
@@ -42,9 +42,9 @@ class UnusedtemplatesPage extends QueryPage {
        function getQueryInfo() {
                return array (
                        'tables' => array ( 'page', 'templatelinks' ),
-                       'fields' => array ( 'page_namespace AS namespace',
-                                       'page_title AS title',
-                                       'page_title AS value' ),
+                       'fields' => array ( 'namespace' => 'page_namespace',
+                                       'title' => 'page_title',
+                                       'value' => 'page_title' ),
                        'conds' => array ( 'page_namespace' => NS_TEMPLATE,
                                        'tl_from IS NULL',
                                        'page_is_redirect' => 0 ),
index 4bd0232..e5a7941 100644 (file)
@@ -41,9 +41,9 @@ class UnwatchedpagesPage extends QueryPage {
        function getQueryInfo() {
                return array (
                        'tables' => array ( 'page', 'watchlist' ),
-                       'fields' => array ( 'page_namespace AS namespace',
-                                       'page_title AS title',
-                                       'page_namespace AS value' ),
+                       'fields' => array ( 'namespace' => 'page_namespace',
+                                       'title' => 'page_title',
+                                       'value' => 'page_namespace' ),
                        'conds' => array ( 'wl_title IS NULL',
                                        'page_is_redirect' => 0,
                                        "page_namespace != '" . NS_MEDIAWIKI .
index f497e4e..0b1fb25 100644 (file)
@@ -37,9 +37,9 @@ class WantedCategoriesPage extends WantedQueryPage {
        function getQueryInfo() {
                return array (
                        'tables' => array ( 'categorylinks', 'page' ),
-                       'fields' => array ( "'" . NS_CATEGORY . "' AS namespace",
-                                       'cl_to AS title',
-                                       'COUNT(*) AS value' ),
+                       'fields' => array ( 'namespace' => NS_CATEGORY,
+                                       'title' => 'cl_to',
+                                       'value' => 'COUNT(*)' ),
                        'conds' => array ( 'page_title IS NULL' ),
                        'options' => array ( 'GROUP BY' => 'cl_to' ),
                        'join_conds' => array ( 'page' => array ( 'LEFT JOIN',
index 2475189..f52f7bb 100644 (file)
@@ -75,9 +75,9 @@ class WantedFilesPage extends WantedQueryPage {
        function getQueryInfo() {
                return array (
                        'tables' => array ( 'imagelinks', 'image' ),
-                       'fields' => array ( "'" . NS_FILE . "' AS namespace",
-                                       'il_to AS title',
-                                       'COUNT(*) AS value' ),
+                       'fields' => array ( 'namespace' => NS_FILE,
+                                       'title' => 'il_to',
+                                       'value' => 'COUNT(*)' ),
                        'conds' => array ( 'img_name IS NULL' ),
                        'options' => array ( 'GROUP BY' => 'il_to' ),
                        'join_conds' => array ( 'image' =>
index 9f5d52d..7673305 100644 (file)
@@ -60,9 +60,9 @@ class WantedPagesPage extends WantedQueryPage {
                                'pg2' => 'page'
                        ),
                        'fields' => array(
-                               'pl_namespace AS namespace',
-                               'pl_title AS title',
-                               'COUNT(*) AS value'
+                               'namespace' => 'pl_namespace',
+                               'title' => 'pl_title',
+                               'value' => 'COUNT(*)'
                        ),
                        'conds' => array(
                                'pg1.page_namespace IS NULL',
index 2b4364b..f3e3369 100644 (file)
@@ -40,9 +40,9 @@ class WantedTemplatesPage extends WantedQueryPage {
        function getQueryInfo() {
                return array (
                        'tables' => array ( 'templatelinks', 'page' ),
-                       'fields' => array ( 'tl_namespace AS namespace',
-                                       'tl_title AS title',
-                                       'COUNT(*) AS value' ),
+                       'fields' => array ( 'namespace' => 'tl_namespace',
+                                       'title' => 'tl_title',
+                                       'value' => 'COUNT(*)' ),
                        'conds' => array ( 'page_title IS NULL',
                                        'tl_namespace' => NS_TEMPLATE ),
                        'options' => array (
index a81eb5b..5dfc113 100644 (file)
@@ -500,7 +500,7 @@ class SpecialWatchlist extends SpecialPage {
                $dbr = wfGetDB( DB_SLAVE, 'watchlist' );
 
                # Fetch the raw count
-               $res = $dbr->select( 'watchlist', 'COUNT(*) AS count',
+               $res = $dbr->select( 'watchlist', array( 'count' => 'COUNT(*)' ),
                        array( 'wl_user' => $this->getUser()->getId() ), __METHOD__ );
                $row = $dbr->fetchObject( $res );
                $count = $row->count;
index 74eedc3..2988b04 100644 (file)
@@ -80,9 +80,9 @@ class WithoutInterwikiPage extends PageQueryPage {
        function getQueryInfo() {
                $query = array (
                        'tables' => array ( 'page', 'langlinks' ),
-                       'fields' => array ( 'page_namespace AS namespace',
-                                       'page_title AS title',
-                                       'page_title AS value' ),
+                       'fields' => array ( 'namespace' => 'page_namespace',
+                                       'title' => 'page_title',
+                                       'value' => 'page_title' ),
                        'conds' => array ( 'll_title IS NULL',
                                        'page_namespace' => MWNamespace::getContentNamespaces(),
                                        'page_is_redirect' => 0 ),
diff --git a/tests/phpunit/includes/db/DatabaseSQLTest.php b/tests/phpunit/includes/db/DatabaseSQLTest.php
new file mode 100644 (file)
index 0000000..d56e632
--- /dev/null
@@ -0,0 +1,75 @@
+<?php
+
+/**
+ * Test the abstract database layer
+ * Using Mysql for the sql at the moment TODO
+ *
+ * @group Database
+ */
+class DatabaseSQLTest extends MediaWikiTestCase {
+
+       public function setUp() {
+               // TODO support other DBMS or find another way to do it
+               if( $this->db->getType() !== 'mysql' ) {
+                       $this->markTestSkipped( 'No mysql database' );
+               }
+       }
+
+       /**
+        * @dataProvider dataSQL
+        */
+       function testSQL( $sql, $sqlText ) {
+               $this->assertEquals( trim( $this->db->selectSQLText(
+                       isset( $sql['tables'] ) ? $sql['tables'] : array(),
+                       isset( $sql['fields'] ) ? $sql['fields'] : array(),
+                       isset( $sql['conds'] ) ? $sql['conds'] : array(),
+                       __METHOD__,
+                       isset( $sql['options'] ) ? $sql['options'] : array(),
+                       isset( $sql['join_conds'] ) ? $sql['join_conds'] : array()
+               ) ), $sqlText );
+       }
+
+       function dataSQL() {
+               return array(
+                       array(
+                               array(
+                                       'tables' => 'table',
+                                       'fields' => array( 'field', 'alias' => 'field2' ),
+                                       'conds' => array( 'alias' => 'text' ),
+                               ),
+                               "SELECT  field,field2 AS alias  " .
+                               "FROM `unittest_table`  " .
+                               "WHERE alias = 'text'"
+                       ),
+                       array(
+                               array(
+                                       'tables' => 'table',
+                                       'fields' => array( 'field', 'alias' => 'field2' ),
+                                       'conds' => array( 'alias' => 'text' ),
+                                       'options' => array( 'LIMIT' => 1, 'ORDER BY' => 'field' ),
+                               ),
+                               "SELECT  field,field2 AS alias  " .
+                               "FROM `unittest_table`  " .
+                               "WHERE alias = 'text'  " .
+                               "ORDER BY field " .
+                               "LIMIT 1"
+                       ),
+                       array(
+                               array(
+                                       'tables' => array( 'table', 't2' => 'table2' ),
+                                       'fields' => array( 'tid', 'field', 'alias' => 'field2', 't2.id' ),
+                                       'conds' => array( 'alias' => 'text' ),
+                                       'options' => array( 'LIMIT' => 1, 'ORDER BY' => 'field' ),
+                                       'join_conds' => array( 't2' => array(
+                                               'LEFT JOIN', 'tid = t2.id'
+                                       )),
+                               ),
+                               "SELECT  tid,field,field2 AS alias,t2.id  " .
+                               "FROM `unittest_table` LEFT JOIN `unittest_table2` `t2` ON ((tid = t2.id))  " .
+                               "WHERE alias = 'text'  " .
+                               "ORDER BY field " .
+                               "LIMIT 1"
+                       ),
+               );
+       }
+}
\ No newline at end of file