'SqliteUpdater' => 'includes/installer/SqliteUpdater.php',
'OracleInstaller' => 'includes/installer/OracleInstaller.php',
'OracleUpdater' => 'includes/installer/OracleUpdater.php',
+ 'Ibm_db2Installer' => 'includes/installer/Ibm_db2Installer.php',
+ 'Ibm_db2Updater' => 'includes/installer/Ibm_db2Updater.php',
# includes/job
'DoubleRedirectJob' => 'includes/job/DoubleRedirectJob.php',
public $mStmtOptions = array();
/** Default schema */
- const USE_GLOBAL = 'mediawiki';
+ const USE_GLOBAL = 'get from global';
/** Option that applies to nothing */
const NONE_OPTION = 0x00;
}
// configure the connection and statement objects
+ /*
+ $this->setDB2Option( 'cursor', 'DB2_SCROLLABLE',
+ self::CONN_OPTION | self::STMT_OPTION );
+ */
$this->setDB2Option( 'db2_attr_case', 'DB2_CASE_LOWER',
self::CONN_OPTION | self::STMT_OPTION );
$this->setDB2Option( 'deferred_prepare', 'DB2_DEFERRED_PREPARE_ON',
* @return a fresh connection
*/
public function open( $server, $user, $password, $dbName ) {
- // Load the port number
- global $wgDBport;
wfProfileIn( __METHOD__ );
- // Load IBM DB2 driver if missing
+ # Load IBM DB2 driver if missing
wfDl( 'ibm_db2' );
- // Test for IBM DB2 support, to avoid suppressed fatal error
+ # Test for IBM DB2 support, to avoid suppressed fatal error
if ( !function_exists( 'db2_connect' ) ) {
- $error = <<<ERROR
-DB2 functions missing, have you enabled the ibm_db2 extension for PHP?
-
-ERROR;
- $this->installPrint( $error );
- $this->reportConnectionError( $error );
+ throw new DBConnectionError( $this, "DB2 functions missing, have you enabled the ibm_db2 extension for PHP?" );
}
- if ( strlen( $user ) < 1 ) {
- wfProfileOut( __METHOD__ );
- return null;
- }
+ global $wgDBport;
// Close existing connection
$this->close();
$this->openUncataloged( $dbName, $user, $password, $server, $port );
- // Apply connection config
- db2_set_option( $this->mConn, $this->mConnOptions, 1 );
- // Some MediaWiki code is still transaction-less (?).
- // The strategy is to keep AutoCommit on for that code
- // but switch it off whenever a transaction is begun.
- db2_autocommit( $this->mConn, DB2_AUTOCOMMIT_ON );
-
if ( !$this->mConn ) {
$this->installPrint( "DB connection error\n" );
$this->installPrint(
"Server: $server, Database: $dbName, User: $user, Password: "
. substr( $password, 0, 3 ) . "...\n" );
$this->installPrint( $this->lastError() . "\n" );
-
wfProfileOut( __METHOD__ );
- return null;
+ wfDebug( "DB connection error\n" );
+ wfDebug( "Server: $server, Database: $dbName, User: $user, Password: " . substr( $password, 0, 3 ) . "...\n" );
+ wfDebug( $this->lastError() . "\n" );
+ throw new DBConnectionError( $this, $this->lastError() );
}
+ // Apply connection config
+ db2_set_option( $this->mConn, $this->mConnOptions, 1 );
+ // Some MediaWiki code is still transaction-less (?).
+ // The strategy is to keep AutoCommit on for that code
+ // but switch it off whenever a transaction is begun.
+ db2_autocommit( $this->mConn, DB2_AUTOCOMMIT_ON );
+
$this->mOpened = true;
$this->applySchema();
*/
protected function openUncataloged( $dbName, $user, $password, $server, $port )
{
- $str = "DRIVER={IBM DB2 ODBC DRIVER};";
- $str .= "DATABASE=$dbName;";
- $str .= "HOSTNAME=$server;";
- // port was formerly validated to not be 0
- $str .= "PORT=$port;";
- $str .= "PROTOCOL=TCPIP;";
- $str .= "UID=$user;";
- $str .= "PWD=$password;";
-
- @$this->mConn = db2_pconnect( $str, $user, $password );
+ $dsn = "DRIVER={IBM DB2 ODBC DRIVER};DATABASE=$dbName;CHARSET=UTF-8;HOSTNAME=$server;PORT=$port;PROTOCOL=TCPIP;UID=$user;PWD=$password;";
+ @$this->mConn = db2_pconnect($dsn, "", "", array());
}
/**
/*private*/
public function doQuery( $sql ) {
$this->applySchema();
-
+
+ // Needed to handle any UTF-8 encoding issues in the raw sql
+ // Note that we fully support prepared statements for DB2
+ // prepare() and execute() should be used instead of doQuery() whenever possible
+ $sql = utf8_decode($sql);
+
$ret = db2_exec( $this->mConn, $sql, $this->mStmtOptions );
if( $ret == false ) {
+ //TODO: Remove commented-out debug code once done debugging
+ //echo '<pre>ERROR</pre>';
+ //echo '<pre>' . $sql . '</pre>';
$error = db2_stmt_errormsg();
+ //echo '<pre>' . $error . '</pre>';
$this->installPrint( "<pre>$sql</pre>" );
$this->installPrint( $error );
throw new DBUnexpectedError( $this, 'SQL error: '
*/
public function tableExists( $table ) {
$schema = $this->mSchema;
- $sql = <<< EOF
+ /*$sql = <<< EOF
SELECT COUNT( * ) FROM SYSIBM.SYSTABLES ST
WHERE ST.NAME = '$table' AND ST.CREATOR = '$schema'
-EOF;
+EOF;*/
+ $sql = "SELECT COUNT( * ) FROM SYSIBM.SYSTABLES ST WHERE ST.NAME = '" .
+ strtoupper( $table ) .
+ "' AND ST.CREATOR = '" .
+ strtoupper( $schema ) . "'";
$res = $this->query( $sql );
if ( !$res ) {
return false;
if ( $res instanceof ResultWrapper ) {
$res = $res->result;
}
- @$row = db2_fetch_array( $res );
- if ( $this->lastErrno() ) {
- throw new DBUnexpectedError( $this, 'Error in fetchRow(): '
- . htmlspecialchars( $this->lastError() ) );
- }
- return $row;
+ if ( db2_num_rows( $res ) > 0) {
+ @$row = db2_fetch_array( $res );
+ if ( $this->lastErrno() ) {
+ throw new DBUnexpectedError( $this, 'Error in fetchRow(): '
+ . htmlspecialchars( $this->lastError() ) );
+ }
+ return $row;
+ }
+ return false;
}
/**
} else {
$sql .= '( ?' . str_repeat( ',?', $key_count-1 ) . ' )';
}
- //$this->installPrint( "Preparing the following SQL:" );
- //$this->installPrint( "$sql" );
- //$this->installPrint( print_r( $args, true ));
+ $this->installPrint( "Preparing the following SQL:" );
+ $this->installPrint( "$sql" );
+ $this->installPrint( print_r( $args, true ));
$stmt = $this->prepare( $sql );
// start a transaction/enter transaction mode
private function removeNullPrimaryKeys( $table, $args ) {
$schema = $this->mSchema;
// find out the primary keys
- $keyres = db2_primary_keys( $this->mConn, null, strtoupper( $schema ),
+ /*$keyres = db2_primary_keys( $this->mConn, null, strtoupper( $schema ),
strtoupper( $table )
- );
+ );*/
+ $keyres = $this->doQuery( "SELECT NAME FROM SYSIBM.SYSCOLUMNS WHERE TBNAME = '" . strtoupper( $table ) . "' AND TBCREATOR = '" . strtoupper( $schema ) . "' AND KEYSEQ > 0" );
$keys = array();
for (
- $row = $this->fetchObject( $keyres );
+ $row = $this->fetchRow( $keyres );
$row != null;
- $row = $this->fetchObject( $keyres )
+ $row = $this->fetchRow( $keyres )
)
{
- $keys[] = strtolower( $row->column_name );
+ $keys[] = strtolower( $row[0] );
}
// remove primary keys
foreach ( $args as $ai => $row ) {
$this->query( $sql, $fname );
}
+ $this->insert($table, $row);
# Now insert the row
- $sql = "INSERT INTO $table ( "
+ /*$sql = "INSERT INTO $table ( "
. $this->makeList( array_keys( $row ), LIST_NAMES )
.' ) VALUES ( ' . $this->makeList( $row, LIST_COMMA ) . ' )';
- $this->query( $sql, $fname );
+ $this->query( $sql, $fname );*/
}
}
if ( $res instanceof ResultWrapper ) {
$res = $res->result;
}
+
if ( $this->mNumRows ) {
return $this->mNumRows;
} else {
*/
public function prepare( $sql, $func = 'DB2::prepare' ) {
$stmt = db2_prepare( $this->mConn, $sql, $this->mStmtOptions );
- return $stmt;
+ return $stmt;
}
/**
--- /dev/null
+<?php\r
+/**\r
+ * IBM_DB2-specific installer.\r
+ *\r
+ * @file\r
+ * @ingroup Deployment\r
+ */\r
+\r
+/**\r
+ * Class for setting up the MediaWiki database using IBM_DB2.\r
+ *\r
+ * @ingroup Deployment\r
+ * @since 1.17\r
+ */\r
+class Ibm_db2Installer extends DatabaseInstaller {\r
+\r
+\r
+ protected $globalNames = array(\r
+ 'wgDBserver',\r
+ 'wgDBport',\r
+ 'wgDBname',\r
+ 'wgDBuser',\r
+ 'wgDBpassword',\r
+ 'wgDBmwschema',\r
+ );\r
+\r
+ /**\r
+ * Get the DB2 database extension name\r
+ * @return string\r
+ */\r
+ public function getName(){\r
+ return 'ibm_db2';\r
+ }\r
+\r
+ /**\r
+ * Determine whether the DB2 database extension is currently available in PHP\r
+ * @return boolean\r
+ */\r
+ public function isCompiled() {\r
+ return self::checkExtension( 'ibm_db2' );\r
+ }\r
+\r
+ /**\r
+ * Generate a connection form for a DB2 database\r
+ * @return string\r
+ */\r
+ public function getConnectForm() {\r
+ return\r
+ $this->getTextBox( 'wgDBserver', 'config-db-host', array(), $this->parent->getHelpBox( 'config-db-host-help' ) ) .\r
+ $this->getTextBox( 'wgDBport', 'config-db-port', array(), $this->parent->getHelpBox( 'config-db-port' ) ) .\r
+ Html::openElement( 'fieldset' ) .\r
+ Html::element( 'legend', array(), wfMsg( 'config-db-wiki-settings' ) ) .\r
+ $this->getTextBox( 'wgDBname', 'config-db-name', array(), $this->parent->getHelpBox( 'config-db-name-help' ) ) .\r
+ $this->getTextBox( 'wgDBmwschema', 'config-db-schema', array(), $this->parent->getHelpBox( 'config-db-schema-help' ) ) .\r
+ Html::closeElement( 'fieldset' ) .\r
+ $this->getInstallUserBox();\r
+ }\r
+\r
+ /**\r
+ * Validate and then execute the connection form for a DB2 database\r
+ * @return Status\r
+ */\r
+ public function submitConnectForm() {\r
+ // Get variables from the request\r
+ $newValues = $this->setVarsFromRequest( \r
+ array( 'wgDBserver', 'wgDBport', 'wgDBname', \r
+ 'wgDBmwschema', 'wgDBuser', 'wgDBpassword' ) );\r
+\r
+ // Validate them\r
+ $status = Status::newGood();\r
+ if ( !strlen( $newValues['wgDBname'] ) ) {\r
+ $status->fatal( 'config-missing-db-name' );\r
+ } elseif ( !preg_match( '/^[a-zA-Z0-9_]+$/', $newValues['wgDBname'] ) ) {\r
+ $status->fatal( 'config-invalid-db-name', $newValues['wgDBname'] );\r
+ }\r
+ if ( !strlen( $newValues['wgDBmwschema'] ) ) {\r
+ $status->fatal( 'config-invalid-schema' );\r
+ }\r
+ elseif ( !preg_match( '/^[a-zA-Z0-9_]*$/', $newValues['wgDBmwschema'] ) ) {\r
+ $status->fatal( 'config-invalid-schema', $newValues['wgDBmwschema'] );\r
+ }\r
+ if ( !strlen( $newValues['wgDBport'] ) ) {\r
+ $status->fatal( 'config-invalid-port' );\r
+ }\r
+ elseif ( !preg_match( '/^[0-9_]*$/', $newValues['wgDBport'] ) ) {\r
+ $status->fatal( 'config-invalid-port', $newValues['wgDBport'] );\r
+ }\r
+\r
+ // Submit user box\r
+ if ( $status->isOK() ) {\r
+ $status->merge( $this->submitInstallUserBox() );\r
+ }\r
+ if ( !$status->isOK() ) {\r
+ return $status;\r
+ }\r
+\r
+ global $wgDBport;\r
+ $wgDBport = $newValues['wgDBport'];\r
+\r
+ // Try to connect\r
+ $status->merge( $this->getConnection() );\r
+ if ( !$status->isOK() ) {\r
+ return $status;\r
+ }\r
+\r
+ $this->parent->setVar( 'wgDBuser', $this->getVar( '_InstallUser' ) );\r
+ $this->parent->setVar( 'wgDBpassword', $this->getVar( '_InstallPassword' ) );\r
+\r
+ return $status;\r
+ \r
+ }\r
+\r
+ /**\r
+ * Open a DB2 database connection\r
+ * @return Status\r
+ */\r
+ public function openConnection() {\r
+ $status = Status::newGood();\r
+ try {\r
+ $db = new DatabaseIbm_db2(\r
+ $this->getVar( 'wgDBserver' ),\r
+ $this->getVar( '_InstallUser' ),\r
+ $this->getVar( '_InstallPassword' ),\r
+ $this->getVar( 'wgDBname' ),\r
+ 0,\r
+ $this->getVar( 'wgDBmwschema' )\r
+ );\r
+ $status->value = $db;\r
+ } catch ( DBConnectionError $e ) {\r
+ $status->fatal( 'config-connection-error', $e->getMessage() );\r
+ }\r
+ return $status;\r
+ }\r
+\r
+ /**\r
+ * Create a DB2 database for MediaWiki\r
+ * @return Status\r
+ */\r
+ public function setupDatabase() {\r
+ $status = $this->getConnection();\r
+ if ( !$status->isOK() ) {\r
+ return $status;\r
+ }\r
+ $conn = $status->value;\r
+ $dbName = $this->getVar( 'wgDBname' );\r
+ if( !$conn->selectDB( $dbName ) ) {\r
+ $conn->query( "CREATE DATABASE "\r
+ . $conn->addIdentifierQuotes( $dbName ) \r
+ . " AUTOMATIC STORAGE YES"\r
+ . " USING CODESET UTF-8 TERRITORY US COLLATE USING SYSTEM"\r
+ . " PAGESIZE 32768", __METHOD__ );\r
+ $conn->selectDB( $dbName );\r
+ }\r
+ $this->setupSchemaVars();\r
+ return $status;\r
+ }\r
+\r
+ /**\r
+ * Create tables from scratch.\r
+ * First check if pagesize >= 32k.\r
+ *\r
+ * @return Status\r
+ */\r
+ public function createTables() {\r
+ $status = $this->getConnection();\r
+ if ( !$status->isOK() ) {\r
+ return $status;\r
+ }\r
+ $this->db->selectDB( $this->getVar( 'wgDBname' ) );\r
+\r
+ if( $this->db->tableExists( 'user' ) ) {\r
+ $status->warning( 'config-install-tables-exist' );\r
+ return $status;\r
+ }\r
+\r
+ /* Check for pagesize */\r
+ $status = $this->checkPageSize();\r
+ if ( !$status->isOK() ) {\r
+ return $status;\r
+ }\r
+\r
+ $this->db->setFlag( DBO_DDLMODE ); // For Oracle's handling of schema files\r
+ $this->db->begin( __METHOD__ );\r
+\r
+ $error = $this->db->sourceFile( $this->db->getSchema() );\r
+ if( $error !== true ) {\r
+ $this->db->reportQueryError( $error, 0, '', __METHOD__ );\r
+ $this->db->rollback( __METHOD__ );\r
+ $status->fatal( 'config-install-tables-failed', $error );\r
+ } else {\r
+ $this->db->commit( __METHOD__ );\r
+ }\r
+ // Resume normal operations\r
+ if( $status->isOk() ) {\r
+ $this->enableLB();\r
+ }\r
+ return $status;\r
+ }\r
+\r
+ /**\r
+ * Check if database has a tablspace with pagesize >= 32k.\r
+ *\r
+ * @return Status\r
+ */\r
+ public function checkPageSize() {\r
+ $status = $this->getConnection();\r
+ if ( !$status->isOK() ) {\r
+ return $status;\r
+ }\r
+ $this->db->selectDB( $this->getVar( 'wgDBname' ) );\r
+\r
+ try {\r
+ $result = $this->db->query( 'SELECT PAGESIZE FROM SYSCAT.TABLESPACES' );\r
+ if( $result == false ) {\r
+ $status->fatal( 'config-connection-error', '' );\r
+ }\r
+ else {\r
+ $nRows = $this->db->numRows( $result );\r
+ while ( $row = $row = $this->db->fetchRow( $result ) ) {\r
+ if( $row[0] >= 32768 ) {\r
+ return $status;\r
+ }\r
+ }\r
+ $status->fatal( 'config-ibm_db2-low-db-pagesize', '' );\r
+ }\r
+ } catch ( DBUnexpectedError $e ) {\r
+ $status->fatal( 'config-connection-error', $e->getMessage() );\r
+ }\r
+\r
+ return $status;\r
+ }\r
+\r
+ /**\r
+ * Generate the code to store the DB2-specific settings defined by the configuration form\r
+ * @return string\r
+ */\r
+ public function getLocalSettings() {\r
+ $schema = LocalSettingsGenerator::escapePhpString( $this->getVar( 'wgDBmwschema' ) );\r
+ $port = LocalSettingsGenerator::escapePhpString( $this->getVar( 'wgDBport' ) );\r
+ return\r
+"# IBM_DB2 specific settings\r
+\$wgDBmwschema = \"{$schema}\";\r
+\$wgDBport = \"{$port}\";";\r
+ }\r
+\r
+ public function __construct($parent) {\r
+ parent::__construct($parent);\r
+ }\r
+}\r
+?>\r
--- /dev/null
+<?php\r
+/**\r
+ * IBM_DB2-specific updater.\r
+ *\r
+ * @file\r
+ * @ingroup Deployment\r
+ */\r
+\r
+/**\r
+ * Class for handling updates to IBM_DB2 databases.\r
+ *\r
+ * @ingroup Deployment\r
+ * @since 1.17\r
+ */\r
+class Ibm_db2Updater extends DatabaseUpdater {\r
+\r
+ /**\r
+ * Get the changes in the DB2 database scheme since MediaWiki 1.14\r
+ * @return array \r
+ */\r
+ protected function getCoreUpdateList() {\r
+ return array(\r
+ // 1.14\r
+ array( 'addField', 'site_stats', 'ss_active_users', 'patch-ss_active_users.sql' ),\r
+ array( 'addField', 'ipblocks', 'ipb_allow_usertalk', 'patch-ipb_allow_usertalk.sql' ),\r
+ \r
+ // 1.15\r
+ array( 'addTable', 'change_tag', 'patch-change_tag.sql' ),\r
+ array( 'addTable', 'tag_summary', 'patch-change_tag_summary.sql' ),\r
+ array( 'addTable', 'valid_tag', 'patch-change_valid_tag.sql' ),\r
+ \r
+ // 1.16\r
+ array( 'addTable', 'user_properties', 'patch-user_properties.sql' ),\r
+ array( 'addTable', 'log_search', 'patch-log_search.sql' ),\r
+ array( 'addField', 'logging', 'log_user_text', 'patch-log_user_text.sql' ),\r
+ array( 'addTable', 'l10n_cache', 'patch-l10n_cache.sql' ),\r
+ array( 'addTable', 'external_user', 'patch-external_user.sql' ),\r
+ array( 'addIndex', 'log_search', 'ls_field_val', 'patch-log_search-rename-index.sql' ),\r
+ array( 'addIndex', 'change_tag', 'change_tag_rc_tag', 'patch-change_tag-indexes.sql' ),\r
+ array( 'addField', 'redirect', 'rd_interwiki', 'patch-rd_interwiki.sql' ),\r
+ \r
+ // 1.17\r
+ array( 'addTable', 'iwlinks', 'patch-iwlinks.sql' ),\r
+ array( 'addField', 'updatelog', 'ul_value', 'patch-ul_value.sql' ),\r
+ array( 'addField', 'interwiki', 'iw_api', 'patch-iw_api_and_wikiid.sql' ),\r
+ array( 'addField', 'categorylinks', 'cl_collation', 'patch-categorylinks-better-collation.sql' ),\r
+ array( 'addTable', 'msg_resource', 'patch-msg_resource.sql' ),\r
+ array( 'addTable', 'module_deps', 'patch-module_deps.sql' ),\r
+\r
+ // Tables\r
+ array( 'addTable', 'iwlinks', 'patch-iwlinks.sql' ),\r
+ array( 'addTable', 'msg_resource_links', 'patch-msg_resource_links.sql' ),\r
+ array( 'addTable', 'msg_resource', 'patch-msg_resource.sql' ),\r
+ array( 'addTable', 'module_deps', 'patch-module_deps.sql' ),\r
+ \r
+ // Indexes\r
+ array( 'addIndex', 'msg_resource_links', 'uq61_msg_resource_links', 'patch-uq_61_msg_resource_links.sql' ),\r
+ array( 'addIndex', 'msg_resource', 'uq81_msg_resource', 'patch-uq_81_msg_resource.sql' ),\r
+ array( 'addIndex', 'module_deps', 'uq96_module_deps', 'patch-uq_96_module_deps.sql' ),\r
+ \r
+ // Fields\r
+ array( 'addField', 'categorylinks', 'cl_sortkey_prefix', 'patch-cl_sortkey_prefix-field.sql' ),\r
+ array( 'addField', 'categorylinks', 'cl_collation', 'patch-cl_collation-field.sql' ),\r
+ array( 'addField', 'categorylinks', 'cl_type', 'patch-cl_type-field.sql' ),\r
+ array( 'addField', 'interwiki', 'iw_api', 'patch-iw_api-field.sql' ),\r
+ array( 'addField', 'interwiki', 'iw_wikiid', 'patch-iw_wikiid-field.sql' )\r
+ );\r
+ }\r
+}\r
+?>\r
'config-type-postgres' => 'PostgreSQL',
'config-type-sqlite' => 'SQLite',
'config-type-oracle' => 'Oracle',
+ 'config-type-ibm_db2' => 'IBM DB2',
'config-support-info' => 'MediaWiki supports the following database systems:
$1
'config-support-postgres' => '* $1 is a popular open source database system as an alternative to MySQL ([http://www.php.net/manual/en/pgsql.installation.php how to compile PHP with PostgreSQL support]). There may be some minor outstanding bugs, and it is not recommended for use in a production environment.',
'config-support-sqlite' => '* $1 is a lightweight database system which is very well supported. ([http://www.php.net/manual/en/pdo.installation.php How to compile PHP with SQLite support], uses PDO)',
'config-support-oracle' => '* $1 is a commercial enterprise database. ([http://www.php.net/manual/en/oci8.installation.php How to compile PHP with OCI8 support])',
+ 'config-support-ibm_db2' => '* $1 is a commercial enterprise database.',
'config-header-mysql' => 'MySQL settings',
'config-header-postgres' => 'PostgreSQL settings',
'config-header-sqlite' => 'SQLite settings',
'config-header-oracle' => 'Oracle settings',
+ 'config-header-ibm_db2' => 'IBM DB2 settings',
'config-invalid-db-type' => 'Invalid database type',
'config-missing-db-name' => 'You must enter a value for "Database name"',
'config-missing-db-host' => 'You must enter a value for "Database host"',
This is more efficient than MySQL's UTF-8 mode, and allows you to use the full range of Unicode characters.
In '''UTF-8 mode''', MySQL will know what character set your data is in, and can present and convert it appropriately, but it will not let you store characters above the [http://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes Basic Multilingual Plane].",
+
+ 'config-ibm_db2-low-db-pagesize' => 'There must be a tableblespace with at least 32k of pagesize.',
+
'config-site-name' => 'Name of wiki:',
'config-site-name-help' => "This will appear in the title bar of the browser and in various other places.",
'config-site-name-blank' => 'Enter a site name.',
'postgres',
'oracle',
'sqlite',
+ 'ibm_db2',
);
/**
--- /dev/null
+--\r
+-- patch-categorylinks-better-collation.sql\r
+--\r
+--\r
+-- Track category inclusions *used inline*\r
+-- This tracks a single level of category membership\r
+-- (folksonomic tagging, really).\r
+--\r
+CREATE TABLE categorylinks (\r
+ cl_from BIGINT NOT NULL DEFAULT 0,\r
+ -- REFERENCES page(page_id) ON DELETE CASCADE,\r
+ cl_to VARCHAR(255) NOT NULL,\r
+ -- cl_sortkey has to be at least 86 wide \r
+ -- in order to be compatible with the old MySQL schema from MW 1.10\r
+ --cl_sortkey VARCHAR(86),\r
+ cl_sortkey VARCHAR(230) FOR BIT DATA NOT NULL ,\r
+ cl_sortkey_prefix VARCHAR(255) FOR BIT DATA NOT NULL ,\r
+ cl_timestamp TIMESTAMP(3) NOT NULL,\r
+ cl_collation VARCHAR(32) FOR BIT DATA NOT NULL ,\r
+ cl_type VARCHAR(6) FOR BIT DATA NOT NULL\r
+);\r
--- /dev/null
+CREATE UNIQUE INDEX change_tag_rc_tag ON change_tag (ct_rc_id,ct_tag);\r
+CREATE UNIQUE INDEX change_tag_log_tag ON change_tag (ct_log_id,ct_tag);\r
+CREATE UNIQUE INDEX change_tag_rev_tag ON change_tag (ct_rev_id,ct_tag);\r
+-- Covering index, so we can pull all the info only out of the index.\r
+CREATE INDEX change_tag_tag_id ON change_tag (ct_tag,ct_rc_id,ct_rev_id,ct_log_id);\r
--- /dev/null
+-- A table to track tags for revisions, logs and recent changes.\r
+CREATE TABLE change_tag (\r
+ ct_rc_id INTEGER,\r
+ ct_log_id INTEGER,\r
+ ct_rev_id INTEGER,\r
+ ct_tag varchar(255) NOT NULL,\r
+ ct_params CLOB(64K) INLINE LENGTH 4096\r
+);\r
--- /dev/null
+-- Rollup table to pull a LIST of tags simply\r
+CREATE TABLE tag_summary (\r
+ ts_rc_id INTEGER,\r
+ ts_log_id INTEGER,\r
+ ts_rev_id INTEGER,\r
+ ts_tags CLOB(64K) INLINE LENGTH 4096 NOT NULL\r
+);\r
--- /dev/null
+CREATE TABLE valid_tag (\r
+ vt_tag varchar(255) NOT NULL PRIMARY KEY\r
+);\r
--- /dev/null
+ALTER TABLE categorylinks ADD cl_collation VARCHAR(32) FOR BIT DATA NOT NULL\r
--- /dev/null
+ALTER TABLE categorylinks ADD cl_sortkey_prefix VARCHAR(255) FOR BIT DATA NOT NULL\r
--- /dev/null
+ALTER TABLE categorylinks ADD cl_type VARCHAR(6) FOR BIT DATA NOT NULL\r
--- /dev/null
+CREATE TABLE external_user (\r
+ -- Foreign key to user_id\r
+ eu_local_id BIGINT NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (START WITH 1),\r
+\r
+ -- Some opaque identifier provided by the external database\r
+ eu_external_id VARCHAR(255) NOT NULL\r
+);\r
--- /dev/null
+CREATE TABLE ipblocks (\r
+ ipb_id INTEGER NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (START WITH 1),\r
+ --DEFAULT nextval('ipblocks_ipb_id_val'),\r
+ ipb_address VARCHAR(1024),\r
+ ipb_user BIGINT NOT NULL DEFAULT 0,\r
+ -- REFERENCES user(user_id) ON DELETE SET NULL,\r
+ ipb_by BIGINT NOT NULL DEFAULT 0,\r
+ -- REFERENCES user(user_id) ON DELETE CASCADE,\r
+ ipb_by_text VARCHAR(255) NOT NULL DEFAULT '',\r
+ ipb_reason VARCHAR(1024) NOT NULL,\r
+ ipb_timestamp TIMESTAMP(3) NOT NULL,\r
+ ipb_auto SMALLINT NOT NULL DEFAULT 0,\r
+ ipb_anon_only SMALLINT NOT NULL DEFAULT 0,\r
+ ipb_create_account SMALLINT NOT NULL DEFAULT 1,\r
+ ipb_enable_autoblock SMALLINT NOT NULL DEFAULT 1,\r
+ ipb_expiry TIMESTAMP(3) NOT NULL,\r
+ ipb_range_start VARCHAR(1024),\r
+ ipb_range_end VARCHAR(1024),\r
+ ipb_deleted SMALLINT NOT NULL DEFAULT 0,\r
+ ipb_block_email SMALLINT NOT NULL DEFAULT 0,\r
+ ipb_allow_usertalk SMALLINT NOT NULL DEFAULT 0\r
+\r
+);\r
--- /dev/null
+ALTER TABLE interwiki ADD iw_api CLOB(64K) INLINE LENGTH 4096 NOT NULL\r
--- /dev/null
+CREATE TABLE interwiki (\r
+ iw_prefix VARCHAR(32) NOT NULL UNIQUE,\r
+ iw_url CLOB(64K) INLINE LENGTH 4096 NOT NULL,\r
+ iw_api CLOB(64K) INLINE LENGTH 4096 NOT NULL,\r
+ iw_wikiid varchar(64) NOT NULL,\r
+ iw_local SMALLINT NOT NULL,\r
+ iw_trans SMALLINT NOT NULL DEFAULT 0\r
+);\r
--- /dev/null
+ALTER TABLE interwiki ADD iw_wikiid varchar(64) NOT NULL\r
--- /dev/null
+CREATE TABLE "IWLINKS"\r
+(\r
+"IWL_FROM" INT NOT NULL ,\r
+"IWL_PREFIX" VARCHAR(20) FOR BIT DATA NOT NULL ,\r
+"IWL_TITLE" VARCHAR(255) FOR BIT DATA NOT NULL\r
+)\r
+;\r
--- /dev/null
+CREATE TABLE l10n_cache (\r
+ -- Language code\r
+ lc_lang VARCHAR(32) NOT NULL,\r
+ -- Cache key\r
+ lc_key VARCHAR(255) NOT NULL,\r
+ -- Value\r
+ lc_value CLOB(16M) INLINE LENGTH 4096 NOT NULL\r
+);\r
--- /dev/null
+CREATE TABLE log_search (\r
+ -- The type of ID (rev ID, log ID, rev TIMESTAMP(3), username)\r
+ ls_field VARCHAR(32) FOR BIT DATA NOT NULL,\r
+ -- The value of the ID\r
+ ls_value varchar(255) NOT NULL,\r
+ -- Key to log_id\r
+ ls_log_id BIGINT NOT NULL default 0\r
+);\r
--- /dev/null
+CREATE TABLE log_search (\r
+ -- The type of ID (rev ID, log ID, rev TIMESTAMP(3), username)\r
+ ls_field VARCHAR(32) FOR BIT DATA NOT NULL,\r
+ -- The value of the ID\r
+ ls_value varchar(255) NOT NULL,\r
+ -- Key to log_id\r
+ ls_log_id BIGINT NOT NULL default 0\r
+);\r
--- /dev/null
+CREATE TABLE logging (\r
+ log_id BIGINT NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (START WITH 1),\r
+ --PRIMARY KEY DEFAULT nextval('log_log_id_seq'),\r
+ log_type VARCHAR(32) NOT NULL,\r
+ log_action VARCHAR(32) NOT NULL,\r
+ log_timestamp TIMESTAMP(3) NOT NULL,\r
+ log_user BIGINT NOT NULL DEFAULT 0,\r
+ -- REFERENCES user(user_id) ON DELETE SET NULL,\r
+ -- Name of the user who performed this action\r
+ log_user_text VARCHAR(255) NOT NULL default '',\r
+ log_namespace SMALLINT NOT NULL,\r
+ log_title VARCHAR(255) NOT NULL,\r
+ log_page BIGINT,\r
+ log_comment VARCHAR(255),\r
+ log_params CLOB(64K) INLINE LENGTH 4096,\r
+ log_deleted SMALLINT NOT NULL DEFAULT 0\r
+);\r
--- /dev/null
+CREATE TABLE "MODULE_DEPS" (\r
+"MD_MODULE" VARCHAR(255) FOR BIT DATA NOT NULL ,\r
+"MD_SKIN" VARCHAR(32) FOR BIT DATA NOT NULL ,\r
+"MD_DEPS" CLOB(16M) INLINE LENGTH 4096 NOT NULL\r
+)\r
+;\r
--- /dev/null
+CREATE TABLE "MSG_RESOURCE"\r
+(\r
+"MR_RESOURCE" VARCHAR(255) FOR BIT DATA NOT NULL ,\r
+"MR_LANG" VARCHAR(32) FOR BIT DATA NOT NULL ,\r
+"MR_BLOB" BLOB NOT NULL ,\r
+"MR_TIMESTAMP" TIMESTAMP(3) NOT NULL\r
+)\r
+;\r
--- /dev/null
+CREATE TABLE "MSG_RESOURCE_LINKS"\r
+(\r
+"MRL_RESOURCE" VARCHAR(255) FOR BIT DATA NOT NULL ,\r
+"MRL_MESSAGE" VARCHAR(255) FOR BIT DATA NOT NULL\r
+)\r
+;\r
--- /dev/null
+CREATE TABLE redirect (\r
+ rd_from BIGINT NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (START WITH 1),\r
+ --REFERENCES page(page_id) ON DELETE CASCADE,\r
+ rd_namespace SMALLINT NOT NULL DEFAULT 0,\r
+ rd_title VARCHAR(255) NOT NULL DEFAULT '',\r
+ rd_interwiki varchar(32),\r
+ rd_fragment VARCHAR(255)\r
+);\r
--- /dev/null
+CREATE TABLE site_stats (\r
+ ss_row_id BIGINT NOT NULL UNIQUE,\r
+ ss_total_views BIGINT DEFAULT 0,\r
+ ss_total_edits BIGINT DEFAULT 0,\r
+ ss_good_articles BIGINT DEFAULT 0,\r
+ ss_total_pages INTEGER DEFAULT -1,\r
+ ss_users INTEGER DEFAULT -1,\r
+ ss_active_users INTEGER DEFAULT -1,\r
+ ss_admins INTEGER DEFAULT -1,\r
+ ss_images INTEGER DEFAULT 0\r
+);\r
--- /dev/null
+CREATE TABLE updatelog (\r
+ ul_key VARCHAR(255) NOT NULL PRIMARY KEY\r
+);\r
--- /dev/null
+CREATE UNIQUE INDEX "UQ61_MSG_RESOURCE_LINKS" ON "MSG_RESOURCE_LINKS"\r
+(\r
+"MRL_MESSAGE",\r
+"MRL_RESOURCE"\r
+)\r
+ALLOW REVERSE SCANS\r
+;\r
--- /dev/null
+CREATE UNIQUE INDEX "UQ81_MSG_RESOURCE" ON "MSG_RESOURCE"\r
+(\r
+"MR_RESOURCE"\r
+,"MR_LANG"\r
+)\r
+ALLOW REVERSE SCANS\r
+;\r
--- /dev/null
+CREATE UNIQUE INDEX "UQ96_MODULE_DEPS" ON "MODULE_DEPS"\r
+(\r
+"MD_MODULE"\r
+,"MD_SKIN"\r
+)\r
+ALLOW REVERSE SCANS\r
+;\r
--- /dev/null
+CREATE TABLE user_properties (\r
+ -- Foreign key to user.user_id\r
+ up_user BIGINT NOT NULL,\r
+ \r
+ -- Name of the option being saved. This is indexed for bulk lookup.\r
+ up_property VARCHAR(32) FOR BIT DATA NOT NULL,\r
+ \r
+ -- Property value as a string.\r
+ up_value CLOB(64K) INLINE LENGTH 4096\r
+);\r
CREATE TABLE user (
-- Needs to start with 0
- user_id BIGINT PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (START WITH 0),
+ user_id BIGINT PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (START WITH 0),
user_name VARCHAR(255) NOT NULL UNIQUE,
user_real_name VARCHAR(255),
user_password VARCHAR(1024),
cl_to VARCHAR(255) NOT NULL,
-- cl_sortkey has to be at least 86 wide
-- in order to be compatible with the old MySQL schema from MW 1.10
- cl_sortkey VARCHAR(86),
- cl_timestamp TIMESTAMP(3) NOT NULL
+ --cl_sortkey VARCHAR(86),
+ cl_sortkey VARCHAR(230) FOR BIT DATA NOT NULL ,
+ cl_sortkey_prefix VARCHAR(255) FOR BIT DATA NOT NULL ,
+ cl_timestamp TIMESTAMP(3) NOT NULL,
+ cl_collation VARCHAR(32) FOR BIT DATA NOT NULL ,
+ cl_type VARCHAR(6) FOR BIT DATA NOT NULL
);
CREATE UNIQUE INDEX cl_from ON categorylinks (cl_from, cl_to);
CREATE INDEX cl_sortkey ON categorylinks (cl_to, cl_sortkey, cl_from);
CREATE TABLE interwiki (
iw_prefix VARCHAR(32) NOT NULL UNIQUE,
iw_url CLOB(64K) INLINE LENGTH 4096 NOT NULL,
+ iw_api CLOB(64K) INLINE LENGTH 4096 NOT NULL,
+ iw_wikiid varchar(64) NOT NULL,
iw_local SMALLINT NOT NULL,
iw_trans SMALLINT NOT NULL DEFAULT 0
);
CREATE TABLE objectcache (
keyname VARCHAR(255) NOT NULL UNIQUE, -- was nullable
value CLOB(16M) INLINE LENGTH 4096 NOT NULL DEFAULT '',
- exptime TIMESTAMP(3) NOT NULL
+ exptime TIMESTAMP(3) NOT NULL
);
CREATE INDEX objectcacache_exptime ON objectcache (exptime);
);
CREATE INDEX lc_lang_key ON l10n_cache (lc_lang, lc_key);
+
+CREATE TABLE "MSG_RESOURCE_LINKS"
+(
+"MRL_RESOURCE" VARCHAR(255) FOR BIT DATA NOT NULL ,
+"MRL_MESSAGE" VARCHAR(255) FOR BIT DATA NOT NULL
+)
+;
+
+CREATE UNIQUE INDEX "UQ61_MSG_RESOURCE_LINKS" ON "MSG_RESOURCE_LINKS"
+(
+"MRL_MESSAGE",
+"MRL_RESOURCE"
+)
+ALLOW REVERSE SCANS
+;
+
+CREATE TABLE "MSG_RESOURCE"
+(
+"MR_RESOURCE" VARCHAR(255) FOR BIT DATA NOT NULL ,
+"MR_LANG" VARCHAR(32) FOR BIT DATA NOT NULL ,
+"MR_BLOB" BLOB NOT NULL ,
+"MR_TIMESTAMP" TIMESTAMP(3) NOT NULL
+)
+;
+
+CREATE UNIQUE INDEX "UQ81_MSG_RESOURCE" ON "MSG_RESOURCE"
+(
+"MR_RESOURCE"
+,"MR_LANG"
+)
+ALLOW REVERSE SCANS
+;
+
+CREATE TABLE "MODULE_DEPS" (
+"MD_MODULE" VARCHAR(255) FOR BIT DATA NOT NULL ,
+"MD_SKIN" VARCHAR(32) FOR BIT DATA NOT NULL ,
+"MD_DEPS" CLOB(16M) INLINE LENGTH 4096 NOT NULL
+)
+;
+
+CREATE UNIQUE INDEX "UQ96_MODULE_DEPS" ON "MODULE_DEPS"
+(
+"MD_MODULE"
+,"MD_SKIN"
+)
+ALLOW REVERSE SCANS
+;
+
+CREATE TABLE "IWLINKS"
+(
+"IWL_FROM" INT NOT NULL ,
+"IWL_PREFIX" VARCHAR(20) FOR BIT DATA NOT NULL ,
+"IWL_TITLE" VARCHAR(255) FOR BIT DATA NOT NULL
+)
+;