From 7a31146918cdceef14689bf05d8f1602ec05bfcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?coadde=20=5BM=C3=A1rcio=20Alexandre=20Silva=20Delgado=5D?= Date: Mon, 4 Jul 2016 16:01:35 -0300 Subject: remove nonfree Database support --- INSTALL | 2 - docs/database.txt | 2 - includes/db/DatabaseMssql.php | 1490 ------------------- includes/db/DatabaseOracle.php | 1546 -------------------- includes/installer/MssqlInstaller.php | 736 ---------- includes/installer/MssqlUpdater.php | 143 -- includes/installer/OracleInstaller.php | 344 ----- includes/installer/OracleUpdater.php | 289 ---- includes/libs/IEContentAnalyzer.php | 851 ----------- includes/libs/IEUrlExtension.php | 271 ---- includes/search/SearchMssql.php | 210 --- includes/search/SearchOracle.php | 273 ---- maintenance/dictionary/mediawiki.dic | 2 - maintenance/mssql/archives/named_constraints.sql | 38 - .../archives/patch-fa_major_mime-chemical.sql | 4 - .../archives/patch-img_major_mime-chemical.sql | 4 - .../archives/patch-oi_major_mime-chemical.sql | 4 - .../mssql/archives/patch-page_page_lang.sql | 1 - .../mssql/archives/patch-user_password_expires.sql | 1 - maintenance/mssql/tables.sql | 1324 ----------------- maintenance/mssql/update-keys.sql | 31 - maintenance/oracle/alterSharedConstraints.php | 95 -- .../oracle/archives/patch-ar_sha1_field.sql | 3 - .../archives/patch-archive-ar_content_format.sql | 3 - .../archives/patch-archive-ar_content_model.sql | 3 - .../oracle/archives/patch-archive-ar_id.sql | 6 - maintenance/oracle/archives/patch-cat_hidden.sql | 4 - .../oracle/archives/patch-externallinks-el_id.sql | 4 - maintenance/oracle/archives/patch-fa_sha1.sql | 5 - .../oracle/archives/patch-ipblocks_i05_index.sql | 4 - maintenance/oracle/archives/patch-job_attempts.sql | 4 - .../oracle/archives/patch-job_timestamp_field.sql | 4 - .../oracle/archives/patch-job_timestamp_index.sql | 4 - maintenance/oracle/archives/patch-job_token.sql | 12 - .../archives/patch-logging_type_action_index.sql | 4 - .../patch-logging_user_text_time_index.sql | 4 - .../patch-logging_user_text_type_time_index.sql | 4 - .../archives/patch-page-page_content_model.sql | 3 - .../oracle/archives/patch-page-page_lang.sql | 3 - .../oracle/archives/patch-page_links_updated.sql | 4 - .../archives/patch-page_redirect_namespace_len.sql | 4 - .../archives/patch-page_restrictions_pkuk_fix.sql | 7 - maintenance/oracle/archives/patch-rc_moved.sql | 4 - maintenance/oracle/archives/patch-rc_source.sql | 3 - .../oracle/archives/patch-rev_sha1_field.sql | 4 - .../archives/patch-revision-rev_content_format.sql | 3 - .../archives/patch-revision-rev_content_model.sql | 3 - .../oracle/archives/patch-revision_i05_index.sql | 4 - maintenance/oracle/archives/patch-sites.sql | 34 - maintenance/oracle/archives/patch-ss_admins.sql | 4 - maintenance/oracle/archives/patch-testrun.sql | 37 - .../patch-ufg_group-length-increase-255.sql | 9 - .../patch-ug_group-length-increase-255.sql | 9 - maintenance/oracle/archives/patch-up_property.sql | 3 - .../oracle/archives/patch-uploadstash-us_props.sql | 4 - maintenance/oracle/archives/patch-uploadstash.sql | 25 - .../oracle/archives/patch-us_chunk_inx_field.sql | 4 - .../oracle/archives/patch-user_email_index.sql | 4 - .../oracle/archives/patch-user_former_groups.sql | 9 - .../oracle/archives/patch-user_password_expire.sql | 3 - .../oracle/archives/patch_16_17_schema_changes.sql | 98 -- .../oracle/archives/patch_create_17_functions.sql | 125 -- .../oracle/archives/patch_fk_rename_deferred.sql | 40 - .../oracle/archives/patch_namespace_defaults.sql | 17 - .../oracle/archives/patch_rebuild_dupfunc.sql | 149 -- .../archives/patch_recentchanges_fk2_cascade.sql | 5 - .../archives/patch_remove_not_null_empty_defs.sql | 9 - .../archives/patch_remove_not_null_empty_defs2.sql | 3 - maintenance/oracle/patch_seq_names_pre1.16.sql | 8 - maintenance/oracle/tables.sql | 971 ------------ maintenance/oracle/update-keys.sql | 29 - maintenance/oracle/user.sql | 16 - .../includes/installer/OracleInstallerTest.php | 52 - 73 files changed, 9438 deletions(-) delete mode 100644 includes/db/DatabaseMssql.php delete mode 100644 includes/db/DatabaseOracle.php delete mode 100644 includes/installer/MssqlInstaller.php delete mode 100644 includes/installer/MssqlUpdater.php delete mode 100644 includes/installer/OracleInstaller.php delete mode 100644 includes/installer/OracleUpdater.php delete mode 100644 includes/libs/IEContentAnalyzer.php delete mode 100644 includes/libs/IEUrlExtension.php delete mode 100644 includes/search/SearchMssql.php delete mode 100644 includes/search/SearchOracle.php delete mode 100644 maintenance/mssql/archives/named_constraints.sql delete mode 100644 maintenance/mssql/archives/patch-fa_major_mime-chemical.sql delete mode 100644 maintenance/mssql/archives/patch-img_major_mime-chemical.sql delete mode 100644 maintenance/mssql/archives/patch-oi_major_mime-chemical.sql delete mode 100644 maintenance/mssql/archives/patch-page_page_lang.sql delete mode 100644 maintenance/mssql/archives/patch-user_password_expires.sql delete mode 100644 maintenance/mssql/tables.sql delete mode 100644 maintenance/mssql/update-keys.sql delete mode 100644 maintenance/oracle/alterSharedConstraints.php delete mode 100644 maintenance/oracle/archives/patch-ar_sha1_field.sql delete mode 100644 maintenance/oracle/archives/patch-archive-ar_content_format.sql delete mode 100644 maintenance/oracle/archives/patch-archive-ar_content_model.sql delete mode 100644 maintenance/oracle/archives/patch-archive-ar_id.sql delete mode 100644 maintenance/oracle/archives/patch-cat_hidden.sql delete mode 100644 maintenance/oracle/archives/patch-externallinks-el_id.sql delete mode 100644 maintenance/oracle/archives/patch-fa_sha1.sql delete mode 100644 maintenance/oracle/archives/patch-ipblocks_i05_index.sql delete mode 100644 maintenance/oracle/archives/patch-job_attempts.sql delete mode 100644 maintenance/oracle/archives/patch-job_timestamp_field.sql delete mode 100644 maintenance/oracle/archives/patch-job_timestamp_index.sql delete mode 100644 maintenance/oracle/archives/patch-job_token.sql delete mode 100644 maintenance/oracle/archives/patch-logging_type_action_index.sql delete mode 100644 maintenance/oracle/archives/patch-logging_user_text_time_index.sql delete mode 100644 maintenance/oracle/archives/patch-logging_user_text_type_time_index.sql delete mode 100644 maintenance/oracle/archives/patch-page-page_content_model.sql delete mode 100644 maintenance/oracle/archives/patch-page-page_lang.sql delete mode 100644 maintenance/oracle/archives/patch-page_links_updated.sql delete mode 100644 maintenance/oracle/archives/patch-page_redirect_namespace_len.sql delete mode 100644 maintenance/oracle/archives/patch-page_restrictions_pkuk_fix.sql delete mode 100644 maintenance/oracle/archives/patch-rc_moved.sql delete mode 100644 maintenance/oracle/archives/patch-rc_source.sql delete mode 100644 maintenance/oracle/archives/patch-rev_sha1_field.sql delete mode 100644 maintenance/oracle/archives/patch-revision-rev_content_format.sql delete mode 100644 maintenance/oracle/archives/patch-revision-rev_content_model.sql delete mode 100644 maintenance/oracle/archives/patch-revision_i05_index.sql delete mode 100644 maintenance/oracle/archives/patch-sites.sql delete mode 100644 maintenance/oracle/archives/patch-ss_admins.sql delete mode 100644 maintenance/oracle/archives/patch-testrun.sql delete mode 100644 maintenance/oracle/archives/patch-ufg_group-length-increase-255.sql delete mode 100644 maintenance/oracle/archives/patch-ug_group-length-increase-255.sql delete mode 100644 maintenance/oracle/archives/patch-up_property.sql delete mode 100644 maintenance/oracle/archives/patch-uploadstash-us_props.sql delete mode 100644 maintenance/oracle/archives/patch-uploadstash.sql delete mode 100644 maintenance/oracle/archives/patch-us_chunk_inx_field.sql delete mode 100644 maintenance/oracle/archives/patch-user_email_index.sql delete mode 100644 maintenance/oracle/archives/patch-user_former_groups.sql delete mode 100644 maintenance/oracle/archives/patch-user_password_expire.sql delete mode 100644 maintenance/oracle/archives/patch_16_17_schema_changes.sql delete mode 100644 maintenance/oracle/archives/patch_create_17_functions.sql delete mode 100644 maintenance/oracle/archives/patch_fk_rename_deferred.sql delete mode 100644 maintenance/oracle/archives/patch_namespace_defaults.sql delete mode 100644 maintenance/oracle/archives/patch_rebuild_dupfunc.sql delete mode 100644 maintenance/oracle/archives/patch_recentchanges_fk2_cascade.sql delete mode 100644 maintenance/oracle/archives/patch_remove_not_null_empty_defs.sql delete mode 100644 maintenance/oracle/archives/patch_remove_not_null_empty_defs2.sql delete mode 100644 maintenance/oracle/patch_seq_names_pre1.16.sql delete mode 100644 maintenance/oracle/tables.sql delete mode 100644 maintenance/oracle/update-keys.sql delete mode 100644 maintenance/oracle/user.sql delete mode 100644 tests/phpunit/includes/installer/OracleInstallerTest.php diff --git a/INSTALL b/INSTALL index 2054a57e..7889f9b3 100644 --- a/INSTALL +++ b/INSTALL @@ -11,8 +11,6 @@ Required software: ** MySQL 5.0.3 or higher ** PostgreSQL 8.3 or higher ** SQLite 3.3.7 or higher -** Oracle 9.0.1 or higher -** Microsoft SQL Server 2005 (9.00.1399) MediaWiki is developed and tested mainly on Unix/Linux platforms, but should work on Windows as well. diff --git a/docs/database.txt b/docs/database.txt index ba3045ed..fe287c59 100644 --- a/docs/database.txt +++ b/docs/database.txt @@ -176,8 +176,6 @@ MediaWiki does support the following other DBMSs to varying degrees. * PostgreSQL * SQLite -* Oracle -* MSSQL More information can be found about each of these databases (known issues, level of support, extra configuration) in the "databases" subdirectory in diff --git a/includes/db/DatabaseMssql.php b/includes/db/DatabaseMssql.php deleted file mode 100644 index 85f1b96d..00000000 --- a/includes/db/DatabaseMssql.php +++ /dev/null @@ -1,1490 +0,0 @@ - - * @author Chris Pucci - * @author Ryan Biesemeyer - * @author Ryan Schmidt - */ - -/** - * @ingroup Database - */ -class DatabaseMssql extends DatabaseBase { - protected $mInsertId = null; - protected $mLastResult = null; - protected $mAffectedRows = null; - protected $mSubqueryId = 0; - protected $mScrollableCursor = true; - protected $mPrepareStatements = true; - protected $mBinaryColumnCache = null; - protected $mBitColumnCache = null; - protected $mIgnoreDupKeyErrors = false; - - protected $mPort; - - public function cascadingDeletes() { - return true; - } - - public function cleanupTriggers() { - return false; - } - - public function strictIPs() { - return false; - } - - public function realTimestamps() { - return false; - } - - public function implicitGroupby() { - return false; - } - - public function implicitOrderby() { - return false; - } - - public function functionalIndexes() { - return true; - } - - public function unionSupportsOrderAndLimit() { - return false; - } - - /** - * Usually aborts on failure - * @param string $server - * @param string $user - * @param string $password - * @param string $dbName - * @throws DBConnectionError - * @return bool|DatabaseBase|null - */ - public function open( $server, $user, $password, $dbName ) { - # Test for driver support, to avoid suppressed fatal error - if ( !function_exists( 'sqlsrv_connect' ) ) { - throw new DBConnectionError( - $this, - "Microsoft SQL Server Native (sqlsrv) functions missing. - You can download the driver from: http://go.microsoft.com/fwlink/?LinkId=123470\n" - ); - } - - global $wgDBport, $wgDBWindowsAuthentication; - - # e.g. the class is being loaded - if ( !strlen( $user ) ) { - return null; - } - - $this->close(); - $this->mServer = $server; - $this->mPort = $wgDBport; - $this->mUser = $user; - $this->mPassword = $password; - $this->mDBname = $dbName; - - $connectionInfo = array(); - - if ( $dbName ) { - $connectionInfo['Database'] = $dbName; - } - - // Decide which auth scenerio to use - // if we are using Windows auth, don't add credentials to $connectionInfo - if ( !$wgDBWindowsAuthentication ) { - $connectionInfo['UID'] = $user; - $connectionInfo['PWD'] = $password; - } - - MediaWiki\suppressWarnings(); - $this->mConn = sqlsrv_connect( $server, $connectionInfo ); - MediaWiki\restoreWarnings(); - - if ( $this->mConn === false ) { - throw new DBConnectionError( $this, $this->lastError() ); - } - - $this->mOpened = true; - - return $this->mConn; - } - - /** - * Closes a database connection, if it is open - * Returns success, true if already closed - * @return bool - */ - protected function closeConnection() { - return sqlsrv_close( $this->mConn ); - } - - /** - * @param bool|MssqlResultWrapper|resource $result - * @return bool|MssqlResultWrapper - */ - public function resultObject( $result ) { - if ( empty( $result ) ) { - return false; - } elseif ( $result instanceof MssqlResultWrapper ) { - return $result; - } elseif ( $result === true ) { - // Successful write query - return $result; - } else { - return new MssqlResultWrapper( $this, $result ); - } - } - - /** - * @param string $sql - * @return bool|MssqlResult - * @throws DBUnexpectedError - */ - protected function doQuery( $sql ) { - if ( $this->debug() ) { - wfDebug( "SQL: [$sql]\n" ); - } - $this->offset = 0; - - // several extensions seem to think that all databases support limits - // via LIMIT N after the WHERE clause well, MSSQL uses SELECT TOP N, - // so to catch any of those extensions we'll do a quick check for a - // LIMIT clause and pass $sql through $this->LimitToTopN() which parses - // the limit clause and passes the result to $this->limitResult(); - if ( preg_match( '/\bLIMIT\s*/i', $sql ) ) { - // massage LIMIT -> TopN - $sql = $this->LimitToTopN( $sql ); - } - - // MSSQL doesn't have EXTRACT(epoch FROM XXX) - if ( preg_match( '#\bEXTRACT\s*?\(\s*?EPOCH\s+FROM\b#i', $sql, $matches ) ) { - // This is same as UNIX_TIMESTAMP, we need to calc # of seconds from 1970 - $sql = str_replace( $matches[0], "DATEDIFF(s,CONVERT(datetime,'1/1/1970'),", $sql ); - } - - // perform query - - // SQLSRV_CURSOR_STATIC is slower than SQLSRV_CURSOR_CLIENT_BUFFERED (one of the two is - // needed if we want to be able to seek around the result set), however CLIENT_BUFFERED - // has a bug in the sqlsrv driver where wchar_t types (such as nvarchar) that are empty - // strings make php throw a fatal error "Severe error translating Unicode" - if ( $this->mScrollableCursor ) { - $scrollArr = array( 'Scrollable' => SQLSRV_CURSOR_STATIC ); - } else { - $scrollArr = array(); - } - - if ( $this->mPrepareStatements ) { - // we do prepare + execute so we can get its field metadata for later usage if desired - $stmt = sqlsrv_prepare( $this->mConn, $sql, array(), $scrollArr ); - $success = sqlsrv_execute( $stmt ); - } else { - $stmt = sqlsrv_query( $this->mConn, $sql, array(), $scrollArr ); - $success = (bool)$stmt; - } - - if ( $this->mIgnoreDupKeyErrors ) { - // ignore duplicate key errors, but nothing else - // this emulates INSERT IGNORE in MySQL - if ( $success === false ) { - $errors = sqlsrv_errors( SQLSRV_ERR_ERRORS ); - $success = true; - - foreach ( $errors as $err ) { - if ( $err['SQLSTATE'] == '23000' && $err['code'] == '2601' ) { - continue; // duplicate key error caused by unique index - } elseif ( $err['SQLSTATE'] == '23000' && $err['code'] == '2627' ) { - continue; // duplicate key error caused by primary key - } elseif ( $err['SQLSTATE'] == '01000' && $err['code'] == '3621' ) { - continue; // generic "the statement has been terminated" error - } - - $success = false; // getting here means we got an error we weren't expecting - break; - } - - if ( $success ) { - $this->mAffectedRows = 0; - return $stmt; - } - } - } - - if ( $success === false ) { - return false; - } - // remember number of rows affected - $this->mAffectedRows = sqlsrv_rows_affected( $stmt ); - - return $stmt; - } - - public function freeResult( $res ) { - if ( $res instanceof ResultWrapper ) { - $res = $res->result; - } - - sqlsrv_free_stmt( $res ); - } - - /** - * @param MssqlResultWrapper $res - * @return stdClass - */ - public function fetchObject( $res ) { - // $res is expected to be an instance of MssqlResultWrapper here - return $res->fetchObject(); - } - - /** - * @param MssqlResultWrapper $res - * @return array - */ - public function fetchRow( $res ) { - return $res->fetchRow(); - } - - /** - * @param mixed $res - * @return int - */ - public function numRows( $res ) { - if ( $res instanceof ResultWrapper ) { - $res = $res->result; - } - - return sqlsrv_num_rows( $res ); - } - - /** - * @param mixed $res - * @return int - */ - public function numFields( $res ) { - if ( $res instanceof ResultWrapper ) { - $res = $res->result; - } - - return sqlsrv_num_fields( $res ); - } - - /** - * @param mixed $res - * @param int $n - * @return int - */ - public function fieldName( $res, $n ) { - if ( $res instanceof ResultWrapper ) { - $res = $res->result; - } - - $metadata = sqlsrv_field_metadata( $res ); - return $metadata[$n]['Name']; - } - - /** - * This must be called after nextSequenceVal - * @return int|null - */ - public function insertId() { - return $this->mInsertId; - } - - /** - * @param MssqlResultWrapper $res - * @param int $row - * @return bool - */ - public function dataSeek( $res, $row ) { - return $res->seek( $row ); - } - - /** - * @return string - */ - public function lastError() { - $strRet = ''; - $retErrors = sqlsrv_errors( SQLSRV_ERR_ALL ); - if ( $retErrors != null ) { - foreach ( $retErrors as $arrError ) { - $strRet .= $this->formatError( $arrError ) . "\n"; - } - } else { - $strRet = "No errors found"; - } - - return $strRet; - } - - /** - * @param array $err - * @return string - */ - private function formatError( $err ) { - return '[SQLSTATE ' . $err['SQLSTATE'] . '][Error Code ' . $err['code'] . ']' . $err['message']; - } - - /** - * @return string - */ - public function lastErrno() { - $err = sqlsrv_errors( SQLSRV_ERR_ALL ); - if ( $err !== null && isset( $err[0] ) ) { - return $err[0]['code']; - } else { - return 0; - } - } - - /** - * @return int - */ - public function affectedRows() { - return $this->mAffectedRows; - } - - /** - * SELECT wrapper - * - * @param mixed $table Array or string, table name(s) (prefix auto-added) - * @param mixed $vars Array or string, field name(s) to be retrieved - * @param mixed $conds Array or string, condition(s) for WHERE - * @param string $fname Calling function name (use __METHOD__) for logs/profiling - * @param array $options Associative array of options (e.g. - * array('GROUP BY' => 'page_title')), see Database::makeSelectOptions - * code for list of supported stuff - * @param array $join_conds Associative array of table join conditions - * (optional) (e.g. array( 'page' => array('LEFT JOIN','page_latest=rev_id') ) - * @return mixed Database result resource (feed to Database::fetchObject - * or whatever), or false on failure - * @throws DBQueryError - * @throws DBUnexpectedError - * @throws Exception - */ - public function select( $table, $vars, $conds = '', $fname = __METHOD__, - $options = array(), $join_conds = array() - ) { - $sql = $this->selectSQLText( $table, $vars, $conds, $fname, $options, $join_conds ); - if ( isset( $options['EXPLAIN'] ) ) { - try { - $this->mScrollableCursor = false; - $this->mPrepareStatements = false; - $this->query( "SET SHOWPLAN_ALL ON" ); - $ret = $this->query( $sql, $fname ); - $this->query( "SET SHOWPLAN_ALL OFF" ); - } catch ( DBQueryError $dqe ) { - if ( isset( $options['FOR COUNT'] ) ) { - // likely don't have privs for SHOWPLAN, so run a select count instead - $this->query( "SET SHOWPLAN_ALL OFF" ); - unset( $options['EXPLAIN'] ); - $ret = $this->select( - $table, - 'COUNT(*) AS EstimateRows', - $conds, - $fname, - $options, - $join_conds - ); - } else { - // someone actually wanted the query plan instead of an est row count - // let them know of the error - $this->mScrollableCursor = true; - $this->mPrepareStatements = true; - throw $dqe; - } - } - $this->mScrollableCursor = true; - $this->mPrepareStatements = true; - return $ret; - } - return $this->query( $sql, $fname ); - } - - /** - * SELECT wrapper - * - * @param mixed $table Array or string, table name(s) (prefix auto-added) - * @param mixed $vars Array or string, field name(s) to be retrieved - * @param mixed $conds Array or string, condition(s) for WHERE - * @param string $fname Calling function name (use __METHOD__) for logs/profiling - * @param array $options Associative array of options (e.g. array('GROUP BY' => 'page_title')), - * see Database::makeSelectOptions code for list of supported stuff - * @param array $join_conds Associative array of table join conditions (optional) - * (e.g. array( 'page' => array('LEFT JOIN','page_latest=rev_id') ) - * @return string The SQL text - */ - public function selectSQLText( $table, $vars, $conds = '', $fname = __METHOD__, - $options = array(), $join_conds = array() - ) { - if ( isset( $options['EXPLAIN'] ) ) { - unset( $options['EXPLAIN'] ); - } - - $sql = parent::selectSQLText( $table, $vars, $conds, $fname, $options, $join_conds ); - - // try to rewrite aggregations of bit columns (currently MAX and MIN) - if ( strpos( $sql, 'MAX(' ) !== false || strpos( $sql, 'MIN(' ) !== false ) { - $bitColumns = array(); - if ( is_array( $table ) ) { - foreach ( $table as $t ) { - $bitColumns += $this->getBitColumns( $this->tableName( $t ) ); - } - } else { - $bitColumns = $this->getBitColumns( $this->tableName( $table ) ); - } - - foreach ( $bitColumns as $col => $info ) { - $replace = array( - "MAX({$col})" => "MAX(CAST({$col} AS tinyint))", - "MIN({$col})" => "MIN(CAST({$col} AS tinyint))", - ); - $sql = str_replace( array_keys( $replace ), array_values( $replace ), $sql ); - } - } - - return $sql; - } - - public function deleteJoin( $delTable, $joinTable, $delVar, $joinVar, $conds, - $fname = __METHOD__ - ) { - $this->mScrollableCursor = false; - try { - parent::deleteJoin( $delTable, $joinTable, $delVar, $joinVar, $conds, $fname ); - } catch ( Exception $e ) { - $this->mScrollableCursor = true; - throw $e; - } - $this->mScrollableCursor = true; - } - - public function delete( $table, $conds, $fname = __METHOD__ ) { - $this->mScrollableCursor = false; - try { - parent::delete( $table, $conds, $fname ); - } catch ( Exception $e ) { - $this->mScrollableCursor = true; - throw $e; - } - $this->mScrollableCursor = true; - } - - /** - * Estimate rows in dataset - * Returns estimated count, based on SHOWPLAN_ALL output - * This is not necessarily an accurate estimate, so use sparingly - * Returns -1 if count cannot be found - * Takes same arguments as Database::select() - * @param string $table - * @param string $vars - * @param string $conds - * @param string $fname - * @param array $options - * @return int - */ - public function estimateRowCount( $table, $vars = '*', $conds = '', - $fname = __METHOD__, $options = array() - ) { - // http://msdn2.microsoft.com/en-us/library/aa259203.aspx - $options['EXPLAIN'] = true; - $options['FOR COUNT'] = true; - $res = $this->select( $table, $vars, $conds, $fname, $options ); - - $rows = -1; - if ( $res ) { - $row = $this->fetchRow( $res ); - - if ( isset( $row['EstimateRows'] ) ) { - $rows = (int)$row['EstimateRows']; - } - } - - return $rows; - } - - /** - * Returns information about an index - * If errors are explicitly ignored, returns NULL on failure - * @param string $table - * @param string $index - * @param string $fname - * @return array|bool|null - */ - public function indexInfo( $table, $index, $fname = __METHOD__ ) { - # This does not return the same info as MYSQL would, but that's OK - # because MediaWiki never uses the returned value except to check for - # the existance of indexes. - $sql = "sp_helpindex '" . $table . "'"; - $res = $this->query( $sql, $fname ); - if ( !$res ) { - return null; - } - - $result = array(); - foreach ( $res as $row ) { - if ( $row->index_name == $index ) { - $row->Non_unique = !stristr( $row->index_description, "unique" ); - $cols = explode( ", ", $row->index_keys ); - foreach ( $cols as $col ) { - $row->Column_name = trim( $col ); - $result[] = clone $row; - } - } elseif ( $index == 'PRIMARY' && stristr( $row->index_description, 'PRIMARY' ) ) { - $row->Non_unique = 0; - $cols = explode( ", ", $row->index_keys ); - foreach ( $cols as $col ) { - $row->Column_name = trim( $col ); - $result[] = clone $row; - } - } - } - - return empty( $result ) ? false : $result; - } - - /** - * INSERT wrapper, inserts an array into a table - * - * $arrToInsert may be a single associative array, or an array of these with numeric keys, for - * multi-row insert. - * - * Usually aborts on failure - * If errors are explicitly ignored, returns success - * @param string $table - * @param array $arrToInsert - * @param string $fname - * @param array $options - * @return bool - * @throws Exception - */ - public function insert( $table, $arrToInsert, $fname = __METHOD__, $options = array() ) { - # No rows to insert, easy just return now - if ( !count( $arrToInsert ) ) { - return true; - } - - if ( !is_array( $options ) ) { - $options = array( $options ); - } - - $table = $this->tableName( $table ); - - if ( !( isset( $arrToInsert[0] ) && is_array( $arrToInsert[0] ) ) ) { // Not multi row - $arrToInsert = array( 0 => $arrToInsert ); // make everything multi row compatible - } - - // We know the table we're inserting into, get its identity column - $identity = null; - // strip matching square brackets and the db/schema from table name - $tableRawArr = explode( '.', preg_replace( '#\[([^\]]*)\]#', '$1', $table ) ); - $tableRaw = array_pop( $tableRawArr ); - $res = $this->doQuery( - "SELECT NAME AS idColumn FROM SYS.IDENTITY_COLUMNS " . - "WHERE OBJECT_NAME(OBJECT_ID)='{$tableRaw}'" - ); - if ( $res && sqlsrv_has_rows( $res ) ) { - // There is an identity for this table. - $identityArr = sqlsrv_fetch_array( $res, SQLSRV_FETCH_ASSOC ); - $identity = array_pop( $identityArr ); - } - sqlsrv_free_stmt( $res ); - - // Determine binary/varbinary fields so we can encode data as a hex string like 0xABCDEF - $binaryColumns = $this->getBinaryColumns( $table ); - - // INSERT IGNORE is not supported by SQL Server - // remove IGNORE from options list and set ignore flag to true - if ( in_array( 'IGNORE', $options ) ) { - $options = array_diff( $options, array( 'IGNORE' ) ); - $this->mIgnoreDupKeyErrors = true; - } - - foreach ( $arrToInsert as $a ) { - // start out with empty identity column, this is so we can return - // it as a result of the insert logic - $sqlPre = ''; - $sqlPost = ''; - $identityClause = ''; - - // if we have an identity column - if ( $identity ) { - // iterate through - foreach ( $a as $k => $v ) { - if ( $k == $identity ) { - if ( !is_null( $v ) ) { - // there is a value being passed to us, - // we need to turn on and off inserted identity - $sqlPre = "SET IDENTITY_INSERT $table ON;"; - $sqlPost = ";SET IDENTITY_INSERT $table OFF;"; - } else { - // we can't insert NULL into an identity column, - // so remove the column from the insert. - unset( $a[$k] ); - } - } - } - - // we want to output an identity column as result - $identityClause = "OUTPUT INSERTED.$identity "; - } - - $keys = array_keys( $a ); - - // Build the actual query - $sql = $sqlPre . 'INSERT ' . implode( ' ', $options ) . - " INTO $table (" . implode( ',', $keys ) . ") $identityClause VALUES ("; - - $first = true; - foreach ( $a as $key => $value ) { - if ( isset( $binaryColumns[$key] ) ) { - $value = new MssqlBlob( $value ); - } - if ( $first ) { - $first = false; - } else { - $sql .= ','; - } - if ( is_null( $value ) ) { - $sql .= 'null'; - } elseif ( is_array( $value ) || is_object( $value ) ) { - if ( is_object( $value ) && $value instanceof Blob ) { - $sql .= $this->addQuotes( $value ); - } else { - $sql .= $this->addQuotes( serialize( $value ) ); - } - } else { - $sql .= $this->addQuotes( $value ); - } - } - $sql .= ')' . $sqlPost; - - // Run the query - $this->mScrollableCursor = false; - try { - $ret = $this->query( $sql ); - } catch ( Exception $e ) { - $this->mScrollableCursor = true; - $this->mIgnoreDupKeyErrors = false; - throw $e; - } - $this->mScrollableCursor = true; - - if ( !is_null( $identity ) ) { - // then we want to get the identity column value we were assigned and save it off - $row = $ret->fetchObject(); - if ( is_object( $row ) ) { - $this->mInsertId = $row->$identity; - } - } - } - $this->mIgnoreDupKeyErrors = false; - return $ret; - } - - /** - * INSERT SELECT wrapper - * $varMap must be an associative array of the form array( 'dest1' => 'source1', ...) - * Source items may be literals rather than field names, but strings should - * be quoted with Database::addQuotes(). - * @param string $destTable - * @param array|string $srcTable May be an array of tables. - * @param array $varMap - * @param array $conds May be "*" to copy the whole table. - * @param string $fname - * @param array $insertOptions - * @param array $selectOptions - * @return null|ResultWrapper - * @throws Exception - */ - public function insertSelect( $destTable, $srcTable, $varMap, $conds, $fname = __METHOD__, - $insertOptions = array(), $selectOptions = array() - ) { - $this->mScrollableCursor = false; - try { - $ret = parent::insertSelect( - $destTable, - $srcTable, - $varMap, - $conds, - $fname, - $insertOptions, - $selectOptions - ); - } catch ( Exception $e ) { - $this->mScrollableCursor = true; - throw $e; - } - $this->mScrollableCursor = true; - - return $ret; - } - - /** - * UPDATE wrapper. Takes a condition array and a SET array. - * - * @param string $table Name of the table to UPDATE. This will be passed through - * DatabaseBase::tableName(). - * - * @param array $values An array of values to SET. For each array element, - * the key gives the field name, and the value gives the data - * to set that field to. The data will be quoted by - * DatabaseBase::addQuotes(). - * - * @param array $conds An array of conditions (WHERE). See - * DatabaseBase::select() for the details of the format of - * condition arrays. Use '*' to update all rows. - * - * @param string $fname The function name of the caller (from __METHOD__), - * for logging and profiling. - * - * @param array $options An array of UPDATE options, can be: - * - IGNORE: Ignore unique key conflicts - * - LOW_PRIORITY: MySQL-specific, see MySQL manual. - * @return bool - * @throws DBUnexpectedError - * @throws Exception - * @throws MWException - */ - function update( $table, $values, $conds, $fname = __METHOD__, $options = array() ) { - $table = $this->tableName( $table ); - $binaryColumns = $this->getBinaryColumns( $table ); - - $opts = $this->makeUpdateOptions( $options ); - $sql = "UPDATE $opts $table SET " . $this->makeList( $values, LIST_SET, $binaryColumns ); - - if ( $conds !== array() && $conds !== '*' ) { - $sql .= " WHERE " . $this->makeList( $conds, LIST_AND, $binaryColumns ); - } - - $this->mScrollableCursor = false; - try { - $ret = $this->query( $sql ); - } catch ( Exception $e ) { - $this->mScrollableCursor = true; - throw $e; - } - $this->mScrollableCursor = true; - return true; - } - - /** - * Makes an encoded list of strings from an array - * @param array $a Containing the data - * @param int $mode Constant - * - LIST_COMMA: comma separated, no field names - * - LIST_AND: ANDed WHERE clause (without the WHERE). See - * the documentation for $conds in DatabaseBase::select(). - * - 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 - * @param array $binaryColumns Contains a list of column names that are binary types - * This is a custom parameter only present for MS SQL. - * - * @throws MWException|DBUnexpectedError - * @return string - */ - public function makeList( $a, $mode = LIST_COMMA, $binaryColumns = array() ) { - if ( !is_array( $a ) ) { - throw new DBUnexpectedError( $this, - 'DatabaseBase::makeList called with incorrect parameters' ); - } - - if ( $mode != LIST_NAMES ) { - // In MS SQL, values need to be specially encoded when they are - // inserted into binary fields. Perform this necessary encoding - // for the specified set of columns. - foreach ( array_keys( $a ) as $field ) { - if ( !isset( $binaryColumns[$field] ) ) { - continue; - } - - if ( is_array( $a[$field] ) ) { - foreach ( $a[$field] as &$v ) { - $v = new MssqlBlob( $v ); - } - unset( $v ); - } else { - $a[$field] = new MssqlBlob( $a[$field] ); - } - } - } - - return parent::makeList( $a, $mode ); - } - - /** - * @param string $table - * @param string $field - * @return int Returns the size of a text field, or -1 for "unlimited" - */ - public function textFieldSize( $table, $field ) { - $table = $this->tableName( $table ); - $sql = "SELECT CHARACTER_MAXIMUM_LENGTH,DATA_TYPE FROM INFORMATION_SCHEMA.Columns - WHERE TABLE_NAME = '$table' AND COLUMN_NAME = '$field'"; - $res = $this->query( $sql ); - $row = $this->fetchRow( $res ); - $size = -1; - if ( strtolower( $row['DATA_TYPE'] ) != 'text' ) { - $size = $row['CHARACTER_MAXIMUM_LENGTH']; - } - - return $size; - } - - /** - * Construct a LIMIT query with optional offset - * This is used for query pages - * - * @param string $sql SQL query we will append the limit too - * @param int $limit The SQL limit - * @param bool|int $offset The SQL offset (default false) - * @return array|string - * @throws DBUnexpectedError - */ - public function limitResult( $sql, $limit, $offset = false ) { - if ( $offset === false || $offset == 0 ) { - if ( strpos( $sql, "SELECT" ) === false ) { - return "TOP {$limit} " . $sql; - } else { - return preg_replace( '/\bSELECT(\s+DISTINCT)?\b/Dsi', - 'SELECT$1 TOP ' . $limit, $sql, 1 ); - } - } else { - // This one is fun, we need to pull out the select list as well as any ORDER BY clause - $select = $orderby = array(); - $s1 = preg_match( '#SELECT\s+(.+?)\s+FROM#Dis', $sql, $select ); - $s2 = preg_match( '#(ORDER BY\s+.+?)(\s*FOR XML .*)?$#Dis', $sql, $orderby ); - $overOrder = $postOrder = ''; - $first = $offset + 1; - $last = $offset + $limit; - $sub1 = 'sub_' . $this->mSubqueryId; - $sub2 = 'sub_' . ( $this->mSubqueryId + 1 ); - $this->mSubqueryId += 2; - if ( !$s1 ) { - // wat - throw new DBUnexpectedError( $this, "Attempting to LIMIT a non-SELECT query\n" ); - } - if ( !$s2 ) { - // no ORDER BY - $overOrder = 'ORDER BY (SELECT 1)'; - } else { - if ( !isset( $orderby[2] ) || !$orderby[2] ) { - // don't need to strip it out if we're using a FOR XML clause - $sql = str_replace( $orderby[1], '', $sql ); - } - $overOrder = $orderby[1]; - $postOrder = ' ' . $overOrder; - } - $sql = "SELECT {$select[1]} - FROM ( - SELECT ROW_NUMBER() OVER({$overOrder}) AS rowNumber, * - FROM ({$sql}) {$sub1} - ) {$sub2} - WHERE rowNumber BETWEEN {$first} AND {$last}{$postOrder}"; - - return $sql; - } - } - - /** - * If there is a limit clause, parse it, strip it, and pass the remaining - * SQL through limitResult() with the appropriate parameters. Not the - * prettiest solution, but better than building a whole new parser. This - * exists becase there are still too many extensions that don't use dynamic - * sql generation. - * - * @param string $sql - * @return array|mixed|string - */ - public function LimitToTopN( $sql ) { - // Matches: LIMIT {[offset,] row_count | row_count OFFSET offset} - $pattern = '/\bLIMIT\s+((([0-9]+)\s*,\s*)?([0-9]+)(\s+OFFSET\s+([0-9]+))?)/i'; - if ( preg_match( $pattern, $sql, $matches ) ) { - $row_count = $matches[4]; - $offset = $matches[3] ?: $matches[6] ?: false; - - // strip the matching LIMIT clause out - $sql = str_replace( $matches[0], '', $sql ); - - return $this->limitResult( $sql, $row_count, $offset ); - } - - return $sql; - } - - /** - * @return string Wikitext of a link to the server software's web site - */ - public function getSoftwareLink() { - return "[{{int:version-db-mssql-url}} MS SQL Server]"; - } - - /** - * @return string Version information from the database - */ - public function getServerVersion() { - $server_info = sqlsrv_server_info( $this->mConn ); - $version = 'Error'; - if ( isset( $server_info['SQLServerVersion'] ) ) { - $version = $server_info['SQLServerVersion']; - } - - return $version; - } - - /** - * @param string $table - * @param string $fname - * @return bool - */ - public function tableExists( $table, $fname = __METHOD__ ) { - list( $db, $schema, $table ) = $this->tableName( $table, 'split' ); - - if ( $db !== false ) { - // remote database - wfDebug( "Attempting to call tableExists on a remote table" ); - return false; - } - - if ( $schema === false ) { - global $wgDBmwschema; - $schema = $wgDBmwschema; - } - - $res = $this->query( "SELECT 1 FROM INFORMATION_SCHEMA.TABLES - WHERE TABLE_TYPE = 'BASE TABLE' - AND TABLE_SCHEMA = '$schema' AND TABLE_NAME = '$table'" ); - - if ( $res->numRows() ) { - return true; - } else { - return false; - } - } - - /** - * Query whether a given column exists in the mediawiki schema - * @param string $table - * @param string $field - * @param string $fname - * @return bool - */ - public function fieldExists( $table, $field, $fname = __METHOD__ ) { - list( $db, $schema, $table ) = $this->tableName( $table, 'split' ); - - if ( $db !== false ) { - // remote database - wfDebug( "Attempting to call fieldExists on a remote table" ); - return false; - } - - $res = $this->query( "SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS - WHERE TABLE_SCHEMA = '$schema' AND TABLE_NAME = '$table' AND COLUMN_NAME = '$field'" ); - - if ( $res->numRows() ) { - return true; - } else { - return false; - } - } - - public function fieldInfo( $table, $field ) { - list( $db, $schema, $table ) = $this->tableName( $table, 'split' ); - - if ( $db !== false ) { - // remote database - wfDebug( "Attempting to call fieldInfo on a remote table" ); - return false; - } - - $res = $this->query( "SELECT * FROM INFORMATION_SCHEMA.COLUMNS - WHERE TABLE_SCHEMA = '$schema' AND TABLE_NAME = '$table' AND COLUMN_NAME = '$field'" ); - - $meta = $res->fetchRow(); - if ( $meta ) { - return new MssqlField( $meta ); - } - - return false; - } - - /** - * Begin a transaction, committing any previously open transaction - * @param string $fname - */ - protected function doBegin( $fname = __METHOD__ ) { - sqlsrv_begin_transaction( $this->mConn ); - $this->mTrxLevel = 1; - } - - /** - * End a transaction - * @param string $fname - */ - protected function doCommit( $fname = __METHOD__ ) { - sqlsrv_commit( $this->mConn ); - $this->mTrxLevel = 0; - } - - /** - * Rollback a transaction. - * No-op on non-transactional databases. - * @param string $fname - */ - protected function doRollback( $fname = __METHOD__ ) { - sqlsrv_rollback( $this->mConn ); - $this->mTrxLevel = 0; - } - - /** - * Escapes a identifier for use inm SQL. - * Throws an exception if it is invalid. - * Reference: http://msdn.microsoft.com/en-us/library/aa224033%28v=SQL.80%29.aspx - * @param string $identifier - * @throws MWException - * @return string - */ - private function escapeIdentifier( $identifier ) { - if ( strlen( $identifier ) == 0 ) { - throw new MWException( "An identifier must not be empty" ); - } - if ( strlen( $identifier ) > 128 ) { - throw new MWException( "The identifier '$identifier' is too long (max. 128)" ); - } - if ( ( strpos( $identifier, '[' ) !== false ) - || ( strpos( $identifier, ']' ) !== false ) - ) { - // It may be allowed if you quoted with double quotation marks, but - // that would break if QUOTED_IDENTIFIER is OFF - throw new MWException( "Square brackets are not allowed in '$identifier'" ); - } - - return "[$identifier]"; - } - - /** - * @param string $s - * @return string - */ - public function strencode( $s ) { - // Should not be called by us - - return str_replace( "'", "''", $s ); - } - - /** - * @param string|Blob $s - * @return string - */ - public function addQuotes( $s ) { - if ( $s instanceof MssqlBlob ) { - return $s->fetch(); - } elseif ( $s instanceof Blob ) { - // this shouldn't really ever be called, but it's here if needed - // (and will quite possibly make the SQL error out) - $blob = new MssqlBlob( $s->fetch() ); - return $blob->fetch(); - } else { - if ( is_bool( $s ) ) { - $s = $s ? 1 : 0; - } - return parent::addQuotes( $s ); - } - } - - /** - * @param string $s - * @return string - */ - public function addIdentifierQuotes( $s ) { - // http://msdn.microsoft.com/en-us/library/aa223962.aspx - return '[' . $s . ']'; - } - - /** - * @param string $name - * @return bool - */ - public function isQuotedIdentifier( $name ) { - return strlen( $name ) && $name[0] == '[' && substr( $name, -1, 1 ) == ']'; - } - - /** - * @param string $db - * @return bool - */ - public function selectDB( $db ) { - try { - $this->mDBname = $db; - $this->query( "USE $db" ); - return true; - } catch ( Exception $e ) { - return false; - } - } - - /** - * @param array $options An associative array of options to be turned into - * an SQL query, valid keys are listed in the function. - * @return array - */ - public function makeSelectOptions( $options ) { - $tailOpts = ''; - $startOpts = ''; - - $noKeyOptions = array(); - foreach ( $options as $key => $option ) { - if ( is_numeric( $key ) ) { - $noKeyOptions[$option] = true; - } - } - - $tailOpts .= $this->makeGroupByWithHaving( $options ); - - $tailOpts .= $this->makeOrderBy( $options ); - - if ( isset( $noKeyOptions['DISTINCT'] ) || isset( $noKeyOptions['DISTINCTROW'] ) ) { - $startOpts .= 'DISTINCT'; - } - - if ( isset( $noKeyOptions['FOR XML'] ) ) { - // used in group concat field emulation - $tailOpts .= " FOR XML PATH('')"; - } - - // we want this to be compatible with the output of parent::makeSelectOptions() - return array( $startOpts, '', $tailOpts, '' ); - } - - /** - * Get the type of the DBMS, as it appears in $wgDBtype. - * @return string - */ - public function getType() { - return 'mssql'; - } - - /** - * @param array $stringList - * @return string - */ - public function buildConcat( $stringList ) { - return implode( ' + ', $stringList ); - } - - /** - * Build a GROUP_CONCAT or equivalent statement for a query. - * MS SQL doesn't have GROUP_CONCAT so we emulate it with other stuff (and boy is it nasty) - * - * This is useful for combining a field for several rows into a single string. - * NULL values will not appear in the output, duplicated values will appear, - * and the resulting delimiter-separated values have no defined sort order. - * Code using the results may need to use the PHP unique() or sort() methods. - * - * @param string $delim Glue to bind the results together - * @param string|array $table Table name - * @param string $field Field name - * @param string|array $conds Conditions - * @param string|array $join_conds Join conditions - * @return string SQL text - * @since 1.23 - */ - public function buildGroupConcatField( $delim, $table, $field, $conds = '', - $join_conds = array() - ) { - $gcsq = 'gcsq_' . $this->mSubqueryId; - $this->mSubqueryId++; - - $delimLen = strlen( $delim ); - $fld = "{$field} + {$this->addQuotes( $delim )}"; - $sql = "(SELECT LEFT({$field}, LEN({$field}) - {$delimLen}) FROM (" - . $this->selectSQLText( $table, $fld, $conds, null, array( 'FOR XML' ), $join_conds ) - . ") {$gcsq} ({$field}))"; - - return $sql; - } - - /** - * @return string - */ - public function getSearchEngine() { - return "SearchMssql"; - } - - /** - * Returns an associative array for fields that are of type varbinary, binary, or image - * $table can be either a raw table name or passed through tableName() first - * @param string $table - * @return array - */ - private function getBinaryColumns( $table ) { - $tableRawArr = explode( '.', preg_replace( '#\[([^\]]*)\]#', '$1', $table ) ); - $tableRaw = array_pop( $tableRawArr ); - - if ( $this->mBinaryColumnCache === null ) { - $this->populateColumnCaches(); - } - - return isset( $this->mBinaryColumnCache[$tableRaw] ) - ? $this->mBinaryColumnCache[$tableRaw] - : array(); - } - - /** - * @param string $table - * @return array - */ - private function getBitColumns( $table ) { - $tableRawArr = explode( '.', preg_replace( '#\[([^\]]*)\]#', '$1', $table ) ); - $tableRaw = array_pop( $tableRawArr ); - - if ( $this->mBitColumnCache === null ) { - $this->populateColumnCaches(); - } - - return isset( $this->mBitColumnCache[$tableRaw] ) - ? $this->mBitColumnCache[$tableRaw] - : array(); - } - - private function populateColumnCaches() { - $res = $this->select( 'INFORMATION_SCHEMA.COLUMNS', '*', - array( - 'TABLE_CATALOG' => $this->mDBname, - 'TABLE_SCHEMA' => $this->mSchema, - 'DATA_TYPE' => array( 'varbinary', 'binary', 'image', 'bit' ) - ) ); - - $this->mBinaryColumnCache = array(); - $this->mBitColumnCache = array(); - foreach ( $res as $row ) { - if ( $row->DATA_TYPE == 'bit' ) { - $this->mBitColumnCache[$row->TABLE_NAME][$row->COLUMN_NAME] = $row; - } else { - $this->mBinaryColumnCache[$row->TABLE_NAME][$row->COLUMN_NAME] = $row; - } - } - } - - /** - * @param string $name - * @param string $format - * @return string - */ - function tableName( $name, $format = 'quoted' ) { - # Replace reserved words with better ones - switch ( $name ) { - case 'user': - return $this->realTableName( 'mwuser', $format ); - default: - return $this->realTableName( $name, $format ); - } - } - - /** - * call this instead of tableName() in the updater when renaming tables - * @param string $name - * @param string $format One of quoted, raw, or split - * @return string - */ - function realTableName( $name, $format = 'quoted' ) { - $table = parent::tableName( $name, $format ); - if ( $format == 'split' ) { - // Used internally, we want the schema split off from the table name and returned - // as a list with 3 elements (database, schema, table) - $table = explode( '.', $table ); - while ( count( $table ) < 3 ) { - array_unshift( $table, false ); - } - } - return $table; - } - - /** - * Called in the installer and updater. - * Probably doesn't need to be called anywhere else in the codebase. - * @param bool|null $value - * @return bool|null - */ - public function prepareStatements( $value = null ) { - return wfSetVar( $this->mPrepareStatements, $value ); - } - - /** - * Called in the installer and updater. - * Probably doesn't need to be called anywhere else in the codebase. - * @param bool|null $value - * @return bool|null - */ - public function scrollableCursor( $value = null ) { - return wfSetVar( $this->mScrollableCursor, $value ); - } -} // end DatabaseMssql class - -/** - * Utility class. - * - * @ingroup Database - */ -class MssqlField implements Field { - private $name, $tableName, $default, $max_length, $nullable, $type; - - function __construct( $info ) { - $this->name = $info['COLUMN_NAME']; - $this->tableName = $info['TABLE_NAME']; - $this->default = $info['COLUMN_DEFAULT']; - $this->max_length = $info['CHARACTER_MAXIMUM_LENGTH']; - $this->nullable = !( strtolower( $info['IS_NULLABLE'] ) == 'no' ); - $this->type = $info['DATA_TYPE']; - } - - function name() { - return $this->name; - } - - function tableName() { - return $this->tableName; - } - - function defaultValue() { - return $this->default; - } - - function maxLength() { - return $this->max_length; - } - - function isNullable() { - return $this->nullable; - } - - function type() { - return $this->type; - } -} - -class MssqlBlob extends Blob { - public function __construct( $data ) { - if ( $data instanceof MssqlBlob ) { - return $data; - } elseif ( $data instanceof Blob ) { - $this->mData = $data->fetch(); - } elseif ( is_array( $data ) && is_object( $data ) ) { - $this->mData = serialize( $data ); - } else { - $this->mData = $data; - } - } - - /** - * Returns an unquoted hex representation of a binary string - * for insertion into varbinary-type fields - * @return string - */ - public function fetch() { - if ( $this->mData === null ) { - return 'null'; - } - - $ret = '0x'; - $dataLength = strlen( $this->mData ); - for ( $i = 0; $i < $dataLength; $i++ ) { - $ret .= bin2hex( pack( 'C', ord( $this->mData[$i] ) ) ); - } - - return $ret; - } -} - -class MssqlResultWrapper extends ResultWrapper { - private $mSeekTo = null; - - /** - * @return stdClass|bool - */ - public function fetchObject() { - $res = $this->result; - - if ( $this->mSeekTo !== null ) { - $result = sqlsrv_fetch_object( $res, 'stdClass', array(), - SQLSRV_SCROLL_ABSOLUTE, $this->mSeekTo ); - $this->mSeekTo = null; - } else { - $result = sqlsrv_fetch_object( $res ); - } - - // MediaWiki expects us to return boolean false when there are no more rows instead of null - if ( $result === null ) { - return false; - } - - return $result; - } - - /** - * @return array|bool - */ - public function fetchRow() { - $res = $this->result; - - if ( $this->mSeekTo !== null ) { - $result = sqlsrv_fetch_array( $res, SQLSRV_FETCH_BOTH, - SQLSRV_SCROLL_ABSOLUTE, $this->mSeekTo ); - $this->mSeekTo = null; - } else { - $result = sqlsrv_fetch_array( $res ); - } - - // MediaWiki expects us to return boolean false when there are no more rows instead of null - if ( $result === null ) { - return false; - } - - return $result; - } - - /** - * @param int $row - * @return bool - */ - public function seek( $row ) { - $res = $this->result; - - // check bounds - $numRows = $this->db->numRows( $res ); - $row = intval( $row ); - - if ( $numRows === 0 ) { - return false; - } elseif ( $row < 0 || $row > $numRows - 1 ) { - return false; - } - - // Unlike MySQL, the seek actually happens on the next access - $this->mSeekTo = $row; - return true; - } -} diff --git a/includes/db/DatabaseOracle.php b/includes/db/DatabaseOracle.php deleted file mode 100644 index 87c31646..00000000 --- a/includes/db/DatabaseOracle.php +++ /dev/null @@ -1,1546 +0,0 @@ -db =& $db; - - $this->nrows = oci_fetch_all( $stmt, $this->rows, 0, -1, OCI_FETCHSTATEMENT_BY_ROW | OCI_NUM ); - if ( $this->nrows === false ) { - $e = oci_error( $stmt ); - $db->reportQueryError( $e['message'], $e['code'], '', __METHOD__ ); - $this->free(); - - return; - } - - if ( $unique ) { - $this->rows = $this->array_unique_md( $this->rows ); - $this->nrows = count( $this->rows ); - } - - if ( $this->nrows > 0 ) { - foreach ( $this->rows[0] as $k => $v ) { - $this->columns[$k] = strtolower( oci_field_name( $stmt, $k + 1 ) ); - } - } - - $this->cursor = 0; - oci_free_statement( $stmt ); - } - - public function free() { - unset( $this->db ); - } - - public function seek( $row ) { - $this->cursor = min( $row, $this->nrows ); - } - - public function numRows() { - return $this->nrows; - } - - public function numFields() { - return count( $this->columns ); - } - - public function fetchObject() { - if ( $this->cursor >= $this->nrows ) { - return false; - } - $row = $this->rows[$this->cursor++]; - $ret = new stdClass(); - foreach ( $row as $k => $v ) { - $lc = $this->columns[$k]; - $ret->$lc = $v; - } - - return $ret; - } - - public function fetchRow() { - if ( $this->cursor >= $this->nrows ) { - return false; - } - - $row = $this->rows[$this->cursor++]; - $ret = array(); - foreach ( $row as $k => $v ) { - $lc = $this->columns[$k]; - $ret[$lc] = $v; - $ret[$k] = $v; - } - - return $ret; - } -} - -/** - * Utility class. - * @ingroup Database - */ -class ORAField implements Field { - private $name, $tablename, $default, $max_length, $nullable, - $is_pk, $is_unique, $is_multiple, $is_key, $type; - - function __construct( $info ) { - $this->name = $info['column_name']; - $this->tablename = $info['table_name']; - $this->default = $info['data_default']; - $this->max_length = $info['data_length']; - $this->nullable = $info['not_null']; - $this->is_pk = isset( $info['prim'] ) && $info['prim'] == 1 ? 1 : 0; - $this->is_unique = isset( $info['uniq'] ) && $info['uniq'] == 1 ? 1 : 0; - $this->is_multiple = isset( $info['nonuniq'] ) && $info['nonuniq'] == 1 ? 1 : 0; - $this->is_key = ( $this->is_pk || $this->is_unique || $this->is_multiple ); - $this->type = $info['data_type']; - } - - function name() { - return $this->name; - } - - function tableName() { - return $this->tablename; - } - - function defaultValue() { - return $this->default; - } - - function maxLength() { - return $this->max_length; - } - - function isNullable() { - return $this->nullable; - } - - function isKey() { - return $this->is_key; - } - - function isMultipleKey() { - return $this->is_multiple; - } - - function type() { - return $this->type; - } -} - -/** - * @ingroup Database - */ -class DatabaseOracle extends DatabaseBase { - /** @var resource */ - protected $mLastResult = null; - - /** @var int The number of rows affected as an integer */ - protected $mAffectedRows; - - /** @var int */ - private $mInsertId = null; - - /** @var bool */ - private $ignoreDupValOnIndex = false; - - /** @var bool|array */ - private $sequenceData = null; - - /** @var string Character set for Oracle database */ - private $defaultCharset = 'AL32UTF8'; - - /** @var array */ - private $mFieldInfoCache = array(); - - function __construct( array $p ) { - global $wgDBprefix; - - if ( $p['tablePrefix'] == 'get from global' ) { - $p['tablePrefix'] = $wgDBprefix; - } - $p['tablePrefix'] = strtoupper( $p['tablePrefix'] ); - parent::__construct( $p ); - Hooks::run( 'DatabaseOraclePostInit', array( $this ) ); - } - - function __destruct() { - if ( $this->mOpened ) { - MediaWiki\suppressWarnings(); - $this->close(); - MediaWiki\restoreWarnings(); - } - } - - function getType() { - return 'oracle'; - } - - function cascadingDeletes() { - return true; - } - - function cleanupTriggers() { - return true; - } - - function strictIPs() { - return true; - } - - function realTimestamps() { - return true; - } - - function implicitGroupby() { - return false; - } - - function implicitOrderby() { - return false; - } - - function searchableIPs() { - return true; - } - - /** - * Usually aborts on failure - * @param string $server - * @param string $user - * @param string $password - * @param string $dbName - * @throws DBConnectionError - * @return DatabaseBase|null - */ - function open( $server, $user, $password, $dbName ) { - global $wgDBOracleDRCP; - if ( !function_exists( 'oci_connect' ) ) { - throw new DBConnectionError( - $this, - "Oracle functions missing, have you compiled PHP with the --with-oci8 option?\n " . - "(Note: if you recently installed PHP, you may need to restart your webserver\n " . - "and database)\n" ); - } - - $this->close(); - $this->mUser = $user; - $this->mPassword = $password; - // changed internal variables functions - // mServer now holds the TNS endpoint - // mDBname is schema name if different from username - if ( !$server ) { - // backward compatibillity (server used to be null and TNS was supplied in dbname) - $this->mServer = $dbName; - $this->mDBname = $user; - } else { - $this->mServer = $server; - if ( !$dbName ) { - $this->mDBname = $user; - } else { - $this->mDBname = $dbName; - } - } - - if ( !strlen( $user ) ) { # e.g. the class is being loaded - return null; - } - - if ( $wgDBOracleDRCP ) { - $this->setFlag( DBO_PERSISTENT ); - } - - $session_mode = $this->mFlags & DBO_SYSDBA ? OCI_SYSDBA : OCI_DEFAULT; - - MediaWiki\suppressWarnings(); - if ( $this->mFlags & DBO_PERSISTENT ) { - $this->mConn = oci_pconnect( - $this->mUser, - $this->mPassword, - $this->mServer, - $this->defaultCharset, - $session_mode - ); - } elseif ( $this->mFlags & DBO_DEFAULT ) { - $this->mConn = oci_new_connect( - $this->mUser, - $this->mPassword, - $this->mServer, - $this->defaultCharset, - $session_mode - ); - } else { - $this->mConn = oci_connect( - $this->mUser, - $this->mPassword, - $this->mServer, - $this->defaultCharset, - $session_mode - ); - } - MediaWiki\restoreWarnings(); - - if ( $this->mUser != $this->mDBname ) { - //change current schema in session - $this->selectDB( $this->mDBname ); - } - - if ( !$this->mConn ) { - throw new DBConnectionError( $this, $this->lastError() ); - } - - $this->mOpened = true; - - # removed putenv calls because they interfere with the system globaly - $this->doQuery( 'ALTER SESSION SET NLS_TIMESTAMP_FORMAT=\'DD-MM-YYYY HH24:MI:SS.FF6\'' ); - $this->doQuery( 'ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT=\'DD-MM-YYYY HH24:MI:SS.FF6\'' ); - $this->doQuery( 'ALTER SESSION SET NLS_NUMERIC_CHARACTERS=\'.,\'' ); - - return $this->mConn; - } - - /** - * Closes a database connection, if it is open - * Returns success, true if already closed - * @return bool - */ - protected function closeConnection() { - return oci_close( $this->mConn ); - } - - function execFlags() { - return $this->mTrxLevel ? OCI_NO_AUTO_COMMIT : OCI_COMMIT_ON_SUCCESS; - } - - protected function doQuery( $sql ) { - wfDebug( "SQL: [$sql]\n" ); - if ( !StringUtils::isUtf8( $sql ) ) { - throw new MWException( "SQL encoding is invalid\n$sql" ); - } - - // handle some oracle specifics - // remove AS column/table/subquery namings - if ( !$this->getFlag( DBO_DDLMODE ) ) { - $sql = preg_replace( '/ as /i', ' ', $sql ); - } - - // Oracle has issues with UNION clause if the statement includes LOB fields - // So we do a UNION ALL and then filter the results array with array_unique - $union_unique = ( preg_match( '/\/\* UNION_UNIQUE \*\/ /', $sql ) != 0 ); - // EXPLAIN syntax in Oracle is EXPLAIN PLAN FOR and it return nothing - // you have to select data from plan table after explain - $explain_id = MWTimestamp::getLocalInstance()->format( 'dmYHis' ); - - $sql = preg_replace( - '/^EXPLAIN /', - 'EXPLAIN PLAN SET STATEMENT_ID = \'' . $explain_id . '\' FOR', - $sql, - 1, - $explain_count - ); - - MediaWiki\suppressWarnings(); - - if ( ( $this->mLastResult = $stmt = oci_parse( $this->mConn, $sql ) ) === false ) { - $e = oci_error( $this->mConn ); - $this->reportQueryError( $e['message'], $e['code'], $sql, __METHOD__ ); - - return false; - } - - if ( !oci_execute( $stmt, $this->execFlags() ) ) { - $e = oci_error( $stmt ); - if ( !$this->ignoreDupValOnIndex || $e['code'] != '1' ) { - $this->reportQueryError( $e['message'], $e['code'], $sql, __METHOD__ ); - - return false; - } - } - - MediaWiki\restoreWarnings(); - - if ( $explain_count > 0 ) { - return $this->doQuery( 'SELECT id, cardinality "ROWS" FROM plan_table ' . - 'WHERE statement_id = \'' . $explain_id . '\'' ); - } elseif ( oci_statement_type( $stmt ) == 'SELECT' ) { - return new ORAResult( $this, $stmt, $union_unique ); - } else { - $this->mAffectedRows = oci_num_rows( $stmt ); - - return true; - } - } - - function queryIgnore( $sql, $fname = '' ) { - return $this->query( $sql, $fname, true ); - } - - /** - * Frees resources associated with the LOB descriptor - * @param ResultWrapper|resource $res - */ - function freeResult( $res ) { - if ( $res instanceof ResultWrapper ) { - $res = $res->result; - } - - $res->free(); - } - - /** - * @param ResultWrapper|stdClass $res - * @return mixed - */ - function fetchObject( $res ) { - if ( $res instanceof ResultWrapper ) { - $res = $res->result; - } - - return $res->fetchObject(); - } - - function fetchRow( $res ) { - if ( $res instanceof ResultWrapper ) { - $res = $res->result; - } - - return $res->fetchRow(); - } - - function numRows( $res ) { - if ( $res instanceof ResultWrapper ) { - $res = $res->result; - } - - return $res->numRows(); - } - - function numFields( $res ) { - if ( $res instanceof ResultWrapper ) { - $res = $res->result; - } - - return $res->numFields(); - } - - function fieldName( $stmt, $n ) { - return oci_field_name( $stmt, $n ); - } - - /** - * This must be called after nextSequenceVal - * @return null|int - */ - function insertId() { - return $this->mInsertId; - } - - /** - * @param mixed $res - * @param int $row - */ - function dataSeek( $res, $row ) { - if ( $res instanceof ORAResult ) { - $res->seek( $row ); - } else { - $res->result->seek( $row ); - } - } - - function lastError() { - if ( $this->mConn === false ) { - $e = oci_error(); - } else { - $e = oci_error( $this->mConn ); - } - - return $e['message']; - } - - function lastErrno() { - if ( $this->mConn === false ) { - $e = oci_error(); - } else { - $e = oci_error( $this->mConn ); - } - - return $e['code']; - } - - function affectedRows() { - return $this->mAffectedRows; - } - - /** - * Returns information about an index - * If errors are explicitly ignored, returns NULL on failure - * @param string $table - * @param string $index - * @param string $fname - * @return bool - */ - function indexInfo( $table, $index, $fname = __METHOD__ ) { - return false; - } - - function indexUnique( $table, $index, $fname = __METHOD__ ) { - return false; - } - - function insert( $table, $a, $fname = __METHOD__, $options = array() ) { - if ( !count( $a ) ) { - return true; - } - - if ( !is_array( $options ) ) { - $options = array( $options ); - } - - if ( in_array( 'IGNORE', $options ) ) { - $this->ignoreDupValOnIndex = true; - } - - if ( !is_array( reset( $a ) ) ) { - $a = array( $a ); - } - - foreach ( $a as &$row ) { - $this->insertOneRow( $table, $row, $fname ); - } - $retVal = true; - - if ( in_array( 'IGNORE', $options ) ) { - $this->ignoreDupValOnIndex = false; - } - - return $retVal; - } - - private function fieldBindStatement( $table, $col, &$val, $includeCol = false ) { - $col_info = $this->fieldInfoMulti( $table, $col ); - $col_type = $col_info != false ? $col_info->type() : 'CONSTANT'; - - $bind = ''; - if ( is_numeric( $col ) ) { - $bind = $val; - $val = null; - - return $bind; - } elseif ( $includeCol ) { - $bind = "$col = "; - } - - if ( $val == '' && $val !== 0 && $col_type != 'BLOB' && $col_type != 'CLOB' ) { - $val = null; - } - - if ( $val === 'NULL' ) { - $val = null; - } - - if ( $val === null ) { - if ( $col_info != false && $col_info->isNullable() == 0 && $col_info->defaultValue() != null ) { - $bind .= 'DEFAULT'; - } else { - $bind .= 'NULL'; - } - } else { - $bind .= ':' . $col; - } - - return $bind; - } - - /** - * @param string $table - * @param array $row - * @param string $fname - * @return bool - * @throws DBUnexpectedError - */ - private function insertOneRow( $table, $row, $fname ) { - global $wgContLang; - - $table = $this->tableName( $table ); - // "INSERT INTO tables (a, b, c)" - $sql = "INSERT INTO " . $table . " (" . join( ',', array_keys( $row ) ) . ')'; - $sql .= " VALUES ("; - - // for each value, append ":key" - $first = true; - foreach ( $row as $col => &$val ) { - if ( !$first ) { - $sql .= ', '; - } else { - $first = false; - } - if ( $this->isQuotedIdentifier( $val ) ) { - $sql .= $this->removeIdentifierQuotes( $val ); - unset( $row[$col] ); - } else { - $sql .= $this->fieldBindStatement( $table, $col, $val ); - } - } - $sql .= ')'; - - if ( ( $this->mLastResult = $stmt = oci_parse( $this->mConn, $sql ) ) === false ) { - $e = oci_error( $this->mConn ); - $this->reportQueryError( $e['message'], $e['code'], $sql, __METHOD__ ); - - return false; - } - foreach ( $row as $col => &$val ) { - $col_info = $this->fieldInfoMulti( $table, $col ); - $col_type = $col_info != false ? $col_info->type() : 'CONSTANT'; - - if ( $val === null ) { - // do nothing ... null was inserted in statement creation - } elseif ( $col_type != 'BLOB' && $col_type != 'CLOB' ) { - if ( is_object( $val ) ) { - $val = $val->fetch(); - } - - // backward compatibility - if ( preg_match( '/^timestamp.*/i', $col_type ) == 1 && strtolower( $val ) == 'infinity' ) { - $val = $this->getInfinity(); - } - - $val = ( $wgContLang != null ) ? $wgContLang->checkTitleEncoding( $val ) : $val; - if ( oci_bind_by_name( $stmt, ":$col", $val, -1, SQLT_CHR ) === false ) { - $e = oci_error( $stmt ); - $this->reportQueryError( $e['message'], $e['code'], $sql, __METHOD__ ); - - return false; - } - } else { - /** @var OCI_Lob[] $lob */ - if ( ( $lob[$col] = oci_new_descriptor( $this->mConn, OCI_D_LOB ) ) === false ) { - $e = oci_error( $stmt ); - throw new DBUnexpectedError( $this, "Cannot create LOB descriptor: " . $e['message'] ); - } - - if ( is_object( $val ) ) { - $val = $val->fetch(); - } - - if ( $col_type == 'BLOB' ) { - $lob[$col]->writeTemporary( $val, OCI_TEMP_BLOB ); - oci_bind_by_name( $stmt, ":$col", $lob[$col], -1, OCI_B_BLOB ); - } else { - $lob[$col]->writeTemporary( $val, OCI_TEMP_CLOB ); - oci_bind_by_name( $stmt, ":$col", $lob[$col], -1, OCI_B_CLOB ); - } - } - } - - MediaWiki\suppressWarnings(); - - if ( oci_execute( $stmt, $this->execFlags() ) === false ) { - $e = oci_error( $stmt ); - if ( !$this->ignoreDupValOnIndex || $e['code'] != '1' ) { - $this->reportQueryError( $e['message'], $e['code'], $sql, __METHOD__ ); - - return false; - } else { - $this->mAffectedRows = oci_num_rows( $stmt ); - } - } else { - $this->mAffectedRows = oci_num_rows( $stmt ); - } - - MediaWiki\restoreWarnings(); - - if ( isset( $lob ) ) { - foreach ( $lob as $lob_v ) { - $lob_v->free(); - } - } - - if ( !$this->mTrxLevel ) { - oci_commit( $this->mConn ); - } - - return oci_free_statement( $stmt ); - } - - function insertSelect( $destTable, $srcTable, $varMap, $conds, $fname = __METHOD__, - $insertOptions = array(), $selectOptions = array() - ) { - $destTable = $this->tableName( $destTable ); - if ( !is_array( $selectOptions ) ) { - $selectOptions = array( $selectOptions ); - } - list( $startOpts, $useIndex, $tailOpts ) = $this->makeSelectOptions( $selectOptions ); - if ( is_array( $srcTable ) ) { - $srcTable = implode( ',', array_map( array( &$this, 'tableName' ), $srcTable ) ); - } else { - $srcTable = $this->tableName( $srcTable ); - } - - if ( ( $sequenceData = $this->getSequenceData( $destTable ) ) !== false && - !isset( $varMap[$sequenceData['column']] ) - ) { - $varMap[$sequenceData['column']] = 'GET_SEQUENCE_VALUE(\'' . $sequenceData['sequence'] . '\')'; - } - - // count-alias subselect fields to avoid abigious definition errors - $i = 0; - foreach ( $varMap as &$val ) { - $val = $val . ' field' . ( $i++ ); - } - - $sql = "INSERT INTO $destTable (" . implode( ',', array_keys( $varMap ) ) . ')' . - " SELECT $startOpts " . implode( ',', $varMap ) . - " FROM $srcTable $useIndex "; - if ( $conds != '*' ) { - $sql .= ' WHERE ' . $this->makeList( $conds, LIST_AND ); - } - $sql .= " $tailOpts"; - - if ( in_array( 'IGNORE', $insertOptions ) ) { - $this->ignoreDupValOnIndex = true; - } - - $retval = $this->query( $sql, $fname ); - - if ( in_array( 'IGNORE', $insertOptions ) ) { - $this->ignoreDupValOnIndex = false; - } - - return $retval; - } - - public function upsert( $table, array $rows, array $uniqueIndexes, array $set, - $fname = __METHOD__ - ) { - if ( !count( $rows ) ) { - return true; // nothing to do - } - - if ( !is_array( reset( $rows ) ) ) { - $rows = array( $rows ); - } - - $sequenceData = $this->getSequenceData( $table ); - if ( $sequenceData !== false ) { - // add sequence column to each list of columns, when not set - foreach ( $rows as &$row ) { - if ( !isset( $row[$sequenceData['column']] ) ) { - $row[$sequenceData['column']] = - $this->addIdentifierQuotes( 'GET_SEQUENCE_VALUE(\'' . - $sequenceData['sequence'] . '\')' ); - } - } - } - - return parent::upsert( $table, $rows, $uniqueIndexes, $set, $fname ); - } - - function tableName( $name, $format = 'quoted' ) { - /* - Replace reserved words with better ones - Using uppercase because that's the only way Oracle can handle - quoted tablenames - */ - switch ( $name ) { - case 'user': - $name = 'MWUSER'; - break; - case 'text': - $name = 'PAGECONTENT'; - break; - } - - return strtoupper( parent::tableName( $name, $format ) ); - } - - function tableNameInternal( $name ) { - $name = $this->tableName( $name ); - - return preg_replace( '/.*\.(.*)/', '$1', $name ); - } - - /** - * Return the next in a sequence, save the value for retrieval via insertId() - * - * @param string $seqName - * @return null|int - */ - function nextSequenceValue( $seqName ) { - $res = $this->query( "SELECT $seqName.nextval FROM dual" ); - $row = $this->fetchRow( $res ); - $this->mInsertId = $row[0]; - - return $this->mInsertId; - } - - /** - * Return sequence_name if table has a sequence - * - * @param string $table - * @return bool - */ - private function getSequenceData( $table ) { - if ( $this->sequenceData == null ) { - $result = $this->doQuery( "SELECT lower(asq.sequence_name), - lower(atc.table_name), - lower(atc.column_name) - FROM all_sequences asq, all_tab_columns atc - WHERE decode( - atc.table_name, - '{$this->mTablePrefix}MWUSER', - '{$this->mTablePrefix}USER', - atc.table_name - ) || '_' || - atc.column_name || '_SEQ' = '{$this->mTablePrefix}' || asq.sequence_name - AND asq.sequence_owner = upper('{$this->mDBname}') - AND atc.owner = upper('{$this->mDBname}')" ); - - while ( ( $row = $result->fetchRow() ) !== false ) { - $this->sequenceData[$row[1]] = array( - 'sequence' => $row[0], - 'column' => $row[2] - ); - } - } - $table = strtolower( $this->removeIdentifierQuotes( $this->tableName( $table ) ) ); - - return ( isset( $this->sequenceData[$table] ) ) ? $this->sequenceData[$table] : false; - } - - /** - * Returns the size of a text field, or -1 for "unlimited" - * - * @param string $table - * @param string $field - * @return mixed - */ - function textFieldSize( $table, $field ) { - $fieldInfoData = $this->fieldInfo( $table, $field ); - - return $fieldInfoData->maxLength(); - } - - function limitResult( $sql, $limit, $offset = false ) { - if ( $offset === false ) { - $offset = 0; - } - - return "SELECT * FROM ($sql) WHERE rownum >= (1 + $offset) AND rownum < (1 + $limit + $offset)"; - } - - function encodeBlob( $b ) { - return new Blob( $b ); - } - - function decodeBlob( $b ) { - if ( $b instanceof Blob ) { - $b = $b->fetch(); - } - - return $b; - } - - function unionQueries( $sqls, $all ) { - $glue = ' UNION ALL '; - - return 'SELECT * ' . ( $all ? '' : '/* UNION_UNIQUE */ ' ) . - 'FROM (' . implode( $glue, $sqls ) . ')'; - } - - function wasDeadlock() { - return $this->lastErrno() == 'OCI-00060'; - } - - function duplicateTableStructure( $oldName, $newName, $temporary = false, - $fname = __METHOD__ - ) { - $temporary = $temporary ? 'TRUE' : 'FALSE'; - - $newName = strtoupper( $newName ); - $oldName = strtoupper( $oldName ); - - $tabName = substr( $newName, strlen( $this->mTablePrefix ) ); - $oldPrefix = substr( $oldName, 0, strlen( $oldName ) - strlen( $tabName ) ); - $newPrefix = strtoupper( $this->mTablePrefix ); - - return $this->doQuery( "BEGIN DUPLICATE_TABLE( '$tabName', " . - "'$oldPrefix', '$newPrefix', $temporary ); END;" ); - } - - function listTables( $prefix = null, $fname = __METHOD__ ) { - $listWhere = ''; - if ( !empty( $prefix ) ) { - $listWhere = ' AND table_name LIKE \'' . strtoupper( $prefix ) . '%\''; - } - - $owner = strtoupper( $this->mDBname ); - $result = $this->doQuery( "SELECT table_name FROM all_tables " . - "WHERE owner='$owner' AND table_name NOT LIKE '%!_IDX\$_' ESCAPE '!' $listWhere" ); - - // dirty code ... i know - $endArray = array(); - $endArray[] = strtoupper( $prefix . 'MWUSER' ); - $endArray[] = strtoupper( $prefix . 'PAGE' ); - $endArray[] = strtoupper( $prefix . 'IMAGE' ); - $fixedOrderTabs = $endArray; - while ( ( $row = $result->fetchRow() ) !== false ) { - if ( !in_array( $row['table_name'], $fixedOrderTabs ) ) { - $endArray[] = $row['table_name']; - } - } - - return $endArray; - } - - public function dropTable( $tableName, $fName = __METHOD__ ) { - $tableName = $this->tableName( $tableName ); - if ( !$this->tableExists( $tableName ) ) { - return false; - } - - return $this->doQuery( "DROP TABLE $tableName CASCADE CONSTRAINTS PURGE" ); - } - - function timestamp( $ts = 0 ) { - return wfTimestamp( TS_ORACLE, $ts ); - } - - /** - * Return aggregated value function call - * - * @param array $valuedata - * @param string $valuename - * @return mixed - */ - public function aggregateValue( $valuedata, $valuename = 'value' ) { - return $valuedata; - } - - /** - * @return string Wikitext of a link to the server software's web site - */ - public function getSoftwareLink() { - return '[{{int:version-db-oracle-url}} Oracle]'; - } - - /** - * @return string Version information from the database - */ - function getServerVersion() { - //better version number, fallback on driver - $rset = $this->doQuery( - 'SELECT version FROM product_component_version ' . - 'WHERE UPPER(product) LIKE \'ORACLE DATABASE%\'' - ); - if ( !( $row = $rset->fetchRow() ) ) { - return oci_server_version( $this->mConn ); - } - - return $row['version']; - } - - /** - * Query whether a given index exists - * @param string $table - * @param string $index - * @param string $fname - * @return bool - */ - function indexExists( $table, $index, $fname = __METHOD__ ) { - $table = $this->tableName( $table ); - $table = strtoupper( $this->removeIdentifierQuotes( $table ) ); - $index = strtoupper( $index ); - $owner = strtoupper( $this->mDBname ); - $sql = "SELECT 1 FROM all_indexes WHERE owner='$owner' AND index_name='{$table}_{$index}'"; - $res = $this->doQuery( $sql ); - if ( $res ) { - $count = $res->numRows(); - $res->free(); - } else { - $count = 0; - } - - return $count != 0; - } - - /** - * Query whether a given table exists (in the given schema, or the default mw one if not given) - * @param string $table - * @param string $fname - * @return bool - */ - function tableExists( $table, $fname = __METHOD__ ) { - $table = $this->tableName( $table ); - $table = $this->addQuotes( strtoupper( $this->removeIdentifierQuotes( $table ) ) ); - $owner = $this->addQuotes( strtoupper( $this->mDBname ) ); - $sql = "SELECT 1 FROM all_tables WHERE owner=$owner AND table_name=$table"; - $res = $this->doQuery( $sql ); - if ( $res && $res->numRows() > 0 ) { - $exists = true; - } else { - $exists = false; - } - - $res->free(); - - return $exists; - } - - /** - * Function translates mysql_fetch_field() functionality on ORACLE. - * Caching is present for reducing query time. - * For internal calls. Use fieldInfo for normal usage. - * Returns false if the field doesn't exist - * - * @param array|string $table - * @param string $field - * @return ORAField|ORAResult - */ - private function fieldInfoMulti( $table, $field ) { - $field = strtoupper( $field ); - if ( is_array( $table ) ) { - $table = array_map( array( &$this, 'tableNameInternal' ), $table ); - $tableWhere = 'IN ('; - foreach ( $table as &$singleTable ) { - $singleTable = $this->removeIdentifierQuotes( $singleTable ); - if ( isset( $this->mFieldInfoCache["$singleTable.$field"] ) ) { - return $this->mFieldInfoCache["$singleTable.$field"]; - } - $tableWhere .= '\'' . $singleTable . '\','; - } - $tableWhere = rtrim( $tableWhere, ',' ) . ')'; - } else { - $table = $this->removeIdentifierQuotes( $this->tableNameInternal( $table ) ); - if ( isset( $this->mFieldInfoCache["$table.$field"] ) ) { - return $this->mFieldInfoCache["$table.$field"]; - } - $tableWhere = '= \'' . $table . '\''; - } - - $fieldInfoStmt = oci_parse( - $this->mConn, - 'SELECT * FROM wiki_field_info_full WHERE table_name ' . - $tableWhere . ' and column_name = \'' . $field . '\'' - ); - if ( oci_execute( $fieldInfoStmt, $this->execFlags() ) === false ) { - $e = oci_error( $fieldInfoStmt ); - $this->reportQueryError( $e['message'], $e['code'], 'fieldInfo QUERY', __METHOD__ ); - - return false; - } - $res = new ORAResult( $this, $fieldInfoStmt ); - if ( $res->numRows() == 0 ) { - if ( is_array( $table ) ) { - foreach ( $table as &$singleTable ) { - $this->mFieldInfoCache["$singleTable.$field"] = false; - } - } else { - $this->mFieldInfoCache["$table.$field"] = false; - } - $fieldInfoTemp = null; - } else { - $fieldInfoTemp = new ORAField( $res->fetchRow() ); - $table = $fieldInfoTemp->tableName(); - $this->mFieldInfoCache["$table.$field"] = $fieldInfoTemp; - } - $res->free(); - - return $fieldInfoTemp; - } - - /** - * @throws DBUnexpectedError - * @param string $table - * @param string $field - * @return ORAField - */ - function fieldInfo( $table, $field ) { - if ( is_array( $table ) ) { - throw new DBUnexpectedError( $this, 'DatabaseOracle::fieldInfo called with table array!' ); - } - - return $this->fieldInfoMulti( $table, $field ); - } - - protected function doBegin( $fname = __METHOD__ ) { - $this->mTrxLevel = 1; - $this->doQuery( 'SET CONSTRAINTS ALL DEFERRED' ); - } - - protected function doCommit( $fname = __METHOD__ ) { - if ( $this->mTrxLevel ) { - $ret = oci_commit( $this->mConn ); - if ( !$ret ) { - throw new DBUnexpectedError( $this, $this->lastError() ); - } - $this->mTrxLevel = 0; - $this->doQuery( 'SET CONSTRAINTS ALL IMMEDIATE' ); - } - } - - protected function doRollback( $fname = __METHOD__ ) { - if ( $this->mTrxLevel ) { - oci_rollback( $this->mConn ); - $this->mTrxLevel = 0; - $this->doQuery( 'SET CONSTRAINTS ALL IMMEDIATE' ); - } - } - - /** - * defines must comply with ^define\s*([^\s=]*)\s*=\s?'\{\$([^\}]*)\}'; - * - * @param resource $fp - * @param bool|string $lineCallback - * @param bool|callable $resultCallback - * @param string $fname - * @param bool|callable $inputCallback - * @return bool|string - */ - function sourceStream( $fp, $lineCallback = false, $resultCallback = false, - $fname = __METHOD__, $inputCallback = false ) { - $cmd = ''; - $done = false; - $dollarquote = false; - - $replacements = array(); - - while ( !feof( $fp ) ) { - if ( $lineCallback ) { - call_user_func( $lineCallback ); - } - $line = trim( fgets( $fp, 1024 ) ); - $sl = strlen( $line ) - 1; - - if ( $sl < 0 ) { - continue; - } - if ( '-' == $line[0] && '-' == $line[1] ) { - continue; - } - - // Allow dollar quoting for function declarations - if ( substr( $line, 0, 8 ) == '/*$mw$*/' ) { - if ( $dollarquote ) { - $dollarquote = false; - $line = str_replace( '/*$mw$*/', '', $line ); // remove dollarquotes - $done = true; - } else { - $dollarquote = true; - } - } elseif ( !$dollarquote ) { - if ( ';' == $line[$sl] && ( $sl < 2 || ';' != $line[$sl - 1] ) ) { - $done = true; - $line = substr( $line, 0, $sl ); - } - } - - if ( $cmd != '' ) { - $cmd .= ' '; - } - $cmd .= "$line\n"; - - if ( $done ) { - $cmd = str_replace( ';;', ";", $cmd ); - if ( strtolower( substr( $cmd, 0, 6 ) ) == 'define' ) { - if ( preg_match( '/^define\s*([^\s=]*)\s*=\s*\'\{\$([^\}]*)\}\'/', $cmd, $defines ) ) { - $replacements[$defines[2]] = $defines[1]; - } - } else { - foreach ( $replacements as $mwVar => $scVar ) { - $cmd = str_replace( '&' . $scVar . '.', '`{$' . $mwVar . '}`', $cmd ); - } - - $cmd = $this->replaceVars( $cmd ); - if ( $inputCallback ) { - call_user_func( $inputCallback, $cmd ); - } - $res = $this->doQuery( $cmd ); - if ( $resultCallback ) { - call_user_func( $resultCallback, $res, $this ); - } - - if ( false === $res ) { - $err = $this->lastError(); - - return "Query \"{$cmd}\" failed with error code \"$err\".\n"; - } - } - - $cmd = ''; - $done = false; - } - } - - return true; - } - - function selectDB( $db ) { - $this->mDBname = $db; - if ( $db == null || $db == $this->mUser ) { - return true; - } - $sql = 'ALTER SESSION SET CURRENT_SCHEMA=' . strtoupper( $db ); - $stmt = oci_parse( $this->mConn, $sql ); - MediaWiki\suppressWarnings(); - $success = oci_execute( $stmt ); - MediaWiki\restoreWarnings(); - if ( !$success ) { - $e = oci_error( $stmt ); - if ( $e['code'] != '1435' ) { - $this->reportQueryError( $e['message'], $e['code'], $sql, __METHOD__ ); - } - - return false; - } - - return true; - } - - function strencode( $s ) { - return str_replace( "'", "''", $s ); - } - - function addQuotes( $s ) { - global $wgContLang; - if ( isset( $wgContLang->mLoaded ) && $wgContLang->mLoaded ) { - $s = $wgContLang->checkTitleEncoding( $s ); - } - - return "'" . $this->strencode( $s ) . "'"; - } - - public function addIdentifierQuotes( $s ) { - if ( !$this->getFlag( DBO_DDLMODE ) ) { - $s = '/*Q*/' . $s; - } - - return $s; - } - - public function removeIdentifierQuotes( $s ) { - return strpos( $s, '/*Q*/' ) === false ? $s : substr( $s, 5 ); - } - - public function isQuotedIdentifier( $s ) { - return strpos( $s, '/*Q*/' ) !== false; - } - - private function wrapFieldForWhere( $table, &$col, &$val ) { - global $wgContLang; - - $col_info = $this->fieldInfoMulti( $table, $col ); - $col_type = $col_info != false ? $col_info->type() : 'CONSTANT'; - if ( $col_type == 'CLOB' ) { - $col = 'TO_CHAR(' . $col . ')'; - $val = $wgContLang->checkTitleEncoding( $val ); - } elseif ( $col_type == 'VARCHAR2' ) { - $val = $wgContLang->checkTitleEncoding( $val ); - } - } - - private function wrapConditionsForWhere( $table, $conds, $parentCol = null ) { - $conds2 = array(); - foreach ( $conds as $col => $val ) { - if ( is_array( $val ) ) { - $conds2[$col] = $this->wrapConditionsForWhere( $table, $val, $col ); - } else { - if ( is_numeric( $col ) && $parentCol != null ) { - $this->wrapFieldForWhere( $table, $parentCol, $val ); - } else { - $this->wrapFieldForWhere( $table, $col, $val ); - } - $conds2[$col] = $val; - } - } - - return $conds2; - } - - function selectRow( $table, $vars, $conds, $fname = __METHOD__, - $options = array(), $join_conds = array() - ) { - if ( is_array( $conds ) ) { - $conds = $this->wrapConditionsForWhere( $table, $conds ); - } - - return parent::selectRow( $table, $vars, $conds, $fname, $options, $join_conds ); - } - - /** - * Returns an optional USE INDEX clause to go after the table, and a - * string to go at the end of the query - * - * @param array $options An 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['FOR UPDATE'] ) ) { - $postLimitTail .= ' FOR UPDATE'; - } - - if ( isset( $noKeyOptions['DISTINCT'] ) || isset( $noKeyOptions['DISTINCTROW'] ) ) { - $startOpts .= 'DISTINCT'; - } - - if ( isset( $options['USE INDEX'] ) && !is_array( $options['USE INDEX'] ) ) { - $useIndex = $this->useIndexClause( $options['USE INDEX'] ); - } else { - $useIndex = ''; - } - - return array( $startOpts, $useIndex, $preLimitTail, $postLimitTail ); - } - - public function delete( $table, $conds, $fname = __METHOD__ ) { - if ( is_array( $conds ) ) { - $conds = $this->wrapConditionsForWhere( $table, $conds ); - } - // a hack for deleting pages, users and images (which have non-nullable FKs) - // all deletions on these tables have transactions so final failure rollbacks these updates - $table = $this->tableName( $table ); - if ( $table == $this->tableName( 'user' ) ) { - $this->update( 'archive', array( 'ar_user' => 0 ), - array( 'ar_user' => $conds['user_id'] ), $fname ); - $this->update( 'ipblocks', array( 'ipb_user' => 0 ), - array( 'ipb_user' => $conds['user_id'] ), $fname ); - $this->update( 'image', array( 'img_user' => 0 ), - array( 'img_user' => $conds['user_id'] ), $fname ); - $this->update( 'oldimage', array( 'oi_user' => 0 ), - array( 'oi_user' => $conds['user_id'] ), $fname ); - $this->update( 'filearchive', array( 'fa_deleted_user' => 0 ), - array( 'fa_deleted_user' => $conds['user_id'] ), $fname ); - $this->update( 'filearchive', array( 'fa_user' => 0 ), - array( 'fa_user' => $conds['user_id'] ), $fname ); - $this->update( 'uploadstash', array( 'us_user' => 0 ), - array( 'us_user' => $conds['user_id'] ), $fname ); - $this->update( 'recentchanges', array( 'rc_user' => 0 ), - array( 'rc_user' => $conds['user_id'] ), $fname ); - $this->update( 'logging', array( 'log_user' => 0 ), - array( 'log_user' => $conds['user_id'] ), $fname ); - } elseif ( $table == $this->tableName( 'image' ) ) { - $this->update( 'oldimage', array( 'oi_name' => 0 ), - array( 'oi_name' => $conds['img_name'] ), $fname ); - } - - return parent::delete( $table, $conds, $fname ); - } - - /** - * @param string $table - * @param array $values - * @param array $conds - * @param string $fname - * @param array $options - * @return bool - * @throws DBUnexpectedError - */ - function update( $table, $values, $conds, $fname = __METHOD__, $options = array() ) { - global $wgContLang; - - $table = $this->tableName( $table ); - $opts = $this->makeUpdateOptions( $options ); - $sql = "UPDATE $opts $table SET "; - - $first = true; - foreach ( $values as $col => &$val ) { - $sqlSet = $this->fieldBindStatement( $table, $col, $val, true ); - - if ( !$first ) { - $sqlSet = ', ' . $sqlSet; - } else { - $first = false; - } - $sql .= $sqlSet; - } - - if ( $conds !== array() && $conds !== '*' ) { - $conds = $this->wrapConditionsForWhere( $table, $conds ); - $sql .= ' WHERE ' . $this->makeList( $conds, LIST_AND ); - } - - if ( ( $this->mLastResult = $stmt = oci_parse( $this->mConn, $sql ) ) === false ) { - $e = oci_error( $this->mConn ); - $this->reportQueryError( $e['message'], $e['code'], $sql, __METHOD__ ); - - return false; - } - foreach ( $values as $col => &$val ) { - $col_info = $this->fieldInfoMulti( $table, $col ); - $col_type = $col_info != false ? $col_info->type() : 'CONSTANT'; - - if ( $val === null ) { - // do nothing ... null was inserted in statement creation - } elseif ( $col_type != 'BLOB' && $col_type != 'CLOB' ) { - if ( is_object( $val ) ) { - $val = $val->getData(); - } - - if ( preg_match( '/^timestamp.*/i', $col_type ) == 1 && strtolower( $val ) == 'infinity' ) { - $val = '31-12-2030 12:00:00.000000'; - } - - $val = ( $wgContLang != null ) ? $wgContLang->checkTitleEncoding( $val ) : $val; - if ( oci_bind_by_name( $stmt, ":$col", $val ) === false ) { - $e = oci_error( $stmt ); - $this->reportQueryError( $e['message'], $e['code'], $sql, __METHOD__ ); - - return false; - } - } else { - /** @var OCI_Lob[] $lob */ - if ( ( $lob[$col] = oci_new_descriptor( $this->mConn, OCI_D_LOB ) ) === false ) { - $e = oci_error( $stmt ); - throw new DBUnexpectedError( $this, "Cannot create LOB descriptor: " . $e['message'] ); - } - - if ( is_object( $val ) ) { - $val = $val->getData(); - } - - if ( $col_type == 'BLOB' ) { - $lob[$col]->writeTemporary( $val ); - oci_bind_by_name( $stmt, ":$col", $lob[$col], -1, SQLT_BLOB ); - } else { - $lob[$col]->writeTemporary( $val ); - oci_bind_by_name( $stmt, ":$col", $lob[$col], -1, OCI_B_CLOB ); - } - } - } - - MediaWiki\suppressWarnings(); - - if ( oci_execute( $stmt, $this->execFlags() ) === false ) { - $e = oci_error( $stmt ); - if ( !$this->ignoreDupValOnIndex || $e['code'] != '1' ) { - $this->reportQueryError( $e['message'], $e['code'], $sql, __METHOD__ ); - - return false; - } else { - $this->mAffectedRows = oci_num_rows( $stmt ); - } - } else { - $this->mAffectedRows = oci_num_rows( $stmt ); - } - - MediaWiki\restoreWarnings(); - - if ( isset( $lob ) ) { - foreach ( $lob as $lob_v ) { - $lob_v->free(); - } - } - - if ( !$this->mTrxLevel ) { - oci_commit( $this->mConn ); - } - - return oci_free_statement( $stmt ); - } - - function bitNot( $field ) { - // expecting bit-fields smaller than 4bytes - return 'BITNOT(' . $field . ')'; - } - - function bitAnd( $fieldLeft, $fieldRight ) { - return 'BITAND(' . $fieldLeft . ', ' . $fieldRight . ')'; - } - - function bitOr( $fieldLeft, $fieldRight ) { - return 'BITOR(' . $fieldLeft . ', ' . $fieldRight . ')'; - } - - function getDBname() { - return $this->mDBname; - } - - function getServer() { - return $this->mServer; - } - - public function buildGroupConcatField( - $delim, $table, $field, $conds = '', $join_conds = array() - ) { - $fld = "LISTAGG($field," . $this->addQuotes( $delim ) . ") WITHIN GROUP (ORDER BY $field)"; - - return '(' . $this->selectSQLText( $table, $fld, $conds, null, array(), $join_conds ) . ')'; - } - - public function getSearchEngine() { - return 'SearchOracle'; - } - - public function getInfinity() { - return '31-12-2030 12:00:00.000000'; - } -} diff --git a/includes/installer/MssqlInstaller.php b/includes/installer/MssqlInstaller.php deleted file mode 100644 index 4d79d966..00000000 --- a/includes/installer/MssqlInstaller.php +++ /dev/null @@ -1,736 +0,0 @@ - 'sa', - '_InstallWindowsAuthentication' => 'sqlauth', - '_WebWindowsAuthentication' => 'sqlauth', - ); - - // SQL Server 2005 RTM - // @todo Are SQL Express version numbers different?) - public $minimumVersion = '9.00.1399'; - - // These are schema-level privs - // Note: the web user will be created will full permissions if possible, this permission - // list is only used if we are unable to grant full permissions. - public $webUserPrivs = array( - 'DELETE', - 'INSERT', - 'SELECT', - 'UPDATE', - 'EXECUTE', - ); - - /** - * @return string - */ - public function getName() { - return 'mssql'; - } - - /** - * @return bool - */ - public function isCompiled() { - return self::checkExtension( 'sqlsrv' ); - } - - /** - * @return string - */ - public function getConnectForm() { - if ( $this->getVar( '_InstallWindowsAuthentication' ) == 'windowsauth' ) { - $displayStyle = 'display: none;'; - } else { - $displayStyle = 'display: block;'; - } - - return $this->getTextBox( - 'wgDBserver', - 'config-db-host', - array(), - $this->parent->getHelpBox( 'config-db-host-help' ) - ) . - Html::openElement( 'fieldset' ) . - Html::element( 'legend', array(), wfMessage( 'config-db-wiki-settings' )->text() ) . - $this->getTextBox( 'wgDBname', 'config-db-name', array( 'dir' => 'ltr' ), - $this->parent->getHelpBox( 'config-db-name-help' ) ) . - $this->getTextBox( 'wgDBmwschema', 'config-db-schema', array( 'dir' => 'ltr' ), - $this->parent->getHelpBox( 'config-db-schema-help' ) ) . - $this->getTextBox( 'wgDBprefix', 'config-db-prefix', array( 'dir' => 'ltr' ), - $this->parent->getHelpBox( 'config-db-prefix-help' ) ) . - Html::closeElement( 'fieldset' ) . - Html::openElement( 'fieldset' ) . - Html::element( 'legend', array(), wfMessage( 'config-db-install-account' )->text() ) . - $this->getRadioSet( array( - 'var' => '_InstallWindowsAuthentication', - 'label' => 'config-mssql-auth', - 'itemLabelPrefix' => 'config-mssql-', - 'values' => array( 'sqlauth', 'windowsauth' ), - 'itemAttribs' => array( - 'sqlauth' => array( - 'class' => 'showHideRadio', - 'rel' => 'dbCredentialBox', - ), - 'windowsauth' => array( - 'class' => 'hideShowRadio', - 'rel' => 'dbCredentialBox', - ) - ), - 'help' => $this->parent->getHelpBox( 'config-mssql-install-auth' ) - ) ) . - Html::openElement( 'div', array( 'id' => 'dbCredentialBox', 'style' => $displayStyle ) ) . - $this->getTextBox( - '_InstallUser', - 'config-db-username', - array( 'dir' => 'ltr' ), - $this->parent->getHelpBox( 'config-db-install-username' ) - ) . - $this->getPasswordBox( - '_InstallPassword', - 'config-db-password', - array( 'dir' => 'ltr' ), - $this->parent->getHelpBox( 'config-db-install-password' ) - ) . - Html::closeElement( 'div' ) . - Html::closeElement( 'fieldset' ); - } - - public function submitConnectForm() { - // Get variables from the request. - $newValues = $this->setVarsFromRequest( array( - 'wgDBserver', - 'wgDBname', - 'wgDBmwschema', - 'wgDBprefix' - ) ); - - // Validate them. - $status = Status::newGood(); - if ( !strlen( $newValues['wgDBserver'] ) ) { - $status->fatal( 'config-missing-db-host' ); - } - if ( !strlen( $newValues['wgDBname'] ) ) { - $status->fatal( 'config-missing-db-name' ); - } elseif ( !preg_match( '/^[a-z0-9_]+$/i', $newValues['wgDBname'] ) ) { - $status->fatal( 'config-invalid-db-name', $newValues['wgDBname'] ); - } - if ( !preg_match( '/^[a-z0-9_]*$/i', $newValues['wgDBmwschema'] ) ) { - $status->fatal( 'config-invalid-schema', $newValues['wgDBmwschema'] ); - } - if ( !preg_match( '/^[a-z0-9_]*$/i', $newValues['wgDBprefix'] ) ) { - $status->fatal( 'config-invalid-db-prefix', $newValues['wgDBprefix'] ); - } - if ( !$status->isOK() ) { - return $status; - } - - // Check for blank schema and remap to dbo - if ( $newValues['wgDBmwschema'] === '' ) { - $this->setVar( 'wgDBmwschema', 'dbo' ); - } - - // User box - $this->setVarsFromRequest( array( - '_InstallUser', - '_InstallPassword', - '_InstallWindowsAuthentication' - ) ); - - // Try to connect - $status = $this->getConnection(); - if ( !$status->isOK() ) { - return $status; - } - /** - * @var $conn DatabaseBase - */ - $conn = $status->value; - - // Check version - $version = $conn->getServerVersion(); - if ( version_compare( $version, $this->minimumVersion ) < 0 ) { - return Status::newFatal( 'config-mssql-old', $this->minimumVersion, $version ); - } - - return $status; - } - - /** - * @return Status - */ - public function openConnection() { - global $wgDBWindowsAuthentication; - $status = Status::newGood(); - $user = $this->getVar( '_InstallUser' ); - $password = $this->getVar( '_InstallPassword' ); - - if ( $this->getVar( '_InstallWindowsAuthentication' ) == 'windowsauth' ) { - // Use Windows authentication for this connection - $wgDBWindowsAuthentication = true; - } else { - $wgDBWindowsAuthentication = false; - } - - try { - $db = DatabaseBase::factory( 'mssql', array( - 'host' => $this->getVar( 'wgDBserver' ), - 'user' => $user, - 'password' => $password, - 'dbname' => false, - 'flags' => 0, - 'schema' => $this->getVar( 'wgDBmwschema' ), - 'tablePrefix' => $this->getVar( 'wgDBprefix' ) ) ); - $db->prepareStatements( false ); - $db->scrollableCursor( false ); - $status->value = $db; - } catch ( DBConnectionError $e ) { - $status->fatal( 'config-connection-error', $e->getMessage() ); - } - - return $status; - } - - public function preUpgrade() { - global $wgDBuser, $wgDBpassword; - - $status = $this->getConnection(); - if ( !$status->isOK() ) { - $this->parent->showStatusError( $status ); - - return; - } - /** - * @var $conn DatabaseBase - */ - $conn = $status->value; - $conn->selectDB( $this->getVar( 'wgDBname' ) ); - - # Normal user and password are selected after this step, so for now - # just copy these two - $wgDBuser = $this->getVar( '_InstallUser' ); - $wgDBpassword = $this->getVar( '_InstallPassword' ); - } - - /** - * Return true if the install user can create accounts - * - * @return bool - */ - public function canCreateAccounts() { - $status = $this->getConnection(); - if ( !$status->isOK() ) { - return false; - } - /** @var $conn DatabaseBase */ - $conn = $status->value; - - // We need the server-level ALTER ANY LOGIN permission to create new accounts - $res = $conn->query( "SELECT permission_name FROM sys.fn_my_permissions( NULL, 'SERVER' )" ); - $serverPrivs = array( - 'ALTER ANY LOGIN' => false, - 'CONTROL SERVER' => false, - ); - - foreach ( $res as $row ) { - $serverPrivs[$row->permission_name] = true; - } - - if ( !$serverPrivs['ALTER ANY LOGIN'] ) { - return false; - } - - // Check to ensure we can grant everything needed as well - // We can't actually tell if we have WITH GRANT OPTION for a given permission, so we assume we do - // and just check for the permission - // http://technet.microsoft.com/en-us/library/ms178569.aspx - // The following array sets up which permissions imply whatever permissions we specify - $implied = array( - // schema database server - 'DELETE' => array( 'DELETE', 'CONTROL SERVER' ), - 'EXECUTE' => array( 'EXECUTE', 'CONTROL SERVER' ), - 'INSERT' => array( 'INSERT', 'CONTROL SERVER' ), - 'SELECT' => array( 'SELECT', 'CONTROL SERVER' ), - 'UPDATE' => array( 'UPDATE', 'CONTROL SERVER' ), - ); - - $grantOptions = array_flip( $this->webUserPrivs ); - - // Check for schema and db-level permissions, but only if the schema/db exists - $schemaPrivs = $dbPrivs = array( - 'DELETE' => false, - 'EXECUTE' => false, - 'INSERT' => false, - 'SELECT' => false, - 'UPDATE' => false, - ); - - $dbPrivs['ALTER ANY USER'] = false; - - if ( $this->databaseExists( $this->getVar( 'wgDBname' ) ) ) { - $conn->selectDB( $this->getVar( 'wgDBname' ) ); - $res = $conn->query( "SELECT permission_name FROM sys.fn_my_permissions( NULL, 'DATABASE' )" ); - - foreach ( $res as $row ) { - $dbPrivs[$row->permission_name] = true; - } - - // If the db exists, we need ALTER ANY USER privs on it to make a new user - if ( !$dbPrivs['ALTER ANY USER'] ) { - return false; - } - - if ( $this->schemaExists( $this->getVar( 'wgDBmwschema' ) ) ) { - // wgDBmwschema is validated to only contain alphanumeric + underscore, so this is safe - $res = $conn->query( "SELECT permission_name FROM sys.fn_my_permissions( " - . "'{$this->getVar( 'wgDBmwschema' )}', 'SCHEMA' )" ); - - foreach ( $res as $row ) { - $schemaPrivs[$row->permission_name] = true; - } - } - } - - // Now check all the grants we'll need to be doing to see if we can - foreach ( $this->webUserPrivs as $permission ) { - if ( ( isset( $schemaPrivs[$permission] ) && $schemaPrivs[$permission] ) - || ( isset( $dbPrivs[$implied[$permission][0]] ) - && $dbPrivs[$implied[$permission][0]] ) - || ( isset( $serverPrivs[$implied[$permission][1]] ) - && $serverPrivs[$implied[$permission][1]] ) - ) { - unset( $grantOptions[$permission] ); - } - } - - if ( count( $grantOptions ) ) { - // Can't grant everything - return false; - } - - return true; - } - - /** - * @return string - */ - public function getSettingsForm() { - if ( $this->canCreateAccounts() ) { - $noCreateMsg = false; - } else { - $noCreateMsg = 'config-db-web-no-create-privs'; - } - - $wrapperStyle = $this->getVar( '_SameAccount' ) ? 'display: none' : ''; - $displayStyle = $this->getVar( '_WebWindowsAuthentication' ) == 'windowsauth' - ? 'display: none' - : ''; - $s = Html::openElement( 'fieldset' ) . - Html::element( 'legend', array(), wfMessage( 'config-db-web-account' )->text() ) . - $this->getCheckBox( - '_SameAccount', 'config-db-web-account-same', - array( 'class' => 'hideShowRadio', 'rel' => 'dbOtherAccount' ) - ) . - Html::openElement( 'div', array( 'id' => 'dbOtherAccount', 'style' => $wrapperStyle ) ) . - $this->getRadioSet( array( - 'var' => '_WebWindowsAuthentication', - 'label' => 'config-mssql-auth', - 'itemLabelPrefix' => 'config-mssql-', - 'values' => array( 'sqlauth', 'windowsauth' ), - 'itemAttribs' => array( - 'sqlauth' => array( - 'class' => 'showHideRadio', - 'rel' => 'dbCredentialBox', - ), - 'windowsauth' => array( - 'class' => 'hideShowRadio', - 'rel' => 'dbCredentialBox', - ) - ), - 'help' => $this->parent->getHelpBox( 'config-mssql-web-auth' ) - ) ) . - Html::openElement( 'div', array( 'id' => 'dbCredentialBox', 'style' => $displayStyle ) ) . - $this->getTextBox( 'wgDBuser', 'config-db-username' ) . - $this->getPasswordBox( 'wgDBpassword', 'config-db-password' ) . - Html::closeElement( 'div' ); - - if ( $noCreateMsg ) { - $s .= $this->parent->getWarningBox( wfMessage( $noCreateMsg )->plain() ); - } else { - $s .= $this->getCheckBox( '_CreateDBAccount', 'config-db-web-create' ); - } - - $s .= Html::closeElement( 'div' ) . Html::closeElement( 'fieldset' ); - - return $s; - } - - /** - * @return Status - */ - public function submitSettingsForm() { - $this->setVarsFromRequest( array( - 'wgDBuser', - 'wgDBpassword', - '_SameAccount', - '_CreateDBAccount', - '_WebWindowsAuthentication' - ) ); - - if ( $this->getVar( '_SameAccount' ) ) { - $this->setVar( '_WebWindowsAuthentication', $this->getVar( '_InstallWindowsAuthentication' ) ); - $this->setVar( 'wgDBuser', $this->getVar( '_InstallUser' ) ); - $this->setVar( 'wgDBpassword', $this->getVar( '_InstallPassword' ) ); - } - - if ( $this->getVar( '_WebWindowsAuthentication' ) == 'windowsauth' ) { - $this->setVar( 'wgDBuser', '' ); - $this->setVar( 'wgDBpassword', '' ); - $this->setVar( 'wgDBWindowsAuthentication', true ); - } else { - $this->setVar( 'wgDBWindowsAuthentication', false ); - } - - if ( $this->getVar( '_CreateDBAccount' ) - && $this->getVar( '_WebWindowsAuthentication' ) == 'sqlauth' - && strval( $this->getVar( 'wgDBpassword' ) ) == '' - ) { - return Status::newFatal( 'config-db-password-empty', $this->getVar( 'wgDBuser' ) ); - } - - // Validate the create checkbox - $canCreate = $this->canCreateAccounts(); - if ( !$canCreate ) { - $this->setVar( '_CreateDBAccount', false ); - $create = false; - } else { - $create = $this->getVar( '_CreateDBAccount' ); - } - - if ( !$create ) { - // Test the web account - $user = $this->getVar( 'wgDBuser' ); - $password = $this->getVar( 'wgDBpassword' ); - - if ( $this->getVar( '_WebWindowsAuthentication' ) == 'windowsauth' ) { - $user = 'windowsauth'; - $password = 'windowsauth'; - } - - try { - DatabaseBase::factory( 'mssql', array( - 'host' => $this->getVar( 'wgDBserver' ), - 'user' => $user, - 'password' => $password, - 'dbname' => false, - 'flags' => 0, - 'tablePrefix' => $this->getVar( 'wgDBprefix' ), - 'schema' => $this->getVar( 'wgDBmwschema' ), - ) ); - } catch ( DBConnectionError $e ) { - return Status::newFatal( 'config-connection-error', $e->getMessage() ); - } - } - - return Status::newGood(); - } - - public function preInstall() { - # Add our user callback to installSteps, right before the tables are created. - $callback = array( - 'name' => 'user', - 'callback' => array( $this, 'setupUser' ), - ); - $this->parent->addInstallStep( $callback, 'tables' ); - } - - /** - * @return Status - */ - public function setupDatabase() { - $status = $this->getConnection(); - if ( !$status->isOK() ) { - return $status; - } - /** @var DatabaseBase $conn */ - $conn = $status->value; - $dbName = $this->getVar( 'wgDBname' ); - $schemaName = $this->getVar( 'wgDBmwschema' ); - if ( !$this->databaseExists( $dbName ) ) { - $conn->query( - "CREATE DATABASE " . $conn->addIdentifierQuotes( $dbName ), - __METHOD__ - ); - $conn->selectDB( $dbName ); - if ( !$this->schemaExists( $schemaName ) ) { - $conn->query( - "CREATE SCHEMA " . $conn->addIdentifierQuotes( $schemaName ), - __METHOD__ - ); - } - if ( !$this->catalogExists( $schemaName ) ) { - $conn->query( - "CREATE FULLTEXT CATALOG " . $conn->addIdentifierQuotes( $schemaName ), - __METHOD__ - ); - } - } - $this->setupSchemaVars(); - - return $status; - } - - /** - * @return Status - */ - public function setupUser() { - $dbUser = $this->getVar( 'wgDBuser' ); - if ( $dbUser == $this->getVar( '_InstallUser' ) - || ( $this->getVar( '_InstallWindowsAuthentication' ) == 'windowsauth' - && $this->getVar( '_WebWindowsAuthentication' ) == 'windowsauth' ) ) { - return Status::newGood(); - } - $status = $this->getConnection(); - if ( !$status->isOK() ) { - return $status; - } - - $this->setupSchemaVars(); - $dbName = $this->getVar( 'wgDBname' ); - $this->db->selectDB( $dbName ); - $password = $this->getVar( 'wgDBpassword' ); - $schemaName = $this->getVar( 'wgDBmwschema' ); - - if ( $this->getVar( '_WebWindowsAuthentication' ) == 'windowsauth' ) { - $dbUser = 'windowsauth'; - $password = 'windowsauth'; - } - - if ( $this->getVar( '_CreateDBAccount' ) ) { - $tryToCreate = true; - } else { - $tryToCreate = false; - } - - $escUser = $this->db->addIdentifierQuotes( $dbUser ); - $escDb = $this->db->addIdentifierQuotes( $dbName ); - $escSchema = $this->db->addIdentifierQuotes( $schemaName ); - $grantableNames = array(); - if ( $tryToCreate ) { - $escPass = $this->db->addQuotes( $password ); - - if ( !$this->loginExists( $dbUser ) ) { - try { - $this->db->begin(); - $this->db->selectDB( 'master' ); - $logintype = $this->getVar( '_WebWindowsAuthentication' ) == 'windowsauth' - ? 'FROM WINDOWS' - : "WITH PASSWORD = $escPass"; - $this->db->query( "CREATE LOGIN $escUser $logintype" ); - $this->db->selectDB( $dbName ); - $this->db->query( "CREATE USER $escUser FOR LOGIN $escUser WITH DEFAULT_SCHEMA = $escSchema" ); - $this->db->commit(); - $grantableNames[] = $dbUser; - } catch ( DBQueryError $dqe ) { - $this->db->rollback(); - $status->warning( 'config-install-user-create-failed', $dbUser, $dqe->getText() ); - } - } elseif ( !$this->userExists( $dbUser ) ) { - try { - $this->db->begin(); - $this->db->selectDB( $dbName ); - $this->db->query( "CREATE USER $escUser FOR LOGIN $escUser WITH DEFAULT_SCHEMA = $escSchema" ); - $this->db->commit(); - $grantableNames[] = $dbUser; - } catch ( DBQueryError $dqe ) { - $this->db->rollback(); - $status->warning( 'config-install-user-create-failed', $dbUser, $dqe->getText() ); - } - } else { - $status->warning( 'config-install-user-alreadyexists', $dbUser ); - $grantableNames[] = $dbUser; - } - } - - // Try to grant to all the users we know exist or we were able to create - $this->db->selectDB( $dbName ); - foreach ( $grantableNames as $name ) { - try { - // First try to grant full permissions - $fullPrivArr = array( - 'BACKUP DATABASE', 'BACKUP LOG', 'CREATE FUNCTION', 'CREATE PROCEDURE', - 'CREATE TABLE', 'CREATE VIEW', 'CREATE FULLTEXT CATALOG', 'SHOWPLAN' - ); - $fullPrivList = implode( ', ', $fullPrivArr ); - $this->db->begin(); - $this->db->query( "GRANT $fullPrivList ON DATABASE :: $escDb TO $escUser", __METHOD__ ); - $this->db->query( "GRANT CONTROL ON SCHEMA :: $escSchema TO $escUser", __METHOD__ ); - $this->db->commit(); - } catch ( DBQueryError $dqe ) { - // If that fails, try to grant the limited subset specified in $this->webUserPrivs - try { - $privList = implode( ', ', $this->webUserPrivs ); - $this->db->rollback(); - $this->db->begin(); - $this->db->query( "GRANT $privList ON SCHEMA :: $escSchema TO $escUser", __METHOD__ ); - $this->db->commit(); - } catch ( DBQueryError $dqe ) { - $this->db->rollback(); - $status->fatal( 'config-install-user-grant-failed', $dbUser, $dqe->getText() ); - } - // Also try to grant SHOWPLAN on the db, but don't fail if we can't - // (just makes a couple things in mediawiki run slower since - // we have to run SELECT COUNT(*) instead of getting the query plan) - try { - $this->db->query( "GRANT SHOWPLAN ON DATABASE :: $escDb TO $escUser", __METHOD__ ); - } catch ( DBQueryError $dqe ) { - } - } - } - - return $status; - } - - public function createTables() { - $status = parent::createTables(); - - // Do last-minute stuff like fulltext indexes (since they can't be inside a transaction) - if ( $status->isOk() ) { - $searchindex = $this->db->tableName( 'searchindex' ); - $schema = $this->db->addIdentifierQuotes( $this->getVar( 'wgDBmwschema' ) ); - try { - $this->db->query( "CREATE FULLTEXT INDEX ON $searchindex (si_title, si_text) " - . "KEY INDEX si_page ON $schema" ); - } catch ( DBQueryError $dqe ) { - $status->fatal( 'config-install-tables-failed', $dqe->getText() ); - } - } - - return $status; - } - - public function getGlobalDefaults() { - // The default $wgDBmwschema is null, which breaks Postgres and other DBMSes that require - // the use of a schema, so we need to set it here - return array_merge( parent::getGlobalDefaults(), array( - 'wgDBmwschema' => 'mediawiki', - ) ); - } - - /** - * Try to see if the login exists - * @param string $user Username to check - * @return bool - */ - private function loginExists( $user ) { - $res = $this->db->selectField( 'sys.sql_logins', 1, array( 'name' => $user ) ); - return (bool)$res; - } - - /** - * Try to see if the user account exists - * We assume we already have the appropriate database selected - * @param string $user Username to check - * @return bool - */ - private function userExists( $user ) { - $res = $this->db->selectField( 'sys.sysusers', 1, array( 'name' => $user ) ); - return (bool)$res; - } - - /** - * Try to see if a given database exists - * @param string $dbName Database name to check - * @return bool - */ - private function databaseExists( $dbName ) { - $res = $this->db->selectField( 'sys.databases', 1, array( 'name' => $dbName ) ); - return (bool)$res; - } - - /** - * Try to see if a given schema exists - * We assume we already have the appropriate database selected - * @param string $schemaName Schema name to check - * @return bool - */ - private function schemaExists( $schemaName ) { - $res = $this->db->selectField( 'sys.schemas', 1, array( 'name' => $schemaName ) ); - return (bool)$res; - } - - /** - * Try to see if a given fulltext catalog exists - * We assume we already have the appropriate database selected - * @param string $catalogName Catalog name to check - * @return bool - */ - private function catalogExists( $catalogName ) { - $res = $this->db->selectField( 'sys.fulltext_catalogs', 1, array( 'name' => $catalogName ) ); - return (bool)$res; - } - - /** - * Get variables to substitute into tables.sql and the SQL patch files. - * - * @return array - */ - public function getSchemaVars() { - return array( - 'wgDBname' => $this->getVar( 'wgDBname' ), - 'wgDBmwschema' => $this->getVar( 'wgDBmwschema' ), - 'wgDBuser' => $this->getVar( 'wgDBuser' ), - 'wgDBpassword' => $this->getVar( 'wgDBpassword' ), - ); - } - - public function getLocalSettings() { - $schema = LocalSettingsGenerator::escapePhpString( $this->getVar( 'wgDBmwschema' ) ); - $prefix = LocalSettingsGenerator::escapePhpString( $this->getVar( 'wgDBprefix' ) ); - $windowsauth = $this->getVar( 'wgDBWindowsAuthentication' ) ? 'true' : 'false'; - - return "# MSSQL specific settings -\$wgDBWindowsAuthentication = {$windowsauth}; -\$wgDBmwschema = \"{$schema}\"; -\$wgDBprefix = \"{$prefix}\";"; - } -} diff --git a/includes/installer/MssqlUpdater.php b/includes/installer/MssqlUpdater.php deleted file mode 100644 index 164cfab4..00000000 --- a/includes/installer/MssqlUpdater.php +++ /dev/null @@ -1,143 +0,0 @@ -_ckc - * - * @param string $constraintType - * @param string $table Name of the table to which the field belongs - * @param string $field Name of the field to modify - * @return bool False if patch is skipped. - */ - protected function updateConstraints( $constraintType, $table, $field ) { - global $wgDBname, $wgDBmwschema; - - if ( !$this->doTable( $table ) ) { - return true; - } - - $this->output( "...updating constraints on [$table].[$field] ..." ); - $updateKey = "$field-$constraintType-ck"; - if ( !$this->db->tableExists( $table, __METHOD__ ) ) { - $this->output( "...$table table does not exist, skipping modify field patch.\n" ); - return true; - } elseif ( !$this->db->fieldExists( $table, $field, __METHOD__ ) ) { - $this->output( "...$field field does not exist in $table table, " . - "skipping modify field patch.\n" ); - return true; - } elseif ( $this->updateRowExists( $updateKey ) ) { - $this->output( "...$field in table $table already patched.\n" ); - return true; - } - - # After all checks passed, start the update - $this->insertUpdateRow( $updateKey ); - $path = 'named_constraints.sql'; - $constraintMap = array( - 'category_types' => - "($field in('page', 'subcat', 'file'))", - 'major_mime' => - "($field in('unknown', 'application', 'audio', 'image', 'text', 'video'," . - " 'message', 'model', 'multipart'))", - 'media_type' => - "($field in('UNKNOWN', 'BITMAP', 'DRAWING', 'AUDIO', 'VIDEO', 'MULTIMEDIA'," . - "'OFFICE', 'TEXT', 'EXECUTABLE', 'ARCHIVE'))" - ); - $constraint = $constraintMap[$constraintType]; - - # and hack-in those variables that should be replaced - # in our template file right now - $this->db->setSchemaVars( array( - 'tableName' => $table, - 'fieldName' => $field, - 'checkConstraint' => $constraint, - 'wgDBname' => $wgDBname, - 'wgDBmwschema' => $wgDBmwschema, - ) ); - - # Full path from file name - $path = $this->db->patchPath( $path ); - - # No need for a cursor allowing result-iteration; just apply a patch - # store old value for re-setting later - $wasScrollable = $this->db->scrollableCursor( false ); - - # Apply patch - $this->db->sourceFile( $path ); - - # Reset DB instance to have original state - $this->db->setSchemaVars( false ); - $this->db->scrollableCursor( $wasScrollable ); - - $this->output( "done.\n" ); - - return true; - } -} diff --git a/includes/installer/OracleInstaller.php b/includes/installer/OracleInstaller.php deleted file mode 100644 index 9e692ea4..00000000 --- a/includes/installer/OracleInstaller.php +++ /dev/null @@ -1,344 +0,0 @@ - 'USERS', - '_OracleTempTS' => 'TEMP', - '_InstallUser' => 'SYSTEM', - ); - - public $minimumVersion = '9.0.1'; // 9iR1 - - protected $connError = null; - - public function getName() { - return 'oracle'; - } - - public function isCompiled() { - return self::checkExtension( 'oci8' ); - } - - public function getConnectForm() { - if ( $this->getVar( 'wgDBserver' ) == 'localhost' ) { - $this->parent->setVar( 'wgDBserver', '' ); - } - - return $this->getTextBox( - 'wgDBserver', - 'config-db-host-oracle', - array(), - $this->parent->getHelpBox( 'config-db-host-oracle-help' ) - ) . - Html::openElement( 'fieldset' ) . - Html::element( 'legend', array(), wfMessage( 'config-db-wiki-settings' )->text() ) . - $this->getTextBox( 'wgDBprefix', 'config-db-prefix' ) . - $this->getTextBox( '_OracleDefTS', 'config-oracle-def-ts' ) . - $this->getTextBox( - '_OracleTempTS', - 'config-oracle-temp-ts', - array(), - $this->parent->getHelpBox( 'config-db-oracle-help' ) - ) . - Html::closeElement( 'fieldset' ) . - $this->parent->getWarningBox( wfMessage( 'config-db-account-oracle-warn' )->text() ) . - $this->getInstallUserBox() . - $this->getWebUserBox(); - } - - public function submitInstallUserBox() { - parent::submitInstallUserBox(); - $this->parent->setVar( '_InstallDBname', $this->getVar( '_InstallUser' ) ); - - return Status::newGood(); - } - - public function submitConnectForm() { - // Get variables from the request - $newValues = $this->setVarsFromRequest( array( - 'wgDBserver', - 'wgDBprefix', - 'wgDBuser', - 'wgDBpassword' - ) ); - $this->parent->setVar( 'wgDBname', $this->getVar( 'wgDBuser' ) ); - - // Validate them - $status = Status::newGood(); - if ( !strlen( $newValues['wgDBserver'] ) ) { - $status->fatal( 'config-missing-db-server-oracle' ); - } elseif ( !self::checkConnectStringFormat( $newValues['wgDBserver'] ) ) { - $status->fatal( 'config-invalid-db-server-oracle', $newValues['wgDBserver'] ); - } - if ( !preg_match( '/^[a-zA-Z0-9_]*$/', $newValues['wgDBprefix'] ) ) { - $status->fatal( 'config-invalid-schema', $newValues['wgDBprefix'] ); - } - if ( !$status->isOK() ) { - return $status; - } - - // Submit user box - $status = $this->submitInstallUserBox(); - if ( !$status->isOK() ) { - return $status; - } - - // Try to connect trough multiple scenarios - // Scenario 1: Install with a manually created account - $status = $this->getConnection(); - if ( !$status->isOK() ) { - if ( $this->connError == 28009 ) { - // _InstallUser seems to be a SYSDBA - // Scenario 2: Create user with SYSDBA and install with new user - $status = $this->submitWebUserBox(); - if ( !$status->isOK() ) { - return $status; - } - $status = $this->openSYSDBAConnection(); - if ( !$status->isOK() ) { - return $status; - } - if ( !$this->getVar( '_CreateDBAccount' ) ) { - $status->fatal( 'config-db-sys-create-oracle' ); - } - } else { - return $status; - } - } else { - // check for web user credentials - // Scenario 3: Install with a priviliged user but use a restricted user - $statusIS3 = $this->submitWebUserBox(); - if ( !$statusIS3->isOK() ) { - return $statusIS3; - } - } - - /** - * @var $conn DatabaseBase - */ - $conn = $status->value; - - // Check version - $version = $conn->getServerVersion(); - if ( version_compare( $version, $this->minimumVersion ) < 0 ) { - return Status::newFatal( 'config-oracle-old', $this->minimumVersion, $version ); - } - - return $status; - } - - public function openConnection() { - $status = Status::newGood(); - try { - $db = new DatabaseOracle( - $this->getVar( 'wgDBserver' ), - $this->getVar( '_InstallUser' ), - $this->getVar( '_InstallPassword' ), - $this->getVar( '_InstallDBname' ), - 0, - $this->getVar( 'wgDBprefix' ) - ); - $status->value = $db; - } catch ( DBConnectionError $e ) { - $this->connError = $e->db->lastErrno(); - $status->fatal( 'config-connection-error', $e->getMessage() ); - } - - return $status; - } - - public function openSYSDBAConnection() { - $status = Status::newGood(); - try { - $db = new DatabaseOracle( - $this->getVar( 'wgDBserver' ), - $this->getVar( '_InstallUser' ), - $this->getVar( '_InstallPassword' ), - $this->getVar( '_InstallDBname' ), - DBO_SYSDBA, - $this->getVar( 'wgDBprefix' ) - ); - $status->value = $db; - } catch ( DBConnectionError $e ) { - $this->connError = $e->db->lastErrno(); - $status->fatal( 'config-connection-error', $e->getMessage() ); - } - - return $status; - } - - public function needsUpgrade() { - $tempDBname = $this->getVar( 'wgDBname' ); - $this->parent->setVar( 'wgDBname', $this->getVar( 'wgDBuser' ) ); - $retVal = parent::needsUpgrade(); - $this->parent->setVar( 'wgDBname', $tempDBname ); - - return $retVal; - } - - public function preInstall() { - # Add our user callback to installSteps, right before the tables are created. - $callback = array( - 'name' => 'user', - 'callback' => array( $this, 'setupUser' ) - ); - $this->parent->addInstallStep( $callback, 'database' ); - } - - public function setupDatabase() { - $status = Status::newGood(); - - return $status; - } - - public function setupUser() { - global $IP; - - if ( !$this->getVar( '_CreateDBAccount' ) ) { - return Status::newGood(); - } - - // normaly only SYSDBA users can create accounts - $status = $this->openSYSDBAConnection(); - if ( !$status->isOK() ) { - if ( $this->connError == 1031 ) { - // insufficient privileges (looks like a normal user) - $status = $this->openConnection(); - if ( !$status->isOK() ) { - return $status; - } - } else { - return $status; - } - } - - $this->db = $status->value; - $this->setupSchemaVars(); - - if ( !$this->db->selectDB( $this->getVar( 'wgDBuser' ) ) ) { - $this->db->setFlag( DBO_DDLMODE ); - $error = $this->db->sourceFile( "$IP/maintenance/oracle/user.sql" ); - if ( $error !== true || !$this->db->selectDB( $this->getVar( 'wgDBuser' ) ) ) { - $status->fatal( 'config-install-user-failed', $this->getVar( 'wgDBuser' ), $error ); - } - } elseif ( $this->db->getFlag( DBO_SYSDBA ) ) { - $status->fatal( 'config-db-sys-user-exists-oracle', $this->getVar( 'wgDBuser' ) ); - } - - if ( $status->isOK() ) { - // user created or already existing, switching back to a normal connection - // as the new user has all needed privileges to setup the rest of the schema - // i will be using that user as _InstallUser from this point on - $this->db->close(); - $this->db = false; - $this->parent->setVar( '_InstallUser', $this->getVar( 'wgDBuser' ) ); - $this->parent->setVar( '_InstallPassword', $this->getVar( 'wgDBpassword' ) ); - $this->parent->setVar( '_InstallDBname', $this->getVar( 'wgDBuser' ) ); - $status = $this->getConnection(); - } - - return $status; - } - - /** - * Overload: after this action field info table has to be rebuilt - * @return Status - */ - public function createTables() { - $this->setupSchemaVars(); - $this->db->setFlag( DBO_DDLMODE ); - $this->parent->setVar( 'wgDBname', $this->getVar( 'wgDBuser' ) ); - $status = parent::createTables(); - $this->db->clearFlag( DBO_DDLMODE ); - - $this->db->query( 'BEGIN fill_wiki_info; END;' ); - - return $status; - } - - public function getSchemaVars() { - $varNames = array( - # These variables are used by maintenance/oracle/user.sql - '_OracleDefTS', - '_OracleTempTS', - 'wgDBuser', - 'wgDBpassword', - - # These are used by tables.sql - 'wgDBprefix', - ); - $vars = array(); - foreach ( $varNames as $name ) { - $vars[$name] = $this->getVar( $name ); - } - - return $vars; - } - - public function getLocalSettings() { - $prefix = $this->getVar( 'wgDBprefix' ); - - return "# Oracle specific settings -\$wgDBprefix = \"{$prefix}\"; -"; - } - - /** - * Function checks the format of Oracle connect string - * The actual validity of the string is checked by attempting to connect - * - * Regex should be able to validate all connect string formats - * [//](host|tns_name)[:port][/service_name][:POOLED] - * http://www.orafaq.com/wiki/EZCONNECT - * - * @since 1.22 - * - * @param string $connect_string - * - * @return bool Whether the connection string is valid. - */ - public static function checkConnectStringFormat( $connect_string ) { - // @@codingStandardsIgnoreStart Long lines with regular expressions. - // @todo Very long regular expression. Make more readable? - $isValid = preg_match( '/^[[:alpha:]][\w\-]*(?:\.[[:alpha:]][\w\-]*){0,2}$/', $connect_string ); // TNS name - $isValid |= preg_match( '/^(?:\/\/)?[\w\-\.]+(?::[\d]+)?(?:\/(?:[\w\-\.]+(?::(pooled|dedicated|shared))?)?(?:\/[\w\-\.]+)?)?$/', $connect_string ); // EZConnect - // @@codingStandardsIgnoreEnd - return (bool)$isValid; - } -} diff --git a/includes/installer/OracleUpdater.php b/includes/installer/OracleUpdater.php deleted file mode 100644 index 03dbd1ce..00000000 --- a/includes/installer/OracleUpdater.php +++ /dev/null @@ -1,289 +0,0 @@ -db->fieldInfo( 'page', 'page_namespace' ); - if ( $meta->defaultValue() != null ) { - return; - } - - $this->applyPatch( - 'patch_namespace_defaults.sql', - false, - 'Altering namespace fields with default value' - ); - } - - /** - * Uniform FK names + deferrable state - */ - protected function doFKRenameDeferr() { - $meta = $this->db->query( ' - SELECT COUNT(*) cnt - FROM user_constraints - WHERE constraint_type = \'R\' AND deferrable = \'DEFERRABLE\'' - ); - $row = $meta->fetchRow(); - if ( $row && $row['cnt'] > 0 ) { - return; - } - - $this->applyPatch( 'patch_fk_rename_deferred.sql', false, "Altering foreign keys ... " ); - } - - /** - * Recreate functions to 17 schema layout - */ - protected function doFunctions17() { - $this->applyPatch( 'patch_create_17_functions.sql', false, "Recreating functions" ); - } - - /** - * Schema upgrade 16->17 - * there are no incremental patches prior to this - */ - protected function doSchemaUpgrade17() { - // check if iwlinks table exists which was added in 1.17 - if ( $this->db->tableExists( 'iwlinks' ) ) { - return; - } - $this->applyPatch( 'patch_16_17_schema_changes.sql', false, "Updating schema to 17" ); - } - - /** - * Insert page (page_id = 0) to prevent FK constraint violation - */ - protected function doInsertPage0() { - $this->output( "Inserting page 0 if missing ... " ); - $row = array( - 'page_id' => 0, - 'page_namespace' => 0, - 'page_title' => ' ', - 'page_is_redirect' => 0, - 'page_is_new' => 0, - 'page_random' => 0, - 'page_touched' => $this->db->timestamp(), - 'page_latest' => 0, - 'page_len' => 0 - ); - $this->db->insert( 'page', $row, 'OracleUpdater:doInserPage0', array( 'IGNORE' ) ); - $this->output( "ok\n" ); - } - - /** - * Remove DEFAULT '' NOT NULL constraints from fields as '' is internally - * converted to NULL in Oracle - */ - protected function doRemoveNotNullEmptyDefaults() { - $meta = $this->db->fieldInfo( 'categorylinks', 'cl_sortkey_prefix' ); - if ( $meta->isNullable() ) { - return; - } - $this->applyPatch( - 'patch_remove_not_null_empty_defs.sql', - false, - 'Removing not null empty constraints' - ); - } - - protected function doRemoveNotNullEmptyDefaults2() { - $meta = $this->db->fieldInfo( 'ipblocks', 'ipb_by_text' ); - if ( $meta->isNullable() ) { - return; - } - $this->applyPatch( - 'patch_remove_not_null_empty_defs2.sql', - false, - 'Removing not null empty constraints' - ); - } - - /** - * Removed forcing of invalid state on recentchanges_fk2. - * cascading taken in account in the deleting function - */ - protected function doRecentchangesFK2Cascade() { - $meta = $this->db->query( 'SELECT 1 FROM all_constraints WHERE owner = \'' . - strtoupper( $this->db->getDBname() ) . - '\' AND constraint_name = \'' . - $this->db->tablePrefix() . - 'RECENTCHANGES_FK2\' AND delete_rule = \'CASCADE\'' - ); - $row = $meta->fetchRow(); - if ( $row ) { - return; - } - - $this->applyPatch( 'patch_recentchanges_fk2_cascade.sql', false, "Altering RECENTCHANGES_FK2" ); - } - - /** - * Fixed wrong PK, UK definition - */ - protected function doPageRestrictionsPKUKFix() { - $this->output( "Altering PAGE_RESTRICTIONS keys ... " ); - - $meta = $this->db->query( 'SELECT column_name FROM all_cons_columns WHERE owner = \'' . - strtoupper( $this->db->getDBname() ) . - '\' AND constraint_name = \'' . - $this->db->tablePrefix() . - 'PAGE_RESTRICTIONS_PK\' AND rownum = 1' - ); - $row = $meta->fetchRow(); - if ( $row['column_name'] == 'PR_ID' ) { - $this->output( "seems to be up to date.\n" ); - - return; - } - - $this->applyPatch( 'patch-page_restrictions_pkuk_fix.sql', false ); - $this->output( "ok\n" ); - } - - /** - * rebuilding of the function that duplicates tables for tests - */ - protected function doRebuildDuplicateFunction() { - $this->applyPatch( 'patch_rebuild_dupfunc.sql', false, "Rebuilding duplicate function" ); - } - - /** - * Overload: after this action field info table has to be rebuilt - * - * @param array $what - */ - public function doUpdates( $what = array( 'core', 'extensions', 'purge', 'stats' ) ) { - parent::doUpdates( $what ); - - $this->db->query( 'BEGIN fill_wiki_info; END;' ); - } - - /** - * Overload: because of the DDL_MODE tablename escaping is a bit dodgy - */ - public function purgeCache() { - # We can't guarantee that the user will be able to use TRUNCATE, - # but we know that DELETE is available to us - $this->output( "Purging caches..." ); - $this->db->delete( '/*Q*/' . $this->db->tableName( 'objectcache' ), '*', __METHOD__ ); - $this->output( "done.\n" ); - } -} diff --git a/includes/libs/IEContentAnalyzer.php b/includes/libs/IEContentAnalyzer.php deleted file mode 100644 index c31a3527..00000000 --- a/includes/libs/IEContentAnalyzer.php +++ /dev/null @@ -1,851 +0,0 @@ - array( - 'text/plain', - 'application/octet-stream', - 'application/x-netcdf', // [sic] - ), - 'text' /*3*/ => array( - 'text/richtext', 'image/x-bitmap', 'application/postscript', 'application/base64', - 'application/macbinhex40', 'application/x-cdf', 'text/scriptlet' - ), - 'binary' /*4*/ => array( - 'application/pdf', 'audio/x-aiff', 'audio/basic', 'audio/wav', 'image/gif', - 'image/pjpeg', 'image/jpeg', 'image/tiff', 'image/x-png', 'image/png', 'image/bmp', - 'image/x-jg', 'image/x-art', 'image/x-emf', 'image/x-wmf', 'video/avi', - 'video/x-msvideo', 'video/mpeg', 'application/x-compressed', - 'application/x-zip-compressed', 'application/x-gzip-compressed', 'application/java', - 'application/x-msdownload' - ), - 'html' /*5*/ => array( 'text/html' ), - ); - - /** - * Changes to the type table in later versions of IE - */ - protected $addedTypes = array( - 'ie07' => array( - 'text' => array( 'text/xml', 'application/xml' ) - ), - ); - - /** - * An approximation of the "Content Type" values in HKEY_CLASSES_ROOT in a - * typical Windows installation. - * - * Used for extension to MIME type mapping if detection fails. - */ - protected $registry = array( - '.323' => 'text/h323', - '.3g2' => 'video/3gpp2', - '.3gp' => 'video/3gpp', - '.3gp2' => 'video/3gpp2', - '.3gpp' => 'video/3gpp', - '.aac' => 'audio/aac', - '.ac3' => 'audio/ac3', - '.accda' => 'application/msaccess', - '.accdb' => 'application/msaccess', - '.accdc' => 'application/msaccess', - '.accde' => 'application/msaccess', - '.accdr' => 'application/msaccess', - '.accdt' => 'application/msaccess', - '.ade' => 'application/msaccess', - '.adp' => 'application/msaccess', - '.adts' => 'audio/aac', - '.ai' => 'application/postscript', - '.aif' => 'audio/aiff', - '.aifc' => 'audio/aiff', - '.aiff' => 'audio/aiff', - '.amc' => 'application/x-mpeg', - '.application' => 'application/x-ms-application', - '.asf' => 'video/x-ms-asf', - '.asx' => 'video/x-ms-asf', - '.au' => 'audio/basic', - '.avi' => 'video/avi', - '.bmp' => 'image/bmp', - '.caf' => 'audio/x-caf', - '.cat' => 'application/vnd.ms-pki.seccat', - '.cbo' => 'application/sha', - '.cdda' => 'audio/aiff', - '.cer' => 'application/x-x509-ca-cert', - '.conf' => 'text/plain', - '.crl' => 'application/pkix-crl', - '.crt' => 'application/x-x509-ca-cert', - '.css' => 'text/css', - '.csv' => 'application/vnd.ms-excel', - '.der' => 'application/x-x509-ca-cert', - '.dib' => 'image/bmp', - '.dif' => 'video/x-dv', - '.dll' => 'application/x-msdownload', - '.doc' => 'application/msword', - '.docm' => 'application/vnd.ms-word.document.macroEnabled.12', - '.docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - '.dot' => 'application/msword', - '.dotm' => 'application/vnd.ms-word.template.macroEnabled.12', - '.dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', - '.dv' => 'video/x-dv', - '.dwfx' => 'model/vnd.dwfx+xps', - '.edn' => 'application/vnd.adobe.edn', - '.eml' => 'message/rfc822', - '.eps' => 'application/postscript', - '.etd' => 'application/x-ebx', - '.exe' => 'application/x-msdownload', - '.fdf' => 'application/vnd.fdf', - '.fif' => 'application/fractals', - '.gif' => 'image/gif', - '.gsm' => 'audio/x-gsm', - '.hqx' => 'application/mac-binhex40', - '.hta' => 'application/hta', - '.htc' => 'text/x-component', - '.htm' => 'text/html', - '.html' => 'text/html', - '.htt' => 'text/webviewhtml', - '.hxa' => 'application/xml', - '.hxc' => 'application/xml', - '.hxd' => 'application/octet-stream', - '.hxe' => 'application/xml', - '.hxf' => 'application/xml', - '.hxh' => 'application/octet-stream', - '.hxi' => 'application/octet-stream', - '.hxk' => 'application/xml', - '.hxq' => 'application/octet-stream', - '.hxr' => 'application/octet-stream', - '.hxs' => 'application/octet-stream', - '.hxt' => 'application/xml', - '.hxv' => 'application/xml', - '.hxw' => 'application/octet-stream', - '.ico' => 'image/x-icon', - '.iii' => 'application/x-iphone', - '.ins' => 'application/x-internet-signup', - '.iqy' => 'text/x-ms-iqy', - '.isp' => 'application/x-internet-signup', - '.jfif' => 'image/jpeg', - '.jnlp' => 'application/x-java-jnlp-file', - '.jpe' => 'image/jpeg', - '.jpeg' => 'image/jpeg', - '.jpg' => 'image/jpeg', - '.jtx' => 'application/x-jtx+xps', - '.latex' => 'application/x-latex', - '.log' => 'text/plain', - '.m1v' => 'video/mpeg', - '.m2v' => 'video/mpeg', - '.m3u' => 'audio/x-mpegurl', - '.mac' => 'image/x-macpaint', - '.man' => 'application/x-troff-man', - '.mda' => 'application/msaccess', - '.mdb' => 'application/msaccess', - '.mde' => 'application/msaccess', - '.mfp' => 'application/x-shockwave-flash', - '.mht' => 'message/rfc822', - '.mhtml' => 'message/rfc822', - '.mid' => 'audio/mid', - '.midi' => 'audio/mid', - '.mod' => 'video/mpeg', - '.mov' => 'video/quicktime', - '.mp2' => 'video/mpeg', - '.mp2v' => 'video/mpeg', - '.mp3' => 'audio/mpeg', - '.mp4' => 'video/mp4', - '.mpa' => 'video/mpeg', - '.mpe' => 'video/mpeg', - '.mpeg' => 'video/mpeg', - '.mpf' => 'application/vnd.ms-mediapackage', - '.mpg' => 'video/mpeg', - '.mpv2' => 'video/mpeg', - '.mqv' => 'video/quicktime', - '.NMW' => 'application/nmwb', - '.nws' => 'message/rfc822', - '.odc' => 'text/x-ms-odc', - '.ols' => 'application/vnd.ms-publisher', - '.p10' => 'application/pkcs10', - '.p12' => 'application/x-pkcs12', - '.p7b' => 'application/x-pkcs7-certificates', - '.p7c' => 'application/pkcs7-mime', - '.p7m' => 'application/pkcs7-mime', - '.p7r' => 'application/x-pkcs7-certreqresp', - '.p7s' => 'application/pkcs7-signature', - '.pct' => 'image/pict', - '.pdf' => 'application/pdf', - '.pdx' => 'application/vnd.adobe.pdx', - '.pfx' => 'application/x-pkcs12', - '.pic' => 'image/pict', - '.pict' => 'image/pict', - '.pinstall' => 'application/x-picasa-detect', - '.pko' => 'application/vnd.ms-pki.pko', - '.png' => 'image/png', - '.pnt' => 'image/x-macpaint', - '.pntg' => 'image/x-macpaint', - '.pot' => 'application/vnd.ms-powerpoint', - '.potm' => 'application/vnd.ms-powerpoint.template.macroEnabled.12', - '.potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template', - '.ppa' => 'application/vnd.ms-powerpoint', - '.ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12', - '.pps' => 'application/vnd.ms-powerpoint', - '.ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12', - '.ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', - '.ppt' => 'application/vnd.ms-powerpoint', - '.pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12', - '.pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', - '.prf' => 'application/pics-rules', - '.ps' => 'application/postscript', - '.pub' => 'application/vnd.ms-publisher', - '.pwz' => 'application/vnd.ms-powerpoint', - '.py' => 'text/plain', - '.pyw' => 'text/plain', - '.qht' => 'text/x-html-insertion', - '.qhtm' => 'text/x-html-insertion', - '.qt' => 'video/quicktime', - '.qti' => 'image/x-quicktime', - '.qtif' => 'image/x-quicktime', - '.qtl' => 'application/x-quicktimeplayer', - '.rat' => 'application/rat-file', - '.rmf' => 'application/vnd.adobe.rmf', - '.rmi' => 'audio/mid', - '.rqy' => 'text/x-ms-rqy', - '.rtf' => 'application/msword', - '.sct' => 'text/scriptlet', - '.sd2' => 'audio/x-sd2', - '.sdp' => 'application/sdp', - '.shtml' => 'text/html', - '.sit' => 'application/x-stuffit', - '.sldm' => 'application/vnd.ms-powerpoint.slide.macroEnabled.12', - '.sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide', - '.slk' => 'application/vnd.ms-excel', - '.snd' => 'audio/basic', - '.so' => 'application/x-apachemodule', - '.sol' => 'text/plain', - '.sor' => 'text/plain', - '.spc' => 'application/x-pkcs7-certificates', - '.spl' => 'application/futuresplash', - '.sst' => 'application/vnd.ms-pki.certstore', - '.stl' => 'application/vnd.ms-pki.stl', - '.swf' => 'application/x-shockwave-flash', - '.thmx' => 'application/vnd.ms-officetheme', - '.tif' => 'image/tiff', - '.tiff' => 'image/tiff', - '.txt' => 'text/plain', - '.uls' => 'text/iuls', - '.vcf' => 'text/x-vcard', - '.vdx' => 'application/vnd.ms-visio.viewer', - '.vsd' => 'application/vnd.ms-visio.viewer', - '.vss' => 'application/vnd.ms-visio.viewer', - '.vst' => 'application/vnd.ms-visio.viewer', - '.vsx' => 'application/vnd.ms-visio.viewer', - '.vtx' => 'application/vnd.ms-visio.viewer', - '.wav' => 'audio/wav', - '.wax' => 'audio/x-ms-wax', - '.wbk' => 'application/msword', - '.wdp' => 'image/vnd.ms-photo', - '.wiz' => 'application/msword', - '.wm' => 'video/x-ms-wm', - '.wma' => 'audio/x-ms-wma', - '.wmd' => 'application/x-ms-wmd', - '.wmv' => 'video/x-ms-wmv', - '.wmx' => 'video/x-ms-wmx', - '.wmz' => 'application/x-ms-wmz', - '.wpl' => 'application/vnd.ms-wpl', - '.wsc' => 'text/scriptlet', - '.wvx' => 'video/x-ms-wvx', - '.xaml' => 'application/xaml+xml', - '.xbap' => 'application/x-ms-xbap', - '.xdp' => 'application/vnd.adobe.xdp+xml', - '.xfdf' => 'application/vnd.adobe.xfdf', - '.xht' => 'application/xhtml+xml', - '.xhtml' => 'application/xhtml+xml', - '.xla' => 'application/vnd.ms-excel', - '.xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12', - '.xlk' => 'application/vnd.ms-excel', - '.xll' => 'application/vnd.ms-excel', - '.xlm' => 'application/vnd.ms-excel', - '.xls' => 'application/vnd.ms-excel', - '.xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12', - '.xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12', - '.xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - '.xlt' => 'application/vnd.ms-excel', - '.xltm' => 'application/vnd.ms-excel.template.macroEnabled.12', - '.xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', - '.xlw' => 'application/vnd.ms-excel', - '.xml' => 'text/xml', - '.xps' => 'application/vnd.ms-xpsdocument', - '.xsl' => 'text/xml', - ); - - /** - * IE versions which have been analysed to bring you this class, and for - * which some substantive difference exists. These will appear as keys - * in the return value of getRealMimesFromData(). The names are chosen to sort correctly. - */ - protected $versions = array( 'ie05', 'ie06', 'ie07', 'ie07.strict', 'ie07.nohtml' ); - - /** - * Type table with versions expanded - */ - protected $typeTable = array(); - - /** constructor */ - function __construct() { - // Construct versioned type arrays from the base type array plus additions - $types = $this->baseTypeTable; - foreach ( $this->versions as $version ) { - if ( isset( $this->addedTypes[$version] ) ) { - foreach ( $this->addedTypes[$version] as $format => $addedTypes ) { - $types[$format] = array_merge( $types[$format], $addedTypes ); - } - } - $this->typeTable[$version] = $types; - } - } - - /** - * Get the MIME types from getMimesFromData(), but convert the result from IE's - * idiosyncratic private types into something other apps will understand. - * - * @param string $fileName the file name (unused at present) - * @param string $chunk the first 256 bytes of the file - * @param string $proposed the MIME type proposed by the server - * - * @return Array: map of IE version to detected MIME type - */ - public function getRealMimesFromData( $fileName, $chunk, $proposed ) { - $types = $this->getMimesFromData( $fileName, $chunk, $proposed ); - $types = array_map( array( $this, 'translateMimeType' ), $types ); - return $types; - } - - /** - * Translate a MIME type from IE's idiosyncratic private types into - * more commonly understood type strings - * @param $type - * @return string - */ - public function translateMimeType( $type ) { - static $table = array( - 'image/pjpeg' => 'image/jpeg', - 'image/x-png' => 'image/png', - 'image/x-wmf' => 'application/x-msmetafile', - 'image/bmp' => 'image/x-bmp', - 'application/x-zip-compressed' => 'application/zip', - 'application/x-compressed' => 'application/x-compress', - 'application/x-gzip-compressed' => 'application/x-gzip', - 'audio/mid' => 'audio/midi', - ); - if ( isset( $table[$type] ) ) { - $type = $table[$type]; - } - return $type; - } - - /** - * Get the untranslated MIME types for all known versions - * - * @param string $fileName the file name (unused at present) - * @param string $chunk the first 256 bytes of the file - * @param string $proposed the MIME type proposed by the server - * - * @return Array: map of IE version to detected MIME type - */ - public function getMimesFromData( $fileName, $chunk, $proposed ) { - $types = array(); - foreach ( $this->versions as $version ) { - $types[$version] = $this->getMimeTypeForVersion( $version, $fileName, $chunk, $proposed ); - } - return $types; - } - - /** - * Get the MIME type for a given named version - * @param $version - * @param $fileName - * @param $chunk - * @param $proposed - * @return bool|string - */ - protected function getMimeTypeForVersion( $version, $fileName, $chunk, $proposed ) { - // Strip text after a semicolon - $semiPos = strpos( $proposed, ';' ); - if ( $semiPos !== false ) { - $proposed = substr( $proposed, 0, $semiPos ); - } - - $proposedFormat = $this->getDataFormat( $version, $proposed ); - if ( $proposedFormat == 'unknown' - && $proposed != 'multipart/mixed' - && $proposed != 'multipart/x-mixed-replace' ) - { - return $proposed; - } - if ( strval( $chunk ) === '' ) { - return $proposed; - } - - // Truncate chunk at 255 bytes - $chunk = substr( $chunk, 0, 255 ); - - // IE does the Check*Headers() calls last, and instead does the following image - // type checks by directly looking for the magic numbers. What I do here should - // have the same effect since the magic number checks are identical in both cases. - $result = $this->sampleData( $version, $chunk ); - $sampleFound = $result['found']; - $counters = $result['counters']; - $binaryType = $this->checkBinaryHeaders( $version, $chunk ); - $textType = $this->checkTextHeaders( $version, $chunk ); - - if ( $proposed == 'text/html' && isset( $sampleFound['html'] ) ) { - return 'text/html'; - } - if ( $proposed == 'image/gif' && $binaryType == 'image/gif' ) { - return 'image/gif'; - } - if ( ( $proposed == 'image/pjpeg' || $proposed == 'image/jpeg' ) - && $binaryType == 'image/pjpeg' ) - { - return $proposed; - } - // PNG check added in IE 7 - if ( $version >= 'ie07' - && ( $proposed == 'image/x-png' || $proposed == 'image/png' ) - && $binaryType == 'image/x-png' ) - { - return $proposed; - } - - // CDF was removed in IE 7 so it won't be in $sampleFound for later versions - if ( isset( $sampleFound['cdf'] ) ) { - return 'application/x-cdf'; - } - - // RSS and Atom were added in IE 7 so they won't be in $sampleFound for - // previous versions - if ( isset( $sampleFound['rss'] ) ) { - return 'application/rss+xml'; - } - if ( isset( $sampleFound['rdf-tag'] ) - && isset( $sampleFound['rdf-url'] ) - && isset( $sampleFound['rdf-purl'] ) ) - { - return 'application/rss+xml'; - } - if ( isset( $sampleFound['atom'] ) ) { - return 'application/atom+xml'; - } - - if ( isset( $sampleFound['xml'] ) ) { - // TODO: I'm not sure under what circumstances this flag is enabled - if ( strpos( $version, 'strict' ) !== false ) { - if ( $proposed == 'text/html' || $proposed == 'text/xml' ) { - return 'text/xml'; - } - } else { - return 'text/xml'; - } - } - if ( isset( $sampleFound['html'] ) ) { - // TODO: I'm not sure under what circumstances this flag is enabled - if ( strpos( $version, 'nohtml' ) !== false ) { - if ( $proposed == 'text/plain' ) { - return 'text/html'; - } - } else { - return 'text/html'; - } - } - if ( isset( $sampleFound['xbm'] ) ) { - return 'image/x-bitmap'; - } - if ( isset( $sampleFound['binhex'] ) ) { - return 'application/macbinhex40'; - } - if ( isset( $sampleFound['scriptlet'] ) ) { - if ( strpos( $version, 'strict' ) !== false ) { - if ( $proposed == 'text/plain' || $proposed == 'text/scriptlet' ) { - return 'text/scriptlet'; - } - } else { - return 'text/scriptlet'; - } - } - - // Freaky heuristics to determine if the data is text or binary - // The heuristic is of course broken for non-ASCII text - if ( $counters['ctrl'] != 0 && ( $counters['ff'] + $counters['low'] ) - < ( $counters['ctrl'] + $counters['high'] ) * 16 ) - { - $kindOfBinary = true; - $type = $binaryType ? $binaryType : $textType; - if ( $type === false ) { - $type = 'application/octet-stream'; - } - } else { - $kindOfBinary = false; - $type = $textType ? $textType : $binaryType; - if ( $type === false ) { - $type = 'text/plain'; - } - } - - // Check if the output format is ambiguous - // This generally means that detection failed, real types aren't ambiguous - $detectedFormat = $this->getDataFormat( $version, $type ); - if ( $detectedFormat != 'ambiguous' ) { - return $type; - } - - if ( $proposedFormat != 'ambiguous' ) { - // FormatAgreesWithData() - if ( $proposedFormat == 'text' && !$kindOfBinary ) { - return $proposed; - } - if ( $proposedFormat == 'binary' && $kindOfBinary ) { - return $proposed; - } - if ( $proposedFormat == 'html' ) { - return $proposed; - } - } - - // Find a MIME type by searching the registry for the file extension. - $dotPos = strrpos( $fileName, '.' ); - if ( $dotPos === false ) { - return $type; - } - $ext = substr( $fileName, $dotPos ); - if ( isset( $this->registry[$ext] ) ) { - return $this->registry[$ext]; - } - - // TODO: If the extension has an application registered to it, IE will return - // application/octet-stream. We'll skip that, so we could erroneously - // return text/plain or application/x-netcdf where application/octet-stream - // would be correct. - - return $type; - } - - /** - * Check for text headers at the start of the chunk - * Confirmed same in 5 and 7. - * @param $version - * @param $chunk - * @return bool|string - */ - private function checkTextHeaders( $version, $chunk ) { - $chunk2 = substr( $chunk, 0, 2 ); - $chunk4 = substr( $chunk, 0, 4 ); - $chunk5 = substr( $chunk, 0, 5 ); - if ( $chunk4 == '%PDF' ) { - return 'application/pdf'; - } - if ( $chunk2 == '%!' ) { - return 'application/postscript'; - } - if ( $chunk5 == '{\\rtf' ) { - return 'text/richtext'; - } - if ( $chunk5 == 'begin' ) { - return 'application/base64'; - } - return false; - } - - /** - * Check for binary headers at the start of the chunk - * Confirmed same in 5 and 7. - * @param $version - * @param $chunk - * @return bool|string - */ - private function checkBinaryHeaders( $version, $chunk ) { - $chunk2 = substr( $chunk, 0, 2 ); - $chunk3 = substr( $chunk, 0, 3 ); - $chunk4 = substr( $chunk, 0, 4 ); - $chunk5 = substr( $chunk, 0, 5 ); - $chunk5uc = strtoupper( $chunk5 ); - $chunk8 = substr( $chunk, 0, 8 ); - if ( $chunk5uc == 'GIF87' || $chunk5uc == 'GIF89' ) { - return 'image/gif'; - } - if ( $chunk2 == "\xff\xd8" ) { - return 'image/pjpeg'; // actually plain JPEG but this is what IE returns - } - - if ( $chunk2 == 'BM' - && substr( $chunk, 6, 2 ) == "\000\000" - && substr( $chunk, 8, 2 ) == "\000\000" ) - { - return 'image/bmp'; // another non-standard MIME - } - if ( $chunk4 == 'RIFF' - && substr( $chunk, 8, 4 ) == 'WAVE' ) - { - return 'audio/wav'; - } - // These were integer literals in IE - // Perhaps the author was not sure what the target endianness was - if ( $chunk4 == ".sd\000" - || $chunk4 == ".snd" - || $chunk4 == "\000ds." - || $chunk4 == "dns." ) - { - return 'audio/basic'; - } - if ( $chunk3 == "MM\000" ) { - return 'image/tiff'; - } - if ( $chunk2 == 'MZ' ) { - return 'application/x-msdownload'; - } - if ( $chunk8 == "\x89PNG\x0d\x0a\x1a\x0a" ) { - return 'image/x-png'; // [sic] - } - if ( strlen( $chunk ) >= 5 ) { - $byte2 = ord( $chunk[2] ); - $byte4 = ord( $chunk[4] ); - if ( $byte2 >= 3 && $byte2 <= 31 && $byte4 == 0 && $chunk2 == 'JG' ) { - return 'image/x-jg'; - } - } - // More endian confusion? - if ( $chunk4 == 'MROF' ) { - return 'audio/x-aiff'; - } - $chunk4_8 = substr( $chunk, 8, 4 ); - if ( $chunk4 == 'FORM' && ( $chunk4_8 == 'AIFF' || $chunk4_8 == 'AIFC' ) ) { - return 'audio/x-aiff'; - } - if ( $chunk4 == 'RIFF' && $chunk4_8 == 'AVI ' ) { - return 'video/avi'; - } - if ( $chunk4 == "\x00\x00\x01\xb3" || $chunk4 == "\x00\x00\x01\xba" ) { - return 'video/mpeg'; - } - if ( $chunk4 == "\001\000\000\000" - && substr( $chunk, 40, 4 ) == ' EMF' ) - { - return 'image/x-emf'; - } - if ( $chunk4 == "\xd7\xcd\xc6\x9a" ) { - return 'image/x-wmf'; - } - if ( $chunk4 == "\xca\xfe\xba\xbe" ) { - return 'application/java'; - } - if ( $chunk2 == 'PK' ) { - return 'application/x-zip-compressed'; - } - if ( $chunk2 == "\x1f\x9d" ) { - return 'application/x-compressed'; - } - if ( $chunk2 == "\x1f\x8b" ) { - return 'application/x-gzip-compressed'; - } - // Skip redundant check for ZIP - if ( $chunk5 == "MThd\000" ) { - return 'audio/mid'; - } - if ( $chunk4 == '%PDF' ) { - return 'application/pdf'; - } - return false; - } - - /** - * Do heuristic checks on the bulk of the data sample. - * Search for HTML tags. - * @param $version - * @param $chunk - * @return array - */ - protected function sampleData( $version, $chunk ) { - $found = array(); - $counters = array( - 'ctrl' => 0, - 'high' => 0, - 'low' => 0, - 'lf' => 0, - 'cr' => 0, - 'ff' => 0 - ); - $htmlTags = array( - 'html', - 'head', - 'title', - 'body', - 'script', - 'a href', - 'pre', - 'img', - 'plaintext', - 'table' - ); - $rdfUrl = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'; - $rdfPurl = 'http://purl.org/rss/1.0/'; - $xbmMagic1 = '#define'; - $xbmMagic2 = '_width'; - $xbmMagic3 = '_bits'; - $binhexMagic = 'converted with BinHex'; - $chunkLength = strlen( $chunk ); - - for ( $offset = 0; $offset < $chunkLength; $offset++ ) { - $curChar = $chunk[$offset]; - if ( $curChar == "\x0a" ) { - $counters['lf']++; - continue; - } elseif ( $curChar == "\x0d" ) { - $counters['cr']++; - continue; - } elseif ( $curChar == "\x0c" ) { - $counters['ff']++; - continue; - } elseif ( $curChar == "\t" ) { - $counters['low']++; - continue; - } elseif ( ord( $curChar ) < 32 ) { - $counters['ctrl']++; - continue; - } elseif ( ord( $curChar ) >= 128 ) { - $counters['high']++; - continue; - } - - $counters['low']++; - if ( $curChar == '<' ) { - // XML - $remainder = substr( $chunk, $offset + 1 ); - if ( !strncasecmp( $remainder, '?XML', 4 ) ) { - $nextChar = substr( $chunk, $offset + 5, 1 ); - if ( $nextChar == ':' || $nextChar == ' ' || $nextChar == "\t" ) { - $found['xml'] = true; - } - } - // Scriptlet (JSP) - if ( !strncasecmp( $remainder, 'SCRIPTLET', 9 ) ) { - $found['scriptlet'] = true; - break; - } - // HTML - foreach ( $htmlTags as $tag ) { - if ( !strncasecmp( $remainder, $tag, strlen( $tag ) ) ) { - $found['html'] = true; - } - } - // Skip broken check for additional tags (HR etc.) - - // CHANNEL replaced by RSS, RDF and FEED in IE 7 - if ( $version < 'ie07' ) { - if ( !strncasecmp( $remainder, 'CHANNEL', 7 ) ) { - $found['cdf'] = true; - } - } else { - // RSS - if ( !strncasecmp( $remainder, 'RSS', 3 ) ) { - $found['rss'] = true; - break; // return from SampleData - } - if ( !strncasecmp( $remainder, 'rdf:RDF', 7 ) ) { - $found['rdf-tag'] = true; - // no break - } - if ( !strncasecmp( $remainder, 'FEED', 4 ) ) { - $found['atom'] = true; - break; - } - } - continue; - } - // Skip broken check for --> - - // RSS URL checks - // For some reason both URLs must appear before it is recognised - $remainder = substr( $chunk, $offset ); - if ( !strncasecmp( $remainder, $rdfUrl, strlen( $rdfUrl ) ) ) { - $found['rdf-url'] = true; - if ( isset( $found['rdf-tag'] ) - && isset( $found['rdf-purl'] ) ) // [sic] - { - break; - } - continue; - } - - if ( !strncasecmp( $remainder, $rdfPurl, strlen( $rdfPurl ) ) ) { - if ( isset( $found['rdf-tag'] ) - && isset( $found['rdf-url'] ) ) // [sic] - { - break; - } - continue; - } - - // XBM checks - if ( !strncasecmp( $remainder, $xbmMagic1, strlen( $xbmMagic1 ) ) ) { - $found['xbm1'] = true; - continue; - } - if ( $curChar == '_' ) { - if ( isset( $found['xbm2'] ) ) { - if ( !strncasecmp( $remainder, $xbmMagic3, strlen( $xbmMagic3 ) ) ) { - $found['xbm'] = true; - break; - } - } elseif ( isset( $found['xbm1'] ) ) { - if ( !strncasecmp( $remainder, $xbmMagic2, strlen( $xbmMagic2 ) ) ) { - $found['xbm2'] = true; - } - } - } - - // BinHex - if ( !strncmp( $remainder, $binhexMagic, strlen( $binhexMagic ) ) ) { - $found['binhex'] = true; - } - } - return array( 'found' => $found, 'counters' => $counters ); - } - - /** - * @param $version - * @param $type - * @return int|string - */ - protected function getDataFormat( $version, $type ) { - $types = $this->typeTable[$version]; - if ( $type == '(null)' || strval( $type ) === '' ) { - return 'ambiguous'; - } - foreach ( $types as $format => $list ) { - if ( in_array( $type, $list ) ) { - return $format; - } - } - return 'unknown'; - } -} diff --git a/includes/libs/IEUrlExtension.php b/includes/libs/IEUrlExtension.php deleted file mode 100644 index 49d05d4b..00000000 --- a/includes/libs/IEUrlExtension.php +++ /dev/null @@ -1,271 +0,0 @@ -\"/:|?.# - * - if we find a possible extension followed by the end of the string or - * a #, that's our extension - * - if we find a possible extension followed by a ?, that's our extension - * - UNLESS it's exe, dll or cgi, in which case we ignore it and continue - * searching for another possible extension - * - if we find a possible extension followed by a dot or another illegal - * character, we ignore it and continue searching - * - * @param string $url URL - * @return mixed Detected extension (string), or false if none found - */ - public static function findIE6Extension( $url ) { - $pos = 0; - $hashPos = strpos( $url, '#' ); - if ( $hashPos !== false ) { - $urlLength = $hashPos; - } else { - $urlLength = strlen( $url ); - } - $remainingLength = $urlLength; - while ( $remainingLength > 0 ) { - // Skip ahead to the next dot - $pos += strcspn( $url, '.', $pos, $remainingLength ); - if ( $pos >= $urlLength ) { - // End of string, we're done - return false; - } - - // We found a dot. Skip past it - $pos++; - $remainingLength = $urlLength - $pos; - - // Check for illegal characters in our prospective extension, - // or for another dot - $nextPos = $pos + strcspn( $url, "<>\\\"/:|?*.", $pos, $remainingLength ); - if ( $nextPos >= $urlLength ) { - // No illegal character or next dot - // We have our extension - return substr( $url, $pos, $urlLength - $pos ); - } - if ( $url[$nextPos] === '?' ) { - // We've found a legal extension followed by a question mark - // If the extension is NOT exe, dll or cgi, return it - $extension = substr( $url, $pos, $nextPos - $pos ); - if ( strcasecmp( $extension, 'exe' ) && strcasecmp( $extension, 'dll' ) && - strcasecmp( $extension, 'cgi' ) ) - { - return $extension; - } - // Else continue looking - } - // We found an illegal character or another dot - // Skip to that character and continue the loop - $pos = $nextPos; - $remainingLength = $urlLength - $pos; - } - return false; - } - - /** - * When passed the value of $_SERVER['SERVER_SOFTWARE'], this function - * returns true if that server is known to have a REQUEST_URI variable - * with %2E not decoded to ".". On such a server, it is possible to detect - * whether the script filename has been obscured. - * - * The function returns false if the server is not known to have this - * behavior. Microsoft IIS in particular is known to decode escaped script - * filenames. - * - * SERVER_SOFTWARE typically contains either a plain string such as "Zeus", - * or a specification in the style of a User-Agent header, such as - * "Apache/1.3.34 (Unix) mod_ssl/2.8.25 OpenSSL/0.9.8a PHP/4.4.2" - * - * @param $serverSoftware - * @return bool - * - */ - public static function haveUndecodedRequestUri( $serverSoftware ) { - static $whitelist = array( - 'Apache', - 'Zeus', - 'LiteSpeed' ); - if ( preg_match( '/^(.*?)($|\/| )/', $serverSoftware, $m ) ) { - return in_array( $m[1], $whitelist ); - } else { - return false; - } - } - -} diff --git a/includes/search/SearchMssql.php b/includes/search/SearchMssql.php deleted file mode 100644 index 0d7970de..00000000 --- a/includes/search/SearchMssql.php +++ /dev/null @@ -1,210 +0,0 @@ -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 string $term Raw search term - * @return SqlSearchResultSet - * @access public - */ - function searchTitle( $term ) { - $resultSet = $this->db->query( $this->getQuery( $this->filter( $term ), false ) ); - return new SqlSearchResultSet( $resultSet, $this->searchTerms ); - } - - /** - * Return a partial WHERE clause to limit the search to the given namespaces - * - * @return string - * @private - */ - function queryNamespaces() { - $namespaces = implode( ',', $this->namespaces ); - if ( $namespaces == '' ) { - $namespaces = '0'; - } - return 'AND page_namespace IN (' . $namespaces . ')'; - } - - /** - * Return a LIMIT clause to limit results on the query. - * - * @param string $sql - * - * @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 - * - * @param string $filteredTerm - * @param bool $fulltext - * @return string - */ - function queryRanking( $filteredTerm, $fulltext ) { - return ' ORDER BY ftindex.[RANK] DESC'; // return ' ORDER BY score(1)'; - } - - /** - * Construct the full SQL query to do the search. - * The guts shoulds be constructed in queryMain() - * - * @param string $filteredTerm - * @param bool $fulltext - * @return string - */ - function getQuery( $filteredTerm, $fulltext ) { - return $this->queryLimit( $this->queryMain( $filteredTerm, $fulltext ) . ' ' . - $this->queryNamespaces() . ' ' . - $this->queryRanking( $filteredTerm, $fulltext ) . ' ' ); - } - - /** - * Picks which field to index on, depending on what type of query. - * - * @param bool $fulltext - * @return string - */ - function getIndexField( $fulltext ) { - return $fulltext ? 'si_text' : 'si_title'; - } - - /** - * Get the base part of the search query. - * - * @param string $filteredTerm - * @param bool $fulltext - * @return string - * @private - */ - 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, ftindex.[RANK]' . - "FROM $page,FREETEXTTABLE($searchindex , $match, LANGUAGE 'English') as ftindex " . - 'WHERE page_id=ftindex.[KEY] '; - } - - /** @todo document - * @param string $filteredText - * @param bool $fulltext - * @return string - */ - function parseQuery( $filteredText, $fulltext ) { - global $wgContLang; - $lc = $this->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 ) { - $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->addQuotes( join( ',', $q ) ); - $field = $this->getIndexField( $fulltext ); - return "$field, $searchon"; - } - - /** - * Create or update the search index record for the given page. - * Title and text should be pre-processed. - * - * @param int $id - * @param string $title - * @param string $text - * @return bool|ResultWrapper - */ - function update( $id, $title, $text ) { - // We store the column data as UTF-8 byte order marked binary stream - // because we are invoking the plain text IFilter on it so that, and we want it - // to properly decode the stream as UTF-8. SQL doesn't support UTF8 as a data type - // but the indexer will correctly handle it by this method. Since all we are doing - // is passing this data to the indexer and never retrieving it via PHP, this will save space - $table = $this->db->tableName( 'searchindex' ); - $utf8bom = '0xEFBBBF'; - $si_title = $utf8bom . bin2hex( $title ); - $si_text = $utf8bom . bin2hex( $text ); - $sql = "DELETE FROM $table WHERE si_page = $id;"; - $sql .= "INSERT INTO $table (si_page, si_title, si_text) VALUES ($id, $si_title, $si_text)"; - return $this->db->query( $sql, 'SearchMssql::update' ); - } - - /** - * Update a search index record's title only. - * Title should be pre-processed. - * - * @param int $id - * @param string $title - * @return bool|ResultWrapper - */ - function updateTitle( $id, $title ) { - $table = $this->db->tableName( 'searchindex' ); - - // see update for why we are using the utf8bom - $utf8bom = '0xEFBBBF'; - $si_title = $utf8bom . bin2hex( $title ); - $sql = "DELETE FROM $table WHERE si_page = $id;"; - $sql .= "INSERT INTO $table (si_page, si_title, si_text) VALUES ($id, $si_title, 0x00)"; - return $this->db->query( $sql, 'SearchMssql::updateTitle' ); - } -} diff --git a/includes/search/SearchOracle.php b/includes/search/SearchOracle.php deleted file mode 100644 index 58211484..00000000 --- a/includes/search/SearchOracle.php +++ /dev/null @@ -1,273 +0,0 @@ - - * https://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 Oracle (ConText). - * @ingroup Search - */ -class SearchOracle extends SearchDatabase { - private $reservedWords = array( - 'ABOUT' => 1, - 'ACCUM' => 1, - 'AND' => 1, - 'BT' => 1, - 'BTG' => 1, - 'BTI' => 1, - 'BTP' => 1, - 'FUZZY' => 1, - 'HASPATH' => 1, - 'INPATH' => 1, - 'MINUS' => 1, - 'NEAR' => 1, - 'NOT' => 1, - 'NT' => 1, - 'NTG' => 1, - 'NTI' => 1, - 'NTP' => 1, - 'OR' => 1, - 'PT' => 1, - 'RT' => 1, - 'SQE' => 1, - 'SYN' => 1, - 'TR' => 1, - 'TRSYN' => 1, - 'TT' => 1, - 'WITHIN' => 1, - ); - - /** - * Perform a full text search query and return a result set. - * - * @param string $term Raw search term - * @return SqlSearchResultSet - */ - function searchText( $term ) { - if ( $term == '' ) { - return new SqlSearchResultSet( false, '' ); - } - - $resultSet = $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 string $term Raw search term - * @return SqlSearchResultSet - */ - function searchTitle( $term ) { - if ( $term == '' ) { - return new SqlSearchResultSet( false, '' ); - } - - $resultSet = $this->db->query( $this->getQuery( $this->filter( $term ), false ) ); - return new SqlSearchResultSet( $resultSet, $this->searchTerms ); - } - - /** - * Return a partial WHERE clause to limit the search to the given namespaces - * @return string - */ - function queryNamespaces() { - if ( is_null( $this->namespaces ) ) { - return ''; - } - if ( !count( $this->namespaces ) ) { - $namespaces = '0'; - } else { - $namespaces = $this->db->makeList( $this->namespaces ); - } - return 'AND page_namespace IN (' . $namespaces . ')'; - } - - /** - * Return a LIMIT clause to limit results on the query. - * - * @param string $sql - * - * @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 - * - * @param string $filteredTerm - * @param bool $fulltext - * @return string - */ - function queryRanking( $filteredTerm, $fulltext ) { - return ' ORDER BY score(1)'; - } - - /** - * Construct the full SQL query to do the search. - * The guts shoulds be constructed in queryMain() - * @param string $filteredTerm - * @param bool $fulltext - * @return string - */ - function getQuery( $filteredTerm, $fulltext ) { - return $this->queryLimit( $this->queryMain( $filteredTerm, $fulltext ) . ' ' . - $this->queryNamespaces() . ' ' . - $this->queryRanking( $filteredTerm, $fulltext ) . ' ' ); - } - - /** - * Picks which field to index on, depending on what type of query. - * @param bool $fulltext - * @return string - */ - function getIndexField( $fulltext ) { - return $fulltext ? 'si_text' : 'si_title'; - } - - /** - * Get the base part of the search query. - * - * @param string $filteredTerm - * @param bool $fulltext - * @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; - } - - /** - * Parse a user input search string, and return an SQL fragment to be used - * as part of a WHERE clause - * @param string $filteredText - * @param bool $fulltext - * @return string - */ - function parseQuery( $filteredText, $fulltext ) { - global $wgContLang; - $lc = $this->legalSearchChars(); - $this->searchTerms = array(); - - # @todo FIXME: This doesn't handle parenthetical expressions. - $m = array(); - $searchon = ''; - 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 ) { - $searchon .= ( $terms[1] == '-' ? ' ~' : ' & ' ) . $this->escapeTerm( $t ); - } - } - else { - $searchon .= ( $terms[1] == '-' ? ' ~' : ' & ' ) . $this->escapeTerm( $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->addQuotes( ltrim( $searchon, ' &' ) ); - $field = $this->getIndexField( $fulltext ); - return " CONTAINS($field, $searchon, 1) > 0 "; - } - - private function escapeTerm( $t ) { - global $wgContLang; - $t = $wgContLang->normalizeForSearch( $t ); - $t = isset( $this->reservedWords[strtoupper( $t )] ) ? '{' . $t . '}' : $t; - $t = preg_replace( '/^"(.*)"$/', '($1)', $t ); - $t = preg_replace( '/([-&|])/', '\\\\$1', $t ); - return $t; - } - - /** - * Create or update the search index record for the given page. - * Title and text should be pre-processed. - * - * @param int $id - * @param string $title - * @param string $text - */ - 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 - ), 'SearchOracle::update' ); - - // Sync the index - // We need to specify the DB name (i.e. user/schema) here so that - // it can work from the installer, where - // ALTER SESSION SET CURRENT_SCHEMA = ... - // was used. - $dbw->query( "CALL ctx_ddl.sync_index(" . - $dbw->addQuotes( $dbw->getDBname() . '.' . $dbw->tableName( 'si_text_idx', 'raw' ) ) . ")" ); - $dbw->query( "CALL ctx_ddl.sync_index(" . - $dbw->addQuotes( $dbw->getDBname() . '.' . $dbw->tableName( 'si_title_idx', 'raw' ) ) . ")" ); - } - - /** - * Update a search index record's title only. - * Title should be pre-processed. - * - * @param int $id - * @param string $title - */ - function updateTitle( $id, $title ) { - $dbw = wfGetDB( DB_MASTER ); - - $dbw->update( 'searchindex', - array( 'si_title' => $title ), - array( 'si_page' => $id ), - 'SearchOracle::updateTitle', - array() ); - } - - public static function legalSearchChars() { - return "\"" . parent::legalSearchChars(); - } -} diff --git a/maintenance/dictionary/mediawiki.dic b/maintenance/dictionary/mediawiki.dic index 8e4e5314..fd67fa63 100644 --- a/maintenance/dictionary/mediawiki.dic +++ b/maintenance/dictionary/mediawiki.dic @@ -187,7 +187,6 @@ Mostlinkedcategories Mostlinkedtemplates Mostrevisions Move -Mssql Mwstore Myuploads NEWPAGE @@ -2495,7 +2494,6 @@ msgtext msie msmetafile msnbot -mssql msvideo msword mtime diff --git a/maintenance/mssql/archives/named_constraints.sql b/maintenance/mssql/archives/named_constraints.sql deleted file mode 100644 index 94b77ea7..00000000 --- a/maintenance/mssql/archives/named_constraints.sql +++ /dev/null @@ -1,38 +0,0 @@ -DECLARE @fullyQualifiedTableName nvarchar(max), -@tableName sysname, -@fieldName sysname, -@constr sysname, -@constrNew sysname, -@sqlcmd nvarchar(max), -@sqlcreate nvarchar(max) - -SET @fullyQualifiedTableName = '/*_*//*$tableName*/' -SET @tableName = '/*$tableName*/' -SET @fieldName = '/*$fieldName*/' - -SELECT @constr = CONSTRAINT_NAME -FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS -WHERE TABLE_NAME = @tableName -AND CONSTRAINT_CATALOG = '/*$wgDBname*/' -AND CONSTRAINT_SCHEMA = '/*$wgDBmwschema*/' -AND CONSTRAINT_TYPE = 'CHECK' -AND CONSTRAINT_NAME LIKE ('CK__' + left(@tableName,9) + '__' + left(@fieldName,5) + '%') - -SELECT @constrNew = CONSTRAINT_NAME -FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS -WHERE TABLE_NAME = @tableName -AND CONSTRAINT_CATALOG = '/*$wgDBname*/' -AND CONSTRAINT_SCHEMA = '/*$wgDBmwschema*/' -AND CONSTRAINT_TYPE = 'CHECK' -AND CONSTRAINT_NAME = (@fieldName + '_ckc') - -IF @constr IS NOT NULL -BEGIN - SET @sqlcmd = 'ALTER TABLE ' + @fullyQualifiedTableName + ' DROP CONSTRAINT [' + @constr + ']' - EXECUTE sp_executesql @sqlcmd -END -IF @constrNew IS NULL -BEGIN - SET @sqlcreate = 'ALTER TABLE ' + @fullyQualifiedTableName + ' WITH NOCHECK ADD CONSTRAINT ' + @fieldName + '_ckc CHECK /*$checkConstraint*/;' - EXECUTE sp_executesql @sqlcreate -END \ No newline at end of file diff --git a/maintenance/mssql/archives/patch-fa_major_mime-chemical.sql b/maintenance/mssql/archives/patch-fa_major_mime-chemical.sql deleted file mode 100644 index 18368087..00000000 --- a/maintenance/mssql/archives/patch-fa_major_mime-chemical.sql +++ /dev/null @@ -1,4 +0,0 @@ -ALTER TABLE /*_*/filearchive -DROP CONSTRAINT fa_major_mime_ckc; -ALTER TABLE /*_*/filearchive -WITH NOCHECK ADD CONSTRAINT fa_major_mime_ckc CHECK (fa_major_mime IN('unknown', 'application', 'audio', 'image', 'text', 'video', 'message', 'model', 'multipart', 'chemical')); \ No newline at end of file diff --git a/maintenance/mssql/archives/patch-img_major_mime-chemical.sql b/maintenance/mssql/archives/patch-img_major_mime-chemical.sql deleted file mode 100644 index eed07869..00000000 --- a/maintenance/mssql/archives/patch-img_major_mime-chemical.sql +++ /dev/null @@ -1,4 +0,0 @@ -ALTER TABLE /*_*/image -DROP CONSTRAINT img_major_mime_ckc; -ALTER TABLE /*_*/image -WITH NOCHECK ADD CONSTRAINT img_major_mime_ckc CHECK (img_major_mime IN('unknown', 'application', 'audio', 'image', 'text', 'video', 'message', 'model', 'multipart', 'chemical')); \ No newline at end of file diff --git a/maintenance/mssql/archives/patch-oi_major_mime-chemical.sql b/maintenance/mssql/archives/patch-oi_major_mime-chemical.sql deleted file mode 100644 index 35482edc..00000000 --- a/maintenance/mssql/archives/patch-oi_major_mime-chemical.sql +++ /dev/null @@ -1,4 +0,0 @@ -ALTER TABLE /*_*/oldimage -DROP CONSTRAINT oi_major_mime_ckc; -ALTER TABLE /*_*/oldimage -WITH NOCHECK ADD CONSTRAINT oi_major_mime_ckc CHECK (oi_major_mime IN('unknown', 'application', 'audio', 'image', 'text', 'video', 'message', 'model', 'multipart', 'chemical')); \ No newline at end of file diff --git a/maintenance/mssql/archives/patch-page_page_lang.sql b/maintenance/mssql/archives/patch-page_page_lang.sql deleted file mode 100644 index d2f537b0..00000000 --- a/maintenance/mssql/archives/patch-page_page_lang.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE /*_*/page ADD page_lang VARBINARY(35) DEFAULT NULL diff --git a/maintenance/mssql/archives/patch-user_password_expires.sql b/maintenance/mssql/archives/patch-user_password_expires.sql deleted file mode 100644 index c22b10c7..00000000 --- a/maintenance/mssql/archives/patch-user_password_expires.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE /*_*/mwuser ADD user_password_expires VARCHAR(14) DEFAULT NULL \ No newline at end of file diff --git a/maintenance/mssql/tables.sql b/maintenance/mssql/tables.sql deleted file mode 100644 index 5b09ffdc..00000000 --- a/maintenance/mssql/tables.sql +++ /dev/null @@ -1,1324 +0,0 @@ --- Experimental table definitions for Microsoft SQL Server with --- content-holding fields switched to explicit BINARY charset. --- ------------------------------------------------------------ - --- 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. - --- --- General notes: --- --- The comments in this and other files are --- replaced with the defined table prefix by the installer --- and updater scripts. If you are installing or running --- updates manually, you will need to manually insert the --- table prefix if any when running these scripts. --- - - --- --- The user table contains basic account information, --- authentication keys, etc. --- --- Some multi-wiki sites may share a single central user table --- between separate wikis using the $wgSharedDB setting. --- --- Note that when a external authentication plugin is used, --- user table entries still need to be created to store --- preferences and to key tracking information in the other --- tables. - --- LINE:53 -CREATE TABLE /*_*/mwuser ( - user_id INT NOT NULL PRIMARY KEY IDENTITY(0,1), - user_name NVARCHAR(255) NOT NULL UNIQUE DEFAULT '', - user_real_name NVARCHAR(255) NOT NULL DEFAULT '', - user_password NVARCHAR(255) NOT NULL DEFAULT '', - user_newpassword NVARCHAR(255) NOT NULL DEFAULT '', - user_newpass_time varchar(14) NULL DEFAULT NULL, - user_email NVARCHAR(255) NOT NULL DEFAULT '', - user_options NVARCHAR(MAX) NOT NULL DEFAULT '', - user_touched varchar(14) NOT NULL DEFAULT '', - user_token NCHAR(32) NOT NULL DEFAULT '', - user_email_authenticated varchar(14) DEFAULT NULL, - user_email_token NCHAR(32) DEFAULT '', - user_email_token_expires varchar(14) DEFAULT NULL, - user_registration varchar(14) DEFAULT NULL, - user_editcount INT NULL DEFAULT NULL, - user_password_expires varchar(14) DEFAULT NULL -); -CREATE UNIQUE INDEX /*i*/user_name ON /*_*/mwuser (user_name); -CREATE INDEX /*i*/user_email_token ON /*_*/mwuser (user_email_token); -CREATE INDEX /*i*/user_email ON /*_*/mwuser (user_email); - --- Insert a dummy user to represent anons -INSERT INTO /*_*/mwuser (user_name) VALUES ('##Anonymous##'); - --- --- User permissions have been broken out to a separate table; --- this allows sites with a shared user table to have different --- permissions assigned to a user in each project. --- --- This table replaces the old user_rights field which used a --- comma-separated nvarchar(max). -CREATE TABLE /*_*/user_groups ( - ug_user INT NOT NULL REFERENCES /*_*/mwuser(user_id) ON DELETE CASCADE, - ug_group NVARCHAR(255) NOT NULL DEFAULT '', -); -CREATE UNIQUE clustered INDEX /*i*/ug_user_group ON /*_*/user_groups (ug_user, ug_group); -CREATE INDEX /*i*/ug_group ON /*_*/user_groups(ug_group); - --- Stores the groups the user has once belonged to. --- The user may still belong to these groups (check user_groups). --- Users are not autopromoted to groups from which they were removed. -CREATE TABLE /*_*/user_former_groups ( - ufg_user INT NOT NULL REFERENCES /*_*/mwuser(user_id) ON DELETE CASCADE, - ufg_group nvarchar(255) NOT NULL default '' -); -CREATE UNIQUE INDEX /*i*/ufg_user_group ON /*_*/user_former_groups (ufg_user,ufg_group); - --- Stores notifications of user talk page changes, for the display --- of the "you have new messages" box --- Changed user_id column to user_id to avoid clashing with user_id function -CREATE TABLE /*_*/user_newtalk ( - user_id INT NOT NULL REFERENCES /*_*/mwuser(user_id) ON DELETE CASCADE, - user_ip NVARCHAR(40) NOT NULL DEFAULT '', - user_last_timestamp varchar(14) DEFAULT NULL, -); -CREATE INDEX /*i*/un_user_id ON /*_*/user_newtalk (user_id); -CREATE INDEX /*i*/un_user_ip ON /*_*/user_newtalk (user_ip); - --- --- User preferences and other fun stuff --- replaces old user.user_options nvarchar(max) --- -CREATE TABLE /*_*/user_properties ( - up_user INT NOT NULL REFERENCES /*_*/mwuser(user_id) ON DELETE CASCADE, - up_property NVARCHAR(255) NOT NULL, - up_value NVARCHAR(MAX), -); -CREATE UNIQUE CLUSTERED INDEX /*i*/user_properties_user_property ON /*_*/user_properties (up_user,up_property); -CREATE INDEX /*i*/user_properties_property ON /*_*/user_properties (up_property); - - --- --- Core of the wiki: each page has an entry here which identifies --- it by title and contains some essential metadata. --- -CREATE TABLE /*_*/page ( - page_id INT NOT NULL PRIMARY KEY IDENTITY(0,1), - page_namespace INT NOT NULL, - page_title NVARCHAR(255) NOT NULL, - page_restrictions NVARCHAR(255) NOT NULL, - page_is_redirect BIT NOT NULL DEFAULT 0, - page_is_new BIT NOT NULL DEFAULT 0, - page_random real NOT NULL DEFAULT RAND(), - page_touched varchar(14) NOT NULL default '', - page_links_updated varchar(14) DEFAULT NULL, - page_latest INT, -- FK inserted later - page_len INT NOT NULL, - page_content_model nvarchar(32) default null, - page_lang VARBINARY(35) DEFAULT NULL -); -CREATE UNIQUE INDEX /*i*/name_title ON /*_*/page (page_namespace,page_title); -CREATE INDEX /*i*/page_random ON /*_*/page (page_random); -CREATE INDEX /*i*/page_len ON /*_*/page (page_len); -CREATE INDEX /*i*/page_redirect_namespace_len ON /*_*/page (page_is_redirect, page_namespace, page_len); - --- insert a dummy page -INSERT INTO /*_*/page (page_namespace, page_title, page_restrictions, page_latest, page_len) VALUES (-1,'','',0,0); - --- --- Every edit of a page creates also a revision row. --- This stores metadata about the revision, and a reference --- to the TEXT storage backend. --- -CREATE TABLE /*_*/revision ( - rev_id INT NOT NULL UNIQUE IDENTITY(0,1), - rev_page INT NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE, - rev_text_id INT NOT NULL, -- FK added later - rev_comment NVARCHAR(255) NOT NULL, - rev_user INT REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL, - rev_user_text NVARCHAR(255) NOT NULL DEFAULT '', - rev_timestamp varchar(14) NOT NULL default '', - rev_minor_edit BIT NOT NULL DEFAULT 0, - rev_deleted TINYINT NOT NULL DEFAULT 0, - rev_len INT, - rev_parent_id INT DEFAULT NULL REFERENCES /*_*/revision(rev_id), - rev_sha1 nvarchar(32) not null default '', - rev_content_model nvarchar(32) default null, - rev_content_format nvarchar(64) default null -); -CREATE UNIQUE CLUSTERED INDEX /*i*/rev_page_id ON /*_*/revision (rev_page, rev_id); -CREATE INDEX /*i*/rev_timestamp ON /*_*/revision (rev_timestamp); -CREATE INDEX /*i*/page_timestamp ON /*_*/revision (rev_page,rev_timestamp); -CREATE INDEX /*i*/user_timestamp ON /*_*/revision (rev_user,rev_timestamp); -CREATE INDEX /*i*/usertext_timestamp ON /*_*/revision (rev_user_text,rev_timestamp); -CREATE INDEX /*i*/page_user_timestamp ON /*_*/revision (rev_page,rev_user,rev_timestamp); - --- insert a dummy revision -INSERT INTO /*_*/revision (rev_page,rev_text_id,rev_comment,rev_user,rev_len) VALUES (0,0,'',0,0); - -ALTER TABLE /*_*/page ADD CONSTRAINT FK_page_latest_page_id FOREIGN KEY (page_latest) REFERENCES /*_*/revision(rev_id); - --- --- Holds TEXT of individual page revisions. --- --- Field names are a holdover from the 'old' revisions table in --- MediaWiki 1.4 and earlier: an upgrade will transform that --- table INTo the 'text' table to minimize unnecessary churning --- and downtime. If upgrading, the other fields will be left unused. -CREATE TABLE /*_*/text ( - old_id INT NOT NULL PRIMARY KEY IDENTITY(0,1), - old_text nvarchar(max) NOT NULL, - old_flags NVARCHAR(255) NOT NULL, -); - --- insert a dummy text -INSERT INTO /*_*/text (old_text,old_flags) VALUES ('',''); - -ALTER TABLE /*_*/revision ADD CONSTRAINT FK_rev_text_id_old_id FOREIGN KEY (rev_text_id) REFERENCES /*_*/text(old_id) ON DELETE CASCADE; - --- --- Holding area for deleted articles, which may be viewed --- or restored by admins through the Special:Undelete interface. --- The fields generally correspond to the page, revision, and text --- fields, with several caveats. --- Cannot reasonably create views on this table, due to the presence of TEXT --- columns. -CREATE TABLE /*_*/archive ( - ar_id int NOT NULL PRIMARY KEY IDENTITY, - ar_namespace SMALLINT NOT NULL DEFAULT 0, - ar_title NVARCHAR(255) NOT NULL DEFAULT '', - ar_text NVARCHAR(MAX) NOT NULL, - ar_comment NVARCHAR(255) NOT NULL, - ar_user INT REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL, - ar_user_text NVARCHAR(255) NOT NULL, - ar_timestamp varchar(14) NOT NULL default '', - ar_minor_edit BIT NOT NULL DEFAULT 0, - ar_flags NVARCHAR(255) NOT NULL, - ar_rev_id INT NULL, -- NOT a FK, the row gets deleted from revision and moved here - ar_text_id INT REFERENCES /*_*/text(old_id) ON DELETE CASCADE, - ar_deleted TINYINT NOT NULL DEFAULT 0, - ar_len INT, - ar_page_id INT NULL, -- NOT a FK, the row gets deleted from page and moved here - ar_parent_id INT NULL REFERENCES /*_*/revision(rev_id), - ar_sha1 nvarchar(32) default null, - ar_content_model nvarchar(32) DEFAULT NULL, - ar_content_format nvarchar(64) DEFAULT NULL -); -CREATE INDEX /*i*/name_title_timestamp ON /*_*/archive (ar_namespace,ar_title,ar_timestamp); -CREATE INDEX /*i*/ar_usertext_timestamp ON /*_*/archive (ar_user_text,ar_timestamp); -CREATE INDEX /*i*/ar_revid ON /*_*/archive (ar_rev_id); - - --- --- Track page-to-page hyperlinks within the wiki. --- -CREATE TABLE /*_*/pagelinks ( - pl_from INT NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE, - pl_namespace INT NOT NULL DEFAULT 0, - pl_title NVARCHAR(255) NOT NULL DEFAULT '', -); -CREATE UNIQUE INDEX /*i*/pl_from ON /*_*/pagelinks (pl_from,pl_namespace,pl_title); -CREATE UNIQUE INDEX /*i*/pl_namespace ON /*_*/pagelinks (pl_namespace,pl_title,pl_from); - - --- --- Track template inclusions. --- -CREATE TABLE /*_*/templatelinks ( - tl_from int NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE, - tl_namespace int NOT NULL default 0, - tl_title nvarchar(255) NOT NULL default '' -); - -CREATE UNIQUE INDEX /*i*/tl_from ON /*_*/templatelinks (tl_from,tl_namespace,tl_title); -CREATE UNIQUE INDEX /*i*/tl_namespace ON /*_*/templatelinks (tl_namespace,tl_title,tl_from); - - --- --- Track links to images *used inline* --- We don't distinguish live from broken links here, so --- they do not need to be changed on upload/removal. --- -CREATE TABLE /*_*/imagelinks ( - -- Key to page_id of the page containing the image / media link. - il_from int NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE, - - -- Filename of target image. - -- This is also the page_title of the file's description page; - -- all such pages are in namespace 6 (NS_FILE). - il_to nvarchar(255) NOT NULL default '' -); - -CREATE UNIQUE INDEX /*i*/il_from ON /*_*/imagelinks (il_from,il_to); -CREATE UNIQUE INDEX /*i*/il_to ON /*_*/imagelinks (il_to,il_from); - --- --- Track category inclusions *used inline* --- This tracks a single level of category membership --- -CREATE TABLE /*_*/categorylinks ( - -- Key to page_id of the page defined as a category member. - cl_from int NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE, - - -- Name of the category. - -- This is also the page_title of the category's description page; - -- all such pages are in namespace 14 (NS_CATEGORY). - cl_to nvarchar(255) NOT NULL default '', - - -- A binary string obtained by applying a sortkey generation algorithm - -- (Collation::getSortKey()) to page_title, or cl_sortkey_prefix . "\n" - -- . page_title if cl_sortkey_prefix is nonempty. - cl_sortkey varbinary(230) NOT NULL default 0x, - - -- A prefix for the raw sortkey manually specified by the user, either via - -- [[Category:Foo|prefix]] or {{defaultsort:prefix}}. If nonempty, it's - -- concatenated with a line break followed by the page title before the sortkey - -- conversion algorithm is run. We store this so that we can update - -- collations without reparsing all pages. - -- Note: If you change the length of this field, you also need to change - -- code in LinksUpdate.php. See bug 25254. - cl_sortkey_prefix varbinary(255) NOT NULL default 0x, - - -- This isn't really used at present. Provided for an optional - -- sorting method by approximate addition time. - cl_timestamp varchar(14) NOT NULL, - - -- Stores $wgCategoryCollation at the time cl_sortkey was generated. This - -- can be used to install new collation versions, tracking which rows are not - -- yet updated. '' means no collation, this is a legacy row that needs to be - -- updated by updateCollation.php. In the future, it might be possible to - -- specify different collations per category. - cl_collation nvarchar(32) NOT NULL default '', - - -- Stores whether cl_from is a category, file, or other page, so we can - -- paginate the three categories separately. This never has to be updated - -- after the page is created, since none of these page types can be moved to - -- any other. - cl_type varchar(10) NOT NULL default 'page', - -- SQL server doesn't have enums, so we approximate with this - CONSTRAINT cl_type_ckc CHECK (cl_type IN('page', 'subcat', 'file')) -); - -CREATE UNIQUE INDEX /*i*/cl_from ON /*_*/categorylinks (cl_from,cl_to); - --- We always sort within a given category, and within a given type. FIXME: --- Formerly this index didn't cover cl_type (since that didn't exist), so old --- callers won't be using an index: fix this? -CREATE INDEX /*i*/cl_sortkey ON /*_*/categorylinks (cl_to,cl_type,cl_sortkey,cl_from); - --- Used by the API (and some extensions) -CREATE INDEX /*i*/cl_timestamp ON /*_*/categorylinks (cl_to,cl_timestamp); - --- FIXME: Not used, delete this -CREATE INDEX /*i*/cl_collation ON /*_*/categorylinks (cl_collation); - --- --- Track all existing categories. Something is a category if 1) it has an en- --- try somewhere in categorylinks, or 2) it once did. Categories might not --- have corresponding pages, so they need to be tracked separately. --- -CREATE TABLE /*_*/category ( - -- Primary key - cat_id int NOT NULL PRIMARY KEY IDENTITY, - - -- Name of the category, in the same form as page_title (with underscores). - -- If there is a category page corresponding to this category, by definition, - -- it has this name (in the Category namespace). - cat_title nvarchar(255) NOT NULL, - - -- The numbers of member pages (including categories and media), subcatego- - -- ries, and Image: namespace members, respectively. These are signed to - -- make underflow more obvious. We make the first number include the second - -- two for better sorting: subtracting for display is easy, adding for order- - -- ing is not. - cat_pages int NOT NULL default 0, - cat_subcats int NOT NULL default 0, - cat_files int NOT NULL default 0 -); - -CREATE UNIQUE INDEX /*i*/cat_title ON /*_*/category (cat_title); - --- For Special:Mostlinkedcategories -CREATE INDEX /*i*/cat_pages ON /*_*/category (cat_pages); - - --- --- Track links to external URLs --- -CREATE TABLE /*_*/externallinks ( - -- Primary key - el_id int NOT NULL PRIMARY KEY IDENTITY, - - -- page_id of the referring page - el_from int NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE, - - -- The URL - el_to nvarchar(max) NOT NULL, - - -- In the case of HTTP URLs, this is the URL with any username or password - -- removed, and with the labels in the hostname reversed and converted to - -- lower case. An extra dot is added to allow for matching of either - -- example.com or *.example.com in a single scan. - -- Example: - -- http://user:password@sub.example.com/page.html - -- becomes - -- http://com.example.sub./page.html - -- which allows for fast searching for all pages under example.com with the - -- clause: - -- WHERE el_index LIKE 'http://com.example.%' - el_index nvarchar(450) NOT NULL -); - -CREATE INDEX /*i*/el_from ON /*_*/externallinks (el_from); -CREATE INDEX /*i*/el_index ON /*_*/externallinks (el_index); - --- --- Track interlanguage links --- -CREATE TABLE /*_*/langlinks ( - -- page_id of the referring page - ll_from int NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE, - - -- Language code of the target - ll_lang nvarchar(20) NOT NULL default '', - - -- Title of the target, including namespace - ll_title nvarchar(255) NOT NULL default '' -); - -CREATE UNIQUE INDEX /*i*/ll_from ON /*_*/langlinks (ll_from, ll_lang); -CREATE INDEX /*i*/ll_lang ON /*_*/langlinks (ll_lang, ll_title); - - --- --- Track inline interwiki links --- -CREATE TABLE /*_*/iwlinks ( - -- page_id of the referring page - iwl_from int NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE, - - -- Interwiki prefix code of the target - iwl_prefix nvarchar(20) NOT NULL default '', - - -- Title of the target, including namespace - iwl_title nvarchar(255) NOT NULL default '' -); - -CREATE UNIQUE INDEX /*i*/iwl_from ON /*_*/iwlinks (iwl_from, iwl_prefix, iwl_title); -CREATE INDEX /*i*/iwl_prefix_title_from ON /*_*/iwlinks (iwl_prefix, iwl_title, iwl_from); -CREATE INDEX /*i*/iwl_prefix_from_title ON /*_*/iwlinks (iwl_prefix, iwl_from, iwl_title); - - --- --- Contains a single row with some aggregate info --- on the state of the site. --- -CREATE TABLE /*_*/site_stats ( - -- The single row should contain 1 here. - ss_row_id int NOT NULL, - - -- Total number of edits performed. - ss_total_edits bigint default 0, - - -- An approximate count of pages matching the following criteria: - -- * in namespace 0 - -- * not a redirect - -- * contains the text '[[' - -- See Article::isCountable() in includes/Article.php - ss_good_articles bigint default 0, - - -- Total pages, theoretically equal to SELECT COUNT(*) FROM page; except faster - ss_total_pages bigint default '-1', - - -- Number of users, theoretically equal to SELECT COUNT(*) FROM user; - ss_users bigint default '-1', - - -- Number of users that still edit - ss_active_users bigint default '-1', - - -- Number of images, equivalent to SELECT COUNT(*) FROM image - ss_images int default 0 -); - --- Pointless index to assuage developer superstitions -CREATE UNIQUE INDEX /*i*/ss_row_id ON /*_*/site_stats (ss_row_id); - - --- --- The internet is full of jerks, alas. Sometimes it's handy --- to block a vandal or troll account. --- -CREATE TABLE /*_*/ipblocks ( - -- Primary key, introduced for privacy. - ipb_id int NOT NULL PRIMARY KEY IDENTITY, - - -- Blocked IP address in dotted-quad form or user name. - ipb_address nvarchar(255) NOT NULL, - - -- Blocked user ID or 0 for IP blocks. - ipb_user int REFERENCES /*_*/mwuser(user_id), - - -- User ID who made the block. - ipb_by int REFERENCES /*_*/mwuser(user_id) ON DELETE CASCADE, - - -- User name of blocker - ipb_by_text nvarchar(255) NOT NULL default '', - - -- Text comment made by blocker. - ipb_reason nvarchar(255) NOT NULL, - - -- Creation (or refresh) date in standard YMDHMS form. - -- IP blocks expire automatically. - ipb_timestamp varchar(14) NOT NULL default '', - - -- Indicates that the IP address was banned because a banned - -- user accessed a page through it. If this is 1, ipb_address - -- will be hidden, and the block identified by block ID number. - ipb_auto bit NOT NULL default 0, - - -- If set to 1, block applies only to logged-out users - ipb_anon_only bit NOT NULL default 0, - - -- Block prevents account creation from matching IP addresses - ipb_create_account bit NOT NULL default 1, - - -- Block triggers autoblocks - ipb_enable_autoblock bit NOT NULL default 1, - - -- Time at which the block will expire. - -- May be "infinity" - ipb_expiry varchar(14) NOT NULL, - - -- Start and end of an address range, in hexadecimal - -- Size chosen to allow IPv6 - -- FIXME: these fields were originally blank for single-IP blocks, - -- but now they are populated. No migration was ever done. They - -- should be fixed to be blank again for such blocks (bug 49504). - ipb_range_start varchar(255) NOT NULL, - ipb_range_end varchar(255) NOT NULL, - - -- Flag for entries hidden from users and Sysops - ipb_deleted bit NOT NULL default 0, - - -- Block prevents user from accessing Special:Emailuser - ipb_block_email bit NOT NULL default 0, - - -- Block allows user to edit their own talk page - ipb_allow_usertalk bit NOT NULL default 0, - - -- ID of the block that caused this block to exist - -- Autoblocks set this to the original block - -- so that the original block being deleted also - -- deletes the autoblocks - ipb_parent_block_id int default NULL REFERENCES /*_*/ipblocks(ipb_id) - -); - --- Unique index to support "user already blocked" messages --- Any new options which prevent collisions should be included -CREATE UNIQUE INDEX /*i*/ipb_address ON /*_*/ipblocks (ipb_address, ipb_user, ipb_auto, ipb_anon_only); - -CREATE INDEX /*i*/ipb_user ON /*_*/ipblocks (ipb_user); -CREATE INDEX /*i*/ipb_range ON /*_*/ipblocks (ipb_range_start, ipb_range_end); -CREATE INDEX /*i*/ipb_timestamp ON /*_*/ipblocks (ipb_timestamp); -CREATE INDEX /*i*/ipb_expiry ON /*_*/ipblocks (ipb_expiry); -CREATE INDEX /*i*/ipb_parent_block_id ON /*_*/ipblocks (ipb_parent_block_id); - - --- --- Uploaded images and other files. --- -CREATE TABLE /*_*/image ( - -- Filename. - -- This is also the title of the associated description page, - -- which will be in namespace 6 (NS_FILE). - img_name varbinary(255) NOT NULL default 0x PRIMARY KEY, - - -- File size in bytes. - img_size int NOT NULL default 0, - - -- For images, size in pixels. - img_width int NOT NULL default 0, - img_height int NOT NULL default 0, - - -- Extracted Exif metadata stored as a serialized PHP array. - img_metadata varbinary(max) NOT NULL, - - -- For images, bits per pixel if known. - img_bits int NOT NULL default 0, - - -- Media type as defined by the MEDIATYPE_xxx constants - img_media_type varchar(16) default null, - - -- major part of a MIME media type as defined by IANA - -- see http://www.iana.org/assignments/media-types/ - img_major_mime varchar(16) not null default 'unknown', - - -- minor part of a MIME media type as defined by IANA - -- the minor parts are not required to adher to any standard - -- but should be consistent throughout the database - -- see http://www.iana.org/assignments/media-types/ - img_minor_mime nvarchar(100) NOT NULL default 'unknown', - - -- Description field as entered by the uploader. - -- This is displayed in image upload history and logs. - img_description nvarchar(255) NOT NULL, - - -- user_id and user_name of uploader. - img_user int REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL, - img_user_text nvarchar(255) NOT NULL, - - -- Time of the upload. - img_timestamp nvarchar(14) NOT NULL default '', - - -- SHA-1 content hash in base-36 - img_sha1 nvarchar(32) NOT NULL default '', - - CONSTRAINT img_major_mime_ckc check (img_major_mime IN('unknown', 'application', 'audio', 'image', 'text', 'video', 'message', 'model', 'multipart', 'chemical')), - CONSTRAINT img_media_type_ckc check (img_media_type in('UNKNOWN', 'BITMAP', 'DRAWING', 'AUDIO', 'VIDEO', 'MULTIMEDIA', 'OFFICE', 'TEXT', 'EXECUTABLE', 'ARCHIVE')) -); - -CREATE INDEX /*i*/img_usertext_timestamp ON /*_*/image (img_user_text,img_timestamp); --- Used by Special:ListFiles for sort-by-size -CREATE INDEX /*i*/img_size ON /*_*/image (img_size); --- Used by Special:Newimages and Special:ListFiles -CREATE INDEX /*i*/img_timestamp ON /*_*/image (img_timestamp); --- Used in API and duplicate search -CREATE INDEX /*i*/img_sha1 ON /*_*/image (img_sha1); --- Used to get media of one type -CREATE INDEX /*i*/img_media_mime ON /*_*/image (img_media_type,img_major_mime,img_minor_mime); - - --- --- Previous revisions of uploaded files. --- Awkwardly, image rows have to be moved into --- this table at re-upload time. --- -CREATE TABLE /*_*/oldimage ( - -- Base filename: key to image.img_name - oi_name varbinary(255) NOT NULL default 0x REFERENCES /*_*/image(img_name) ON DELETE CASCADE ON UPDATE CASCADE, - - -- Filename of the archived file. - -- This is generally a timestamp and '!' prepended to the base name. - oi_archive_name varbinary(255) NOT NULL default 0x, - - -- Other fields as in image... - oi_size int NOT NULL default 0, - oi_width int NOT NULL default 0, - oi_height int NOT NULL default 0, - oi_bits int NOT NULL default 0, - oi_description nvarchar(255) NOT NULL, - oi_user int REFERENCES /*_*/mwuser(user_id), - oi_user_text nvarchar(255) NOT NULL, - oi_timestamp varchar(14) NOT NULL default '', - - oi_metadata nvarchar(max) NOT NULL, - oi_media_type varchar(16) default null, - oi_major_mime varchar(16) not null default 'unknown', - oi_minor_mime nvarchar(100) NOT NULL default 'unknown', - oi_deleted tinyint NOT NULL default 0, - oi_sha1 nvarchar(32) NOT NULL default '', - - CONSTRAINT oi_major_mime_ckc check (oi_major_mime IN('unknown', 'application', 'audio', 'image', 'text', 'video', 'message', 'model', 'multipart', 'chemical')), - CONSTRAINT oi_media_type_ckc check (oi_media_type IN('UNKNOWN', 'BITMAP', 'DRAWING', 'AUDIO', 'VIDEO', 'MULTIMEDIA', 'OFFICE', 'TEXT', 'EXECUTABLE', 'ARCHIVE')) -); - -CREATE INDEX /*i*/oi_usertext_timestamp ON /*_*/oldimage (oi_user_text,oi_timestamp); -CREATE INDEX /*i*/oi_name_timestamp ON /*_*/oldimage (oi_name,oi_timestamp); --- oi_archive_name truncated to 14 to avoid key length overflow -CREATE INDEX /*i*/oi_name_archive_name ON /*_*/oldimage (oi_name,oi_archive_name); -CREATE INDEX /*i*/oi_sha1 ON /*_*/oldimage (oi_sha1); - - --- --- Record of deleted file data --- -CREATE TABLE /*_*/filearchive ( - -- Unique row id - fa_id int NOT NULL PRIMARY KEY IDENTITY, - - -- Original base filename; key to image.img_name, page.page_title, etc - fa_name nvarchar(255) NOT NULL default '', - - -- Filename of archived file, if an old revision - fa_archive_name nvarchar(255) default '', - - -- Which storage bin (directory tree or object store) the file data - -- is stored in. Should be 'deleted' for files that have been deleted; - -- any other bin is not yet in use. - fa_storage_group nvarchar(16), - - -- SHA-1 of the file contents plus extension, used as a key for storage. - -- eg 8f8a562add37052a1848ff7771a2c515db94baa9.jpg - -- - -- If NULL, the file was missing at deletion time or has been purged - -- from the archival storage. - fa_storage_key nvarchar(64) default '', - - -- Deletion information, if this file is deleted. - fa_deleted_user int, - fa_deleted_timestamp varchar(14) default '', - fa_deleted_reason nvarchar(max), - - -- Duped fields from image - fa_size int default 0, - fa_width int default 0, - fa_height int default 0, - fa_metadata nvarchar(max), - fa_bits int default 0, - fa_media_type varchar(16) default null, - fa_major_mime varchar(16) not null default 'unknown', - fa_minor_mime nvarchar(100) default 'unknown', - fa_description nvarchar(255), - fa_user int default 0 REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL, - fa_user_text nvarchar(255), - fa_timestamp varchar(14) default '', - - -- Visibility of deleted revisions, bitfield - fa_deleted tinyint NOT NULL default 0, - - -- sha1 hash of file content - fa_sha1 nvarchar(32) NOT NULL default '', - - CONSTRAINT fa_major_mime_ckc check (fa_major_mime in('unknown', 'application', 'audio', 'image', 'text', 'video', 'message', 'model', 'multipart', 'chemical')), - CONSTRAINT fa_media_type_ckc check (fa_media_type in('UNKNOWN', 'BITMAP', 'DRAWING', 'AUDIO', 'VIDEO', 'MULTIMEDIA', 'OFFICE', 'TEXT', 'EXECUTABLE', 'ARCHIVE')) -); - --- pick out by image name -CREATE INDEX /*i*/fa_name ON /*_*/filearchive (fa_name, fa_timestamp); --- pick out dupe files -CREATE INDEX /*i*/fa_storage_group ON /*_*/filearchive (fa_storage_group, fa_storage_key); --- sort by deletion time -CREATE INDEX /*i*/fa_deleted_timestamp ON /*_*/filearchive (fa_deleted_timestamp); --- sort by uploader -CREATE INDEX /*i*/fa_user_timestamp ON /*_*/filearchive (fa_user_text,fa_timestamp); --- find file by sha1, 10 bytes will be enough for hashes to be indexed -CREATE INDEX /*i*/fa_sha1 ON /*_*/filearchive (fa_sha1); - - --- --- Store information about newly uploaded files before they're --- moved into the actual filestore --- -CREATE TABLE /*_*/uploadstash ( - us_id int NOT NULL PRIMARY KEY IDENTITY, - - -- the user who uploaded the file. - us_user int REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL, - - -- file key. this is how applications actually search for the file. - -- this might go away, or become the primary key. - us_key nvarchar(255) NOT NULL, - - -- the original path - us_orig_path nvarchar(255) NOT NULL, - - -- the temporary path at which the file is actually stored - us_path nvarchar(255) NOT NULL, - - -- which type of upload the file came from (sometimes) - us_source_type nvarchar(50), - - -- the date/time on which the file was added - us_timestamp varchar(14) NOT NULL, - - us_status nvarchar(50) NOT NULL, - - -- chunk counter starts at 0, current offset is stored in us_size - us_chunk_inx int NULL, - - -- Serialized file properties from FSFile::getProps() - us_props nvarchar(max), - - -- file size in bytes - us_size int NOT NULL, - -- this hash comes from FSFile::getSha1Base36(), and is 31 characters - us_sha1 nvarchar(31) NOT NULL, - us_mime nvarchar(255), - -- Media type as defined by the MEDIATYPE_xxx constants, should duplicate definition in the image table - us_media_type varchar(16) default null, - -- image-specific properties - us_image_width int, - us_image_height int, - us_image_bits smallint, - - CONSTRAINT us_media_type_ckc check (us_media_type in('UNKNOWN', 'BITMAP', 'DRAWING', 'AUDIO', 'VIDEO', 'MULTIMEDIA', 'OFFICE', 'TEXT', 'EXECUTABLE', 'ARCHIVE')) -); - --- sometimes there's a delete for all of a user's stuff. -CREATE INDEX /*i*/us_user ON /*_*/uploadstash (us_user); --- pick out files by key, enforce key uniqueness -CREATE UNIQUE INDEX /*i*/us_key ON /*_*/uploadstash (us_key); --- the abandoned upload cleanup script needs this -CREATE INDEX /*i*/us_timestamp ON /*_*/uploadstash (us_timestamp); - - --- --- Primarily a summary table for Special:Recentchanges, --- this table contains some additional info on edits from --- the last few days, see Article::editUpdates() --- -CREATE TABLE /*_*/recentchanges ( - rc_id int NOT NULL PRIMARY KEY IDENTITY, - rc_timestamp varchar(14) not null default '', - - -- This is no longer used - -- Field kept in database for downgrades - -- @todo: add drop patch with 1.24 - rc_cur_time varchar(14) NOT NULL default '', - - -- As in revision - rc_user int NOT NULL default 0 REFERENCES /*_*/mwuser(user_id), - rc_user_text nvarchar(255) NOT NULL, - - -- When pages are renamed, their RC entries do _not_ change. - rc_namespace int NOT NULL default 0, - rc_title nvarchar(255) NOT NULL default '', - - -- as in revision... - rc_comment nvarchar(255) NOT NULL default '', - rc_minor bit NOT NULL default 0, - - -- Edits by user accounts with the 'bot' rights key are - -- marked with a 1 here, and will be hidden from the - -- default view. - rc_bot bit NOT NULL default 0, - - -- Set if this change corresponds to a page creation - rc_new bit NOT NULL default 0, - - -- Key to page_id (was cur_id prior to 1.5). - -- This will keep links working after moves while - -- retaining the at-the-time name in the changes list. - rc_cur_id int REFERENCES /*_*/page(page_id), - - -- rev_id of the given revision - rc_this_oldid int REFERENCES /*_*/revision(rev_id), - - -- rev_id of the prior revision, for generating diff links. - rc_last_oldid int REFERENCES /*_*/revision(rev_id), - - -- The type of change entry (RC_EDIT,RC_NEW,RC_LOG,RC_EXTERNAL) - rc_type tinyint NOT NULL default 0, - - -- The source of the change entry (replaces rc_type) - -- default of '' is temporary, needed for initial migration - rc_source nvarchar(16) not null default '', - - -- If the Recent Changes Patrol option is enabled, - -- users may mark edits as having been reviewed to - -- remove a warning flag on the RC list. - -- A value of 1 indicates the page has been reviewed. - rc_patrolled bit NOT NULL default 0, - - -- Recorded IP address the edit was made from, if the - -- $wgPutIPinRC option is enabled. - rc_ip nvarchar(40) NOT NULL default '', - - -- Text length in characters before - -- and after the edit - rc_old_len int, - rc_new_len int, - - -- Visibility of recent changes items, bitfield - rc_deleted tinyint NOT NULL default 0, - - -- Value corresponding to log_id, specific log entries - rc_logid int, -- FK added later - -- Store log type info here, or null - rc_log_type nvarchar(255) NULL default NULL, - -- Store log action or null - rc_log_action nvarchar(255) NULL default NULL, - -- Log params - rc_params nvarchar(max) NULL -); - -CREATE INDEX /*i*/rc_timestamp ON /*_*/recentchanges (rc_timestamp); -CREATE INDEX /*i*/rc_namespace_title ON /*_*/recentchanges (rc_namespace, rc_title); -CREATE INDEX /*i*/rc_cur_id ON /*_*/recentchanges (rc_cur_id); -CREATE INDEX /*i*/new_name_timestamp ON /*_*/recentchanges (rc_new,rc_namespace,rc_timestamp); -CREATE INDEX /*i*/rc_ip ON /*_*/recentchanges (rc_ip); -CREATE INDEX /*i*/rc_ns_usertext ON /*_*/recentchanges (rc_namespace, rc_user_text); -CREATE INDEX /*i*/rc_user_text ON /*_*/recentchanges (rc_user_text, rc_timestamp); - - -CREATE TABLE /*_*/watchlist ( - -- Key to user.user_id - wl_user int NOT NULL REFERENCES /*_*/mwuser(user_id) ON DELETE CASCADE, - - -- Key to page_namespace/page_title - -- Note that users may watch pages which do not exist yet, - -- or existed in the past but have been deleted. - wl_namespace int NOT NULL default 0, - wl_title nvarchar(255) NOT NULL default '', - - -- Timestamp used to send notification e-mails and show "updated since last visit" markers on - -- history and recent changes / watchlist. Set to NULL when the user visits the latest revision - -- of the page, which means that they should be sent an e-mail on the next change. - wl_notificationtimestamp varchar(14) - -); - -CREATE UNIQUE INDEX /*i*/wl_user ON /*_*/watchlist (wl_user, wl_namespace, wl_title); -CREATE INDEX /*i*/namespace_title ON /*_*/watchlist (wl_namespace, wl_title); - - --- --- Our search index for the builtin MediaWiki search --- -CREATE TABLE /*_*/searchindex ( - -- Key to page_id - si_page int NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE, - - -- Munged version of title - si_title nvarchar(255) NOT NULL default '', - - -- Munged version of body text - si_text nvarchar(max) NOT NULL -); - -CREATE UNIQUE INDEX /*i*/si_page ON /*_*/searchindex (si_page); --- Fulltext index is defined in MssqlInstaller.php - --- --- Recognized interwiki link prefixes --- -CREATE TABLE /*_*/interwiki ( - -- The interwiki prefix, (e.g. "Meatball", or the language prefix "de") - iw_prefix nvarchar(32) NOT NULL, - - -- The URL of the wiki, with "$1" as a placeholder for an article name. - -- Any spaces in the name will be transformed to underscores before - -- insertion. - iw_url nvarchar(max) NOT NULL, - - -- The URL of the file api.php - iw_api nvarchar(max) NOT NULL, - - -- The name of the database (for a connection to be established with wfGetLB( 'wikiid' )) - iw_wikiid nvarchar(64) NOT NULL, - - -- A boolean value indicating whether the wiki is in this project - -- (used, for example, to detect redirect loops) - iw_local bit NOT NULL, - - -- Boolean value indicating whether interwiki transclusions are allowed. - iw_trans bit NOT NULL default 0 -); - -CREATE UNIQUE INDEX /*i*/iw_prefix ON /*_*/interwiki (iw_prefix); - - --- --- Used for caching expensive grouped queries --- -CREATE TABLE /*_*/querycache ( - -- A key name, generally the base name of of the special page. - qc_type nvarchar(32) NOT NULL, - - -- Some sort of stored value. Sizes, counts... - qc_value int NOT NULL default 0, - - -- Target namespace+title - qc_namespace int NOT NULL default 0, - qc_title nvarchar(255) NOT NULL default '' -); - -CREATE INDEX /*i*/qc_type ON /*_*/querycache (qc_type,qc_value); - - --- --- For a few generic cache operations if not using Memcached --- -CREATE TABLE /*_*/objectcache ( - keyname nvarchar(255) NOT NULL default '' PRIMARY KEY, - value varbinary(max), - exptime varchar(14) -); -CREATE INDEX /*i*/exptime ON /*_*/objectcache (exptime); - - --- --- Cache of interwiki transclusion --- -CREATE TABLE /*_*/transcache ( - tc_url nvarchar(255) NOT NULL, - tc_contents nvarchar(max), - tc_time varchar(14) NOT NULL -); - -CREATE UNIQUE INDEX /*i*/tc_url_idx ON /*_*/transcache (tc_url); - - -CREATE TABLE /*_*/logging ( - -- Log ID, for referring to this specific log entry, probably for deletion and such. - log_id int NOT NULL PRIMARY KEY IDENTITY(0,1), - - -- Symbolic keys for the general log type and the action type - -- within the log. The output format will be controlled by the - -- action field, but only the type controls categorization. - log_type nvarchar(32) NOT NULL default '', - log_action nvarchar(32) NOT NULL default '', - - -- Timestamp. Duh. - log_timestamp varchar(14) NOT NULL default '', - - -- The user who performed this action; key to user_id - log_user int REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL, - - -- Name of the user who performed this action - log_user_text nvarchar(255) NOT NULL default '', - - -- Key to the page affected. Where a user is the target, - -- this will point to the user page. - log_namespace int NOT NULL default 0, - log_title nvarchar(255) NOT NULL default '', - log_page int NULL REFERENCES /*_*/page(page_id) ON DELETE SET NULL, - - -- Freeform text. Interpreted as edit history comments. - log_comment nvarchar(255) NOT NULL default '', - - -- miscellaneous parameters: - -- LF separated list (old system) or serialized PHP array (new system) - log_params nvarchar(max) NOT NULL, - - -- rev_deleted for logs - log_deleted tinyint NOT NULL default 0 -); - -CREATE INDEX /*i*/type_time ON /*_*/logging (log_type, log_timestamp); -CREATE INDEX /*i*/user_time ON /*_*/logging (log_user, log_timestamp); -CREATE INDEX /*i*/page_time ON /*_*/logging (log_namespace, log_title, log_timestamp); -CREATE INDEX /*i*/times ON /*_*/logging (log_timestamp); -CREATE INDEX /*i*/log_user_type_time ON /*_*/logging (log_user, log_type, log_timestamp); -CREATE INDEX /*i*/log_page_id_time ON /*_*/logging (log_page,log_timestamp); -CREATE INDEX /*i*/type_action ON /*_*/logging (log_type, log_action, log_timestamp); -CREATE INDEX /*i*/log_user_text_type_time ON /*_*/logging (log_user_text, log_type, log_timestamp); -CREATE INDEX /*i*/log_user_text_time ON /*_*/logging (log_user_text, log_timestamp); - -INSERT INTO /*_*/logging (log_user,log_page,log_params) VALUES(0,0,''); - -ALTER TABLE /*_*/recentchanges ADD CONSTRAINT FK_rc_logid_log_id FOREIGN KEY (rc_logid) REFERENCES /*_*/logging(log_id) ON DELETE CASCADE; - -CREATE TABLE /*_*/log_search ( - -- The type of ID (rev ID, log ID, rev timestamp, username) - ls_field nvarchar(32) NOT NULL, - -- The value of the ID - ls_value nvarchar(255) NOT NULL, - -- Key to log_id - ls_log_id int REFERENCES /*_*/logging(log_id) ON DELETE CASCADE -); -CREATE UNIQUE INDEX /*i*/ls_field_val ON /*_*/log_search (ls_field,ls_value,ls_log_id); -CREATE INDEX /*i*/ls_log_id ON /*_*/log_search (ls_log_id); - - --- Jobs performed by parallel apache threads or a command-line daemon -CREATE TABLE /*_*/job ( - job_id int NOT NULL PRIMARY KEY IDENTITY, - - -- Command name - -- Limited to 60 to prevent key length overflow - job_cmd nvarchar(60) NOT NULL default '', - - -- Namespace and title to act on - -- Should be 0 and '' if the command does not operate on a title - job_namespace int NOT NULL, - job_title nvarchar(255) NOT NULL, - - -- Timestamp of when the job was inserted - -- NULL for jobs added before addition of the timestamp - job_timestamp nvarchar(14) NULL default NULL, - - -- Any other parameters to the command - -- Stored as a PHP serialized array, or an empty string if there are no parameters - job_params nvarchar(max) NOT NULL, - - -- Random, non-unique, number used for job acquisition (for lock concurrency) - job_random int NOT NULL default 0, - - -- The number of times this job has been locked - job_attempts int NOT NULL default 0, - - -- Field that conveys process locks on rows via process UUIDs - job_token nvarchar(32) NOT NULL default '', - - -- Timestamp when the job was locked - job_token_timestamp varchar(14) NULL default NULL, - - -- Base 36 SHA1 of the job parameters relevant to detecting duplicates - job_sha1 nvarchar(32) NOT NULL default '' -); - -CREATE INDEX /*i*/job_sha1 ON /*_*/job (job_sha1); -CREATE INDEX /*i*/job_cmd_token ON /*_*/job (job_cmd,job_token,job_random); -CREATE INDEX /*i*/job_cmd_token_id ON /*_*/job (job_cmd,job_token,job_id); -CREATE INDEX /*i*/job_cmd ON /*_*/job (job_cmd, job_namespace, job_title); -CREATE INDEX /*i*/job_timestamp ON /*_*/job (job_timestamp); - - --- Details of updates to cached special pages -CREATE TABLE /*_*/querycache_info ( - -- Special page name - -- Corresponds to a qc_type value - qci_type nvarchar(32) NOT NULL default '', - - -- Timestamp of last update - qci_timestamp varchar(14) NOT NULL default '' -); - -CREATE UNIQUE INDEX /*i*/qci_type ON /*_*/querycache_info (qci_type); - - --- For each redirect, this table contains exactly one row defining its target -CREATE TABLE /*_*/redirect ( - -- Key to the page_id of the redirect page - rd_from int NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE, - - -- Key to page_namespace/page_title of the target page. - -- The target page may or may not exist, and due to renames - -- and deletions may refer to different page records as time - -- goes by. - rd_namespace int NOT NULL default 0, - rd_title nvarchar(255) NOT NULL default '', - rd_interwiki nvarchar(32) default NULL, - rd_fragment nvarchar(255) default NULL -); - -CREATE INDEX /*i*/rd_ns_title ON /*_*/redirect (rd_namespace,rd_title,rd_from); - - --- Used for caching expensive grouped queries that need two links (for example double-redirects) -CREATE TABLE /*_*/querycachetwo ( - -- A key name, generally the base name of of the special page. - qcc_type nvarchar(32) NOT NULL, - - -- Some sort of stored value. Sizes, counts... - qcc_value int NOT NULL default 0, - - -- Target namespace+title - qcc_namespace int NOT NULL default 0, - qcc_title nvarchar(255) NOT NULL default '', - - -- Target namespace+title2 - qcc_namespacetwo int NOT NULL default 0, - qcc_titletwo nvarchar(255) NOT NULL default '' -); - -CREATE INDEX /*i*/qcc_type ON /*_*/querycachetwo (qcc_type,qcc_value); -CREATE INDEX /*i*/qcc_title ON /*_*/querycachetwo (qcc_type,qcc_namespace,qcc_title); -CREATE INDEX /*i*/qcc_titletwo ON /*_*/querycachetwo (qcc_type,qcc_namespacetwo,qcc_titletwo); - - --- Used for storing page restrictions (i.e. protection levels) -CREATE TABLE /*_*/page_restrictions ( - -- Field for an ID for this restrictions row (sort-key for Special:ProtectedPages) - pr_id int NOT NULL PRIMARY KEY IDENTITY, - -- Page to apply restrictions to (Foreign Key to page). - pr_page int NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE, - -- The protection type (edit, move, etc) - pr_type nvarchar(60) NOT NULL, - -- The protection level (Sysop, autoconfirmed, etc) - pr_level nvarchar(60) NOT NULL, - -- Whether or not to cascade the protection down to pages transcluded. - pr_cascade bit NOT NULL, - -- Field for future support of per-user restriction. - pr_user int NULL, - -- Field for time-limited protection. - pr_expiry varchar(14) NULL -); - -CREATE UNIQUE INDEX /*i*/pr_pagetype ON /*_*/page_restrictions (pr_page,pr_type); -CREATE INDEX /*i*/pr_typelevel ON /*_*/page_restrictions (pr_type,pr_level); -CREATE INDEX /*i*/pr_level ON /*_*/page_restrictions (pr_level); -CREATE INDEX /*i*/pr_cascade ON /*_*/page_restrictions (pr_cascade); - - --- Protected titles - nonexistent pages that have been protected -CREATE TABLE /*_*/protected_titles ( - pt_namespace int NOT NULL, - pt_title nvarchar(255) NOT NULL, - pt_user int REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL, - pt_reason nvarchar(255), - pt_timestamp varchar(14) NOT NULL, - pt_expiry varchar(14) NOT NULL, - pt_create_perm nvarchar(60) NOT NULL -); - -CREATE UNIQUE INDEX /*i*/pt_namespace_title ON /*_*/protected_titles (pt_namespace,pt_title); -CREATE INDEX /*i*/pt_timestamp ON /*_*/protected_titles (pt_timestamp); - - --- Name/value pairs indexed by page_id -CREATE TABLE /*_*/page_props ( - pp_page int NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE, - pp_propname nvarchar(60) NOT NULL, - pp_value nvarchar(max) NOT NULL -); - -CREATE UNIQUE INDEX /*i*/pp_page_propname ON /*_*/page_props (pp_page,pp_propname); -CREATE UNIQUE INDEX /*i*/pp_propname_page ON /*_*/page_props (pp_propname,pp_page); - - --- A table to log updates, one text key row per update. -CREATE TABLE /*_*/updatelog ( - ul_key nvarchar(255) NOT NULL PRIMARY KEY, - ul_value nvarchar(max) -); - - --- A table to track tags for revisions, logs and recent changes. -CREATE TABLE /*_*/change_tag ( - -- RCID for the change - ct_rc_id int NULL REFERENCES /*_*/recentchanges(rc_id), - -- LOGID for the change - ct_log_id int NULL REFERENCES /*_*/logging(log_id), - -- REVID for the change - ct_rev_id int NULL REFERENCES /*_*/revision(rev_id), - -- Tag applied - ct_tag nvarchar(255) NOT NULL, - -- Parameters for the tag, presently unused - ct_params nvarchar(max) NULL -); - -CREATE UNIQUE INDEX /*i*/change_tag_rc_tag ON /*_*/change_tag (ct_rc_id,ct_tag); -CREATE UNIQUE INDEX /*i*/change_tag_log_tag ON /*_*/change_tag (ct_log_id,ct_tag); -CREATE UNIQUE INDEX /*i*/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 /*i*/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 without ugly GROUP_CONCAT --- that only works on MySQL 4.1+ -CREATE TABLE /*_*/tag_summary ( - -- RCID for the change - ts_rc_id int NULL REFERENCES /*_*/recentchanges(rc_id), - -- LOGID for the change - ts_log_id int NULL REFERENCES /*_*/logging(log_id), - -- REVID for the change - ts_rev_id int NULL REFERENCES /*_*/revision(rev_id), - -- Comma-separated list of tags - ts_tags nvarchar(max) NOT NULL -); - -CREATE UNIQUE INDEX /*i*/tag_summary_rc_id ON /*_*/tag_summary (ts_rc_id); -CREATE UNIQUE INDEX /*i*/tag_summary_log_id ON /*_*/tag_summary (ts_log_id); -CREATE UNIQUE INDEX /*i*/tag_summary_rev_id ON /*_*/tag_summary (ts_rev_id); - - -CREATE TABLE /*_*/valid_tag ( - vt_tag nvarchar(255) NOT NULL PRIMARY KEY -); - --- Table for storing localisation data -CREATE TABLE /*_*/l10n_cache ( - -- Language code - lc_lang nvarchar(32) NOT NULL, - -- Cache key - lc_key nvarchar(255) NOT NULL, - -- Value - lc_value varbinary(max) NOT NULL -); -CREATE INDEX /*i*/lc_lang_key ON /*_*/l10n_cache (lc_lang, lc_key); - --- Table for caching JSON message texts for the resource loader -CREATE TABLE /*_*/msg_resource ( - -- Resource name - mr_resource nvarchar(255) NOT NULL, - -- Language code - mr_lang nvarchar(32) NOT NULL, - -- JSON blob - mr_blob varbinary(max) NOT NULL, - -- Timestamp of last update - mr_timestamp varchar(14) NOT NULL -); -CREATE UNIQUE INDEX /*i*/mr_resource_lang ON /*_*/msg_resource (mr_resource, mr_lang); - --- Table for administering which message is contained in which resource -CREATE TABLE /*_*/msg_resource_links ( - mrl_resource varbinary(255) NOT NULL, - -- Message key - mrl_message varbinary(255) NOT NULL -); -CREATE UNIQUE INDEX /*i*/mrl_message_resource ON /*_*/msg_resource_links (mrl_message, mrl_resource); - --- Table caching which local files a module depends on that aren't --- registered directly, used for fast retrieval of file dependency. --- Currently only used for tracking images that CSS depends on -CREATE TABLE /*_*/module_deps ( - -- Module name - md_module nvarchar(255) NOT NULL, - -- Skin name - md_skin nvarchar(32) NOT NULL, - -- JSON nvarchar(max) with file dependencies - md_deps nvarchar(max) NOT NULL -); -CREATE UNIQUE INDEX /*i*/md_module_skin ON /*_*/module_deps (md_module, md_skin); - --- Holds all the sites known to the wiki. -CREATE TABLE /*_*/sites ( - -- Numeric id of the site - site_id int NOT NULL PRIMARY KEY IDENTITY, - - -- Global identifier for the site, ie 'enwiktionary' - site_global_key nvarchar(32) NOT NULL, - - -- Type of the site, ie 'mediawiki' - site_type nvarchar(32) NOT NULL, - - -- Group of the site, ie 'wikipedia' - site_group nvarchar(32) NOT NULL, - - -- Source of the site data, ie 'local', 'wikidata', 'my-magical-repo' - site_source nvarchar(32) NOT NULL, - - -- Language code of the sites primary language. - site_language nvarchar(32) NOT NULL, - - -- Protocol of the site, ie 'http://', 'irc://', '//' - -- This field is an index for lookups and is build from type specific data in site_data. - site_protocol nvarchar(32) NOT NULL, - - -- Domain of the site in reverse order, ie 'org.mediawiki.www.' - -- This field is an index for lookups and is build from type specific data in site_data. - site_domain NVARCHAR(255) NOT NULL, - - -- Type dependent site data. - site_data nvarchar(max) NOT NULL, - - -- If site.tld/path/key:pageTitle should forward users to the page on - -- the actual site, where "key" is the local identifier. - site_forward bit NOT NULL, - - -- Type dependent site config. - -- For instance if template transclusion should be allowed if it's a MediaWiki. - site_config nvarchar(max) NOT NULL -); - -CREATE UNIQUE INDEX /*i*/sites_global_key ON /*_*/sites (site_global_key); -CREATE INDEX /*i*/sites_type ON /*_*/sites (site_type); -CREATE INDEX /*i*/sites_group ON /*_*/sites (site_group); -CREATE INDEX /*i*/sites_source ON /*_*/sites (site_source); -CREATE INDEX /*i*/sites_language ON /*_*/sites (site_language); -CREATE INDEX /*i*/sites_protocol ON /*_*/sites (site_protocol); -CREATE INDEX /*i*/sites_domain ON /*_*/sites (site_domain); -CREATE INDEX /*i*/sites_forward ON /*_*/sites (site_forward); - --- Links local site identifiers to their corresponding site. -CREATE TABLE /*_*/site_identifiers ( - -- Key on site.site_id - si_site int NOT NULL REFERENCES /*_*/sites(site_id) ON DELETE CASCADE, - - -- local key type, ie 'interwiki' or 'langlink' - si_type nvarchar(32) NOT NULL, - - -- local key value, ie 'en' or 'wiktionary' - si_key nvarchar(32) NOT NULL -); - -CREATE UNIQUE INDEX /*i*/site_ids_type ON /*_*/site_identifiers (si_type, si_key); -CREATE INDEX /*i*/site_ids_site ON /*_*/site_identifiers (si_site); -CREATE INDEX /*i*/site_ids_key ON /*_*/site_identifiers (si_key); diff --git a/maintenance/mssql/update-keys.sql b/maintenance/mssql/update-keys.sql deleted file mode 100644 index 4d2c1c12..00000000 --- a/maintenance/mssql/update-keys.sql +++ /dev/null @@ -1,31 +0,0 @@ --- Update keys for Microsoft SQL Server --- SQL to insert update keys into the initial tables after a --- fresh installation of MediaWiki's database. --- This is read and executed by the install script; you should --- not have to run it by itself unless doing a manual install. --- Insert keys here if either the unnecessary would cause heavy --- processing or could potentially cause trouble by lowering field --- sizes, adding constraints, etc. --- When adjusting field sizes, it is recommended removing old --- patches but to play safe, update keys should also inserted here. - --- --- The /*_*/ comments in this and other files are --- replaced with the defined table prefix by the installer --- and updater scripts. If you are installing or running --- updates manually, you will need to manually insert the --- table prefix if any when running these scripts. --- - -INSERT INTO /*_*/updatelog - SELECT 'filearchive-fa_major_mime-patch-fa_major_mime-chemical.sql' AS ul_key, null as ul_value - UNION SELECT 'image-img_major_mime-patch-img_major_mime-chemical.sql', null - UNION SELECT 'oldimage-oi_major_mime-patch-oi_major_mime-chemical.sql', null - UNION SELECT 'cl_type-category_types-ck', null - UNION SELECT 'fa_major_mime-major_mime-ck', null - UNION SELECT 'fa_media_type-media_type-ck', null - UNION SELECT 'img_major_mime-major_mime-ck', null - UNION SELECT 'img_media_type-media_type-ck', null - UNION SELECT 'oi_major_mime-major_mime-ck', null - UNION SELECT 'oi_media_type-media_type-ck', null - UNION SELECT 'us_media_type-media_type-ck', null; \ No newline at end of file diff --git a/maintenance/oracle/alterSharedConstraints.php b/maintenance/oracle/alterSharedConstraints.php deleted file mode 100644 index eea6f7b1..00000000 --- a/maintenance/oracle/alterSharedConstraints.php +++ /dev/null @@ -1,95 +0,0 @@ -mDescription = "Alter foreign key to reference master tables in shared database setup."; - } - - public function getDbType() { - return Maintenance::DB_ADMIN; - } - - public function execute() { - global $wgSharedDB, $wgSharedTables, $wgSharedPrefix, $wgDBprefix; - - if ( $wgSharedDB == null ) { - $this->output( "Database sharing is not enabled\n" ); - - return; - } - - $dbw = wfGetDB( DB_MASTER ); - foreach ( $wgSharedTables as $table ) { - $stable = $dbw->tableNameInternal( $table ); - if ( $wgSharedPrefix != null ) { - $ltable = preg_replace( "/^$wgSharedPrefix(.*)/i", "$wgDBprefix\\1", $stable ); - } else { - $ltable = "{$wgDBprefix}{$stable}"; - } - - $result = $dbw->query( "SELECT uc.constraint_name, uc.table_name, ucc.column_name, - uccpk.table_name pk_table_name, uccpk.column_name pk_column_name, - uc.delete_rule, uc.deferrable, uc.deferred - FROM user_constraints uc, user_cons_columns ucc, user_cons_columns uccpk - WHERE uc.constraint_type = 'R' - AND ucc.constraint_name = uc.constraint_name - AND uccpk.constraint_name = uc.r_constraint_name - AND uccpk.table_name = '$ltable'" ); - while ( ( $row = $result->fetchRow() ) !== false ) { - - $this->output( "Altering {$row['constraint_name']} ..." ); - - try { - $dbw->query( "ALTER TABLE {$row['table_name']} - DROP CONSTRAINT {$wgDBprefix}{$row['constraint_name']}" ); - } catch ( DBQueryError $exdb ) { - if ( $exdb->errno != 2443 ) { - throw $exdb; - } - } - - $deleteRule = $row['delete_rule'] == 'NO ACTION' ? '' : "ON DELETE {$row['delete_rule']}"; - $dbw->query( "ALTER TABLE {$row['table_name']} - ADD CONSTRAINT {$wgDBprefix}{$row['constraint_name']} - FOREIGN KEY ({$row['column_name']}) - REFERENCES {$wgSharedDB}.$stable({$row['pk_column_name']}) - {$deleteRule} {$row['deferrable']} INITIALLY {$row['deferred']}" ); - - $this->output( "DONE\n" ); - } - } - } -} - -$maintClass = "AlterSharedConstraints"; -require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/oracle/archives/patch-ar_sha1_field.sql b/maintenance/oracle/archives/patch-ar_sha1_field.sql deleted file mode 100644 index de723ce7..00000000 --- a/maintenance/oracle/archives/patch-ar_sha1_field.sql +++ /dev/null @@ -1,3 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -ALTER TABLE &mw_prefix.archive ADD ar_sha1 VARCHAR2(32); diff --git a/maintenance/oracle/archives/patch-archive-ar_content_format.sql b/maintenance/oracle/archives/patch-archive-ar_content_format.sql deleted file mode 100644 index 0c0c0d94..00000000 --- a/maintenance/oracle/archives/patch-archive-ar_content_format.sql +++ /dev/null @@ -1,3 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -ALTER TABLE &mw_prefix.archive ADD ar_content_format VARCHAR2(64); diff --git a/maintenance/oracle/archives/patch-archive-ar_content_model.sql b/maintenance/oracle/archives/patch-archive-ar_content_model.sql deleted file mode 100644 index d18fc9e4..00000000 --- a/maintenance/oracle/archives/patch-archive-ar_content_model.sql +++ /dev/null @@ -1,3 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -ALTER TABLE &mw_prefix.archive ADD ar_content_model VARCHAR2(32); diff --git a/maintenance/oracle/archives/patch-archive-ar_id.sql b/maintenance/oracle/archives/patch-archive-ar_id.sql deleted file mode 100644 index a43f7602..00000000 --- a/maintenance/oracle/archives/patch-archive-ar_id.sql +++ /dev/null @@ -1,6 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -ALTER TABLE &mw_prefix.archive ADD ( -ar_id NUMBER NOT NULL, -); -ALTER TABLE &mw_prefix.archive ADD CONSTRAINT &mw_prefix.archive_pk PRIMARY KEY (ar_id); diff --git a/maintenance/oracle/archives/patch-cat_hidden.sql b/maintenance/oracle/archives/patch-cat_hidden.sql deleted file mode 100644 index d1649c7c..00000000 --- a/maintenance/oracle/archives/patch-cat_hidden.sql +++ /dev/null @@ -1,4 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -ALTER TABLE &mw_prefix.category DROP COLUMN cat_hidden; - diff --git a/maintenance/oracle/archives/patch-externallinks-el_id.sql b/maintenance/oracle/archives/patch-externallinks-el_id.sql deleted file mode 100644 index a8c443f4..00000000 --- a/maintenance/oracle/archives/patch-externallinks-el_id.sql +++ /dev/null @@ -1,4 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -ALTER TABLE &mw_prefix.externallinks ADD el_id NUMBER NOT NULL; -ALTER TABLE &mw_prefix.externallinks ADD CONSTRAINT &mw_prefix.externallinks_pk PRIMARY KEY (el_id); \ No newline at end of file diff --git a/maintenance/oracle/archives/patch-fa_sha1.sql b/maintenance/oracle/archives/patch-fa_sha1.sql deleted file mode 100644 index 70c9e60c..00000000 --- a/maintenance/oracle/archives/patch-fa_sha1.sql +++ /dev/null @@ -1,5 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -ALTER TABLE &mw_prefix.filearchive ADD fa_sha1 VARCHAR2(32); -CREATE INDEX &mw_prefix.filearchive_i05 ON &mw_prefix.filearchive (fa_sha1); - diff --git a/maintenance/oracle/archives/patch-ipblocks_i05_index.sql b/maintenance/oracle/archives/patch-ipblocks_i05_index.sql deleted file mode 100644 index 14275383..00000000 --- a/maintenance/oracle/archives/patch-ipblocks_i05_index.sql +++ /dev/null @@ -1,4 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -CREATE INDEX &mw_prefix.ipblocks_i05 ON &mw_prefix.ipblocks (ipb_parent_block_id); - diff --git a/maintenance/oracle/archives/patch-job_attempts.sql b/maintenance/oracle/archives/patch-job_attempts.sql deleted file mode 100644 index b05c8779..00000000 --- a/maintenance/oracle/archives/patch-job_attempts.sql +++ /dev/null @@ -1,4 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -ALTER TABLE &mw_prefix.job ADD job_attempts NUMBER DEFAULT 0 NOT NULL; -CREATE INDEX &mw_prefix.job_i05 ON &mw_prefix.job (job_attempts); diff --git a/maintenance/oracle/archives/patch-job_timestamp_field.sql b/maintenance/oracle/archives/patch-job_timestamp_field.sql deleted file mode 100644 index 4901c87c..00000000 --- a/maintenance/oracle/archives/patch-job_timestamp_field.sql +++ /dev/null @@ -1,4 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -ALTER TABLE &mw_prefix.job ADD job_timestamp TIMESTAMP(6) WITH TIME ZONE NULL; - diff --git a/maintenance/oracle/archives/patch-job_timestamp_index.sql b/maintenance/oracle/archives/patch-job_timestamp_index.sql deleted file mode 100644 index 6db43046..00000000 --- a/maintenance/oracle/archives/patch-job_timestamp_index.sql +++ /dev/null @@ -1,4 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -CREATE INDEX &mw_prefix.job_i02 ON &mw_prefix.job (job_timestamp); - diff --git a/maintenance/oracle/archives/patch-job_token.sql b/maintenance/oracle/archives/patch-job_token.sql deleted file mode 100644 index 1a730e95..00000000 --- a/maintenance/oracle/archives/patch-job_token.sql +++ /dev/null @@ -1,12 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -ALTER TABLE &mw_prefix.job ADD ( - job_random NUMBER DEFAULT 0 NOT NULL, - job_token VARCHAR2(32), - job_token_timestamp TIMESTAMP(6) WITH TIME ZONE, - job_sha1 VARCHAR2(32) -); - -CREATE INDEX &mw_prefix.job_i03 ON &mw_prefix.job (job_sha1); -CREATE INDEX &mw_prefix.job_i04 ON &mw_prefix.job (job_cmd,job_token,job_random); - diff --git a/maintenance/oracle/archives/patch-logging_type_action_index.sql b/maintenance/oracle/archives/patch-logging_type_action_index.sql deleted file mode 100644 index d30e0cfc..00000000 --- a/maintenance/oracle/archives/patch-logging_type_action_index.sql +++ /dev/null @@ -1,4 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -CREATE INDEX &mw_prefix.logging_i05 ON &mw_prefix.logging (log_type, log_action, log_timestamp); - diff --git a/maintenance/oracle/archives/patch-logging_user_text_time_index.sql b/maintenance/oracle/archives/patch-logging_user_text_time_index.sql deleted file mode 100644 index e04abf5f..00000000 --- a/maintenance/oracle/archives/patch-logging_user_text_time_index.sql +++ /dev/null @@ -1,4 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -CREATE INDEX &mw_prefix.logging_i07 ON &mw_prefix.logging (log_user_text, log_timestamp); - diff --git a/maintenance/oracle/archives/patch-logging_user_text_type_time_index.sql b/maintenance/oracle/archives/patch-logging_user_text_type_time_index.sql deleted file mode 100644 index c1c0d4f2..00000000 --- a/maintenance/oracle/archives/patch-logging_user_text_type_time_index.sql +++ /dev/null @@ -1,4 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -CREATE INDEX &mw_prefix.logging_i06 ON &mw_prefix.logging (log_user_text, log_type, log_timestamp); - diff --git a/maintenance/oracle/archives/patch-page-page_content_model.sql b/maintenance/oracle/archives/patch-page-page_content_model.sql deleted file mode 100644 index e5839d9a..00000000 --- a/maintenance/oracle/archives/patch-page-page_content_model.sql +++ /dev/null @@ -1,3 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -ALTER TABLE &mw_prefix.page ADD page_content_model VARCHAR2(32); diff --git a/maintenance/oracle/archives/patch-page-page_lang.sql b/maintenance/oracle/archives/patch-page-page_lang.sql deleted file mode 100644 index cae7cf90..00000000 --- a/maintenance/oracle/archives/patch-page-page_lang.sql +++ /dev/null @@ -1,3 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -ALTER TABLE &mw_prefix.page ADD page_lang VARCHAR2(35); diff --git a/maintenance/oracle/archives/patch-page_links_updated.sql b/maintenance/oracle/archives/patch-page_links_updated.sql deleted file mode 100644 index 53603294..00000000 --- a/maintenance/oracle/archives/patch-page_links_updated.sql +++ /dev/null @@ -1,4 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -ALTER TABLE &mw_prefix.page ADD page_links_updated TIMESTAMP(6) WITH TIME ZONE; - diff --git a/maintenance/oracle/archives/patch-page_redirect_namespace_len.sql b/maintenance/oracle/archives/patch-page_redirect_namespace_len.sql deleted file mode 100644 index 1f8b9d9a..00000000 --- a/maintenance/oracle/archives/patch-page_redirect_namespace_len.sql +++ /dev/null @@ -1,4 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -CREATE INDEX &mw_prefix.page_i03 ON &mw_prefix.page (page_is_redirect, page_namespace, page_len); - diff --git a/maintenance/oracle/archives/patch-page_restrictions_pkuk_fix.sql b/maintenance/oracle/archives/patch-page_restrictions_pkuk_fix.sql deleted file mode 100644 index 56c392c1..00000000 --- a/maintenance/oracle/archives/patch-page_restrictions_pkuk_fix.sql +++ /dev/null @@ -1,7 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -ALTER TABLE &mw_prefix.page_restrictions DROP CONSTRAINT &mw_prefix.page_restrictions_pk; - -ALTER TABLE &mw_prefix.page_restrictions ADD CONSTRAINT &mw_prefix.page_restrictions_pk PRIMARY KEY (pr_id); - -CREATE UNIQUE INDEX &mw_prefix.page_restrictions_u01 ON &mw_prefix.page_restrictions (pr_page,pr_type); diff --git a/maintenance/oracle/archives/patch-rc_moved.sql b/maintenance/oracle/archives/patch-rc_moved.sql deleted file mode 100644 index 2a71315d..00000000 --- a/maintenance/oracle/archives/patch-rc_moved.sql +++ /dev/null @@ -1,4 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -ALTER TABLE &mw_prefix.recentchanges DROP ( rc_moved_to_ns, rc_moved_to_title ); - diff --git a/maintenance/oracle/archives/patch-rc_source.sql b/maintenance/oracle/archives/patch-rc_source.sql deleted file mode 100644 index 0c80afab..00000000 --- a/maintenance/oracle/archives/patch-rc_source.sql +++ /dev/null @@ -1,3 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -ALTER TABLE &mw_prefix.recentchanges ADD rc_source VARCHAR2(16); diff --git a/maintenance/oracle/archives/patch-rev_sha1_field.sql b/maintenance/oracle/archives/patch-rev_sha1_field.sql deleted file mode 100644 index 80544e89..00000000 --- a/maintenance/oracle/archives/patch-rev_sha1_field.sql +++ /dev/null @@ -1,4 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -ALTER TABLE &mw_prefix.revision ADD rev_sha1 VARCHAR2(32); - diff --git a/maintenance/oracle/archives/patch-revision-rev_content_format.sql b/maintenance/oracle/archives/patch-revision-rev_content_format.sql deleted file mode 100644 index ebde71c9..00000000 --- a/maintenance/oracle/archives/patch-revision-rev_content_format.sql +++ /dev/null @@ -1,3 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -ALTER TABLE &mw_prefix.revision ADD rev_content_format VARCHAR2(64); diff --git a/maintenance/oracle/archives/patch-revision-rev_content_model.sql b/maintenance/oracle/archives/patch-revision-rev_content_model.sql deleted file mode 100644 index dd226423..00000000 --- a/maintenance/oracle/archives/patch-revision-rev_content_model.sql +++ /dev/null @@ -1,3 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -ALTER TABLE &mw_prefix.revision ADD rev_content_model VARCHAR2(32); diff --git a/maintenance/oracle/archives/patch-revision_i05_index.sql b/maintenance/oracle/archives/patch-revision_i05_index.sql deleted file mode 100644 index 929c7b31..00000000 --- a/maintenance/oracle/archives/patch-revision_i05_index.sql +++ /dev/null @@ -1,4 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -CREATE INDEX &mw_prefix.revision_i05 ON &mw_prefix.revision (rev_page,rev_user,rev_timestamp); - diff --git a/maintenance/oracle/archives/patch-sites.sql b/maintenance/oracle/archives/patch-sites.sql deleted file mode 100644 index 868b210f..00000000 --- a/maintenance/oracle/archives/patch-sites.sql +++ /dev/null @@ -1,34 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -CREATE SEQUENCE sites_site_id_seq MINVALUE 0 START WITH 0; -CREATE TABLE &mw_prefix.sites ( - site_id NUMBER NOT NULL, - site_global_key VARCHAR2(32) NOT NULL, - site_type VARCHAR2(32) NOT NULL, - site_group VARCHAR2(32) NOT NULL, - site_source VARCHAR2(32) NOT NULL, - site_language VARCHAR2(32) NOT NULL, - site_protocol VARCHAR2(32) NOT NULL, - site_domain VARCHAR2(255) NOT NULL, - site_data BLOB NOT NULL, - site_forward NUMBER(1) NOT NULL, - site_config BLOB NOT NULL -); -ALTER TABLE &mw_prefix.sites ADD CONSTRAINT &mw_prefix.sites_pk PRIMARY KEY (site_id); -CREATE UNIQUE INDEX &mw_prefix.sites_u01 ON &mw_prefix.sites (site_global_key); -CREATE INDEX &mw_prefix.sites_i01 ON &mw_prefix.sites (site_type); -CREATE INDEX &mw_prefix.sites_i02 ON &mw_prefix.sites (site_group); -CREATE INDEX &mw_prefix.sites_i03 ON &mw_prefix.sites (site_source); -CREATE INDEX &mw_prefix.sites_i04 ON &mw_prefix.sites (site_language); -CREATE INDEX &mw_prefix.sites_i05 ON &mw_prefix.sites (site_protocol); -CREATE INDEX &mw_prefix.sites_i06 ON &mw_prefix.sites (site_domain); -CREATE INDEX &mw_prefix.sites_i07 ON &mw_prefix.sites (site_forward); - -CREATE TABLE &mw_prefix.site_identifiers ( - si_site NUMBER NOT NULL, - si_type VARCHAR2(32) NOT NULL, - si_key VARCHAR2(32) NOT NULL -); -CREATE UNIQUE INDEX &mw_prefix.site_identifiers_u01 ON &mw_prefix.site_identifiers (si_type, si_key); -CREATE INDEX &mw_prefix.site_identifiers_i01 ON &mw_prefix.site_identifiers (si_site); -CREATE INDEX &mw_prefix.site_identifiers_i02 ON &mw_prefix.site_identifiers (si_key); diff --git a/maintenance/oracle/archives/patch-ss_admins.sql b/maintenance/oracle/archives/patch-ss_admins.sql deleted file mode 100644 index c2e9242e..00000000 --- a/maintenance/oracle/archives/patch-ss_admins.sql +++ /dev/null @@ -1,4 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -ALTER TABLE &mw_prefix.site_stats DROP COLUMN ss_admins; - diff --git a/maintenance/oracle/archives/patch-testrun.sql b/maintenance/oracle/archives/patch-testrun.sql deleted file mode 100644 index 84facabc..00000000 --- a/maintenance/oracle/archives/patch-testrun.sql +++ /dev/null @@ -1,37 +0,0 @@ --- --- Optional tables for parserTests recording mode --- With --record option, success data will be saved to these tables, --- and comparisons of what's changed from the previous run will be --- displayed at the end of each run. --- --- defines must comply with ^define\s*([^\s=]*)\s*=\s?'\{\$([^\}]*)\}'; -define mw_prefix='{$wgDBprefix}'; - -DROP TABLE &mw_prefix.testitem CASCADE CONSTRAINTS; -DROP TABLE &mw_prefix.testrun CASCADE CONSTRAINTS; - -CREATE SEQUENCE testrun_tr_id_seq; -CREATE TABLE &mw_prefix.testrun ( - tr_id NUMBER NOT NULL, - tr_date DATE, - tr_mw_version BLOB, - tr_php_version BLOB, - tr_db_version BLOB, - tr_uname BLOB, -); -ALTER TABLE &mw_prefix.testrun ADD CONSTRAINT &mw_prefix.testrun_pk PRIMARY KEY (tr_id); -CREATE OR REPLACE TRIGGER &mw_prefix.testrun_bir -BEFORE UPDATE FOR EACH ROW -ON &mw_prefix.testrun -BEGIN - SELECT testrun_tr_id_seq.NEXTVAL into :NEW.tr_id FROM dual; -END; - -CREATE TABLE /*$wgDBprefix*/testitem ( - ti_run NUMBER NOT NULL REFERENCES &mw_prefix.testrun (tr_id) ON DELETE CASCADE, - ti_name VARCHAR22(255), - ti_success NUMBER(1) -); -CREATE UNIQUE INDEX &mw_prefix.testitem_u01 ON &mw_prefix.testitem (ti_run, ti_name); -CREATE UNIQUE INDEX &mw_prefix.testitem_u01 ON &mw_prefix.testitem (ti_run, ti_success); - diff --git a/maintenance/oracle/archives/patch-ufg_group-length-increase-255.sql b/maintenance/oracle/archives/patch-ufg_group-length-increase-255.sql deleted file mode 100644 index 6a4a7517..00000000 --- a/maintenance/oracle/archives/patch-ufg_group-length-increase-255.sql +++ /dev/null @@ -1,9 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -/*$mw$*/ -BEGIN - EXECUTE IMMEDIATE 'ALTER TABLE &mw_prefix.user_former_groups MODIFY ufg_group VARCHAR2(255) NOT NULL'; -EXCEPTION WHEN OTHERS THEN - IF (SQLCODE = -01442) THEN NULL; ELSE RAISE; END IF; -END; -/*$mw$*/ diff --git a/maintenance/oracle/archives/patch-ug_group-length-increase-255.sql b/maintenance/oracle/archives/patch-ug_group-length-increase-255.sql deleted file mode 100644 index 00a5e7b2..00000000 --- a/maintenance/oracle/archives/patch-ug_group-length-increase-255.sql +++ /dev/null @@ -1,9 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -/*$mw$*/ -BEGIN - EXECUTE IMMEDIATE 'ALTER TABLE &mw_prefix.user_groups MODIFY ug_group VARCHAR2(255) NOT NULL'; -EXCEPTION WHEN OTHERS THEN - IF (SQLCODE = -01442) THEN NULL; ELSE RAISE; END IF; -END; -/*$mw$*/ diff --git a/maintenance/oracle/archives/patch-up_property.sql b/maintenance/oracle/archives/patch-up_property.sql deleted file mode 100644 index c8e2dd95..00000000 --- a/maintenance/oracle/archives/patch-up_property.sql +++ /dev/null @@ -1,3 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -ALTER TABLE &mw_prefix.user_properties MODIFY up_property varchar2(255); diff --git a/maintenance/oracle/archives/patch-uploadstash-us_props.sql b/maintenance/oracle/archives/patch-uploadstash-us_props.sql deleted file mode 100644 index 8962dc7c..00000000 --- a/maintenance/oracle/archives/patch-uploadstash-us_props.sql +++ /dev/null @@ -1,4 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -ALTER TABLE &mw_prefix.uploadstash ADD us_props BLOB; - diff --git a/maintenance/oracle/archives/patch-uploadstash.sql b/maintenance/oracle/archives/patch-uploadstash.sql deleted file mode 100644 index 3e37ceff..00000000 --- a/maintenance/oracle/archives/patch-uploadstash.sql +++ /dev/null @@ -1,25 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -CREATE SEQUENCE uploadstash_us_id_seq; -CREATE TABLE &mw_prefix.uploadstash ( - us_id NUMBER NOT NULL, - us_user NUMBER DEFAULT 0 NOT NULL, - us_key VARCHAR2(255) NOT NULL, - us_orig_path VARCHAR2(255) NOT NULL, - us_path VARCHAR2(255) NOT NULL, - us_source_type VARCHAR2(50), - us_timestamp TIMESTAMP(6) WITH TIME ZONE, - us_status VARCHAR2(50) NOT NULL, - us_size NUMBER NOT NULL, - us_sha1 VARCHAR2(32) NOT NULL, - us_mime VARCHAR2(255), - us_media_type VARCHAR2(32) DEFAULT NULL, - us_image_width NUMBER, - us_image_height NUMBER, - us_image_bits NUMBER -); -ALTER TABLE &mw_prefix.uploadstash ADD CONSTRAINT &mw_prefix.uploadstash_pk PRIMARY KEY (us_id); -ALTER TABLE &mw_prefix.uploadstash ADD CONSTRAINT &mw_prefix.uploadstash_fk1 FOREIGN KEY (us_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED; -CREATE INDEX &mw_prefix.uploadstash_i01 ON &mw_prefix.uploadstash (us_user); -CREATE INDEX &mw_prefix.uploadstash_i02 ON &mw_prefix.uploadstash (us_timestamp); -CREATE UNIQUE INDEX &mw_prefix.uploadstash_u01 ON &mw_prefix.uploadstash (us_key); diff --git a/maintenance/oracle/archives/patch-us_chunk_inx_field.sql b/maintenance/oracle/archives/patch-us_chunk_inx_field.sql deleted file mode 100644 index 43ee16ec..00000000 --- a/maintenance/oracle/archives/patch-us_chunk_inx_field.sql +++ /dev/null @@ -1,4 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -ALTER TABLE &mw_prefix.uploadstash ADD us_chunk_inx NUMBER; - diff --git a/maintenance/oracle/archives/patch-user_email_index.sql b/maintenance/oracle/archives/patch-user_email_index.sql deleted file mode 100644 index e34d8656..00000000 --- a/maintenance/oracle/archives/patch-user_email_index.sql +++ /dev/null @@ -1,4 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -CREATE INDEX &mw_prefix.mwuser_i02 ON &mw_prefix.mwuser (user_email); - diff --git a/maintenance/oracle/archives/patch-user_former_groups.sql b/maintenance/oracle/archives/patch-user_former_groups.sql deleted file mode 100644 index c14824eb..00000000 --- a/maintenance/oracle/archives/patch-user_former_groups.sql +++ /dev/null @@ -1,9 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -CREATE TABLE &mw_prefix.user_former_groups ( - ufg_user NUMBER DEFAULT 0 NOT NULL, - ufg_group VARCHAR2(255) NOT NULL -); -ALTER TABLE &mw_prefix.user_former_groups ADD CONSTRAINT &mw_prefix.user_former_groups_fk1 FOREIGN KEY (ufg_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; -CREATE UNIQUE INDEX &mw_prefix.user_former_groups_u01 ON &mw_prefix.user_former_groups (ufg_user,ufg_group); - diff --git a/maintenance/oracle/archives/patch-user_password_expire.sql b/maintenance/oracle/archives/patch-user_password_expire.sql deleted file mode 100644 index 824cc820..00000000 --- a/maintenance/oracle/archives/patch-user_password_expire.sql +++ /dev/null @@ -1,3 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -ALTER TABLE &mw_prefix.mwuser ADD user_password_expires TIMESTAMP(6) WITH TIME ZONE; diff --git a/maintenance/oracle/archives/patch_16_17_schema_changes.sql b/maintenance/oracle/archives/patch_16_17_schema_changes.sql deleted file mode 100644 index cd99f7cc..00000000 --- a/maintenance/oracle/archives/patch_16_17_schema_changes.sql +++ /dev/null @@ -1,98 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -ALTER TABLE &mw_prefix.archive MODIFY ar_user DEFAULT 0 NOT NULL; -ALTER TABLE &mw_prefix.archive MODIFY ar_deleted CHAR(1); -CREATE INDEX &mw_prefix.archive_i03 ON &mw_prefix.archive (ar_rev_id); - -ALTER TABLE &mw_prefix.page MODIFY page_is_redirect default '0'; -ALTER TABLE &mw_prefix.page MODIFY page_is_new default '0'; -ALTER TABLE &mw_prefix.page MODIFY page_latest default 0; -ALTER TABLE &mw_prefix.page MODIFY page_len default 0; - -ALTER TABLE &mw_prefix.categorylinks MODIFY cl_sortkey VARCHAR2(230); -ALTER TABLE &mw_prefix.categorylinks ADD cl_sortkey_prefix VARCHAR2(255) DEFAULT '' NOT NULL; -ALTER TABLE &mw_prefix.categorylinks ADD cl_collation VARCHAR2(32) DEFAULT '' NOT NULL; -ALTER TABLE &mw_prefix.categorylinks ADD cl_type VARCHAR2(6) DEFAULT 'page' NOT NULL; -DROP INDEX &mw_prefix.categorylinks_i01; -CREATE INDEX &mw_prefix.categorylinks_i01 ON &mw_prefix.categorylinks (cl_to,cl_type,cl_sortkey,cl_from); -CREATE INDEX &mw_prefix.categorylinks_i03 ON &mw_prefix.categorylinks (cl_collation); - -ALTER TABLE &mw_prefix.filearchive MODIFY fa_deleted_user DEFAULT 0 NOT NULL; -ALTER TABLE &mw_prefix.filearchive MODIFY fa_size DEFAULT 0; -ALTER TABLE &mw_prefix.filearchive MODIFY fa_width DEFAULT 0; -ALTER TABLE &mw_prefix.filearchive MODIFY fa_height DEFAULT 0; -ALTER TABLE &mw_prefix.filearchive MODIFY fa_bits DEFAULT 0 NOT NULL; -ALTER TABLE &mw_prefix.filearchive MODIFY fa_user DEFAULT 0 NOT NULL; -ALTER TABLE &mw_prefix.filearchive MODIFY fa_deleted DEFAULT 0; - -ALTER TABLE &mw_prefix.image MODIFY img_size DEFAULT 0; -ALTER TABLE &mw_prefix.image MODIFY img_width DEFAULT 0; -ALTER TABLE &mw_prefix.image MODIFY img_height DEFAULT 0; -ALTER TABLE &mw_prefix.image MODIFY img_bits DEFAULT 0 NOT NULL; -ALTER TABLE &mw_prefix.image MODIFY img_user DEFAULT 0 NOT NULL; - -ALTER TABLE &mw_prefix.interwiki ADD iw_api BLOB DEFAULT EMPTY_BLOB(); -ALTER TABLE &mw_prefix.interwiki MODIFY iw_api DEFAULT NULL NOT NULL; -ALTER TABLE &mw_prefix.interwiki ADD iw_wikiid VARCHAR2(64); - -ALTER TABLE &mw_prefix.ipblocks MODIFY ipb_user DEFAULT 0 NOT NULL; -ALTER TABLE &mw_prefix.ipblocks MODIFY ipb_by DEFAULT 0; - -CREATE TABLE &mw_prefix.iwlinks ( - iwl_from NUMBER DEFAULT 0 NOT NULL, - iwl_prefix VARCHAR2(20) DEFAULT '' NOT NULL, - iwl_title VARCHAR2(255) DEFAULT '' NOT NULL -); -CREATE UNIQUE INDEX &mw_prefix.iwlinks_ui01 ON &mw_prefix.iwlinks (iwl_from, iwl_prefix, iwl_title); -CREATE UNIQUE INDEX &mw_prefix.iwlinks_ui02 ON &mw_prefix.iwlinks (iwl_prefix, iwl_title, iwl_from); - -ALTER TABLE &mw_prefix.logging MODIFY log_user DEFAULT 0 NOT NULL; -ALTER TABLE &mw_prefix.logging MODIFY log_deleted CHAR(1); - -CREATE TABLE &mw_prefix.module_deps ( - md_module VARCHAR2(255) NOT NULL, - md_skin VARCHAR2(32) NOT NULL, - md_deps BLOB NOT NULL -); -CREATE UNIQUE INDEX &mw_prefix.module_deps_u01 ON &mw_prefix.module_deps (md_module, md_skin); - -CREATE TABLE &mw_prefix.msg_resource_links ( - mrl_resource VARCHAR2(255) NOT NULL, - mrl_message VARCHAR2(255) NOT NULL -); -CREATE UNIQUE INDEX &mw_prefix.msg_resource_links_u01 ON &mw_prefix.msg_resource_links (mrl_message, mrl_resource); - -CREATE TABLE &mw_prefix.msg_resource ( - mr_resource VARCHAR2(255) NOT NULL, - mr_lang varchar2(32) NOT NULL, - mr_blob BLOB NOT NULL, - mr_timestamp TIMESTAMP(6) WITH TIME ZONE NOT NULL -); -CREATE UNIQUE INDEX &mw_prefix.msg_resource_u01 ON &mw_prefix.msg_resource (mr_resource, mr_lang); - -ALTER TABLE &mw_prefix.oldimage MODIFY oi_name DEFAULT 0; -ALTER TABLE &mw_prefix.oldimage MODIFY oi_size DEFAULT 0; -ALTER TABLE &mw_prefix.oldimage MODIFY oi_width DEFAULT 0; -ALTER TABLE &mw_prefix.oldimage MODIFY oi_height DEFAULT 0; -ALTER TABLE &mw_prefix.oldimage MODIFY oi_bits DEFAULT 0; -ALTER TABLE &mw_prefix.oldimage MODIFY oi_user DEFAULT 0 NOT NULL; - -ALTER TABLE &mw_prefix.querycache MODIFY qc_value DEFAULT 0; - -ALTER TABLE &mw_prefix.recentchanges MODIFY rc_user DEFAULT 0 NOT NULL; -ALTER TABLE &mw_prefix.recentchanges MODIFY rc_cur_id DEFAULT 0 NOT NULL; -ALTER TABLE &mw_prefix.recentchanges MODIFY rc_this_oldid DEFAULT 0; -ALTER TABLE &mw_prefix.recentchanges MODIFY rc_last_oldid DEFAULT 0; -ALTER TABLE &mw_prefix.recentchanges MODIFY rc_moved_to_ns DEFAULT 0 NOT NULL; -ALTER TABLE &mw_prefix.recentchanges MODIFY rc_deleted CHAR(1); -ALTER TABLE &mw_prefix.recentchanges MODIFY rc_logid DEFAULT 0; - -ALTER TABLE &mw_prefix.revision MODIFY rev_page NOT NULL; -ALTER TABLE &mw_prefix.revision MODIFY rev_user DEFAULT 0; - -ALTER TABLE &mw_prefix.updatelog ADD ul_value BLOB; - -ALTER TABLE &mw_prefix.user_groups MODIFY ug_user DEFAULT 0 NOT NULL; - -ALTER TABLE &mw_prefix.user_newtalk MODIFY user_id DEFAULT 0; - diff --git a/maintenance/oracle/archives/patch_create_17_functions.sql b/maintenance/oracle/archives/patch_create_17_functions.sql deleted file mode 100644 index 6c9c9542..00000000 --- a/maintenance/oracle/archives/patch_create_17_functions.sql +++ /dev/null @@ -1,125 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -/*$mw$*/ -CREATE OR REPLACE PROCEDURE duplicate_table(p_tabname IN VARCHAR2, - p_oldprefix IN VARCHAR2, - p_newprefix IN VARCHAR2, - p_temporary IN BOOLEAN) IS - e_table_not_exist EXCEPTION; - PRAGMA EXCEPTION_INIT(e_table_not_exist, -00942); - l_temp_ei_sql VARCHAR2(2000); -BEGIN - BEGIN - EXECUTE IMMEDIATE 'DROP TABLE ' || p_newprefix || p_tabname || - ' CASCADE CONSTRAINTS'; - EXCEPTION - WHEN e_table_not_exist THEN - NULL; - END; - IF (p_temporary) THEN - EXECUTE IMMEDIATE 'CREATE GLOBAL TEMPORARY TABLE ' || p_newprefix || - p_tabname || ' AS SELECT * FROM ' || p_oldprefix || - p_tabname || ' WHERE ROWNUM = 0'; - ELSE - EXECUTE IMMEDIATE 'CREATE TABLE ' || p_newprefix || p_tabname || - ' AS SELECT * FROM ' || p_oldprefix || p_tabname || - ' WHERE ROWNUM = 0'; - END IF; - FOR rc IN (SELECT column_name, data_default - FROM user_tab_columns - WHERE table_name = p_oldprefix || p_tabname - AND data_default IS NOT NULL) LOOP - EXECUTE IMMEDIATE 'ALTER TABLE ' || p_newprefix || p_tabname || - ' MODIFY ' || rc.column_name || ' DEFAULT ' || - SUBSTR(rc.data_default, 1, 2000); - END LOOP; - FOR rc IN (SELECT REPLACE(REPLACE(DBMS_LOB.SUBSTR(DBMS_METADATA.get_ddl('CONSTRAINT', - constraint_name), - 32767, - 1), - USER || '"."' || p_oldprefix, - USER || '"."' || p_newprefix), - '"' || constraint_name || '"', - '"' || p_newprefix || constraint_name || '"') DDLVC2, - constraint_name - FROM user_constraints uc - WHERE table_name = p_oldprefix || p_tabname - AND constraint_type = 'P') LOOP - l_temp_ei_sql := SUBSTR(rc.ddlvc2, 1, INSTR(rc.ddlvc2, 'PCTFREE') - 1); - l_temp_ei_sql := SUBSTR(l_temp_ei_sql, 1, INSTR(l_temp_ei_sql, ')', INSTR(l_temp_ei_sql, 'PRIMARY KEY')+1)+1); - EXECUTE IMMEDIATE l_temp_ei_sql; - END LOOP; - IF (NOT p_temporary) THEN - FOR rc IN (SELECT REPLACE(DBMS_LOB.SUBSTR(DBMS_METADATA.get_ddl('REF_CONSTRAINT', - constraint_name), - 32767, - 1), - USER || '"."' || p_oldprefix, - USER || '"."' || p_newprefix) DDLVC2, - constraint_name - FROM user_constraints uc - WHERE table_name = p_oldprefix || p_tabname - AND constraint_type = 'R') LOOP - EXECUTE IMMEDIATE rc.ddlvc2; - END LOOP; - END IF; - FOR rc IN (SELECT REPLACE(REPLACE(DBMS_LOB.SUBSTR(DBMS_METADATA.get_ddl('INDEX', - index_name), - 32767, - 1), - USER || '"."' || p_oldprefix, - USER || '"."' || p_newprefix), - '"' || index_name || '"', - '"' || p_newprefix || index_name || '"') DDLVC2, - index_name, - index_type - FROM user_indexes ui - WHERE table_name = p_oldprefix || p_tabname - AND index_type NOT IN ('LOB', 'DOMAIN') - AND NOT EXISTS - (SELECT NULL - FROM user_constraints - WHERE table_name = ui.table_name - AND constraint_name = ui.index_name)) LOOP - l_temp_ei_sql := SUBSTR(rc.ddlvc2, 1, INSTR(rc.ddlvc2, 'PCTFREE') - 1); - l_temp_ei_sql := SUBSTR(l_temp_ei_sql, 1, INSTR(l_temp_ei_sql, ')', INSTR(l_temp_ei_sql, '"' || USER || '"."' || p_newprefix || '"')+1)+1); - EXECUTE IMMEDIATE l_temp_ei_sql; - END LOOP; - FOR rc IN (SELECT REPLACE(REPLACE(UPPER(DBMS_LOB.SUBSTR(DBMS_METADATA.get_ddl('TRIGGER', - trigger_name), - 32767, - 1)), - USER || '"."' || p_oldprefix, - USER || '"."' || p_newprefix), - ' ON ' || p_oldprefix || p_tabname, - ' ON ' || p_newprefix || p_tabname) DDLVC2, - trigger_name - FROM user_triggers - WHERE table_name = p_oldprefix || p_tabname) LOOP - l_temp_ei_sql := SUBSTR(rc.ddlvc2, 1, INSTR(rc.ddlvc2, 'ALTER ') - 1); - dbms_output.put_line(l_temp_ei_sql); - EXECUTE IMMEDIATE l_temp_ei_sql; - END LOOP; -END; -/*$mw$*/ - -CREATE OR REPLACE TYPE GET_OUTPUT_TYPE IS TABLE OF VARCHAR2(255); - -/*$mw$*/ -CREATE OR REPLACE FUNCTION GET_OUTPUT_LINES RETURN GET_OUTPUT_TYPE PIPELINED AS - v_line VARCHAR2(255); - v_status INTEGER := 0; -BEGIN - - LOOP - DBMS_OUTPUT.GET_LINE(v_line, v_status); - IF (v_status = 0) THEN RETURN; END IF; - PIPE ROW (v_line); - END LOOP; - RETURN; -EXCEPTION - WHEN OTHERS THEN - RETURN; -END; -/*$mw$*/ - diff --git a/maintenance/oracle/archives/patch_fk_rename_deferred.sql b/maintenance/oracle/archives/patch_fk_rename_deferred.sql deleted file mode 100644 index ca9c997f..00000000 --- a/maintenance/oracle/archives/patch_fk_rename_deferred.sql +++ /dev/null @@ -1,40 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -/*$mw$*/ -BEGIN --- drop all, recreate manual in case anyone was missing - FOR cc1 IN (SELECT uc.table_name, - uc.constraint_name - FROM user_constraints uc - WHERE uc.constraint_type = 'R') LOOP - EXECUTE IMMEDIATE 'ALTER TABLE &mw_prefix.' || cc1.table_name || - ' DROP CONSTRAINT ' || cc1.constraint_name; - END LOOP; -END; -/*$mw$*/ - -ALTER TABLE &mw_prefix.user_groups ADD CONSTRAINT &mw_prefix.user_groups_fk1 FOREIGN KEY (ug_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; -ALTER TABLE &mw_prefix.user_newtalk ADD CONSTRAINT &mw_prefix.user_newtalk_fk1 FOREIGN KEY (user_id) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; -ALTER TABLE &mw_prefix.revision ADD CONSTRAINT &mw_prefix.revision_fk1 FOREIGN KEY (rev_page) REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; -ALTER TABLE &mw_prefix.revision ADD CONSTRAINT &mw_prefix.revision_fk2 FOREIGN KEY (rev_user) REFERENCES &mw_prefix.mwuser(user_id) DEFERRABLE INITIALLY DEFERRED; -ALTER TABLE &mw_prefix.archive ADD CONSTRAINT &mw_prefix.archive_fk1 FOREIGN KEY (ar_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED; -ALTER TABLE &mw_prefix.pagelinks ADD CONSTRAINT &mw_prefix.pagelinks_fk1 FOREIGN KEY (pl_from) REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; -ALTER TABLE &mw_prefix.templatelinks ADD CONSTRAINT &mw_prefix.templatelinks_fk1 FOREIGN KEY (tl_from) REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; -ALTER TABLE &mw_prefix.imagelinks ADD CONSTRAINT &mw_prefix.imagelinks_fk1 FOREIGN KEY (il_from) REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; -ALTER TABLE &mw_prefix.categorylinks ADD CONSTRAINT &mw_prefix.categorylinks_fk1 FOREIGN KEY (cl_from) REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; -ALTER TABLE &mw_prefix.externallinks ADD CONSTRAINT &mw_prefix.externallinks_fk1 FOREIGN KEY (el_from) REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; -ALTER TABLE &mw_prefix.langlinks ADD CONSTRAINT &mw_prefix.langlinks_fk1 FOREIGN KEY (ll_from) REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; -ALTER TABLE &mw_prefix.ipblocks ADD CONSTRAINT &mw_prefix.ipblocks_fk1 FOREIGN KEY (ipb_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED; -ALTER TABLE &mw_prefix.ipblocks ADD CONSTRAINT &mw_prefix.ipblocks_fk2 FOREIGN KEY (ipb_by) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; -ALTER TABLE &mw_prefix.image ADD CONSTRAINT &mw_prefix.image_fk1 FOREIGN KEY (img_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED; -ALTER TABLE &mw_prefix.oldimage ADD CONSTRAINT &mw_prefix.oldimage_fk1 FOREIGN KEY (oi_name) REFERENCES &mw_prefix.image(img_name) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED; -ALTER TABLE &mw_prefix.oldimage ADD CONSTRAINT &mw_prefix.oldimage_fk2 FOREIGN KEY (oi_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED; -ALTER TABLE &mw_prefix.filearchive ADD CONSTRAINT &mw_prefix.filearchive_fk1 FOREIGN KEY (fa_deleted_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED; -ALTER TABLE &mw_prefix.filearchive ADD CONSTRAINT &mw_prefix.filearchive_fk2 FOREIGN KEY (fa_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED; -ALTER TABLE &mw_prefix.recentchanges ADD CONSTRAINT &mw_prefix.recentchanges_fk1 FOREIGN KEY (rc_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED; -ALTER TABLE &mw_prefix.recentchanges ADD CONSTRAINT &mw_prefix.recentchanges_fk2 FOREIGN KEY (rc_cur_id) REFERENCES &mw_prefix.page(page_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED; -ALTER TABLE &mw_prefix.watchlist ADD CONSTRAINT &mw_prefix.watchlist_fk1 FOREIGN KEY (wl_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; -ALTER TABLE &mw_prefix.logging ADD CONSTRAINT &mw_prefix.logging_fk1 FOREIGN KEY (log_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED; -ALTER TABLE &mw_prefix.redirect ADD CONSTRAINT &mw_prefix.redirect_fk1 FOREIGN KEY (rd_from) REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; -ALTER TABLE &mw_prefix.page_restrictions ADD CONSTRAINT &mw_prefix.page_restrictions_fk1 FOREIGN KEY (pr_page) REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; - diff --git a/maintenance/oracle/archives/patch_namespace_defaults.sql b/maintenance/oracle/archives/patch_namespace_defaults.sql deleted file mode 100644 index 24c95643..00000000 --- a/maintenance/oracle/archives/patch_namespace_defaults.sql +++ /dev/null @@ -1,17 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -ALTER TABLE &mw_prefix.page MODIFY page_namespace DEFAULT 0; -ALTER TABLE &mw_prefix.archive MODIFY ar_namespace DEFAULT 0; -ALTER TABLE &mw_prefix.pagelinks MODIFY pl_namespace DEFAULT 0; -ALTER TABLE &mw_prefix.templatelinks MODIFY tl_namespace DEFAULT 0; -ALTER TABLE &mw_prefix.recentchanges MODIFY rc_namespace DEFAULT 0; -ALTER TABLE &mw_prefix.querycache MODIFY qc_namespace DEFAULT 0; -ALTER TABLE &mw_prefix.logging MODIFY log_namespace DEFAULT 0; -ALTER TABLE &mw_prefix.job MODIFY job_namespace DEFAULT 0; -ALTER TABLE &mw_prefix.redirect MODIFY rd_namespace DEFAULT 0; -ALTER TABLE &mw_prefix.protected_titles MODIFY pt_namespace DEFAULT 0; -ALTER TABLE &mw_prefix.archive MODIFY ar_namespace DEFAULT 0; -ALTER TABLE &mw_prefix.archive MODIFY ar_namespace DEFAULT 0; -ALTER TABLE &mw_prefix.archive MODIFY ar_namespace DEFAULT 0; -ALTER TABLE &mw_prefix.archive MODIFY ar_namespace DEFAULT 0; - diff --git a/maintenance/oracle/archives/patch_rebuild_dupfunc.sql b/maintenance/oracle/archives/patch_rebuild_dupfunc.sql deleted file mode 100644 index 56ee5b3e..00000000 --- a/maintenance/oracle/archives/patch_rebuild_dupfunc.sql +++ /dev/null @@ -1,149 +0,0 @@ -/*$mw$*/ -CREATE OR REPLACE PROCEDURE duplicate_table(p_tabname IN VARCHAR2, - p_oldprefix IN VARCHAR2, - p_newprefix IN VARCHAR2, - p_temporary IN BOOLEAN) IS - e_table_not_exist EXCEPTION; - PRAGMA EXCEPTION_INIT(e_table_not_exist, -00942); - l_temp_ei_sql VARCHAR2(2000); - l_temporary BOOLEAN := p_temporary; -BEGIN - BEGIN - EXECUTE IMMEDIATE 'DROP TABLE ' || p_newprefix || p_tabname || - ' CASCADE CONSTRAINTS PURGE'; - EXCEPTION - WHEN e_table_not_exist THEN - NULL; - END; - IF (p_tabname = 'SEARCHINDEX') THEN - l_temporary := FALSE; - END IF; - IF (l_temporary) THEN - EXECUTE IMMEDIATE 'CREATE GLOBAL TEMPORARY TABLE ' || p_newprefix || - p_tabname || - ' ON COMMIT PRESERVE ROWS AS SELECT * FROM ' || - p_oldprefix || p_tabname || ' WHERE ROWNUM = 0'; - ELSE - EXECUTE IMMEDIATE 'CREATE TABLE ' || p_newprefix || p_tabname || - ' AS SELECT * FROM ' || p_oldprefix || p_tabname || - ' WHERE ROWNUM = 0'; - END IF; - FOR rc IN (SELECT column_name, data_default - FROM user_tab_columns - WHERE table_name = p_oldprefix || p_tabname - AND data_default IS NOT NULL) LOOP - EXECUTE IMMEDIATE 'ALTER TABLE ' || p_newprefix || p_tabname || - ' MODIFY ' || rc.column_name || ' DEFAULT ' || - SUBSTR(rc.data_default, 1, 2000); - END LOOP; - FOR rc IN (SELECT REPLACE(REPLACE(DBMS_LOB.SUBSTR(DBMS_METADATA.get_ddl('CONSTRAINT', - constraint_name), - 32767, - 1), - USER || '"."' || p_oldprefix, - USER || '"."' || p_newprefix), - '"' || constraint_name || '"', - '"' || p_newprefix || constraint_name || '"') DDLVC2, - constraint_name - FROM user_constraints uc - WHERE table_name = p_oldprefix || p_tabname - AND constraint_type = 'P') LOOP - l_temp_ei_sql := SUBSTR(rc.ddlvc2, 1, INSTR(rc.ddlvc2, 'PCTFREE') - 1); - l_temp_ei_sql := SUBSTR(l_temp_ei_sql, - 1, - INSTR(l_temp_ei_sql, - ')', - INSTR(l_temp_ei_sql, 'PRIMARY KEY') + 1) + 1); - IF nvl(length(l_temp_ei_sql), 0) > 0 THEN - EXECUTE IMMEDIATE l_temp_ei_sql; - END IF; - END LOOP; - IF (NOT l_temporary) THEN - FOR rc IN (SELECT REPLACE(DBMS_LOB.SUBSTR(DBMS_METADATA.get_ddl('REF_CONSTRAINT', - constraint_name), - 32767, - 1), - USER || '"."' || p_oldprefix, - USER || '"."' || p_newprefix) DDLVC2, - constraint_name - FROM user_constraints uc - WHERE table_name = p_oldprefix || p_tabname - AND constraint_type = 'R') LOOP - IF nvl(length(l_temp_ei_sql), 0) > 0 AND - INSTR(l_temp_ei_sql, 'PRIMARY KEY') = 0 THEN - EXECUTE IMMEDIATE l_temp_ei_sql; - END IF; - END LOOP; - END IF; - FOR rc IN (SELECT REPLACE(REPLACE(DBMS_LOB.SUBSTR(DBMS_METADATA.get_ddl('INDEX', - index_name), - 32767, - 1), - USER || '"."' || p_oldprefix, - USER || '"."' || p_newprefix), - '"' || index_name || '"', - '"' || p_newprefix || index_name || '"') DDLVC2, - index_name, - index_type - FROM user_indexes ui - WHERE table_name = p_oldprefix || p_tabname - AND index_type NOT IN ('LOB', 'DOMAIN') - AND NOT EXISTS - (SELECT NULL - FROM user_constraints - WHERE table_name = ui.table_name - AND constraint_name = ui.index_name)) LOOP - l_temp_ei_sql := SUBSTR(rc.ddlvc2, 1, INSTR(rc.ddlvc2, 'PCTFREE') - 1); - l_temp_ei_sql := SUBSTR(l_temp_ei_sql, - 1, - INSTR(l_temp_ei_sql, - ')', - INSTR(l_temp_ei_sql, - '"' || USER || '"."' || p_newprefix || '"') + 1) + 1); - IF nvl(length(l_temp_ei_sql), 0) > 0 THEN - EXECUTE IMMEDIATE l_temp_ei_sql; - END IF; - END LOOP; - FOR rc IN (SELECT REPLACE(REPLACE(DBMS_LOB.SUBSTR(DBMS_METADATA.get_ddl('INDEX', - index_name), - 32767, - 1), - USER || '"."' || p_oldprefix, - USER || '"."' || p_newprefix), - '"' || index_name || '"', - '"' || p_newprefix || index_name || '"') DDLVC2, - index_name, - index_type - FROM user_indexes ui - WHERE table_name = p_oldprefix || p_tabname - AND index_type = 'DOMAIN' - AND NOT EXISTS - (SELECT NULL - FROM user_constraints - WHERE table_name = ui.table_name - AND constraint_name = ui.index_name)) LOOP - l_temp_ei_sql := rc.ddlvc2; - IF nvl(length(l_temp_ei_sql), 0) > 0 THEN - EXECUTE IMMEDIATE l_temp_ei_sql; - END IF; - END LOOP; - FOR rc IN (SELECT REPLACE(REPLACE(UPPER(DBMS_LOB.SUBSTR(DBMS_METADATA.get_ddl('TRIGGER', - trigger_name), - 32767, - 1)), - USER || '"."' || p_oldprefix, - USER || '"."' || p_newprefix), - ' ON ' || p_oldprefix || p_tabname, - ' ON ' || p_newprefix || p_tabname) DDLVC2, - trigger_name - FROM user_triggers - WHERE table_name = p_oldprefix || p_tabname) LOOP - l_temp_ei_sql := SUBSTR(rc.ddlvc2, 1, INSTR(rc.ddlvc2, 'ALTER ') - 1); - IF nvl(length(l_temp_ei_sql), 0) > 0 THEN - EXECUTE IMMEDIATE l_temp_ei_sql; - END IF; - END LOOP; -END; - -/*$mw$*/ - diff --git a/maintenance/oracle/archives/patch_recentchanges_fk2_cascade.sql b/maintenance/oracle/archives/patch_recentchanges_fk2_cascade.sql deleted file mode 100644 index 45509518..00000000 --- a/maintenance/oracle/archives/patch_recentchanges_fk2_cascade.sql +++ /dev/null @@ -1,5 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -ALTER TABLE &mw_prefix.recentchanges DROP CONSTRAINT &mw_prefix.recentchanges_fk2; -ALTER TABLE &mw_prefix.recentchanges ADD CONSTRAINT &mw_prefix.recentchanges_fk2 FOREIGN KEY (rc_cur_id) REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; - diff --git a/maintenance/oracle/archives/patch_remove_not_null_empty_defs.sql b/maintenance/oracle/archives/patch_remove_not_null_empty_defs.sql deleted file mode 100644 index 76e50a0a..00000000 --- a/maintenance/oracle/archives/patch_remove_not_null_empty_defs.sql +++ /dev/null @@ -1,9 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -ALTER TABLE &mw_prefix.categorylinks MODIFY cl_sortkey_prefix DEFAULT NULL NULL; -ALTER TABLE &mw_prefix.categorylinks MODIFY cl_collation DEFAULT NULL NULL; -ALTER TABLE &mw_prefix.iwlinks MODIFY iwl_prefix DEFAULT NULL NULL; -ALTER TABLE &mw_prefix.iwlinks MODIFY iwl_title DEFAULT NULL NULL; -ALTER TABLE &mw_prefix.searchindex MODIFY si_title DEFAULT NULL NULL; -ALTER TABLE &mw_prefix.querycachetwo MODIFY qcc_title DEFAULT NULL NULL; -ALTER TABLE &mw_prefix.querycachetwo MODIFY qcc_titletwo DEFAULT NULL NULL; diff --git a/maintenance/oracle/archives/patch_remove_not_null_empty_defs2.sql b/maintenance/oracle/archives/patch_remove_not_null_empty_defs2.sql deleted file mode 100644 index f7a38a05..00000000 --- a/maintenance/oracle/archives/patch_remove_not_null_empty_defs2.sql +++ /dev/null @@ -1,3 +0,0 @@ -define mw_prefix='{$wgDBprefix}'; - -ALTER TABLE &mw_prefix.ipblocks MODIFY ipb_by_text DEFAULT NULL NULL; diff --git a/maintenance/oracle/patch_seq_names_pre1.16.sql b/maintenance/oracle/patch_seq_names_pre1.16.sql deleted file mode 100644 index 5346b141..00000000 --- a/maintenance/oracle/patch_seq_names_pre1.16.sql +++ /dev/null @@ -1,8 +0,0 @@ --- script for renameing sequence names to conform with __seq format -RENAME rev_rev_id_val TO revision_rev_id_seq; -RENAME text_old_id_val TO text_old_id_seq; -RENAME category_id_seq TO category_cat_id_seq; -RENAME ipblocks_ipb_id_val TO ipblocks_ipb_id_seq; -RENAME rc_rc_id_seq TO recentchanges_rc_id_seq; -RENAME log_log_id_seq TO logging_log_id_seq; -RENAME pr_id_val TO page_restrictions_pr_id_seq; \ No newline at end of file diff --git a/maintenance/oracle/tables.sql b/maintenance/oracle/tables.sql deleted file mode 100644 index 12f6518a..00000000 --- a/maintenance/oracle/tables.sql +++ /dev/null @@ -1,971 +0,0 @@ --- defines must comply with ^define\s*([^\s=]*)\s*=\s?'\{\$([^\}]*)\}'; -define mw_prefix='{$wgDBprefix}'; - - -CREATE SEQUENCE user_user_id_seq; -CREATE TABLE &mw_prefix.mwuser ( -- replace reserved word 'user' - user_id NUMBER NOT NULL, - user_name VARCHAR2(255) NOT NULL, - user_real_name VARCHAR2(512), - user_password VARCHAR2(255), - user_newpassword VARCHAR2(255), - user_newpass_time TIMESTAMP(6) WITH TIME ZONE, - user_token VARCHAR2(32), - user_email VARCHAR2(255), - user_email_token VARCHAR2(32), - user_email_token_expires TIMESTAMP(6) WITH TIME ZONE, - user_email_authenticated TIMESTAMP(6) WITH TIME ZONE, - user_options CLOB, - user_touched TIMESTAMP(6) WITH TIME ZONE, - user_registration TIMESTAMP(6) WITH TIME ZONE, - user_editcount NUMBER, - user_password_expires TIMESTAMP(6) WITH TIME ZONE -); -ALTER TABLE &mw_prefix.mwuser ADD CONSTRAINT &mw_prefix.mwuser_pk PRIMARY KEY (user_id); -CREATE UNIQUE INDEX &mw_prefix.mwuser_u01 ON &mw_prefix.mwuser (user_name); -CREATE INDEX &mw_prefix.mwuser_i01 ON &mw_prefix.mwuser (user_email_token); -CREATE INDEX &mw_prefix.mwuser_i02 ON &mw_prefix.mwuser (user_email, user_name); - --- Create a dummy user to satisfy fk contraints especially with revisions -INSERT INTO &mw_prefix.mwuser - (user_id, user_name, user_options, user_touched, user_registration, user_editcount) - VALUES (0,'Anonymous','', current_timestamp, current_timestamp,0); - -CREATE TABLE &mw_prefix.user_groups ( - ug_user NUMBER DEFAULT 0 NOT NULL, - ug_group VARCHAR2(255) NOT NULL -); -ALTER TABLE &mw_prefix.user_groups ADD CONSTRAINT &mw_prefix.user_groups_fk1 FOREIGN KEY (ug_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; -CREATE UNIQUE INDEX &mw_prefix.user_groups_u01 ON &mw_prefix.user_groups (ug_user,ug_group); -CREATE INDEX &mw_prefix.user_groups_i01 ON &mw_prefix.user_groups (ug_group); - -CREATE TABLE &mw_prefix.user_former_groups ( - ufg_user NUMBER DEFAULT 0 NOT NULL, - ufg_group VARCHAR2(255) NOT NULL -); -ALTER TABLE &mw_prefix.user_former_groups ADD CONSTRAINT &mw_prefix.user_former_groups_fk1 FOREIGN KEY (ufg_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; -CREATE UNIQUE INDEX &mw_prefix.user_former_groups_u01 ON &mw_prefix.user_former_groups (ufg_user,ufg_group); - -CREATE TABLE &mw_prefix.user_newtalk ( - user_id NUMBER DEFAULT 0 NOT NULL, - user_ip VARCHAR2(40) NULL, - user_last_timestamp TIMESTAMP(6) WITH TIME ZONE -); -ALTER TABLE &mw_prefix.user_newtalk ADD CONSTRAINT &mw_prefix.user_newtalk_fk1 FOREIGN KEY (user_id) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; -CREATE INDEX &mw_prefix.user_newtalk_i01 ON &mw_prefix.user_newtalk (user_id); -CREATE INDEX &mw_prefix.user_newtalk_i02 ON &mw_prefix.user_newtalk (user_ip); - -CREATE TABLE &mw_prefix.user_properties ( - up_user NUMBER NOT NULL, - up_property VARCHAR2(255) NOT NULL, - up_value CLOB -); -CREATE UNIQUE INDEX &mw_prefix.user_properties_u01 on &mw_prefix.user_properties (up_user,up_property); -CREATE INDEX &mw_prefix.user_properties_i01 on &mw_prefix.user_properties (up_property); - -CREATE SEQUENCE page_page_id_seq; -CREATE TABLE &mw_prefix.page ( - page_id NUMBER NOT NULL, - page_namespace NUMBER DEFAULT 0 NOT NULL, - page_title VARCHAR2(255) NOT NULL, - page_restrictions VARCHAR2(255), - page_is_redirect CHAR(1) DEFAULT '0' NOT NULL, - page_is_new CHAR(1) DEFAULT '0' NOT NULL, - page_random NUMBER(15,14) NOT NULL, - page_touched TIMESTAMP(6) WITH TIME ZONE, - page_links_updated TIMESTAMP(6) WITH TIME ZONE, - page_latest NUMBER DEFAULT 0 NOT NULL, -- FK? - page_len NUMBER DEFAULT 0 NOT NULL, - page_content_model VARCHAR2(32), - page_lang VARCHAR2(35) DEFAULT NULL -); -ALTER TABLE &mw_prefix.page ADD CONSTRAINT &mw_prefix.page_pk PRIMARY KEY (page_id); -CREATE UNIQUE INDEX &mw_prefix.page_u01 ON &mw_prefix.page (page_namespace,page_title); -CREATE INDEX &mw_prefix.page_i01 ON &mw_prefix.page (page_random); -CREATE INDEX &mw_prefix.page_i02 ON &mw_prefix.page (page_len); -CREATE INDEX &mw_prefix.page_i03 ON &mw_prefix.page (page_is_redirect, page_namespace, page_len); - --- Create a dummy page to satisfy fk contraints especially with revisions -INSERT INTO &mw_prefix.page - VALUES (0, 0, ' ', NULL, 0, 0, 0, 0, current_timestamp, NULL, 0, 0, NULL, NULL); - -/*$mw$*/ -CREATE TRIGGER &mw_prefix.page_set_random BEFORE INSERT ON &mw_prefix.page - FOR EACH ROW WHEN (new.page_random IS NULL) -BEGIN - SELECT dbms_random.value INTO :NEW.page_random FROM dual; -END; -/*$mw$*/ - -CREATE SEQUENCE revision_rev_id_seq; -CREATE TABLE &mw_prefix.revision ( - rev_id NUMBER NOT NULL, - rev_page NUMBER NOT NULL, - rev_text_id NUMBER NULL, - rev_comment VARCHAR2(255), - rev_user NUMBER DEFAULT 0 NOT NULL, - rev_user_text VARCHAR2(255) NOT NULL, - rev_timestamp TIMESTAMP(6) WITH TIME ZONE NOT NULL, - rev_minor_edit CHAR(1) DEFAULT '0' NOT NULL, - rev_deleted CHAR(1) DEFAULT '0' NOT NULL, - rev_len NUMBER NULL, - rev_parent_id NUMBER DEFAULT NULL, - rev_sha1 VARCHAR2(32) NULL, - rev_content_model VARCHAR2(32), - rev_content_format VARCHAR2(64) -); -ALTER TABLE &mw_prefix.revision ADD CONSTRAINT &mw_prefix.revision_pk PRIMARY KEY (rev_id); -ALTER TABLE &mw_prefix.revision ADD CONSTRAINT &mw_prefix.revision_fk1 FOREIGN KEY (rev_page) REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; -ALTER TABLE &mw_prefix.revision ADD CONSTRAINT &mw_prefix.revision_fk2 FOREIGN KEY (rev_user) REFERENCES &mw_prefix.mwuser(user_id) DEFERRABLE INITIALLY DEFERRED; -CREATE UNIQUE INDEX &mw_prefix.revision_u01 ON &mw_prefix.revision (rev_page, rev_id); -CREATE INDEX &mw_prefix.revision_i01 ON &mw_prefix.revision (rev_timestamp); -CREATE INDEX &mw_prefix.revision_i02 ON &mw_prefix.revision (rev_page,rev_timestamp); -CREATE INDEX &mw_prefix.revision_i03 ON &mw_prefix.revision (rev_user,rev_timestamp); -CREATE INDEX &mw_prefix.revision_i04 ON &mw_prefix.revision (rev_user_text,rev_timestamp); -CREATE INDEX &mw_prefix.revision_i05 ON &mw_prefix.revision (rev_page,rev_user,rev_timestamp); - -CREATE SEQUENCE text_old_id_seq; -CREATE TABLE &mw_prefix.pagecontent ( -- replaces reserved word 'text' - old_id NUMBER NOT NULL, - old_text CLOB, - old_flags VARCHAR2(255) -); -ALTER TABLE &mw_prefix.pagecontent ADD CONSTRAINT &mw_prefix.pagecontent_pk PRIMARY KEY (old_id); - -CREATE SEQUENCE archive_ar_id_seq; -CREATE TABLE &mw_prefix.archive ( - ar_id NUMBER NOT NULL, - ar_namespace NUMBER DEFAULT 0 NOT NULL, - ar_title VARCHAR2(255) NOT NULL, - ar_text CLOB, - ar_comment VARCHAR2(255), - ar_user NUMBER DEFAULT 0 NOT NULL, - ar_user_text VARCHAR2(255) NOT NULL, - ar_timestamp TIMESTAMP(6) WITH TIME ZONE NOT NULL, - ar_minor_edit CHAR(1) DEFAULT '0' NOT NULL, - ar_flags VARCHAR2(255), - ar_rev_id NUMBER, - ar_text_id NUMBER, - ar_deleted CHAR(1) DEFAULT '0' NOT NULL, - ar_len NUMBER, - ar_page_id NUMBER, - ar_parent_id NUMBER, - ar_sha1 VARCHAR2(32), - ar_content_model VARCHAR2(32), - ar_content_format VARCHAR2(64) -); -ALTER TABLE &mw_prefix.archive ADD CONSTRAINT &mw_prefix.archive_pk PRIMARY KEY (ar_id); -ALTER TABLE &mw_prefix.archive ADD CONSTRAINT &mw_prefix.archive_fk1 FOREIGN KEY (ar_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED; -CREATE INDEX &mw_prefix.archive_i01 ON &mw_prefix.archive (ar_namespace,ar_title,ar_timestamp); -CREATE INDEX &mw_prefix.archive_i02 ON &mw_prefix.archive (ar_user_text,ar_timestamp); -CREATE INDEX &mw_prefix.archive_i03 ON &mw_prefix.archive (ar_rev_id); - -CREATE TABLE &mw_prefix.pagelinks ( - pl_from NUMBER NOT NULL, - pl_namespace NUMBER DEFAULT 0 NOT NULL, - pl_title VARCHAR2(255) NOT NULL -); -ALTER TABLE &mw_prefix.pagelinks ADD CONSTRAINT &mw_prefix.pagelinks_fk1 FOREIGN KEY (pl_from) REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; -CREATE UNIQUE INDEX &mw_prefix.pagelinks_u01 ON &mw_prefix.pagelinks (pl_from,pl_namespace,pl_title); -CREATE UNIQUE INDEX &mw_prefix.pagelinks_u02 ON &mw_prefix.pagelinks (pl_namespace,pl_title,pl_from); - -CREATE TABLE &mw_prefix.templatelinks ( - tl_from NUMBER NOT NULL, - tl_namespace NUMBER DEFAULT 0 NOT NULL, - tl_title VARCHAR2(255) NOT NULL -); -ALTER TABLE &mw_prefix.templatelinks ADD CONSTRAINT &mw_prefix.templatelinks_fk1 FOREIGN KEY (tl_from) REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; -CREATE UNIQUE INDEX &mw_prefix.templatelinks_u01 ON &mw_prefix.templatelinks (tl_from,tl_namespace,tl_title); -CREATE UNIQUE INDEX &mw_prefix.templatelinks_u02 ON &mw_prefix.templatelinks (tl_namespace,tl_title,tl_from); - -CREATE TABLE &mw_prefix.imagelinks ( - il_from NUMBER NOT NULL, - il_to VARCHAR2(255) NOT NULL -); -ALTER TABLE &mw_prefix.imagelinks ADD CONSTRAINT &mw_prefix.imagelinks_fk1 FOREIGN KEY (il_from) REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; -CREATE UNIQUE INDEX &mw_prefix.imagelinks_u01 ON &mw_prefix.imagelinks (il_from,il_to); -CREATE UNIQUE INDEX &mw_prefix.imagelinks_u02 ON &mw_prefix.imagelinks (il_to,il_from); - - -CREATE TABLE &mw_prefix.categorylinks ( - cl_from NUMBER NOT NULL, - cl_to VARCHAR2(255) NOT NULL, - cl_sortkey VARCHAR2(230), - cl_sortkey_prefix VARCHAR2(255), - cl_timestamp TIMESTAMP(6) WITH TIME ZONE NOT NULL, - cl_collation VARCHAR2(32), - cl_type VARCHAR2(6) DEFAULT 'page' NOT NULL -); -ALTER TABLE &mw_prefix.categorylinks ADD CONSTRAINT &mw_prefix.categorylinks_fk1 FOREIGN KEY (cl_from) REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; -CREATE UNIQUE INDEX &mw_prefix.categorylinks_u01 ON &mw_prefix.categorylinks (cl_from,cl_to); -CREATE INDEX &mw_prefix.categorylinks_i01 ON &mw_prefix.categorylinks (cl_to,cl_type,cl_sortkey,cl_from); -CREATE INDEX &mw_prefix.categorylinks_i02 ON &mw_prefix.categorylinks (cl_to,cl_timestamp); -CREATE INDEX &mw_prefix.categorylinks_i03 ON &mw_prefix.categorylinks (cl_collation); - -CREATE SEQUENCE category_cat_id_seq; -CREATE TABLE &mw_prefix.category ( - cat_id NUMBER NOT NULL, - cat_title VARCHAR2(255) NOT NULL, - cat_pages NUMBER DEFAULT 0 NOT NULL, - cat_subcats NUMBER DEFAULT 0 NOT NULL, - cat_files NUMBER DEFAULT 0 NOT NULL -); -ALTER TABLE &mw_prefix.category ADD CONSTRAINT &mw_prefix.category_pk PRIMARY KEY (cat_id); -CREATE UNIQUE INDEX &mw_prefix.category_u01 ON &mw_prefix.category (cat_title); -CREATE INDEX &mw_prefix.category_i01 ON &mw_prefix.category (cat_pages); - -CREATE SEQUENCE externallinks_el_id_seq; -CREATE TABLE &mw_prefix.externallinks ( - el_id NUMBER NOT NULL, - el_from NUMBER NOT NULL, - el_to VARCHAR2(2048) NOT NULL, - el_index VARCHAR2(2048) NOT NULL -); -ALTER TABLE &mw_prefix.externallinks ADD CONSTRAINT &mw_prefix.externallinks_pk PRIMARY KEY (el_id); -ALTER TABLE &mw_prefix.externallinks ADD CONSTRAINT &mw_prefix.externallinks_fk1 FOREIGN KEY (el_from) REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; -CREATE INDEX &mw_prefix.externallinks_i01 ON &mw_prefix.externallinks (el_from, el_to); -CREATE INDEX &mw_prefix.externallinks_i02 ON &mw_prefix.externallinks (el_to, el_from); -CREATE INDEX &mw_prefix.externallinks_i03 ON &mw_prefix.externallinks (el_index); - -CREATE TABLE &mw_prefix.langlinks ( - ll_from NUMBER NOT NULL, - ll_lang VARCHAR2(20), - ll_title VARCHAR2(255) -); -ALTER TABLE &mw_prefix.langlinks ADD CONSTRAINT &mw_prefix.langlinks_fk1 FOREIGN KEY (ll_from) REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; -CREATE UNIQUE INDEX &mw_prefix.langlinks_u01 ON &mw_prefix.langlinks (ll_from, ll_lang); -CREATE INDEX &mw_prefix.langlinks_i01 ON &mw_prefix.langlinks (ll_lang, ll_title); - -CREATE TABLE &mw_prefix.iwlinks ( - iwl_from NUMBER DEFAULT 0 NOT NULL, - iwl_prefix VARCHAR2(20), - iwl_title VARCHAR2(255) -); -CREATE UNIQUE INDEX &mw_prefix.iwlinks_ui01 ON &mw_prefix.iwlinks (iwl_from, iwl_prefix, iwl_title); -CREATE UNIQUE INDEX &mw_prefix.iwlinks_ui02 ON &mw_prefix.iwlinks (iwl_prefix, iwl_title, iwl_from); - -CREATE TABLE &mw_prefix.site_stats ( - ss_row_id NUMBER NOT NULL , - ss_total_edits NUMBER DEFAULT 0, - ss_good_articles NUMBER DEFAULT 0, - ss_total_pages NUMBER DEFAULT -1, - ss_users NUMBER DEFAULT -1, - ss_active_users NUMBER DEFAULT -1, - ss_images NUMBER DEFAULT 0 -); -CREATE UNIQUE INDEX &mw_prefix.site_stats_u01 ON &mw_prefix.site_stats (ss_row_id); - -CREATE SEQUENCE ipblocks_ipb_id_seq; -CREATE TABLE &mw_prefix.ipblocks ( - ipb_id NUMBER NOT NULL, - ipb_address VARCHAR2(255) NULL, - ipb_user NUMBER DEFAULT 0 NOT NULL, - ipb_by NUMBER DEFAULT 0 NOT NULL, - ipb_by_text VARCHAR2(255) NULL, - ipb_reason VARCHAR2(255) NOT NULL, - ipb_timestamp TIMESTAMP(6) WITH TIME ZONE NOT NULL, - ipb_auto CHAR(1) DEFAULT '0' NOT NULL, - ipb_anon_only CHAR(1) DEFAULT '0' NOT NULL, - ipb_create_account CHAR(1) DEFAULT '1' NOT NULL, - ipb_enable_autoblock CHAR(1) DEFAULT '1' NOT NULL, - ipb_expiry TIMESTAMP(6) WITH TIME ZONE NOT NULL, - ipb_range_start VARCHAR2(255), - ipb_range_end VARCHAR2(255), - ipb_deleted CHAR(1) DEFAULT '0' NOT NULL, - ipb_block_email CHAR(1) DEFAULT '0' NOT NULL, - ipb_allow_usertalk CHAR(1) DEFAULT '0' NOT NULL, - ipb_parent_block_id NUMBER DEFAULT NULL -); -ALTER TABLE &mw_prefix.ipblocks ADD CONSTRAINT &mw_prefix.ipblocks_pk PRIMARY KEY (ipb_id); -ALTER TABLE &mw_prefix.ipblocks ADD CONSTRAINT &mw_prefix.ipblocks_fk1 FOREIGN KEY (ipb_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED; -ALTER TABLE &mw_prefix.ipblocks ADD CONSTRAINT &mw_prefix.ipblocks_fk2 FOREIGN KEY (ipb_by) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; -CREATE UNIQUE INDEX &mw_prefix.ipblocks_u01 ON &mw_prefix.ipblocks (ipb_address, ipb_user, ipb_auto, ipb_anon_only); -CREATE INDEX &mw_prefix.ipblocks_i01 ON &mw_prefix.ipblocks (ipb_user); -CREATE INDEX &mw_prefix.ipblocks_i02 ON &mw_prefix.ipblocks (ipb_range_start, ipb_range_end); -CREATE INDEX &mw_prefix.ipblocks_i03 ON &mw_prefix.ipblocks (ipb_timestamp); -CREATE INDEX &mw_prefix.ipblocks_i04 ON &mw_prefix.ipblocks (ipb_expiry); -CREATE INDEX &mw_prefix.ipblocks_i05 ON &mw_prefix.ipblocks (ipb_parent_block_id); - -CREATE TABLE &mw_prefix.image ( - img_name VARCHAR2(255) NOT NULL, - img_size NUMBER DEFAULT 0 NOT NULL, - img_width NUMBER DEFAULT 0 NOT NULL, - img_height NUMBER DEFAULT 0 NOT NULL, - img_metadata CLOB, - img_bits NUMBER DEFAULT 0 NOT NULL, - img_media_type VARCHAR2(32), - img_major_mime VARCHAR2(32) DEFAULT 'unknown', - img_minor_mime VARCHAR2(100) DEFAULT 'unknown', - img_description VARCHAR2(255), - img_user NUMBER DEFAULT 0 NOT NULL, - img_user_text VARCHAR2(255) NOT NULL, - img_timestamp TIMESTAMP(6) WITH TIME ZONE, - img_sha1 VARCHAR2(32) -); -ALTER TABLE &mw_prefix.image ADD CONSTRAINT &mw_prefix.image_pk PRIMARY KEY (img_name); -ALTER TABLE &mw_prefix.image ADD CONSTRAINT &mw_prefix.image_fk1 FOREIGN KEY (img_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED; -CREATE INDEX &mw_prefix.image_i01 ON &mw_prefix.image (img_user_text,img_timestamp); -CREATE INDEX &mw_prefix.image_i02 ON &mw_prefix.image (img_size); -CREATE INDEX &mw_prefix.image_i03 ON &mw_prefix.image (img_timestamp); -CREATE INDEX &mw_prefix.image_i04 ON &mw_prefix.image (img_sha1); - - -CREATE TABLE &mw_prefix.oldimage ( - oi_name VARCHAR2(255) DEFAULT 0 NOT NULL, - oi_archive_name VARCHAR2(255), - oi_size NUMBER DEFAULT 0 NOT NULL, - oi_width NUMBER DEFAULT 0 NOT NULL, - oi_height NUMBER DEFAULT 0 NOT NULL, - oi_bits NUMBER DEFAULT 0 NOT NULL, - oi_description VARCHAR2(255), - oi_user NUMBER DEFAULT 0 NOT NULL, - oi_user_text VARCHAR2(255) NOT NULL, - oi_timestamp TIMESTAMP(6) WITH TIME ZONE NOT NULL, - oi_metadata CLOB, - oi_media_type VARCHAR2(32) DEFAULT NULL, - oi_major_mime VARCHAR2(32) DEFAULT 'unknown', - oi_minor_mime VARCHAR2(100) DEFAULT 'unknown', - oi_deleted NUMBER DEFAULT 0 NOT NULL, - oi_sha1 VARCHAR2(32) -); -ALTER TABLE &mw_prefix.oldimage ADD CONSTRAINT &mw_prefix.oldimage_fk1 FOREIGN KEY (oi_name) REFERENCES &mw_prefix.image(img_name) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED; -ALTER TABLE &mw_prefix.oldimage ADD CONSTRAINT &mw_prefix.oldimage_fk2 FOREIGN KEY (oi_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED; -CREATE INDEX &mw_prefix.oldimage_i01 ON &mw_prefix.oldimage (oi_user_text,oi_timestamp); -CREATE INDEX &mw_prefix.oldimage_i02 ON &mw_prefix.oldimage (oi_name,oi_timestamp); -CREATE INDEX &mw_prefix.oldimage_i03 ON &mw_prefix.oldimage (oi_name,oi_archive_name); -CREATE INDEX &mw_prefix.oldimage_i04 ON &mw_prefix.oldimage (oi_sha1); - - -CREATE SEQUENCE filearchive_fa_id_seq; -CREATE TABLE &mw_prefix.filearchive ( - fa_id NUMBER NOT NULL, - fa_name VARCHAR2(255) NOT NULL, - fa_archive_name VARCHAR2(255), - fa_storage_group VARCHAR2(16), - fa_storage_key VARCHAR2(64), - fa_deleted_user NUMBER DEFAULT 0 NOT NULL, - fa_deleted_timestamp TIMESTAMP(6) WITH TIME ZONE NOT NULL, - fa_deleted_reason CLOB, - fa_size NUMBER DEFAULT 0 NOT NULL, - fa_width NUMBER DEFAULT 0 NOT NULL, - fa_height NUMBER DEFAULT 0 NOT NULL, - fa_metadata CLOB, - fa_bits NUMBER DEFAULT 0 NOT NULL, - fa_media_type VARCHAR2(32) DEFAULT NULL, - fa_major_mime VARCHAR2(32) DEFAULT 'unknown', - fa_minor_mime VARCHAR2(100) DEFAULT 'unknown', - fa_description VARCHAR2(255), - fa_user NUMBER DEFAULT 0 NOT NULL, - fa_user_text VARCHAR2(255) NOT NULL, - fa_timestamp TIMESTAMP(6) WITH TIME ZONE, - fa_deleted NUMBER DEFAULT 0 NOT NULL, - fa_sha1 VARCHAR2(32) -); -ALTER TABLE &mw_prefix.filearchive ADD CONSTRAINT &mw_prefix.filearchive_pk PRIMARY KEY (fa_id); -ALTER TABLE &mw_prefix.filearchive ADD CONSTRAINT &mw_prefix.filearchive_fk1 FOREIGN KEY (fa_deleted_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED; -ALTER TABLE &mw_prefix.filearchive ADD CONSTRAINT &mw_prefix.filearchive_fk2 FOREIGN KEY (fa_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED; -CREATE INDEX &mw_prefix.filearchive_i01 ON &mw_prefix.filearchive (fa_name, fa_timestamp); -CREATE INDEX &mw_prefix.filearchive_i02 ON &mw_prefix.filearchive (fa_storage_group, fa_storage_key); -CREATE INDEX &mw_prefix.filearchive_i03 ON &mw_prefix.filearchive (fa_deleted_timestamp); -CREATE INDEX &mw_prefix.filearchive_i04 ON &mw_prefix.filearchive (fa_user_text,fa_timestamp); -CREATE INDEX &mw_prefix.filearchive_i05 ON &mw_prefix.filearchive (fa_sha1); - -CREATE SEQUENCE uploadstash_us_id_seq; -CREATE TABLE &mw_prefix.uploadstash ( - us_id NUMBER NOT NULL, - us_user NUMBER DEFAULT 0 NOT NULL, - us_key VARCHAR2(255) NOT NULL, - us_orig_path VARCHAR2(255) NOT NULL, - us_path VARCHAR2(255) NOT NULL, - us_source_type VARCHAR2(50), - us_timestamp TIMESTAMP(6) WITH TIME ZONE, - us_status VARCHAR2(50) NOT NULL, - us_chunk_inx NUMBER, - us_size NUMBER NOT NULL, - us_sha1 VARCHAR2(32) NOT NULL, - us_mime VARCHAR2(255), - us_media_type VARCHAR2(32) DEFAULT NULL, - us_image_width NUMBER, - us_image_height NUMBER, - us_image_bits NUMBER, - us_props BLOB -); -ALTER TABLE &mw_prefix.uploadstash ADD CONSTRAINT &mw_prefix.uploadstash_pk PRIMARY KEY (us_id); -ALTER TABLE &mw_prefix.uploadstash ADD CONSTRAINT &mw_prefix.uploadstash_fk1 FOREIGN KEY (us_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED; -CREATE INDEX &mw_prefix.uploadstash_i01 ON &mw_prefix.uploadstash (us_user); -CREATE INDEX &mw_prefix.uploadstash_i02 ON &mw_prefix.uploadstash (us_timestamp); -CREATE UNIQUE INDEX &mw_prefix.uploadstash_u01 ON &mw_prefix.uploadstash (us_key); - -CREATE SEQUENCE recentchanges_rc_id_seq; -CREATE TABLE &mw_prefix.recentchanges ( - rc_id NUMBER NOT NULL, - rc_timestamp TIMESTAMP(6) WITH TIME ZONE NOT NULL, - rc_cur_time TIMESTAMP(6) WITH TIME ZONE, - rc_user NUMBER DEFAULT 0 NOT NULL, - rc_user_text VARCHAR2(255) NOT NULL, - rc_namespace NUMBER DEFAULT 0 NOT NULL, - rc_title VARCHAR2(255) NOT NULL, - rc_comment VARCHAR2(255), - rc_minor CHAR(1) DEFAULT '0' NOT NULL, - rc_bot CHAR(1) DEFAULT '0' NOT NULL, - rc_new CHAR(1) DEFAULT '0' NOT NULL, - rc_cur_id NUMBER DEFAULT 0 NOT NULL, - rc_this_oldid NUMBER DEFAULT 0 NOT NULL, - rc_last_oldid NUMBER DEFAULT 0 NOT NULL, - rc_type CHAR(1) DEFAULT '0' NOT NULL, - rc_source VARCHAR2(16), - rc_patrolled CHAR(1) DEFAULT '0' NOT NULL, - rc_ip VARCHAR2(15), - rc_old_len NUMBER, - rc_new_len NUMBER, - rc_deleted CHAR(1) DEFAULT '0' NOT NULL, - rc_logid NUMBER DEFAULT 0 NOT NULL, - rc_log_type VARCHAR2(255), - rc_log_action VARCHAR2(255), - rc_params CLOB -); -ALTER TABLE &mw_prefix.recentchanges ADD CONSTRAINT &mw_prefix.recentchanges_pk PRIMARY KEY (rc_id); -ALTER TABLE &mw_prefix.recentchanges ADD CONSTRAINT &mw_prefix.recentchanges_fk1 FOREIGN KEY (rc_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED; -ALTER TABLE &mw_prefix.recentchanges ADD CONSTRAINT &mw_prefix.recentchanges_fk2 FOREIGN KEY (rc_cur_id) REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; -CREATE INDEX &mw_prefix.recentchanges_i01 ON &mw_prefix.recentchanges (rc_timestamp); -CREATE INDEX &mw_prefix.recentchanges_i02 ON &mw_prefix.recentchanges (rc_namespace, rc_title); -CREATE INDEX &mw_prefix.recentchanges_i03 ON &mw_prefix.recentchanges (rc_cur_id); -CREATE INDEX &mw_prefix.recentchanges_i04 ON &mw_prefix.recentchanges (rc_new,rc_namespace,rc_timestamp); -CREATE INDEX &mw_prefix.recentchanges_i05 ON &mw_prefix.recentchanges (rc_ip); -CREATE INDEX &mw_prefix.recentchanges_i06 ON &mw_prefix.recentchanges (rc_namespace, rc_user_text); -CREATE INDEX &mw_prefix.recentchanges_i07 ON &mw_prefix.recentchanges (rc_user_text, rc_timestamp); - -CREATE TABLE &mw_prefix.watchlist ( - wl_user NUMBER NOT NULL, - wl_namespace NUMBER DEFAULT 0 NOT NULL, - wl_title VARCHAR2(255) NOT NULL, - wl_notificationtimestamp TIMESTAMP(6) WITH TIME ZONE -); -ALTER TABLE &mw_prefix.watchlist ADD CONSTRAINT &mw_prefix.watchlist_fk1 FOREIGN KEY (wl_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; -CREATE UNIQUE INDEX &mw_prefix.watchlist_u01 ON &mw_prefix.watchlist (wl_user, wl_namespace, wl_title); -CREATE INDEX &mw_prefix.watchlist_i01 ON &mw_prefix.watchlist (wl_namespace, wl_title); - - -CREATE TABLE &mw_prefix.searchindex ( - si_page NUMBER NOT NULL, - si_title VARCHAR2(255), - si_text CLOB NOT NULL -); -CREATE UNIQUE INDEX &mw_prefix.searchindex_u01 ON &mw_prefix.searchindex (si_page); - -CREATE TABLE &mw_prefix.interwiki ( - iw_prefix VARCHAR2(32) NOT NULL, - iw_url VARCHAR2(127) NOT NULL, - iw_api BLOB NOT NULL, - iw_wikiid VARCHAR2(64), - iw_local CHAR(1) NOT NULL, - iw_trans CHAR(1) DEFAULT '0' NOT NULL -); -CREATE UNIQUE INDEX &mw_prefix.interwiki_u01 ON &mw_prefix.interwiki (iw_prefix); - -CREATE TABLE &mw_prefix.querycache ( - qc_type VARCHAR2(32) NOT NULL, - qc_value NUMBER DEFAULT 0 NOT NULL, - qc_namespace NUMBER DEFAULT 0 NOT NULL, - qc_title VARCHAR2(255) NOT NULL -); -CREATE INDEX &mw_prefix.querycache_u01 ON &mw_prefix.querycache (qc_type,qc_value); - -CREATE TABLE &mw_prefix.objectcache ( - keyname VARCHAR2(255) , - value BLOB, - exptime TIMESTAMP(6) WITH TIME ZONE NOT NULL -); -CREATE INDEX &mw_prefix.objectcache_i01 ON &mw_prefix.objectcache (exptime); - -CREATE TABLE &mw_prefix.transcache ( - tc_url VARCHAR2(255) NOT NULL, - tc_contents CLOB NOT NULL, - tc_time TIMESTAMP(6) WITH TIME ZONE NOT NULL -); -CREATE UNIQUE INDEX &mw_prefix.transcache_u01 ON &mw_prefix.transcache (tc_url); - - -CREATE SEQUENCE logging_log_id_seq; -CREATE TABLE &mw_prefix.logging ( - log_id NUMBER NOT NULL, - log_type VARCHAR2(10) NOT NULL, - log_action VARCHAR2(10) NOT NULL, - log_timestamp TIMESTAMP(6) WITH TIME ZONE NOT NULL, - log_user NUMBER DEFAULT 0 NOT NULL, - log_user_text VARCHAR2(255), - log_namespace NUMBER DEFAULT 0 NOT NULL, - log_title VARCHAR2(255) NOT NULL, - log_page NUMBER, - log_comment VARCHAR2(255), - log_params CLOB, - log_deleted CHAR(1) DEFAULT '0' NOT NULL -); -ALTER TABLE &mw_prefix.logging ADD CONSTRAINT &mw_prefix.logging_pk PRIMARY KEY (log_id); -ALTER TABLE &mw_prefix.logging ADD CONSTRAINT &mw_prefix.logging_fk1 FOREIGN KEY (log_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED; -CREATE INDEX &mw_prefix.logging_i01 ON &mw_prefix.logging (log_type, log_timestamp); -CREATE INDEX &mw_prefix.logging_i02 ON &mw_prefix.logging (log_user, log_timestamp); -CREATE INDEX &mw_prefix.logging_i03 ON &mw_prefix.logging (log_namespace, log_title, log_timestamp); -CREATE INDEX &mw_prefix.logging_i04 ON &mw_prefix.logging (log_timestamp); -CREATE INDEX &mw_prefix.logging_i05 ON &mw_prefix.logging (log_type, log_action, log_timestamp); -CREATE INDEX &mw_prefix.logging_i06 ON &mw_prefix.logging (log_user_text, log_type, log_timestamp); -CREATE INDEX &mw_prefix.logging_i07 ON &mw_prefix.logging (log_user_text, log_timestamp); - -CREATE TABLE &mw_prefix.log_search ( - ls_field VARCHAR2(32) NOT NULL, - ls_value VARCHAR2(255) NOT NULL, - ls_log_id NuMBER DEFAULT 0 NOT NULL -); -ALTER TABLE &mw_prefix.log_search ADD CONSTRAINT log_search_pk PRIMARY KEY (ls_field,ls_value,ls_log_id); -CREATE INDEX &mw_prefix.log_search_i01 ON &mw_prefix.log_search (ls_log_id); - - -CREATE SEQUENCE job_job_id_seq; -CREATE TABLE &mw_prefix.job ( - job_id NUMBER NOT NULL, - job_cmd VARCHAR2(60) NOT NULL, - job_namespace NUMBER DEFAULT 0 NOT NULL, - job_title VARCHAR2(255) NOT NULL, - job_timestamp TIMESTAMP(6) WITH TIME ZONE NULL, - job_params CLOB NOT NULL, - job_random NUMBER DEFAULT 0 NOT NULL, - job_token VARCHAR2(32), - job_token_timestamp TIMESTAMP(6) WITH TIME ZONE, - job_sha1 VARCHAR2(32), - job_attempts NUMBER DEFAULT 0 NOT NULL -); -ALTER TABLE &mw_prefix.job ADD CONSTRAINT &mw_prefix.job_pk PRIMARY KEY (job_id); -CREATE INDEX &mw_prefix.job_i01 ON &mw_prefix.job (job_cmd, job_namespace, job_title); -CREATE INDEX &mw_prefix.job_i02 ON &mw_prefix.job (job_timestamp); -CREATE INDEX &mw_prefix.job_i03 ON &mw_prefix.job (job_sha1); -CREATE INDEX &mw_prefix.job_i04 ON &mw_prefix.job (job_cmd,job_token,job_random); -CREATE INDEX &mw_prefix.job_i05 ON &mw_prefix.job (job_attempts); - -CREATE TABLE &mw_prefix.querycache_info ( - qci_type VARCHAR2(32) NOT NULL, - qci_timestamp TIMESTAMP(6) WITH TIME ZONE NULL -); -CREATE UNIQUE INDEX &mw_prefix.querycache_info_u01 ON &mw_prefix.querycache_info (qci_type); - -CREATE TABLE &mw_prefix.redirect ( - rd_from NUMBER NOT NULL, - rd_namespace NUMBER DEFAULT 0 NOT NULL, - rd_title VARCHAR2(255) NOT NULL, - rd_interwiki VARCHAR2(32), - rd_fragment VARCHAR2(255) -); -ALTER TABLE &mw_prefix.redirect ADD CONSTRAINT &mw_prefix.redirect_fk1 FOREIGN KEY (rd_from) REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; -CREATE INDEX &mw_prefix.redirect_i01 ON &mw_prefix.redirect (rd_namespace,rd_title,rd_from); - -CREATE TABLE &mw_prefix.querycachetwo ( - qcc_type VARCHAR2(32) NOT NULL, - qcc_value NUMBER DEFAULT 0 NOT NULL, - qcc_namespace NUMBER DEFAULT 0 NOT NULL, - qcc_title VARCHAR2(255), - qcc_namespacetwo NUMBER DEFAULT 0 NOT NULL, - qcc_titletwo VARCHAR2(255) -); -CREATE INDEX &mw_prefix.querycachetwo_i01 ON &mw_prefix.querycachetwo (qcc_type,qcc_value); -CREATE INDEX &mw_prefix.querycachetwo_i02 ON &mw_prefix.querycachetwo (qcc_type,qcc_namespace,qcc_title); -CREATE INDEX &mw_prefix.querycachetwo_i03 ON &mw_prefix.querycachetwo (qcc_type,qcc_namespacetwo,qcc_titletwo); - -CREATE SEQUENCE page_restrictions_pr_id_seq; -CREATE TABLE &mw_prefix.page_restrictions ( - pr_id NUMBER NOT NULL, - pr_page NUMBER NOT NULL, - pr_type VARCHAR2(255) NOT NULL, - pr_level VARCHAR2(255) NOT NULL, - pr_cascade NUMBER NOT NULL, - pr_user NUMBER NULL, - pr_expiry TIMESTAMP(6) WITH TIME ZONE NULL -); -ALTER TABLE &mw_prefix.page_restrictions ADD CONSTRAINT &mw_prefix.page_restrictions_pk PRIMARY KEY (pr_id); -ALTER TABLE &mw_prefix.page_restrictions ADD CONSTRAINT &mw_prefix.page_restrictions_fk1 FOREIGN KEY (pr_page) REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; -CREATE UNIQUE INDEX &mw_prefix.page_restrictions_u01 ON &mw_prefix.page_restrictions (pr_page,pr_type); -CREATE INDEX &mw_prefix.page_restrictions_i01 ON &mw_prefix.page_restrictions (pr_type,pr_level); -CREATE INDEX &mw_prefix.page_restrictions_i02 ON &mw_prefix.page_restrictions (pr_level); -CREATE INDEX &mw_prefix.page_restrictions_i03 ON &mw_prefix.page_restrictions (pr_cascade); - -CREATE TABLE &mw_prefix.protected_titles ( - pt_namespace NUMBER DEFAULT 0 NOT NULL, - pt_title VARCHAR2(255) NOT NULL, - pt_user NUMBER NOT NULL, - pt_reason VARCHAR2(255), - pt_timestamp TIMESTAMP(6) WITH TIME ZONE NOT NULL, - pt_expiry VARCHAR2(14) NOT NULL, - pt_create_perm VARCHAR2(60) NOT NULL -); -CREATE UNIQUE INDEX &mw_prefix.protected_titles_u01 ON &mw_prefix.protected_titles (pt_namespace,pt_title); -CREATE INDEX &mw_prefix.protected_titles_i01 ON &mw_prefix.protected_titles (pt_timestamp); - -CREATE TABLE &mw_prefix.page_props ( - pp_page NUMBER NOT NULL, - pp_propname VARCHAR2(60) NOT NULL, - pp_value BLOB NOT NULL -); -CREATE UNIQUE INDEX &mw_prefix.page_props_u01 ON &mw_prefix.page_props (pp_page,pp_propname); - - -CREATE TABLE &mw_prefix.updatelog ( - ul_key VARCHAR2(255) NOT NULL, - ul_value BLOB -); -ALTER TABLE &mw_prefix.updatelog ADD CONSTRAINT &mw_prefix.updatelog_pk PRIMARY KEY (ul_key); - -CREATE TABLE &mw_prefix.change_tag ( - ct_rc_id NUMBER NULL, - ct_log_id NUMBER NULL, - ct_rev_id NUMBER NULL, - ct_tag VARCHAR2(255) NOT NULL, - ct_params BLOB NULL -); -CREATE UNIQUE INDEX &mw_prefix.change_tag_u01 ON &mw_prefix.change_tag (ct_rc_id,ct_tag); -CREATE UNIQUE INDEX &mw_prefix.change_tag_u02 ON &mw_prefix.change_tag (ct_log_id,ct_tag); -CREATE UNIQUE INDEX &mw_prefix.change_tag_u03 ON &mw_prefix.change_tag (ct_rev_id,ct_tag); -CREATE INDEX &mw_prefix.change_tag_i01 ON &mw_prefix.change_tag (ct_tag,ct_rc_id,ct_rev_id,ct_log_id); - -CREATE TABLE &mw_prefix.tag_summary ( - ts_rc_id NUMBER NULL, - ts_log_id NUMBER NULL, - ts_rev_id NUMBER NULL, - ts_tags BLOB NOT NULL -); -CREATE UNIQUE INDEX &mw_prefix.tag_summary_u01 ON &mw_prefix.tag_summary (ts_rc_id); -CREATE UNIQUE INDEX &mw_prefix.tag_summary_u02 ON &mw_prefix.tag_summary (ts_log_id); -CREATE UNIQUE INDEX &mw_prefix.tag_summary_u03 ON &mw_prefix.tag_summary (ts_rev_id); - -CREATE TABLE &mw_prefix.valid_tag ( - vt_tag VARCHAR2(255) NOT NULL -); -ALTER TABLE &mw_prefix.valid_tag ADD CONSTRAINT &mw_prefix.valid_tag_pk PRIMARY KEY (vt_tag); - --- This table is not used unless profiling is turned on ---CREATE TABLE &mw_prefix.profiling ( --- pf_count NUMBER DEFAULT 0 NOT NULL, --- pf_time NUMBER(18,10) DEFAULT 0 NOT NULL, --- pf_memory NUMBER(18,10) DEFAULT 0 NOT NULL, --- pf_name VARCHAR2(255), --- pf_server VARCHAR2(30) ---); ---CREATE UNIQUE INDEX &mw_prefix.profiling_u01 ON &mw_prefix.profiling (pf_name, pf_server); - -CREATE INDEX &mw_prefix.si_title_idx ON &mw_prefix.searchindex(si_title) INDEXTYPE IS ctxsys.context; -CREATE INDEX &mw_prefix.si_text_idx ON &mw_prefix.searchindex(si_text) INDEXTYPE IS ctxsys.context; - -CREATE TABLE &mw_prefix.l10n_cache ( - lc_lang varchar2(32) NOT NULL, - lc_key varchar2(255) NOT NULL, - lc_value clob NOT NULL -); -CREATE INDEX &mw_prefix.l10n_cache_u01 ON &mw_prefix.l10n_cache (lc_lang, lc_key); - -CREATE TABLE &mw_prefix.msg_resource ( - mr_resource VARCHAR2(255) NOT NULL, - mr_lang varchar2(32) NOT NULL, - mr_blob BLOB NOT NULL, - mr_timestamp TIMESTAMP(6) WITH TIME ZONE NOT NULL -); -CREATE UNIQUE INDEX &mw_prefix.msg_resource_u01 ON &mw_prefix.msg_resource (mr_resource, mr_lang); - -CREATE TABLE &mw_prefix.msg_resource_links ( - mrl_resource VARCHAR2(255) NOT NULL, - mrl_message VARCHAR2(255) NOT NULL -); -CREATE UNIQUE INDEX &mw_prefix.msg_resource_links_u01 ON &mw_prefix.msg_resource_links (mrl_message, mrl_resource); - -CREATE TABLE &mw_prefix.module_deps ( - md_module VARCHAR2(255) NOT NULL, - md_skin VARCHAR2(32) NOT NULL, - md_deps BLOB NOT NULL -); -CREATE UNIQUE INDEX &mw_prefix.module_deps_u01 ON &mw_prefix.module_deps (md_module, md_skin); - -CREATE SEQUENCE sites_site_id_seq MINVALUE 0 START WITH 0; -CREATE TABLE &mw_prefix.sites ( - site_id NUMBER NOT NULL, - site_global_key VARCHAR2(32) NOT NULL, - site_type VARCHAR2(32) NOT NULL, - site_group VARCHAR2(32) NOT NULL, - site_source VARCHAR2(32) NOT NULL, - site_language VARCHAR2(32) NOT NULL, - site_protocol VARCHAR2(32) NOT NULL, - site_domain VARCHAR2(255) NOT NULL, - site_data BLOB NOT NULL, - site_forward NUMBER(1) NOT NULL, - site_config BLOB NOT NULL -); -ALTER TABLE &mw_prefix.sites ADD CONSTRAINT &mw_prefix.sites_pk PRIMARY KEY (site_id); -CREATE UNIQUE INDEX &mw_prefix.sites_u01 ON &mw_prefix.sites (site_global_key); -CREATE INDEX &mw_prefix.sites_i01 ON &mw_prefix.sites (site_type); -CREATE INDEX &mw_prefix.sites_i02 ON &mw_prefix.sites (site_group); -CREATE INDEX &mw_prefix.sites_i03 ON &mw_prefix.sites (site_source); -CREATE INDEX &mw_prefix.sites_i04 ON &mw_prefix.sites (site_language); -CREATE INDEX &mw_prefix.sites_i05 ON &mw_prefix.sites (site_protocol); -CREATE INDEX &mw_prefix.sites_i06 ON &mw_prefix.sites (site_domain); -CREATE INDEX &mw_prefix.sites_i07 ON &mw_prefix.sites (site_forward); - -CREATE TABLE &mw_prefix.site_identifiers ( - si_site NUMBER NOT NULL, - si_type VARCHAR2(32) NOT NULL, - si_key VARCHAR2(32) NOT NULL -); -CREATE UNIQUE INDEX &mw_prefix.site_identifiers_u01 ON &mw_prefix.site_identifiers (si_type, si_key); -CREATE INDEX &mw_prefix.site_identifiers_i01 ON &mw_prefix.site_identifiers (si_site); -CREATE INDEX &mw_prefix.site_identifiers_i02 ON &mw_prefix.site_identifiers (si_key); - --- do not prefix this table as it breaks parserTests -CREATE TABLE wiki_field_info_full ( -table_name VARCHAR2(35) NOT NULL, -column_name VARCHAR2(35) NOT NULL, -data_default VARCHAR2(4000), -data_length NUMBER NOT NULL, -data_type VARCHAR2(106), -not_null CHAR(1) NOT NULL, -prim NUMBER(1), -uniq NUMBER(1), -nonuniq NUMBER(1) -); -ALTER TABLE wiki_field_info_full ADD CONSTRAINT wiki_field_info_full_pk PRIMARY KEY (table_name, column_name); - -/*$mw$*/ -CREATE PROCEDURE fill_wiki_info IS - BEGIN - DELETE wiki_field_info_full; - - FOR x_rec IN (SELECT t.table_name table_name, t.column_name, - t.data_default, t.data_length, t.data_type, - DECODE (t.nullable, 'Y', '1', 'N', '0') not_null, - (SELECT 1 - FROM user_cons_columns ucc, - user_constraints uc - WHERE ucc.table_name = t.table_name - AND ucc.column_name = t.column_name - AND uc.constraint_name = ucc.constraint_name - AND uc.constraint_type = 'P' - AND ROWNUM < 2) prim, - (SELECT 1 - FROM user_ind_columns uic, - user_indexes ui - WHERE uic.table_name = t.table_name - AND uic.column_name = t.column_name - AND ui.index_name = uic.index_name - AND ui.uniqueness = 'UNIQUE' - AND ROWNUM < 2) uniq, - (SELECT 1 - FROM user_ind_columns uic, - user_indexes ui - WHERE uic.table_name = t.table_name - AND uic.column_name = t.column_name - AND ui.index_name = uic.index_name - AND ui.uniqueness = 'NONUNIQUE' - AND ROWNUM < 2) nonuniq - FROM user_tab_columns t, user_tables ut - WHERE ut.table_name = t.table_name) - LOOP - INSERT INTO wiki_field_info_full - (table_name, column_name, - data_default, data_length, - data_type, not_null, prim, - uniq, nonuniq - ) - VALUES (x_rec.table_name, x_rec.column_name, - x_rec.data_default, x_rec.data_length, - x_rec.data_type, x_rec.not_null, x_rec.prim, - x_rec.uniq, x_rec.nonuniq - ); - END LOOP; - COMMIT; -END; -/*$mw$*/ - -/*$mw$*/ -CREATE OR REPLACE PROCEDURE duplicate_table(p_tabname IN VARCHAR2, - p_oldprefix IN VARCHAR2, - p_newprefix IN VARCHAR2, - p_temporary IN BOOLEAN) IS - e_table_not_exist EXCEPTION; - PRAGMA EXCEPTION_INIT(e_table_not_exist, -00942); - l_temp_ei_sql VARCHAR2(2000); - l_temporary BOOLEAN := p_temporary; -BEGIN - BEGIN - EXECUTE IMMEDIATE 'DROP TABLE ' || p_newprefix || p_tabname || - ' CASCADE CONSTRAINTS PURGE'; - EXCEPTION - WHEN e_table_not_exist THEN - NULL; - END; - IF (p_tabname = 'SEARCHINDEX') THEN - l_temporary := FALSE; - END IF; - IF (l_temporary) THEN - EXECUTE IMMEDIATE 'CREATE GLOBAL TEMPORARY TABLE ' || p_newprefix || - p_tabname || - ' ON COMMIT PRESERVE ROWS AS SELECT * FROM ' || - p_oldprefix || p_tabname || ' WHERE ROWNUM = 0'; - ELSE - EXECUTE IMMEDIATE 'CREATE TABLE ' || p_newprefix || p_tabname || - ' AS SELECT * FROM ' || p_oldprefix || p_tabname || - ' WHERE ROWNUM = 0'; - END IF; - FOR rc IN (SELECT column_name, data_default - FROM user_tab_columns - WHERE table_name = p_oldprefix || p_tabname - AND data_default IS NOT NULL) LOOP - EXECUTE IMMEDIATE 'ALTER TABLE ' || p_newprefix || p_tabname || - ' MODIFY ' || rc.column_name || ' DEFAULT ' || - SUBSTR(rc.data_default, 1, 2000); - END LOOP; - FOR rc IN (SELECT REPLACE(REPLACE(DBMS_LOB.SUBSTR(DBMS_METADATA.get_ddl('CONSTRAINT', - constraint_name), - 32767, - 1), - USER || '"."' || p_oldprefix, - USER || '"."' || p_newprefix), - '"' || constraint_name || '"', - '"' || p_newprefix || constraint_name || '"') DDLVC2, - constraint_name - FROM user_constraints uc - WHERE table_name = p_oldprefix || p_tabname - AND constraint_type = 'P') LOOP - l_temp_ei_sql := SUBSTR(rc.ddlvc2, 1, INSTR(rc.ddlvc2, 'PCTFREE') - 1); - l_temp_ei_sql := SUBSTR(l_temp_ei_sql, - 1, - INSTR(l_temp_ei_sql, - ')', - INSTR(l_temp_ei_sql, 'PRIMARY KEY') + 1) + 1); - IF nvl(length(l_temp_ei_sql), 0) > 0 THEN - EXECUTE IMMEDIATE l_temp_ei_sql; - END IF; - END LOOP; - IF (NOT l_temporary) THEN - FOR rc IN (SELECT REPLACE(DBMS_LOB.SUBSTR(DBMS_METADATA.get_ddl('REF_CONSTRAINT', - constraint_name), - 32767, - 1), - USER || '"."' || p_oldprefix, - USER || '"."' || p_newprefix) DDLVC2, - constraint_name - FROM user_constraints uc - WHERE table_name = p_oldprefix || p_tabname - AND constraint_type = 'R') LOOP - IF nvl(length(l_temp_ei_sql), 0) > 0 AND - INSTR(l_temp_ei_sql, 'PRIMARY KEY') = 0 THEN - EXECUTE IMMEDIATE l_temp_ei_sql; - END IF; - END LOOP; - END IF; - FOR rc IN (SELECT REPLACE(REPLACE(DBMS_LOB.SUBSTR(DBMS_METADATA.get_ddl('INDEX', - index_name), - 32767, - 1), - USER || '"."' || p_oldprefix, - USER || '"."' || p_newprefix), - '"' || index_name || '"', - '"' || p_newprefix || index_name || '"') DDLVC2, - index_name, - index_type - FROM user_indexes ui - WHERE table_name = p_oldprefix || p_tabname - AND index_type NOT IN ('LOB', 'DOMAIN') - AND NOT EXISTS - (SELECT NULL - FROM user_constraints - WHERE table_name = ui.table_name - AND constraint_name = ui.index_name)) LOOP - l_temp_ei_sql := SUBSTR(rc.ddlvc2, 1, INSTR(rc.ddlvc2, 'PCTFREE') - 1); - l_temp_ei_sql := SUBSTR(l_temp_ei_sql, - 1, - INSTR(l_temp_ei_sql, - ')', - INSTR(l_temp_ei_sql, - '"' || USER || '"."' || p_newprefix || '"') + 1) + 1); - IF nvl(length(l_temp_ei_sql), 0) > 0 THEN - EXECUTE IMMEDIATE l_temp_ei_sql; - END IF; - END LOOP; - FOR rc IN (SELECT REPLACE(REPLACE(DBMS_LOB.SUBSTR(DBMS_METADATA.get_ddl('INDEX', - index_name), - 32767, - 1), - USER || '"."' || p_oldprefix, - USER || '"."' || p_newprefix), - '"' || index_name || '"', - '"' || p_newprefix || index_name || '"') DDLVC2, - index_name, - index_type - FROM user_indexes ui - WHERE table_name = p_oldprefix || p_tabname - AND index_type = 'DOMAIN' - AND NOT EXISTS - (SELECT NULL - FROM user_constraints - WHERE table_name = ui.table_name - AND constraint_name = ui.index_name)) LOOP - l_temp_ei_sql := rc.ddlvc2; - IF nvl(length(l_temp_ei_sql), 0) > 0 THEN - EXECUTE IMMEDIATE l_temp_ei_sql; - END IF; - END LOOP; - FOR rc IN (SELECT REPLACE(REPLACE(UPPER(DBMS_LOB.SUBSTR(DBMS_METADATA.get_ddl('TRIGGER', - trigger_name), - 32767, - 1)), - USER || '"."' || p_oldprefix, - USER || '"."' || p_newprefix), - ' ON ' || p_oldprefix || p_tabname, - ' ON ' || p_newprefix || p_tabname) DDLVC2, - trigger_name - FROM user_triggers - WHERE table_name = p_oldprefix || p_tabname) LOOP - l_temp_ei_sql := SUBSTR(rc.ddlvc2, 1, INSTR(rc.ddlvc2, 'ALTER ') - 1); - IF nvl(length(l_temp_ei_sql), 0) > 0 THEN - EXECUTE IMMEDIATE l_temp_ei_sql; - END IF; - END LOOP; -END; - -/*$mw$*/ - -/*$mw$*/ -CREATE OR REPLACE FUNCTION BITOR (x IN NUMBER, y IN NUMBER) RETURN NUMBER AS -BEGIN - RETURN (x + y - BITAND(x, y)); -END; -/*$mw$*/ - -/*$mw$*/ -CREATE OR REPLACE FUNCTION BITNOT (x IN NUMBER) RETURN NUMBER AS -BEGIN - RETURN (4294967295 - x); -END; -/*$mw$*/ - -CREATE OR REPLACE TYPE GET_OUTPUT_TYPE IS TABLE OF VARCHAR2(255); - -/*$mw$*/ -CREATE OR REPLACE FUNCTION GET_OUTPUT_LINES RETURN GET_OUTPUT_TYPE PIPELINED AS - v_line VARCHAR2(255); - v_status INTEGER := 0; -BEGIN - - LOOP - DBMS_OUTPUT.GET_LINE(v_line, v_status); - IF (v_status = 0) THEN RETURN; END IF; - PIPE ROW (v_line); - END LOOP; - RETURN; -EXCEPTION - WHEN OTHERS THEN - RETURN; -END; -/*$mw$*/ - -/*$mw$*/ -CREATE OR REPLACE FUNCTION GET_SEQUENCE_VALUE(seq IN VARCHAR2) RETURN NUMBER AS - v_value NUMBER; -BEGIN - EXECUTE IMMEDIATE 'SELECT '||seq||'.NEXTVAL INTO :outVar FROM DUAL' INTO v_value; - RETURN v_value; -END; -/*$mw$*/ diff --git a/maintenance/oracle/update-keys.sql b/maintenance/oracle/update-keys.sql deleted file mode 100644 index 7761d0c5..00000000 --- a/maintenance/oracle/update-keys.sql +++ /dev/null @@ -1,29 +0,0 @@ --- SQL to insert update keys into the initial tables after a --- fresh installation of MediaWiki's database. --- This is read and executed by the install script; you should --- not have to run it by itself unless doing a manual install. --- Insert keys here if either the unnecessary would cause heavy --- processing or could potentially cause trouble by lowering field --- sizes, adding constraints, etc. --- When adjusting field sizes, it is recommended removing old --- patches but to play safe, update keys should also inserted here. - --- The /*_*/ comments in this and other files are --- replaced with the defined table prefix by the installer --- and updater scripts. If you are installing or running --- updates manually, you will need to manually insert the --- table prefix if any when running these scripts. --- - -INSERT INTO /*_*/updatelog (ul_key, ul_value) - VALUES( 'filearchive-fa_major_mime-patch-fa_major_mime-chemical.sql', null ); -INSERT INTO /*_*/updatelog (ul_key, ul_value) - VALUES( 'image-img_major_mime-patch-img_major_mime-chemical.sql', null ); -INSERT INTO /*_*/updatelog (ul_key, ul_value) - VALUES( 'oldimage-oi_major_mime-patch-oi_major_mime-chemical.sql', null ); -INSERT INTO /*_*/updatelog (ul_key, ul_value) - VALUES( 'user_groups-ug_group-patch-ug_group-length-increase-255.sql', null ); -INSERT INTO /*_*/updatelog (ul_key, ul_value) - VALUES( 'user_former_groups-ufg_group-patch-ufg_group-length-increase-255.sql', null ); -INSERT INTO /*_*/updatelog (ul_key, ul_value) - VALUES( 'user_properties-up_property-patch-up_property.sql', null ); diff --git a/maintenance/oracle/user.sql b/maintenance/oracle/user.sql deleted file mode 100644 index 57688eae..00000000 --- a/maintenance/oracle/user.sql +++ /dev/null @@ -1,16 +0,0 @@ --- defines must comply with ^define\s*([^\s=]*)\s*=\s?'\{\$([^\}]*)\}'; -define wiki_user='{$wgDBuser}'; -define wiki_pass='{$wgDBpassword}'; -define def_ts='{$_OracleDefTS}'; -define temp_ts='{$_OracleTempTS}'; - -create user &wiki_user. identified by &wiki_pass. default tablespace &def_ts. temporary tablespace &temp_ts. quota unlimited on &def_ts.; -grant connect, resource to &wiki_user.; -grant alter session to &wiki_user.; -grant ctxapp to &wiki_user.; -grant execute on ctx_ddl to &wiki_user.; -grant create view to &wiki_user.; -grant create synonym to &wiki_user.; -grant create table to &wiki_user.; -grant create sequence to &wiki_user.; -grant create trigger to &wiki_user.; diff --git a/tests/phpunit/includes/installer/OracleInstallerTest.php b/tests/phpunit/includes/installer/OracleInstallerTest.php deleted file mode 100644 index fdcecf9e..00000000 --- a/tests/phpunit/includes/installer/OracleInstallerTest.php +++ /dev/null @@ -1,52 +0,0 @@ -assertEquals( $expected, - OracleInstaller::checkConnectStringFormat( $connectString ), - $msg - ); - } - - /** - * Provider to test OracleInstaller::checkConnectStringFormat() - */ - function provideOracleConnectStrings() { - // expected result, connectString[, message] - return array( - array( true, 'simple_01', 'Simple TNS name' ), - array( true, 'simple_01.world', 'TNS name with domain' ), - array( true, 'simple_01.domain.net', 'TNS name with domain' ), - array( true, 'host123', 'Host only' ), - array( true, 'host123.domain.net', 'FQDN only' ), - array( true, '//host123.domain.net', 'FQDN URL only' ), - array( true, '123.223.213.132', 'Host IP only' ), - array( true, 'host:1521', 'Host and port' ), - array( true, 'host:1521/service', 'Host, port and service' ), - array( true, 'host:1521/service:shared', 'Host, port, service and shared server type' ), - array( true, 'host:1521/service:dedicated', 'Host, port, service and dedicated server type' ), - array( true, 'host:1521/service:pooled', 'Host, port, service and pooled server type' ), - array( - true, - 'host:1521/service:shared/instance1', - 'Host, port, service, server type and instance' - ), - array( true, 'host:1521//instance1', 'Host, port and instance' ), - ); - } - -} -- cgit v1.2.2