From 6f4448dd71851c903e1fb0746fa07197e08c12f5 Mon Sep 17 00:00:00 2001 From: Chad Horohoe Date: Mon, 25 Feb 2013 10:55:50 -0800 Subject: [PATCH] Remove DB2 support Change-Id: I9b294a213a4000f503c0010d88757db6dda927c0 --- RELEASE-NOTES-1.21 | 5 +- docs/database.txt | 1 - docs/databases/ibm_db2.txt | 3 - includes/AutoLoader.php | 8 - includes/Defines.php | 1 - includes/GlobalFunctions.php | 5 - includes/Revision.php | 2 +- includes/Timestamp.php | 3 - includes/db/Database.php | 2 +- includes/db/DatabaseIbm_db2.php | 1727 ----------------- includes/installer/Ibm_db2Installer.php | 270 --- includes/installer/Ibm_db2Updater.php | 96 - includes/installer/Installer.i18n.php | 5 - includes/installer/Installer.php | 1 - includes/search/SearchIBM_DB2.php | 234 --- maintenance/ibm_db2/foreignkeys.sql | 102 - .../patch-categorylinks-better-collation.sql | 21 - .../ibm_db2/patch-change_tag-indexes.sql | 5 - maintenance/ibm_db2/patch-change_tag.sql | 8 - .../ibm_db2/patch-change_tag_summary.sql | 7 - .../ibm_db2/patch-change_valid_tag.sql | 3 - .../ibm_db2/patch-cl_collation-field.sql | 1 - .../ibm_db2/patch-cl_sortkey_prefix-field.sql | 1 - maintenance/ibm_db2/patch-cl_type-field.sql | 1 - maintenance/ibm_db2/patch-external_user.sql | 7 - .../ibm_db2/patch-ipb_allow_usertalk.sql | 23 - maintenance/ibm_db2/patch-iw_api-field.sql | 1 - .../ibm_db2/patch-iw_api_and_wikiid.sql | 8 - maintenance/ibm_db2/patch-iw_wikiid-field.sql | 1 - maintenance/ibm_db2/patch-iwlinks.sql | 7 - maintenance/ibm_db2/patch-l10n_cache.sql | 8 - .../ibm_db2/patch-log_search-rename-index.sql | 8 - maintenance/ibm_db2/patch-log_search.sql | 8 - maintenance/ibm_db2/patch-log_user_text.sql | 17 - maintenance/ibm_db2/patch-module_deps.sql | 6 - maintenance/ibm_db2/patch-msg_resource.sql | 8 - .../ibm_db2/patch-msg_resource_links.sql | 6 - maintenance/ibm_db2/patch-rd_interwiki.sql | 8 - maintenance/ibm_db2/patch-ss_active_users.sql | 11 - maintenance/ibm_db2/patch-ul_value.sql | 3 - .../ibm_db2/patch-uq61_msg_resource_links.sql | 7 - .../ibm_db2/patch-uq81_msg_resource.sql | 7 - .../ibm_db2/patch-uq96_module_deps.sql | 7 - maintenance/ibm_db2/patch-user_properties.sql | 10 - maintenance/ibm_db2/tables.sql | 929 --------- tests/phpunit/includes/TimestampTest.php | 1 - 46 files changed, 5 insertions(+), 3598 deletions(-) delete mode 100644 docs/databases/ibm_db2.txt delete mode 100644 includes/db/DatabaseIbm_db2.php delete mode 100644 includes/installer/Ibm_db2Installer.php delete mode 100644 includes/installer/Ibm_db2Updater.php delete mode 100644 includes/search/SearchIBM_DB2.php delete mode 100644 maintenance/ibm_db2/foreignkeys.sql delete mode 100644 maintenance/ibm_db2/patch-categorylinks-better-collation.sql delete mode 100644 maintenance/ibm_db2/patch-change_tag-indexes.sql delete mode 100644 maintenance/ibm_db2/patch-change_tag.sql delete mode 100644 maintenance/ibm_db2/patch-change_tag_summary.sql delete mode 100644 maintenance/ibm_db2/patch-change_valid_tag.sql delete mode 100644 maintenance/ibm_db2/patch-cl_collation-field.sql delete mode 100644 maintenance/ibm_db2/patch-cl_sortkey_prefix-field.sql delete mode 100644 maintenance/ibm_db2/patch-cl_type-field.sql delete mode 100644 maintenance/ibm_db2/patch-external_user.sql delete mode 100644 maintenance/ibm_db2/patch-ipb_allow_usertalk.sql delete mode 100644 maintenance/ibm_db2/patch-iw_api-field.sql delete mode 100644 maintenance/ibm_db2/patch-iw_api_and_wikiid.sql delete mode 100644 maintenance/ibm_db2/patch-iw_wikiid-field.sql delete mode 100644 maintenance/ibm_db2/patch-iwlinks.sql delete mode 100644 maintenance/ibm_db2/patch-l10n_cache.sql delete mode 100644 maintenance/ibm_db2/patch-log_search-rename-index.sql delete mode 100644 maintenance/ibm_db2/patch-log_search.sql delete mode 100644 maintenance/ibm_db2/patch-log_user_text.sql delete mode 100644 maintenance/ibm_db2/patch-module_deps.sql delete mode 100644 maintenance/ibm_db2/patch-msg_resource.sql delete mode 100644 maintenance/ibm_db2/patch-msg_resource_links.sql delete mode 100644 maintenance/ibm_db2/patch-rd_interwiki.sql delete mode 100644 maintenance/ibm_db2/patch-ss_active_users.sql delete mode 100644 maintenance/ibm_db2/patch-ul_value.sql delete mode 100644 maintenance/ibm_db2/patch-uq61_msg_resource_links.sql delete mode 100644 maintenance/ibm_db2/patch-uq81_msg_resource.sql delete mode 100644 maintenance/ibm_db2/patch-uq96_module_deps.sql delete mode 100644 maintenance/ibm_db2/patch-user_properties.sql delete mode 100644 maintenance/ibm_db2/tables.sql diff --git a/RELEASE-NOTES-1.21 b/RELEASE-NOTES-1.21 index 59199db967..652125e1c3 100644 --- a/RELEASE-NOTES-1.21 +++ b/RELEASE-NOTES-1.21 @@ -260,14 +260,15 @@ changes to languages because of Bugzilla reports. were using it, you have to either copy it to your extension, or install the Vector extension (and possibly disable its features using config settings if you don't want them). +* Experimental IBM DB2 support was removed due to lack of interest and maintainership == Compatibility == MediaWiki 1.21 requires PHP 5.3.2 or later. MySQL is the recommended DBMS. PostgreSQL or SQLite can also be used, but -support for them is somewhat less mature. There is experimental support for IBM -DB2 and Oracle. +support for them is somewhat less mature. There is experimental support for +Oracle. The supported versions are: diff --git a/docs/database.txt b/docs/database.txt index c0a2412ca7..65a597b345 100644 --- a/docs/database.txt +++ b/docs/database.txt @@ -180,7 +180,6 @@ MediaWiki does support the following other DBMSs to varying degrees. * PostgreSQL * SQLite * Oracle -* IBM DB2 * MSSQL More information can be found about each of these databases (known issues, diff --git a/docs/databases/ibm_db2.txt b/docs/databases/ibm_db2.txt deleted file mode 100644 index 3c3f381c8e..0000000000 --- a/docs/databases/ibm_db2.txt +++ /dev/null @@ -1,3 +0,0 @@ -== See also == -*[http://www.mediawiki.org/wiki/Manual:IBM_DB2 Installation instructions] -*[http://ca.php.net/manual/en/function.db2-connect.php PHP Manual for DB2 functions] \ No newline at end of file diff --git a/includes/AutoLoader.php b/includes/AutoLoader.php index e0b7c8fb81..5a760cb4e7 100644 --- a/includes/AutoLoader.php +++ b/includes/AutoLoader.php @@ -473,7 +473,6 @@ $wgAutoloadLocalClasses = array( 'ChronologyProtector' => 'includes/db/LBFactory.php', 'CloneDatabase' => 'includes/db/CloneDatabase.php', 'DatabaseBase' => 'includes/db/Database.php', - 'DatabaseIbm_db2' => 'includes/db/DatabaseIbm_db2.php', 'DatabaseMssql' => 'includes/db/DatabaseMssql.php', 'DatabaseMysql' => 'includes/db/DatabaseMysql.php', 'DatabaseOracle' => 'includes/db/DatabaseOracle.php', @@ -492,10 +491,6 @@ $wgAutoloadLocalClasses = array( 'DBUnexpectedError' => 'includes/db/DatabaseError.php', 'FakeResultWrapper' => 'includes/db/DatabaseUtility.php', 'Field' => 'includes/db/DatabaseUtility.php', - 'IBM_DB2Blob' => 'includes/db/DatabaseIbm_db2.php', - 'IBM_DB2Field' => 'includes/db/DatabaseIbm_db2.php', - 'IBM_DB2Helper' => 'includes/db/DatabaseIbm_db2.php', - 'IBM_DB2Result' => 'includes/db/DatabaseIbm_db2.php', 'LBFactory' => 'includes/db/LBFactory.php', 'LBFactory_Fake' => 'includes/db/LBFactory.php', 'LBFactory_Multi' => 'includes/db/LBFactory_Multi.php', @@ -623,8 +618,6 @@ $wgAutoloadLocalClasses = array( 'CliInstaller' => 'includes/installer/CliInstaller.php', 'DatabaseInstaller' => 'includes/installer/DatabaseInstaller.php', 'DatabaseUpdater' => 'includes/installer/DatabaseUpdater.php', - 'Ibm_db2Installer' => 'includes/installer/Ibm_db2Installer.php', - 'Ibm_db2Updater' => 'includes/installer/Ibm_db2Updater.php', 'InstallDocFormatter' => 'includes/installer/InstallDocFormatter.php', 'Installer' => 'includes/installer/Installer.php', 'LocalSettingsGenerator' => 'includes/installer/LocalSettingsGenerator.php', @@ -867,7 +860,6 @@ $wgAutoloadLocalClasses = array( 'SearchEngine' => 'includes/search/SearchEngine.php', 'SearchEngineDummy' => 'includes/search/SearchEngine.php', 'SearchHighlighter' => 'includes/search/SearchEngine.php', - 'SearchIBM_DB2' => 'includes/search/SearchIBM_DB2.php', 'SearchMssql' => 'includes/search/SearchMssql.php', 'SearchMySQL' => 'includes/search/SearchMySQL.php', 'SearchNearMatchResultSet' => 'includes/search/SearchEngine.php', diff --git a/includes/Defines.php b/includes/Defines.php index 46a3773427..c4b0b472ae 100644 --- a/includes/Defines.php +++ b/includes/Defines.php @@ -200,7 +200,6 @@ define( 'LIST_AND', 1 ); define( 'LIST_SET', 2 ); define( 'LIST_NAMES', 3); define( 'LIST_OR', 4); -define( 'LIST_SET_PREPARED', 8); // List of (?, ?, ?) for DatabaseIbm_db2 /**@}*/ /** diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php index be862e7b57..f677033b35 100644 --- a/includes/GlobalFunctions.php +++ b/includes/GlobalFunctions.php @@ -2430,11 +2430,6 @@ define( 'TS_ORACLE', 6 ); */ define( 'TS_POSTGRES', 7 ); -/** - * DB2 format time - */ -define( 'TS_DB2', 8 ); - /** * ISO 8601 basic format with no timezone: 19860209T200000Z. This is used by ResourceLoader */ diff --git a/includes/Revision.php b/includes/Revision.php index 4bdce87eab..df1e43e94a 100644 --- a/includes/Revision.php +++ b/includes/Revision.php @@ -1587,7 +1587,7 @@ class Revision implements IDBAccessObject { */ static function getTimestampFromId( $title, $id ) { $dbr = wfGetDB( DB_SLAVE ); - // Casting fix for DB2 + // Casting fix for databases that can't take '' for rev_id if ( $id == '' ) { $id = 0; } diff --git a/includes/Timestamp.php b/includes/Timestamp.php index 630ac5357f..3066ca9dff 100644 --- a/includes/Timestamp.php +++ b/includes/Timestamp.php @@ -42,7 +42,6 @@ class MWTimestamp { TS_RFC2822 => 'D, d M Y H:i:s', TS_ORACLE => 'd-m-Y H:i:s.000000', // Was 'd-M-y h.i.s A' . ' +00:00' before r51500 TS_POSTGRES => 'Y-m-d H:i:s', - TS_DB2 => 'Y-m-d H:i:s', ); /** @@ -118,8 +117,6 @@ class MWTimestamp { # TS_POSTGRES } elseif ( preg_match( '/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)\.*\d* GMT$/', $ts, $da ) ) { # TS_POSTGRES - } elseif (preg_match( '/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)\.\d\d\d$/', $ts, $da ) ) { - # TS_DB2 } elseif ( preg_match( '/^[ \t\r\n]*([A-Z][a-z]{2},[ \t\r\n]*)?' . # Day of week '\d\d?[ \t\r\n]*[A-Z][a-z]{2}[ \t\r\n]*\d{2}(?:\d{2})?' . # dd Mon yyyy '[ \t\r\n]*\d\d[ \t\r\n]*:[ \t\r\n]*\d\d[ \t\r\n]*:[ \t\r\n]*\d\d/S', $ts ) ) { # hh:mm:ss diff --git a/includes/db/Database.php b/includes/db/Database.php index 05a0ca0582..ff2f7f7593 100644 --- a/includes/db/Database.php +++ b/includes/db/Database.php @@ -728,7 +728,7 @@ abstract class DatabaseBase implements DatabaseType { */ final public static function factory( $dbType, $p = array() ) { $canonicalDBTypes = array( - 'mysql', 'postgres', 'sqlite', 'oracle', 'mssql', 'ibm_db2' + 'mysql', 'postgres', 'sqlite', 'oracle', 'mssql' ); $dbType = strtolower( $dbType ); $class = 'Database' . ucfirst( $dbType ); diff --git a/includes/db/DatabaseIbm_db2.php b/includes/db/DatabaseIbm_db2.php deleted file mode 100644 index 30bc665107..0000000000 --- a/includes/db/DatabaseIbm_db2.php +++ /dev/null @@ -1,1727 +0,0 @@ -query( - sprintf( $q, - $db->addQuotes( $wgDBmwschema ), - $db->addQuotes( $table ), - $db->addQuotes( $field ) - ) - ); - $row = $db->fetchObject( $res ); - if ( !$row ) { - return null; - } - $n = new IBM_DB2Field; - $n->type = $row->typname; - $n->nullable = ( $row->attnotnull == 'N' ); - $n->name = $field; - $n->tablename = $table; - $n->max_length = $row->attlen; - return $n; - } - /** - * Get column name - * @return string column name - */ - function name() { return $this->name; } - /** - * Get table name - * @return string table name - */ - function tableName() { return $this->tablename; } - /** - * Get column type - * @return string column type - */ - function type() { return $this->type; } - /** - * Can column be null? - * @return bool true or false - */ - function isNullable() { return $this->nullable; } - /** - * How much can you fit in the column per row? - * @return int length - */ - function maxLength() { return $this->max_length; } -} - -/** - * Wrapper around binary large objects - * @ingroup Database - */ -class IBM_DB2Blob { - private $mData; - - public function __construct( $data ) { - $this->mData = $data; - } - - public function getData() { - return $this->mData; - } - - public function __toString() { - return $this->mData; - } -} - -/** - * Wrapper to address lack of certain operations in the DB2 driver - * ( seek, num_rows ) - * @ingroup Database - * @since 1.19 - */ -class IBM_DB2Result{ - private $db; - private $result; - private $num_rows; - private $current_pos; - private $columns = array(); - private $sql; - - private $resultSet = array(); - private $loadedLines = 0; - - /** - * Construct and initialize a wrapper for DB2 query results - * @param $db DatabaseBase - * @param $result Object - * @param $num_rows Integer - * @param $sql String - * @param $columns Array - */ - public function __construct( $db, $result, $num_rows, $sql, $columns ) { - $this->db = $db; - - if( $result instanceof ResultWrapper ) { - $this->result = $result->result; - } else { - $this->result = $result; - } - - $this->num_rows = $num_rows; - $this->current_pos = 0; - if ( $this->num_rows > 0 ) { - // Make a lower-case list of the column names - // By default, DB2 column names are capitalized - // while MySQL column names are lowercase - - // Is there a reasonable maximum value for $i? - // Setting to 2048 to prevent an infinite loop - for( $i = 0; $i < 2048; $i++ ) { - $name = db2_field_name( $this->result, $i ); - if ( $name != false ) { - continue; - } - else { - return false; - } - - $this->columns[$i] = strtolower( $name ); - } - } - - $this->sql = $sql; - } - - /** - * Unwrap the DB2 query results - * @return mixed Object on success, false on failure - */ - public function getResult() { - if ( $this->result ) { - return $this->result; - } - else return false; - } - - /** - * Get the number of rows in the result set - * @return integer - */ - public function getNum_rows() { - return $this->num_rows; - } - - /** - * Return a row from the result set in object format - * @return mixed Object on success, false on failure. - */ - public function fetchObject() { - if ( $this->result - && $this->num_rows > 0 - && $this->current_pos >= 0 - && $this->current_pos < $this->num_rows ) - { - $row = $this->fetchRow(); - $ret = new stdClass(); - - foreach ( $row as $k => $v ) { - $lc = $this->columns[$k]; - $ret->$lc = $v; - } - return $ret; - } - return false; - } - - /** - * Return a row form the result set in array format - * @return mixed Array on success, false on failure - * @throws DBUnexpectedError - */ - public function fetchRow() { - if ( $this->result - && $this->num_rows > 0 - && $this->current_pos >= 0 - && $this->current_pos < $this->num_rows ) - { - if ( $this->loadedLines <= $this->current_pos ) { - $row = db2_fetch_array( $this->result ); - $this->resultSet[$this->loadedLines++] = $row; - if ( $this->db->lastErrno() ) { - throw new DBUnexpectedError( $this->db, 'Error in fetchRow(): ' - . htmlspecialchars( $this->db->lastError() ) ); - } - } - - if ( $this->loadedLines > $this->current_pos ) { - return $this->resultSet[$this->current_pos++]; - } - - } - return false; - } - - /** - * Free a DB2 result object - * @throws DBUnexpectedError - */ - public function freeResult() { - unset( $this->resultSet ); - if ( !@db2_free_result( $this->result ) ) { - throw new DBUnexpectedError( $this, "Unable to free DB2 result\n" ); - } - } -} - -/** - * Primary database interface - * @ingroup Database - */ -class DatabaseIbm_db2 extends DatabaseBase { - /* - * Inherited members - protected $mLastQuery = ''; - protected $mPHPError = false; - - protected $mServer, $mUser, $mPassword, $mConn = null, $mDBname; - protected $mOpened = false; - - protected $mTablePrefix; - protected $mFlags; - protected $mTrxLevel = 0; - protected $mErrorCount = 0; - protected $mLBInfo = array(); - protected $mFakeSlaveLag = null, $mFakeMaster = false; - * - */ - - /** Database server port */ - protected $mPort = null; - /** Schema for tables, stored procedures, triggers */ - protected $mSchema = null; - /** Whether the schema has been applied in this session */ - protected $mSchemaSet = false; - /** Result of last query */ - protected $mLastResult = null; - /** Number of rows affected by last INSERT/UPDATE/DELETE */ - protected $mAffectedRows = null; - /** Number of rows returned by last SELECT */ - protected $mNumRows = null; - /** Current row number on the cursor of the last SELECT */ - protected $currentRow = 0; - - /** Connection config options - see constructor */ - public $mConnOptions = array(); - /** Statement config options -- see constructor */ - public $mStmtOptions = array(); - - /** Default schema */ - const USE_GLOBAL = 'get from global'; - - /** Option that applies to nothing */ - const NONE_OPTION = 0x00; - /** Option that applies to connection objects */ - const CONN_OPTION = 0x01; - /** Option that applies to statement objects */ - const STMT_OPTION = 0x02; - - /** Regular operation mode -- minimal debug messages */ - const REGULAR_MODE = 'regular'; - /** Installation mode -- lots of debug messages */ - const INSTALL_MODE = 'install'; - - /** Controls the level of debug message output */ - protected $mMode = self::REGULAR_MODE; - - /** Last sequence value used for a primary key */ - protected $mInsertId = null; - - ###################################### - # Getters and Setters - ###################################### - - /** - * Returns true if this database supports (and uses) cascading deletes - * @return bool - */ - function cascadingDeletes() { - return true; - } - - /** - * Returns true if this database supports (and uses) triggers (e.g. on the - * page table) - * @return bool - */ - function cleanupTriggers() { - return true; - } - - /** - * Returns true if this database is strict about what can be put into an - * IP field. - * Specifically, it uses a NULL value instead of an empty string. - * @return bool - */ - function strictIPs() { - return true; - } - - /** - * Returns true if this database uses timestamps rather than integers - * @return bool - */ - function realTimestamps() { - return true; - } - - /** - * Returns true if this database does an implicit sort when doing GROUP BY - * @return bool - */ - function implicitGroupby() { - return false; - } - - /** - * Returns true if this database does an implicit order by when the column - * has an index - * For example: SELECT page_title FROM page LIMIT 1 - * @return bool - */ - function implicitOrderby() { - return false; - } - - /** - * Returns true if this database can do a native search on IP columns - * e.g. this works as expected: .. WHERE rc_ip = '127.42.12.102/32'; - * @return bool - */ - function searchableIPs() { - return true; - } - - /** - * Returns true if this database can use functional indexes - * @return bool - */ - function functionalIndexes() { - return true; - } - - /** - * Returns a unique string representing the wiki on the server - * @return string - */ - public function getWikiID() { - if( $this->mSchema ) { - return "{$this->mDBname}-{$this->mSchema}"; - } else { - return $this->mDBname; - } - } - - /** - * Returns the database software identifieir - * @return string - */ - public function getType() { - return 'ibm_db2'; - } - - /** - * Returns the database connection object - * @return Object - */ - public function getDb() { - return $this->mConn; - } - - /** - * - * @param $server String: hostname of database server - * @param $user String: username - * @param $password String: password - * @param $dbName String: database name on the server - * @param $flags Integer: database behaviour flags (optional, unused) - * @param $schema String - */ - public function __construct( $server = false, $user = false, - $password = false, - $dbName = false, $flags = 0, - $schema = self::USE_GLOBAL ) - { - global $wgDBmwschema; - - if ( $schema == self::USE_GLOBAL ) { - $this->mSchema = $wgDBmwschema; - } else { - $this->mSchema = $schema; - } - - // configure the connection and statement objects - $this->setDB2Option( 'db2_attr_case', 'DB2_CASE_LOWER', - self::CONN_OPTION | self::STMT_OPTION ); - $this->setDB2Option( 'deferred_prepare', 'DB2_DEFERRED_PREPARE_ON', - self::STMT_OPTION ); - $this->setDB2Option( 'rowcount', 'DB2_ROWCOUNT_PREFETCH_ON', - self::STMT_OPTION ); - parent::__construct( $server, $user, $password, $dbName, DBO_TRX | $flags ); - } - - /** - * Enables options only if the ibm_db2 extension version supports them - * @param $name String: name of the option in the options array - * @param $const String: name of the constant holding the right option value - * @param $type Integer: whether this is a Connection or Statement otion - */ - private function setDB2Option( $name, $const, $type ) { - if ( defined( $const ) ) { - if ( $type & self::CONN_OPTION ) { - $this->mConnOptions[$name] = constant( $const ); - } - if ( $type & self::STMT_OPTION ) { - $this->mStmtOptions[$name] = constant( $const ); - } - } else { - $this->installPrint( - "$const is not defined. ibm_db2 version is likely too low." ); - } - } - - /** - * Outputs debug information in the appropriate place - * @param $string String: the relevant debug message - */ - private function installPrint( $string ) { - wfDebug( "$string\n" ); - if ( $this->mMode == self::INSTALL_MODE ) { - print "
  • $string
  • "; - flush(); - } - } - - /** - * Opens a database connection and returns it - * Closes any existing connection - * - * @param $server String: hostname - * @param $user String - * @param $password String - * @param $dbName String: database name - * @throws DBConnectionError - * @return DatabaseBase a fresh connection - */ - public function open( $server, $user, $password, $dbName ) { - wfProfileIn( __METHOD__ ); - - # Load IBM DB2 driver if missing - wfDl( 'ibm_db2' ); - - # Test for IBM DB2 support, to avoid suppressed fatal error - if ( !function_exists( 'db2_connect' ) ) { - throw new DBConnectionError( $this, "DB2 functions missing, have you enabled the ibm_db2 extension for PHP?" ); - } - - global $wgDBport; - - // Close existing connection - $this->close(); - // Cache conn info - $this->mServer = $server; - $this->mPort = $port = $wgDBport; - $this->mUser = $user; - $this->mPassword = $password; - $this->mDBname = $dbName; - - $this->openUncataloged( $dbName, $user, $password, $server, $port ); - - 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__ ); - 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() ); - } - - // 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(); - - wfProfileOut( __METHOD__ ); - return $this->mConn; - } - - /** - * Opens a cataloged database connection, sets mConn - */ - protected function openCataloged( $dbName, $user, $password ) { - wfSuppressWarnings(); - $this->mConn = db2_pconnect( $dbName, $user, $password ); - wfRestoreWarnings(); - } - - /** - * Opens an uncataloged database connection, sets mConn - */ - protected function openUncataloged( $dbName, $user, $password, $server, $port ) - { - $dsn = "DRIVER={IBM DB2 ODBC DRIVER};DATABASE=$dbName;CHARSET=UTF-8;HOSTNAME=$server;PORT=$port;PROTOCOL=TCPIP;UID=$user;PWD=$password;"; - wfSuppressWarnings(); - $this->mConn = db2_pconnect( $dsn, "", "", array() ); - wfRestoreWarnings(); - } - - /** - * Closes a database connection, if it is open - * Returns success, true if already closed - * @return bool - */ - protected function closeConnection() { - return db2_close( $this->mConn ); - } - - /** - * Retrieves the most current database error - * Forces a database rollback - * @return bool|string - */ - public function lastError() { - $connerr = db2_conn_errormsg(); - if ( $connerr ) { - //$this->rollback( __METHOD__ ); - return $connerr; - } - $stmterr = db2_stmt_errormsg(); - if ( $stmterr ) { - //$this->rollback( __METHOD__ ); - return $stmterr; - } - - return false; - } - - /** - * Get the last error number - * Return 0 if no error - * @return integer - */ - public function lastErrno() { - $connerr = db2_conn_error(); - if ( $connerr ) { - return $connerr; - } - $stmterr = db2_stmt_error(); - if ( $stmterr ) { - return $stmterr; - } - return 0; - } - - /** - * Is a database connection open? - * @return - */ - public function isOpen() { return $this->mOpened; } - - /** - * The DBMS-dependent part of query() - * @param $sql String: SQL query. - * @throws DBUnexpectedError - * @return object Result object for fetch functions or false on failure - */ - protected 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 ) { - $error = db2_stmt_errormsg(); - - $this->installPrint( "
    $sql
    " ); - $this->installPrint( $error ); - throw new DBUnexpectedError( $this, 'SQL error: ' - . htmlspecialchars( $error ) ); - } - $this->mLastResult = $ret; - $this->mAffectedRows = null; // Not calculated until asked for - return $ret; - } - - /** - * @return string Version information from the database - */ - public function getServerVersion() { - $info = db2_server_info( $this->mConn ); - return $info->DBMS_VER; - } - - /** - * Queries whether a given table exists - * @return boolean - */ - public function tableExists( $table, $fname = __METHOD__ ) { - $schema = $this->mSchema; - - $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 the table exists, there should be one of it - $row = $this->fetchRow( $res ); - $count = $row[0]; - if ( $count == '1' || $count == 1 ) { - return true; - } - - return false; - } - - /** - * Fetch the next row from the given result object, in object form. - * Fields can be retrieved with $row->fieldname, with fields acting like - * member variables. - * If no more rows are available, false is returned. - * - * @param $res array|ResultWrapper SQL result object as returned from Database::query(), etc. - * @return object|bool - * @throws DBUnexpectedError Thrown if the database returns an error - */ - public function fetchObject( $res ) { - if ( $res instanceof ResultWrapper ) { - $res = $res->result; - } - wfSuppressWarnings(); - $row = db2_fetch_object( $res ); - wfRestoreWarnings(); - if( $this->lastErrno() ) { - throw new DBUnexpectedError( $this, 'Error in fetchObject(): ' - . htmlspecialchars( $this->lastError() ) ); - } - return $row; - } - - /** - * Fetch the next row from the given result object, in associative array - * form. Fields are retrieved with $row['fieldname']. - * If no more rows are available, false is returned. - * - * @param $res array|ResultWrapper SQL result object as returned from Database::query(), etc. - * @return array|bool - * @throws DBUnexpectedError Thrown if the database returns an error - */ - public function fetchRow( $res ) { - if ( $res instanceof ResultWrapper ) { - $res = $res->result; - } - if ( db2_num_rows( $res ) > 0) { - wfSuppressWarnings(); - $row = db2_fetch_array( $res ); - wfRestoreWarnings(); - if ( $this->lastErrno() ) { - throw new DBUnexpectedError( $this, 'Error in fetchRow(): ' - . htmlspecialchars( $this->lastError() ) ); - } - return $row; - } - return false; - } - - /** - * Escapes strings - * Doesn't escape numbers - * - * @param $s String: string to escape - * @return string escaped string - */ - public function addQuotes( $s ) { - //$this->installPrint( "DB2::addQuotes( $s )\n" ); - if ( is_null( $s ) ) { - return 'NULL'; - } elseif ( $s instanceof Blob ) { - return "'" . $s->fetch( $s ) . "'"; - } elseif ( $s instanceof IBM_DB2Blob ) { - return "'" . $this->decodeBlob( $s ) . "'"; - } - $s = $this->strencode( $s ); - if ( is_numeric( $s ) ) { - return $s; - } else { - return "'$s'"; - } - } - - /** - * Verifies that a DB2 column/field type is numeric - * - * @param $type String: DB2 column type - * @return Boolean: true if numeric - */ - public function is_numeric_type( $type ) { - switch ( strtoupper( $type ) ) { - case 'SMALLINT': - case 'INTEGER': - case 'INT': - case 'BIGINT': - case 'DECIMAL': - case 'REAL': - case 'DOUBLE': - case 'DECFLOAT': - return true; - } - return false; - } - - /** - * Alias for addQuotes() - * @param $s String: string to escape - * @return string escaped string - */ - public function strencode( $s ) { - // Bloody useless function - // Prepends backslashes to \x00, \n, \r, \, ', " and \x1a. - // But also necessary - $s = db2_escape_string( $s ); - // Wide characters are evil -- some of them look like ' - $s = utf8_encode( $s ); - // Fix its stupidity - $from = array( "\\\\", "\\'", '\\n', '\\t', '\\"', '\\r' ); - $to = array( "\\", "''", "\n", "\t", '"', "\r" ); - $s = str_replace( $from, $to, $s ); // DB2 expects '', not \' escaping - return $s; - } - - /** - * Switch into the database schema - */ - protected function applySchema() { - if ( !( $this->mSchemaSet ) ) { - $this->mSchemaSet = true; - $this->begin( __METHOD__ ); - $this->doQuery( "SET SCHEMA = $this->mSchema" ); - $this->commit( __METHOD__ ); - } - } - - /** - * Start a transaction (mandatory) - */ - protected function doBegin( $fname = 'DatabaseIbm_db2::begin' ) { - // BEGIN is implicit for DB2 - // However, it requires that AutoCommit be off. - - // 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_OFF ); - - $this->mTrxLevel = 1; - } - - /** - * End a transaction - * Must have a preceding begin() - */ - protected function doCommit( $fname = 'DatabaseIbm_db2::commit' ) { - db2_commit( $this->mConn ); - - // 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->mTrxLevel = 0; - } - - /** - * Cancel a transaction - */ - protected function doRollback( $fname = 'DatabaseIbm_db2::rollback' ) { - db2_rollback( $this->mConn ); - // turn auto-commit back on - // not sure if this is appropriate - db2_autocommit( $this->mConn, DB2_AUTOCOMMIT_ON ); - $this->mTrxLevel = 0; - } - - /** - * Makes an encoded list of strings from an array - * $mode: - * LIST_COMMA - comma separated, no field names - * LIST_AND - ANDed WHERE clause (without the WHERE) - * LIST_OR - ORed WHERE clause (without the WHERE) - * LIST_SET - comma separated with field names, like a SET clause - * LIST_NAMES - comma separated field names - * LIST_SET_PREPARED - like LIST_SET, except with ? tokens as values - * @param array $a - * @param int $mode - * @throws DBUnexpectedError - * @return string - */ - function makeList( $a, $mode = LIST_COMMA ) { - if ( !is_array( $a ) ) { - throw new DBUnexpectedError( $this, - 'DatabaseIbm_db2::makeList called with incorrect parameters' ); - } - - // if this is for a prepared UPDATE statement - // (this should be promoted to the parent class - // once other databases use prepared statements) - if ( $mode == LIST_SET_PREPARED ) { - $first = true; - $list = ''; - foreach ( $a as $field => $value ) { - if ( !$first ) { - $list .= ", $field = ?"; - } else { - $list .= "$field = ?"; - $first = false; - } - } - $list .= ''; - - return $list; - } - - // otherwise, call the usual function - return parent::makeList( $a, $mode ); - } - - /** - * Construct a LIMIT query with optional offset - * This is used for query pages - * - * @param $sql string SQL query we will append the limit too - * @param $limit integer the SQL limit - * @param bool|int $offset SQL offset (default false) - * @throws DBUnexpectedError - * @return string - */ - public function limitResult( $sql, $limit, $offset=false ) { - if( !is_numeric( $limit ) ) { - throw new DBUnexpectedError( $this, - "Invalid non-numeric limit passed to limitResult()\n" ); - } - if( $offset ) { - if ( stripos( $sql, 'where' ) === false ) { - return "$sql AND ( ROWNUM BETWEEN $offset AND $offset+$limit )"; - } else { - return "$sql WHERE ( ROWNUM BETWEEN $offset AND $offset+$limit )"; - } - } - return "$sql FETCH FIRST $limit ROWS ONLY "; - } - - /** - * Handle reserved keyword replacement in table names - * - * @param $name Object - * @param $format String Ignored parameter Default 'quoted'Boolean - * @return String - */ - public function tableName( $name, $format = 'quoted' ) { - // we want maximum compatibility with MySQL schema - return $name; - } - - /** - * Generates a timestamp in an insertable format - * - * @param $ts string timestamp - * @return String: timestamp value - */ - public function timestamp( $ts = 0 ) { - // TS_MW cannot be easily distinguished from an integer - return wfTimestamp( TS_DB2, $ts ); - } - - /** - * Return the next in a sequence, save the value for retrieval via insertId() - * @param $seqName String: name of a defined sequence in the database - * @return int next value in that sequence - */ - public function nextSequenceValue( $seqName ) { - // Not using sequences in the primary schema to allow for easier migration - // from MySQL - // Emulating MySQL behaviour of using NULL to signal that sequences - // aren't used - /* - $safeseq = preg_replace( "/'/", "''", $seqName ); - $res = $this->query( "VALUES NEXTVAL FOR $safeseq" ); - $row = $this->fetchRow( $res ); - $this->mInsertId = $row[0]; - return $this->mInsertId; - */ - return null; - } - - /** - * This must be called after nextSequenceVal - * @return int Last sequence value used as a primary key - */ - public function insertId() { - return $this->mInsertId; - } - - /** - * Updates the mInsertId property with the value of the last insert - * into a generated column - * - * @param $table String: sanitized table name - * @param $primaryKey Mixed: string name of the primary key - * @param $stmt Resource: prepared statement resource - * of the SELECT primary_key FROM FINAL TABLE ( INSERT ... ) form - */ - private function calcInsertId( $table, $primaryKey, $stmt ) { - if ( $primaryKey ) { - $this->mInsertId = db2_last_insert_id( $this->mConn ); - } - } - - /** - * INSERT wrapper, inserts an array into a table - * - * $args may be a single associative array, or an array of arrays - * with numeric keys, for multi-row insert - * - * @param $table String: Name of the table to insert to. - * @param $args Array: Items to insert into the table. - * @param $fname String: Name of the function, for profiling - * @param $options String or Array. Valid options: IGNORE - * - * @return bool Success of insert operation. IGNORE always returns true. - */ - public function insert( $table, $args, $fname = 'DatabaseIbm_db2::insert', - $options = array() ) - { - if ( !count( $args ) ) { - return true; - } - // get database-specific table name (not used) - $table = $this->tableName( $table ); - // format options as an array - $options = IBM_DB2Helper::makeArray( $options ); - // format args as an array of arrays - if ( !( isset( $args[0] ) && is_array( $args[0] ) ) ) { - $args = array( $args ); - } - - // prevent insertion of NULL into primary key columns - list( $args, $primaryKeys ) = $this->removeNullPrimaryKeys( $table, $args ); - // if there's only one primary key - // we'll be able to read its value after insertion - $primaryKey = false; - if ( count( $primaryKeys ) == 1 ) { - $primaryKey = $primaryKeys[0]; - } - - // get column names - $keys = array_keys( $args[0] ); - $key_count = count( $keys ); - - // If IGNORE is set, we use savepoints to emulate mysql's behavior - $ignore = in_array( 'IGNORE', $options ) ? 'mw' : ''; - - // assume success - $res = true; - // If we are not in a transaction, we need to be for savepoint trickery - if ( !$this->mTrxLevel ) { - $this->begin( __METHOD__ ); - } - - $sql = "INSERT INTO $table ( " . implode( ',', $keys ) . ' ) VALUES '; - if ( $key_count == 1 ) { - $sql .= '( ? )'; - } else { - $sql .= '( ?' . str_repeat( ',?', $key_count-1 ) . ' )'; - } - $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 - $this->begin( __METHOD__ ); - - if ( !$ignore ) { - //$first = true; - foreach ( $args as $row ) { - //$this->installPrint( "Inserting " . print_r( $row, true )); - // insert each row into the database - $res = $res & $this->execute( $stmt, $row ); - if ( !$res ) { - $this->installPrint( 'Last error:' ); - $this->installPrint( $this->lastError() ); - } - // get the last inserted value into a generated column - $this->calcInsertId( $table, $primaryKey, $stmt ); - } - } else { - $olde = error_reporting( 0 ); - // For future use, we may want to track the number of actual inserts - // Right now, insert (all writes) simply return true/false - $numrowsinserted = 0; - - // always return true - $res = true; - - foreach ( $args as $row ) { - $overhead = "SAVEPOINT $ignore ON ROLLBACK RETAIN CURSORS"; - db2_exec( $this->mConn, $overhead, $this->mStmtOptions ); - - $res2 = $this->execute( $stmt, $row ); - - if ( !$res2 ) { - $this->installPrint( 'Last error:' ); - $this->installPrint( $this->lastError() ); - } - // get the last inserted value into a generated column - $this->calcInsertId( $table, $primaryKey, $stmt ); - - $errNum = $this->lastErrno(); - if ( $errNum ) { - db2_exec( $this->mConn, "ROLLBACK TO SAVEPOINT $ignore", - $this->mStmtOptions ); - } else { - db2_exec( $this->mConn, "RELEASE SAVEPOINT $ignore", - $this->mStmtOptions ); - $numrowsinserted++; - } - } - - $olde = error_reporting( $olde ); - // Set the affected row count for the whole operation - $this->mAffectedRows = $numrowsinserted; - } - // commit either way - $this->commit( __METHOD__ ); - $this->freePrepared( $stmt ); - - return $res; - } - - /** - * Given a table name and a hash of columns with values - * Removes primary key columns from the hash where the value is NULL - * - * @param $table String: name of the table - * @param $args Array of hashes of column names with values - * @return Array: tuple( filtered array of columns, array of primary keys ) - */ - private function removeNullPrimaryKeys( $table, $args ) { - $schema = $this->mSchema; - - // find out the primary keys - $keyres = $this->doQuery( "SELECT NAME FROM SYSIBM.SYSCOLUMNS WHERE TBNAME = '" - . strtoupper( $table ) - . "' AND TBCREATOR = '" - . strtoupper( $schema ) - . "' AND KEYSEQ > 0" ); - - $keys = array(); - for ( - $row = $this->fetchRow( $keyres ); - $row != null; - $row = $this->fetchRow( $keyres ) - ) - { - $keys[] = strtolower( $row[0] ); - } - // remove primary keys - foreach ( $args as $ai => $row ) { - foreach ( $keys as $key ) { - if ( $row[$key] == null ) { - unset( $row[$key] ); - } - } - $args[$ai] = $row; - } - // return modified hash - return array( $args, $keys ); - } - - /** - * UPDATE wrapper, takes a condition array and a SET array - * - * @param $table String: The table to UPDATE - * @param $values array An array of values to SET - * @param $conds array An array of conditions ( WHERE ). Use '*' to update all rows. - * @param $fname String: The Class::Function calling this function - * ( for the log ) - * @param $options array An array of UPDATE options, can be one or - * more of IGNORE, LOW_PRIORITY - * @return Boolean - */ - public function update( $table, $values, $conds, $fname = 'DatabaseIbm_db2::update', - $options = array() ) - { - $table = $this->tableName( $table ); - $opts = $this->makeUpdateOptions( $options ); - $sql = "UPDATE $opts $table SET " - . $this->makeList( $values, LIST_SET_PREPARED ); - if ( $conds != '*' ) { - $sql .= " WHERE " . $this->makeList( $conds, LIST_AND ); - } - $stmt = $this->prepare( $sql ); - $this->installPrint( 'UPDATE: ' . print_r( $values, true ) ); - // assuming for now that an array with string keys will work - // if not, convert to simple array first - $result = $this->execute( $stmt, $values ); - $this->freePrepared( $stmt ); - - return $result; - } - - /** - * DELETE query wrapper - * - * Use $conds == "*" to delete all rows - * @param array $table - * @param array|string $conds - * @param string $fname - * @throws DBUnexpectedError - * @return bool|ResultWrapper - */ - public function delete( $table, $conds, $fname = 'DatabaseIbm_db2::delete' ) { - if ( !$conds ) { - throw new DBUnexpectedError( $this, - 'DatabaseIbm_db2::delete() called with no conditions' ); - } - $table = $this->tableName( $table ); - $sql = "DELETE FROM $table"; - if ( $conds != '*' ) { - $sql .= ' WHERE ' . $this->makeList( $conds, LIST_AND ); - } - $result = $this->query( $sql, $fname ); - - return $result; - } - - /** - * Returns the number of rows affected by the last query or 0 - * @return Integer: the number of rows affected by the last query - */ - public function affectedRows() { - if ( !is_null( $this->mAffectedRows ) ) { - // Forced result for simulated queries - return $this->mAffectedRows; - } - if( empty( $this->mLastResult ) ) { - return 0; - } - return db2_num_rows( $this->mLastResult ); - } - - /** - * Returns the number of rows in the result set - * Has to be called right after the corresponding select query - * @param $res Object result set - * @return Integer: number of rows - */ - public function numRows( $res ) { - if ( $res instanceof ResultWrapper ) { - $res = $res->result; - } - - if ( $this->mNumRows ) { - return $this->mNumRows; - } else { - return 0; - } - } - - /** - * Moves the row pointer of the result set - * @param $res Object: result set - * @param $row Integer: row number - * @return bool success or failure - */ - public function dataSeek( $res, $row ) { - if ( $res instanceof ResultWrapper ) { - return $res = $res->result; - } - if ( $res instanceof IBM_DB2Result ) { - return $res->dataSeek( $row ); - } - wfDebug( "dataSeek operation in DB2 database\n" ); - return false; - } - - ### - # Fix notices in Block.php - ### - - /** - * Frees memory associated with a statement resource - * @param $res Object: statement resource to free - * @throws DBUnexpectedError - * @return Boolean success or failure - */ - public function freeResult( $res ) { - if ( $res instanceof ResultWrapper ) { - $res = $res->result; - } - wfSuppressWarnings(); - $ok = db2_free_result( $res ); - wfRestoreWarnings(); - if ( !$ok ) { - throw new DBUnexpectedError( $this, "Unable to free DB2 result\n" ); - } - } - - /** - * Returns the number of columns in a resource - * @param $res Object: statement resource - * @return Number of fields/columns in resource - */ - public function numFields( $res ) { - if ( $res instanceof ResultWrapper ) { - $res = $res->result; - } - if ( $res instanceof IBM_DB2Result ) { - $res = $res->getResult(); - } - return db2_num_fields( $res ); - } - - /** - * Returns the nth column name - * @param $res Object: statement resource - * @param $n Integer: Index of field or column - * @return String name of nth column - */ - public function fieldName( $res, $n ) { - if ( $res instanceof ResultWrapper ) { - $res = $res->result; - } - if ( $res instanceof IBM_DB2Result ) { - $res = $res->getResult(); - } - return db2_field_name( $res, $n ); - } - - /** - * SELECT wrapper - * - * @param $table Array or string, table name(s) (prefix auto-added) - * @param $vars Array or string, field name(s) to be retrieved - * @param $conds Array or string, condition(s) for WHERE - * @param $fname String: calling function name (use __METHOD__) - * for logs/profiling - * @param $options array Associative array of options - * (e.g. array( 'GROUP BY' => 'page_title' )), - * see Database::makeSelectOptions code for list of - * supported stuff - * @param $join_conds array Associative array of table join conditions (optional) - * (e.g. array( 'page' => array('LEFT JOIN', - * 'page_latest=rev_id') ) - * @return Mixed: database result resource for fetch functions or false - * on failure - */ - public function select( $table, $vars, $conds = '', $fname = 'DatabaseIbm_db2::select', $options = array(), $join_conds = array() ) - { - $res = parent::select( $table, $vars, $conds, $fname, $options, - $join_conds ); - $sql = $this->selectSQLText( $table, $vars, $conds, $fname, $options, $join_conds ); - - // We must adjust for offset - if ( isset( $options['LIMIT'] ) && isset ( $options['OFFSET'] ) ) { - $limit = $options['LIMIT']; - $offset = $options['OFFSET']; - } - - // DB2 does not have a proper num_rows() function yet, so we must emulate - // DB2 9.5.4 and the corresponding ibm_db2 driver will introduce - // a working one - // TODO: Yay! - - // we want the count - $vars2 = array( 'count( * ) as num_rows' ); - // respecting just the limit option - $options2 = array(); - if ( isset( $options['LIMIT'] ) ) { - $options2['LIMIT'] = $options['LIMIT']; - } - // but don't try to emulate for GROUP BY - if ( isset( $options['GROUP BY'] ) ) { - return $res; - } - - $res2 = parent::select( $table, $vars2, $conds, $fname, $options2, - $join_conds ); - - $obj = $this->fetchObject( $res2 ); - $this->mNumRows = $obj->num_rows; - - return new ResultWrapper( $this, new IBM_DB2Result( $this, $res, $obj->num_rows, $vars, $sql ) ); - } - - /** - * Handles ordering, grouping, and having options ('GROUP BY' => colname) - * Has limited support for per-column options (colnum => 'DISTINCT') - * - * @private - * - * @param $options array Associative array of options to be turned into - * an SQL query, valid keys are listed in the function. - * @return Array - */ - function makeSelectOptions( $options ) { - $preLimitTail = $postLimitTail = ''; - $startOpts = ''; - - $noKeyOptions = array(); - foreach ( $options as $key => $option ) { - if ( is_numeric( $key ) ) { - $noKeyOptions[$option] = true; - } - } - - $preLimitTail .= $this->makeGroupByWithHaving( $options ); - - $preLimitTail .= $this->makeOrderBy( $options ); - - if ( isset( $noKeyOptions['DISTINCT'] ) - || isset( $noKeyOptions['DISTINCTROW'] ) ) - { - $startOpts .= 'DISTINCT'; - } - - return array( $startOpts, '', $preLimitTail, $postLimitTail ); - } - - /** - * Returns link to IBM DB2 free download - * @return String: wikitext of a link to the server software's web site - */ - public static function getSoftwareLink() { - return '[http://www.ibm.com/db2/express/ IBM DB2]'; - } - - /** - * Get search engine class. All subclasses of this - * need to implement this if they wish to use searching. - * - * @return String - */ - public function getSearchEngine() { - return 'SearchIBM_DB2'; - } - - /** - * Did the last database access fail because of deadlock? - * @return Boolean - */ - public function wasDeadlock() { - // get SQLSTATE - $err = $this->lastErrno(); - switch( $err ) { - // This is literal port of the MySQL logic and may be wrong for DB2 - case '40001': // sql0911n, Deadlock or timeout, rollback - case '57011': // sql0904n, Resource unavailable, no rollback - case '57033': // sql0913n, Deadlock or timeout, no rollback - $this->installPrint( "In a deadlock because of SQLSTATE $err" ); - return true; - } - return false; - } - - /** - * Ping the server and try to reconnect if it there is no connection - * The connection may be closed and reopened while this happens - * @return Boolean: whether the connection exists - */ - public function ping() { - // db2_ping() doesn't exist - // Emulate - $this->close(); - $this->openUncataloged( $this->mDBName, $this->mUser, - $this->mPassword, $this->mServer, $this->mPort ); - - return false; - } - ###################################### - # Unimplemented and not applicable - ###################################### - - /** - * Only useful with fake prepare like in base Database class - * @return string - */ - public function fillPreparedArg( $matches ) { - $this->installPrint( 'Not useful for DB2: fillPreparedArg()' ); - return ''; - } - - ###################################### - # Reflection - ###################################### - - /** - * Returns information about an index - * If errors are explicitly ignored, returns NULL on failure - * @param $table String: table name - * @param $index String: index name - * @param $fname String: function name for logging and profiling - * @return Object query row in object form - */ - public function indexInfo( $table, $index, - $fname = 'DatabaseIbm_db2::indexExists' ) - { - $table = $this->tableName( $table ); - $sql = <<query( $sql, $fname ); - if ( !$res ) { - return null; - } - $row = $this->fetchObject( $res ); - if ( $row != null ) { - return $row; - } else { - return false; - } - } - - /** - * Returns an information object on a table column - * @param $table String: table name - * @param $field String: column name - * @return IBM_DB2Field - */ - public function fieldInfo( $table, $field ) { - return IBM_DB2Field::fromText( $this, $table, $field ); - } - - /** - * db2_field_type() wrapper - * @param $res Object: result of executed statement - * @param $index Mixed: number or name of the column - * @return String column type - */ - public function fieldType( $res, $index ) { - if ( $res instanceof ResultWrapper ) { - $res = $res->result; - } - if ( $res instanceof IBM_DB2Result ) { - $res = $res->getResult(); - } - return db2_field_type( $res, $index ); - } - - /** - * Verifies that an index was created as unique - * @param $table String: table name - * @param $index String: index name - * @param $fname string function name for profiling - * @return Bool - */ - public function indexUnique ( $table, $index, - $fname = 'DatabaseIbm_db2::indexUnique' ) - { - $table = $this->tableName( $table ); - $sql = <<query( $sql, $fname ); - if ( !$res ) { - return null; - } - if ( $this->fetchObject( $res ) ) { - return true; - } - return false; - - } - - /** - * Returns the size of a text field, or -1 for "unlimited" - * @param $table String: table name - * @param $field String: column name - * @return Integer: length or -1 for unlimited - */ - public function textFieldSize( $table, $field ) { - $table = $this->tableName( $table ); - $sql = <<query( $sql ); - $row = $this->fetchObject( $res ); - $size = $row->size; - return $size; - } - - /** - * Description is left as an exercise for the reader - * @param $b Mixed: data to be encoded - * @return IBM_DB2Blob - */ - public function encodeBlob( $b ) { - return new IBM_DB2Blob( $b ); - } - - /** - * Description is left as an exercise for the reader - * @param $b IBM_DB2Blob: data to be decoded - * @return mixed - */ - public function decodeBlob( $b ) { - return "$b"; - } - - /** - * Convert into a list of string being concatenated - * @param $stringList Array: strings that need to be joined together - * by the SQL engine - * @return String: joined by the concatenation operator - */ - public function buildConcat( $stringList ) { - // || is equivalent to CONCAT - // Sample query: VALUES 'foo' CONCAT 'bar' CONCAT 'baz' - return implode( ' || ', $stringList ); - } - - /** - * Generates the SQL required to convert a DB2 timestamp into a Unix epoch - * @param $column String: name of timestamp column - * @return String: SQL code - */ - public function extractUnixEpoch( $column ) { - // TODO - // see SpecialAncientpages - } - - ###################################### - # Prepared statements - ###################################### - - /** - * Intended to be compatible with the PEAR::DB wrapper functions. - * http://pear.php.net/manual/en/package.database.db.intro-execute.php - * - * ? = scalar value, quoted as necessary - * ! = raw SQL bit (a function for instance) - * & = filename; reads the file and inserts as a blob - * (we don't use this though...) - * @param $sql String: SQL statement with appropriate markers - * @param $func String: Name of the function, for profiling - * @return resource a prepared DB2 SQL statement - */ - public function prepare( $sql, $func = 'DB2::prepare' ) { - $stmt = db2_prepare( $this->mConn, $sql, $this->mStmtOptions ); - return $stmt; - } - - /** - * Frees resources associated with a prepared statement - * @return Boolean success or failure - */ - public function freePrepared( $prepared ) { - return db2_free_stmt( $prepared ); - } - - /** - * Execute a prepared query with the various arguments - * @param $prepared String: the prepared sql - * @param $args Mixed: either an array here, or put scalars as varargs - * @return Resource: results object - */ - public function execute( $prepared, $args = null ) { - if( !is_array( $args ) ) { - # Pull the var args - $args = func_get_args(); - array_shift( $args ); - } - $res = db2_execute( $prepared, $args ); - if ( !$res ) { - $this->installPrint( db2_stmt_errormsg() ); - } - return $res; - } - - /** - * For faking prepared SQL statements on DBs that don't support - * it directly. - * @param $preparedQuery String: a 'preparable' SQL statement - * @param $args Array of arguments to fill it with - * @return String: executable statement - */ - public function fillPrepared( $preparedQuery, $args ) { - reset( $args ); - $this->preparedArgs =& $args; - - foreach ( $args as $i => $arg ) { - db2_bind_param( $preparedQuery, $i+1, $args[$i] ); - } - - return $preparedQuery; - } - - /** - * Switches module between regular and install modes - * @return string - */ - public function setMode( $mode ) { - $old = $this->mMode; - $this->mMode = $mode; - return $old; - } - - /** - * Bitwise negation of a column or value in SQL - * Same as (~field) in C - * @param $field String - * @return String - */ - function bitNot( $field ) { - // expecting bit-fields smaller than 4bytes - return "BITNOT( $field )"; - } - - /** - * Bitwise AND of two columns or values in SQL - * Same as (fieldLeft & fieldRight) in C - * @param $fieldLeft String - * @param $fieldRight String - * @return String - */ - function bitAnd( $fieldLeft, $fieldRight ) { - return "BITAND( $fieldLeft, $fieldRight )"; - } - - /** - * Bitwise OR of two columns or values in SQL - * Same as (fieldLeft | fieldRight) in C - * @param $fieldLeft String - * @param $fieldRight String - * @return String - */ - function bitOr( $fieldLeft, $fieldRight ) { - return "BITOR( $fieldLeft, $fieldRight )"; - } -} - -class IBM_DB2Helper { - public static function makeArray( $maybeArray ) { - if ( !is_array( $maybeArray ) ) { - return array( $maybeArray ); - } - - return $maybeArray; - } -} diff --git a/includes/installer/Ibm_db2Installer.php b/includes/installer/Ibm_db2Installer.php deleted file mode 100644 index bf19055a75..0000000000 --- a/includes/installer/Ibm_db2Installer.php +++ /dev/null @@ -1,270 +0,0 @@ - 'db2admin' - ); - - /** - * Get the DB2 database extension name - * @return string - */ - public function getName() { - return 'ibm_db2'; - } - - /** - * Determine whether the DB2 database extension is currently available in PHP - * @return boolean - */ - public function isCompiled() { - return self::checkExtension( 'ibm_db2' ); - } - - /** - * Generate a connection form for a DB2 database - * @return string - */ - public function getConnectForm() { - return - $this->getTextBox( 'wgDBserver', 'config-db-host', array(), $this->parent->getHelpBox( 'config-db-host-help' ) ) . - $this->getTextBox( 'wgDBport', 'config-db-port', array(), $this->parent->getHelpBox( 'config-db-port' ) ) . - Html::openElement( 'fieldset' ) . - Html::element( 'legend', array(), wfMessage( 'config-db-wiki-settings' )->text() ) . - $this->getTextBox( 'wgDBname', 'config-db-name', array(), $this->parent->getHelpBox( 'config-db-name-help' ) ) . - $this->getTextBox( 'wgDBmwschema', 'config-db-schema', array(), $this->parent->getHelpBox( 'config-db-schema-help' ) ) . - Html::closeElement( 'fieldset' ) . - $this->getInstallUserBox(); - } - - /** - * Validate and then execute the connection form for a DB2 database - * @return Status - */ - public function submitConnectForm() { - // Get variables from the request - $newValues = $this->setVarsFromRequest( - array( 'wgDBserver', 'wgDBport', 'wgDBname', - 'wgDBmwschema', 'wgDBuser', 'wgDBpassword' ) ); - - // Validate them - $status = Status::newGood(); - if ( !strlen( $newValues['wgDBname'] ) ) { - $status->fatal( 'config-missing-db-name' ); - } elseif ( !preg_match( '/^[a-zA-Z0-9_]+$/', $newValues['wgDBname'] ) ) { - $status->fatal( 'config-invalid-db-name', $newValues['wgDBname'] ); - } - if ( !strlen( $newValues['wgDBmwschema'] ) ) { - $status->fatal( 'config-invalid-schema' ); - } - elseif ( !preg_match( '/^[a-zA-Z0-9_]*$/', $newValues['wgDBmwschema'] ) ) { - $status->fatal( 'config-invalid-schema', $newValues['wgDBmwschema'] ); - } - if ( !strlen( $newValues['wgDBport'] ) ) { - $status->fatal( 'config-invalid-port' ); - } - elseif ( !preg_match( '/^[0-9_]*$/', $newValues['wgDBport'] ) ) { - $status->fatal( 'config-invalid-port', $newValues['wgDBport'] ); - } - - // Submit user box - if ( $status->isOK() ) { - $status->merge( $this->submitInstallUserBox() ); - } - if ( !$status->isOK() ) { - return $status; - } - - global $wgDBport; - $wgDBport = $newValues['wgDBport']; - - // Try to connect - $status->merge( $this->getConnection() ); - if ( !$status->isOK() ) { - return $status; - } - - $this->parent->setVar( 'wgDBuser', $this->getVar( '_InstallUser' ) ); - $this->parent->setVar( 'wgDBpassword', $this->getVar( '_InstallPassword' ) ); - - return $status; - } - - /** - * Open a DB2 database connection - * @return Status - */ - public function openConnection() { - $status = Status::newGood(); - try { - $db = new DatabaseIbm_db2( - $this->getVar( 'wgDBserver' ), - $this->getVar( '_InstallUser' ), - $this->getVar( '_InstallPassword' ), - $this->getVar( 'wgDBname' ), - 0, - $this->getVar( 'wgDBmwschema' ) - ); - $status->value = $db; - } catch ( DBConnectionError $e ) { - $status->fatal( 'config-connection-error', $e->getMessage() ); - } - return $status; - } - - /** - * Create a DB2 database for MediaWiki - * @return Status - */ - public function setupDatabase() { - $status = $this->getConnection(); - if ( !$status->isOK() ) { - return $status; - } - /** - * @var $conn DatabaseBase - */ - $conn = $status->value; - $dbName = $this->getVar( 'wgDBname' ); - if( !$conn->selectDB( $dbName ) ) { - $conn->query( "CREATE DATABASE " - . $conn->addIdentifierQuotes( $dbName ) - . " AUTOMATIC STORAGE YES" - . " USING CODESET UTF-8 TERRITORY US COLLATE USING SYSTEM" - . " PAGESIZE 32768", __METHOD__ ); - $conn->selectDB( $dbName ); - } - $this->setupSchemaVars(); - return $status; - } - - /** - * Create tables from scratch. - * First check if pagesize >= 32k. - * - * @return Status - */ - public function createTables() { - $status = $this->getConnection(); - if ( !$status->isOK() ) { - return $status; - } - $this->db->selectDB( $this->getVar( 'wgDBname' ) ); - - if( $this->db->tableExists( 'user' ) ) { - $status->warning( 'config-install-tables-exist' ); - return $status; - } - - /* Check for pagesize */ - $status = $this->checkPageSize(); - if ( !$status->isOK() ) { - return $status; - } - - $this->db->setFlag( DBO_DDLMODE ); // For Oracle's handling of schema files - $this->db->begin( __METHOD__ ); - - $error = $this->db->sourceFile( $this->db->getSchemaPath() ); - if( $error !== true ) { - $this->db->reportQueryError( $error, 0, '', __METHOD__ ); - $this->db->rollback( __METHOD__ ); - $status->fatal( 'config-install-tables-failed', $error ); - } else { - $this->db->commit( __METHOD__ ); - } - // Resume normal operations - if( $status->isOk() ) { - $this->enableLB(); - } - return $status; - } - - /** - * Check if database has a tablspace with pagesize >= 32k. - * - * @return Status - */ - public function checkPageSize() { - $status = $this->getConnection(); - if ( !$status->isOK() ) { - return $status; - } - $this->db->selectDB( $this->getVar( 'wgDBname' ) ); - - try { - $result = $this->db->query( 'SELECT PAGESIZE FROM SYSCAT.TABLESPACES FOR READ ONLY' ); - if( $result == false ) { - $status->fatal( 'config-connection-error', '' ); - } else { - $row = $this->db->fetchRow( $result ); - while ( $row ) { - if( $row[0] >= 32768 ) { - return $status; - } - $row = $this->db->fetchRow( $result ); - } - $status->fatal( 'config-ibm_db2-low-db-pagesize', '' ); - } - } catch ( DBUnexpectedError $e ) { - $status->fatal( 'config-connection-error', $e->getMessage() ); - } - - return $status; - } - - /** - * Generate the code to store the DB2-specific settings defined by the configuration form - * @return string - */ - public function getLocalSettings() { - $schema = LocalSettingsGenerator::escapePhpString( $this->getVar( 'wgDBmwschema' ) ); - $port = LocalSettingsGenerator::escapePhpString( $this->getVar( 'wgDBport' ) ); - return -"# IBM_DB2 specific settings -\$wgDBmwschema = \"{$schema}\"; -\$wgDBport = \"{$port}\";"; - } - - public function __construct( $parent ) { - parent::__construct( $parent ); - } -} diff --git a/includes/installer/Ibm_db2Updater.php b/includes/installer/Ibm_db2Updater.php deleted file mode 100644 index 33bf69c69e..0000000000 --- a/includes/installer/Ibm_db2Updater.php +++ /dev/null @@ -1,96 +0,0 @@ -/v '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 @@ -251,12 +250,10 @@ If you do not see the database system you are trying to use listed below, then f '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. ([http://www.php.net/manual/en/ibm-db2.installation.php How to compile PHP with IBM DB2 support])', '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"', @@ -349,8 +346,6 @@ This is more efficient than MySQL's UTF-8 mode, and allows you to use the full r 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 [//en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes Basic Multilingual Plane].", - 'config-ibm_db2-low-db-pagesize' => "Your DB2 database has a default tablespace with an insufficient pagesize. The pagesize has to be '''32K''' or greater.", - '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.', diff --git a/includes/installer/Installer.php b/includes/installer/Installer.php index 325f894c5c..850fb31578 100644 --- a/includes/installer/Installer.php +++ b/includes/installer/Installer.php @@ -88,7 +88,6 @@ abstract class Installer { 'postgres', 'oracle', 'sqlite', - 'ibm_db2', ); /** diff --git a/includes/search/SearchIBM_DB2.php b/includes/search/SearchIBM_DB2.php deleted file mode 100644 index ebc9d5a054..0000000000 --- a/includes/search/SearchIBM_DB2.php +++ /dev/null @@ -1,234 +0,0 @@ - - * http://www.mediawiki.org/ - * - * 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 Search - */ - -/** - * Search engine hook base class for IBM DB2 - * @ingroup Search - */ -class SearchIBM_DB2 extends SearchEngine { - - /** - * Creates an instance of this class - * @param $db DatabaseIbm_db2: database object - */ - function __construct( $db ) { - parent::__construct( $db ); - } - - /** - * Perform a full text search query and return a result set. - * - * @param $term String: raw search term - * @return SqlSearchResultSet - */ - function searchText( $term ) { - $resultSet = $this->db->resultObject( $this->db->query( $this->getQuery( $this->filter( $term ), true ) ) ); - return new SqlSearchResultSet( $resultSet, $this->searchTerms ); - } - - /** - * Perform a title-only search query and return a result set. - * - * @param $term String: taw search term - * @return SqlSearchResultSet - */ - function searchTitle( $term ) { - $resultSet = $this->db->resultObject( $this->db->query( $this->getQuery( $this->filter( $term ), false ) ) ); - return new SqlSearchResultSet( $resultSet, $this->searchTerms ); - } - - - /** - * Return a partial WHERE clause to exclude redirects, if so set - * @return String - */ - function queryRedirect() { - if ( $this->showRedirects ) { - return ''; - } else { - return 'AND page_is_redirect=0'; - } - } - - /** - * Return a partial WHERE clause to limit the search to the given namespaces - * @return String - */ - function queryNamespaces() { - if( is_null( $this->namespaces ) ) - return ''; - $namespaces = implode( ',', $this->namespaces ); - if ( $namespaces == '' ) { - $namespaces = '0'; - } - return 'AND page_namespace IN (' . $namespaces . ')'; - } - - /** - * Return a LIMIT clause to limit results on the query. - * @return String - */ - function queryLimit( $sql ) { - return $this->db->limitResult( $sql, $this->limit, $this->offset ); - } - - /** - * Does not do anything for generic search engine - * subclasses may define this though - * @return String - */ - function queryRanking( $filteredTerm, $fulltext ) { - // requires Net Search Extender or equivalent - // return ' ORDER BY score(1)'; - return ''; - } - - /** - * Construct the full SQL query to do the search. - * The guts shoulds be constructed in queryMain() - * @param $filteredTerm String - * @param $fulltext Boolean - * @return String - */ - function getQuery( $filteredTerm, $fulltext ) { - return $this->queryLimit( $this->queryMain( $filteredTerm, $fulltext ) . ' ' . - $this->queryRedirect() . ' ' . - $this->queryNamespaces() . ' ' . - $this->queryRanking( $filteredTerm, $fulltext ) . ' ' ); - } - - - /** - * Picks which field to index on, depending on what type of query. - * @param $fulltext Boolean - * @return String - */ - function getIndexField( $fulltext ) { - return $fulltext ? 'si_text' : 'si_title'; - } - - /** - * Get the base part of the search query. - * - * @param $filteredTerm String - * @param $fulltext Boolean - * @return String - */ - function queryMain( $filteredTerm, $fulltext ) { - $match = $this->parseQuery( $filteredTerm, $fulltext ); - $page = $this->db->tableName( 'page' ); - $searchindex = $this->db->tableName( 'searchindex' ); - return 'SELECT page_id, page_namespace, page_title ' . - "FROM $page,$searchindex " . - 'WHERE page_id=si_page AND ' . $match; - } - - /** @todo document - * @return string - */ - function parseQuery( $filteredText, $fulltext ) { - global $wgContLang; - $lc = SearchEngine::legalSearchChars(); - $this->searchTerms = array(); - - # @todo FIXME: This doesn't handle parenthetical expressions. - $m = array(); - $q = array(); - - if ( preg_match_all( '/([-+<>~]?)(([' . $lc . ']+)(\*?)|"[^"]*")/', - $filteredText, $m, PREG_SET_ORDER ) ) { - foreach( $m as $terms ) { - - // Search terms in all variant forms, only - // apply on wiki with LanguageConverter - $temp_terms = $wgContLang->autoConvertToAllVariants( $terms[2] ); - if( is_array( $temp_terms )) { - $temp_terms = array_unique( array_values( $temp_terms )); - foreach( $temp_terms as $t ) - $q[] = $terms[1] . $wgContLang->normalizeForSearch( $t ); - } - else - $q[] = $terms[1] . $wgContLang->normalizeForSearch( $terms[2] ); - - if ( !empty( $terms[3] ) ) { - $regexp = preg_quote( $terms[3], '/' ); - if ( $terms[4] ) - $regexp .= "[0-9A-Za-z_]+"; - } else { - $regexp = preg_quote(str_replace( '"', '', $terms[2]), '/' ); - } - $this->searchTerms[] = $regexp; - } - } - - $searchon = $this->db->strencode( join( ',', $q ) ); - $field = $this->getIndexField( $fulltext ); - - // requires Net Search Extender or equivalent - //return " CONTAINS($field, '$searchon') > 0 "; - - return " lcase($field) LIKE lcase('%$searchon%')"; - } - - /** - * Create or update the search index record for the given page. - * Title and text should be pre-processed. - * - * @param $id Integer - * @param $title String - * @param $text String - */ - function update( $id, $title, $text ) { - $dbw = wfGetDB( DB_MASTER ); - $dbw->replace( 'searchindex', - array( 'si_page' ), - array( - 'si_page' => $id, - 'si_title' => $title, - 'si_text' => $text - ), 'SearchIBM_DB2::update' ); - // ? - //$dbw->query( "CALL ctx_ddl.sync_index('si_text_idx')" ); - //$dbw->query( "CALL ctx_ddl.sync_index('si_title_idx')" ); - } - - /** - * Update a search index record's title only. - * Title should be pre-processed. - * - * @param $id Integer - * @param $title String - */ - function updateTitle( $id, $title ) { - $dbw = wfGetDB( DB_MASTER ); - - $dbw->update( 'searchindex', - array( 'si_title' => $title ), - array( 'si_page' => $id ), - 'SearchIBM_DB2::updateTitle', - array() ); - } -} diff --git a/maintenance/ibm_db2/foreignkeys.sql b/maintenance/ibm_db2/foreignkeys.sql deleted file mode 100644 index 4f1450d9b6..0000000000 --- a/maintenance/ibm_db2/foreignkeys.sql +++ /dev/null @@ -1,102 +0,0 @@ --- good -ALTER TABLE user_groups ADD CONSTRAINT USER_GROUPS_FK1 FOREIGN KEY (ug_user) REFERENCES user(user_id) ON DELETE CASCADE -; - --- good -ALTER TABLE user_newtalk ADD CONSTRAINT USER_NEWTALK_FK1 FOREIGN KEY (user_id) REFERENCES user(user_id) ON DELETE CASCADE -; - --- referenced value not found -ALTER TABLE revision ADD CONSTRAINT REVISION_PAGE_FK FOREIGN KEY (rev_page) REFERENCES page(page_id) ON DELETE CASCADE -; --- referenced value not found -ALTER TABLE revision ADD CONSTRAINT REVISION_USER_FK FOREIGN KEY (rev_user) REFERENCES user(user_id) ON DELETE RESTRICT -; - --- good -ALTER TABLE page_restrictions ADD CONSTRAINT PAGE_RESTRICTIONS_PAGE_FK FOREIGN KEY (pr_page) REFERENCES page(page_id) ON DELETE CASCADE -; - --- good -ALTER TABLE page_props ADD CONSTRAINT PAGE_PROPS_PAGE_FK FOREIGN KEY (pp_page) REFERENCES page(page_id) ON DELETE CASCADE -; - --- cannot contain null values --- ALTER TABLE archive ADD CONSTRAINT ARCHIVE_USER_FK FOREIGN KEY (ar_user) REFERENCES user(user_id) ON DELETE SET NULL ---; - --- referenced value not found -ALTER TABLE redirect ADD CONSTRAINT REDIRECT_FROM_FK FOREIGN KEY (rd_from) REFERENCES page(page_id) ON DELETE CASCADE -; - --- referenced value not found -ALTER TABLE pagelinks ADD CONSTRAINT PAGELINKS_FROM_FK FOREIGN KEY (pl_from) REFERENCES page(page_id) ON DELETE CASCADE -; - --- good -ALTER TABLE templatelinks ADD CONSTRAINT TEMPLATELINKS_FROM_FK FOREIGN KEY (tl_from) REFERENCES page(page_id) ON DELETE CASCADE -; - --- good -ALTER TABLE imagelinks ADD CONSTRAINT IMAGELINKS_FROM_FK FOREIGN KEY (il_from) REFERENCES page(page_id) ON DELETE CASCADE -; - --- good -ALTER TABLE categorylinks ADD CONSTRAINT CATEGORYLINKS_FROM_FK FOREIGN KEY (cl_from) REFERENCES page(page_id) ON DELETE CASCADE -; - --- good -ALTER TABLE externallinks ADD CONSTRAINT EXTERNALLINKS_FROM_FK FOREIGN KEY (el_from) REFERENCES page(page_id) ON DELETE CASCADE -; - --- good -ALTER TABLE langlinks ADD CONSTRAINT LANGLINKS_FROM_FK FOREIGN KEY (ll_from) REFERENCES page(page_id) ON DELETE CASCADE -; - --- cannot contain null values --- ALTER TABLE ipblocks ADD CONSTRAINT IPBLOCKS_USER_FK FOREIGN KEY (ipb_user) REFERENCES user(user_id) ON DELETE SET NULL ---; - --- good -ALTER TABLE ipblocks ADD CONSTRAINT IPBLOCKS_BY_FK FOREIGN KEY (ipb_by) REFERENCES user(user_id) ON DELETE CASCADE -; - --- cannot contain null values --- ALTER TABLE image ADD CONSTRAINT IMAGE_USER_FK FOREIGN KEY (img_user) REFERENCES user(user_id) ON DELETE SET NULL ---; - --- cannot contain null values --- ALTER TABLE oldimage ADD CONSTRAINT OLDIMAGE_USER_FK FOREIGN KEY (oi_user) REFERENCES user(user_id) ON DELETE SET NULL ---; - --- good -ALTER TABLE oldimage ADD CONSTRAINT OLDIMAGE_NAME_FK FOREIGN KEY (oi_name) REFERENCES image(img_name) ON DELETE CASCADE -; - --- cannot contain null values --- ALTER TABLE filearchive ADD CONSTRAINT FILEARCHIVE_DELETED_USER_FK FOREIGN KEY (fa_deleted_user) REFERENCES user(user_id) ON DELETE SET NULL ---; - --- cannot contain null values --- ALTER TABLE filearchive ADD CONSTRAINT FILEARCHIVE_USER_FK FOREIGN KEY (fa_user) REFERENCES user(user_id) ON DELETE SET NULL ---; - --- cannot contain null values --- ALTER TABLE recentchanges ADD CONSTRAINT RECENTCHANGES_USER_FK FOREIGN KEY (rc_user) REFERENCES user(user_id) ON DELETE SET NULL ---; - --- cannot contain null values --- ALTER TABLE recentchanges ADD CONSTRAINT RECENTCHANGES_CUR_ID_FK FOREIGN KEY (rc_cur_id) REFERENCES page(page_id) ON DELETE SET NULL ---; - --- good -ALTER TABLE watchlist ADD CONSTRAINT WATCHLIST_USER_FK FOREIGN KEY (wl_user) REFERENCES user(user_id) ON DELETE CASCADE -; - --- cannot contain null values --- ALTER TABLE protected_titles ADD CONSTRAINT PROTECTED_TITLES_USER_FK FOREIGN KEY (pt_user) REFERENCES user(user_id) ON DELETE SET NULL ---; - --- cannot contain null values --- ALTER TABLE logging ADD CONSTRAINT LOGGING_USER_FK FOREIGN KEY (log_user) REFERENCES user(user_id) ON DELETE SET NULL ---; \ No newline at end of file diff --git a/maintenance/ibm_db2/patch-categorylinks-better-collation.sql b/maintenance/ibm_db2/patch-categorylinks-better-collation.sql deleted file mode 100644 index 568d5cd675..0000000000 --- a/maintenance/ibm_db2/patch-categorylinks-better-collation.sql +++ /dev/null @@ -1,21 +0,0 @@ --- --- patch-categorylinks-better-collation.sql --- --- --- Track category inclusions *used inline* --- This tracks a single level of category membership --- (folksonomic tagging, really). --- -CREATE TABLE categorylinks ( - cl_from BIGINT NOT NULL DEFAULT 0, - -- REFERENCES page(page_id) ON DELETE CASCADE, - 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_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 -); diff --git a/maintenance/ibm_db2/patch-change_tag-indexes.sql b/maintenance/ibm_db2/patch-change_tag-indexes.sql deleted file mode 100644 index 1621a0380e..0000000000 --- a/maintenance/ibm_db2/patch-change_tag-indexes.sql +++ /dev/null @@ -1,5 +0,0 @@ -CREATE UNIQUE INDEX change_tag_rc_tag ON change_tag (ct_rc_id,ct_tag); -CREATE UNIQUE INDEX change_tag_log_tag ON change_tag (ct_log_id,ct_tag); -CREATE UNIQUE INDEX change_tag_rev_tag ON change_tag (ct_rev_id,ct_tag); --- Covering index, so we can pull all the info only out of the index. -CREATE INDEX change_tag_tag_id ON change_tag (ct_tag,ct_rc_id,ct_rev_id,ct_log_id); diff --git a/maintenance/ibm_db2/patch-change_tag.sql b/maintenance/ibm_db2/patch-change_tag.sql deleted file mode 100644 index 3b6f9d5481..0000000000 --- a/maintenance/ibm_db2/patch-change_tag.sql +++ /dev/null @@ -1,8 +0,0 @@ --- A table to track tags for revisions, logs and recent changes. -CREATE TABLE change_tag ( - ct_rc_id INTEGER, - ct_log_id INTEGER, - ct_rev_id INTEGER, - ct_tag varchar(255) NOT NULL, - ct_params CLOB(64K) INLINE LENGTH 4096 -); diff --git a/maintenance/ibm_db2/patch-change_tag_summary.sql b/maintenance/ibm_db2/patch-change_tag_summary.sql deleted file mode 100644 index 768cbfaa64..0000000000 --- a/maintenance/ibm_db2/patch-change_tag_summary.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Rollup table to pull a LIST of tags simply -CREATE TABLE tag_summary ( - ts_rc_id INTEGER, - ts_log_id INTEGER, - ts_rev_id INTEGER, - ts_tags CLOB(64K) INLINE LENGTH 4096 NOT NULL -); diff --git a/maintenance/ibm_db2/patch-change_valid_tag.sql b/maintenance/ibm_db2/patch-change_valid_tag.sql deleted file mode 100644 index 9bdcbc92ff..0000000000 --- a/maintenance/ibm_db2/patch-change_valid_tag.sql +++ /dev/null @@ -1,3 +0,0 @@ -CREATE TABLE valid_tag ( - vt_tag varchar(255) NOT NULL PRIMARY KEY -); diff --git a/maintenance/ibm_db2/patch-cl_collation-field.sql b/maintenance/ibm_db2/patch-cl_collation-field.sql deleted file mode 100644 index 6999dace33..0000000000 --- a/maintenance/ibm_db2/patch-cl_collation-field.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE categorylinks ADD cl_collation VARCHAR(32) FOR BIT DATA NOT NULL diff --git a/maintenance/ibm_db2/patch-cl_sortkey_prefix-field.sql b/maintenance/ibm_db2/patch-cl_sortkey_prefix-field.sql deleted file mode 100644 index 58b781475d..0000000000 --- a/maintenance/ibm_db2/patch-cl_sortkey_prefix-field.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE categorylinks ADD cl_sortkey_prefix VARCHAR(255) FOR BIT DATA NOT NULL diff --git a/maintenance/ibm_db2/patch-cl_type-field.sql b/maintenance/ibm_db2/patch-cl_type-field.sql deleted file mode 100644 index 5952c989c9..0000000000 --- a/maintenance/ibm_db2/patch-cl_type-field.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE categorylinks ADD cl_type VARCHAR(6) FOR BIT DATA NOT NULL diff --git a/maintenance/ibm_db2/patch-external_user.sql b/maintenance/ibm_db2/patch-external_user.sql deleted file mode 100644 index 96cb82373f..0000000000 --- a/maintenance/ibm_db2/patch-external_user.sql +++ /dev/null @@ -1,7 +0,0 @@ -CREATE TABLE external_user ( - -- Foreign key to user_id - eu_local_id BIGINT NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (START WITH 1), - - -- Some opaque identifier provided by the external database - eu_external_id VARCHAR(255) NOT NULL -); diff --git a/maintenance/ibm_db2/patch-ipb_allow_usertalk.sql b/maintenance/ibm_db2/patch-ipb_allow_usertalk.sql deleted file mode 100644 index 6274bb2200..0000000000 --- a/maintenance/ibm_db2/patch-ipb_allow_usertalk.sql +++ /dev/null @@ -1,23 +0,0 @@ -CREATE TABLE ipblocks ( - ipb_id INTEGER NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (START WITH 1), - --DEFAULT nextval('ipblocks_ipb_id_val'), - ipb_address VARCHAR(1024), - ipb_user BIGINT NOT NULL DEFAULT 0, - -- REFERENCES user(user_id) ON DELETE SET NULL, - ipb_by BIGINT NOT NULL DEFAULT 0, - -- REFERENCES user(user_id) ON DELETE CASCADE, - ipb_by_text VARCHAR(255) NOT NULL DEFAULT '', - ipb_reason VARCHAR(1024) NOT NULL, - ipb_timestamp TIMESTAMP(3) NOT NULL, - ipb_auto SMALLINT NOT NULL DEFAULT 0, - ipb_anon_only SMALLINT NOT NULL DEFAULT 0, - ipb_create_account SMALLINT NOT NULL DEFAULT 1, - ipb_enable_autoblock SMALLINT NOT NULL DEFAULT 1, - ipb_expiry TIMESTAMP(3) NOT NULL, - ipb_range_start VARCHAR(1024), - ipb_range_end VARCHAR(1024), - ipb_deleted SMALLINT NOT NULL DEFAULT 0, - ipb_block_email SMALLINT NOT NULL DEFAULT 0, - ipb_allow_usertalk SMALLINT NOT NULL DEFAULT 0 - -); diff --git a/maintenance/ibm_db2/patch-iw_api-field.sql b/maintenance/ibm_db2/patch-iw_api-field.sql deleted file mode 100644 index dd732a58aa..0000000000 --- a/maintenance/ibm_db2/patch-iw_api-field.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE interwiki ADD iw_api CLOB(64K) INLINE LENGTH 4096 NOT NULL diff --git a/maintenance/ibm_db2/patch-iw_api_and_wikiid.sql b/maintenance/ibm_db2/patch-iw_api_and_wikiid.sql deleted file mode 100644 index 1b1e3592d6..0000000000 --- a/maintenance/ibm_db2/patch-iw_api_and_wikiid.sql +++ /dev/null @@ -1,8 +0,0 @@ -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 -); diff --git a/maintenance/ibm_db2/patch-iw_wikiid-field.sql b/maintenance/ibm_db2/patch-iw_wikiid-field.sql deleted file mode 100644 index fe49e3c01b..0000000000 --- a/maintenance/ibm_db2/patch-iw_wikiid-field.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE interwiki ADD iw_wikiid varchar(64) NOT NULL diff --git a/maintenance/ibm_db2/patch-iwlinks.sql b/maintenance/ibm_db2/patch-iwlinks.sql deleted file mode 100644 index 2902512fb5..0000000000 --- a/maintenance/ibm_db2/patch-iwlinks.sql +++ /dev/null @@ -1,7 +0,0 @@ -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 -) -; diff --git a/maintenance/ibm_db2/patch-l10n_cache.sql b/maintenance/ibm_db2/patch-l10n_cache.sql deleted file mode 100644 index 49ebed2b32..0000000000 --- a/maintenance/ibm_db2/patch-l10n_cache.sql +++ /dev/null @@ -1,8 +0,0 @@ -CREATE TABLE l10n_cache ( - -- Language code - lc_lang VARCHAR(32) NOT NULL, - -- Cache key - lc_key VARCHAR(255) NOT NULL, - -- Value - lc_value CLOB(16M) INLINE LENGTH 4096 NOT NULL -); diff --git a/maintenance/ibm_db2/patch-log_search-rename-index.sql b/maintenance/ibm_db2/patch-log_search-rename-index.sql deleted file mode 100644 index a6a696e1d1..0000000000 --- a/maintenance/ibm_db2/patch-log_search-rename-index.sql +++ /dev/null @@ -1,8 +0,0 @@ -CREATE TABLE log_search ( - -- The type of ID (rev ID, log ID, rev TIMESTAMP(3), username) - ls_field VARCHAR(32) FOR BIT DATA NOT NULL, - -- The value of the ID - ls_value varchar(255) NOT NULL, - -- Key to log_id - ls_log_id BIGINT NOT NULL default 0 -); diff --git a/maintenance/ibm_db2/patch-log_search.sql b/maintenance/ibm_db2/patch-log_search.sql deleted file mode 100644 index a6a696e1d1..0000000000 --- a/maintenance/ibm_db2/patch-log_search.sql +++ /dev/null @@ -1,8 +0,0 @@ -CREATE TABLE log_search ( - -- The type of ID (rev ID, log ID, rev TIMESTAMP(3), username) - ls_field VARCHAR(32) FOR BIT DATA NOT NULL, - -- The value of the ID - ls_value varchar(255) NOT NULL, - -- Key to log_id - ls_log_id BIGINT NOT NULL default 0 -); diff --git a/maintenance/ibm_db2/patch-log_user_text.sql b/maintenance/ibm_db2/patch-log_user_text.sql deleted file mode 100644 index 3534057a82..0000000000 --- a/maintenance/ibm_db2/patch-log_user_text.sql +++ /dev/null @@ -1,17 +0,0 @@ -CREATE TABLE logging ( - log_id BIGINT NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (START WITH 1), - --PRIMARY KEY DEFAULT nextval('log_log_id_seq'), - log_type VARCHAR(32) NOT NULL, - log_action VARCHAR(32) NOT NULL, - log_timestamp TIMESTAMP(3) NOT NULL, - log_user BIGINT NOT NULL DEFAULT 0, - -- REFERENCES user(user_id) ON DELETE SET NULL, - -- Name of the user who performed this action - log_user_text VARCHAR(255) NOT NULL default '', - log_namespace SMALLINT NOT NULL, - log_title VARCHAR(255) NOT NULL, - log_page BIGINT, - log_comment VARCHAR(255), - log_params CLOB(64K) INLINE LENGTH 4096, - log_deleted SMALLINT NOT NULL DEFAULT 0 -); diff --git a/maintenance/ibm_db2/patch-module_deps.sql b/maintenance/ibm_db2/patch-module_deps.sql deleted file mode 100644 index 5058d1f5c3..0000000000 --- a/maintenance/ibm_db2/patch-module_deps.sql +++ /dev/null @@ -1,6 +0,0 @@ -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 -) -; diff --git a/maintenance/ibm_db2/patch-msg_resource.sql b/maintenance/ibm_db2/patch-msg_resource.sql deleted file mode 100644 index 58b3dd6c07..0000000000 --- a/maintenance/ibm_db2/patch-msg_resource.sql +++ /dev/null @@ -1,8 +0,0 @@ -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 -) -; diff --git a/maintenance/ibm_db2/patch-msg_resource_links.sql b/maintenance/ibm_db2/patch-msg_resource_links.sql deleted file mode 100644 index 4c0ff9189b..0000000000 --- a/maintenance/ibm_db2/patch-msg_resource_links.sql +++ /dev/null @@ -1,6 +0,0 @@ -CREATE TABLE "MSG_RESOURCE_LINKS" -( -"MRL_RESOURCE" VARCHAR(255) FOR BIT DATA NOT NULL , -"MRL_MESSAGE" VARCHAR(255) FOR BIT DATA NOT NULL -) -; diff --git a/maintenance/ibm_db2/patch-rd_interwiki.sql b/maintenance/ibm_db2/patch-rd_interwiki.sql deleted file mode 100644 index c162548c0d..0000000000 --- a/maintenance/ibm_db2/patch-rd_interwiki.sql +++ /dev/null @@ -1,8 +0,0 @@ -CREATE TABLE redirect ( - rd_from BIGINT NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (START WITH 1), - --REFERENCES page(page_id) ON DELETE CASCADE, - rd_namespace SMALLINT NOT NULL DEFAULT 0, - rd_title VARCHAR(255) NOT NULL DEFAULT '', - rd_interwiki varchar(32), - rd_fragment VARCHAR(255) -); diff --git a/maintenance/ibm_db2/patch-ss_active_users.sql b/maintenance/ibm_db2/patch-ss_active_users.sql deleted file mode 100644 index f0e6d145a4..0000000000 --- a/maintenance/ibm_db2/patch-ss_active_users.sql +++ /dev/null @@ -1,11 +0,0 @@ -CREATE TABLE site_stats ( - ss_row_id BIGINT NOT NULL UNIQUE, - ss_total_views BIGINT DEFAULT 0, - ss_total_edits BIGINT DEFAULT 0, - ss_good_articles BIGINT DEFAULT 0, - ss_total_pages INTEGER DEFAULT -1, - ss_users INTEGER DEFAULT -1, - ss_active_users INTEGER DEFAULT -1, - ss_admins INTEGER DEFAULT -1, - ss_images INTEGER DEFAULT 0 -); diff --git a/maintenance/ibm_db2/patch-ul_value.sql b/maintenance/ibm_db2/patch-ul_value.sql deleted file mode 100644 index cd00f8e093..0000000000 --- a/maintenance/ibm_db2/patch-ul_value.sql +++ /dev/null @@ -1,3 +0,0 @@ -CREATE TABLE updatelog ( - ul_key VARCHAR(255) NOT NULL PRIMARY KEY -); diff --git a/maintenance/ibm_db2/patch-uq61_msg_resource_links.sql b/maintenance/ibm_db2/patch-uq61_msg_resource_links.sql deleted file mode 100644 index d9185c0af0..0000000000 --- a/maintenance/ibm_db2/patch-uq61_msg_resource_links.sql +++ /dev/null @@ -1,7 +0,0 @@ -CREATE UNIQUE INDEX "UQ61_MSG_RESOURCE_LINKS" ON "MSG_RESOURCE_LINKS" -( -"MRL_MESSAGE", -"MRL_RESOURCE" -) -ALLOW REVERSE SCANS -; diff --git a/maintenance/ibm_db2/patch-uq81_msg_resource.sql b/maintenance/ibm_db2/patch-uq81_msg_resource.sql deleted file mode 100644 index 8ed85379da..0000000000 --- a/maintenance/ibm_db2/patch-uq81_msg_resource.sql +++ /dev/null @@ -1,7 +0,0 @@ -CREATE UNIQUE INDEX "UQ81_MSG_RESOURCE" ON "MSG_RESOURCE" -( -"MR_RESOURCE" -,"MR_LANG" -) -ALLOW REVERSE SCANS -; diff --git a/maintenance/ibm_db2/patch-uq96_module_deps.sql b/maintenance/ibm_db2/patch-uq96_module_deps.sql deleted file mode 100644 index e0cc879ac9..0000000000 --- a/maintenance/ibm_db2/patch-uq96_module_deps.sql +++ /dev/null @@ -1,7 +0,0 @@ -CREATE UNIQUE INDEX "UQ96_MODULE_DEPS" ON "MODULE_DEPS" -( -"MD_MODULE" -,"MD_SKIN" -) -ALLOW REVERSE SCANS -; diff --git a/maintenance/ibm_db2/patch-user_properties.sql b/maintenance/ibm_db2/patch-user_properties.sql deleted file mode 100644 index 6798604398..0000000000 --- a/maintenance/ibm_db2/patch-user_properties.sql +++ /dev/null @@ -1,10 +0,0 @@ -CREATE TABLE user_properties ( - -- Foreign key to user.user_id - up_user BIGINT NOT NULL, - - -- Name of the option being saved. This is indexed for bulk lookup. - up_property VARCHAR(32) FOR BIT DATA NOT NULL, - - -- Property value as a string. - up_value CLOB(64K) INLINE LENGTH 4096 -); diff --git a/maintenance/ibm_db2/tables.sql b/maintenance/ibm_db2/tables.sql deleted file mode 100644 index 2edb7f0178..0000000000 --- a/maintenance/ibm_db2/tables.sql +++ /dev/null @@ -1,929 +0,0 @@ --- IBM DB2 - --- SQL to create the initial tables for the MediaWiki database. --- This is read and executed by the install script; you should --- not have to run it by itself unless doing a manual install. - --- Notes: --- * DB2 will convert all table and column names to all caps internally. --- * DB2 has a 32k limit on SQL filesize, so it may be necessary --- to split this into two files soon. - - -CREATE TABLE user ( - -- Needs to 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), - user_newpassword VARCHAR(1024), - user_newpass_time TIMESTAMP(3), - user_token VARCHAR(255), - user_email VARCHAR(1024), - user_email_token VARCHAR(255), - user_email_token_expires TIMESTAMP(3), - user_email_authenticated TIMESTAMP(3), - -- obsolete, replace by user_properties table - -- user_options CLOB(64K) INLINE LENGTH 4096, - user_touched TIMESTAMP(3), - user_registration TIMESTAMP(3), - user_editcount INTEGER -); -CREATE INDEX user_email_token_idx - ON user (user_email_token); -CREATE UNIQUE INDEX user_include_idx - ON user (user_id) - INCLUDE (user_name, user_real_name, user_password, user_newpassword, - user_newpass_time, user_token, - user_email, user_email_token, user_email_token_expires, - user_email_authenticated, - user_touched, user_registration, user_editcount); -CREATE UNIQUE INDEX user_email - ON user (user_email); - - - --- Create a dummy user to satisfy fk contraints especially with revisions -INSERT INTO user( - user_name, user_real_name, user_password, user_newpassword, user_newpass_time, - user_email, user_email_authenticated, user_token, user_registration, user_editcount -) -VALUES ( - 'Anonymous', '', NULL, NULL, CURRENT_TIMESTAMP, - NULL, NULL, NULL, CURRENT_TIMESTAMP, 0 -); - - - -CREATE TABLE user_groups ( - ug_user BIGINT NOT NULL DEFAULT 0, - -- REFERENCES user(user_id) ON DELETE CASCADE, - ug_group VARCHAR(255) NOT NULL -); -CREATE INDEX user_groups_unique - ON user_groups (ug_user, ug_group); - - - -CREATE TABLE user_newtalk ( - -- registered users key - user_id BIGINT NOT NULL DEFAULT 0, - -- REFERENCES user(user_id) ON DELETE CASCADE, - -- anonymous users key - user_ip VARCHAR(40), - user_last_timestamp TIMESTAMP(3) -); -CREATE INDEX user_newtalk_id_idx - ON user_newtalk (user_id); -CREATE INDEX user_newtalk_ip_idx - ON user_newtalk (user_ip); -CREATE UNIQUE INDEX user_newtalk_include_idx - ON user_newtalk (user_id, user_ip) - INCLUDE (user_last_timestamp); - - - -CREATE TABLE page ( - page_id BIGINT - PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (START WITH 1), - page_namespace SMALLINT NOT NULL, - page_title VARCHAR(255) NOT NULL, - page_restrictions VARCHAR(1024), - page_counter BIGINT NOT NULL DEFAULT 0, - page_is_redirect SMALLINT NOT NULL DEFAULT 0, - page_is_new SMALLINT NOT NULL DEFAULT 0, - page_random NUMERIC(15,14) NOT NULL, - page_touched TIMESTAMP(3), - page_latest BIGINT NOT NULL, -- FK? - page_len BIGINT NOT NULL -); -CREATE UNIQUE INDEX page_unique_name - ON page (page_namespace, page_title); -CREATE INDEX page_random_idx - ON page (page_random); -CREATE INDEX page_len_idx - ON page (page_len); -CREATE UNIQUE INDEX page_id_include - ON page (page_id) - INCLUDE (page_namespace, page_title, page_restrictions, page_counter, page_is_redirect, page_is_new, page_random, page_touched, page_latest, page_len); -CREATE UNIQUE INDEX page_name_include - ON page (page_namespace, page_title) - INCLUDE (page_id, page_restrictions, page_counter, page_is_redirect, page_is_new, page_random, page_touched, page_latest, page_len); - - - -CREATE TABLE revision ( - rev_id BIGINT - PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (START WITH 1), - rev_page BIGINT NOT NULL DEFAULT 0, - -- REFERENCES page (page_id) ON DELETE CASCADE, - rev_text_id BIGINT, -- FK - rev_comment VARCHAR(1024), - rev_user BIGINT NOT NULL DEFAULT 0, - -- REFERENCES user(user_id) ON DELETE RESTRICT, - rev_user_text VARCHAR(255) NOT NULL, - rev_timestamp TIMESTAMP(3) NOT NULL, - rev_minor_edit SMALLINT NOT NULL DEFAULT 0, - rev_deleted SMALLINT NOT NULL DEFAULT 0, - rev_len BIGINT, - rev_parent_id BIGINT DEFAULT NULL, - rev_sha1 VARCHAR(255) NOT NULL DEFAULT '' -); -CREATE UNIQUE INDEX revision_unique - ON revision (rev_page, rev_id); -CREATE INDEX rev_text_id_idx - ON revision (rev_text_id); -CREATE INDEX rev_timestamp_idx - ON revision (rev_timestamp); -CREATE INDEX rev_user_idx - ON revision (rev_user); -CREATE INDEX rev_user_text_idx - ON revision (rev_user_text); - - - -CREATE TABLE text ( -- replaces reserved word 'text' - old_id INTEGER - PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (START WITH 1), - old_text CLOB(16M) INLINE LENGTH 4096, - old_flags VARCHAR(1024) -); - - - -CREATE TABLE page_restrictions ( - pr_id BIGINT - PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (START WITH 1), - pr_page INTEGER NOT NULL DEFAULT 0, - --(used to be nullable) - -- REFERENCES page (page_id) ON DELETE CASCADE, - pr_type VARCHAR(60) NOT NULL, - pr_level VARCHAR(60) NOT NULL, - pr_cascade SMALLINT NOT NULL, - pr_user INTEGER, - pr_expiry TIMESTAMP(3) - --PRIMARY KEY (pr_page, pr_type) -); ---ALTER TABLE page_restrictions ADD CONSTRAINT page_restrictions_pk PRIMARY KEY (pr_page, pr_type); -CREATE UNIQUE INDEX pr_pagetype - ON page_restrictions (pr_page, pr_type); -CREATE INDEX pr_typelevel - ON page_restrictions (pr_type, pr_level); -CREATE INDEX pr_level - ON page_restrictions (pr_level); -CREATE INDEX pr_cascade - ON page_restrictions (pr_cascade); - - - -CREATE TABLE page_props ( - pp_page INTEGER NOT NULL DEFAULT 0, - -- REFERENCES page (page_id) ON DELETE CASCADE, - pp_propname VARCHAR(255) NOT NULL, - pp_value CLOB(64K) INLINE LENGTH 4096 NOT NULL, - PRIMARY KEY (pp_page, pp_propname) -); -CREATE INDEX page_props_propname - ON page_props (pp_propname); - - - -CREATE TABLE archive ( - ar_namespace SMALLINT NOT NULL, - ar_title VARCHAR(255) NOT NULL, - ar_text CLOB(16M) INLINE LENGTH 4096, - ar_comment VARCHAR(1024), - ar_user BIGINT NOT NULL, - -- no foreign keys in MySQL - -- REFERENCES user(user_id) ON DELETE SET NULL, - ar_user_text VARCHAR(255) NOT NULL, - ar_timestamp TIMESTAMP(3) NOT NULL, - ar_minor_edit SMALLINT NOT NULL DEFAULT 0, - ar_flags VARCHAR(1024), - ar_rev_id INTEGER, - ar_text_id INTEGER, - ar_deleted SMALLINT NOT NULL DEFAULT 0, - ar_len INTEGER, - ar_page_id INTEGER, - ar_parent_id INTEGER, - ar_sha1 VARCHAR(255) NOT NULL DEFAULT '' -); -CREATE INDEX archive_name_title_timestamp - ON archive (ar_namespace, ar_title, ar_timestamp); -CREATE INDEX archive_user_text - ON archive (ar_user_text); - - - -CREATE TABLE redirect ( - rd_from BIGINT NOT NULL - PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (START WITH 1), - --REFERENCES page(page_id) ON DELETE CASCADE, - rd_namespace SMALLINT NOT NULL DEFAULT 0, - rd_title VARCHAR(255) NOT NULL DEFAULT '', - rd_interwiki VARCHAR(32), - rd_fragment VARCHAR(255) -); -CREATE INDEX redirect_ns_title - ON redirect (rd_namespace, rd_title, rd_from); - - -CREATE TABLE pagelinks ( - pl_from BIGINT NOT NULL DEFAULT 0, - -- REFERENCES page(page_id) ON DELETE CASCADE, - pl_namespace SMALLINT NOT NULL, - pl_title VARCHAR(255) NOT NULL -); -CREATE UNIQUE INDEX pagelink_unique - ON pagelinks (pl_from, pl_namespace, pl_title); - - - -CREATE TABLE templatelinks ( - tl_from BIGINT NOT NULL DEFAULT 0, - -- REFERENCES page(page_id) ON DELETE CASCADE, - tl_namespace SMALLINT NOT NULL, - tl_title VARCHAR(255) NOT NULL -); -CREATE UNIQUE INDEX templatelinks_unique - ON templatelinks (tl_namespace, tl_title, tl_from); -CREATE UNIQUE INDEX tl_from_idx - ON templatelinks (tl_from, tl_namespace, tl_title); - - - -CREATE TABLE imagelinks ( - il_from BIGINT NOT NULL DEFAULT 0, - -- REFERENCES page(page_id) ON DELETE CASCADE, - il_to VARCHAR(255) NOT NULL -); -CREATE UNIQUE INDEX il_from_idx - ON imagelinks (il_to, il_from); -CREATE UNIQUE INDEX il_to_idx - ON imagelinks (il_from, il_to); - - - -CREATE TABLE categorylinks ( - cl_from BIGINT NOT NULL DEFAULT 0, - -- REFERENCES page(page_id) ON DELETE CASCADE, - 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_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 externallinks ( - el_from BIGINT NOT NULL DEFAULT 0, - -- REFERENCES page(page_id) ON DELETE CASCADE, - el_to VARCHAR(1024) NOT NULL, - el_index VARCHAR(1024) NOT NULL -); -CREATE INDEX externallinks_from_to - ON externallinks (el_from, el_to); -CREATE INDEX externallinks_index - ON externallinks (el_index); - - - --- --- Track external user accounts, if ExternalAuth is used --- -CREATE TABLE external_user ( - -- Foreign key to user_id - eu_local_id BIGINT NOT NULL - PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (START WITH 1), - - -- Some opaque identifier provided by the external database - eu_external_id VARCHAR(255) NOT NULL -); -CREATE UNIQUE INDEX eu_external_id_idx - ON external_user (eu_external_id) - INCLUDE (eu_local_id); -CREATE UNIQUE INDEX eu_local_id_idx - ON external_user (eu_local_id) - INCLUDE (eu_external_id); - - - -CREATE TABLE langlinks ( - ll_from BIGINT NOT NULL DEFAULT 0, - -- REFERENCES page (page_id) ON DELETE CASCADE, - ll_lang VARCHAR(20), - ll_title VARCHAR(255) -); -CREATE UNIQUE INDEX langlinks_unique - ON langlinks (ll_from, ll_lang); -CREATE INDEX langlinks_lang_title - ON langlinks (ll_lang, ll_title); - - - -CREATE TABLE site_stats ( - ss_row_id BIGINT NOT NULL UNIQUE, - ss_total_views BIGINT DEFAULT 0, - ss_total_edits BIGINT DEFAULT 0, - ss_good_articles BIGINT DEFAULT 0, - ss_total_pages INTEGER DEFAULT -1, - ss_users INTEGER DEFAULT -1, - ss_active_users INTEGER DEFAULT -1, - ss_admins INTEGER DEFAULT -1, - ss_images INTEGER DEFAULT 0 -); - - - -CREATE TABLE hitcounter ( - hc_id BIGINT NOT NULL -); - - - -CREATE TABLE ipblocks ( - ipb_id INTEGER NOT NULL - PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (START WITH 1), - ipb_address VARCHAR(1024), - ipb_user BIGINT NOT NULL DEFAULT 0, - -- REFERENCES user(user_id) ON DELETE SET NULL, - ipb_by BIGINT NOT NULL DEFAULT 0, - -- REFERENCES user(user_id) ON DELETE CASCADE, - ipb_by_text VARCHAR(255) NOT NULL DEFAULT '', - ipb_reason VARCHAR(1024) NOT NULL, - ipb_timestamp TIMESTAMP(3) NOT NULL, - ipb_auto SMALLINT NOT NULL DEFAULT 0, - ipb_anon_only SMALLINT NOT NULL DEFAULT 0, - ipb_create_account SMALLINT NOT NULL DEFAULT 1, - ipb_enable_autoblock SMALLINT NOT NULL DEFAULT 1, - ipb_expiry TIMESTAMP(3) NOT NULL, - ipb_range_start VARCHAR(1024), - ipb_range_end VARCHAR(1024), - ipb_deleted SMALLINT NOT NULL DEFAULT 0, - ipb_block_email SMALLINT NOT NULL DEFAULT 0, - ipb_allow_usertalk SMALLINT NOT NULL DEFAULT 0, - ipb_parent_block_id INTEGER DEFAULT NULL - -- REFERENCES ipblocks(ipb_id) ON DELETE SET NULL - -); -CREATE INDEX ipb_address - ON ipblocks (ipb_address); -CREATE INDEX ipb_user - ON ipblocks (ipb_user); -CREATE INDEX ipb_range - ON ipblocks (ipb_range_start, ipb_range_end); - - - -CREATE TABLE image ( - img_name VARCHAR(255) NOT NULL - PRIMARY KEY, - img_size BIGINT NOT NULL, - img_width INTEGER NOT NULL, - img_height INTEGER NOT NULL, - img_metadata CLOB(16M) INLINE LENGTH 4096 NOT NULL DEFAULT '', - img_bits SMALLINT, - img_media_type VARCHAR(255), - img_major_mime VARCHAR(255) DEFAULT 'unknown', - img_minor_mime VARCHAR(32) DEFAULT 'unknown', - img_description VARCHAR(1024) NOT NULL DEFAULT '', - img_user BIGINT NOT NULL DEFAULT 0, - -- REFERENCES user(user_id) ON DELETE SET NULL, - img_user_text VARCHAR(255) NOT NULL DEFAULT '', - img_timestamp TIMESTAMP(3), - img_sha1 VARCHAR(255) NOT NULL DEFAULT '' -); -CREATE INDEX img_size_idx - ON image (img_size); -CREATE INDEX img_timestamp_idx - ON image (img_timestamp); -CREATE INDEX img_sha1 - ON image (img_sha1); - - -CREATE TABLE oldimage ( - oi_name VARCHAR(255) NOT NULL DEFAULT '', - oi_archive_name VARCHAR(255) NOT NULL, - oi_size BIGINT NOT NULL, - oi_width INTEGER NOT NULL, - oi_height INTEGER NOT NULL, - oi_bits SMALLINT NOT NULL, - oi_description VARCHAR(1024), - oi_user BIGINT NOT NULL DEFAULT 0, - -- REFERENCES user(user_id) ON DELETE SET NULL, - oi_user_text VARCHAR(255) NOT NULL, - oi_timestamp TIMESTAMP(3) NOT NULL, - oi_metadata CLOB(16M) INLINE LENGTH 4096 NOT NULL DEFAULT '', - oi_media_type VARCHAR(255), - oi_major_mime VARCHAR(255) NOT NULL DEFAULT 'unknown', - oi_minor_mime VARCHAR(255) NOT NULL DEFAULT 'unknown', - oi_deleted SMALLINT NOT NULL DEFAULT 0, - oi_sha1 VARCHAR(255) NOT NULL DEFAULT '' - --FOREIGN KEY (oi_name) REFERENCES image(img_name) ON DELETE CASCADE -); -CREATE INDEX oi_name_timestamp - ON oldimage (oi_name, oi_timestamp); -CREATE INDEX oi_name_archive_name - ON oldimage (oi_name, oi_archive_name); -CREATE INDEX oi_sha1 - ON oldimage (oi_sha1); - - - -CREATE TABLE filearchive ( - fa_id INTEGER NOT NULL - PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (START WITH 1), - fa_name VARCHAR(255) NOT NULL, - fa_archive_name VARCHAR(255), - fa_storage_group VARCHAR(255), - fa_storage_key VARCHAR(64) DEFAULT '', - fa_deleted_user BIGINT NOT NULL DEFAULT 0, - -- REFERENCES user(user_id) ON DELETE SET NULL, - fa_deleted_timestamp TIMESTAMP(3) NOT NULL, - fa_deleted_reason VARCHAR(255), - fa_size BIGINT NOT NULL, - fa_width INTEGER NOT NULL, - fa_height INTEGER NOT NULL, - fa_metadata CLOB(16M) INLINE LENGTH 4096 NOT NULL DEFAULT '', - fa_bits SMALLINT, - fa_media_type VARCHAR(255), - fa_major_mime VARCHAR(255) DEFAULT 'unknown', - fa_minor_mime VARCHAR(255) DEFAULT 'unknown', - fa_description VARCHAR(1024) NOT NULL, - fa_user BIGINT NOT NULL DEFAULT 0, - -- REFERENCES user(user_id) ON DELETE SET NULL, - fa_user_text VARCHAR(255) NOT NULL, - fa_timestamp TIMESTAMP(3), - fa_deleted SMALLINT NOT NULL DEFAULT 0 -); -CREATE INDEX fa_name_time - ON filearchive (fa_name, fa_timestamp); -CREATE INDEX fa_dupe - ON filearchive (fa_storage_group, fa_storage_key); -CREATE INDEX fa_notime - ON filearchive (fa_deleted_timestamp); -CREATE INDEX fa_nouser - ON filearchive (fa_deleted_user); - - - -CREATE TABLE recentchanges ( - rc_id INTEGER NOT NULL - PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (START WITH 1), - rc_timestamp TIMESTAMP(3) NOT NULL, - rc_cur_time TIMESTAMP(3) NOT NULL, - rc_user BIGINT NOT NULL DEFAULT 0, - -- REFERENCES user(user_id) ON DELETE SET NULL, - rc_user_text VARCHAR(255) NOT NULL, - rc_namespace SMALLINT NOT NULL, - rc_title VARCHAR(255) NOT NULL, - rc_comment VARCHAR(255), - rc_minor SMALLINT NOT NULL DEFAULT 0, - rc_bot SMALLINT NOT NULL DEFAULT 0, - rc_new SMALLINT NOT NULL DEFAULT 0, - rc_cur_id BIGINT NOT NULL DEFAULT 0, - -- REFERENCES page(page_id) ON DELETE SET NULL, - rc_this_oldid BIGINT NOT NULL, - rc_last_oldid BIGINT NOT NULL, - rc_type SMALLINT NOT NULL DEFAULT 0, - rc_moved_to_ns SMALLINT, - rc_moved_to_title VARCHAR(255), - rc_patrolled SMALLINT NOT NULL DEFAULT 0, - rc_ip VARCHAR(40), -- was CIDR type - rc_old_len INTEGER, - rc_new_len INTEGER, - rc_deleted SMALLINT NOT NULL DEFAULT 0, - rc_logid BIGINT NOT NULL DEFAULT 0, - rc_log_type VARCHAR(255), - rc_log_action VARCHAR(255), - rc_params CLOB(64K) INLINE LENGTH 4096 -); -CREATE INDEX rc_timestamp - ON recentchanges (rc_timestamp); -CREATE INDEX rc_namespace_title - ON recentchanges (rc_namespace, rc_title); -CREATE INDEX rc_cur_id - ON recentchanges (rc_cur_id); -CREATE INDEX new_name_timestamp - ON recentchanges (rc_new, rc_namespace, rc_timestamp); -CREATE INDEX rc_ip - ON recentchanges (rc_ip); - - - -CREATE TABLE watchlist ( - wl_user BIGINT NOT NULL DEFAULT 0, - -- REFERENCES user(user_id) ON DELETE CASCADE, - wl_namespace SMALLINT NOT NULL DEFAULT 0, - wl_title VARCHAR(255) NOT NULL, - wl_notificationtimestamp TIMESTAMP(3) -); -CREATE UNIQUE INDEX wl_user_namespace_title - ON watchlist (wl_namespace, wl_title, wl_user); - - - -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 querycache ( - qc_type VARCHAR(255) NOT NULL, - qc_value BIGINT NOT NULL, - qc_namespace INTEGER NOT NULL, - qc_title VARCHAR(255) NOT NULL -); -CREATE INDEX querycache_type_value - ON querycache (qc_type, qc_value); - - - -CREATE TABLE querycache_info ( - qci_type VARCHAR(255) UNIQUE NOT NULL, - qci_timestamp TIMESTAMP(3) -); - - - -CREATE TABLE querycachetwo ( - qcc_type VARCHAR(255) NOT NULL, - qcc_value BIGINT NOT NULL DEFAULT 0, - qcc_namespace INTEGER NOT NULL DEFAULT 0, - qcc_title VARCHAR(255) NOT NULL DEFAULT '', - qcc_namespacetwo INTEGER NOT NULL DEFAULT 0, - qcc_titletwo VARCHAR(255) NOT NULL DEFAULT '' -); -CREATE INDEX querycachetwo_type_value - ON querycachetwo (qcc_type, qcc_value); -CREATE INDEX querycachetwo_title - ON querycachetwo (qcc_type, qcc_namespace, qcc_title); -CREATE INDEX querycachetwo_titletwo - ON querycachetwo (qcc_type, qcc_namespacetwo, qcc_titletwo); - - - -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 -); -CREATE INDEX objectcacache_exptime - ON objectcache (exptime); - - - -CREATE TABLE transcache ( - tc_url VARCHAR(255) NOT NULL UNIQUE, - tc_contents CLOB(64K) INLINE LENGTH 4096 NOT NULL, - tc_time TIMESTAMP(3) NOT NULL -); - - - -CREATE TABLE logging ( - log_id BIGINT NOT NULL - PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (START WITH 1), - log_type VARCHAR(32) NOT NULL, - log_action VARCHAR(32) NOT NULL, - log_timestamp TIMESTAMP(3) NOT NULL, - log_user BIGINT NOT NULL DEFAULT 0, - -- REFERENCES user(user_id) ON DELETE SET NULL, - -- Name of the user who performed this action - log_user_text VARCHAR(255) NOT NULL DEFAULT '', - log_namespace SMALLINT NOT NULL, - log_title VARCHAR(255) NOT NULL, - log_page BIGINT, - log_comment VARCHAR(255), - log_params CLOB(64K) INLINE LENGTH 4096, - log_deleted SMALLINT NOT NULL DEFAULT 0 -); -CREATE INDEX logging_type_name - ON logging (log_type, log_timestamp); -CREATE INDEX logging_user_time - ON logging (log_timestamp, log_user); -CREATE INDEX logging_page_time - ON logging (log_namespace, log_title, log_timestamp); -CREATE INDEX log_user_type_time - ON logging (log_user, log_type, log_timestamp); -CREATE INDEX log_page_id_time - ON logging (log_page, log_timestamp); -CREATE UNIQUE INDEX type_action - ON logging (log_type, log_action, log_timestamp); - - - -CREATE TABLE trackbacks ( - tb_id INTEGER NOT NULL - PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (START WITH 1), - -- foreign key also in MySQL - tb_page INTEGER, - -- REFERENCES page(page_id) ON DELETE CASCADE, - tb_title VARCHAR(255) NOT NULL, - tb_url CLOB(64K) INLINE LENGTH 4096 NOT NULL, - tb_ex CLOB(64K) INLINE LENGTH 4096, - tb_name VARCHAR(255) -); -CREATE INDEX trackback_page - ON trackbacks (tb_page); - - - -CREATE TABLE job ( - job_id BIGINT NOT NULL - PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (START WITH 1), - job_cmd VARCHAR(255) NOT NULL, - job_namespace SMALLINT NOT NULL, - job_title VARCHAR(255) NOT NULL, - job_params CLOB(64K) INLINE LENGTH 4096 NOT NULL -); -CREATE INDEX job_cmd_namespace_title - ON job (job_cmd, job_namespace, job_title); - - - ---TODO ---CREATE FUNCTION add_interwiki (TEXT, INT, SMALLINT) RETURNS INT LANGUAGE SQL AS ---$mw$ --- INSERT INTO interwiki (iw_prefix, iw_url, iw_local) VALUES ($1,$2,$3); --- SELECT 1; ---$mw$; - - - --- hack implementation --- should be replaced with OmniFind, Contains(), etc -CREATE TABLE searchindex ( - si_page BIGINT NOT NULL, - si_title VARCHAR(255) NOT NULL DEFAULT '', - si_text CLOB NOT NULL -); - - - --- This table is not used unless profiling is turned on -CREATE TABLE profiling ( - pf_count INTEGER NOT NULL DEFAULT 0, - pf_time NUMERIC(18,10) NOT NULL DEFAULT 0, - pf_memory NUMERIC(18,10) NOT NULL DEFAULT 0, - pf_name VARCHAR(255) NOT NULL, - pf_server VARCHAR(255) -); -CREATE UNIQUE INDEX pf_name_server - ON profiling (pf_name, pf_server); - - - -CREATE TABLE protected_titles ( - pt_namespace INTEGER NOT NULL, - pt_title VARCHAR(255) NOT NULL, - pt_user BIGINT NOT NULL DEFAULT 0, - -- REFERENCES user(user_id) ON DELETE SET NULL, - pt_reason VARCHAR(1024), - pt_timestamp TIMESTAMP(3) NOT NULL, - pt_expiry TIMESTAMP(3), - pt_create_perm VARCHAR(60) NOT NULL DEFAULT '' -); -CREATE UNIQUE INDEX protected_titles_unique - ON protected_titles (pt_namespace, pt_title); - - - -CREATE TABLE updatelog ( - ul_key VARCHAR(255) NOT NULL - PRIMARY KEY -); - - - -CREATE TABLE category ( - cat_id INTEGER NOT NULL - PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (START WITH 1), - cat_title VARCHAR(255) NOT NULL, - cat_pages INTEGER NOT NULL DEFAULT 0, - cat_subcats INTEGER NOT NULL DEFAULT 0, - cat_files INTEGER NOT NULL DEFAULT 0, - cat_hidden SMALLINT NOT NULL DEFAULT 0 -); -CREATE UNIQUE INDEX category_title - ON category (cat_title); -CREATE INDEX category_pages - ON category (cat_pages); - - - --- A table to track tags for revisions, logs and recent changes. -CREATE TABLE change_tag ( - ct_rc_id INTEGER, - ct_log_id INTEGER, - ct_rev_id INTEGER, - ct_tag VARCHAR(255) NOT NULL, - ct_params CLOB(64K) INLINE LENGTH 4096 -); -CREATE UNIQUE INDEX change_tag_rc_tag - ON change_tag (ct_rc_id, ct_tag); -CREATE UNIQUE INDEX change_tag_log_tag - ON change_tag (ct_log_id, ct_tag); -CREATE UNIQUE INDEX change_tag_rev_tag - ON change_tag (ct_rev_id, ct_tag); --- Covering index, so we can pull all the info only out of the index. -CREATE INDEX change_tag_tag_id - ON change_tag (ct_tag, ct_rc_id, ct_rev_id, ct_log_id); - - - --- Rollup table to pull a LIST of tags simply -CREATE TABLE tag_summary ( - ts_rc_id INTEGER, - ts_log_id INTEGER, - ts_rev_id INTEGER, - ts_tags CLOB(64K) INLINE LENGTH 4096 NOT NULL -); -CREATE UNIQUE INDEX tag_summary_rc_id - ON tag_summary (ts_rc_id); -CREATE UNIQUE INDEX tag_summary_log_id - ON tag_summary (ts_log_id); -CREATE UNIQUE INDEX tag_summary_rev_id - ON tag_summary (ts_rev_id); - - - -CREATE TABLE valid_tag ( - vt_tag VARCHAR(255) NOT NULL - PRIMARY KEY -); - - - --- --- User preferences and perhaps other fun stuff. :) --- Replaces the old user.user_options blob, with a couple nice properties: --- --- 1) We only store non-default settings, so changes to the DEFAULTs --- are now reflected for everybody, not just new accounts. --- 2) We can more easily do bulk lookups, statistics, or modifications of --- saved options since it's a sane table structure. --- -CREATE TABLE user_properties ( - -- Foreign key to user.user_id - up_user BIGINT NOT NULL, - -- Name of the option being saved. This is indexed for bulk lookup. - up_property VARCHAR(255) FOR BIT DATA NOT NULL, - -- Property value as a string. - up_value CLOB(64K) INLINE LENGTH 4096 -); -CREATE UNIQUE INDEX user_properties_user_property - ON user_properties (up_user, up_property); -CREATE INDEX user_properties_property - ON user_properties (up_property); - -CREATE TABLE log_search ( - -- The type of ID (rev ID, log ID, rev TIMESTAMP(3), username) - ls_field VARCHAR(32) FOR BIT DATA NOT NULL, - -- The value of the ID - ls_value VARCHAR(255) NOT NULL, - -- Key to log_id - ls_log_id BIGINT NOT NULL DEFAULT 0 -); -CREATE UNIQUE INDEX ls_field_val - ON log_search (ls_field, ls_value, ls_log_id); -CREATE INDEX ls_log_id - ON log_search (ls_log_id); - - - --- Table for storing localisation data -CREATE TABLE l10n_cache ( - -- Language code - lc_lang VARCHAR(32) NOT NULL, - -- Cache key - lc_key VARCHAR(255) NOT NULL, - -- Value - lc_value CLOB(16M) INLINE LENGTH 4096 NOT NULL -); -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); --- All DB2 indexes DEFAULT to allowing 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 CLOB(64K) INLINE LENGTH 4096 NOT NULL, - mr_timestamp TIMESTAMP(3) NOT NULL -); -CREATE UNIQUE INDEX uq81_msg_resource - ON msg_resource (mr_resource, mr_lang); --- All DB2 indexes DEFAULT to allowing 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); --- All DB2 indexes DEFAULT to allowing reverse scans - - - -CREATE TABLE iwlinks -( - iwl_from INTEGER NOT NULL, - iwl_prefix VARCHAR(20) FOR BIT DATA NOT NULL, - iwl_title VARCHAR(255) FOR BIT DATA NOT NULL -); - - - --- --- Store information about newly uploaded files before they're --- moved into the actual filestore --- -CREATE TABLE uploadstash ( - us_id BIGINT NOT NULL - PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY (START WITH 1), - -- the user who uploaded the file. - us_user BIGINT NOT NULL, - -- file key. this is how applications actually search for the file. - -- this might go away, or become the primary key. - us_key VARCHAR(255) NOT NULL, - -- the original path - us_orig_path VARCHAR(255) NOT NULL, - -- the temporary path at which the file is actually stored - us_path VARCHAR(255) NOT NULL, - -- which type of upload the file came from (sometimes) - us_source_type VARCHAR(50), - -- the date/time on which the file was added - us_timestamp TIMESTAMP(3) NOT NULL, - us_status VARCHAR(50) NOT NULL, - -- file properties from File::getPropsFromPath. these may prove unnecessary. - -- - us_size BIGINT NOT NULL, - -- this hash comes from File::sha1Base36(), and is 31 characters - us_sha1 VARCHAR(31) NOT NULL, - us_mime VARCHAR(255), - -- Media type as defined by the MEDIATYPE_xxx constants, should duplicate definition in the image table - us_media_type VARCHAR(30) - CONSTRAINT my_constraint - CHECK ( - us_media_type in ( - 'UNKNOWN', 'BITMAP', 'DRAWING', 'AUDIO', 'VIDEO', 'MULTIMEDIA', - 'OFFICE', 'TEXT', 'EXECUTABLE', 'ARCHIVE' - ) - ) DEFAULT NULL, - -- image-specific properties - us_image_width BIGINT, - us_image_height BIGINT, - us_image_bits INTEGER -); --- sometimes there's a delete for all of a user's stuff. -CREATE INDEX us_user - ON uploadstash (us_user); --- pick out files by key, enforce key UNIQUEness -CREATE UNIQUE INDEX us_key - ON uploadstash (us_key); --- the abandoned upload cleanup script needs this -CREATE INDEX us_timestamp - ON uploadstash (us_timestamp); - - - --- Stores the groups the user has once belonged to. --- The user may still belong these groups. Check user_groups. -CREATE TABLE user_former_groups ( - ufg_user BIGINT NOT NULL DEFAULT 0, - ufg_group VARCHAR(16) FOR BIT DATA NOT NULL -); -CREATE UNIQUE INDEX ufg_user_group - ON user_former_groups (ufg_user, ufg_group); diff --git a/tests/phpunit/includes/TimestampTest.php b/tests/phpunit/includes/TimestampTest.php index 91c23ec638..0690683aab 100644 --- a/tests/phpunit/includes/TimestampTest.php +++ b/tests/phpunit/includes/TimestampTest.php @@ -78,7 +78,6 @@ class TimestampTest extends MediaWikiTestCase { array( TS_RFC2822, 'Tue, 31 Jul 2012 19:01:08 GMT', '20120731190108' ), array( TS_ORACLE, '31-07-2012 19:01:08.000000', '20120731190108' ), array( TS_POSTGRES, '2012-07-31 19:01:08 GMT', '20120731190108' ), - array( TS_DB2, '2012-07-31 19:01:08', '20120731190108' ), // Some extremes and weird values array( TS_ISO_8601, '9999-12-31T23:59:59Z', '99991231235959' ), array( TS_UNIX, '-62135596801', '00001231235959' ) -- 2.20.1