Merge "SpecialLog: Don't ignore offender when it's a nonexistent username"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Thu, 18 Jan 2018 03:09:53 +0000 (03:09 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Thu, 18 Jan 2018 03:09:53 +0000 (03:09 +0000)
36 files changed:
RELEASE-NOTES-1.31
autoload.php
docs/ontology.owl
includes/CategoriesRdf.php
includes/DefaultSettings.php
includes/api/i18n/es.json
includes/installer/MssqlUpdater.php
includes/installer/MysqlInstaller.php
includes/installer/OracleUpdater.php
includes/installer/PostgresUpdater.php
includes/installer/i18n/ia.json
includes/libs/rdbms/database/Database.php
includes/libs/rdbms/database/DatabaseMysql.php [deleted file]
languages/i18n/ar.json
languages/i18n/ca.json
languages/i18n/cs.json
languages/i18n/eu.json
languages/i18n/fi.json
languages/i18n/ia.json
languages/i18n/krl.json
languages/i18n/lij.json
languages/i18n/lv.json
languages/i18n/mk.json
languages/i18n/mr.json
languages/i18n/pl.json
languages/i18n/roa-tara.json
languages/i18n/sah.json
languages/i18n/sr-ec.json
maintenance/dumpCategoriesAsRdf.php
maintenance/mssql/archives/patch-comment-table.sql [new file with mode: 0644]
maintenance/mssql/tables.sql
maintenance/oracle/archives/patch-comment-table.sql [new file with mode: 0644]
maintenance/oracle/tables.sql
tests/phpunit/data/categoriesrdf/categoriesRdf-out.nt
tests/phpunit/includes/libs/rdbms/database/DatabaseMysqlBaseTest.php
tests/phpunit/maintenance/categoriesRdfTest.php

index 307a8b5..695b88f 100644 (file)
@@ -171,6 +171,9 @@ changes to languages because of Phabricator reports.
 * The HtmlFormatter class was removed (deprecated in 1.27). The namespaced
   HtmlFormatter\HtmlFormatter class should be used instead.
 * License::getLicenses has been deprecated; use License::getLines instead.
+* The driver 'mysql' for MySQL, deprecated in MediaWiki 1.30, has been removed.
+  The driver has been deprecated since PHP 5.5 and was removed in PHP 7.0. The
+  default driver for MySQL has been 'mysqli' since MediaWiki 1.22.
 
 == Compatibility ==
 MediaWiki 1.31 requires PHP 5.5.9 or later. Although HHVM 3.18.5 or later is supported,
index 5d6104c..cc35dc3 100644 (file)
@@ -345,7 +345,6 @@ $wgAutoloadLocalClasses = [
        'DatabaseLag' => __DIR__ . '/maintenance/lag.php',
        'DatabaseLogEntry' => __DIR__ . '/includes/logging/LogEntry.php',
        'DatabaseMssql' => __DIR__ . '/includes/libs/rdbms/database/DatabaseMssql.php',
-       'DatabaseMysql' => __DIR__ . '/includes/libs/rdbms/database/DatabaseMysql.php',
        'DatabaseMysqlBase' => __DIR__ . '/includes/libs/rdbms/database/DatabaseMysqlBase.php',
        'DatabaseMysqli' => __DIR__ . '/includes/libs/rdbms/database/DatabaseMysqli.php',
        'DatabaseOracle' => __DIR__ . '/includes/db/DatabaseOracle.php',
@@ -1673,7 +1672,6 @@ $wgAutoloadLocalClasses = [
        'Wikimedia\\Rdbms\\Database' => __DIR__ . '/includes/libs/rdbms/database/Database.php',
        'Wikimedia\\Rdbms\\DatabaseDomain' => __DIR__ . '/includes/libs/rdbms/database/DatabaseDomain.php',
        'Wikimedia\\Rdbms\\DatabaseMssql' => __DIR__ . '/includes/libs/rdbms/database/DatabaseMssql.php',
-       'Wikimedia\\Rdbms\\DatabaseMysql' => __DIR__ . '/includes/libs/rdbms/database/DatabaseMysql.php',
        'Wikimedia\\Rdbms\\DatabaseMysqlBase' => __DIR__ . '/includes/libs/rdbms/database/DatabaseMysqlBase.php',
        'Wikimedia\\Rdbms\\DatabaseMysqli' => __DIR__ . '/includes/libs/rdbms/database/DatabaseMysqli.php',
        'Wikimedia\\Rdbms\\DatabasePostgres' => __DIR__ . '/includes/libs/rdbms/database/DatabasePostgres.php',
index 6b2e0b7..19476a3 100644 (file)
     <rdfs:comment>MediaWiki category.</rdfs:comment>
   </owl:Class>
 
+  <owl:Class rdf:about="&mediawiki;HiddenCategory">
+    <rdfs:label>HiddenCategory</rdfs:label>
+    <rdfs:comment>MediaWiki hidden category.</rdfs:comment>
+  </owl:Class>
+
   <!--
   ///////////////////////////////////////////////////////////////////////////////////////
   //
       <rdfs:domain rdf:resource="&mediawiki;Category"/>
   </owl:ObjectProperty>
 
+  <owl:DatatypeProperty rdf:about="&mediawiki;pages">
+      <rdfs:label>pages</rdfs:label>
+      <rdfs:comment>Number of articles belonging to this category.</rdfs:comment>
+      <rdfs:range rdf:resource="&mediawiki;Category"/>
+      <rdfs:range rdf:resource="&xsd;integer"/>
+  </owl:DatatypeProperty>
+
+  <owl:DatatypeProperty rdf:about="&mediawiki;subcategories">
+      <rdfs:label>subcategories</rdfs:label>
+      <rdfs:comment>Number of subcategories belonging to this category.</rdfs:comment>
+      <rdfs:range rdf:resource="&mediawiki;Category"/>
+      <rdfs:range rdf:resource="&xsd;integer"/>
+  </owl:DatatypeProperty>
+
 </rdf:RDF>
index 463f6e8..fc296d4 100644 (file)
@@ -80,14 +80,23 @@ class CategoriesRdf {
        /**
         * Write out the data for single category.
         * @param string $categoryName Category name
+        * @param bool $isHidden Hidden category?
+        * @param int $pages Page count (note this includes only Wiki articles, not subcats or files)
+        * @param int $subcategories Subcategory count
         */
-       public function writeCategoryData( $categoryName ) {
+       public function writeCategoryData( $categoryName, $isHidden, $pages, $subcategories ) {
                $title = Title::makeTitle( NS_CATEGORY, $categoryName );
                $this->rdfWriter->about( $this->titleToUrl( $title ) )
                        ->say( 'a' )
                        ->is( self::ONTOLOGY_PREFIX, 'Category' );
+               if ( $isHidden ) {
+                       $this->rdfWriter->is( self::ONTOLOGY_PREFIX, 'HiddenCategory' );
+               }
                $titletext = $title->getText();
                $this->rdfWriter->say( 'rdfs', 'label' )->value( $titletext );
+               $this->rdfWriter->say( self::ONTOLOGY_PREFIX, 'pages' )->value( $pages );
+               $this->rdfWriter->say( self::ONTOLOGY_PREFIX, 'subcategories' )->value( $subcategories );
+               // TODO: do we want files too here? Easy to add, but don't have use case so far.
        }
 
        /**
index ab01c5f..9208dec 100644 (file)
@@ -1940,6 +1940,7 @@ $wgSharedSchema = false;
  *   - user:        DB user
  *   - password:    DB password
  *   - type:        DB type
+ *   - driver:      DB driver (when there are multiple drivers)
  *
  *   - load:        Ratio of DB_REPLICA load, must be >=0, the sum of all loads must be >0.
  *                  If this is zero for any given server, no normal query traffic will be
index 1526a35..d2aaa77 100644 (file)
        "apihelp-query+watchlist-paramvalue-prop-sizes": "Añade la longitud vieja y la nueva de la página.",
        "apihelp-query+watchlist-paramvalue-prop-notificationtimestamp": "Añade fecha y hora de cuando el usuario fue notificado por última vez acerca de la edición.",
        "apihelp-query+watchlist-paramvalue-prop-loginfo": "Añade información del registro cuando corresponda.",
+       "apihelp-query+watchlist-paramvalue-prop-tags": "Enumera las etiquetas de la entrada.",
        "apihelp-query+watchlist-param-show": "Muestra solo los elementos que cumplan estos criterios. Por ejemplo, para ver solo ediciones menores realizadas por usuarios conectados, introduce $1show=minor|!anon.",
        "apihelp-query+watchlist-param-type": "Qué tipos de cambios mostrar:",
        "apihelp-query+watchlist-paramvalue-type-edit": "Ediciones comunes a páginas",
index b4b34de..1fd1d9b 100644 (file)
@@ -106,6 +106,10 @@ class MssqlUpdater extends DatabaseUpdater {
                        [ 'modifyField', 'image', 'img_media_type', 'patch-add-3d.sql' ],
                        [ 'addIndex', 'site_stats', 'PRIMARY', 'patch-site_stats-pk.sql' ],
 
+                       // Should have been in 1.30
+                       [ 'addTable', 'comment', 'patch-comment-table.sql' ],
+                       [ 'migrateComments' ],
+
                        // 1.31
                        [ 'addTable', 'slots', 'patch-slots.sql' ],
                        [ 'addTable', 'content', 'patch-content.sql' ],
index ab5701a..6256204 100644 (file)
@@ -73,7 +73,7 @@ class MysqlInstaller extends DatabaseInstaller {
         * @return bool
         */
        public function isCompiled() {
-               return self::checkExtension( 'mysql' ) || self::checkExtension( 'mysqli' );
+               return self::checkExtension( 'mysqli' );
        }
 
        /**
index ea68412..3ee51ea 100644 (file)
@@ -127,6 +127,10 @@ class OracleUpdater extends DatabaseUpdater {
                        [ 'doAutoIncrementTriggers' ],
                        [ 'addIndex', 'site_stats', 'PRIMARY', 'patch-site_stats-pk.sql' ],
 
+                       // Should have been in 1.30
+                       [ 'addTable', 'comment', 'patch-comment-table.sql' ],
+                       [ 'migrateComments' ],
+
                        // 1.31
                        [ 'addTable', 'slots', 'patch-slots.sql' ],
                        [ 'addTable', 'content', 'patch-content.sql' ],
index 367d431..8d12404 100644 (file)
@@ -481,6 +481,7 @@ class PostgresUpdater extends DatabaseUpdater {
                        [ 'changeNullableField', 'protected_titles', 'pt_reason', 'NOT NULL', true ],
                        [ 'addPgField', 'protected_titles', 'pt_reason_id', 'INTEGER NOT NULL DEFAULT 0' ],
                        [ 'addTable', 'comment', 'patch-comment-table.sql' ],
+                       [ 'migrateComments' ],
                        [ 'addIndex', 'site_stats', 'site_stats_pkey', 'patch-site_stats-pk.sql' ],
                        [ 'addTable', 'ip_changes', 'patch-ip_changes.sql' ],
 
index e1625fb..7674895 100644 (file)
        "config-install-mainpage-failed": "Non poteva inserer le pagina principal: $1",
        "config-install-done": "<strong>Felicitationes!</strong>\nTu ha installate MediaWiki.\n\nLe installator ha generate un file <code>LocalSettings.php</code>.\nIste contine tote le configuration.\n\nEs necessari discargar lo e poner lo in le base del installation wiki (le mesme directorio que index.php).\nLe discargamento debe haber comenciate automaticamente.\n\nSi le discargamento non ha comenciate, o si illo esseva cancellate, recomencia le discargamento con un clic sur le ligamine sequente:\n\n$3\n\n<strong>Nota:</strong> Si tu non discarga iste file de configuration ora, illo non essera disponibile plus tarde.\n\nPost facer isto, tu pote <strong>[$2 entrar in tu wiki]</strong>.",
        "config-install-done-path": "<strong>Felicitationes!</strong>\nTu ha installate MediaWiki.\n\nLe installator ha generate un file <code>LocalSettings.php</code>.\nIste contine tote le configuration.\n\nEs necessari discargar lo e poner lo in <code>$4</code>.\nLe discargamento debe haber comenciate automaticamente.\n\nSi le discargamento non ha comenciate, o si illo esseva cancellate, recomencia le discargamento con un clic sur le ligamine sequente:\n\n$3\n\n<strong>Nota:</strong> Si tu non discarga iste file de configuration ora, illo non essera disponibile plus tarde.\n\nPost facer isto, tu pote <strong>[$2 entrar in tu wiki]</strong>.",
+       "config-install-success": "MediaWiki ha essite installate con successo. Tu pote ora\nvisitar <$1$2> pro vider tu wiki.\nSi tu ha questiones, consulta nostre lista de questiones frequentemente ponite:\n<https://www.mediawiki.org/wiki/Manual:FAQ> o usa un del\nforos de supporto indicate sur ille pagina.",
        "config-download-localsettings": "Discargar <code>LocalSettings.php</code>",
        "config-help": "adjuta",
        "config-help-tooltip": "clicca pro displicar",
index 2eb5c54..323c147 100644 (file)
@@ -317,8 +317,8 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         *   - flags : Optional bitfield of DBO_* constants that define connection, protocol,
         *      buffering, and transaction behavior. It is STRONGLY adviced to leave the DBO_DEFAULT
         *      flag in place UNLESS this this database simply acts as a key/value store.
-        *   - driver: Optional name of a specific DB client driver. For MySQL, there is the old
-        *      'mysql' driver and the newer 'mysqli' driver.
+        *   - driver: Optional name of a specific DB client driver. For MySQL, there is only the
+        *      'mysqli' driver; the old one 'mysql' has been removed.
         *   - variables: Optional map of session variables to set after connecting. This can be
         *      used to adjust lock timeouts or encoding modes and the like.
         *   - connLogger: Optional PSR-3 logger interface instance.
@@ -337,7 +337,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         */
        final public static function factory( $dbType, $p = [] ) {
                static $canonicalDBTypes = [
-                       'mysql' => [ 'mysqli', 'mysql' ],
+                       'mysql' => [ 'mysqli' ],
                        'postgres' => [],
                        'sqlite' => [],
                        'oracle' => [],
@@ -345,7 +345,6 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                ];
                static $classAliases = [
                        'DatabaseMssql' => DatabaseMssql::class,
-                       'DatabaseMysql' => DatabaseMysql::class,
                        'DatabaseMysqli' => DatabaseMysqli::class,
                        'DatabaseSqlite' => DatabaseSqlite::class,
                        'DatabasePostgres' => DatabasePostgres::class
diff --git a/includes/libs/rdbms/database/DatabaseMysql.php b/includes/libs/rdbms/database/DatabaseMysql.php
deleted file mode 100644 (file)
index 58b0926..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-<?php
-/**
- * This is the MySQL database abstraction layer.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Database
- */
-namespace Wikimedia\Rdbms;
-
-/**
- * Database abstraction object for PHP extension mysql.
- *
- * @deprecated 1.30 PHP extension 'mysql' was deprecated in PHP 5.5 and removed in PHP 7.0.
- * @see PHP extension 'mysqli' and DatabaseMysqli
- *
- * @ingroup Database
- * @see Database
- */
-class DatabaseMysql extends DatabaseMysqlBase {
-       /**
-        * @param string $sql
-        * @return resource False on error
-        */
-       protected function doQuery( $sql ) {
-               $conn = $this->getBindingHandle();
-
-               if ( $this->bufferResults() ) {
-                       $ret = mysql_query( $sql, $conn );
-               } else {
-                       $ret = mysql_unbuffered_query( $sql, $conn );
-               }
-
-               return $ret;
-       }
-
-       /**
-        * @param string $realServer
-        * @return bool|resource MySQL Database connection or false on failure to connect
-        * @throws DBConnectionError
-        */
-       protected function mysqlConnect( $realServer ) {
-               # Avoid a suppressed fatal error, which is very hard to track down
-               if ( !extension_loaded( 'mysql' ) ) {
-                       throw new DBConnectionError(
-                               $this,
-                               "MySQL functions missing, have you compiled PHP with the --with-mysql option?\n"
-                       );
-               }
-
-               $connFlags = 0;
-               if ( $this->mFlags & self::DBO_SSL ) {
-                       $connFlags |= MYSQL_CLIENT_SSL;
-               }
-               if ( $this->mFlags & self::DBO_COMPRESS ) {
-                       $connFlags |= MYSQL_CLIENT_COMPRESS;
-               }
-
-               if ( ini_get( 'mysql.connect_timeout' ) <= 3 ) {
-                       $numAttempts = 2;
-               } else {
-                       $numAttempts = 1;
-               }
-
-               $conn = false;
-
-               # The kernel's default SYN retransmission period is far too slow for us,
-               # so we use a short timeout plus a manual retry. Retrying means that a small
-               # but finite rate of SYN packet loss won't cause user-visible errors.
-               for ( $i = 0; $i < $numAttempts && !$conn; $i++ ) {
-                       if ( $i > 1 ) {
-                               usleep( 1000 );
-                       }
-                       if ( $this->mFlags & self::DBO_PERSISTENT ) {
-                               $conn = mysql_pconnect( $realServer, $this->mUser, $this->mPassword, $connFlags );
-                       } else {
-                               # Create a new connection...
-                               $conn = mysql_connect( $realServer, $this->mUser, $this->mPassword, true, $connFlags );
-                       }
-               }
-
-               return $conn;
-       }
-
-       /**
-        * @param string $charset
-        * @return bool
-        */
-       protected function mysqlSetCharset( $charset ) {
-               $conn = $this->getBindingHandle();
-
-               if ( function_exists( 'mysql_set_charset' ) ) {
-                       return mysql_set_charset( $charset, $conn );
-               } else {
-                       return $this->query( 'SET NAMES ' . $charset, __METHOD__ );
-               }
-       }
-
-       /**
-        * @return bool
-        */
-       protected function closeConnection() {
-               $conn = $this->getBindingHandle();
-
-               return mysql_close( $conn );
-       }
-
-       /**
-        * @return int
-        */
-       function insertId() {
-               $conn = $this->getBindingHandle();
-
-               return mysql_insert_id( $conn );
-       }
-
-       /**
-        * @return int
-        */
-       function lastErrno() {
-               if ( $this->mConn ) {
-                       return mysql_errno( $this->mConn );
-               } else {
-                       return mysql_errno();
-               }
-       }
-
-       /**
-        * @return int
-        */
-       function affectedRows() {
-               $conn = $this->getBindingHandle();
-
-               return mysql_affected_rows( $conn );
-       }
-
-       /**
-        * @param string $db
-        * @return bool
-        */
-       function selectDB( $db ) {
-               $conn = $this->getBindingHandle();
-
-               $this->mDBname = $db;
-
-               return mysql_select_db( $db, $conn );
-       }
-
-       protected function mysqlFreeResult( $res ) {
-               return mysql_free_result( $res );
-       }
-
-       protected function mysqlFetchObject( $res ) {
-               return mysql_fetch_object( $res );
-       }
-
-       protected function mysqlFetchArray( $res ) {
-               return mysql_fetch_array( $res );
-       }
-
-       protected function mysqlNumRows( $res ) {
-               return mysql_num_rows( $res );
-       }
-
-       protected function mysqlNumFields( $res ) {
-               return mysql_num_fields( $res );
-       }
-
-       protected function mysqlFetchField( $res, $n ) {
-               return mysql_fetch_field( $res, $n );
-       }
-
-       protected function mysqlFieldName( $res, $n ) {
-               return mysql_field_name( $res, $n );
-       }
-
-       protected function mysqlFieldType( $res, $n ) {
-               return mysql_field_type( $res, $n );
-       }
-
-       protected function mysqlDataSeek( $res, $row ) {
-               return mysql_data_seek( $res, $row );
-       }
-
-       protected function mysqlError( $conn = null ) {
-               return ( $conn !== null ) ? mysql_error( $conn ) : mysql_error(); // avoid warning
-       }
-
-       protected function mysqlRealEscapeString( $s ) {
-               $conn = $this->getBindingHandle();
-
-               return mysql_real_escape_string( (string)$s, $conn );
-       }
-}
-
-class_alias( DatabaseMysql::class, 'DatabaseMysql' );
index 8f537c2..0f640cf 100644 (file)
        "years": "{{PLURAL:$1||سنة واحدة|سنتين|$1 سنين|$1 سنة}}",
        "ago": "قبل $1",
        "just-now": "الآن فقط",
-       "hours-ago": "Ù\85Ù\86Ø° {{PLURAL:$1|ساعة|$1 ساعات}}",
-       "minutes-ago": "Ù\85Ù\86Ø° {{PLURAL:$1|دقيقة|$1 دقائق}}",
-       "seconds-ago": "Ù\85Ù\86Ø° {{PLURAL:$1|ثانية|$1 ثوان}}",
+       "hours-ago": "Ù\82بÙ\84 {{PLURAL:$1|ساعة|$1 ساعات}}",
+       "minutes-ago": "Ù\82بÙ\84 {{PLURAL:$1|دقيقة|$1 دقائق}}",
+       "seconds-ago": "Ù\82بÙ\84 {{PLURAL:$1|ثانية|$1 ثوان}}",
        "monday-at": "يوم الإثنين الساعة $1",
        "tuesday-at": "يوم الثلاثاء الساعة $1",
        "wednesday-at": "يوم الأربعاء الساعة $1",
        "authmanager-create-not-in-progress": "إنشاء الحساب ليس جاريا أو بيانات الجلسة تم فقدها. من فضلك ابدأ ثانية من البداية.",
        "authmanager-create-no-primary": "الاعتمادات الموفرة لم يمكن استخدامها لإنشاء الحساب.",
        "authmanager-link-no-primary": "الاعتماد الموفر لم يمكن استخدامه لوصل الحسابات.",
-       "authmanager-link-not-in-progress": "وصل الحساب ليس جاريا أو بيانات الجلسة تم فقدها. من فضلك ابدأ ثانية منذ البداية.",
+       "authmanager-link-not-in-progress": "وصل الحساب ليس جاريا أو بيانات الجلسة تم فقدها. من فضلك ابدأ ثانية من البداية.",
        "authmanager-authplugin-setpass-failed-title": "تغيير كلمة السر فشل",
        "authmanager-authplugin-setpass-failed-message": "إضافة التحقق رفضت تغيير كلمة السر.",
        "authmanager-authplugin-create-fail": "إضافة التحقق رفضت إنشاء الحساب.",
index c1bcb29..7410198 100644 (file)
        "recentchanges-page-removed-from-category": "[[:$1]] treta de la categoria",
        "recentchanges-page-removed-from-category-bundled": "[[:$1]] treta de la categoria, [[Special:WhatLinksHere/$1|aquesta pàgina està inclosa en d'altres]]",
        "autochange-username": "Canvi automàtic del MediaWiki",
-       "upload": "Pujar un fitxer",
+       "upload": "Puja un fitxer",
        "uploadbtn": "Carrega un fitxer",
        "reuploaddesc": "Torna al formulari per apujar.",
        "upload-tryagain": "Envia la descripció del fitxer modificat",
index 74fccaa..b79aaec 100644 (file)
        "pageinfo-category-subcats": "Počet podkategorií",
        "pageinfo-category-files": "Počet souborů",
        "pageinfo-user-id": "ID uživatele",
+       "pageinfo-file-hash": "Kontrolní součet",
        "markaspatrolleddiff": "Označit jako prověřené",
        "markaspatrolledtext": "Označit tuto stránku jako prověřenou",
        "markaspatrolledtext-file": "Označit tuto verzi souboru jako prověřenou",
        "version-poweredby-others": "další",
        "version-poweredby-translators": "překladatelé na translatewiki.net",
        "version-credits-summary": "Následujícím lidem bychom rádi poděkovali za jejich příspěvky [[Special:Version|MediaWiki]].",
-       "version-license-info": "MediaWiki je svobodný software; můžete jej šířit nebo modifikovat podle podmínek GNU General Public License, vydávané Free Software Foundation; buď verze 2 této licence, anebo (podle vašeho uvážení) kterékoli pozdější verze.\n\nMediaWiki je distribuována v naději, že bude užitečná, avšak BEZ JAKÉKOLI ZÁRUKY; neposkytují se ani odvozené záruky PRODEJNOSTI anebo VHODNOSTI PRO URČITÝ ÚČEL. Podrobnosti se dočtete v textu GNU General Public License.\n\n[{{SERVER}}{{SCRIPTPATH}}/COPYING Kopii GNU General Public License] jste měli obdržet spolu s tímto programem, pokud ne, napište na Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA nebo [//www.gnu.org/licenses/old-licenses/gpl-2.0.html si ji přečtěte online].",
+       "version-license-info": "MediaWiki je svobodný software; můžete jej šířit nebo modifikovat podle podmínek GNU General Public License, vydávané Free Software Foundation; buď verze 2 této licence, anebo (podle vašeho uvážení) kterékoli pozdější verze.\n\nMediaWiki je distribuována v naději, že bude užitečná, avšak <em>BEZ JAKÉKOLI ZÁRUKY</em>; neposkytují se ani odvozené záruky <strong>PRODEJNOSTI</strong> anebo <strong>VHODNOSTI PRO URČITÝ ÚČEL</strong>. Podrobnosti se dočtete v textu GNU General Public License.\n\n[{{SERVER}}{{SCRIPTPATH}}/COPYING Kopii GNU General Public License] jste měli obdržet spolu s tímto programem, pokud ne, napište na Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA nebo [//www.gnu.org/licenses/old-licenses/gpl-2.0.html si ji přečtěte online].",
        "version-software": "Nainstalovaný software",
        "version-software-product": "Název",
        "version-software-version": "Verze",
index 2e407ae..f22cb84 100644 (file)
        "logentry-protect-protect-cascade": "$1 wikilariak  {{GENDER:$2|}} $3 $4 babestu du [korrontean]",
        "logentry-protect-modify": "$1 wikilariak {{GENDER:$2|}} $3 $4rentzako babespen maila aldatu du",
        "logentry-protect-modify-cascade": "$1 wikilariak $3 $4 duten babespen maila {{GENDER:$2|aldatu}} egin du [kaskada bidez]",
-       "logentry-rights-rights": "$1 wikilariak {{GENDER:$6 eta|$3 wikilarientzako}} talde bazkidetza $4tik $5ra {{GENDER:$2|aldatu}} dizkie",
-       "logentry-rights-rights-legacy": "$1 erabiltzaileak $3ren talde bazkidetza {{GENDER:$2|aldatu}} egin du",
+       "logentry-rights-rights": "$1 wikilariak {{GENDER:$6|$3}} wikilaria $4 taldetik $5 taldera aldatu du",
+       "logentry-rights-rights-legacy": "$1 wikilariak $3 wikilaria taldez {{GENDER:$2|aldatu}} du",
        "logentry-rights-autopromote": "$1 automatikoki $4tik $5ra  {{GENDER:$2|igo}} egin zaio",
        "logentry-upload-upload": "$1(e)k $3 {{GENDER:$2|igo du}}",
        "logentry-upload-overwrite": "$1(e)k $3(r)en bertsio berria {{GENDER:$2|igo du}}",
index 738d65f..9a23029 100644 (file)
        "userrights-expiry-existing": "Nykyinen vanhentumisaika: $2 kello $3",
        "userrights-expiry-othertime": "Muu aika:",
        "userrights-expiry-options": "1 päivä:1 day,1 viikko:1 week,1 kuukausi:1 month,3 kuukautta:3 months,6 kuukautta:6 months,1 vuosi:1 year",
+       "userrights-invalid-expiry": "Ryhmän \"$1\" vanhentumisaika on virheellinen.",
+       "userrights-expiry-in-past": "Ryhmän \"$1\" vanhentumisaika on mennyt.",
        "userrights-conflict": "Päällekkäinen käyttöoikeuksien muutos! Tarkista tekemäsi muutokset ja vahvista ne.",
        "group": "Ryhmä",
        "group-user": "käyttäjät",
        "recentchangeslinked-feed": "Linkitettyjen sivujen muutokset",
        "recentchangeslinked-toolbox": "Linkitettyjen sivujen muutokset",
        "recentchangeslinked-title": "Sivulta $1 linkitettyjen sivujen muutokset",
-       "recentchangeslinked-summary": "Tämä on luettelo muutoksista, jotka on viimeksi tehty niihin sivuihin, joihin johtaa linkki tietystä sivusta (tai jonkun määrätyn luokan sisältämistä sivuista). Omalla [[Special:Watchlist|tarkkailulistallasi]] olevat sivut on <strong>lihavoitu</strong>.",
+       "recentchangeslinked-summary": "Kirjoita sivun nimi nähdäksesi muutokset sivuihin jotka on linkitetty tai ovat tältä sivulta. (Nähdäksesi luokan jäsenet, kirjoita Luokka:Luokan nimi). Muutokset sivuihin\n[[Special:Watchlist|tarkkailulistallasi]] on <strong>lihavoitu</strong>.",
        "recentchangeslinked-page": "Sivun nimi:",
        "recentchangeslinked-to": "Näytä sen sijaan muutokset sivuihin, joista on linkki tähän sivuun",
        "recentchanges-page-added-to-category": "[[:$1]] lisätty luokkaan",
        "uploadstash-thumbnail": "näytä pienoiskuva",
        "uploadstash-bad-path": "\nPolkua ei ole.",
        "uploadstash-bad-path-invalid": "Polku ei kelpaa.",
+       "uploadstash-bad-path-unknown-type": "Tuntematon tyyppi \"$1\".",
        "uploadstash-not-logged-in": "Käyttäjää ei ole kirjautunut sisään, tiedostojen on kuuluttava käyttäjille.",
+       "uploadstash-no-such-key": "Ei tälläistä avainta ($1), ei voi poistaa.",
        "uploadstash-no-extension": "Laajennus on tyhjä.",
        "invalid-chunk-offset": "Kelpaamaton siirtymä lohkoissa",
        "img-auth-accessdenied": "Pääsy estetty",
        "ipb_blocked_as_range": "IP-osoite $1 on estetty välillisesti ja sen estoa ei voi poistaa. Se on estetty osana verkkoaluetta $2, jonka eston voi poistaa",
        "ip_range_invalid": "Virheellinen IP-alue.",
        "ip_range_toolarge": "Suuremmat osoitealue-estot kuin /$1 eivät ole sallittuja.",
+       "ip_range_toolow": "IP-alueet eivät käytännöllisesti katsoen ole sallittuja.",
        "proxyblocker": "Välityspalvelinesto",
        "proxyblockreason": "IP-osoitteestasi on estetty muokkaukset, koska se on avoin välityspalvelin. Ota yhteyttä Internet-palveluntarjoajaasi tai tekniseen tukeen ja kerro heille tästä tietoturvaongelmasta.",
        "sorbsreason": "IP-osoitteesi on listattu avoimena välityspalvelimena DNSBL:n mustalla listalla sivustolla {{SITENAME}}.",
        "sorbs_create_account_reason": "IP-osoitteesi on listattu avoimena välityspalvelimena DNSBL:n mustalla listalla sivustolla {{SITENAME}}. \nEt voi luoda käyttäjätunnusta.",
+       "softblockrangesreason": "Anonyymit muokkaukset eivät ole sallittuja IP-osoitteestasi ($1). Ole hyvä ja kirjaudu.",
        "xffblockreason": "Yhteydet IP-osoitteesta, joka löytyy sinun tai käyttämäsi välipalvelimen X-Forwarded-For-otsakkeesta, on estetty. Alkuperäinen estämisen syy oli: $1",
        "cant-see-hidden-user": "Käyttäjä, jota yrität estää, on jo estetty ja käyttäjänimi on piilotettu. \nKoska sinulla ei ole hideuser-oikeutta, et voi nähdä tai muuttaa käyttäjän estoasetuksia.",
        "ipbblocked": "Et voi estää tai poistaa estoja muilta käyttäjiltä, koska itse olet estettynä",
        "usercssispublic": "Huomio: CSS-alasivuilla ei tulisi olla luottamuksellisia tietoja, koska muut käyttäjät voivat nähdä ne.",
        "restrictionsfield-badip": "Virheellinen IP-osoite tai alue: $1",
        "restrictionsfield-label": "Sallitut IP-alueet:",
+       "restrictionsfield-help": "Yksi IP-osoite tai CIDR-alue per rivi. Ottaaksesi kaiken käyttöön, käytä:<pre>0.0.0.0/0\n::/0</pre>",
        "revid": "versio $1",
        "pageid": "sivun tunnistenumero $1",
        "rawhtml-notallowed": "&lt;html&gt; komentoa ei voida käyttää normaalien sivujen ulkopuolella.",
index e9f23a4..311561a 100644 (file)
        "pageinfo-category-subcats": "Numero de subcategorias",
        "pageinfo-category-files": "Numero de files",
        "pageinfo-user-id": "ID de usator",
+       "pageinfo-file-hash": "Valor hash",
        "markaspatrolleddiff": "Marcar como patruliate",
        "markaspatrolledtext": "Marcar iste pagina como patruliate",
        "markaspatrolledtext-file": "Marcar iste version del file como patruliate",
        "version-poweredby-others": "alteres",
        "version-poweredby-translators": "Traductores de translatewiki.net",
        "version-credits-summary": "Nos vole recognoscer le sequente personas pro lor contribution a [[Special:Version|MediaWiki]].",
-       "version-license-info": "MediaWiki es software libere; vos pote redistribuer lo e/o modificar lo sub le conditiones del Licentia Public General de GNU publicate per le Free Software Foundation; version 2 del Licentia, o (a vostre option) qualcunque version posterior.\n\nIste programma es distribuite in le sperantia que illo sia utile, ma SIN GARANTIA; sin mesmo le implicite garantia de COMMERCIALISATION o APTITUDE PRO UN PROPOSITO PARTICULAR. Vide le Licentia Public General de GNU pro plus detalios.\n\nVos deberea haber recipite [{{SERVER}}{{SCRIPTPATH}}/COPYING un exemplar del Licentia Public General de GNU] con iste programma; si non, scribe al Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA, o [//www.gnu.org/copyleft/gpl.html lege lo in linea].",
+       "version-license-info": "MediaWiki es software libere; vos pote redistribuer lo e/o modificar lo sub le conditiones del Licentia Public General de GNU publicate per le Free Software Foundation; version 2 del Licentia, o (a vostre option) qualcunque version posterior.\n\nIste programma es distribuite in le sperantia que illo sia utile, ma <em>SIN GARANTIA</em>; sin mesmo le implicite garantia de <strong>COMMERCIALISATION</strong> o <strong>APTITUDE PRO UN PROPOSITO PARTICULAR</sdtrong>. Vide le Licentia Public General de GNU pro plus detalios.\n\nVos deberea haber recipite [{{SERVER}}{{SCRIPTPATH}}/COPYING un exemplar del Licentia Public General de GNU] con iste programma; si non, scribe al Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA, o [//www.gnu.org/copyleft/gpl.html lege lo in linea].",
        "version-software": "Software installate",
        "version-software-product": "Producto",
        "version-software-version": "Version",
        "limitreport-expansiondepth": "Maxime profunditate de expansion",
        "limitreport-expensivefunctioncount": "Numero de functiones analysator costose",
        "expandtemplates": "Expander patronos",
-       "expand_templates_intro": "Iste pagina special prende texto e expande recursivemente tote le patronos in illo.\nIllo expande etiam le functiones del analysator syntactic como\n<code><nowiki>{{</nowiki>#language:…}}</code>, e variabiles como\n<code><nowiki>{{</nowiki>CURRENTDAY}}</code>.\nDe facto, illo expande quasi toto inter accolladas duple.",
+       "expand_templates_intro": "Iste pagina special prende wikitexto e expande recursivemente tote le patronos in illo.\nIllo expande etiam le functiones del analysator syntactic como\n<code><nowiki>{{</nowiki>#language:…}}</code>, e variabiles como\n<code><nowiki>{{</nowiki>CURRENTDAY}}</code>.\nDe facto, illo expande quasi toto inter accolladas duple.",
        "expand_templates_title": "Titulo de contexto, pro {{FULLPAGENAME}} etc.:",
-       "expand_templates_input": "Texto de entrata:",
+       "expand_templates_input": "Scribe wikitexto:",
        "expand_templates_output": "Resultato",
        "expand_templates_xml_output": "Output XML",
        "expand_templates_html_output": "Resultato in HTML brute",
        "expand_templates_preview": "Previsualisation",
        "expand_templates_preview_fail_html": "<em>Perque {{SITENAME}} ha HTML crude activate e il habeva un perdita de datos de session, le previsualisation es celate como precaution contra attaccos con JavaScript.</em>\n\n<strong>Si isto es un tentativa de previsualisation legitime, per favor essaya lo de novo.</strong>\nSi illo ancora non functiona, essaya [[Special:UserLogout|clauder le session]] e aperir un nove session, e verifica que tu navigator permitte le cookies de iste sito.",
        "expand_templates_preview_fail_html_anon": "<em>Perque {{SITENAME}} ha HTML crude activate e tu non ha aperite session, le previsualisation es celate como precaution contra attaccos con JavaScript.</em>\n\n<strong>Si isto es un tentativa de previsualisation legitime, per favor [[Special:UserLogin|aperi session]] e essaya lo de novo.</strong>",
-       "expand_templates_input_missing": "Tu debe scriber alcun texto de entrata.",
+       "expand_templates_input_missing": "Tu debe fornir alcun wikitexto.",
        "pagelanguage": "Cambiar lingua del pagina",
        "pagelang-name": "Pagina",
        "pagelang-language": "Lingua",
index 334c209..53ba8e9 100644 (file)
@@ -81,6 +81,7 @@
        "category_header": "Šivut, kumpaset ollah luokašša $1",
        "subcategories": "Alaluokat",
        "category-media-header": "Medijafailit luokašša «$1»",
+       "category-empty": "Täššä luokašša ei ole šivuja tahi failoja.",
        "hidden-categories": "{{PLURAL:$1|Peitetty luokka|Peitetyt luokat}}",
        "hidden-category-category": "Peitetyt luokat",
        "category-subcat-count": "{{PLURAL:$2|Täššä luokašša on vain tämä alaluokka.|Täššä luokašša on nämä {{PLURAL:$1|subcategory|$1 alaluokkua}}, kaikkieštah $2.}}",
        "ok": "OK",
        "retrievedfrom": "Lähte - \"$1\"",
        "youhavenewmessages": "{{PLURAL:$3|Šiula on}} $1 ($2).",
+       "newmessageslinkplural": "{{PLURAL:$1|uusi viesti|999=uusie viestie}}",
+       "newmessagesdifflinkplural": "{{PLURAL:$1|jälkimäini muutos|999=jälkimäistä muutosta}}",
        "editsection": "kohentele",
        "editold": "kohentele",
        "viewsourceold": "näytä wikiteksti",
        "nstab-special": "Toimintošivu",
        "nstab-project": "Projektišivu",
        "nstab-image": "Faili",
+       "nstab-mediawiki": "Viesti",
        "nstab-template": "Malli",
        "nstab-category": "Luokka",
        "mainpage-nstab": "Piäšivu",
        "template-protected": "(šuojattu)",
        "template-semiprotected": "(ošittain šuojattu)",
        "hiddencategories": "Tämä šivu kuuluu {{PLURAL:$1|1 peitettyh kategorijah|$1 peitettylöih kategorijoih}}:",
+       "permissionserrors": "Ei oikevukšie",
        "permissionserrorstext-withaction": "Šiula ei ole oikeutta {{lcfirst:$2}} {{PLURAL:$1|šeuruavašta šyyštä|šeuruavista šyistä}}:",
        "moveddeleted-notice": "Tämä šivu on poissettu.\nAlla on tämän šivun poisto- ta šiirtoistorija.",
        "content-model-wikitext": "wikiteksti",
        "history-fieldset-title": "Eči kohennukšet",
        "histfirst": "vanhin",
        "histlast": "uušin",
+       "history-feed-title": "Kohennusistorija",
+       "history-feed-description": "Tämän šivun kohennusistorija",
        "history-feed-item-nocomment": "$1 ($2)",
        "rev-delundel": "muuta näkyvyttä",
        "history-title": "Šivun ”$1” muutošistorija",
        "protectcomment": "Šyy",
        "protect-default": "Anna lupa kohennella kaikilla käyttäjillä",
        "restriction-edit": "Kohentele",
+       "restriction-move": "Šiirrä",
        "undelete-search-submit": "Ečindy",
        "namespace": "Nimitilat:",
        "invert": "Päinvaštani valinta",
        "tooltip-ca-nstab-image": "Näytä failin šivu",
        "tooltip-ca-nstab-template": "Näytä malli",
        "tooltip-ca-nstab-category": "Näytä luokkašivu",
+       "tooltip-minoredit": "Merkiče tämä pieneksi kohennukseksi",
        "tooltip-save": "Tallenna muutokšet",
        "tooltip-preview": "Esikačo muutokšet. Ole hyvä, luaji šitä aina ennen tallennušta.",
        "tooltip-diff": "Näytä luajitut muutokšet",
        "tooltip-undo": "Kumuomini palauttau tämän muutokšen ta avuau artikkelin esikaččelušša. Yhtehvetokenttäh voi kirjuttua palautukšen šyyn.",
        "tooltip-summary": "Kirjuta lyhyt kuvauš",
        "simpleantispam-label": "Anti-spam-tarkissuš. \n<strong>älä</strong> täytä tätä!",
+       "pageinfo-title": "Tietoja šivušta $1",
+       "pageinfo-header-edits": "Kohennukšien istorija",
        "pageinfo-header-restrictions": "Šivun šuojauš",
        "pageinfo-display-title": "Näytä oččikko",
+       "pageinfo-length": "Šivun pituhuš (tavuloina)",
+       "pageinfo-firstuser": "Šivun luatija",
        "pageinfo-toolboxlink": "Šivun tiijot",
        "previousdiff": "← Vanhempi muutoš",
        "nextdiff": "Uuvvempi muutoš →",
        "logentry-move-move": "$1 {{GENDER:$2|šiirretty}} šivu $3 kohtah $4",
        "logentry-newusers-create": "Käyttäjätunnuš $1 {{GENDER:$2|oli luotu}}",
        "logentry-upload-upload": "$1 {{GENDER:$2|päivitetty}} $3",
-       "searchsuggest-search": "Eči {{SITENAME}}"
+       "searchsuggest-search": "Eči {{SITENAME}}",
+       "duration-days": "$1 {{PLURAL:$1|päivä|päivyä}}"
 }
index f2dc697..9fa2949 100644 (file)
        "viewhelppage": "Vizualizza a paggina d'agiutto",
        "categorypage": "Veddi a paggina da categoria",
        "viewtalkpage": "Amia a paggina de discuscion",
-       "otherlanguages": "In âtre lengoe",
+       "otherlanguages": "In âtre léngoe",
        "redirectedfrom": "(Rendirissou da $1)",
        "redirectpagesub": "Paggina de rindirissamento",
        "redirectto": "Rendirissa a:",
        "lastmodifiedat": "Sta pagina a l'è stæta cangiâ l'urtima votta o $1 a $2.",
        "viewcount": "'Sta paggina a l'è stæta vista {{PLURAL:$1|solo 'na vòtta|$1 vòtte}}.",
-       "protectedpage": "Paggina protetta",
+       "protectedpage": "Pàgina protètta",
        "jumpto": "Vanni a:",
        "jumptonavigation": "navegaçión",
        "jumptosearch": "çerca",
        "disclaimers": "Averténse",
        "disclaimerpage": "Project:Avertense generâli",
        "edithelp": "Agiùtto",
-       "helppage-top-gethelp": "Agiutto",
+       "helppage-top-gethelp": "Agiùtto",
        "mainpage": "Pàgina prinçipâ",
        "mainpage-description": "Pagina prinçipâ",
        "policy-url": "Project:Lezzi",
index 90859d6..2f678bb 100644 (file)
@@ -61,6 +61,7 @@
        "tog-watchlisthidebots": "Paslēpt botu labojumus uzraugāmo lapu sarakstā",
        "tog-watchlisthideminor": "Paslēpt maznozīmīgos labojumus uzraugāmo lapu sarakstā",
        "tog-watchlisthideliu": "Paslēpt reģistrēto dalībnieku labojumus uzraugāmo lapu sarakstā",
+       "tog-watchlistreloadautomatically": "Pārlādēt uzraugāmo rakstu sarakstu automātiski, ja tiek mainīts filtrs (nepieciešams JavaScript)",
        "tog-watchlisthideanons": "Paslēpt anonīmo dalībnieku labojumus uzraugāmo lapu sarakstā",
        "tog-watchlisthidepatrolled": "Paslēpt pārbaudītās lapas uzraugāmo lapu sarakstā",
        "tog-watchlisthidecategorization": "Paslēpt lapu kategorizēšanu",
        "version-libraries-description": "Apraksts",
        "version-libraries-authors": "Autori",
        "redirect": "Pāradresēt pēc faila, lietotāja, lapas, versijas vai žurnāla ieraksta ID",
+       "redirect-summary": "Šī īpašā lapa pāradresē uz failu (norādot faila nosaukumu), lapu (norādot versijas vai lapas ID), dalībnieka lapu (norādot dalībnieka skaitlisko ID) vai žurnāla ierakstu (norādot ieraksta ID). Izmantošana: [[{{#Special:Redirect}}/file/Piemers.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]] vai [[{{#Special:Redirect}}/logid/186]].",
        "redirect-submit": "Aiziet",
        "redirect-lookup": "Meklēt:",
        "redirect-value": "Vērtība:",
index 96ce45e..ae5ccb9 100644 (file)
        "rcfilters-activefilters": "Активни филтри",
        "rcfilters-advancedfilters": "Напредни филтри",
        "rcfilters-limit-title": "Ставки за приказ",
-       "rcfilters-limit-and-date-label": "{{PLURAL:$1|промена|$1 промени}}, $2",
+       "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|промена|промени}}, $2",
        "rcfilters-date-popup-title": "Временски период за пребарување",
        "rcfilters-days-title": "Последниве денови",
        "rcfilters-hours-title": "Последниве часови",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Страници кон кои води</strong> избраната страница",
        "rcfilters-filter-showlinkedto-label": "Прикажи промени во страници кои водат кон",
        "rcfilters-filter-showlinkedto-option-label": "<strong>Страници кои води кон</strong> избраната страница",
-       "rcfilters-target-page-placeholder": "Внесете страница",
+       "rcfilters-target-page-placeholder": "Внесете име на страница (или категорија)",
        "rcnotefrom": "Подолу {{PLURAL:$5|е прикажана промената|се прикажани промените}} почнувајќи од <strong>$3, $4</strong>  (се прикажуваат до <b>$1</b>).",
        "rclistfromreset": "Нов избор на датуми",
        "rclistfrom": "Прикажи нови промени почнувајќи од $3 $2",
        "version-poweredby-others": "други",
        "version-poweredby-translators": "преведувачи на translatewiki.net",
        "version-credits-summary": "Би сакале да им се заблагодариме на следниве лица за нивните придонеси кон [[Special:Version|МедијаВики]].",
-       "version-license-info": "МедијаВики е слободна програмска опрема; можете да ја редистрибуирате и/или менувате под условите на ГНУ-овата општа јавна лиценца на Фондацијата за слободна програмска опрема; или верзија 2 на Лиценцата, или некоја понова верзија (по ваш избор).\n\nМедијаВики се нуди со надеж дека ќе биде од корист, но БЕЗ БИЛО КАКВА ГАРАНЦИЈА; дури и без подразбраната гаранција за ПРОДАЖНА ВРЕДНОСТ или ПОГОДНОСТ ЗА ДАДЕНА ЦЕЛ. За повеќе информации, погледајте ја ГНУ-овата општа јавна лиценца.\n\nЗаедно со програмов треба да имате добиено [{{SERVER}}{{SCRIPTPATH}}/COPYING примерок од ГНУ-овата општа јавна лиценца]; ако немате добиено примерок, пишете на Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA или [//www.gnu.org/licenses/old-licenses/gpl-2.0.html прочитајте ја тука].",
+       "version-license-info": "МедијаВики е слободна програмска опрема; можете да ја редистрибуирате и/или менувате под условите на ГНУ-овата општа јавна лиценца на Фондацијата за слободна програмска опрема; или верзија 2 на Лиценцата, или некоја понова верзија (по ваш избор).\n\nМедијаВики се нуди со надеж дека ќе биде од корист, но БЕЗ <em>БИЛО КАКВА ГАРАНЦИЈА</em>; дури и без подразбраната гаранција за <strong>ПРОДАЖНА ВРЕДНОСТ</strong> или <strong>ПОГОДНОСТ ЗА ДАДЕНА ЦЕЛ</strong>. За повеќе информации, погледајте ја ГНУ-овата општа јавна лиценца.\n\nЗаедно со програмов треба да имате добиено [{{SERVER}}{{SCRIPTPATH}}/COPYING примерок од ГНУ-овата општа јавна лиценца]; ако немате добиено примерок, пишете на Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA или [//www.gnu.org/licenses/old-licenses/gpl-2.0.html прочитајте ја тука].",
        "version-software": "Воспоставена програмска опрема",
        "version-software-product": "Производ",
        "version-software-version": "Верзија",
index 9a7919e..ac5e2f7 100644 (file)
        "autosumm-replace": "पान '$1' वापरून बदलले.",
        "autoredircomment": "[[$1]] कडे पुनर्निर्देशित",
        "autosumm-removed-redirect": "[[$1]] ला असणारे पुनर्निर्देशन हटविले",
-       "autosumm-changed-redirect-target": "पुनर्निर्देशन लक्ष्य [[$1]] पासून [[$2]]ला बदलविले",
+       "autosumm-changed-redirect-target": "पुनर्निर्देशन लक्ष्य [[$1]] पासून [[$2]] ला बदलविले",
        "autosumm-new": "नवीन पान \"$1\"",
        "autosumm-newblank": "रिकामे पान बनविले",
        "size-bytes": "$1 बा.",
        "sessionprovider-nocookies": "कुकिज अक्षम असू शकतात. याची खात्री करा कि कुकिज सक्षम केल्या आहेत व पुन्हा सुरुवात करा.",
        "randomrootpage": "अविशिष्ट मूळ पान",
        "log-action-filter-contentmodel": "आशय नमूना बदलाचा प्रकार",
+       "log-action-filter-delete": "वगळण्याचा प्रकार:",
        "log-action-filter-rights-rights": "मानवी बदल",
        "log-action-filter-suppress-block": "रोधामार्फत सदस्य दाबणे",
        "changecredentials": "अधिकारपत्रे (क्रेडेंटियल्स) बदला",
index 82524e3..24e1679 100644 (file)
        "timezoneregion-indian": "Ocean Indyjski",
        "timezoneregion-pacific": "Ocean Spokojny",
        "allowemail": "Inni użytkownicy mogą przesyłać do mnie e‐maile",
+       "email-allow-new-users-label": "Zezwól na otrzymywanie e-maili od całkowicie nowych użytkowników",
        "email-blacklist-label": "Zabroń tym użytkownikom na kontaktowanie się ze mną poprzez e-mail:",
        "prefs-searchoptions": "Wyszukiwanie",
        "prefs-namespaces": "Przestrzenie nazw",
index d85313f..13516e4 100644 (file)
        "expandtemplates": "Template spannute",
        "expand_templates_intro": "Sta pàgena speciale pigghie quacche teste e spanne tutte le template jndr'à jidde recorsivamende.<br />\nJidde spanne pure le funziune de analise cumme<br />\n<code><nowiki>{{</nowiki>#language:…}}</code>, e variabbele cumme <br />\n<code><nowiki>{{</nowiki>CURRENTDAY}}</code>.<br />\nIn pratiche tutte quidde ca stè jndr'à le doppie parendesi graffe.<br />",
        "expand_templates_title": "Titele condestuale, pe {{FULLPAGENAME}} ecc.:",
-       "expand_templates_input": "Teste de input:",
+       "expand_templates_input": "Uicchiteste de input:",
        "expand_templates_output": "Resultete",
        "expand_templates_xml_output": "XML de output",
        "expand_templates_html_output": "Resultate HTML grezze",
index ed00eda..d33d999 100644 (file)
@@ -46,7 +46,7 @@
        "tog-shownumberswatching": "Сирэйи кэтээн көрөр дьон ахсаанын көрдөр",
        "tog-oldsig": "Билигин туттар илии баттааһынын",
        "tog-fancysig": "Бэйэ илии баттааһына (сигэтэ суох)",
-       "tog-uselivepreview": "ХайдаÑ\85 Ð±Ñ\83олÑ\83оÑ\85Ñ\82ааÒ\95Ñ\8bн Ñ\82Ñ\83Ñ\82аÑ\82Ñ\8bна Ñ\8dÑ\80дÑ\8d ÐºÓ©Ñ\80үүнү Ñ\82Ñ\83Ñ\82Ñ\82Ñ\83Ñ\83",
+       "tog-uselivepreview": "ХайдаÑ\85 Ð±Ñ\83олÑ\83оÑ\85Ñ\82ааÒ\95Ñ\8bн Ñ\81иÑ\80Ñ\8dйи Ñ\85оÑ\81 Ñ\85аÑ\87айдаабакка ÐºÓ©Ñ\80дөÑ\80",
        "tog-forceeditsummary": "Тугу уларыппытым туһунан суруйбатахпына сэрэт",
        "tog-watchlisthideown": "Кэтээн көрүү тиһигэр бэйэм уларытыыларбын көрдөрүмэ",
        "tog-watchlisthidebots": "Кэтээн көрүү тиһигэр робот уларытыытын көрдөрүмэ",
        "recentchanges-legend-heading": "<strong>Легендата:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (өссө көр: [[Special:NewPages|Саҥа сирэйдэр тиһиктэрэ]])",
        "recentchanges-submit": "Көрдөр",
+       "rcfilters-tag-remove": "Маны '$1' сот",
        "rcfilters-legend-heading": "<strong>Кылгатыы испииһэгэ:</strong>",
+       "rcfilters-other-review-tools": "Тургутуу атын тэриллэрэ",
+       "rcfilters-group-results-by-page": "Түмүгүн бөлөхтөө",
        "rcfilters-activefilters": "Холбоммут сиидэлэр",
        "rcfilters-advancedfilters": "Сиһилии сиидэлэр",
+       "rcfilters-limit-title": "Көстөр түмүк",
+       "rcfilters-limit-and-date-label": "$1 уларытыы, $2",
+       "rcfilters-date-popup-title": "Көрдүүр болдьох",
+       "rcfilters-days-title": "Тиһэх күннэргэ",
+       "rcfilters-hours-title": "Тиһэх чаастар",
+       "rcfilters-days-show-days": "$1 хонук",
+       "rcfilters-days-show-hours": "$1 чаас",
        "rcfilters-quickfilters": "Бигэргэммит сиидэлэр",
        "rcfilters-quickfilters-placeholder-title": "Бигэргэммит сигэ билигин суох",
        "rcfilters-quickfilters-placeholder-description": "Сиидэ туруорууларын кэлин туһанарга, \"Холбоммут сиидэ\" хонуутугар кыбытык ойуутун баттаа.",
index adf340f..5dbcab6 100644 (file)
@@ -78,7 +78,7 @@
        "tog-watchlisthidecategorization": "Сакриј категоризацију страница",
        "tog-ccmeonemails": "Пошаљи ми копије имејлова које пошаљем другим корисницима",
        "tog-diffonly": "Не приказуј садржај странице испод разлика",
-       "tog-showhiddencats": "Ð\9fÑ\80икажи Ñ\81кривене категорије",
+       "tog-showhiddencats": "Скривене категорије",
        "tog-norollbackdiff": "Не приказуј разлику након извршеног враћања",
        "tog-useeditwarning": "Упозори ме када напуштам страницу са несачуваним променама",
        "tog-prefershttps": "Увек користи сигурну конекцију када сам пријављен.",
        "rcfilters-activefilters": "Активни филтери",
        "rcfilters-advancedfilters": "Напредни филтери",
        "rcfilters-limit-title": "Приказати измена",
-       "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|измена|измена}}, $2",
+       "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|измена|измене}}, $2",
        "rcfilters-date-popup-title": "Временски оквир",
        "rcfilters-days-title": "Претходних неколико дана",
        "rcfilters-hours-title": "Претходних неколико сати",
        "feedback-cancel": "Откажи",
        "feedback-close": "Урађено",
        "feedback-external-bug-report-button": "Пријави баг",
+       "feedback-dialog-title": "Пошаљи повратну информацију",
        "feedback-error1": "Грешка: непрепознат резултат од АПИ-ја",
        "feedback-error2": "Грешка: уређивање није успело",
        "feedback-error3": "Грешка: нема одговора од АПИ-ја",
        "gotointerwiki-invalid": "Одабрани наслов је невалидан.",
        "gotointerwiki-external": "Управо ћете да напустите пројекат {{SITENAME}} да бисте на засебном веб-сајту посетили [[$2]].\n\n'''[$1 Продужи на $1]'''",
        "undelete-cantedit": "Не можете повратити ову страницу јер немате дозволу да је уређујете.",
-       "undelete-cantcreate": "Не можете повратити ову страницу јер нема постојеће странице са овим именом и немате дозволу да направите ову страницу."
+       "undelete-cantcreate": "Не можете повратити ову страницу јер нема постојеће странице са овим именом и немате дозволу да направите ову страницу.",
+       "pagedata-title": "Подаци странице",
+       "pagedata-bad-title": "Неисправан наслов: $1."
 }
index c1835d0..3467932 100644 (file)
@@ -58,14 +58,32 @@ class DumpCategoriesAsRdf extends Maintenance {
        public function getCategoryIterator( IDatabase $dbr ) {
                $it = new BatchRowIterator(
                        $dbr,
-                       'page',
+                       [ 'page', 'page_props', 'category' ],
                        [ 'page_title' ],
                        $this->getBatchSize()
                );
                $it->addConditions( [
                        'page_namespace' => NS_CATEGORY,
                ] );
-               $it->setFetchColumns( [ 'page_title', 'page_id' ] );
+               $it->setFetchColumns( [
+                       'page_title',
+                       'page_id',
+                       'pp_propname',
+                       'cat_pages',
+                       'cat_subcats',
+                       'cat_files'
+               ] );
+               $it->addJoinConditions(
+                       [
+                               'page_props' => [
+                                       'LEFT JOIN', [ 'pp_propname' => 'hiddencat', 'pp_page = page_id' ]
+                               ],
+                               'category' => [
+                                       'LEFT JOIN', [ 'cat_title = page_title' ]
+                               ]
+                       ]
+
+               );
                return $it;
        }
 
@@ -90,6 +108,9 @@ class DumpCategoriesAsRdf extends Maintenance {
                return new RecursiveIteratorIterator( $it );
        }
 
+       /**
+        * @param int $timestamp
+        */
        public function addDumpHeader( $timestamp ) {
                global $wgRightsUrl;
                $licenseUrl = $wgRightsUrl;
@@ -129,7 +150,12 @@ class DumpCategoriesAsRdf extends Maintenance {
                foreach ( $this->getCategoryIterator( $dbr ) as $batch ) {
                        $pages = [];
                        foreach ( $batch as $row ) {
-                               $this->categoriesRdf->writeCategoryData( $row->page_title );
+                               $this->categoriesRdf->writeCategoryData(
+                                       $row->page_title,
+                                       $row->pp_propname === 'hiddencat',
+                                       (int)$row->cat_pages - (int)$row->cat_subcats - (int)$row->cat_files,
+                                       (int)$row->cat_subcats
+                               );
                                $pages[$row->page_id] = $row->page_title;
                        }
 
diff --git a/maintenance/mssql/archives/patch-comment-table.sql b/maintenance/mssql/archives/patch-comment-table.sql
new file mode 100644 (file)
index 0000000..f4c2a90
--- /dev/null
@@ -0,0 +1,57 @@
+--
+-- patch-comment-table.sql
+--
+-- T166732. Add a `comment` table and various columns (and temporary tables) to reference it.
+
+CREATE TABLE /*_*/comment (
+  comment_id bigint unsigned NOT NULL PRIMARY KEY IDENTITY(0,1),
+  comment_hash INT NOT NULL,
+  comment_text nvarchar(max) NOT NULL,
+  comment_data nvarchar(max)
+);
+CREATE INDEX /*i*/comment_hash ON /*_*/comment (comment_hash);
+
+-- dummy row for FKs. Hash is intentionally wrong so CommentStore won't match it.
+INSERT INTO /*_*/comment (comment_hash, comment_text) VALUES (-1, '** dummy **');
+
+
+CREATE TABLE /*_*/revision_comment_temp (
+  revcomment_rev INT NOT NULL CONSTRAINT FK_revcomment_rev FOREIGN KEY REFERENCES /*_*/revision(rev_id) ON DELETE CASCADE,
+  revcomment_comment_id bigint unsigned NOT NULL CONSTRAINT FK_revcomment_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
+  CONSTRAINT PK_revision_comment_temp PRIMARY KEY (revcomment_rev, revcomment_comment_id)
+);
+CREATE UNIQUE INDEX /*i*/revcomment_rev ON /*_*/revision_comment_temp (revcomment_rev);
+
+
+CREATE TABLE /*_*/image_comment_temp (
+  imgcomment_name nvarchar(255) NOT NULL CONSTRAINT FK_imgcomment_name FOREIGN KEY REFERENCES /*_*/image(imgcomment_name) ON DELETE CASCADE,
+  imgcomment_description_id bigint unsigned NOT NULL CONSTRAINT FK_imgcomment_description_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
+  CONSTRAINT PK_image_comment_temp PRIMARY KEY (imgcomment_name, imgcomment_description_id)
+);
+CREATE UNIQUE INDEX /*i*/imgcomment_name ON /*_*/image_comment_temp (imgcomment_name);
+
+
+ALTER TABLE /*_*/revision ADD CONSTRAINT DF_rev_comment DEFAULT '' FOR rev_comment;
+
+ALTER TABLE /*_*/archive ADD CONSTRAINT DF_ar_comment DEFAULT '' FOR ar_comment;
+ALTER TABLE /*_*/archive ADD ar_comment_id bigint unsigned NOT NULL CONSTRAINT DF_ar_comment_id DEFAULT 0 CONSTRAINT FK_ar_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id);
+
+ALTER TABLE /*_*/ipblocks ADD CONSTRAINT DF_ipb_reason DEFAULT '' FOR ipb_reason;
+ALTER TABLE /*_*/ipblocks ADD ipb_reason_id bigint unsigned NOT NULL CONSTRAINT DF_ipb_reason_id DEFAULT 0 CONSTRAINT FK_ipb_reason_id FOREIGN KEY REFERENCES /*_*/comment(comment_id);
+
+ALTER TABLE /*_*/image ADD CONSTRAINT DF_img_description DEFAULT '' FOR img_description;
+
+ALTER TABLE /*_*/oldimage ADD CONSTRAINT DF_oi_description DEFAULT '' FOR oi_description;
+ALTER TABLE /*_*/oldimage ADD oi_description_id bigint unsigned NOT NULL CONSTRAINT DF_oi_description_id DEFAULT 0 CONSTRAINT FK_oi_description_id FOREIGN KEY REFERENCES /*_*/comment(comment_id);
+
+ALTER TABLE /*_*/filearchive ADD CONSTRAINT DF_fa_deleted_reason DEFAULT '' FOR fa_deleted_reason;
+ALTER TABLE /*_*/filearchive ADD fa_deleted_reason_id bigint unsigned NOT NULL CONSTRAINT DF_fa_deleted_reason_id DEFAULT 0 CONSTRAINT FK_fa_deleted_reason_id FOREIGN KEY REFERENCES /*_*/comment(comment_id);
+ALTER TABLE /*_*/filearchive ADD CONSTRAINT DF_fa_description DEFAULT '' FOR fa_description;
+ALTER TABLE /*_*/filearchive ADD fa_description_id bigint unsigned NOT NULL CONSTRAINT DF_fa_description_id DEFAULT 0 CONSTRAINT FK_fa_description_id FOREIGN KEY REFERENCES /*_*/comment(comment_id);
+
+ALTER TABLE /*_*/recentchanges ADD rc_comment_id bigint unsigned NOT NULL CONSTRAINT DF_rc_comment_id DEFAULT 0 CONSTRAINT FK_rc_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id);
+
+ALTER TABLE /*_*/logging ADD log_comment_id bigint unsigned NOT NULL CONSTRAINT DF_log_comment_id DEFAULT 0 CONSTRAINT FK_log_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id);
+
+ALTER TABLE /*_*/protected_titles ADD CONSTRAINT DF_pt_reason DEFAULT '' FOR pt_reason;
+ALTER TABLE /*_*/protected_titles ADD pt_reason_id bigint unsigned NOT NULL CONSTRAINT DF_pt_reason_id DEFAULT 0 CONSTRAINT FK_pt_reason_id FOREIGN KEY REFERENCES /*_*/comment(comment_id);
index 1d5abd0..4673264 100644 (file)
@@ -117,6 +117,28 @@ CREATE TABLE /*_*/bot_passwords (
 );
 
 
+--
+-- Edits, blocks, and other actions typically have a textual comment describing
+-- the action. They are stored here to reduce the size of the main tables, and
+-- to allow for deduplication.
+--
+-- Deduplication is currently best-effort to avoid locking on inserts that
+-- would be required for strict deduplication. There MAY be multiple rows with
+-- the same comment_text and comment_data.
+--
+CREATE TABLE /*_*/comment (
+  comment_id bigint unsigned NOT NULL PRIMARY KEY IDENTITY(0,1),
+  comment_hash INT NOT NULL,
+  comment_text nvarchar(max) NOT NULL,
+  comment_data nvarchar(max)
+);
+-- Index used for deduplication.
+CREATE INDEX /*i*/comment_hash ON /*_*/comment (comment_hash);
+
+-- dummy row for FKs. Hash is intentionally wrong so CommentStore won't match it.
+INSERT INTO /*_*/comment (comment_hash, comment_text) VALUES (-1, '** dummy **');
+
+
 --
 -- Core of the wiki: each page has an entry here which identifies
 -- it by title and contains some essential metadata.
@@ -153,7 +175,7 @@ CREATE TABLE /*_*/revision (
    rev_id INT NOT NULL UNIQUE IDENTITY(0,1),
    rev_page INT NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE,
    rev_text_id INT  NOT NULL, -- FK added later
-   rev_comment NVARCHAR(255) NOT NULL,
+   rev_comment NVARCHAR(255) NOT NULL CONSTRAINT DF_rev_comment DEFAULT '',
    rev_user INT REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
    rev_user_text NVARCHAR(255) NOT NULL DEFAULT '',
    rev_timestamp varchar(14) NOT NULL default '',
@@ -177,6 +199,20 @@ INSERT INTO /*_*/revision (rev_page,rev_text_id,rev_comment,rev_user,rev_len) VA
 
 ALTER TABLE /*_*/page ADD CONSTRAINT FK_page_latest_page_id FOREIGN KEY (page_latest) REFERENCES /*_*/revision(rev_id);
 
+--
+-- Temporary table to avoid blocking on an alter of revision.
+--
+-- On large wikis like the English Wikipedia, altering the revision table is a
+-- months-long process. This table is being created to avoid such an alter, and
+-- will be merged back into revision in the future.
+--
+CREATE TABLE /*_*/revision_comment_temp (
+  revcomment_rev INT NOT NULL CONSTRAINT FK_revcomment_rev FOREIGN KEY REFERENCES /*_*/revision(rev_id) ON DELETE CASCADE,
+  revcomment_comment_id bigint unsigned NOT NULL CONSTRAINT FK_revcomment_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
+  CONSTRAINT PK_revision_comment_temp PRIMARY KEY (revcomment_rev, revcomment_comment_id)
+);
+CREATE UNIQUE INDEX /*i*/revcomment_rev ON /*_*/revision_comment_temp (revcomment_rev);
+
 --
 -- Holds TEXT of individual page revisions.
 --
@@ -207,7 +243,8 @@ CREATE TABLE /*_*/archive (
    ar_namespace SMALLINT NOT NULL DEFAULT 0,
    ar_title NVARCHAR(255) NOT NULL DEFAULT '',
    ar_text NVARCHAR(MAX) NOT NULL,
-   ar_comment NVARCHAR(255) NOT NULL,
+   ar_comment NVARCHAR(255) NOT NULL CONSTRAINT DF_ar_comment DEFAULT '',
+   ar_comment_id bigint unsigned NOT NULL CONSTRAINT DF_ar_comment_id DEFAULT 0 CONSTRAINT FK_ar_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
    ar_user INT CONSTRAINT ar_user__user_id__fk FOREIGN KEY REFERENCES /*_*/mwuser(user_id),
    ar_user_text NVARCHAR(255) NOT NULL,
    ar_timestamp varchar(14) NOT NULL default '',
@@ -567,7 +604,11 @@ CREATE TABLE /*_*/ipblocks (
   ipb_by_text nvarchar(255) NOT NULL default '',
 
   -- Text comment made by blocker.
-  ipb_reason nvarchar(255) NOT NULL,
+  ipb_reason nvarchar(255) NOT NULL CONSTRAINT DF_ipb_reason DEFAULT '',
+
+  -- Key to comment_id. Text comment made by blocker.
+  -- ("DEFAULT 0" is temporary, signaling that ipb_reason should be used)
+  ipb_reason_id bigint unsigned NOT NULL CONSTRAINT DF_ipb_reason_id DEFAULT 0 CONSTRAINT FK_ipb_reason_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
 
   -- Creation (or refresh) date in standard YMDHMS form.
   -- IP blocks expire automatically.
@@ -664,7 +705,7 @@ CREATE TABLE /*_*/image (
 
   -- Description field as entered by the uploader.
   -- This is displayed in image upload history and logs.
-  img_description nvarchar(255) NOT NULL,
+  img_description nvarchar(255) NOT NULL CONSTRAINT DF_img_description DEFAULT '',
 
   -- user_id and user_name of uploader.
   img_user int REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
@@ -690,6 +731,20 @@ CREATE INDEX /*i*/img_sha1 ON /*_*/image (img_sha1);
 -- Used to get media of one type
 CREATE INDEX /*i*/img_media_mime ON /*_*/image (img_media_type,img_major_mime,img_minor_mime);
 
+--
+-- Temporary table to avoid blocking on an alter of image.
+--
+-- On large wikis like Wikimedia Commons, altering the image table is a
+-- months-long process. This table is being created to avoid such an alter, and
+-- will be merged back into image in the future.
+--
+CREATE TABLE /*_*/image_comment_temp (
+  imgcomment_name nvarchar(255) NOT NULL CONSTRAINT FK_imgcomment_name FOREIGN KEY REFERENCES /*_*/image(imgcomment_name) ON DELETE CASCADE,
+  imgcomment_description_id bigint unsigned NOT NULL CONSTRAINT FK_imgcomment_description_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
+  CONSTRAINT PK_image_comment_temp PRIMARY KEY (imgcomment_name, imgcomment_description_id)
+);
+CREATE UNIQUE INDEX /*i*/imgcomment_name ON /*_*/image_comment_temp (imgcomment_name);
+
 
 --
 -- Previous revisions of uploaded files.
@@ -710,7 +765,8 @@ CREATE TABLE /*_*/oldimage (
   oi_width int NOT NULL default 0,
   oi_height int NOT NULL default 0,
   oi_bits int NOT NULL default 0,
-  oi_description nvarchar(255) NOT NULL,
+  oi_description nvarchar(255) NOT NULL CONSTRAINT DF_oi_description DEFAULT '',
+  oi_description_id bigint unsigned NOT NULL CONSTRAINT DF_oi_description_id DEFAULT 0 CONSTRAINT FK_oi_description_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
   oi_user int REFERENCES /*_*/mwuser(user_id),
   oi_user_text nvarchar(255) NOT NULL,
   oi_timestamp varchar(14) NOT NULL default '',
@@ -759,7 +815,8 @@ CREATE TABLE /*_*/filearchive (
   -- Deletion information, if this file is deleted.
   fa_deleted_user int,
   fa_deleted_timestamp varchar(14) default '',
-  fa_deleted_reason nvarchar(max),
+  fa_deleted_reason nvarchar(max) CONSTRAINT DF_fa_deleted_reason DEFAULT '',
+  fa_deleted_reason_id bigint unsigned NOT NULL CONSTRAINT DF_fa_deleted_reason_id DEFAULT 0 CONSTRAINT FK_fa_deleted_reason_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
 
   -- Duped fields from image
   fa_size int default 0,
@@ -770,7 +827,8 @@ CREATE TABLE /*_*/filearchive (
   fa_media_type varchar(16) default null,
   fa_major_mime varchar(16) not null default 'unknown',
   fa_minor_mime nvarchar(100) default 'unknown',
-  fa_description nvarchar(255),
+  fa_description nvarchar(255) CONSTRAINT DF_fa_description DEFAULT '',
+  fa_description_id bigint unsigned NOT NULL CONSTRAINT DF_fa_description DEFAULT 0 CONSTRAINT FK_fa_description FOREIGN KEY REFERENCES /*_*/comment(comment_id),
   fa_user int default 0 REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
   fa_user_text nvarchar(255),
   fa_timestamp varchar(14) default '',
@@ -873,6 +931,7 @@ CREATE TABLE /*_*/recentchanges (
 
   -- as in revision...
   rc_comment nvarchar(255) NOT NULL default '',
+  rc_comment_id bigint unsigned NOT NULL CONSTRAINT DF_rc_comment_id DEFAULT 0 CONSTRAINT FK_rc_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
   rc_minor bit NOT NULL default 0,
 
   -- Edits by user accounts with the 'bot' rights key are
@@ -1076,6 +1135,10 @@ CREATE TABLE /*_*/logging (
   -- Freeform text. Interpreted as edit history comments.
   log_comment nvarchar(255) NOT NULL default '',
 
+  -- Key to comment_id. Comment summarizing the change.
+  -- ("DEFAULT 0" is temporary, signaling that log_comment should be used)
+  log_comment_id bigint unsigned NOT NULL CONSTRAINT DF_log_comment_id DEFAULT 0 CONSTRAINT FK_log_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
+
   -- miscellaneous parameters:
   -- LF separated list (old system) or serialized PHP array (new system)
   log_params nvarchar(max) NOT NULL,
@@ -1236,7 +1299,8 @@ CREATE TABLE /*_*/protected_titles (
   pt_namespace int NOT NULL,
   pt_title nvarchar(255) NOT NULL,
   pt_user int REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
-  pt_reason nvarchar(255),
+  pt_reason nvarchar(255) CONSTRAINT DF_pt_reason DEFAULT '',
+  pt_reason_id bigint unsigned NOT NULL CONSTRAINT DF_pt_reason_id DEFAULT 0 CONSTRAINT FK_pt_reason_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
   pt_timestamp varchar(14) NOT NULL,
   pt_expiry varchar(14) NOT NULL,
   pt_create_perm nvarchar(60) NOT NULL
diff --git a/maintenance/oracle/archives/patch-comment-table.sql b/maintenance/oracle/archives/patch-comment-table.sql
new file mode 100644 (file)
index 0000000..cfe944f
--- /dev/null
@@ -0,0 +1,68 @@
+--
+-- patch-comment-table.sql
+--
+-- T166732. Add a `comment` table and various columns (and temporary tables) to reference it.
+
+CREATE SEQUENCE comment_comment_id_seq;
+CREATE TABLE &mw_prefix."COMMENT" (
+  comment_id NUMBER NOT NULL,
+  comment_hash NUMBER NOT NULL,
+  comment_text CLOB,
+  comment_data CLOB
+);
+CREATE INDEX &mw_prefix.comment_hash ON &mw_prefix."COMMENT" (comment_hash);
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.comment_seq_trg BEFORE INSERT ON &mw_prefix."COMMENT"
+       FOR EACH ROW WHEN (new.comment_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(comment_comment_id_seq.nextval, :new.comment_id);
+END;
+/*$mw$*/
+
+-- dummy row for FKs. Hash is intentionally wrong so CommentStore won't match it.
+INSERT INTO &mw_prefix."COMMENT" (comment_hash, comment_text) VALUES (-1, '** dummy **');
+
+
+CREATE TABLE &mw_prefix.revision_comment_temp (
+  revcomment_rev NUMBER NOT NULL,
+  revcomment_comment_id NUMBER NOT NULL
+);
+ALTER TABLE &mw_prefix.revision_comment_temp ADD CONSTRAINT &mw_prefix.revision_comment_temp_pk PRIMARY KEY (revcomment_rev, revcomment_comment_id);
+ALTER TABLE &mw_prefix.revision_comment_temp ADD CONSTRAINT &mw_prefix.revision_comment_temp_fk1 FOREIGN KEY (revcomment_rev) REFERENCES &mw_prefix.revision(rev_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
+ALTER TABLE &mw_prefix.revision_comment_temp ADD CONSTRAINT &mw_prefix.revision_comment_temp_fk2 FOREIGN KEY (revcomment_comment_id) REFERENCES &mw_prefix."COMMENT"(comment_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
+CREATE UNIQUE INDEX &mw_prefix.revcomment_rev ON &mw_prefix.revision_comment_temp (revcomment_rev);
+
+
+CREATE TABLE &mw_prefix.image_comment_temp (
+  imgcomment_name VARCHAR2(255) NOT NULL,
+  imgcomment_description_id NUMBER NOT NULL
+);
+ALTER TABLE &mw_prefix.image_comment_temp ADD CONSTRAINT &mw_prefix.image_comment_temp_pk PRIMARY KEY (imgcomment_name, imgcomment_description_id);
+ALTER TABLE &mw_prefix.image_comment_temp ADD CONSTRAINT &mw_prefix.image_comment_temp_fk1 FOREIGN KEY (imgcomment_name) REFERENCES &mw_prefix.image(img_name) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
+ALTER TABLE &mw_prefix.image_comment_temp ADD CONSTRAINT &mw_prefix.image_comment_temp_fk2 FOREIGN KEY (imgcomment_description_id) REFERENCES &mw_prefix."COMMENT"(comment_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
+CREATE UNIQUE INDEX &mw_prefix.imgcomment_name ON &mw_prefix.image_comment_temp (imgcomment_name);
+
+
+ALTER TABLE &mw_prefix.archive ADD COLUMN ar_comment_id NUMBER DEFAULT 0 NOT NULL;
+ALTER TABLE &mw_prefix.archive ADD CONSTRAINT &mw_prefix.archive_fk2 FOREIGN KEY (ar_comment_id) REFERENCES &mw_prefix."COMMENT"(comment_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
+
+ALTER TABLE &mw_prefix.ipblocks ALTER COLUMN ipb_reason VARCHAR2(255) NULL;
+ALTER TABLE &mw_prefix.ipblocks ADD COLUMN ipb_reason_id NUMBER DEFAULT 0 NOT NULL;
+ALTER TABLE &mw_prefix.ipblocks ADD CONSTRAINT &mw_prefix.ipblocks_fk3 FOREIGN KEY (ipb_reason_id) REFERENCES &mw_prefix."COMMENT"(comment_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
+
+ALTER TABLE &mw_prefix.oldimage ADD COLUMN oi_description_id NUMBER DEFAULT 0 NOT NULL;
+ALTER TABLE &mw_prefix.oldimage ADD CONSTRAINT &mw_prefix.oldimage_fk3 FOREIGN KEY (oi_description_id) REFERENCES &mw_prefix."COMMENT"(comment_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
+
+ALTER TABLE &mw_prefix.filearchive ADD COLUMN fa_deleted_reason_id NUMBER DEFAULT 0 NOT NULL;
+ALTER TABLE &mw_prefix.filearchive ADD COLUMN fa_description_id NUMBER DEFAULT 0 NOT NULL;
+ALTER TABLE &mw_prefix.filearchive ADD CONSTRAINT &mw_prefix.filearchive_fk3 FOREIGN KEY (fa_deleted_reason_id) REFERENCES &mw_prefix."COMMENT"(comment_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
+ALTER TABLE &mw_prefix.filearchive ADD CONSTRAINT &mw_prefix.filearchive_fk4 FOREIGN KEY (fa_description_id) REFERENCES &mw_prefix."COMMENT"(comment_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
+
+ALTER TABLE &mw_prefix.recentchanges ADD COLUMN rc_comment_id NUMBER DEFAULT 0 NOT NULL;
+ALTER TABLE &mw_prefix.recentchanges ADD CONSTRAINT &mw_prefix.recentchanges_fk3 FOREIGN KEY (rc_comment_id) REFERENCES &mw_prefix."COMMENT"(comment_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
+
+ALTER TABLE &mw_prefix.logging ADD COLUMN log_comment_id NUMBER DEFAULT 0 NOT NULL;
+ALTER TABLE &mw_prefix.logging ADD CONSTRAINT &mw_prefix.logging_fk2 FOREIGN KEY (log_comment_id) REFERENCES &mw_prefix."COMMENT"(comment_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
+
+ALTER TABLE &mw_prefix.protected_titles ADD COLUMN pt_reason_id NUMBER DEFAULT 0 NOT NULL;
+ALTER TABLE &mw_prefix.protected_titles ADD CONSTRAINT &mw_prefix.protected_titles_fk1 FOREIGN KEY (pt_reason_id) REFERENCES &mw_prefix."COMMENT"(comment_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
index 09d1922..7195a5e 100644 (file)
@@ -135,6 +135,25 @@ BEGIN
 END;
 /*$mw$*/
 
+CREATE SEQUENCE comment_comment_id_seq;
+CREATE TABLE &mw_prefix."COMMENT" (
+  comment_id NUMBER NOT NULL,
+  comment_hash NUMBER NOT NULL,
+  comment_text CLOB,
+  comment_data CLOB
+);
+CREATE INDEX &mw_prefix.comment_hash ON &mw_prefix."COMMENT" (comment_hash);
+/*$mw$*/
+CREATE TRIGGER &mw_prefix.comment_seq_trg BEFORE INSERT ON &mw_prefix."COMMENT"
+       FOR EACH ROW WHEN (new.comment_id IS NULL)
+BEGIN
+       &mw_prefix.lastval_pkg.setLastval(comment_comment_id_seq.nextval, :new.comment_id);
+END;
+/*$mw$*/
+
+-- dummy row for FKs. Hash is intentionally wrong so CommentStore won't match it.
+INSERT INTO &mw_prefix."COMMENT" (comment_hash, comment_text) VALUES (-1, '** dummy **');
+
 CREATE SEQUENCE revision_rev_id_seq;
 CREATE TABLE &mw_prefix.revision (
   rev_id          NUMBER      NOT NULL,
@@ -169,6 +188,15 @@ BEGIN
 END;
 /*$mw$*/
 
+CREATE TABLE &mw_prefix.revision_comment_temp (
+  revcomment_rev NUMBER NOT NULL,
+  revcomment_comment_id NUMBER NOT NULL
+);
+ALTER TABLE &mw_prefix.revision_comment_temp ADD CONSTRAINT &mw_prefix.revision_comment_temp_pk PRIMARY KEY (revcomment_rev, revcomment_comment_id);
+ALTER TABLE &mw_prefix.revision_comment_temp ADD CONSTRAINT &mw_prefix.revision_comment_temp_fk1 FOREIGN KEY (revcomment_rev) REFERENCES &mw_prefix.revision(rev_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
+ALTER TABLE &mw_prefix.revision_comment_temp ADD CONSTRAINT &mw_prefix.revision_comment_temp_fk2 FOREIGN KEY (revcomment_comment_id) REFERENCES &mw_prefix."COMMENT"(comment_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
+CREATE UNIQUE INDEX &mw_prefix.revcomment_rev ON &mw_prefix.revision_comment_temp (revcomment_rev);
+
 CREATE SEQUENCE text_old_id_seq;
 CREATE TABLE &mw_prefix.pagecontent ( -- replaces reserved word 'text'
   old_id     NUMBER  NOT NULL,
@@ -191,6 +219,7 @@ CREATE TABLE &mw_prefix.archive (
   ar_title       VARCHAR2(255)         NOT NULL,
   ar_text        CLOB,
   ar_comment     VARCHAR2(255),
+  ar_comment_id  NUMBER DEFAULT 0 NOT NULL,
   ar_user        NUMBER          DEFAULT 0 NOT NULL,
   ar_user_text   VARCHAR2(255)         NOT NULL,
   ar_timestamp   TIMESTAMP(6) WITH TIME ZONE  NOT NULL,
@@ -208,6 +237,7 @@ CREATE TABLE &mw_prefix.archive (
 );
 ALTER TABLE &mw_prefix.archive ADD CONSTRAINT &mw_prefix.archive_pk PRIMARY KEY (ar_id);
 ALTER TABLE &mw_prefix.archive ADD CONSTRAINT &mw_prefix.archive_fk1 FOREIGN KEY (ar_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED;
+ALTER TABLE &mw_prefix.archive ADD CONSTRAINT &mw_prefix.archive_fk2 FOREIGN KEY (ar_comment_id) REFERENCES &mw_prefix."COMMENT"(comment_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
 CREATE INDEX &mw_prefix.archive_i01 ON &mw_prefix.archive (ar_namespace,ar_title,ar_timestamp);
 CREATE INDEX &mw_prefix.archive_i02 ON &mw_prefix.archive (ar_user_text,ar_timestamp);
 CREATE INDEX &mw_prefix.archive_i03 ON &mw_prefix.archive (ar_rev_id);
@@ -409,7 +439,8 @@ CREATE TABLE &mw_prefix.ipblocks (
   ipb_user              NUMBER      DEFAULT 0 NOT  NULL,
   ipb_by                NUMBER      DEFAULT 0 NOT NULL,
   ipb_by_text           VARCHAR2(255)      NULL,
-  ipb_reason            VARCHAR2(255)         NOT NULL,
+  ipb_reason            VARCHAR2(255)      NULL,
+  ipb_reason_id         NUMBER DEFAULT 0 NOT NULL,
   ipb_timestamp         TIMESTAMP(6) WITH TIME ZONE  NOT NULL,
   ipb_auto              CHAR(1)         DEFAULT '0' NOT NULL,
   ipb_anon_only         CHAR(1)         DEFAULT '0' NOT NULL,
@@ -426,6 +457,7 @@ CREATE TABLE &mw_prefix.ipblocks (
 ALTER TABLE &mw_prefix.ipblocks ADD CONSTRAINT &mw_prefix.ipblocks_pk PRIMARY KEY (ipb_id);
 ALTER TABLE &mw_prefix.ipblocks ADD CONSTRAINT &mw_prefix.ipblocks_fk1 FOREIGN KEY (ipb_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED;
 ALTER TABLE &mw_prefix.ipblocks ADD CONSTRAINT &mw_prefix.ipblocks_fk2 FOREIGN KEY (ipb_by) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
+ALTER TABLE &mw_prefix.ipblocks ADD CONSTRAINT &mw_prefix.ipblocks_fk3 FOREIGN KEY (ipb_reason_id) REFERENCES &mw_prefix."COMMENT"(comment_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
 CREATE UNIQUE INDEX &mw_prefix.ipblocks_u01 ON &mw_prefix.ipblocks (ipb_address, ipb_user, ipb_auto, ipb_anon_only);
 CREATE INDEX &mw_prefix.ipblocks_i01 ON &mw_prefix.ipblocks (ipb_user);
 CREATE INDEX &mw_prefix.ipblocks_i02 ON &mw_prefix.ipblocks (ipb_range_start, ipb_range_end);
@@ -463,6 +495,15 @@ CREATE INDEX &mw_prefix.image_i02 ON &mw_prefix.image (img_size);
 CREATE INDEX &mw_prefix.image_i03 ON &mw_prefix.image (img_timestamp);
 CREATE INDEX &mw_prefix.image_i04 ON &mw_prefix.image (img_sha1);
 
+CREATE TABLE &mw_prefix.image_comment_temp (
+  imgcomment_name VARCHAR2(255) NOT NULL,
+  imgcomment_description_id NUMBER NOT NULL
+);
+ALTER TABLE &mw_prefix.image_comment_temp ADD CONSTRAINT &mw_prefix.image_comment_temp_pk PRIMARY KEY (imgcomment_name, imgcomment_description_id);
+ALTER TABLE &mw_prefix.image_comment_temp ADD CONSTRAINT &mw_prefix.image_comment_temp_fk1 FOREIGN KEY (imgcomment_name) REFERENCES &mw_prefix.image(img_name) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
+ALTER TABLE &mw_prefix.image_comment_temp ADD CONSTRAINT &mw_prefix.image_comment_temp_fk2 FOREIGN KEY (imgcomment_description_id) REFERENCES &mw_prefix."COMMENT"(comment_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
+CREATE UNIQUE INDEX &mw_prefix.imgcomment_name ON &mw_prefix.image_comment_temp (imgcomment_name);
+
 
 CREATE TABLE &mw_prefix.oldimage (
   oi_name          VARCHAR2(255)         DEFAULT 0 NOT NULL,
@@ -472,6 +513,7 @@ CREATE TABLE &mw_prefix.oldimage (
   oi_height        NUMBER      DEFAULT 0 NOT NULL,
   oi_bits          NUMBER      DEFAULT 0 NOT NULL,
   oi_description   VARCHAR2(255),
+  oi_description_id  NUMBER DEFAULT 0 NOT NULL,
   oi_user          NUMBER          DEFAULT 0 NOT NULL,
   oi_user_text     VARCHAR2(255)         NOT NULL,
   oi_timestamp     TIMESTAMP(6) WITH TIME ZONE  NOT NULL,
@@ -484,6 +526,7 @@ CREATE TABLE &mw_prefix.oldimage (
 );
 ALTER TABLE &mw_prefix.oldimage ADD CONSTRAINT &mw_prefix.oldimage_fk1 FOREIGN KEY (oi_name) REFERENCES &mw_prefix.image(img_name) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED;
 ALTER TABLE &mw_prefix.oldimage ADD CONSTRAINT &mw_prefix.oldimage_fk2 FOREIGN KEY (oi_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED;
+ALTER TABLE &mw_prefix.oldimage ADD CONSTRAINT &mw_prefix.oldimage_fk3 FOREIGN KEY (oi_description_id) REFERENCES &mw_prefix."COMMENT"(comment_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
 CREATE INDEX &mw_prefix.oldimage_i01 ON &mw_prefix.oldimage (oi_user_text,oi_timestamp);
 CREATE INDEX &mw_prefix.oldimage_i02 ON &mw_prefix.oldimage (oi_name,oi_timestamp);
 CREATE INDEX &mw_prefix.oldimage_i03 ON &mw_prefix.oldimage (oi_name,oi_archive_name);
@@ -500,6 +543,7 @@ CREATE TABLE &mw_prefix.filearchive (
   fa_deleted_user       NUMBER          DEFAULT 0 NOT NULL,
   fa_deleted_timestamp  TIMESTAMP(6) WITH TIME ZONE  NOT NULL,
   fa_deleted_reason     CLOB,
+  fa_deleted_reason_id  NUMBER DEFAULT 0 NOT NULL,
   fa_size               NUMBER     DEFAULT 0 NOT NULL,
   fa_width              NUMBER     DEFAULT 0 NOT NULL,
   fa_height             NUMBER     DEFAULT 0 NOT NULL,
@@ -509,6 +553,7 @@ CREATE TABLE &mw_prefix.filearchive (
   fa_major_mime         VARCHAR2(32) DEFAULT 'unknown',
   fa_minor_mime         VARCHAR2(100) DEFAULT 'unknown',
   fa_description        VARCHAR2(255),
+  fa_description_id     NUMBER DEFAULT 0 NOT NULL,
   fa_user               NUMBER          DEFAULT 0 NOT NULL,
   fa_user_text          VARCHAR2(255)         NOT NULL,
   fa_timestamp          TIMESTAMP(6) WITH TIME ZONE,
@@ -518,6 +563,8 @@ CREATE TABLE &mw_prefix.filearchive (
 ALTER TABLE &mw_prefix.filearchive ADD CONSTRAINT &mw_prefix.filearchive_pk PRIMARY KEY (fa_id);
 ALTER TABLE &mw_prefix.filearchive ADD CONSTRAINT &mw_prefix.filearchive_fk1 FOREIGN KEY (fa_deleted_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED;
 ALTER TABLE &mw_prefix.filearchive ADD CONSTRAINT &mw_prefix.filearchive_fk2 FOREIGN KEY (fa_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED;
+ALTER TABLE &mw_prefix.filearchive ADD CONSTRAINT &mw_prefix.filearchive_fk3 FOREIGN KEY (fa_deleted_reason_id) REFERENCES &mw_prefix."COMMENT"(comment_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
+ALTER TABLE &mw_prefix.filearchive ADD CONSTRAINT &mw_prefix.filearchive_fk4 FOREIGN KEY (fa_description_id) REFERENCES &mw_prefix."COMMENT"(comment_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
 CREATE INDEX &mw_prefix.filearchive_i01 ON &mw_prefix.filearchive (fa_name, fa_timestamp);
 CREATE INDEX &mw_prefix.filearchive_i02 ON &mw_prefix.filearchive (fa_storage_group, fa_storage_key);
 CREATE INDEX &mw_prefix.filearchive_i03 ON &mw_prefix.filearchive (fa_deleted_timestamp);
@@ -574,6 +621,7 @@ CREATE TABLE &mw_prefix.recentchanges (
   rc_namespace       NUMBER     DEFAULT 0 NOT NULL,
   rc_title           VARCHAR2(255)         NOT NULL,
   rc_comment         VARCHAR2(255),
+  rc_comment_id      NUMBER DEFAULT 0 NOT NULL,
   rc_minor           CHAR(1)         DEFAULT '0' NOT NULL,
   rc_bot             CHAR(1)         DEFAULT '0' NOT NULL,
   rc_new             CHAR(1)         DEFAULT '0' NOT NULL,
@@ -595,6 +643,7 @@ CREATE TABLE &mw_prefix.recentchanges (
 ALTER TABLE &mw_prefix.recentchanges ADD CONSTRAINT &mw_prefix.recentchanges_pk PRIMARY KEY (rc_id);
 ALTER TABLE &mw_prefix.recentchanges ADD CONSTRAINT &mw_prefix.recentchanges_fk1 FOREIGN KEY (rc_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED;
 ALTER TABLE &mw_prefix.recentchanges ADD CONSTRAINT &mw_prefix.recentchanges_fk2 FOREIGN KEY (rc_cur_id) REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
+ALTER TABLE &mw_prefix.recentchanges ADD CONSTRAINT &mw_prefix.recentchanges_fk3 FOREIGN KEY (rc_comment_id) REFERENCES &mw_prefix."COMMENT"(comment_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
 CREATE INDEX &mw_prefix.recentchanges_i01 ON &mw_prefix.recentchanges (rc_timestamp);
 CREATE INDEX &mw_prefix.recentchanges_i02 ON &mw_prefix.recentchanges (rc_namespace, rc_title);
 CREATE INDEX &mw_prefix.recentchanges_i03 ON &mw_prefix.recentchanges (rc_cur_id);
@@ -676,11 +725,13 @@ CREATE TABLE &mw_prefix.logging (
   log_title       VARCHAR2(255)         NOT NULL,
   log_page                             NUMBER,
   log_comment     VARCHAR2(255),
+  log_comment_id  NUMBER DEFAULT 0 NOT NULL,
   log_params      CLOB,
   log_deleted     CHAR(1)      DEFAULT '0' NOT NULL
 );
 ALTER TABLE &mw_prefix.logging ADD CONSTRAINT &mw_prefix.logging_pk PRIMARY KEY (log_id);
 ALTER TABLE &mw_prefix.logging ADD CONSTRAINT &mw_prefix.logging_fk1 FOREIGN KEY (log_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED;
+ALTER TABLE &mw_prefix.logging ADD CONSTRAINT &mw_prefix.logging_fk2 FOREIGN KEY (log_comment_id) REFERENCES &mw_prefix."COMMENT"(comment_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
 CREATE INDEX &mw_prefix.logging_i01 ON &mw_prefix.logging (log_type, log_timestamp);
 CREATE INDEX &mw_prefix.logging_i02 ON &mw_prefix.logging (log_user, log_timestamp);
 CREATE INDEX &mw_prefix.logging_i03 ON &mw_prefix.logging (log_namespace, log_title, log_timestamp);
@@ -790,10 +841,12 @@ CREATE TABLE &mw_prefix.protected_titles (
   pt_title       VARCHAR2(255)    NOT NULL,
   pt_user        NUMBER                  NOT NULL,
   pt_reason      VARCHAR2(255),
+  pt_reason_id   NUMBER DEFAULT 0 NOT NULL,
   pt_timestamp   TIMESTAMP(6) WITH TIME ZONE  NOT NULL,
   pt_expiry      VARCHAR2(14) NOT NULL,
   pt_create_perm VARCHAR2(60) NOT NULL
 );
+ALTER TABLE &mw_prefix.protected_titles ADD CONSTRAINT &mw_prefix.protected_titles_fk1 FOREIGN KEY (pt_reason_id) REFERENCES &mw_prefix."COMMENT"(comment_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
 CREATE UNIQUE INDEX &mw_prefix.protected_titles_u01 ON &mw_prefix.protected_titles (pt_namespace,pt_title);
 CREATE INDEX &mw_prefix.protected_titles_i01 ON &mw_prefix.protected_titles (pt_timestamp);
 
index b8bd8e0..bbb3787 100644 (file)
@@ -7,10 +7,17 @@
 <http://acme.test/wiki/Special:CategoryDump> <http://www.w3.org/2002/07/owl#imports> <https://www.mediawiki.org/ontology/ontology.owl> .
 <http://acme.test/wiki/Category:Category_One> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://www.mediawiki.org/ontology#Category> .
 <http://acme.test/wiki/Category:Category_One> <http://www.w3.org/2000/01/rdf-schema#label> "Category One" .
+<http://acme.test/wiki/Category:Category_One> <https://www.mediawiki.org/ontology#pages> "7"^^<http://www.w3.org/2001/XMLSchema#integer> .
+<http://acme.test/wiki/Category:Category_One> <https://www.mediawiki.org/ontology#subcategories> "10"^^<http://www.w3.org/2001/XMLSchema#integer> .
 <http://acme.test/wiki/Category:2_Category_Two> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://www.mediawiki.org/ontology#Category> .
+<http://acme.test/wiki/Category:2_Category_Two> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://www.mediawiki.org/ontology#HiddenCategory> .
 <http://acme.test/wiki/Category:2_Category_Two> <http://www.w3.org/2000/01/rdf-schema#label> "2 Category Two" .
+<http://acme.test/wiki/Category:2_Category_Two> <https://www.mediawiki.org/ontology#pages> "17"^^<http://www.w3.org/2001/XMLSchema#integer> .
+<http://acme.test/wiki/Category:2_Category_Two> <https://www.mediawiki.org/ontology#subcategories> "0"^^<http://www.w3.org/2001/XMLSchema#integer> .
 <http://acme.test/wiki/Category:Category_One> <https://www.mediawiki.org/ontology#isInCategory> <http://acme.test/wiki/Category:Parent_of_1> .
 <http://acme.test/wiki/Category:2_Category_Two> <https://www.mediawiki.org/ontology#isInCategory> <http://acme.test/wiki/Category:Parent_of_2> .
 <http://acme.test/wiki/Category:%D0%A2%D1%80%D0%B5%D1%82%D1%8C%D1%8F_%D0%BA%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://www.mediawiki.org/ontology#Category> .
 <http://acme.test/wiki/Category:%D0%A2%D1%80%D0%B5%D1%82%D1%8C%D1%8F_%D0%BA%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F> <http://www.w3.org/2000/01/rdf-schema#label> "\u0422\u0440\u0435\u0442\u044C\u044F \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u044F" .
+<http://acme.test/wiki/Category:%D0%A2%D1%80%D0%B5%D1%82%D1%8C%D1%8F_%D0%BA%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F> <https://www.mediawiki.org/ontology#pages> "0"^^<http://www.w3.org/2001/XMLSchema#integer> .
+<http://acme.test/wiki/Category:%D0%A2%D1%80%D0%B5%D1%82%D1%8C%D1%8F_%D0%BA%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F> <https://www.mediawiki.org/ontology#subcategories> "0"^^<http://www.w3.org/2001/XMLSchema#integer> .
 <http://acme.test/wiki/Category:%D0%A2%D1%80%D0%B5%D1%82%D1%8C%D1%8F_%D0%BA%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F> <https://www.mediawiki.org/ontology#isInCategory> <http://acme.test/wiki/Category:Parent_of_3> .
index a9f1880..5e59cfd 100644 (file)
@@ -52,7 +52,7 @@ class FakeDatabaseMysqlBase extends DatabaseMysqlBase {
        protected function doQuery( $sql ) {
        }
 
-       // From DatabaseMysql
+       // From DatabaseMysqli
        protected function mysqlConnect( $realServer ) {
        }
 
index 48935c3..5068e70 100644 (file)
@@ -14,12 +14,33 @@ class CategoriesRdfTest extends MediaWikiLangTestCase {
                return [
                        // batch 1
                        [
-                               (object)[ 'page_title' => 'Category One', 'page_id' => 1 ],
-                               (object)[ 'page_title' => '2 Category Two', 'page_id' => 2 ],
+                               (object)[
+                                       'page_title' => 'Category One',
+                                       'page_id' => 1,
+                                       'pp_propname' => null,
+                                       'cat_pages' => '20',
+                                       'cat_subcats' => '10',
+                                       'cat_files' => '3'
+                               ],
+                               (object)[
+                                       'page_title' => '2 Category Two',
+                                       'page_id' => 2,
+                                       'pp_propname' => 'hiddencat',
+                                       'cat_pages' => 20,
+                                       'cat_subcats' => 0,
+                                       'cat_files' => 3
+                               ],
                        ],
                        // batch 2
                        [
-                               (object)[ 'page_title' => 'Третья категория', 'page_id' => 3 ],
+                               (object)[
+                                       'page_title' => 'Третья категория',
+                                       'page_id' => 3,
+                                       'pp_propname' => null,
+                                       'cat_pages' => '0',
+                                       'cat_subcats' => '0',
+                                       'cat_files' => '0'
+                               ],
                        ]
                ];
        }