1) Use CREATE TEMPORARY TABLE ... LIKE for MySQL >= 4.1
authorWil Mahan <wmahan@users.mediawiki.org>
Mon, 27 Sep 2004 21:14:52 +0000 (21:14 +0000)
committerWil Mahan <wmahan@users.mediawiki.org>
Mon, 27 Sep 2004 21:14:52 +0000 (21:14 +0000)
and PostgreSQL (untested, but should fix bug 585). Use a
hack for older MySQL versions that doesn't require including
a .sql file.
2) Die gracefully when an article has an invalid title or
already exists in the database.
3) Detect and report duplicate sections in the test file.

maintenance/parserTests.php
maintenance/parserTests.sql [deleted file]
maintenance/parserTests.txt

index 06e50bc..9e6b1b8 100644 (file)
@@ -115,7 +115,7 @@ class ParserTest {
                                        if( !isset( $data['article'] ) ) {
                                                die( "'endarticle' without 'article' at line $n\n" );
                                        }
-                                       $this->addArticle($this->chomp($data['article']), $this->chomp($data['text']));
+                                       $this->addArticle($this->chomp($data['article']), $this->chomp($data['text']), $n);
                                        $data = array();
                                        $section = null;
                                        continue;
@@ -155,6 +155,9 @@ class ParserTest {
                                        $section = null;
                                        continue;
                                }
+                               if ( isset ($data[$section] ) ) {
+                                       die ( "duplicate section '$section' at line $n\n" );
+                               }
                                $data[$section] = '';
                                continue;
                        }
