Drop Oracle and Mssql

After approval of RFC T191231, we are going to drop oracle and mssql
and it will be possible to bring back the support using the abstract schema

Adding to release notes will be done in a follow-up

Bug: T230418
Change-Id: I90bd5cfcc3e18011b193c965fdb1fa54675040b5
This commit is contained in:
Amir Sarabadani 2019-08-13 19:06:26 +02:00 committed by Reedy
parent dbdbeb7af2
commit 4d10bb14e8
152 changed files with 0 additions and 9997 deletions

View file

@ -20,7 +20,6 @@ $wgAutoloadLocalClasses = [
'AllMessagesTablePager' => __DIR__ . '/includes/specials/pagers/AllMessagesTablePager.php',
'AllTrans' => __DIR__ . '/maintenance/language/alltrans.php',
'AlphabeticPager' => __DIR__ . '/includes/pager/AlphabeticPager.php',
'AlterSharedConstraints' => __DIR__ . '/maintenance/oracle/alterSharedConstraints.php',
'AncientPagesPage' => __DIR__ . '/includes/specials/SpecialAncientpages.php',
'AnsiTermColorer' => __DIR__ . '/maintenance/term/MWTerm.php',
'ApiAMCreateAccount' => __DIR__ . '/includes/api/ApiAMCreateAccount.php',
@ -358,10 +357,8 @@ $wgAutoloadLocalClasses = [
'DatabaseInstaller' => __DIR__ . '/includes/installer/DatabaseInstaller.php',
'DatabaseLag' => __DIR__ . '/maintenance/lag.php',
'DatabaseLogEntry' => __DIR__ . '/includes/logging/DatabaseLogEntry.php',
'DatabaseMssql' => __DIR__ . '/includes/libs/rdbms/database/DatabaseMssql.php',
'DatabaseMysqlBase' => __DIR__ . '/includes/libs/rdbms/database/DatabaseMysqlBase.php',
'DatabaseMysqli' => __DIR__ . '/includes/libs/rdbms/database/DatabaseMysqli.php',
'DatabaseOracle' => __DIR__ . '/includes/db/DatabaseOracle.php',
'DatabasePostgres' => __DIR__ . '/includes/libs/rdbms/database/DatabasePostgres.php',
'DatabaseSqlite' => __DIR__ . '/includes/libs/rdbms/database/DatabaseSqlite.php',
'DatabaseUpdater' => __DIR__ . '/includes/installer/DatabaseUpdater.php',
@ -1011,8 +1008,6 @@ $wgAutoloadLocalClasses = [
'MoveLogFormatter' => __DIR__ . '/includes/logging/MoveLogFormatter.php',
'MovePage' => __DIR__ . '/includes/MovePage.php',
'MovePageForm' => __DIR__ . '/includes/specials/SpecialMovepage.php',
'MssqlInstaller' => __DIR__ . '/includes/installer/MssqlInstaller.php',
'MssqlUpdater' => __DIR__ . '/includes/installer/MssqlUpdater.php',
'MultiConfig' => __DIR__ . '/includes/config/MultiConfig.php',
'MultiHttpClient' => __DIR__ . '/includes/libs/http/MultiHttpClient.php',
'MultiWriteBagOStuff' => __DIR__ . '/includes/libs/objectcache/MultiWriteBagOStuff.php',
@ -1052,8 +1047,6 @@ $wgAutoloadLocalClasses = [
'OldChangesList' => __DIR__ . '/includes/changes/OldChangesList.php',
'OldLocalFile' => __DIR__ . '/includes/filerepo/file/OldLocalFile.php',
'OldRevisionImporter' => __DIR__ . '/includes/import/OldRevisionImporter.php',
'OracleInstaller' => __DIR__ . '/includes/installer/OracleInstaller.php',
'OracleUpdater' => __DIR__ . '/includes/installer/OracleUpdater.php',
'OrderedStreamingForkController' => __DIR__ . '/includes/OrderedStreamingForkController.php',
'OrphanStats' => __DIR__ . '/maintenance/storage/orphanStats.php',
'Orphans' => __DIR__ . '/maintenance/orphans.php',
@ -1664,7 +1657,6 @@ $wgAutoloadLocalClasses = [
'Wikimedia\\Rdbms\\DBUnexpectedError' => __DIR__ . '/includes/libs/rdbms/exception/DBUnexpectedError.php',
'Wikimedia\\Rdbms\\Database' => __DIR__ . '/includes/libs/rdbms/database/Database.php',
'Wikimedia\\Rdbms\\DatabaseDomain' => __DIR__ . '/includes/libs/rdbms/database/domain/DatabaseDomain.php',
'Wikimedia\\Rdbms\\DatabaseMssql' => __DIR__ . '/includes/libs/rdbms/database/DatabaseMssql.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',

File diff suppressed because it is too large Load diff

View file

@ -105,8 +105,6 @@ abstract class Installer {
protected static $dbTypes = [
'mysql',
'postgres',
'oracle',
'mssql',
'sqlite',
];

View file

@ -1,738 +0,0 @@
<?php
/**
* Microsoft SQL Server-specific installer.
*
* 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 Deployment
*/
use Wikimedia\Rdbms\Database;
use Wikimedia\Rdbms\DBQueryError;
use Wikimedia\Rdbms\DBConnectionError;
/**
* Class for setting up the MediaWiki database using Microsoft SQL Server.
*
* @ingroup Deployment
* @since 1.23
*/
class MssqlInstaller extends DatabaseInstaller {
protected $globalNames = [
'wgDBserver',
'wgDBname',
'wgDBuser',
'wgDBpassword',
'wgDBmwschema',
'wgDBprefix',
'wgDBWindowsAuthentication',
];
protected $internalDefaults = [
'_InstallUser' => 'sa',
'_InstallWindowsAuthentication' => 'sqlauth',
'_WebWindowsAuthentication' => 'sqlauth',
];
// SQL Server 2005 RTM
// @todo Are SQL Express version numbers different?)
public static $minimumVersion = '9.00.1399';
protected static $notMinimumVersionMessage = 'config-mssql-old';
// These are schema-level privs
// Note: the web user will be created will full permissions if possible, this permission
// list is only used if we are unable to grant full permissions.
public $webUserPrivs = [
'DELETE',
'INSERT',
'SELECT',
'UPDATE',
'EXECUTE',
];
/**
* @return string
*/
public function getName() {
return 'mssql';
}
/**
* @return bool
*/
public function isCompiled() {
return self::checkExtension( 'sqlsrv' );
}
/**
* @return string
*/
public function getConnectForm() {
if ( $this->getVar( '_InstallWindowsAuthentication' ) == 'windowsauth' ) {
$displayStyle = 'display: none;';
} else {
$displayStyle = 'display: block;';
}
return $this->getTextBox(
'wgDBserver',
'config-db-host',
[],
$this->parent->getHelpBox( 'config-db-host-help' )
) .
Html::openElement( 'fieldset' ) .
Html::element( 'legend', [], wfMessage( 'config-db-wiki-settings' )->text() ) .
$this->getTextBox( 'wgDBname', 'config-db-name', [ 'dir' => 'ltr' ],
$this->parent->getHelpBox( 'config-db-name-help' ) ) .
$this->getTextBox( 'wgDBmwschema', 'config-db-schema', [ 'dir' => 'ltr' ],
$this->parent->getHelpBox( 'config-db-schema-help' ) ) .
$this->getTextBox( 'wgDBprefix', 'config-db-prefix', [ 'dir' => 'ltr' ],
$this->parent->getHelpBox( 'config-db-prefix-help' ) ) .
Html::closeElement( 'fieldset' ) .
Html::openElement( 'fieldset' ) .
Html::element( 'legend', [], wfMessage( 'config-db-install-account' )->text() ) .
$this->getRadioSet( [
'var' => '_InstallWindowsAuthentication',
'label' => 'config-mssql-auth',
'itemLabelPrefix' => 'config-mssql-',
'values' => [ 'sqlauth', 'windowsauth' ],
'itemAttribs' => [
'sqlauth' => [
'class' => 'showHideRadio',
'rel' => 'dbCredentialBox',
],
'windowsauth' => [
'class' => 'hideShowRadio',
'rel' => 'dbCredentialBox',
]
],
'help' => $this->parent->getHelpBox( 'config-mssql-install-auth' )
] ) .
Html::openElement( 'div', [ 'id' => 'dbCredentialBox', 'style' => $displayStyle ] ) .
$this->getTextBox(
'_InstallUser',
'config-db-username',
[ 'dir' => 'ltr' ],
$this->parent->getHelpBox( 'config-db-install-username' )
) .
$this->getPasswordBox(
'_InstallPassword',
'config-db-password',
[ 'dir' => 'ltr' ],
$this->parent->getHelpBox( 'config-db-install-password' )
) .
Html::closeElement( 'div' ) .
Html::closeElement( 'fieldset' );
}
public function submitConnectForm() {
// Get variables from the request.
$newValues = $this->setVarsFromRequest( [
'wgDBserver',
'wgDBname',
'wgDBmwschema',
'wgDBprefix'
] );
// Validate them.
$status = Status::newGood();
if ( !strlen( $newValues['wgDBserver'] ) ) {
$status->fatal( 'config-missing-db-host' );
}
if ( !strlen( $newValues['wgDBname'] ) ) {
$status->fatal( 'config-missing-db-name' );
} elseif ( !preg_match( '/^[a-z0-9_]+$/i', $newValues['wgDBname'] ) ) {
$status->fatal( 'config-invalid-db-name', $newValues['wgDBname'] );
}
if ( !preg_match( '/^[a-z0-9_]*$/i', $newValues['wgDBmwschema'] ) ) {
$status->fatal( 'config-invalid-schema', $newValues['wgDBmwschema'] );
}
if ( !preg_match( '/^[a-z0-9_]*$/i', $newValues['wgDBprefix'] ) ) {
$status->fatal( 'config-invalid-db-prefix', $newValues['wgDBprefix'] );
}
if ( !$status->isOK() ) {
return $status;
}
// Check for blank schema and remap to dbo
if ( $newValues['wgDBmwschema'] === '' ) {
$this->setVar( 'wgDBmwschema', 'dbo' );
}
// User box
$this->setVarsFromRequest( [
'_InstallUser',
'_InstallPassword',
'_InstallWindowsAuthentication'
] );
// Try to connect
$status = $this->getConnection();
if ( !$status->isOK() ) {
return $status;
}
/**
* @var Database $conn
*/
$conn = $status->value;
// Check version
return static::meetsMinimumRequirement( $conn->getServerVersion() );
}
/**
* @return Status
*/
public function openConnection() {
global $wgDBWindowsAuthentication;
$status = Status::newGood();
$user = $this->getVar( '_InstallUser' );
$password = $this->getVar( '_InstallPassword' );
if ( $this->getVar( '_InstallWindowsAuthentication' ) == 'windowsauth' ) {
// Use Windows authentication for this connection
$wgDBWindowsAuthentication = true;
} else {
$wgDBWindowsAuthentication = false;
}
try {
/** @var DatabaseMssql $db */
$db = Database::factory( 'mssql', [
'host' => $this->getVar( 'wgDBserver' ),
'port' => $this->getVar( 'wgDBport' ),
'user' => $user,
'password' => $password,
'dbname' => false,
'flags' => 0,
'schema' => $this->getVar( 'wgDBmwschema' ),
'tablePrefix' => $this->getVar( 'wgDBprefix' ) ] );
$db->prepareStatements( false );
$db->scrollableCursor( false );
$status->value = $db;
} catch ( DBConnectionError $e ) {
$status->fatal( 'config-connection-error', $e->getMessage() );
}
return $status;
}
public function preUpgrade() {
global $wgDBuser, $wgDBpassword;
$status = $this->getConnection();
if ( !$status->isOK() ) {
$this->parent->showStatusMessage( $status );
return;
}
/**
* @var Database $conn
*/
$conn = $status->value;
$conn->selectDB( $this->getVar( 'wgDBname' ) );
# Normal user and password are selected after this step, so for now
# just copy these two
$wgDBuser = $this->getVar( '_InstallUser' );
$wgDBpassword = $this->getVar( '_InstallPassword' );
}
/**
* Return true if the install user can create accounts
*
* @return bool
*/
public function canCreateAccounts() {
$status = $this->getConnection();
if ( !$status->isOK() ) {
return false;
}
/** @var Database $conn */
$conn = $status->value;
// We need the server-level ALTER ANY LOGIN permission to create new accounts
$res = $conn->query( "SELECT permission_name FROM sys.fn_my_permissions( NULL, 'SERVER' )" );
$serverPrivs = [
'ALTER ANY LOGIN' => false,
'CONTROL SERVER' => false,
];
foreach ( $res as $row ) {
$serverPrivs[$row->permission_name] = true;
}
if ( !$serverPrivs['ALTER ANY LOGIN'] ) {
return false;
}
// Check to ensure we can grant everything needed as well
// We can't actually tell if we have WITH GRANT OPTION for a given permission, so we assume we do
// and just check for the permission
// https://technet.microsoft.com/en-us/library/ms178569.aspx
// The following array sets up which permissions imply whatever permissions we specify
$implied = [
// schema database server
'DELETE' => [ 'DELETE', 'CONTROL SERVER' ],
'EXECUTE' => [ 'EXECUTE', 'CONTROL SERVER' ],
'INSERT' => [ 'INSERT', 'CONTROL SERVER' ],
'SELECT' => [ 'SELECT', 'CONTROL SERVER' ],
'UPDATE' => [ 'UPDATE', 'CONTROL SERVER' ],
];
$grantOptions = array_flip( $this->webUserPrivs );
// Check for schema and db-level permissions, but only if the schema/db exists
$schemaPrivs = $dbPrivs = [
'DELETE' => false,
'EXECUTE' => false,
'INSERT' => false,
'SELECT' => false,
'UPDATE' => false,
];
$dbPrivs['ALTER ANY USER'] = false;
if ( $this->databaseExists( $this->getVar( 'wgDBname' ) ) ) {
$conn->selectDB( $this->getVar( 'wgDBname' ) );
$res = $conn->query( "SELECT permission_name FROM sys.fn_my_permissions( NULL, 'DATABASE' )" );
foreach ( $res as $row ) {
$dbPrivs[$row->permission_name] = true;
}
// If the db exists, we need ALTER ANY USER privs on it to make a new user
if ( !$dbPrivs['ALTER ANY USER'] ) {
return false;
}
if ( $this->schemaExists( $this->getVar( 'wgDBmwschema' ) ) ) {
// wgDBmwschema is validated to only contain alphanumeric + underscore, so this is safe
$res = $conn->query( "SELECT permission_name FROM sys.fn_my_permissions( "
. "'{$this->getVar( 'wgDBmwschema' )}', 'SCHEMA' )" );
foreach ( $res as $row ) {
$schemaPrivs[$row->permission_name] = true;
}
}
}
// Now check all the grants we'll need to be doing to see if we can
foreach ( $this->webUserPrivs as $permission ) {
if ( ( isset( $schemaPrivs[$permission] ) && $schemaPrivs[$permission] )
|| ( isset( $dbPrivs[$implied[$permission][0]] )
&& $dbPrivs[$implied[$permission][0]] )
|| ( isset( $serverPrivs[$implied[$permission][1]] )
&& $serverPrivs[$implied[$permission][1]] )
) {
unset( $grantOptions[$permission] );
}
}
if ( count( $grantOptions ) ) {
// Can't grant everything
return false;
}
return true;
}
/**
* @return string
*/
public function getSettingsForm() {
if ( $this->canCreateAccounts() ) {
$noCreateMsg = false;
} else {
$noCreateMsg = 'config-db-web-no-create-privs';
}
$wrapperStyle = $this->getVar( '_SameAccount' ) ? 'display: none' : '';
$displayStyle = $this->getVar( '_WebWindowsAuthentication' ) == 'windowsauth'
? 'display: none'
: '';
$s = Html::openElement( 'fieldset' ) .
Html::element( 'legend', [], wfMessage( 'config-db-web-account' )->text() ) .
$this->getCheckBox(
'_SameAccount', 'config-db-web-account-same',
[ 'class' => 'hideShowRadio', 'rel' => 'dbOtherAccount' ]
) .
Html::openElement( 'div', [ 'id' => 'dbOtherAccount', 'style' => $wrapperStyle ] ) .
$this->getRadioSet( [
'var' => '_WebWindowsAuthentication',
'label' => 'config-mssql-auth',
'itemLabelPrefix' => 'config-mssql-',
'values' => [ 'sqlauth', 'windowsauth' ],
'itemAttribs' => [
'sqlauth' => [
'class' => 'showHideRadio',
'rel' => 'dbCredentialBox',
],
'windowsauth' => [
'class' => 'hideShowRadio',
'rel' => 'dbCredentialBox',
]
],
'help' => $this->parent->getHelpBox( 'config-mssql-web-auth' )
] ) .
Html::openElement( 'div', [ 'id' => 'dbCredentialBox', 'style' => $displayStyle ] ) .
$this->getTextBox( 'wgDBuser', 'config-db-username' ) .
$this->getPasswordBox( 'wgDBpassword', 'config-db-password' ) .
Html::closeElement( 'div' );
if ( $noCreateMsg ) {
$s .= $this->parent->getWarningBox( wfMessage( $noCreateMsg )->plain() );
} else {
$s .= $this->getCheckBox( '_CreateDBAccount', 'config-db-web-create' );
}
$s .= Html::closeElement( 'div' ) . Html::closeElement( 'fieldset' );
return $s;
}
/**
* @return Status
*/
public function submitSettingsForm() {
$this->setVarsFromRequest( [
'wgDBuser',
'wgDBpassword',
'_SameAccount',
'_CreateDBAccount',
'_WebWindowsAuthentication'
] );
if ( $this->getVar( '_SameAccount' ) ) {
$this->setVar( '_WebWindowsAuthentication', $this->getVar( '_InstallWindowsAuthentication' ) );
$this->setVar( 'wgDBuser', $this->getVar( '_InstallUser' ) );
$this->setVar( 'wgDBpassword', $this->getVar( '_InstallPassword' ) );
}
if ( $this->getVar( '_WebWindowsAuthentication' ) == 'windowsauth' ) {
$this->setVar( 'wgDBuser', '' );
$this->setVar( 'wgDBpassword', '' );
$this->setVar( 'wgDBWindowsAuthentication', true );
} else {
$this->setVar( 'wgDBWindowsAuthentication', false );
}
if ( $this->getVar( '_CreateDBAccount' )
&& $this->getVar( '_WebWindowsAuthentication' ) == 'sqlauth'
&& strval( $this->getVar( 'wgDBpassword' ) ) == ''
) {
return Status::newFatal( 'config-db-password-empty', $this->getVar( 'wgDBuser' ) );
}
// Validate the create checkbox
$canCreate = $this->canCreateAccounts();
if ( !$canCreate ) {
$this->setVar( '_CreateDBAccount', false );
$create = false;
} else {
$create = $this->getVar( '_CreateDBAccount' );
}
if ( !$create ) {
// Test the web account
$user = $this->getVar( 'wgDBuser' );
$password = $this->getVar( 'wgDBpassword' );
if ( $this->getVar( '_WebWindowsAuthentication' ) == 'windowsauth' ) {
$user = 'windowsauth';
$password = 'windowsauth';
}
try {
Database::factory( 'mssql', [
'host' => $this->getVar( 'wgDBserver' ),
'user' => $user,
'password' => $password,
'dbname' => false,
'flags' => 0,
'tablePrefix' => $this->getVar( 'wgDBprefix' ),
'schema' => $this->getVar( 'wgDBmwschema' ),
] );
} catch ( DBConnectionError $e ) {
return Status::newFatal( 'config-connection-error', $e->getMessage() );
}
}
return Status::newGood();
}
public function preInstall() {
# Add our user callback to installSteps, right before the tables are created.
$callback = [
'name' => 'user',
'callback' => [ $this, 'setupUser' ],
];
$this->parent->addInstallStep( $callback, 'tables' );
}
/**
* @return Status
*/
public function setupDatabase() {
$status = $this->getConnection();
if ( !$status->isOK() ) {
return $status;
}
/** @var Database $conn */
$conn = $status->value;
$dbName = $this->getVar( 'wgDBname' );
$schemaName = $this->getVar( 'wgDBmwschema' );
if ( !$this->databaseExists( $dbName ) ) {
$conn->query(
"CREATE DATABASE " . $conn->addIdentifierQuotes( $dbName ),
__METHOD__
);
}
$conn->selectDB( $dbName );
if ( !$this->schemaExists( $schemaName ) ) {
$conn->query(
"CREATE SCHEMA " . $conn->addIdentifierQuotes( $schemaName ),
__METHOD__
);
}
if ( !$this->catalogExists( $schemaName ) ) {
$conn->query(
"CREATE FULLTEXT CATALOG " . $conn->addIdentifierQuotes( $schemaName ),
__METHOD__
);
}
$this->setupSchemaVars();
return $status;
}
/**
* @return Status
*/
public function setupUser() {
$dbUser = $this->getVar( 'wgDBuser' );
if ( $dbUser == $this->getVar( '_InstallUser' )
|| ( $this->getVar( '_InstallWindowsAuthentication' ) == 'windowsauth'
&& $this->getVar( '_WebWindowsAuthentication' ) == 'windowsauth' ) ) {
return Status::newGood();
}
$status = $this->getConnection();
if ( !$status->isOK() ) {
return $status;
}
$this->setupSchemaVars();
$dbName = $this->getVar( 'wgDBname' );
$this->db->selectDB( $dbName );
$password = $this->getVar( 'wgDBpassword' );
$schemaName = $this->getVar( 'wgDBmwschema' );
if ( $this->getVar( '_WebWindowsAuthentication' ) == 'windowsauth' ) {
$dbUser = 'windowsauth';
$password = 'windowsauth';
}
if ( $this->getVar( '_CreateDBAccount' ) ) {
$tryToCreate = true;
} else {
$tryToCreate = false;
}
$escUser = $this->db->addIdentifierQuotes( $dbUser );
$escDb = $this->db->addIdentifierQuotes( $dbName );
$escSchema = $this->db->addIdentifierQuotes( $schemaName );
$grantableNames = [];
if ( $tryToCreate ) {
$escPass = $this->db->addQuotes( $password );
if ( !$this->loginExists( $dbUser ) ) {
try {
$this->db->begin();
$this->db->selectDB( 'master' );
$logintype = $this->getVar( '_WebWindowsAuthentication' ) == 'windowsauth'
? 'FROM WINDOWS'
: "WITH PASSWORD = $escPass";
$this->db->query( "CREATE LOGIN $escUser $logintype" );
$this->db->selectDB( $dbName );
$this->db->query( "CREATE USER $escUser FOR LOGIN $escUser WITH DEFAULT_SCHEMA = $escSchema" );
$this->db->commit();
$grantableNames[] = $dbUser;
} catch ( DBQueryError $dqe ) {
$this->db->rollback();
$status->warning( 'config-install-user-create-failed', $dbUser, $dqe->getMessage() );
}
} elseif ( !$this->userExists( $dbUser ) ) {
try {
$this->db->begin();
$this->db->selectDB( $dbName );
$this->db->query( "CREATE USER $escUser FOR LOGIN $escUser WITH DEFAULT_SCHEMA = $escSchema" );
$this->db->commit();
$grantableNames[] = $dbUser;
} catch ( DBQueryError $dqe ) {
$this->db->rollback();
$status->warning( 'config-install-user-create-failed', $dbUser, $dqe->getMessage() );
}
} else {
$status->warning( 'config-install-user-alreadyexists', $dbUser );
$grantableNames[] = $dbUser;
}
}
// Try to grant to all the users we know exist or we were able to create
$this->db->selectDB( $dbName );
if ( $grantableNames ) {
try {
// First try to grant full permissions
$fullPrivArr = [
'BACKUP DATABASE', 'BACKUP LOG', 'CREATE FUNCTION', 'CREATE PROCEDURE',
'CREATE TABLE', 'CREATE VIEW', 'CREATE FULLTEXT CATALOG', 'SHOWPLAN'
];
$fullPrivList = implode( ', ', $fullPrivArr );
$this->db->begin();
$this->db->query( "GRANT $fullPrivList ON DATABASE :: $escDb TO $escUser", __METHOD__ );
$this->db->query( "GRANT CONTROL ON SCHEMA :: $escSchema TO $escUser", __METHOD__ );
$this->db->commit();
} catch ( DBQueryError $dqe ) {
// If that fails, try to grant the limited subset specified in $this->webUserPrivs
try {
$privList = implode( ', ', $this->webUserPrivs );
$this->db->rollback();
$this->db->begin();
$this->db->query( "GRANT $privList ON SCHEMA :: $escSchema TO $escUser", __METHOD__ );
$this->db->commit();
} catch ( DBQueryError $dqe ) {
$this->db->rollback();
$status->fatal( 'config-install-user-grant-failed', $dbUser, $dqe->getMessage() );
}
// Also try to grant SHOWPLAN on the db, but don't fail if we can't
// (just makes a couple things in mediawiki run slower since
// we have to run SELECT COUNT(*) instead of getting the query plan)
try {
$this->db->query( "GRANT SHOWPLAN ON DATABASE :: $escDb TO $escUser", __METHOD__ );
} catch ( DBQueryError $dqe ) {
}
}
}
return $status;
}
public function createTables() {
$status = parent::createTables();
// Do last-minute stuff like fulltext indexes (since they can't be inside a transaction)
if ( $status->isOK() ) {
$searchindex = $this->db->tableName( 'searchindex' );
$schema = $this->db->addIdentifierQuotes( $this->getVar( 'wgDBmwschema' ) );
try {
$this->db->query( "CREATE FULLTEXT INDEX ON $searchindex (si_title, si_text) "
. "KEY INDEX si_page ON $schema" );
} catch ( DBQueryError $dqe ) {
$status->fatal( 'config-install-tables-failed', $dqe->getMessage() );
}
}
return $status;
}
public function getGlobalDefaults() {
// The default $wgDBmwschema is null, which breaks Postgres and other DBMSes that require
// the use of a schema, so we need to set it here
return array_merge( parent::getGlobalDefaults(), [
'wgDBmwschema' => 'mediawiki',
] );
}
/**
* Try to see if the login exists
* @param string $user Username to check
* @return bool
*/
private function loginExists( $user ) {
$res = $this->db->selectField( 'sys.sql_logins', 1, [ 'name' => $user ] );
return (bool)$res;
}
/**
* Try to see if the user account exists
* We assume we already have the appropriate database selected
* @param string $user Username to check
* @return bool
*/
private function userExists( $user ) {
$res = $this->db->selectField( 'sys.sysusers', 1, [ 'name' => $user ] );
return (bool)$res;
}
/**
* Try to see if a given database exists
* @param string $dbName Database name to check
* @return bool
*/
private function databaseExists( $dbName ) {
$res = $this->db->selectField( 'sys.databases', 1, [ 'name' => $dbName ] );
return (bool)$res;
}
/**
* Try to see if a given schema exists
* We assume we already have the appropriate database selected
* @param string $schemaName Schema name to check
* @return bool
*/
private function schemaExists( $schemaName ) {
$res = $this->db->selectField( 'sys.schemas', 1, [ 'name' => $schemaName ] );
return (bool)$res;
}
/**
* Try to see if a given fulltext catalog exists
* We assume we already have the appropriate database selected
* @param string $catalogName Catalog name to check
* @return bool
*/
private function catalogExists( $catalogName ) {
$res = $this->db->selectField( 'sys.fulltext_catalogs', 1, [ 'name' => $catalogName ] );
return (bool)$res;
}
/**
* Get variables to substitute into tables.sql and the SQL patch files.
*
* @return array
*/
public function getSchemaVars() {
return [
'wgDBname' => $this->getVar( 'wgDBname' ),
'wgDBmwschema' => $this->getVar( 'wgDBmwschema' ),
'wgDBuser' => $this->getVar( 'wgDBuser' ),
'wgDBpassword' => $this->getVar( 'wgDBpassword' ),
];
}
public function getLocalSettings() {
$schema = LocalSettingsGenerator::escapePhpString( $this->getVar( 'wgDBmwschema' ) );
$prefix = LocalSettingsGenerator::escapePhpString( $this->getVar( 'wgDBprefix' ) );
$windowsauth = $this->getVar( 'wgDBWindowsAuthentication' ) ? 'true' : 'false';
return "# MSSQL specific settings
\$wgDBWindowsAuthentication = {$windowsauth};
\$wgDBmwschema = \"{$schema}\";
\$wgDBprefix = \"{$prefix}\";";
}
}

View file

@ -1,199 +0,0 @@
<?php
/**
* Microsoft SQL Server-specific installer.
*
* 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 Deployment
*/
use Wikimedia\Rdbms\DatabaseMssql;
/**
* Class for setting up the MediaWiki database using Microsoft SQL Server.
*
* @ingroup Deployment
* @since 1.23
*/
class MssqlUpdater extends DatabaseUpdater {
/**
* @var DatabaseMssql
*/
protected $db;
protected function getCoreUpdateList() {
return [
// 1.23
[ 'addField', 'mwuser', 'user_password_expires', 'patch-user_password_expires.sql' ],
// 1.24
[ 'addField', 'page', 'page_lang', 'patch-page_page_lang.sql' ],
// 1.25
[ 'dropTable', 'hitcounter' ],
[ 'dropField', 'site_stats', 'ss_total_views', 'patch-drop-ss_total_views.sql' ],
[ 'dropField', 'page', 'page_counter', 'patch-drop-page_counter.sql' ],
// scripts were updated in 1.27 due to SQL errors; retaining old updatekeys so that people
// updating from 1.23->1.25->1.27 do not execute these scripts twice even though the
// updatekeys no longer make sense as they are.
[ 'updateSchema', 'categorylinks', 'cl_type-category_types-ck',
'patch-categorylinks-constraints.sql' ],
[ 'updateSchema', 'filearchive', 'fa_major_mime-major_mime-ck',
'patch-filearchive-constraints.sql' ],
[ 'updateSchema', 'oldimage', 'oi_major_mime-major_mime-ck',
'patch-oldimage-constraints.sql' ],
[ 'updateSchema', 'image', 'img_major_mime-major_mime-ck', 'patch-image-constraints.sql' ],
[ 'updateSchema', 'uploadstash', 'us_media_type-media_type-ck',
'patch-uploadstash-constraints.sql' ],
[ 'modifyField', 'image', 'img_major_mime',
'patch-img_major_mime-chemical.sql' ],
[ 'modifyField', 'oldimage', 'oi_major_mime',
'patch-oi_major_mime-chemical.sql' ],
[ 'modifyField', 'filearchive', 'fa_major_mime',
'patch-fa_major_mime-chemical.sql' ],
// 1.27
[ 'dropTable', 'msg_resource_links' ],
[ 'dropTable', 'msg_resource' ],
[ 'addField', 'watchlist', 'wl_id', 'patch-watchlist-wl_id.sql' ],
[ 'dropField', 'mwuser', 'user_options', 'patch-drop-user_options.sql' ],
[ 'addTable', 'bot_passwords', 'patch-bot_passwords.sql' ],
[ 'addField', 'pagelinks', 'pl_from_namespace', 'patch-pl_from_namespace.sql' ],
[ 'addField', 'templatelinks', 'tl_from_namespace', 'patch-tl_from_namespace.sql' ],
[ 'addField', 'imagelinks', 'il_from_namespace', 'patch-il_from_namespace.sql' ],
[ 'dropIndex', 'categorylinks', 'cl_collation', 'patch-kill-cl_collation_index.sql' ],
[ 'addIndex', 'categorylinks', 'cl_collation_ext',
'patch-add-cl_collation_ext_index.sql' ],
[ 'dropField', 'recentchanges', 'rc_cur_time', 'patch-drop-rc_cur_time.sql' ],
[ 'addField', 'page_props', 'pp_sortkey', 'patch-pp_sortkey.sql' ],
[ 'updateSchema', 'oldimage', 'oldimage varchar', 'patch-oldimage-schema.sql' ],
[ 'updateSchema', 'filearchive', 'filearchive varchar', 'patch-filearchive-schema.sql' ],
[ 'updateSchema', 'image', 'image varchar', 'patch-image-schema.sql' ],
[ 'updateSchema', 'recentchanges', 'recentchanges-drop-fks',
'patch-recentchanges-drop-fks.sql' ],
[ 'updateSchema', 'logging', 'logging-drop-fks', 'patch-logging-drop-fks.sql' ],
[ 'updateSchema', 'archive', 'archive-drop-fks', 'patch-archive-drop-fks.sql' ],
// 1.28
[ 'addIndex', 'recentchanges', 'rc_name_type_patrolled_timestamp',
'patch-add-rc_name_type_patrolled_timestamp_index.sql' ],
[ 'addField', 'change_tag', 'ct_id', 'patch-change_tag-ct_id.sql' ],
// 1.29
[ 'addField', 'externallinks', 'el_index_60', 'patch-externallinks-el_index_60.sql' ],
[ 'dropIndex', 'oldimage', 'oi_name_archive_name',
'patch-alter-table-oldimage.sql' ],
// 1.30
[ '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' ],
// This field was added in 1.31, but is put here so it can be used by 'migrateComments'
[ 'addField', 'image', 'img_description_id', 'patch-image-img_description_id.sql' ],
// Should have been in 1.30
[ 'migrateComments' ],
// 1.31
[ 'addTable', 'slot_roles', 'patch-slot_roles.sql' ],
[ 'addTable', 'content_models', 'patch-content_models.sql' ],
[ 'addTable', 'content', 'patch-content.sql' ],
[ 'addTable', 'slots', 'patch-slots.sql' ],
[ 'addField', 'slots', 'slot_origin', 'patch-slot-origin.sql' ],
[ 'migrateArchiveText' ],
[ 'addTable', 'actor', 'patch-actor-table.sql' ],
[ 'migrateActors' ],
[ 'modifyField', 'revision', 'rev_text_id', 'patch-rev_text_id-default.sql' ],
[ 'modifyTable', 'site_stats', 'patch-site_stats-modify.sql' ],
[ 'populateArchiveRevId' ],
[ 'modifyField', 'recentchanges', 'rc_patrolled', 'patch-rc_patrolled_type.sql' ],
[ 'addIndex', 'recentchanges', 'rc_namespace_title_timestamp',
'patch-recentchanges-nttindex.sql' ],
// 1.32
[ 'addTable', 'change_tag_def', 'patch-change_tag_def.sql' ],
[ 'populateExternallinksIndex60' ],
[ 'modifyfield', 'externallinks', 'el_index_60',
'patch-externallinks-el_index_60-drop-default.sql' ],
[ 'runMaintenance', DeduplicateArchiveRevId::class, 'maintenance/deduplicateArchiveRevId.php' ],
[ 'addField', 'change_tag', 'ct_tag_id', 'patch-change_tag-tag_id.sql' ],
[ 'addIndex', 'archive', 'ar_revid_uniq', 'patch-archive-ar_rev_id-unique.sql' ],
[ 'populateContentTables' ],
[ 'addIndex', 'logging', 'log_type_action', 'patch-logging-log-type-action-index.sql' ],
[ 'dropIndex', 'logging', 'type_action', 'patch-logging-drop-type-action-index.sql' ],
[ 'addIndex', 'interwiki', 'PRIMARY', 'patch-interwiki-pk.sql' ],
[ 'addIndex', 'protected_titles', 'PRIMARY', 'patch-protected_titles-pk.sql' ],
[ 'addIndex', 'page_props', 'PRIMARY', 'patch-page_props-pk.sql' ],
[ 'addIndex', 'site_identifiers', 'PRIMARY', 'patch-site_identifiers-pk.sql' ],
[ 'addIndex', 'recentchanges', 'rc_this_oldid', 'patch-recentchanges-rc_this_oldid-index.sql' ],
[ 'dropTable', 'transcache' ],
[ 'runMaintenance', PopulateChangeTagDef::class, 'maintenance/populateChangeTagDef.php' ],
[ 'addIndex', 'change_tag', 'change_tag_rc_tag_id',
'patch-change_tag-change_tag_rc_tag_id.sql' ],
[ 'addField', 'ipblocks', 'ipb_sitewide', 'patch-ipb_sitewide.sql' ],
[ 'addTable', 'ipblocks_restrictions', 'patch-ipblocks_restrictions-table.sql' ],
[ 'migrateImageCommentTemp' ],
// 1.33
[ 'dropField', 'change_tag', 'ct_tag', 'patch-drop-ct_tag.sql' ],
[ 'dropTable', 'valid_tag' ],
[ 'dropTable', 'tag_summary' ],
[ 'dropField', 'protected_titles', 'pt_reason', 'patch-drop-comment-fields.sql' ],
];
}
protected function applyPatch( $path, $isFullPath = false, $msg = null ) {
$prevScroll = $this->db->scrollableCursor( false );
$prevPrep = $this->db->prepareStatements( false );
parent::applyPatch( $path, $isFullPath, $msg );
$this->db->scrollableCursor( $prevScroll );
$this->db->prepareStatements( $prevPrep );
return true;
}
/**
* General schema update for a table that touches more than one field or requires
* destructive actions (such as dropping and recreating the table). NOTE: Usage of
* this function is highly discouraged, use it's successor DatabaseUpdater::modifyTable
* instead.
*
* @param string $table
* @param string $updatekey
* @param string $patch
* @param bool $fullpath
* @return bool
*/
protected function updateSchema( $table, $updatekey, $patch, $fullpath = false ) {
if ( !$this->db->tableExists( $table, __METHOD__ ) ) {
$this->output( "...$table table does not exist, skipping schema update patch.\n" );
} elseif ( $this->updateRowExists( $updatekey ) ) {
$this->output( "...$table already had schema updated by $patch.\n" );
} else {
$apply = $this->applyPatch( $patch, $fullpath, "Updating schema of table $table" );
if ( $apply ) {
$this->insertUpdateRow( $updatekey );
}
return $apply;
}
return true;
}
}

View file

@ -1,340 +0,0 @@
<?php
/**
* Oracle-specific installer.
*
* 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 Deployment
*/
use Wikimedia\Rdbms\Database;
use Wikimedia\Rdbms\DBConnectionError;
/**
* Class for setting up the MediaWiki database using Oracle.
*
* @ingroup Deployment
* @since 1.17
*/
class OracleInstaller extends DatabaseInstaller {
protected $globalNames = [
'wgDBserver',
'wgDBname',
'wgDBuser',
'wgDBpassword',
'wgDBprefix',
];
protected $internalDefaults = [
'_OracleDefTS' => 'USERS',
'_OracleTempTS' => 'TEMP',
'_InstallUser' => 'SYSTEM',
];
public static $minimumVersion = '9.0.1'; // 9iR1
protected static $notMinimumVersionMessage = 'config-oracle-old';
protected $connError = null;
public function getName() {
return 'oracle';
}
public function isCompiled() {
return self::checkExtension( 'oci8' );
}
public function getConnectForm() {
if ( $this->getVar( 'wgDBserver' ) == 'localhost' ) {
$this->parent->setVar( 'wgDBserver', '' );
}
return $this->getTextBox(
'wgDBserver',
'config-db-host-oracle',
[],
$this->parent->getHelpBox( 'config-db-host-oracle-help' )
) .
Html::openElement( 'fieldset' ) .
Html::element( 'legend', [], wfMessage( 'config-db-wiki-settings' )->text() ) .
$this->getTextBox( 'wgDBprefix', 'config-db-prefix' ) .
$this->getTextBox( '_OracleDefTS', 'config-oracle-def-ts' ) .
$this->getTextBox(
'_OracleTempTS',
'config-oracle-temp-ts',
[],
$this->parent->getHelpBox( 'config-db-oracle-help' )
) .
Html::closeElement( 'fieldset' ) .
$this->parent->getWarningBox( wfMessage( 'config-db-account-oracle-warn' )->text() ) .
$this->getInstallUserBox() .
$this->getWebUserBox();
}
public function submitInstallUserBox() {
parent::submitInstallUserBox();
$this->parent->setVar( '_InstallDBname', $this->getVar( '_InstallUser' ) );
return Status::newGood();
}
public function submitConnectForm() {
// Get variables from the request
$newValues = $this->setVarsFromRequest( [
'wgDBserver',
'wgDBprefix',
'wgDBuser',
'wgDBpassword'
] );
$this->parent->setVar( 'wgDBname', $this->getVar( 'wgDBuser' ) );
// Validate them
$status = Status::newGood();
if ( !strlen( $newValues['wgDBserver'] ) ) {
$status->fatal( 'config-missing-db-server-oracle' );
} elseif ( !self::checkConnectStringFormat( $newValues['wgDBserver'] ) ) {
$status->fatal( 'config-invalid-db-server-oracle', $newValues['wgDBserver'] );
}
if ( !preg_match( '/^[a-zA-Z0-9_]*$/', $newValues['wgDBprefix'] ) ) {
$status->fatal( 'config-invalid-schema', $newValues['wgDBprefix'] );
}
if ( !$status->isOK() ) {
return $status;
}
// Submit user box
$status = $this->submitInstallUserBox();
if ( !$status->isOK() ) {
return $status;
}
// Try to connect trough multiple scenarios
// Scenario 1: Install with a manually created account
$status = $this->getConnection();
if ( !$status->isOK() ) {
if ( $this->connError == 28009 ) {
// _InstallUser seems to be a SYSDBA
// Scenario 2: Create user with SYSDBA and install with new user
$status = $this->submitWebUserBox();
if ( !$status->isOK() ) {
return $status;
}
$status = $this->openSYSDBAConnection();
if ( !$status->isOK() ) {
return $status;
}
if ( !$this->getVar( '_CreateDBAccount' ) ) {
$status->fatal( 'config-db-sys-create-oracle' );
}
} else {
return $status;
}
} else {
// check for web user credentials
// Scenario 3: Install with a priviliged user but use a restricted user
$statusIS3 = $this->submitWebUserBox();
if ( !$statusIS3->isOK() ) {
return $statusIS3;
}
}
/**
* @var Database $conn
*/
$conn = $status->value;
// Check version
$status->merge( static::meetsMinimumRequirement( $conn->getServerVersion() ) );
return $status;
}
public function openConnection() {
return $this->doOpenConnection();
}
public function openSYSDBAConnection() {
return $this->doOpenConnection( DatabaseOracle::DBO_SYSDBA );
}
/**
* @param int $flags
* @return Status Status with DatabaseOracle or null as the value
*/
private function doOpenConnection( $flags = 0 ) {
$status = Status::newGood();
try {
$db = Database::factory(
'oracle',
[
'host' => $this->getVar( 'wgDBserver' ),
'user' => $this->getVar( '_InstallUser' ),
'password' => $this->getVar( '_InstallPassword' ),
'dbname' => $this->getVar( '_InstallDBname' ),
'tablePrefix' => $this->getVar( 'wgDBprefix' ),
'flags' => $flags
]
);
$status->value = $db;
} catch ( DBConnectionError $e ) {
$this->connError = $e->db->lastErrno();
$status->fatal( 'config-connection-error', $e->getMessage() );
}
return $status;
}
public function needsUpgrade() {
$tempDBname = $this->getVar( 'wgDBname' );
$this->parent->setVar( 'wgDBname', $this->getVar( 'wgDBuser' ) );
$retVal = parent::needsUpgrade();
$this->parent->setVar( 'wgDBname', $tempDBname );
return $retVal;
}
public function preInstall() {
# Add our user callback to installSteps, right before the tables are created.
$callback = [
'name' => 'user',
'callback' => [ $this, 'setupUser' ]
];
$this->parent->addInstallStep( $callback, 'database' );
}
public function setupDatabase() {
$status = Status::newGood();
return $status;
}
public function setupUser() {
global $IP;
if ( !$this->getVar( '_CreateDBAccount' ) ) {
return Status::newGood();
}
// normaly only SYSDBA users can create accounts
$status = $this->openSYSDBAConnection();
if ( !$status->isOK() ) {
if ( $this->connError == 1031 ) {
// insufficient privileges (looks like a normal user)
$status = $this->openConnection();
if ( !$status->isOK() ) {
return $status;
}
} else {
return $status;
}
}
$this->db = $status->value;
$this->setupSchemaVars();
if ( !$this->db->selectDB( $this->getVar( 'wgDBuser' ) ) ) {
$this->db->setFlag( DBO_DDLMODE );
$error = $this->db->sourceFile( "$IP/maintenance/oracle/user.sql" );
if ( $error !== true || !$this->db->selectDB( $this->getVar( 'wgDBuser' ) ) ) {
$status->fatal( 'config-install-user-failed', $this->getVar( 'wgDBuser' ), $error );
}
} elseif ( $this->db->getFlag( DBO_SYSDBA ) ) {
$status->fatal( 'config-db-sys-user-exists-oracle', $this->getVar( 'wgDBuser' ) );
}
if ( $status->isOK() ) {
// user created or already existing, switching back to a normal connection
// as the new user has all needed privileges to setup the rest of the schema
// i will be using that user as _InstallUser from this point on
$this->db->close();
$this->db = false;
$this->parent->setVar( '_InstallUser', $this->getVar( 'wgDBuser' ) );
$this->parent->setVar( '_InstallPassword', $this->getVar( 'wgDBpassword' ) );
$this->parent->setVar( '_InstallDBname', $this->getVar( 'wgDBuser' ) );
$status = $this->getConnection();
}
return $status;
}
/**
* Overload: after this action field info table has to be rebuilt
* @return Status
*/
public function createTables() {
$this->setupSchemaVars();
$this->db->setFlag( DBO_DDLMODE );
$this->parent->setVar( 'wgDBname', $this->getVar( 'wgDBuser' ) );
$status = parent::createTables();
$this->db->clearFlag( DBO_DDLMODE );
$this->db->query( 'BEGIN fill_wiki_info; END;' );
return $status;
}
public function getSchemaVars() {
$varNames = [
# These variables are used by maintenance/oracle/user.sql
'_OracleDefTS',
'_OracleTempTS',
'wgDBuser',
'wgDBpassword',
# These are used by tables.sql
'wgDBprefix',
];
$vars = [];
foreach ( $varNames as $name ) {
$vars[$name] = $this->getVar( $name );
}
return $vars;
}
public function getLocalSettings() {
$prefix = $this->getVar( 'wgDBprefix' );
return "# Oracle specific settings
\$wgDBprefix = \"{$prefix}\";
";
}
/**
* Function checks the format of Oracle connect string
* The actual validity of the string is checked by attempting to connect
*
* Regex should be able to validate all connect string formats
* [//](host|tns_name)[:port][/service_name][:POOLED]
* http://www.orafaq.com/wiki/EZCONNECT
*
* @since 1.22
*
* @param string $connect_string
*
* @return bool Whether the connection string is valid.
*/
public static function checkConnectStringFormat( $connect_string ) {
// phpcs:disable Generic.Files.LineLength
// @todo Very long regular expression. Make more readable?
$isValid = preg_match( '/^[[:alpha:]][\w\-]*(?:\.[[:alpha:]][\w\-]*){0,2}$/', $connect_string ); // TNS name
$isValid |= preg_match( '/^(?:\/\/)?[\w\-\.]+(?::[\d]+)?(?:\/(?:[\w\-\.]+(?::(pooled|dedicated|shared))?)?(?:\/[\w\-\.]+)?)?$/', $connect_string ); // EZConnect
// phpcs:enable
return (bool)$isValid;
}
}

View file

@ -1,374 +0,0 @@
<?php
/**
* Oracle-specific updater.
*
* 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 Deployment
*/
/**
* Class for handling updates to Oracle databases.
*
* @ingroup Deployment
* @since 1.17
*/
class OracleUpdater extends DatabaseUpdater {
/**
* Handle to the database subclass
*
* @var DatabaseOracle
*/
protected $db;
protected function getCoreUpdateList() {
return [
[ 'disableContentHandlerUseDB' ],
// 1.17
[ 'doNamespaceDefaults' ],
[ 'doFKRenameDeferr' ],
[ 'doFunctions17' ],
[ 'doSchemaUpgrade17' ],
[ 'doInsertPage0' ],
[ 'doRemoveNotNullEmptyDefaults' ],
[ 'addTable', 'user_former_groups', 'patch-user_former_groups.sql' ],
// 1.18
[ 'addIndex', 'user', 'i02', 'patch-user_email_index.sql' ],
[ 'modifyField', 'user_properties', 'up_property', 'patch-up_property.sql' ],
[ 'addTable', 'uploadstash', 'patch-uploadstash.sql' ],
[ 'doRecentchangesFK2Cascade' ],
// 1.19
[ 'addIndex', 'logging', 'i05', 'patch-logging_type_action_index.sql' ],
[ 'addField', 'revision', 'rev_sha1', 'patch-rev_sha1_field.sql' ],
[ 'addField', 'archive', 'ar_sha1', 'patch-ar_sha1_field.sql' ],
[ 'doRemoveNotNullEmptyDefaults2' ],
[ 'addIndex', 'page', 'i03', 'patch-page_redirect_namespace_len.sql' ],
[ 'addField', 'uploadstash', 'us_chunk_inx', 'patch-us_chunk_inx_field.sql' ],
[ 'addField', 'job', 'job_timestamp', 'patch-job_timestamp_field.sql' ],
[ 'addIndex', 'job', 'i02', 'patch-job_timestamp_index.sql' ],
[ 'doPageRestrictionsPKUKFix' ],
// 1.20
[ 'addIndex', 'ipblocks', 'i05', 'patch-ipblocks_i05_index.sql' ],
[ 'addIndex', 'revision', 'i05', 'patch-revision_i05_index.sql' ],
[ 'dropField', 'category', 'cat_hidden', 'patch-cat_hidden.sql' ],
// 1.21
[ 'addField', 'revision', 'rev_content_format',
'patch-revision-rev_content_format.sql' ],
[ 'addField', 'revision', 'rev_content_model',
'patch-revision-rev_content_model.sql' ],
[ 'addField', 'archive', 'ar_content_format', 'patch-archive-ar_content_format.sql' ],
[ 'addField', 'archive', 'ar_content_model', 'patch-archive-ar_content_model.sql' ],
[ 'addField', 'archive', 'ar_id', 'patch-archive-ar_id.sql' ],
[ 'addField', 'externallinks', 'el_id', 'patch-externallinks-el_id.sql' ],
[ 'addField', 'page', 'page_content_model', 'patch-page-page_content_model.sql' ],
[ 'enableContentHandlerUseDB' ],
[ 'dropField', 'site_stats', 'ss_admins', 'patch-ss_admins.sql' ],
[ 'dropField', 'recentchanges', 'rc_moved_to_title', 'patch-rc_moved.sql' ],
[ 'addTable', 'sites', 'patch-sites.sql' ],
[ 'addField', 'filearchive', 'fa_sha1', 'patch-fa_sha1.sql' ],
[ 'addField', 'job', 'job_token', 'patch-job_token.sql' ],
[ 'addField', 'job', 'job_attempts', 'patch-job_attempts.sql' ],
[ 'addField', 'uploadstash', 'us_props', 'patch-uploadstash-us_props.sql' ],
[ 'modifyField', 'user_groups', 'ug_group', 'patch-ug_group-length-increase-255.sql' ],
[ 'modifyField', 'user_former_groups', 'ufg_group',
'patch-ufg_group-length-increase-255.sql' ],
// 1.23
[ 'addIndex', 'logging', 'i06', 'patch-logging_user_text_type_time_index.sql' ],
[ 'addIndex', 'logging', 'i07', 'patch-logging_user_text_time_index.sql' ],
[ 'addField', 'user', 'user_password_expires', 'patch-user_password_expire.sql' ],
[ 'addField', 'page', 'page_links_updated', 'patch-page_links_updated.sql' ],
[ 'addField', 'recentchanges', 'rc_source', 'patch-rc_source.sql' ],
// 1.24
[ 'addField', 'page', 'page_lang', 'patch-page-page_lang.sql' ],
// 1.25
[ 'dropTable', 'hitcounter' ],
[ 'dropField', 'site_stats', 'ss_total_views', 'patch-drop-ss_total_views.sql' ],
[ 'dropField', 'page', 'page_counter', 'patch-drop-page_counter.sql' ],
// 1.27
[ 'dropTable', 'msg_resource_links' ],
[ 'dropTable', 'msg_resource' ],
[ 'addField', 'watchlist', 'wl_id', 'patch-watchlist-wl_id.sql' ],
// 1.28
[ 'addIndex', 'recentchanges', 'rc_name_type_patrolled_timestamp',
'patch-add-rc_name_type_patrolled_timestamp_index.sql' ],
[ 'addField', 'change_tag', 'ct_id', 'patch-change_tag-ct_id.sql' ],
// 1.29
[ 'addField', 'externallinks', 'el_index_60', 'patch-externallinks-el_index_60.sql' ],
[ 'addField', 'user_groups', 'ug_expiry', 'patch-user_groups-ug_expiry.sql' ],
// 1.30
[ 'doAutoIncrementTriggers' ],
[ 'addIndex', 'site_stats', 'PRIMARY', 'patch-site_stats-pk.sql' ],
// Should have been in 1.30
[ 'addTable', 'comment', 'patch-comment-table.sql' ],
// This field was added in 1.31, but is put here so it can be used by 'migrateComments'
[ 'addField', 'image', 'img_description_id', 'patch-image-img_description_id.sql' ],
// Should have been in 1.30
[ 'migrateComments' ],
// 1.31
[ 'addTable', 'slots', 'patch-slots.sql' ],
[ 'addField', 'slots', 'slot_origin', 'patch-slot-origin.sql' ],
[ 'addTable', 'content', 'patch-content.sql' ],
[ 'addTable', 'slot_roles', 'patch-slot_roles.sql' ],
[ 'addTable', 'content_models', 'patch-content_models.sql' ],
[ 'migrateArchiveText' ],
[ 'addTable', 'actor', 'patch-actor-table.sql' ],
[ 'migrateActors' ],
[ 'modifyTable', 'site_stats', 'patch-site_stats-modify.sql' ],
[ 'populateArchiveRevId' ],
[ 'addIndex', 'recentchanges', 'rc_namespace_title_timestamp',
'patch-recentchanges-nttindex.sql' ],
// 1.32
[ 'addTable', 'change_tag_def', 'patch-change_tag_def.sql' ],
[ 'populateExternallinksIndex60' ],
[ 'runMaintenance', DeduplicateArchiveRevId::class, 'maintenance/deduplicateArchiveRevId.php' ],
[ 'addField', 'change_tag', 'ct_tag_id', 'patch-change_tag-tag_id.sql' ],
[ 'addIndex', 'archive', 'ar_revid_uniq', 'patch-archive-ar_rev_id-unique.sql' ],
[ 'populateContentTables' ],
[ 'addIndex', 'recentchanges', 'rc_this_oldid', 'patch-recentchanges-rc_this_oldid-index.sql' ],
[ 'dropTable', 'transcache' ],
[ 'runMaintenance', PopulateChangeTagDef::class, 'maintenance/populateChangeTagDef.php' ],
[ 'addIndex', 'change_tag', 'change_tag_i03',
'patch-change_tag-change_tag_rc_tag_id.sql' ],
[ 'addField', 'ipblocks', 'ipb_sitewide', 'patch-ipb_sitewide.sql' ],
[ 'addTable', 'ipblocks_restrictions', 'patch-ipblocks_restrictions-table.sql' ],
[ 'migrateImageCommentTemp' ],
// 1.33
[ 'dropField', 'change_tag', 'ct_tag', 'patch-drop-ct_tag.sql' ],
[ 'dropTable', 'valid_tag' ],
[ 'dropTable', 'tag_summary' ],
[ 'dropField', 'protected_titles', 'pt_reason', 'patch-drop-comment-fields.sql' ],
// KEEP THIS AT THE BOTTOM!!
[ 'doRebuildDuplicateFunction' ],
];
}
/**
* MySQL uses datatype defaults for NULL inserted into NOT NULL fields
* In namespace case that results into insert of 0 which is default namespace
* Oracle inserts NULL, so namespace fields should have a default value
*/
protected function doNamespaceDefaults() {
$meta = $this->db->fieldInfo( 'page', 'page_namespace' );
if ( $meta->defaultValue() != null ) {
return;
}
$this->applyPatch(
'patch_namespace_defaults.sql',
false,
'Altering namespace fields with default value'
);
}
/**
* Uniform FK names + deferrable state
*/
protected function doFKRenameDeferr() {
$meta = $this->db->query( '
SELECT COUNT(*) cnt
FROM user_constraints
WHERE constraint_type = \'R\' AND deferrable = \'DEFERRABLE\''
);
$row = $meta->fetchRow();
if ( $row && $row['cnt'] > 0 ) {
return;
}
$this->applyPatch( 'patch_fk_rename_deferred.sql', false, "Altering foreign keys ... " );
}
/**
* Recreate functions to 17 schema layout
*/
protected function doFunctions17() {
$this->applyPatch( 'patch_create_17_functions.sql', false, "Recreating functions" );
}
/**
* Schema upgrade 16->17
* there are no incremental patches prior to this
*/
protected function doSchemaUpgrade17() {
// check if iwlinks table exists which was added in 1.17
if ( $this->db->tableExists( 'iwlinks' ) ) {
return;
}
$this->applyPatch( 'patch_16_17_schema_changes.sql', false, "Updating schema to 17" );
}
/**
* Insert page (page_id = 0) to prevent FK constraint violation
*/
protected function doInsertPage0() {
$this->output( "Inserting page 0 if missing ... " );
$row = [
'page_id' => 0,
'page_namespace' => 0,
'page_title' => ' ',
'page_is_redirect' => 0,
'page_is_new' => 0,
'page_random' => 0,
'page_touched' => $this->db->timestamp(),
'page_latest' => 0,
'page_len' => 0
];
$this->db->insert( 'page', $row, 'OracleUpdater:doInserPage0', [ 'IGNORE' ] );
$this->output( "ok\n" );
}
/**
* Remove DEFAULT '' NOT NULL constraints from fields as '' is internally
* converted to NULL in Oracle
*/
protected function doRemoveNotNullEmptyDefaults() {
$meta = $this->db->fieldInfo( 'categorylinks', 'cl_sortkey_prefix' );
if ( $meta->isNullable() ) {
return;
}
$this->applyPatch(
'patch_remove_not_null_empty_defs.sql',
false,
'Removing not null empty constraints'
);
}
protected function doRemoveNotNullEmptyDefaults2() {
$meta = $this->db->fieldInfo( 'ipblocks', 'ipb_by_text' );
if ( $meta->isNullable() ) {
return;
}
$this->applyPatch(
'patch_remove_not_null_empty_defs2.sql',
false,
'Removing not null empty constraints'
);
}
/**
* Removed forcing of invalid state on recentchanges_fk2.
* cascading taken in account in the deleting function
*/
protected function doRecentchangesFK2Cascade() {
$meta = $this->db->query( 'SELECT 1 FROM all_constraints WHERE owner = \'' .
strtoupper( $this->db->getDBname() ) .
'\' AND constraint_name = \'' .
$this->db->tablePrefix() .
'RECENTCHANGES_FK2\' AND delete_rule = \'CASCADE\''
);
$row = $meta->fetchRow();
if ( $row ) {
return;
}
$this->applyPatch( 'patch_recentchanges_fk2_cascade.sql', false, "Altering RECENTCHANGES_FK2" );
}
/**
* Fixed wrong PK, UK definition
*/
protected function doPageRestrictionsPKUKFix() {
$this->output( "Altering PAGE_RESTRICTIONS keys ... " );
$meta = $this->db->query( 'SELECT column_name FROM all_cons_columns WHERE owner = \'' .
strtoupper( $this->db->getDBname() ) .
'\' AND constraint_name = \'' .
$this->db->tablePrefix() .
'PAGE_RESTRICTIONS_PK\' AND rownum = 1'
);
$row = $meta->fetchRow();
if ( $row['column_name'] == 'PR_ID' ) {
$this->output( "seems to be up to date.\n" );
return;
}
$this->applyPatch( 'patch-page_restrictions_pkuk_fix.sql', false );
$this->output( "ok\n" );
}
/**
* Add auto-increment triggers
*/
protected function doAutoIncrementTriggers() {
$this->output( "Adding auto-increment triggers ... " );
$meta = $this->db->query( 'SELECT trigger_name FROM user_triggers WHERE table_owner = \'' .
strtoupper( $this->db->getDBname() ) .
'\' AND trigger_name = \'' .
$this->db->tablePrefix() .
'PAGE_DEFAULT_PAGE_ID\''
);
$row = $meta->fetchRow();
if ( $row['column_name'] ) {
$this->output( "seems to be up to date.\n" );
return;
}
$this->applyPatch( 'patch-auto_increment_triggers.sql', false );
$this->output( "ok\n" );
}
/**
* rebuilding of the function that duplicates tables for tests
*/
protected function doRebuildDuplicateFunction() {
$this->applyPatch( 'patch_rebuild_dupfunc.sql', false, "Rebuilding duplicate function" );
}
/**
* Overload: after this action field info table has to be rebuilt
*
* @param array $what
*/
public function doUpdates( array $what = [ 'core', 'extensions', 'purge', 'stats' ] ) {
parent::doUpdates( $what );
$this->db->query( 'BEGIN fill_wiki_info; END;' );
}
/**
* Overload: because of the DDL_MODE tablename escaping is a bit dodgy
*/
public function purgeCache() {
# We can't guarantee that the user will be able to use TRUNCATE,
# but we know that DELETE is available to us
$this->output( "Purging caches..." );
$this->db->delete( '/*Q*/' . $this->db->tableName( 'objectcache' ), '*', __METHOD__ );
$this->output( "done.\n" );
}
}

View file

@ -453,7 +453,6 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
// we auto-detect the first available driver. For types without built-in support,
// an class named "Database<Type>" us used, eg. DatabaseFoo for type 'foo'.
static $builtinTypes = [
'mssql' => DatabaseMssql::class,
'mysql' => [ 'mysqli' => DatabaseMysqli::class ],
'sqlite' => DatabaseSqlite::class,
'postgres' => DatabasePostgres::class,

File diff suppressed because it is too large Load diff

View file

@ -1,53 +0,0 @@
--
-- patch-actor-table.sql
--
-- T167246. Add an `actor` table and various columns (and temporary tables) to reference it.
CREATE TABLE /*_*/actor (
actor_id bigint NOT NULL CONSTRAINT PK_actor PRIMARY KEY IDENTITY(0,1),
actor_user int,
actor_name nvarchar(255) NOT NULL
);
CREATE UNIQUE INDEX /*i*/actor_user ON /*_*/actor (actor_user);
CREATE UNIQUE INDEX /*i*/actor_name ON /*_*/actor (actor_name);
-- Dummy
INSERT INTO /*_*/actor (actor_name) VALUES ('##Anonymous##');
CREATE TABLE /*_*/revision_actor_temp (
revactor_rev int NOT NULL CONSTRAINT FK_revactor_rev FOREIGN KEY REFERENCES /*_*/revision(rev_id) ON DELETE CASCADE,
revactor_actor bigint NOT NULL,
revactor_timestamp varchar(14) NOT NULL CONSTRAINT DF_revactor_timestamp DEFAULT '',
revactor_page int NOT NULL,
CONSTRAINT PK_revision_actor_temp PRIMARY KEY (revactor_rev, revactor_actor)
);
CREATE UNIQUE INDEX /*i*/revactor_rev ON /*_*/revision_actor_temp (revactor_rev);
CREATE INDEX /*i*/actor_timestamp ON /*_*/revision_actor_temp (revactor_actor,revactor_timestamp);
CREATE INDEX /*i*/page_actor_timestamp ON /*_*/revision_actor_temp (revactor_page,revactor_actor,revactor_timestamp);
ALTER TABLE /*_*/archive ADD CONSTRAINT DF_ar_user_text DEFAULT '' FOR ar_user_text;
ALTER TABLE /*_*/archive ADD ar_actor bigint NOT NULL CONSTRAINT DF_ar_actor DEFAULT 0;
CREATE INDEX /*i*/ar_actor_timestamp ON /*_*/archive (ar_actor,ar_timestamp);
ALTER TABLE /*_*/ipblocks ADD ipb_by_actor bigint NOT NULL CONSTRAINT DF_ipb_by_actor DEFAULT 0;
ALTER TABLE /*_*/image ADD CONSTRAINT DF_img_user_text DEFAULT '' FOR img_user_text;
ALTER TABLE /*_*/image ADD img_actor bigint NOT NULL CONSTRAINT DF_img_actor DEFAULT 0;
CREATE INDEX /*i*/img_actor_timestamp ON /*_*/image (img_actor, img_timestamp);
ALTER TABLE /*_*/oldimage ADD CONSTRAINT DF_oi_user_text DEFAULT '' FOR oi_user_text;
ALTER TABLE /*_*/oldimage ADD oi_actor bigint NOT NULL CONSTRAINT DF_oi_actor DEFAULT 0;
CREATE INDEX /*i*/oi_actor_timestamp ON /*_*/oldimage (oi_actor,oi_timestamp);
ALTER TABLE /*_*/filearchive ADD CONSTRAINT DF_fa_user_text DEFAULT '' FOR fa_user_text;
ALTER TABLE /*_*/filearchive ADD fa_actor bigint NOT NULL CONSTRAINT DF_fa_actor DEFAULT 0;
CREATE INDEX /*i*/fa_actor_timestamp ON /*_*/filearchive (fa_actor,fa_timestamp);
ALTER TABLE /*_*/recentchanges ADD CONSTRAINT DF_rc_user_text DEFAULT '' FOR rc_user_text;
ALTER TABLE /*_*/recentchanges ADD rc_actor bigint NOT NULL CONSTRAINT DF_rc_actor DEFAULT 0;
CREATE INDEX /*i*/rc_ns_actor ON /*_*/recentchanges (rc_namespace, rc_actor);
CREATE INDEX /*i*/rc_actor ON /*_*/recentchanges (rc_actor, rc_timestamp);
ALTER TABLE /*_*/logging ADD log_actor bigint NOT NULL CONSTRAINT DF_log_actor DEFAULT 0;
CREATE INDEX /*i*/actor_time ON /*_*/logging (log_actor, log_timestamp);
CREATE INDEX /*i*/log_actor_type_time ON /*_*/logging (log_actor, log_type, log_timestamp);

View file

@ -1,27 +0,0 @@
ALTER TABLE /*$wgDBprefix*/image
DROP CONSTRAINT img_media_type_ckc;
ALTER TABLE /*$wgDBprefix*/image
ADD CONSTRAINT img_media_type_ckc
CHECK (img_media_type IN("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE", "3D"));
ALTER TABLE /*$wgDBprefix*/oldimage
DROP CONSTRAINT oi_media_type_ckc;
ALTER TABLE /*$wgDBprefix*/oldimage
ADD CONSTRAINT oi_media_type_ckc
CHECK (oi_media_type IN("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE", "3D"));
ALTER TABLE /*$wgDBprefix*/filearchive
DROP CONSTRAINT fa_media_type_ckc;
ALTER TABLE /*$wgDBprefix*/filearchive
ADD CONSTRAINT fa_media_type_ckc
CHECK (fa_media_type IN("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE", "3D"));
ALTER TABLE /*$wgDBprefix*/uploadstash
DROP CONSTRAINT us_media_type_ckc;
ALTER TABLE /*$wgDBprefix*/uploadstash
ADD CONSTRAINT us_media_type_ckc
CHECK (us_media_type IN("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE", "3D"));

View file

@ -1,2 +0,0 @@
-- @since 1.27
CREATE INDEX /*i*/cl_collation_ext ON /*_*/categorylinks (cl_collation, cl_to, cl_type, cl_from);

View file

@ -1 +0,0 @@
DROP INDEX /*i*/oi_name_archive_name ON /*_*/oldimage;

View file

@ -1 +0,0 @@
ALTER TABLE /*_*/archive ALTER COLUMN ar_rev_id INT NOT NULL;

View file

@ -1,59 +0,0 @@
DECLARE @base nvarchar(max),
@SQL nvarchar(max),
@id sysname;--
SET @base = 'ALTER TABLE /*_*/archive DROP CONSTRAINT ';--
SELECT @id = fk.name
FROM sys.foreign_keys fk
JOIN sys.foreign_key_columns fkc
ON fkc.constraint_object_id = fk.object_id
JOIN sys.columns c
ON c.column_id = fkc.parent_column_id
AND c.object_id = fkc.parent_object_id
WHERE
fk.parent_object_id = OBJECT_ID('/*_*/archive')
AND fk.referenced_object_id = OBJECT_ID('/*_*/revision')
AND c.name = 'ar_parent_id';--
SET @SQL = @base + @id;--
EXEC sp_executesql @SQL;--
-- while we're at it, let's fix up the other foreign key constraints on archive
-- as future patches touch constraints on other tables, they'll take the time to update constraint names there as well
SELECT @id = fk.name
FROM sys.foreign_keys fk
JOIN sys.foreign_key_columns fkc
ON fkc.constraint_object_id = fk.object_id
JOIN sys.columns c
ON c.column_id = fkc.parent_column_id
AND c.object_id = fkc.parent_object_id
WHERE
fk.parent_object_id = OBJECT_ID('/*_*/archive')
AND fk.referenced_object_id = OBJECT_ID('/*_*/mwuser')
AND c.name = 'ar_user';--
SET @SQL = @base + @id;--
EXEC sp_executesql @SQL;--
ALTER TABLE /*_*/archive ADD CONSTRAINT ar_user__user_id__fk FOREIGN KEY (ar_user) REFERENCES /*_*/mwuser(user_id);--
SELECT @id = fk.name
FROM sys.foreign_keys fk
JOIN sys.foreign_key_columns fkc
ON fkc.constraint_object_id = fk.object_id
JOIN sys.columns c
ON c.column_id = fkc.parent_column_id
AND c.object_id = fkc.parent_object_id
WHERE
fk.parent_object_id = OBJECT_ID('/*_*/archive')
AND fk.referenced_object_id = OBJECT_ID('/*_*/text')
AND c.name = 'ar_text_id';--
SET @SQL = @base + @id;--
EXEC sp_executesql @SQL;--
ALTER TABLE /*_*/archive ADD CONSTRAINT ar_text_id__old_id__fk FOREIGN KEY (ar_text_id) REFERENCES /*_*/text(old_id) ON DELETE CASCADE;

View file

@ -1,13 +0,0 @@
--
-- This table contains a user's bot passwords: passwords that allow access to
-- the account via the API with limited rights.
--
CREATE TABLE /*_*/bot_passwords (
bp_user int NOT NULL REFERENCES /*_*/mwuser(user_id) ON DELETE CASCADE,
bp_app_id nvarchar(32) NOT NULL,
bp_password nvarchar(255) NOT NULL,
bp_token nvarchar(255) NOT NULL,
bp_restrictions nvarchar(max) NOT NULL,
bp_grants nvarchar(max) NOT NULL,
PRIMARY KEY (bp_user, bp_app_id)
);

View file

@ -1,20 +0,0 @@
DECLARE @baseSQL nvarchar(max),
@SQL nvarchar(max),
@id sysname;--
SET @baseSQL = 'ALTER TABLE /*_*/categorylinks DROP CONSTRAINT ';--
SELECT @id = cc.name
FROM sys.check_constraints cc
JOIN sys.columns c
ON c.object_id = cc.parent_object_id
AND c.column_id = cc.parent_column_id
WHERE
cc.parent_object_id = OBJECT_ID('/*_*/categorylinks')
AND c.name = 'cl_type';--
SET @SQL = @baseSQL + @id;--
EXEC sp_executesql @SQL;--
ALTER TABLE /*_*/categorylinks ADD CONSTRAINT cl_type_ckc CHECK (cl_type IN('page', 'subcat', 'file'));

View file

@ -1,4 +0,0 @@
-- Primary key in change_tag table
ALTER TABLE /*_*/change_tag ADD ct_id INT IDENTITY;
ALTER TABLE /*_*/change_tag ADD CONSTRAINT pk_change_tag PRIMARY KEY(ct_id)

View file

@ -1,7 +0,0 @@
--
-- Add ctd_tag_id to change_tag table to normalize it
--
ALTER TABLE /*_*/change_tag
ADD COLUMN ct_tag_id int NULL CONSTRAINT ctd_tag_id__fk FOREIGN KEY REFERENCES /*_*/change_tag_def(ctd_id);
CREATE INDEX /*i*/change_tag_tag_id_id ON /*_*/change_tag (ct_tag_id,ct_rc_id,ct_rev_id,ct_log_id);

View file

@ -1,16 +0,0 @@
-- Table defining tag names for IDs. Also stores hit counts to avoid expensive queries on change_tag
CREATE TABLE /*_*/change_tag_def (
-- Numerical ID of the tag (ct_tag_id refers to this)
ctd_id int NOT NULL CONSTRAINT PK_change_tag_def PRIMARY KEY IDENTITY,
-- Symbolic name of the tag (what would previously be put in ct_tag)
ctd_name nvarchar(255) NOT NULL,
-- Whether this tag was defined manually by a privileged user using Special:Tags
ctd_user_defined tinyint NOT NULL CONSTRAINT DF_ctd_user_defined DEFAULT 0,
-- Number of times this tag was used
ctd_count int NOT NULL CONSTRAINT DF_ctd_count DEFAULT 0
) /*$wgDBTableOptions*/;
CREATE UNIQUE INDEX /*i*/ctd_name ON /*_*/change_tag_def (ctd_name);
CREATE INDEX /*i*/ctd_count ON /*_*/change_tag_def (ctd_count);
CREATE INDEX /*i*/ctd_user_defined ON /*_*/change_tag_def (ctd_user_defined);

View file

@ -1,57 +0,0 @@
--
-- patch-comment-table.sql
--
-- T166732. Add a `comment` table and various columns (and temporary tables) to reference it.
CREATE TABLE /*_*/comment (
comment_id bigint 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 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(img_name) ON DELETE CASCADE,
imgcomment_description_id bigint 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 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 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 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 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 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 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 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 NOT NULL CONSTRAINT DF_pt_reason_id DEFAULT 0 CONSTRAINT FK_pt_reason_id FOREIGN KEY REFERENCES /*_*/comment(comment_id);

View file

@ -1,21 +0,0 @@
--
-- The content table represents content objects. It's primary purpose is to provide the necessary
-- meta-data for loading and interpreting a serialized data blob to create a content object.
--
CREATE TABLE /*_*/content (
-- ID of the content object
content_id bigint NOT NULL CONSTRAINT PK_content PRIMARY KEY IDENTITY,
-- Nominal size of the content object (not necessarily of the serialized blob)
content_size int NOT NULL,
-- Nominal hash of the content object (not necessarily of the serialized blob)
content_sha1 varchar(32) NOT NULL,
-- reference to model_id
content_model smallint NOT NULL CONSTRAINT FK_content_content_models FOREIGN KEY REFERENCES /*_*/content_models(model_id),
-- URL-like address of the content blob
content_address nvarchar(255) NOT NULL
);

View file

@ -1,11 +0,0 @@
--
-- Normalization table for content model names
--
CREATE TABLE /*_*/content_models (
model_id smallint NOT NULL CONSTRAINT PK_content_models PRIMARY KEY IDENTITY,
model_name nvarchar(64) NOT NULL
);
-- Index for looking of the internal ID of for a name
CREATE UNIQUE INDEX /*i*/model_name ON /*_*/content_models (model_name);

View file

@ -1,21 +0,0 @@
DECLARE @sql nvarchar(max),
@id sysname;--
SET @sql = 'ALTER TABLE /*_*/archive DROP CONSTRAINT ';--
SELECT @id = df.name
FROM sys.default_constraints df
JOIN sys.columns c
ON c.object_id = df.parent_object_id
AND c.column_id = df.parent_column_id
WHERE
df.parent_object_id = OBJECT_ID('/*_*/archive')
AND ( c.name = 'ar_text' OR c.name = 'ar_flags' );--
SET @sql = @sql + @id;--
EXEC sp_executesql @sql;--
ALTER TABLE /*_*/archive DROP COLUMN ar_text;
ALTER TABLE /*_*/archive DROP COLUMN ar_flags;
ALTER TABLE /*_*/archive ALTER COLUMN ar_text_id INT NOT NULL CONSTRAINT DF_ar_text_id DEFAULT 0;

View file

@ -1,55 +0,0 @@
--
-- patch-drop-comment-fields.sql
--
-- T166732. Drop old xx_comment fields, and defaults from xx_comment_id fields.
DECLARE @sql nvarchar(max),
@id sysname;
ALTER TABLE /*_*/archive DROP CONSTRAINT DF_ar_comment, COLUMN ar_comment;
ALTER TABLE /*_*/archive DROP CONSTRAINT DF_ar_comment_id;
ALTER TABLE /*_*/ipblocks DROP CONSTRAINT DF_ipb_reason, COLUMN ipb_reason;
ALTER TABLE /*_*/ipblocks DROP CONSTRAINT DF_ipb_reason_id;
ALTER TABLE /*_*/image DROP CONSTRAINT DF_img_description, COLUMN img_description;
ALTER TABLE /*_*/image DROP CONSTRAINT DF_img_description_id;
ALTER TABLE /*_*/oldimage DROP CONSTRAINT DF_oi_description, COLUMN oi_description;
ALTER TABLE /*_*/oldimage DROP CONSTRAINT DF_oi_description_id;
ALTER TABLE /*_*/filearchive DROP CONSTRAINT DF_fa_deleted_reason, COLUMN fa_deleted_reason;
ALTER TABLE /*_*/filearchive DROP CONSTRAINT DF_fa_deleted_reason_id;
ALTER TABLE /*_*/filearchive DROP CONSTRAINT DF_fa_description, COLUMN fa_description;
ALTER TABLE /*_*/filearchive DROP CONSTRAINT DF_fa_description_id;
SET @sql = 'ALTER TABLE /*_*/recentchanges DROP CONSTRAINT ';
SELECT @id = df.name
FROM sys.default_constraints df
JOIN sys.columns c
ON c.object_id = df.parent_object_id
AND c.column_id = df.parent_column_id
WHERE
df.parent_object_id = OBJECT_ID('/*_*/recentchanges')
AND c.name = 'rc_comment';
SET @sql = @sql + @id;
EXEC sp_executesql @sql;
ALTER TABLE /*_*/recentchanges DROP COLUMN rc_comment;
ALTER TABLE /*_*/recentchanges DROP CONSTRAINT DF_rc_comment_id;
SET @sql = 'ALTER TABLE /*_*/logging DROP CONSTRAINT ';
SELECT @id = df.name
FROM sys.default_constraints df
JOIN sys.columns c
ON c.object_id = df.parent_object_id
AND c.column_id = df.parent_column_id
WHERE
df.parent_object_id = OBJECT_ID('/*_*/logging')
AND c.name = 'log_comment';
SET @sql = @sql + @id;
EXEC sp_executesql @sql;
ALTER TABLE /*_*/logging DROP COLUMN log_comment;
ALTER TABLE /*_*/logging DROP CONSTRAINT DF_log_comment_id;
ALTER TABLE /*_*/protected_titles DROP CONSTRAINT DF_pt_reason, COLUMN pt_reason;
ALTER TABLE /*_*/protected_titles DROP CONSTRAINT DF_pt_reason_id;

View file

@ -1,22 +0,0 @@
-- T185355
ALTER TABLE /*_*/change_tag ALTER COLUMN ct_tag INTEGER NOT NULL
DECLARE @sql nvarchar(max),
@id sysname;--
SET @sql = 'ALTER TABLE /*_*/change_tag DROP CONSTRAINT ';--
SELECT @id = df.name
FROM sys.default_constraints df
JOIN sys.columns c
ON c.object_id = df.parent_object_id
AND c.column_id = df.parent_column_id
WHERE
df.parent_object_id = OBJECT_ID('/*_*/change_tag')
AND c.name = 'ct_tag';--
SET @sql = @sql + @id;--
EXEC sp_executesql @sql;--
ALTER TABLE /*_*/change_tag DROP COLUMN ct_tag;

View file

@ -1,19 +0,0 @@
DECLARE @sql nvarchar(max),
@id sysname;--
SET @sql = 'ALTER TABLE /*_*/page DROP CONSTRAINT ';--
SELECT @id = df.name
FROM sys.default_constraints df
JOIN sys.columns c
ON c.object_id = df.parent_object_id
AND c.column_id = df.parent_column_id
WHERE
df.parent_object_id = OBJECT_ID('/*_*/page')
AND c.name = 'page_counter';--
SET @sql = @sql + @id;--
EXEC sp_executesql @sql;--
ALTER TABLE /*_*/page DROP COLUMN page_counter;

View file

@ -1,19 +0,0 @@
DECLARE @sql nvarchar(max),
@id sysname;--
SET @sql = 'ALTER TABLE /*_*/recentchanges DROP CONSTRAINT ';--
SELECT @id = df.name
FROM sys.default_constraints df
JOIN sys.columns c
ON c.object_id = df.parent_object_id
AND c.column_id = df.parent_column_id
WHERE
df.parent_object_id = OBJECT_ID('/*_*/recentchanges')
AND c.name = 'rc_cur_time';--
SET @sql = @sql + @id;--
EXEC sp_executesql @sql;--
ALTER TABLE /*_*/recentchanges DROP COLUMN rc_cur_time;

View file

@ -1,19 +0,0 @@
DECLARE @sql nvarchar(max),
@id sysname;--
SET @sql = 'ALTER TABLE /*_*/site_stats DROP CONSTRAINT ';--
SELECT @id = df.name
FROM sys.default_constraints df
JOIN sys.columns c
ON c.object_id = df.parent_object_id
AND c.column_id = df.parent_column_id
WHERE
df.parent_object_id = OBJECT_ID('/*_*/site_stats')
AND c.name = 'ss_total_views';--
SET @sql = @sql + @id;--
EXEC sp_executesql @sql;--
ALTER TABLE /*_*/site_stats DROP COLUMN ss_total_views;

View file

@ -1,19 +0,0 @@
DECLARE @sql nvarchar(max),
@id sysname;--
SET @sql = 'ALTER TABLE /*_*/mwuser DROP CONSTRAINT ';--
SELECT @id = df.name
FROM sys.default_constraints df
JOIN sys.columns c
ON c.object_id = df.parent_object_id
AND c.column_id = df.parent_column_id
WHERE
df.parent_object_id = OBJECT_ID('/*_*/mwuser')
AND c.name = 'user_options';--
SET @sql = @sql + @id;--
EXEC sp_executesql @sql;--
ALTER TABLE /*_*/mwuser DROP COLUMN user_options;

View file

@ -1,13 +0,0 @@
DECLARE @sql nvarchar(max)
SET @sql=''
SELECT @sql= @sql + 'ALTER TABLE /*_*/externallinks DROP CONSTRAINT ' + df.name + '; '
FROM sys.default_constraints df
JOIN sys.columns c
ON c.object_id = df.parent_object_id
AND c.column_id = df.parent_column_id
WHERE
df.parent_object_id = OBJECT_ID('/*_*/externallinks')
AND c.name = 'el_index_60';--
EXEC sp_executesql @sql;

View file

@ -1,4 +0,0 @@
ALTER TABLE /*_*/filearchive
DROP CONSTRAINT fa_major_mime_ckc;
ALTER TABLE /*_*/filearchive
WITH NOCHECK ADD CONSTRAINT fa_major_mime_ckc CHECK (fa_major_mime IN('unknown', 'application', 'audio', 'image', 'text', 'video', 'message', 'model', 'multipart', 'chemical'));

View file

@ -1,34 +0,0 @@
DECLARE @baseSQL nvarchar(max),
@SQL nvarchar(max),
@id sysname;--
SET @baseSQL = 'ALTER TABLE /*_*/filearchive DROP CONSTRAINT ';--
SELECT @id = cc.name
FROM sys.check_constraints cc
JOIN sys.columns c
ON c.object_id = cc.parent_object_id
AND c.column_id = cc.parent_column_id
WHERE
cc.parent_object_id = OBJECT_ID('/*_*/filearchive')
AND c.name = 'fa_major_mime';--
SET @SQL = @baseSQL + @id;--
EXEC sp_executesql @SQL;--
SELECT @id = cc.name
FROM sys.check_constraints cc
JOIN sys.columns c
ON c.object_id = cc.parent_object_id
AND c.column_id = cc.parent_column_id
WHERE
cc.parent_object_id = OBJECT_ID('/*_*/filearchive')
AND c.name = 'fa_media_type';--
SET @SQL = @baseSQL + @id;--
EXEC sp_executesql @SQL;--
ALTER TABLE /*_*/filearchive ADD CONSTRAINT fa_major_mime_ckc check (fa_major_mime IN('unknown', 'application', 'audio', 'image', 'text', 'video', 'message', 'model', 'multipart'));--
ALTER TABLE /*_*/filearchive ADD CONSTRAINT fa_media_type_ckc check (fa_media_type in('UNKNOWN', 'BITMAP', 'DRAWING', 'AUDIO', 'VIDEO', 'MULTIMEDIA', 'OFFICE', 'TEXT', 'EXECUTABLE', 'ARCHIVE'));

View file

@ -1,120 +0,0 @@
-- MediaWiki looks for lines ending with semicolons and sends them as separate queries
-- However here we *really* need this all to be sent as a single batch. As such, DO NOT
-- remove the -- from the end of each statement.
DECLARE @temp table (
fa_id int,
fa_name nvarchar(255),
fa_archive_name nvarchar(255),
fa_storage_group nvarchar(16),
fa_storage_key nvarchar(64),
fa_deleted_user int,
fa_deleted_timestamp varchar(14),
fa_deleted_reason nvarchar(max),
fa_size int,
fa_width int,
fa_height int,
fa_metadata nvarchar(max),
fa_bits int,
fa_media_type varchar(16),
fa_major_mime varchar(16),
fa_minor_mime nvarchar(100),
fa_description nvarchar(255),
fa_user int,
fa_user_text nvarchar(255),
fa_timestamp varchar(14),
fa_deleted tinyint,
fa_sha1 nvarchar(32)
);--
INSERT INTO @temp
SELECT * FROM /*_*/filearchive;--
DROP TABLE /*_*/filearchive;--
CREATE TABLE /*_*/filearchive (
fa_id int NOT NULL PRIMARY KEY IDENTITY,
fa_name nvarchar(255) NOT NULL default '',
fa_archive_name nvarchar(255) default '',
fa_storage_group nvarchar(16),
fa_storage_key nvarchar(64) default '',
fa_deleted_user int,
fa_deleted_timestamp varchar(14) default '',
fa_deleted_reason nvarchar(max),
fa_size int default 0,
fa_width int default 0,
fa_height int default 0,
fa_metadata varbinary(max),
fa_bits int default 0,
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_user int default 0 REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
fa_user_text nvarchar(255),
fa_timestamp varchar(14) default '',
fa_deleted tinyint NOT NULL default 0,
fa_sha1 nvarchar(32) NOT NULL default '',
CONSTRAINT fa_major_mime_ckc check (fa_major_mime in('unknown', 'application', 'audio', 'image', 'text', 'video', 'message', 'model', 'multipart', 'chemical')),
CONSTRAINT fa_media_type_ckc check (fa_media_type in('UNKNOWN', 'BITMAP', 'DRAWING', 'AUDIO', 'VIDEO', 'MULTIMEDIA', 'OFFICE', 'TEXT', 'EXECUTABLE', 'ARCHIVE'))
);--
CREATE INDEX /*i*/fa_name ON /*_*/filearchive (fa_name, fa_timestamp);--
CREATE INDEX /*i*/fa_storage_group ON /*_*/filearchive (fa_storage_group, fa_storage_key);--
CREATE INDEX /*i*/fa_deleted_timestamp ON /*_*/filearchive (fa_deleted_timestamp);--
CREATE INDEX /*i*/fa_user_timestamp ON /*_*/filearchive (fa_user_text,fa_timestamp);--
CREATE INDEX /*i*/fa_sha1 ON /*_*/filearchive (fa_sha1);--
SET IDENTITY_INSERT /*_*/filearchive ON;--
INSERT INTO /*_*/filearchive
(
fa_id,
fa_name,
fa_archive_name,
fa_storage_group,
fa_storage_key,
fa_deleted_user,
fa_deleted_timestamp,
fa_deleted_reason,
fa_size,
fa_width,
fa_height,
fa_metadata,
fa_bits,
fa_media_type,
fa_major_mime,
fa_minor_mime,
fa_description,
fa_user,
fa_user_text,
fa_timestamp,
fa_deleted,
fa_sha1
)
SELECT
fa_id,
fa_name,
fa_archive_name,
fa_storage_group,
fa_storage_key,
fa_deleted_user,
fa_deleted_timestamp,
fa_deleted_reason,
fa_size,
fa_width,
fa_height,
CONVERT(varbinary(max), fa_metadata, 0),
fa_bits,
fa_media_type,
fa_major_mime,
fa_minor_mime,
fa_description,
fa_user,
fa_user_text,
fa_timestamp,
fa_deleted,
fa_sha1
FROM @temp t;--
SET IDENTITY_INSERT /*_*/filearchive OFF;

View file

@ -1,4 +0,0 @@
ALTER TABLE /*_*/imagelinks
ADD il_from_namespace int NOT NULL default 0;
CREATE INDEX /*i*/il_backlinks_namespace ON /*_*/imagelinks (il_from_namespace,il_to,il_from);

View file

@ -1,34 +0,0 @@
DECLARE @baseSQL nvarchar(max),
@SQL nvarchar(max),
@id sysname;--
SET @baseSQL = 'ALTER TABLE /*_*/image DROP CONSTRAINT ';--
SELECT @id = cc.name
FROM sys.check_constraints cc
JOIN sys.columns c
ON c.object_id = cc.parent_object_id
AND c.column_id = cc.parent_column_id
WHERE
cc.parent_object_id = OBJECT_ID('/*_*/image')
AND c.name = 'img_major_mime';--
SET @SQL = @baseSQL + @id;--
EXEC sp_executesql @SQL;--
SELECT @id = cc.name
FROM sys.check_constraints cc
JOIN sys.columns c
ON c.object_id = cc.parent_object_id
AND c.column_id = cc.parent_column_id
WHERE
cc.parent_object_id = OBJECT_ID('/*_*/image')
AND c.name = 'img_media_type';--
SET @SQL = @baseSQL + @id;--
EXEC sp_executesql @SQL;--
ALTER TABLE /*_*/image ADD CONSTRAINT img_major_mime_ckc check (img_major_mime IN('unknown', 'application', 'audio', 'image', 'text', 'video', 'message', 'model', 'multipart'));--
ALTER TABLE /*_*/image ADD CONSTRAINT img_media_type_ckc check (img_media_type in('UNKNOWN', 'BITMAP', 'DRAWING', 'AUDIO', 'VIDEO', 'MULTIMEDIA', 'OFFICE', 'TEXT', 'EXECUTABLE', 'ARCHIVE'));

View file

@ -1,6 +0,0 @@
--
-- patch-image-img_description_id.sql
--
-- T188132. Add `img_description_id` to the `image` table.
ALTER TABLE /*_*/image ADD img_description_id bigint NOT NULL CONSTRAINT DF_img_description_id DEFAULT 0 CONSTRAINT FK_img_description_id FOREIGN KEY REFERENCES /*_*/comment(comment_id);

View file

@ -1,84 +0,0 @@
-- MediaWiki looks for lines ending with semicolons and sends them as separate queries
-- However here we *really* need this all to be sent as a single batch. As such, DO NOT
-- remove the -- from the end of each statement.
DECLARE @temp table (
img_name varbinary(255),
img_size int,
img_width int,
img_height int,
img_metadata varbinary(max),
img_bits int,
img_media_type varchar(16),
img_major_mime varchar(16),
img_minor_mime nvarchar(100),
img_description nvarchar(255),
img_user int,
img_user_text nvarchar(255),
img_timestamp nvarchar(14),
img_sha1 nvarchar(32)
);--
INSERT INTO @temp
SELECT * FROM /*_*/image;--
DROP TABLE /*_*/image;--
CREATE TABLE /*_*/image (
img_name nvarchar(255) NOT NULL default '' PRIMARY KEY,
img_size int NOT NULL default 0,
img_width int NOT NULL default 0,
img_height int NOT NULL default 0,
img_metadata varbinary(max) NOT NULL,
img_bits int NOT NULL default 0,
img_media_type varchar(16) default null,
img_major_mime varchar(16) not null default 'unknown',
img_minor_mime nvarchar(100) NOT NULL default 'unknown',
img_description nvarchar(255) NOT NULL,
img_user int REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
img_user_text nvarchar(255) NOT NULL,
img_timestamp nvarchar(14) NOT NULL default '',
img_sha1 nvarchar(32) NOT NULL default '',
CONSTRAINT img_major_mime_ckc check (img_major_mime IN('unknown', 'application', 'audio', 'image', 'text', 'video', 'message', 'model', 'multipart', 'chemical')),
CONSTRAINT img_media_type_ckc check (img_media_type in('UNKNOWN', 'BITMAP', 'DRAWING', 'AUDIO', 'VIDEO', 'MULTIMEDIA', 'OFFICE', 'TEXT', 'EXECUTABLE', 'ARCHIVE'))
);--
CREATE INDEX /*i*/img_usertext_timestamp ON /*_*/image (img_user_text,img_timestamp);--
CREATE INDEX /*i*/img_size ON /*_*/image (img_size);--
CREATE INDEX /*i*/img_timestamp ON /*_*/image (img_timestamp);--
CREATE INDEX /*i*/img_sha1 ON /*_*/image (img_sha1);--
CREATE INDEX /*i*/img_media_mime ON /*_*/image (img_media_type,img_major_mime,img_minor_mime);--
INSERT INTO /*_*/image
(
img_name,
img_size,
img_width,
img_height,
img_metadata,
img_bits,
img_media_type,
img_major_mime,
img_minor_mime,
img_description,
img_user,
img_user_text,
img_timestamp,
img_sha1
)
SELECT
img_name,
img_size,
img_width,
img_height,
img_metadata,
img_bits,
img_media_type,
img_major_mime,
img_minor_mime,
img_description,
img_user,
img_user_text,
img_timestamp,
img_sha1
FROM @temp t;

View file

@ -1,4 +0,0 @@
ALTER TABLE /*_*/image
DROP CONSTRAINT img_major_mime_ckc;
ALTER TABLE /*_*/image
WITH NOCHECK ADD CONSTRAINT img_major_mime_ckc CHECK (img_major_mime IN('unknown', 'application', 'audio', 'image', 'text', 'video', 'message', 'model', 'multipart', 'chemical'));

View file

@ -1,2 +0,0 @@
DROP INDEX IF EXISTS /*i*/iw_prefix ON /*_*/interwiki;
ALTER TABLE /*_*/interwiki ADD CONSTRAINT PK_interwiki PRIMARY KEY(iw_prefix);

View file

@ -1,3 +0,0 @@
-- Adding ipb_sitewide for blocks
ALTER TABLE /*$wgDBprefix*/ipblocks
ADD ipb_sitewide bit NOT NULL CONSTRAINT DF_ipb_sitewide DEFAULT 1;

View file

@ -1,11 +0,0 @@
-- For partial block restrictions --
CREATE TABLE /*_*/ipblocks_restrictions (
ir_ipb_id int NOT NULL CONSTRAINT FK_ir_ipb_id FOREIGN KEY REFERENCES /*_*/ipblocks(ipb_id) ON DELETE CASCADE,
ir_type tinyint NOT NULL,
ir_value int NOT NULL,
CONSTRAINT PK_ipblocks_restrictions PRIMARY KEY (ir_ipb_id, ir_type, ir_value)
) /*$wgDBTableOptions*/;
-- Index to query restrictions by the page or namespace.
CREATE INDEX /*i*/ir_type_value ON /*_*/ipblocks_restrictions (ir_type, ir_value);

View file

@ -1,7 +0,0 @@
--
-- Kill cl_collation index.
-- @since 1.27
--
DROP INDEX /*i*/cl_collation ON /*_*/categorylinks;

View file

@ -1,37 +0,0 @@
DECLARE @base nvarchar(max),
@SQL nvarchar(max),
@id sysname;--
SET @base = 'ALTER TABLE /*_*/logging DROP CONSTRAINT ';--
SELECT @id = fk.name
FROM sys.foreign_keys fk
JOIN sys.foreign_key_columns fkc
ON fkc.constraint_object_id = fk.object_id
JOIN sys.columns c
ON c.column_id = fkc.parent_column_id
AND c.object_id = fkc.parent_object_id
WHERE
fk.parent_object_id = OBJECT_ID('/*_*/logging')
AND fk.referenced_object_id = OBJECT_ID('/*_*/mwuser')
AND c.name = 'log_user';--
SET @SQL = @base + @id;--
EXEC sp_executesql @SQL;--
SELECT @id = fk.name
FROM sys.foreign_keys fk
JOIN sys.foreign_key_columns fkc
ON fkc.constraint_object_id = fk.object_id
JOIN sys.columns c
ON c.column_id = fkc.parent_column_id
AND c.object_id = fkc.parent_object_id
WHERE
fk.parent_object_id = OBJECT_ID('/*_*/logging')
AND fk.referenced_object_id = OBJECT_ID('/*_*/page')
AND c.name = 'log_page';--
SET @SQL = @base + @id;--
EXEC sp_executesql @SQL;

View file

@ -1,4 +0,0 @@
ALTER TABLE /*_*/oldimage
DROP CONSTRAINT oi_major_mime_ckc;
ALTER TABLE /*_*/oldimage
WITH NOCHECK ADD CONSTRAINT oi_major_mime_ckc CHECK (oi_major_mime IN('unknown', 'application', 'audio', 'image', 'text', 'video', 'message', 'model', 'multipart', 'chemical'));

View file

@ -1,34 +0,0 @@
DECLARE @baseSQL nvarchar(max),
@SQL nvarchar(max),
@id sysname;--
SET @baseSQL = 'ALTER TABLE /*_*/oldimage DROP CONSTRAINT ';--
SELECT @id = cc.name
FROM sys.check_constraints cc
JOIN sys.columns c
ON c.object_id = cc.parent_object_id
AND c.column_id = cc.parent_column_id
WHERE
cc.parent_object_id = OBJECT_ID('/*_*/oldimage')
AND c.name = 'oi_major_mime';--
SET @SQL = @baseSQL + @id;--
EXEC sp_executesql @SQL;--
SELECT @id = cc.name
FROM sys.check_constraints cc
JOIN sys.columns c
ON c.object_id = cc.parent_object_id
AND c.column_id = cc.parent_column_id
WHERE
cc.parent_object_id = OBJECT_ID('/*_*/oldimage')
AND c.name = 'oi_media_type';--
SET @SQL = @baseSQL + @id;--
EXEC sp_executesql @SQL;--
ALTER TABLE /*_*/oldimage ADD CONSTRAINT oi_major_mime_ckc check (oi_major_mime IN('unknown', 'application', 'audio', 'image', 'text', 'video', 'message', 'model', 'multipart'));--
ALTER TABLE /*_*/oldimage ADD CONSTRAINT oi_media_type_ckc check (oi_media_type in('UNKNOWN', 'BITMAP', 'DRAWING', 'AUDIO', 'VIDEO', 'MULTIMEDIA', 'OFFICE', 'TEXT', 'EXECUTABLE', 'ARCHIVE'));

View file

@ -1,91 +0,0 @@
-- MediaWiki looks for lines ending with semicolons and sends them as separate queries
-- However here we *really* need this all to be sent as a single batch. As such, DO NOT
-- remove the -- from the end of each statement.
DECLARE @temp table (
oi_name varbinary(255),
oi_archive_name varbinary(255),
oi_size int,
oi_width int,
oi_height int,
oi_bits int,
oi_description nvarchar(255),
oi_user int,
oi_user_text nvarchar(255),
oi_timestamp varchar(14),
oi_metadata nvarchar(max),
oi_media_type varchar(16),
oi_major_mime varchar(16),
oi_minor_mime nvarchar(100),
oi_deleted tinyint,
oi_sha1 nvarchar(32)
);--
INSERT INTO @temp
SELECT * FROM /*_*/oldimage;--
DROP TABLE /*_*/oldimage;--
CREATE TABLE /*_*/oldimage (
oi_name nvarchar(255) NOT NULL default '',
oi_archive_name nvarchar(255) NOT NULL default '',
oi_size int NOT NULL default 0,
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_user int REFERENCES /*_*/mwuser(user_id),
oi_user_text nvarchar(255) NOT NULL,
oi_timestamp varchar(14) NOT NULL default '',
oi_metadata varbinary(max) NOT NULL,
oi_media_type varchar(16) default null,
oi_major_mime varchar(16) not null default 'unknown',
oi_minor_mime nvarchar(100) NOT NULL default 'unknown',
oi_deleted tinyint NOT NULL default 0,
oi_sha1 nvarchar(32) NOT NULL default '',
CONSTRAINT oi_major_mime_ckc check (oi_major_mime IN('unknown', 'application', 'audio', 'image', 'text', 'video', 'message', 'model', 'multipart', 'chemical')),
CONSTRAINT oi_media_type_ckc check (oi_media_type IN('UNKNOWN', 'BITMAP', 'DRAWING', 'AUDIO', 'VIDEO', 'MULTIMEDIA', 'OFFICE', 'TEXT', 'EXECUTABLE', 'ARCHIVE'))
);--
CREATE INDEX /*i*/oi_usertext_timestamp ON /*_*/oldimage (oi_user_text, oi_timestamp);--
CREATE INDEX /*i*/oi_name_timestamp ON /*_*/oldimage (oi_name, oi_timestamp);--
CREATE INDEX /*i*/oi_name_archive_name ON /*_*/oldimage (oi_name, oi_archive_name);--
CREATE INDEX /*i*/oi_sha1 ON /*_*/oldimage (oi_sha1);--
INSERT INTO /*_*/oldimage
(
oi_name,
oi_archive_name,
oi_size,
oi_width,
oi_height,
oi_bits,
oi_description,
oi_user,
oi_user_text,
oi_timestamp,
oi_metadata,
oi_media_type,
oi_major_mime,
oi_minor_mime,
oi_deleted,
oi_sha1
)
SELECT
oi_name,
oi_archive_name,
oi_size,
oi_width,
oi_height,
oi_bits,
oi_description,
oi_user,
oi_user_text,
oi_timestamp,
CONVERT(varbinary(max), oi_metadata, 0),
oi_media_type,
oi_major_mime,
oi_minor_mime,
oi_deleted,
oi_sha1
FROM @temp t;

View file

@ -1 +0,0 @@
ALTER TABLE /*_*/page ADD page_lang VARBINARY(35) DEFAULT NULL

View file

@ -1,2 +0,0 @@
DROP INDEX IF EXISTS /*i*/pp_page_propname ON /*_*/page_props;
ALTER TABLE /*_*/page_props ADD CONSTRAINT PK_page_props PRIMARY KEY(pp_page,pp_propname);

View file

@ -1,4 +0,0 @@
ALTER TABLE /*_*/pagelinks
ADD pl_from_namespace int NOT NULL default 0;
CREATE INDEX /*i*/pl_backlinks_namespace ON /*_*/pagelinks (pl_from_namespace,pl_namespace,pl_title,pl_from);

View file

@ -1,8 +0,0 @@
-- Add a 'sortkey' field to page_props so pages can be efficiently
-- queried by the numeric value of a property.
ALTER TABLE /*_*/page_props
ADD pp_sortkey float DEFAULT NULL;
CREATE UNIQUE INDEX /*i*/pp_propname_sortkey_page
ON /*_*/page_props ( pp_propname, pp_sortkey, pp_page );

View file

@ -1,2 +0,0 @@
DROP INDEX IF EXISTS /*i*/pt_namespace_title ON /*_*/protected_titles;
ALTER TABLE /*_*/protected_titles ADD CONSTRAINT PK_protected_titles PRIMARY KEY(pt_namespace,pt_title);

View file

@ -1,22 +0,0 @@
DECLARE @cname sysname;--
SELECT @cname = dc.name
FROM sys.default_constraints dc
JOIN sys.columns c
ON c.object_id = dc.parent_object_id
AND c.column_id = dc.parent_column_id
WHERE
c.name = 'rc_patrolled'
AND c.object_id = OBJECT_ID('/*_*/recentchanges', 'U');--
IF @cname IS NOT NULL
BEGIN;--
DECLARE @sql nvarchar(max);--
SET @sql = N'ALTER TABLE /*_*/recentchanges DROP CONSTRAINT ' + @cname;--
EXEC sp_executesql @sql;--
END;--
DROP INDEX /*i*/rc_name_type_patrolled_timestamp ON /*_*/recentchanges;--
ALTER TABLE /*_*/recentchanges ALTER COLUMN rc_patrolled tinyint NOT NULL;--
ALTER TABLE /*_*/recentchanges ADD CONSTRAINT DF_rc_patrolled DEFAULT 0 FOR rc_patrolled;--
CREATE INDEX /*i*/rc_name_type_patrolled_timestamp ON /*_*/recentchanges (rc_namespace, rc_type, rc_patrolled, rc_timestamp);

View file

@ -1,76 +0,0 @@
DECLARE @base nvarchar(max),
@SQL nvarchar(max),
@id sysname;--
SET @base = 'ALTER TABLE /*_*/recentchanges DROP CONSTRAINT ';--
SELECT @id = fk.name
FROM sys.foreign_keys fk
JOIN sys.foreign_key_columns fkc
ON fkc.constraint_object_id = fk.object_id
JOIN sys.columns c
ON c.column_id = fkc.parent_column_id
AND c.object_id = fkc.parent_object_id
WHERE
fk.parent_object_id = OBJECT_ID('/*_*/recentchanges')
AND fk.referenced_object_id = OBJECT_ID('/*_*/page')
AND c.name = 'rc_cur_id';--
SET @SQL = @base + @id;--
EXEC sp_executesql @SQL;--
SELECT @id = fk.name
FROM sys.foreign_keys fk
JOIN sys.foreign_key_columns fkc
ON fkc.constraint_object_id = fk.object_id
JOIN sys.columns c
ON c.column_id = fkc.parent_column_id
AND c.object_id = fkc.parent_object_id
WHERE
fk.parent_object_id = OBJECT_ID('/*_*/recentchanges')
AND fk.referenced_object_id = OBJECT_ID('/*_*/revision')
AND c.name = 'rc_this_oldid';--
SET @SQL = @base + @id;--
EXEC sp_executesql @SQL;--
SELECT @id = fk.name
FROM sys.foreign_keys fk
JOIN sys.foreign_key_columns fkc
ON fkc.constraint_object_id = fk.object_id
JOIN sys.columns c
ON c.column_id = fkc.parent_column_id
AND c.object_id = fkc.parent_object_id
WHERE
fk.parent_object_id = OBJECT_ID('/*_*/recentchanges')
AND fk.referenced_object_id = OBJECT_ID('/*_*/revision')
AND c.name = 'rc_last_oldid';--
SET @SQL = @base + @id;--
EXEC sp_executesql @SQL;--
-- while we're at it, let's fix up the other foreign key constraints on recentchanges
-- as future patches touch constraints on other tables, they'll take the time to update constraint names there as well
ALTER TABLE /*_*/recentchanges DROP CONSTRAINT FK_rc_logid_log_id;--
ALTER TABLE /*_*/recentchanges ADD CONSTRAINT rc_logid__log_id__fk FOREIGN KEY (rc_logid) REFERENCES /*_*/logging(log_id) ON DELETE CASCADE;--
SELECT @id = fk.name
FROM sys.foreign_keys fk
JOIN sys.foreign_key_columns fkc
ON fkc.constraint_object_id = fk.object_id
JOIN sys.columns c
ON c.column_id = fkc.parent_column_id
AND c.object_id = fkc.parent_object_id
WHERE
fk.parent_object_id = OBJECT_ID('/*_*/recentchanges')
AND fk.referenced_object_id = OBJECT_ID('/*_*/mwuser')
AND c.name = 'rc_user';--
SET @SQL = @base + @id;--
EXEC sp_executesql @SQL;--
ALTER TABLE /*_*/recentchanges ADD CONSTRAINT rc_user__user_id__fk FOREIGN KEY (rc_user) REFERENCES /*_*/mwuser(user_id);

View file

@ -1,10 +0,0 @@
--
-- Adds a default value to the rev_text_id field in the revision table.
-- This is to allow the Multi Content Revisions migration to happen where
-- rows will have to be added to the revision table with no rev_text_id.
--
-- 2018-03-12
--
ALTER TABLE /*_*/revision
ADD CONSTRAINT DF_rev_text_id DEFAULT 0 FOR rev_text_id;

View file

@ -1,2 +0,0 @@
DROP INDEX IF EXISTS /*i*/site_ids_type ON /*_*/site_identifiers;
ALTER TABLE /*_*/site_identifiers ADD CONSTRAINT PK_site_identifiers PRIMARY KEY(si_type, si_key);

View file

@ -1,32 +0,0 @@
/* Delete old default constraints */
DECLARE @sql nvarchar(max)
SET @sql=''
/* IMHO: A DBMS where you have to do THIS to change a default value sucks. */
SELECT @sql= @sql + 'ALTER TABLE site_stats DROP CONSTRAINT ' + df.name + '; '
FROM sys.default_constraints df
JOIN sys.columns c
ON c.object_id = df.parent_object_id
AND c.column_id = df.parent_column_id
WHERE
df.parent_object_id = OBJECT_ID('site_stats');--
EXEC sp_executesql @sql;
/* Change data type of ss_images from int to bigint.
* All other fields (except ss_row_id) already are bigint.
* This MUST happen before adding new constraints. */
ALTER TABLE site_stats ALTER COLUMN ss_images bigint;
/* Add new default constraints.
* Don't ask me why I have to repeat ALTER TABLE site_stats
* instead of using commas, for some reason SQL Server 2016
* didn't accept it in any other way. Maybe I just don't know
* enough about mssql, but this works.
*/
ALTER TABLE site_stats ADD CONSTRAINT col_ss_total_edits DEFAULT NULL FOR ss_total_edits;
ALTER TABLE site_stats ADD CONSTRAINT col_ss_good_article DEFAULT NULL FOR ss_good_articles;
ALTER TABLE site_stats ADD CONSTRAINT col_ss_total_pages DEFAULT NULL FOR ss_total_pages;
ALTER TABLE site_stats ADD CONSTRAINT col_ss_users DEFAULT NULL FOR ss_users;
ALTER TABLE site_stats ADD CONSTRAINT col_ss_active_users DEFAULT NULL FOR ss_active_users;
ALTER TABLE site_stats ADD CONSTRAINT col_ss_images DEFAULT NULL FOR ss_images;

View file

@ -1,2 +0,0 @@
DROP INDEX ss_row_id ON site_stats;
ALTER TABLE /*_*/site_stats ADD CONSTRAINT /*i*/ss_row_id PRIMARY KEY (ss_row_id);

View file

@ -1,14 +0,0 @@
--
-- Replace slot_inherited with slot_origin.
--
-- NOTE: There is no release that has slot_inherited. This is only needed to transition between
-- snapshot versions of 1.30.
--
-- NOTE: No code that writes to the slots table was merge yet, the table is assumed to be empty.
--
DROP INDEX /*i*/slot_role_inherited ON /*_*/slots;
ALTER TABLE /*_*/slots DROP CONSTRAINT DF_slot_inherited, COLUMN slot_inherited;
ALTER TABLE /*_*/slots ADD COLUMN slot_origin bigint NOT NULL;
CREATE INDEX /*i*/slot_revision_origin_role ON /*_*/slots (slot_revision_id, slot_origin, slot_role_id);

View file

@ -1,10 +0,0 @@
--
-- Normalization table for role names
--
CREATE TABLE /*_*/slot_roles (
role_id smallint NOT NULL CONSTRAINT PK_slot_roles PRIMARY KEY IDENTITY,
role_name nvarchar(64) NOT NULL
);
-- Index for looking of the internal ID of for a name
CREATE UNIQUE INDEX /*i*/role_name ON /*_*/slot_roles (role_name);

View file

@ -1,25 +0,0 @@
--
-- Slots represent an n:m relation between revisions and content objects.
-- A content object can have a specific "role" in one or more revisions.
-- Each revision can have multiple content objects, each having a different role.
--
CREATE TABLE /*_*/slots (
-- reference to rev_id
slot_revision_id bigint NOT NULL,
-- reference to role_id
slot_role_id smallint NOT NULL CONSTRAINT FK_slots_slot_role FOREIGN KEY REFERENCES slot_roles(role_id),
-- reference to content_id
slot_content_id bigint NOT NULL CONSTRAINT FK_slots_content_id FOREIGN KEY REFERENCES content(content_id),
-- The revision ID of the revision that originated the slot's content.
-- To find revisions that changed slots, look for slot_origin = slot_revision_id.
slot_origin bigint NOT NULL,
CONSTRAINT PK_slots PRIMARY KEY (slot_revision_id, slot_role_id)
);
-- Index for finding revisions that modified a specific slot
CREATE INDEX /*i*/slot_revision_origin_role ON /*_*/slots (slot_revision_id, slot_origin, slot_role_id);

View file

@ -1,4 +0,0 @@
ALTER TABLE /*_*/templatelinks
ADD tl_from_namespace int NOT NULL default 0;
CREATE INDEX /*i*/tl_backlinks_namespace ON /*_*/templatelinks (tl_from_namespace,tl_namespace,tl_title,tl_from);

View file

@ -1,20 +0,0 @@
DECLARE @baseSQL nvarchar(max),
@SQL nvarchar(max),
@id sysname;--
SET @baseSQL = 'ALTER TABLE /*_*/uploadstash DROP CONSTRAINT ';--
SELECT @id = cc.name
FROM sys.check_constraints cc
JOIN sys.columns c
ON c.object_id = cc.parent_object_id
AND c.column_id = cc.parent_column_id
WHERE
cc.parent_object_id = OBJECT_ID('/*_*/uploadstash')
AND c.name = 'us_media_type';--
SET @SQL = @baseSQL + @id;--
EXEC sp_executesql @SQL;--
ALTER TABLE /*_*/uploadstash ADD CONSTRAINT us_media_type_ckc check (us_media_type in('UNKNOWN', 'BITMAP', 'DRAWING', 'AUDIO', 'VIDEO', 'MULTIMEDIA', 'OFFICE', 'TEXT', 'EXECUTABLE', 'ARCHIVE'));

View file

@ -1,6 +0,0 @@
-- Primary key and expiry column in user_groups table
DROP INDEX IF EXISTS /*i*/ug_user_group ON /*_*/user_groups;
ALTER TABLE /*_*/user_groups ADD CONSTRAINT pk_user_groups PRIMARY KEY(ug_user, ug_group);
ALTER TABLE /*_*/user_groups ADD ug_expiry varchar(14) DEFAULT NULL;
CREATE INDEX /*i*/ug_expiry ON /*_*/user_groups(ug_expiry);

View file

@ -1 +0,0 @@
ALTER TABLE /*_*/mwuser ADD user_password_expires VARCHAR(14) DEFAULT NULL

View file

@ -1,2 +0,0 @@
ALTER TABLE /*_*/watchlist ADD wl_id INT IDENTITY;
ALTER TABLE /*_*/watchlist ADD CONSTRAINT pk_watchlist PRIMARY KEY(wl_id)

View file

@ -1,16 +0,0 @@
-- T193874: Add new indexes to change_tag table using ct_tag_id instead of ct_tag
CREATE UNIQUE INDEX /*i*/change_tag_rc_tag_id ON /*_*/change_tag (ct_rc_id,ct_tag_id);
CREATE UNIQUE INDEX /*i*/change_tag_log_tag_id ON /*_*/change_tag (ct_log_id,ct_tag_id);
CREATE UNIQUE INDEX /*i*/change_tag_rev_tag_id ON /*_*/change_tag (ct_rev_id,ct_tag_id);
CREATE INDEX /*i*/change_tag_rc_tag_nonuniq ON /*_*/change_tag (ct_rc_id,ct_tag);
CREATE INDEX /*i*/change_tag_log_tag_nonuniq ON /*_*/change_tag (ct_log_id,ct_tag);
CREATE INDEX /*i*/change_tag_rev_tag_nonuniq ON /*_*/change_tag (ct_rev_id,ct_tag);
DROP INDEX /*i*/change_tag_rc_tag ON /*_*/change_tag;
DROP INDEX /*i*/change_tag_log_tag ON /*_*/change_tag;
DROP INDEX /*i*/change_tag_rev_tag ON /*_*/change_tag;
ALTER TABLE /*i*/change_tag
ADD CONSTRAINT DF_ct_tag DEFAULT '' FOR ct_tag;

File diff suppressed because it is too large Load diff

View file

@ -1,31 +0,0 @@
-- Update keys for Microsoft SQL Server
-- SQL to insert update keys into the initial tables after a
-- fresh installation of MediaWiki's database.
-- This is read and executed by the install script; you should
-- not have to run it by itself unless doing a manual install.
-- Insert keys here if either the unnecessary would cause heavy
-- processing or could potentially cause trouble by lowering field
-- sizes, adding constraints, etc.
-- When adjusting field sizes, it is recommended removing old
-- patches but to play safe, update keys should also inserted here.
--
-- The /*_*/ comments in this and other files are
-- replaced with the defined table prefix by the installer
-- and updater scripts. If you are installing or running
-- updates manually, you will need to manually insert the
-- table prefix if any when running these scripts.
--
INSERT INTO /*_*/updatelog
SELECT 'filearchive-fa_major_mime-patch-fa_major_mime-chemical.sql' AS ul_key, null as ul_value
UNION SELECT 'image-img_major_mime-patch-img_major_mime-chemical.sql', null
UNION SELECT 'oldimage-oi_major_mime-patch-oi_major_mime-chemical.sql', null
UNION SELECT 'cl_type-category_types-ck', null
UNION SELECT 'fa_major_mime-major_mime-ck', null
UNION SELECT 'fa_media_type-media_type-ck', null
UNION SELECT 'img_major_mime-major_mime-ck', null
UNION SELECT 'img_media_type-media_type-ck', null
UNION SELECT 'oi_major_mime-major_mime-ck', null
UNION SELECT 'oi_media_type-media_type-ck', null
UNION SELECT 'us_media_type-media_type-ck', null;

View file

@ -1,97 +0,0 @@
<?php
/**
* 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 Maintenance
*/
use Wikimedia\Rdbms\DBQueryError;
/**
* When using shared tables that are referenced by foreign keys on local
* tables you have to change the constraints on local tables.
*
* The shared tables have to have GRANT REFERENCE on shared tables to local schema
* i.e.: GRANT REFERENCES (user_id) ON mwuser TO hubclient;
*/
require_once __DIR__ . '/../Maintenance.php';
class AlterSharedConstraints extends Maintenance {
public function __construct() {
parent::__construct();
$this->addDescription( 'Alter foreign key to reference master tables in shared database setup.' );
}
public function getDbType() {
return Maintenance::DB_ADMIN;
}
public function execute() {
global $wgSharedDB, $wgSharedTables, $wgSharedPrefix, $wgDBprefix;
if ( $wgSharedDB == null ) {
$this->output( "Database sharing is not enabled\n" );
return;
}
$dbw = $this->getDB( DB_MASTER );
foreach ( $wgSharedTables as $table ) {
$stable = $dbw->tableNameInternal( $table );
if ( $wgSharedPrefix != null ) {
$ltable = preg_replace( "/^$wgSharedPrefix(.*)/i", "$wgDBprefix\\1", $stable );
} else {
$ltable = "{$wgDBprefix}{$stable}";
}
$result = $dbw->query( "SELECT uc.constraint_name, uc.table_name, ucc.column_name,
uccpk.table_name pk_table_name, uccpk.column_name pk_column_name,
uc.delete_rule, uc.deferrable, uc.deferred
FROM user_constraints uc, user_cons_columns ucc, user_cons_columns uccpk
WHERE uc.constraint_type = 'R'
AND ucc.constraint_name = uc.constraint_name
AND uccpk.constraint_name = uc.r_constraint_name
AND uccpk.table_name = '$ltable'" );
while ( ( $row = $result->fetchRow() ) !== false ) {
$this->output( "Altering {$row['constraint_name']} ..." );
try {
$dbw->query( "ALTER TABLE {$row['table_name']}
DROP CONSTRAINT {$wgDBprefix}{$row['constraint_name']}" );
} catch ( DBQueryError $exdb ) {
if ( $exdb->errno != 2443 ) {
throw $exdb;
}
}
$deleteRule = $row['delete_rule'] == 'NO ACTION' ? '' : "ON DELETE {$row['delete_rule']}";
$dbw->query( "ALTER TABLE {$row['table_name']}
ADD CONSTRAINT {$wgDBprefix}{$row['constraint_name']}
FOREIGN KEY ({$row['column_name']})
REFERENCES {$wgSharedDB}.$stable({$row['pk_column_name']})
{$deleteRule} {$row['deferrable']} INITIALLY {$row['deferred']}" );
$this->output( "DONE\n" );
}
}
}
}
$maintClass = AlterSharedConstraints::class;
require_once RUN_MAINTENANCE_IF_MAIN;

View file

@ -1,64 +0,0 @@
--
-- patch-actor-table.sql
--
-- T167246. Add an `actor` table and various columns (and temporary tables) to reference it.
define mw_prefix='{$wgDBprefix}';
CREATE SEQUENCE actor_actor_id_seq;
CREATE TABLE &mw_prefix.actor (
actor_id NUMBER NOT NULL,
actor_user NUMBER,
actor_name VARCHAR2(255) NOT NULL
);
ALTER TABLE &mw_prefix.actor ADD CONSTRAINT &mw_prefix.actor_pk PRIMARY KEY (actor_id);
/*$mw$*/
CREATE TRIGGER &mw_prefix.actor_seq_trg BEFORE INSERT ON &mw_prefix.actor
FOR EACH ROW WHEN (new.actor_id IS NULL)
BEGIN
&mw_prefix.lastval_pkg.setLastval(actor_actor_id_seq.nextval, :new.actor_id);
END;
/*$mw$*/
-- Create a dummy actor to satisfy fk contraints
INSERT INTO &mw_prefix.actor (actor_id, actor_name) VALUES (0,'##Anonymous##');
CREATE TABLE &mw_prefix.revision_actor_temp (
revactor_rev NUMBER NOT NULL,
revactor_actor NUMBER NOT NULL,
revactor_timestamp TIMESTAMP(6) WITH TIME ZONE NOT NULL,
revactor_page NUMBER NOT NULL
);
ALTER TABLE &mw_prefix.revision_actor_temp ADD CONSTRAINT &mw_prefix.revision_actor_temp_pk PRIMARY KEY (revactor_rev, revactor_actor);
CREATE UNIQUE INDEX &mw_prefix.revactor_rev ON &mw_prefix.revision_actor_temp (revactor_rev);
CREATE INDEX &mw_prefix.actor_timestamp ON &mw_prefix.revision_actor_temp (revactor_actor,revactor_timestamp);
CREATE INDEX &mw_prefix.page_actor_timestamp ON &mw_prefix.revision_actor_temp (revactor_page,revactor_actor,revactor_timestamp);
ALTER TABLE &mw_prefix.archive MODIFY ( ar_user_text NULL );
ALTER TABLE &mw_prefix.archive ADD ( ar_actor NUMBER DEFAULT 0 NOT NULL );
CREATE INDEX &mw_prefix.ar_actor_timestamp ON &mw_prefix.archive (ar_actor,ar_timestamp);
ALTER TABLE &mw_prefix.ipblocks ADD ( ipb_by_actor NUMBER DEFAULT 0 NOT NULL );
ALTER TABLE &mw_prefix.image MODIFY ( img_user_text NULL );
ALTER TABLE &mw_prefix.image ADD ( img_actor NUMBER DEFAULT 0 NOT NULL );
CREATE INDEX &mw_prefix.img_actor_timestamp ON &mw_prefix.image (img_actor, img_timestamp);
ALTER TABLE &mw_prefix.oldimage MODIFY ( oi_user_text NULL );
ALTER TABLE &mw_prefix.oldimage ADD ( oi_actor NUMBER DEFAULT 0 NOT NULL );
CREATE INDEX &mw_prefix.oi_actor_timestamp ON &mw_prefix.oldimage (oi_actor,oi_timestamp);
ALTER TABLE &mw_prefix.filearchive MODIFY ( fa_user_text NULL );
ALTER TABLE &mw_prefix.filearchive ADD ( fa_actor NUMBER DEFAULT 0 NOT NULL );
CREATE INDEX &mw_prefix.fa_actor_timestamp ON &mw_prefix.filearchive (fa_actor,fa_timestamp);
ALTER TABLE &mw_prefix.recentchanges MODIFY ( rc_user_text NULL );
ALTER TABLE &mw_prefix.recentchanges ADD ( rc_actor NUMBER DEFAULT 0 NOT NULL );
CREATE INDEX &mw_prefix.rc_ns_actor ON &mw_prefix.recentchanges (rc_namespace, rc_actor);
CREATE INDEX &mw_prefix.rc_actor ON &mw_prefix.recentchanges (rc_actor, rc_timestamp);
ALTER TABLE &mw_prefix.logging ADD ( log_actor NUMBER DEFAULT 0 NOT NULL );
CREATE INDEX &mw_prefix.actor_time ON &mw_prefix.logging (log_actor, log_timestamp);
CREATE INDEX &mw_prefix.log_actor_type_time ON &mw_prefix.logging (log_actor, log_type, log_timestamp);

View file

@ -1,4 +0,0 @@
define mw_prefix='{$wgDBprefix}';
CREATE INDEX &mw_prefix.recentchanges_i08 ON &mw_prefix.recentchanges (rc_namespace, rc_type, rc_patrolled, rc_timestamp);

View file

@ -1,5 +0,0 @@
-- T182678: Make ar_rev_id not nullable
define mw_prefix='{$wgDBprefix}';
ALTER TABLE &mw_prefix.archive MODIFY ar_rev_id NUMBER NOT NULL;

View file

@ -1,3 +0,0 @@
define mw_prefix='{$wgDBprefix}';
ALTER TABLE &mw_prefix.archive ADD ar_sha1 VARCHAR2(32);

View file

@ -1,3 +0,0 @@
define mw_prefix='{$wgDBprefix}';
ALTER TABLE &mw_prefix.archive ADD ar_content_format VARCHAR2(64);

View file

@ -1,3 +0,0 @@
define mw_prefix='{$wgDBprefix}';
ALTER TABLE &mw_prefix.archive ADD ar_content_model VARCHAR2(32);

View file

@ -1,6 +0,0 @@
define mw_prefix='{$wgDBprefix}';
ALTER TABLE &mw_prefix.archive ADD (
ar_id NUMBER NOT NULL,
);
ALTER TABLE &mw_prefix.archive ADD CONSTRAINT &mw_prefix.archive_pk PRIMARY KEY (ar_id);

View file

@ -1,6 +0,0 @@
-- T193180: ar_rev_id should be unique
define mw_prefix='{$wgDBprefix}';
CREATE UNIQUE INDEX &mw_prefix.archive_i04 ON &mw_prefix.archive (ar_rev_id);
DROP INDEX &mw_prefix.archive_i03;

View file

@ -1,144 +0,0 @@
define mw_prefix='{$wgDBprefix}';
-- Package to help with making Oracle more like other DBs with respect to
-- auto-incrementing columns.
/*$mw$*/
CREATE PACKAGE &mw_prefix.lastval_pkg IS
lastval NUMBER;
PROCEDURE setLastval(val IN NUMBER, field OUT NUMBER);
FUNCTION getLastval RETURN NUMBER;
END;
/*$mw$*/
/*$mw$*/
CREATE PACKAGE BODY &mw_prefix.lastval_pkg IS
PROCEDURE setLastval(val IN NUMBER, field OUT NUMBER) IS BEGIN
lastval := val;
field := val;
END;
FUNCTION getLastval RETURN NUMBER IS BEGIN
RETURN lastval;
END;
END;
/*$mw$*/
/*$mw$*/
CREATE TRIGGER &mw_prefix.mwuser_seq_trg BEFORE INSERT ON &mw_prefix.mwuser
FOR EACH ROW WHEN (new.user_id IS NULL)
BEGIN
&mw_prefix.lastval_pkg.setLastval(user_user_id_seq.nextval, :new.user_id);
END;
/*$mw$*/
/*$mw$*/
CREATE TRIGGER &mw_prefix.page_seq_trg BEFORE INSERT ON &mw_prefix.page
FOR EACH ROW WHEN (new.page_id IS NULL)
BEGIN
&mw_prefix.lastval_pkg.setLastval(page_page_id_seq.nextval, :new.page_id);
END;
/*$mw$*/
/*$mw$*/
CREATE TRIGGER &mw_prefix.revision_seq_trg BEFORE INSERT ON &mw_prefix.revision
FOR EACH ROW WHEN (new.rev_id IS NULL)
BEGIN
&mw_prefix.lastval_pkg.setLastval(revision_rev_id_seq.nextval, :new.rev_id);
END;
/*$mw$*/
/*$mw$*/
CREATE TRIGGER &mw_prefix.pagecontent_seq_trg BEFORE INSERT ON &mw_prefix.pagecontent
FOR EACH ROW WHEN (new.old_id IS NULL)
BEGIN
&mw_prefix.lastval_pkg.setLastval(text_old_id_seq.nextval, :new.old_id);
END;
/*$mw$*/
/*$mw$*/
CREATE TRIGGER &mw_prefix.archive_seq_trg BEFORE INSERT ON &mw_prefix.archive
FOR EACH ROW WHEN (new.ar_id IS NULL)
BEGIN
&mw_prefix.lastval_pkg.setLastval(archive_ar_id_seq.nextval, :new.ar_id);
END;
/*$mw$*/
/*$mw$*/
CREATE TRIGGER &mw_prefix.category_seq_trg BEFORE INSERT ON &mw_prefix.category
FOR EACH ROW WHEN (new.cat_id IS NULL)
BEGIN
&mw_prefix.lastval_pkg.setLastval(category_cat_id_seq.nextval, :new.cat_id);
END;
/*$mw$*/
/*$mw$*/
CREATE TRIGGER &mw_prefix.externallinks_seq_trg BEFORE INSERT ON &mw_prefix.externallinks
FOR EACH ROW WHEN (new.el_id IS NULL)
BEGIN
&mw_prefix.lastval_pkg.setLastval(externallinks_el_id_seq.nextval, :new.el_id);
END;
/*$mw$*/
/*$mw$*/
CREATE TRIGGER &mw_prefix.ipblocks_seq_trg BEFORE INSERT ON &mw_prefix.ipblocks
FOR EACH ROW WHEN (new.ipb_id IS NULL)
BEGIN
&mw_prefix.lastval_pkg.setLastval(ipblocks_ipb_id_seq.nextval, :new.ipb_id);
END;
/*$mw$*/
/*$mw$*/
CREATE TRIGGER &mw_prefix.filearchive_seq_trg BEFORE INSERT ON &mw_prefix.filearchive
FOR EACH ROW WHEN (new.fa_id IS NULL)
BEGIN
&mw_prefix.lastval_pkg.setLastval(filearchive_fa_id_seq.nextval, :new.fa_id);
END;
/*$mw$*/
/*$mw$*/
CREATE TRIGGER &mw_prefix.uploadstash_seq_trg BEFORE INSERT ON &mw_prefix.uploadstash
FOR EACH ROW WHEN (new.us_id IS NULL)
BEGIN
&mw_prefix.lastval_pkg.setLastval(uploadstash_us_id_seq.nextval, :new.us_id);
END;
/*$mw$*/
/*$mw$*/
CREATE TRIGGER &mw_prefix.recentchanges_seq_trg BEFORE INSERT ON &mw_prefix.recentchanges
FOR EACH ROW WHEN (new.rc_id IS NULL)
BEGIN
&mw_prefix.lastval_pkg.setLastval(recentchanges_rc_id_seq.nextval, :new.rc_id);
END;
/*$mw$*/
/*$mw$*/
CREATE TRIGGER &mw_prefix.logging_seq_trg BEFORE INSERT ON &mw_prefix.logging
FOR EACH ROW WHEN (new.log_id IS NULL)
BEGIN
&mw_prefix.lastval_pkg.setLastval(logging_log_id_seq.nextval, :new.log_id);
END;
/*$mw$*/
/*$mw$*/
CREATE TRIGGER &mw_prefix.job_seq_trg BEFORE INSERT ON &mw_prefix.job
FOR EACH ROW WHEN (new.job_id IS NULL)
BEGIN
&mw_prefix.lastval_pkg.setLastval(job_job_id_seq.nextval, :new.job_id);
END;
/*$mw$*/
/*$mw$*/
CREATE TRIGGER &mw_prefix.page_restrictions_seq_trg BEFORE INSERT ON &mw_prefix.page_restrictions
FOR EACH ROW WHEN (new.pr_id IS NULL)
BEGIN
&mw_prefix.lastval_pkg.setLastval(page_restrictions_pr_id_seq.nextval, :new.pr_id);
END;
/*$mw$*/
/*$mw$*/
CREATE TRIGGER &mw_prefix.sites_seq_trg BEFORE INSERT ON &mw_prefix.sites
FOR EACH ROW WHEN (new.site_id IS NULL)
BEGIN
&mw_prefix.lastval_pkg.setLastval(sites_site_id_seq.nextval, :new.site_id);
END;
/*$mw$*/

View file

@ -1,4 +0,0 @@
define mw_prefix='{$wgDBprefix}';
ALTER TABLE &mw_prefix.category DROP COLUMN cat_hidden;

View file

@ -1,18 +0,0 @@
-- T193874: Add new indexes to change_tag table using ct_tag_id instead of ct_tag
define mw_prefix='{$wgDBprefix}';
CREATE UNIQUE INDEX &mw_prefix.change_tag_u04 ON &mw_prefix.change_tag (ct_rc_id,ct_tag_id);
CREATE UNIQUE INDEX &mw_prefix.change_tag_u05 ON &mw_prefix.change_tag (ct_log_id,ct_tag_id);
CREATE UNIQUE INDEX &mw_prefix.change_tag_u06 ON &mw_prefix.change_tag (ct_rev_id,ct_tag_id);
CREATE INDEX &mw_prefix.change_tag_i03 ON &mw_prefix.change_tag (ct_rc_id,ct_tag);
CREATE INDEX &mw_prefix.change_tag_i04 ON &mw_prefix.change_tag (ct_log_id,ct_tag);
CREATE INDEX &mw_prefix.change_tag_i05 ON &mw_prefix.change_tag (ct_rev_id,ct_tag);
DROP INDEX &mw_prefix.change_tag_u01;
DROP INDEX &mw_prefix.change_tag_u02;
DROP INDEX &mw_prefix.change_tag_u03;
ALTER TABLE &mw_prefix.change_tag
MODIFY ct_tag DEFAULT '///invalid///';

View file

@ -1,6 +0,0 @@
define mw_prefix='{$wgDBprefix}';
ALTER TABLE &mw_prefix.change_tag ADD (
ct_id NUMBER NOT NULL,
);
ALTER TABLE &mw_prefix.change_tag ADD CONSTRAINT &mw_prefix.change_tag_pk PRIMARY KEY (ct_id);

View file

@ -1,6 +0,0 @@
--
-- Add ctd_tag_id to change_tag table to normalize it
--
ALTER TABLE &mw_prefix.change_tag ADD ( ct_tag_id NUMBER DEFAULT NULL );
CREATE INDEX &mw_prefix.change_tag_i02 ON &mw_prefix.change_tag (ct_tag_id,ct_rc_id,ct_rev_id,ct_log_id);

View file

@ -1,25 +0,0 @@
-- Table defining tag names for IDs. Also stores hit counts to avoid expensive queries on change_tag
CREATE SEQUENCE change_tag_def_ctd_id_seq;
CREATE TABLE &mw_prefix.change_tag_def (
-- Numerical ID of the tag (ct_tag_id refers to this)
ctd_id NUMBER NOT NULL,
-- Symbolic name of the tag (what would previously be put in ct_tag)
ctd_name VARCHAR2(255) NOT NULL,
-- Whether this tag was defined manually by a privileged user using Special:Tags
ctd_user_defined CHAR(1) DEFAULT '0' NOT NULL,
-- Number of times this tag was used
ctd_count NUMBER NOT NULL DEFAULT 0
);
ALTER TABLE &mw_prefix.change_tag_def ADD CONSTRAINT &mw_prefix.change_tag_def_pk PRIMARY KEY (ctd_id);
CREATE UNIQUE INDEX &mw_prefix.ctd_name ON &mw_prefix.change_tag_def (ctd_name);
CREATE INDEX &mw_prefix.ctd_count ON &mw_prefix.change_tag_def (ctd_count);
CREATE INDEX &mw_prefix.ctd_user_defined ON &mw_prefix.change_tag_def (ctd_user_defined);
/*$mw$*/
CREATE TRIGGER &mw_prefix.change_tag_def_seq_trg BEFORE INSERT ON &mw_prefix.change_tag_def
FOR EACH ROW WHEN (new.ctd_id IS NULL)
BEGIN
&mw_prefix.lastval_pkg.setLastval(change_tag_def_ctd_id_seq.nextval, :new.ctd_id);
END;
/*$mw$*/

View file

@ -1,68 +0,0 @@
--
-- 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 ( 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 MODIFY ( ipb_reason NULL );
ALTER TABLE &mw_prefix.ipblocks ADD ( 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 ( 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 ( fa_deleted_reason_id NUMBER DEFAULT 0 NOT NULL );
ALTER TABLE &mw_prefix.filearchive ADD ( 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 ( 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 ( 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 ( 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;

View file

@ -1,18 +0,0 @@
CREATE SEQUENCE content_content_id_seq;
CREATE TABLE &mw_prefix.content (
content_id NUMBER NOT NULL,
content_size NUMBER NOT NULL,
content_sha1 VARCHAR2(32) NOT NULL,
content_model NUMBER NOT NULL,
content_address VARCHAR2(255) NOT NULL
);
ALTER TABLE &mw_prefix.content ADD CONSTRAINT &mw_prefix.content_pk PRIMARY KEY (content_id);
/*$mw$*/
CREATE TRIGGER &mw_prefix.content_seq_trg BEFORE INSERT ON &mw_prefix.content
FOR EACH ROW WHEN (new.content_id IS NULL)
BEGIN
&mw_prefix.lastval_pkg.setLastval(content_content_id_seq.nextval, :new.content_id);
END;
/*$mw$*/

View file

@ -1,18 +0,0 @@
CREATE SEQUENCE content_models_model_id_seq;
CREATE TABLE &mw_prefix.content_models (
model_id NUMBER NOT NULL,
model_name VARCHAR2(64) NOT NULL
);
ALTER TABLE &mw_prefix.content_models ADD CONSTRAINT &mw_prefix.content_models_pk PRIMARY KEY (model_id);
CREATE UNIQUE INDEX &mw_prefix.model_name_u01 ON &mw_prefix.content_models (model_name);
/*$mw$*/
CREATE TRIGGER &mw_prefix.content_models_seq_trg BEFORE INSERT ON &mw_prefix.content_models
FOR EACH ROW WHEN (new.model_id IS NULL)
BEGIN
&mw_prefix.lastval_pkg.setLastval(content_models_model_id_seq.nextval, :new.model_id);
END;
/*$mw$*/

View file

@ -1,7 +0,0 @@
-- T33223: Remove obsolete ar_text and ar_flags columns
-- (and make ar_text_id not nullable and default 0)
define mw_prefix='{$wgDBprefix}';
ALTER TABLE &mw_prefix.archive DROP (ar_text, ar_flags);
ALTER TABLE &mw_prefix.archive MODIFY ar_text_id NUMBER DEFAULT 0 NOT NULL;

View file

@ -1,30 +0,0 @@
--
-- patch-drop-comment-fields.sql
--
-- T166732. Drop old xx_comment fields, and defaults from xx_comment_id fields.
ALTER TABLE &mw_prefix.archive DROP COLUMN ar_comment;
ALTER TABLE &mw_prefix.archive MODIFY ar_comment_id DEFAULT NULL;
ALTER TABLE &mw_prefix.ipblocks DROP COLUMN ipb_reason;
ALTER TABLE &mw_prefix.ipblocks MODIFY ipb_reason_id DEFAULT NULL;
ALTER TABLE &mw_prefix.image DROP COLUMN img_description;
ALTER TABLE &mw_prefix.image MODIFY img_description_id DEFAULT NULL;
ALTER TABLE &mw_prefix.oldimage DROP COLUMN oi_description;
ALTER TABLE &mw_prefix.oldimage MODIFY oi_description_id DEFAULT NULL;
ALTER TABLE &mw_prefix.filearchive DROP COLUMN fa_deleted_reason;
ALTER TABLE &mw_prefix.filearchive MODIFY fa_deleted_reason_id DEFAULT NULL,
ALTER TABLE &mw_prefix.filearchive DROP COLUMN fa_description;
ALTER TABLE &mw_prefix.filearchive MODIFY fa_description_id DEFAULT NULL;
ALTER TABLE &mw_prefix.recentchanges DROP COLUMN rc_comment;
ALTER TABLE &mw_prefix.recentchanges MODIFY rc_comment_id DEFAULT NULL;
ALTER TABLE &mw_prefix.logging DROP COLUMN log_comment;
ALTER TABLE &mw_prefix.logging MODIFY log_comment_id DEFAULT NULL;
ALTER TABLE &mw_prefix.protected_titles DROP COLUMN pt_reason;
ALTER TABLE &mw_prefix.protected_titles MODIFY pt_reason_id DEFAULT NULL;

View file

@ -1,9 +0,0 @@
-- T185355
ALTER TABLE &mw_prefix.change_tag MODIFY &mw_prefix.ct_tag_id NUMBER NOT NULL;
DROP INDEX &mw_prefix.change_tag_i03;
DROP INDEX &mw_prefix.change_tag_i04;
DROP INDEX &mw_prefix.change_tag_i05;
DROP INDEX &mw_prefix.change_tag_i01;
ALTER TABLE &mw_prefix.change_tag DROP COLUMN &mw_prefix.ct_tag;

View file

@ -1,4 +0,0 @@
define mw_prefix='{$wgDBprefix}';
ALTER TABLE &mw_prefix.externallinks ADD el_id NUMBER NOT NULL;
ALTER TABLE &mw_prefix.externallinks ADD CONSTRAINT &mw_prefix.externallinks_pk PRIMARY KEY (el_id);

View file

@ -1,5 +0,0 @@
define mw_prefix='{$wgDBprefix}';
ALTER TABLE &mw_prefix.externallinks ADD el_index_60 VARCHAR2(60);
CREATE INDEX &mw_prefix.externallinks_i04 ON &mw_prefix.externallinks (el_index_60, el_id);
CREATE INDEX &mw_prefix.externallinks_i05 ON &mw_prefix.externallinks (el_from, el_index_60, el_id);

View file

@ -1,5 +0,0 @@
define mw_prefix='{$wgDBprefix}';
ALTER TABLE &mw_prefix.filearchive ADD fa_sha1 VARCHAR2(32);
CREATE INDEX &mw_prefix.filearchive_i05 ON &mw_prefix.filearchive (fa_sha1);

View file

@ -1,7 +0,0 @@
--
-- patch-image-img_description_id.sql
--
-- T188132. Add `img_description_id` to the `image` table.
ALTER TABLE &mw_prefix.image ADD ( img_description_id NUMBER DEFAULT 0 NOT NULL );
ALTER TABLE &mw_prefix.image ADD CONSTRAINT &mw_prefix.oldimage_fk2 FOREIGN KEY (img_description_id) REFERENCES &mw_prefix."COMMENT"(comment_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;

View file

@ -1,3 +0,0 @@
-- Adding ipb_sitewide for blocks
ALTER TABLE &mw_prefix.ipblocks
ADD ipb_sitewide CHAR(1) DEFAULT '1' NOT NULL;

View file

@ -1,4 +0,0 @@
define mw_prefix='{$wgDBprefix}';
CREATE INDEX &mw_prefix.ipblocks_i05 ON &mw_prefix.ipblocks (ipb_parent_block_id);

View file

@ -1,12 +0,0 @@
-- For partial block restrictions --
CREATE TABLE &mw_prefix.ipblocks_restrictions (
ir_ipb_id NUMBER NOT NULL,
ir_type NUMBER NOT NULL,
ir_value NUMBER NOT NULL
);
ALTER TABLE &mw_prefix.ipblocks_restrictions ADD CONSTRAINT ipblocks_restrictions_pk PRIMARY KEY (ir_ipb_id, ir_type, ir_value);
-- Index to query restrictions by the page or namespace.
CREATE INDEX &mw_prefix.ir_type_value ON &mw_prefix.ipblocks_restrictions (ir_type, ir_value);

View file

@ -1,4 +0,0 @@
define mw_prefix='{$wgDBprefix}';
ALTER TABLE &mw_prefix.job ADD job_attempts NUMBER DEFAULT 0 NOT NULL;
CREATE INDEX &mw_prefix.job_i05 ON &mw_prefix.job (job_attempts);

View file

@ -1,4 +0,0 @@
define mw_prefix='{$wgDBprefix}';
ALTER TABLE &mw_prefix.job ADD job_timestamp TIMESTAMP(6) WITH TIME ZONE NULL;

View file

@ -1,4 +0,0 @@
define mw_prefix='{$wgDBprefix}';
CREATE INDEX &mw_prefix.job_i02 ON &mw_prefix.job (job_timestamp);

Some files were not shown because too many files have changed in this diff Show more