@@ -282,28 +285,69 @@ class ParserTest {
         * Currently this will only be done once per run, and any changes to
         * the db will be visible to later tests in the run.
         *
-        * This is ugly, but we need a way to modify the database
-        * without breaking anything. Currently it isn't possible
-        * to roll back transactions, which might help with this.
-        * -- wtm
-        *
         * @access private
         */
        function setupDatabase() {
                static $setupDB = false;
-               if (!$setupDB && $GLOBALS['wgDBprefix'] === 'parsertest') {
+               global $wgDBprefix;
+
+               # Make sure we don't mess with the live DB
+               if (!$setupDB && $wgDBprefix === 'parsertest') {
                        $db =& wfGetDB( DB_MASTER );
-                       if (0) {
-                               # XXX CREATE TABLE ... LIKE requires MySQL 4.1
-                               $tables = array('cur', 'interwiki', 'brokenlinks', 'recentchanges');
+
+                       # List of temporary tables to create, without prefix
+                       # Some of these probably aren't necessary
+                       $tables = array('user', 'cur', 'old', 'links',
+                               'brokenlinks', 'imagelinks', 'categorylinks',
+                               'linkscc', 'site_stats', 'hitcounter',
+                               'ipblocks', 'image', 'oldimage',
+                               'recentchanges',
+                               'watchlist', 'math', 'searchindex',
+                               'interwiki', 'querycache',
+                               'objectcache', 'blobs', 'validate'
+                       );
+                       
+                       # List of tables whose contents we need to copy
+                       $copy_tables = array('interwiki');
+
+                       if (!(strcmp($db->getServerVersion(), '4.1') < 0 and stristr($db->getSoftwareLink(), 'MySQL'))) {
+                               # Database that supports CREATE TABLE ... LIKE
                                foreach ($tables as $tbl) {
-                                       $db->query('CREATE TEMPORARY TABLE ' . $GLOBALS['wgDBprefix'] . "$tbl LIKE $tbl");
+                                       $db->query("CREATE TEMPORARY TABLE $wgDBprefix$tbl LIKE $tbl");
                                }
                        }
                        else {
-                               # HACK, sorry
-                               dbsource( 'maintenance/parserTests.sql', $db );
+                               # Hack for MySQL versions < 4.1, which don't support
+                               # "CREATE TABLE ... LIKE". Note that
+                               # "CREATE TEMPORARY TABLE ... SELECT * FROM ... LIMIT 0"
+                               # would not create the indexes we need....
+                               foreach ($tables as $tbl) {
+                                       $res = $db->query("SHOW CREATE TABLE $tbl");
+                                       $row = $db->fetchRow($res);
+                                       $create = $row[1];
+                                       $create_tmp = preg_replace('/CREATE TABLE `(.*?)`/', 'CREATE TEMPORARY TABLE `'
+                                               . $wgDBprefix . '\\1`', $create);
+                                       if ($create === $create_tmp) {
+                                               # Couldn't do replacement
+                                               die("could not create temporary table $tbl");
+                                       }
+                                       $db->query($create_tmp);
+                               }
+
+                       }
+
+                       foreach ($copy_tables as $tbl) {
+                               $db->query("INSERT INTO $wgDBprefix$tbl SELECT * FROM $tbl");
                        }
+
+                       # Hack: insert a few Wikipedia in-project interwiki prefixes,
+                       # for testing inter-language links
+                       $db->query("INSERT INTO ${wgDBprefix}interwiki
+                               (iw_prefix,iw_url,iw_local) VALUES
+                               ('zh','http://zh.wikipedia.org/wiki/$1',1),
+                               ('es','http://es.wikipedia.org/wiki/$1',1),
+                               ('fr','http://fr.wikipedia.org/wiki/$1',1)");
+
                        $setupDB = true;
                }
        }
@@ -431,14 +475,22 @@ class ParserTest {
         * Insert a temporary test article
         * @param $name string the title, including any prefix
         * @param $text string the article text
+        * @param $line int the input line number, for reporting errors
         * @static
         * @access private
         */
-       function addArticle($name, $text) {
-               # TODO: check if article exists and die gracefully
-               # if we are trying to insert a duplicate
+       function addArticle($name, $text, $line) {
                $this->setupGlobals();
                $title = Title::newFromText( $name );
+               if ( is_null($title) ) {
+                       die( "invalid title at line $line\n" );
+               }
+
+               $aid = $title->getArticleID( GAID_FOR_UPDATE );
+               if ($aid != 0) {
+                       die( "duplicate article at line $line\n" );
+               }
+
                $art = new Article($title);
                $art->insertNewArticle($text, '', false, false );
                $this->teardownGlobals();
diff --git a/maintenance/parserTests.sql b/maintenance/parserTests.sql
deleted file mode 100644 (file)
index 26e22af..0000000
+++ /dev/null
@@ -1,293 +0,0 @@
--- HACK: this should go away when there is a better way
-
-CREATE TEMPORARY TABLE parsertestuser (
-  user_id int(5) unsigned NOT NULL auto_increment,
-  user_name varchar(255) binary NOT NULL default '',
-  user_real_name varchar(255) binary NOT NULL default '',
-  user_password tinyblob NOT NULL default '',
-  user_newpassword tinyblob NOT NULL default '',
-  user_email tinytext NOT NULL default '',
-  user_options blob NOT NULL default '',
-  user_touched char(14) binary NOT NULL default '',
-  PRIMARY KEY user_id (user_id),
-  INDEX user_name (user_name(10))
-);
-
-CREATE TEMPORARY TABLE parsertestcur (
-  cur_id int(8) unsigned NOT NULL auto_increment,
-  cur_namespace tinyint(2) unsigned NOT NULL default '0',
-  cur_title varchar(255) binary NOT NULL default '',
-  cur_text mediumtext NOT NULL default '',
-  cur_comment tinyblob NOT NULL default '',
-  cur_user int(5) unsigned NOT NULL default '0',
-  cur_user_text varchar(255) binary NOT NULL default '',
-  cur_timestamp char(14) binary NOT NULL default '',
-  cur_restrictions tinyblob NOT NULL default '',
-  cur_counter bigint(20) unsigned NOT NULL default '0',
-  cur_is_redirect tinyint(1) unsigned NOT NULL default '0',
-  cur_minor_edit tinyint(1) unsigned NOT NULL default '0',
-  cur_is_new tinyint(1) unsigned NOT NULL default '0',
-  cur_random real unsigned NOT NULL,
-  cur_touched char(14) binary NOT NULL default '',
-  inverse_timestamp char(14) binary NOT NULL default '',
-  PRIMARY KEY cur_id (cur_id),
-  UNIQUE INDEX name_title (cur_namespace,cur_title),
-  
-  -- Is this one necessary?
-  INDEX cur_title (cur_title(20)),
-  
-  INDEX cur_timestamp (cur_timestamp),
-  INDEX (cur_random),
-  INDEX name_title_timestamp (cur_namespace,cur_title,inverse_timestamp),
-  INDEX user_timestamp (cur_user,inverse_timestamp),
-  INDEX usertext_timestamp (cur_user_text,inverse_timestamp),
-  INDEX namespace_redirect_timestamp(cur_namespace,cur_is_redirect,cur_timestamp)
-);
-
-CREATE TEMPORARY TABLE parsertestold (
-  old_id int(8) unsigned NOT NULL auto_increment,
-  old_namespace tinyint(2) unsigned NOT NULL default '0',
-  old_title varchar(255) binary NOT NULL default '',
-  old_text mediumtext NOT NULL default '',
-  old_comment tinyblob NOT NULL default '',
-  old_user int(5) unsigned NOT NULL default '0',
-  old_user_text varchar(255) binary NOT NULL,
-  old_timestamp char(14) binary NOT NULL default '',
-  old_minor_edit tinyint(1) NOT NULL default '0',
-  old_flags tinyblob NOT NULL default '',
-  inverse_timestamp char(14) binary NOT NULL default '',
-  
-  PRIMARY KEY old_id (old_id),
-  INDEX old_timestamp (old_timestamp),
-  INDEX name_title_timestamp (old_namespace,old_title,inverse_timestamp),
-  INDEX user_timestamp (old_user,inverse_timestamp),
-  INDEX usertext_timestamp (old_user_text,inverse_timestamp)
-);
-
-CREATE TEMPORARY TABLE parsertestlinks (
-  l_from int(8) unsigned NOT NULL default '0',
-  l_to int(8) unsigned NOT NULL default '0',
-  UNIQUE KEY l_from(l_from,l_to),
-  KEY (l_to)
-);
-
-CREATE TEMPORARY TABLE parsertestbrokenlinks (
-  bl_from int(8) unsigned NOT NULL default '0',
-  bl_to varchar(255) binary NOT NULL default '',
-  UNIQUE KEY bl_from(bl_from,bl_to),
-  KEY (bl_to)
-);
-
-CREATE TEMPORARY TABLE parsertestimagelinks (
-  il_from int(8) unsigned NOT NULL default '0',
-  il_to varchar(255) binary NOT NULL default '',
-  UNIQUE KEY il_from(il_from,il_to),
-  KEY (il_to)
-);
-
-CREATE TEMPORARY TABLE parsertestcategorylinks (
-  cl_from int(8) unsigned NOT NULL default '0',
-  cl_to varchar(255) binary NOT NULL default '',
-  cl_sortkey varchar(255) binary NOT NULL default '',
-  cl_timestamp timestamp NOT NULL,
-  UNIQUE KEY cl_from(cl_from,cl_to),
-  KEY cl_sortkey(cl_to,cl_sortkey(128)),
-  KEY cl_timestamp(cl_to,cl_timestamp)
-);
-
---
--- Stores (possibly gzipped) serialized objects with
--- cache arrays to reduce database load slurping up
--- from links and brokenlinks.
---
-CREATE TEMPORARY TABLE parsertestlinkscc (
-  lcc_pageid INT UNSIGNED NOT NULL UNIQUE KEY,
-  lcc_cacheobj MEDIUMBLOB NOT NULL
-);
-
-CREATE TEMPORARY TABLE parsertestsite_stats (
-  ss_row_id int(8) unsigned NOT NULL,
-  ss_total_views bigint(20) unsigned default '0',
-  ss_total_edits bigint(20) unsigned default '0',
-  ss_good_articles bigint(20) unsigned default '0',
-  UNIQUE KEY ss_row_id (ss_row_id)
-);
-
-CREATE TEMPORARY TABLE parsertesthitcounter (
-  hc_id INTEGER UNSIGNED NOT NULL
-) TYPE=HEAP MAX_ROWS=25000;
-
-CREATE TEMPORARY TABLE parsertestipblocks (
-  ipb_id int(8) NOT NULL auto_increment,
-  ipb_address varchar(40) binary NOT NULL default '',
-  ipb_user int(8) unsigned NOT NULL default '0',
-  ipb_by int(8) unsigned NOT NULL default '0',
-  ipb_reason tinyblob NOT NULL default '',
-  ipb_timestamp char(14) binary NOT NULL default '',
-  ipb_auto tinyint(1) NOT NULL default '0',
-  ipb_expiry char(14) binary NOT NULL default '',
-
-  PRIMARY KEY ipb_id (ipb_id),
-  INDEX ipb_address (ipb_address),
-  INDEX ipb_user (ipb_user)
-);
-
-CREATE TEMPORARY TABLE parsertestimage (
-  img_name varchar(255) binary NOT NULL default '',
-  img_size int(8) unsigned NOT NULL default '0',
-  img_description tinyblob NOT NULL default '',
-  img_user int(5) unsigned NOT NULL default '0',
-  img_user_text varchar(255) binary NOT NULL default '',
-  img_timestamp char(14) binary NOT NULL default '',
-  PRIMARY KEY img_name (img_name),
-  INDEX img_size (img_size),
-  INDEX img_timestamp (img_timestamp)
-);
-
-CREATE TEMPORARY TABLE parsertestoldimage (
-  oi_name varchar(255) binary NOT NULL default '',
-  oi_archive_name varchar(255) binary NOT NULL default '',
-  oi_size int(8) unsigned NOT NULL default 0,
-  oi_description tinyblob NOT NULL default '',
-  oi_user int(5) unsigned NOT NULL default '0',
-  oi_user_text varchar(255) binary NOT NULL default '',
-  oi_timestamp char(14) binary NOT NULL default '',
-  INDEX oi_name (oi_name(10))
-);
-
-CREATE TEMPORARY TABLE parsertestrecentchanges (
-  rc_id int(8) NOT NULL auto_increment,
-  rc_timestamp varchar(14) binary NOT NULL default '',
-  rc_cur_time varchar(14) binary NOT NULL default '',
-  rc_user int(10) unsigned NOT NULL default '0',
-  rc_user_text varchar(255) binary NOT NULL default '',
-  rc_namespace tinyint(3) NOT NULL default '0',
-  rc_title varchar(255) binary NOT NULL default '',
-  rc_comment varchar(255) binary NOT NULL default '',
-  rc_minor tinyint(3) unsigned NOT NULL default '0',
-  rc_bot tinyint(3) unsigned NOT NULL default '0',
-  rc_new tinyint(3) unsigned NOT NULL default '0',
-  rc_cur_id int(10) unsigned NOT NULL default '0',
-  rc_this_oldid int(10) unsigned NOT NULL default '0',
-  rc_last_oldid int(10) unsigned NOT NULL default '0',
-  rc_type tinyint(3) unsigned NOT NULL default '0',
-  rc_moved_to_ns tinyint(3) unsigned NOT NULL default '0',
-  rc_moved_to_title varchar(255) binary NOT NULL default '',
-  rc_patrolled tinyint(3) unsigned NOT NULL default '0',
-  rc_ip char(15) NOT NULL default '',
-  
-  PRIMARY KEY rc_id (rc_id),
-  INDEX rc_timestamp (rc_timestamp),
-  INDEX rc_namespace_title (rc_namespace, rc_title),
-  INDEX rc_cur_id (rc_cur_id),
-  INDEX new_name_timestamp(rc_new,rc_namespace,rc_timestamp),
-  INDEX rc_ip (rc_ip)
-);
-
-CREATE TEMPORARY TABLE parsertestwatchlist (
-  wl_user int(5) unsigned NOT NULL,
-  wl_namespace tinyint(2) unsigned NOT NULL default '0',
-  wl_title varchar(255) binary NOT NULL default '',
-  UNIQUE KEY (wl_user, wl_namespace, wl_title),
-  KEY namespace_title (wl_namespace,wl_title)
-);
-
-CREATE TEMPORARY TABLE parsertestmath (
-  math_inputhash varchar(16) NOT NULL,
-  math_outputhash varchar(16) NOT NULL,
-  math_html_conservativeness tinyint(1) NOT NULL,
-  math_html text,
-  math_mathml text,
-  UNIQUE KEY math_inputhash (math_inputhash)
-);
-
-
--- Table searchindex must be MyISAM for fulltext support
-
-CREATE TEMPORARY TABLE parsertestsearchindex (
-  si_page int(8) unsigned NOT NULL,
-  si_title varchar(255) NOT NULL default '',
-  si_text mediumtext NOT NULL default '',
-  UNIQUE KEY (si_page),
-  FULLTEXT si_title (si_title),
-  FULLTEXT si_text (si_text)
-
-) TYPE=MyISAM;
-
-CREATE TEMPORARY TABLE parsertestinterwiki (
-  iw_prefix char(32) NOT NULL,
-  iw_url char(127) NOT NULL,
-  iw_local BOOL NOT NULL,
-  UNIQUE KEY iw_prefix (iw_prefix)
-);
-
--- Used for caching expensive grouped queries
-CREATE TEMPORARY TABLE parsertestquerycache (
-  qc_type char(32) NOT NULL,
-  qc_value int(5) unsigned NOT NULL default '0',
-  qc_namespace tinyint(2) unsigned NOT NULL default '0',
-  qc_title char(255) binary NOT NULL default '',
-  KEY (qc_type,qc_value)
-);
-
--- For a few generic cache operations if not using Memcached
-CREATE TEMPORARY TABLE parsertestobjectcache (
-  keyname char(255) binary not null default '',
-  value mediumblob,
-  exptime datetime,
-  unique key (keyname),
-  key (exptime)
-);
-
--- For storing revision text
-CREATE TEMPORARY TABLE parsertestblobs (
-  blob_index char(255) binary NOT NULL default '',
-  blob_data longblob NOT NULL default '',
-  UNIQUE key blob_index (blob_index)
-);
-
--- For article validation
-
-CREATE TEMPORARY TABLE `parsertestvalidate` (
-  `val_user` int(11) NOT NULL default '0',
-  `val_title` varchar(255) binary NOT NULL default '',
-  `val_timestamp` varchar(14) binary NOT NULL default '',
-  `val_type` int(10) unsigned NOT NULL default '0',
-  `val_value` int(11) default '0',
-  `val_comment` varchar(255) NOT NULL default '',
-  KEY `val_user` (`val_user`,`val_title`,`val_timestamp`)
-);
-
-
-CREATE TEMPORARY TABLE parsertestlogging (
-  -- Symbolic keys for the general log type and the action type
-  -- within the log. The output format will be controlled by the
-  -- action field, but only the type controls categorization.
-  log_type char(10) NOT NULL default '',
-  log_action char(10) NOT NULL default '',
-  
-  -- Timestamp. Duh.
-  log_timestamp char(14) NOT NULL default '19700101000000',
-  
-  -- The user who performed this action; key to user_id
-  log_user int unsigned NOT NULL default 0,
-  
-  -- Key to the page affected. Where a user is the target,
-  -- this will point to the user page.
-  log_namespace tinyint unsigned NOT NULL default 0,
-  log_title varchar(255) NOT NULL default '',
-  
-  -- Freeform text. Interpreted as edit history comments.
-  log_comment varchar(255) NOT NULL default '',
-  
-  KEY type_time (log_type, log_timestamp),
-  KEY user_time (log_user, log_timestamp),
-  KEY page_time (log_namespace, log_title, log_timestamp)
-);
-
-INSERT INTO parsertestinterwiki (iw_prefix,iw_url,iw_local) VALUES
-       ('MeatBall','http://www.usemod.com/cgi-bin/mb.pl?$1',0),
-       ('es','http://es.wikipedia.org/wiki/$1',1),
-       ('fr','http://fr.wikipedia.org/wiki/$1',1),
-       ('zh','http://zh.wikipedia.org/wiki/$1',1);
-
index 68d34a5..abe4107 100644 (file)
@@ -30,7 +30,6 @@ Main Page
 blah blah
 !! endarticle
 
-
 ###
 ### Basic tests
 ###
@@ -40,6 +39,7 @@ Blank input
 !! result
 !! end
 
+
 !! test
 Simple paragraph
 !! input
@@ -296,7 +296,7 @@ Definition list with wikilink containing colon
 !! input
 ; [[Wikipedia:FAQ]]: The least-read page on Wikipedia
 !! result
-<dl><dt> <a href="/index.php?title=Wikipedia:FAQ&amp;action=edit" class="new" title="Wikipedia:FAQ">Wikipedia:FAQ</a></dt><dd> The least-read page on Wikipedia
+<dl><dt> <a href="http://en.wikipedia.org/wiki/FAQ" class='extiw'>Wikipedia:FAQ</a></dt><dd> The least-read page on Wikipedia
 </dd></dl>
 
 !! end
@@ -322,6 +322,16 @@ Malformed definition list with colon
 
 !! end
 
+!! test
+Definition lists: colon in external link text
+!! input
+; [http://www.wikipedia2.org/ Wikipedia : The Next Generation]: OK, I made that up
+!! result
+<dl><dt> <a href="http://www.wikipedia2.org/" class='external' title="http://www.wikipedia2.org/">Wikipedia&nbsp;: The Next Generation</a><span class='urlexpansion'> (<i>http://www.wikipedia2.org/</i>)</span></dt><dd> OK, I made that up
+</dd></dl>
+
+!! end
+
 
 ###
 ### External links
@@ -826,14 +836,6 @@ Inline interwiki link
 </p>
 !! end
 
-###
-### Images
-###
-
-!! test
-[[
-
-
 ##
 ## XHTML tidiness
 ###