Remove more Oracle and Mssql leftovers
authorDaimona Eaytoy <daimona.wiki@gmail.com>
Thu, 15 Aug 2019 12:21:55 +0000 (14:21 +0200)
committerKrinkle <krinklemail@gmail.com>
Sun, 25 Aug 2019 17:21:49 +0000 (17:21 +0000)
Follows-up 4d10bb14e81 and 807d793ab9079.

According to codesearch [0], these were the last usages. Note that this
patch leaves two constants in places, IDatabase::DBO_SYSDBA and
DBO_DDLMODE. These are public constants used "mostly for oracle" according
to the docs, but maybe we could find other use cases in the future (?).

[0] - https://codesearch.wmflabs.org/core/?q=oracle%7Cmssql&i=fosho&files=%5C.%5B%5Ej%5Cd%5D%7Cen%5C.json&repos=

Bug: T230418
Change-Id: Ibfb748b4b23b885a77f4de161af4bf2ab9649a89

14 files changed:
autoload.php
docs/database.txt
includes/Category.php
includes/WikiMap.php
includes/changes/RecentChange.php
includes/db/MWLBFactory.php
includes/db/ORAField.php [deleted file]
includes/db/ORAResult.php [deleted file]
includes/jobqueue/JobQueueDB.php
includes/libs/rdbms/database/Database.php
includes/libs/rdbms/database/IDatabase.php
includes/libs/rdbms/database/resultwrapper/MssqlResultWrapper.php [deleted file]
includes/libs/rdbms/encasing/MssqlBlob.php [deleted file]
includes/libs/rdbms/field/MssqlField.php [deleted file]

index 9b122cb..dfdf802 100644 (file)
@@ -1045,8 +1045,6 @@ $wgAutoloadLocalClasses = [
        'NullStatsdDataFactory' => __DIR__ . '/includes/libs/stats/NullStatsdDataFactory.php',
        'NumericUppercaseCollation' => __DIR__ . '/includes/collation/NumericUppercaseCollation.php',
        'OOUIHTMLForm' => __DIR__ . '/includes/htmlform/OOUIHTMLForm.php',
        'NullStatsdDataFactory' => __DIR__ . '/includes/libs/stats/NullStatsdDataFactory.php',
        'NumericUppercaseCollation' => __DIR__ . '/includes/collation/NumericUppercaseCollation.php',
        'OOUIHTMLForm' => __DIR__ . '/includes/htmlform/OOUIHTMLForm.php',
-       'ORAField' => __DIR__ . '/includes/db/ORAField.php',
-       'ORAResult' => __DIR__ . '/includes/db/ORAResult.php',
        'ObjectCache' => __DIR__ . '/includes/objectcache/ObjectCache.php',
        'OldChangesList' => __DIR__ . '/includes/changes/OldChangesList.php',
        'OldLocalFile' => __DIR__ . '/includes/filerepo/file/OldLocalFile.php',
        'ObjectCache' => __DIR__ . '/includes/objectcache/ObjectCache.php',
        'OldChangesList' => __DIR__ . '/includes/changes/OldChangesList.php',
        'OldLocalFile' => __DIR__ . '/includes/filerepo/file/OldLocalFile.php',
@@ -1684,9 +1682,6 @@ $wgAutoloadLocalClasses = [
        'Wikimedia\\Rdbms\\LoadMonitorMySQL' => __DIR__ . '/includes/libs/rdbms/loadmonitor/LoadMonitorMySQL.php',
        'Wikimedia\\Rdbms\\LoadMonitorNull' => __DIR__ . '/includes/libs/rdbms/loadmonitor/LoadMonitorNull.php',
        'Wikimedia\\Rdbms\\MaintainableDBConnRef' => __DIR__ . '/includes/libs/rdbms/database/MaintainableDBConnRef.php',
        'Wikimedia\\Rdbms\\LoadMonitorMySQL' => __DIR__ . '/includes/libs/rdbms/loadmonitor/LoadMonitorMySQL.php',
        'Wikimedia\\Rdbms\\LoadMonitorNull' => __DIR__ . '/includes/libs/rdbms/loadmonitor/LoadMonitorNull.php',
        'Wikimedia\\Rdbms\\MaintainableDBConnRef' => __DIR__ . '/includes/libs/rdbms/database/MaintainableDBConnRef.php',
-       'Wikimedia\\Rdbms\\MssqlBlob' => __DIR__ . '/includes/libs/rdbms/encasing/MssqlBlob.php',
-       'Wikimedia\\Rdbms\\MssqlField' => __DIR__ . '/includes/libs/rdbms/field/MssqlField.php',
-       'Wikimedia\\Rdbms\\MssqlResultWrapper' => __DIR__ . '/includes/libs/rdbms/database/resultwrapper/MssqlResultWrapper.php',
        'Wikimedia\\Rdbms\\MySQLField' => __DIR__ . '/includes/libs/rdbms/field/MySQLField.php',
        'Wikimedia\\Rdbms\\MySQLMasterPos' => __DIR__ . '/includes/libs/rdbms/database/position/MySQLMasterPos.php',
        'Wikimedia\\Rdbms\\NextSequenceValue' => __DIR__ . '/includes/libs/rdbms/database/utils/NextSequenceValue.php',
        'Wikimedia\\Rdbms\\MySQLField' => __DIR__ . '/includes/libs/rdbms/field/MySQLField.php',
        'Wikimedia\\Rdbms\\MySQLMasterPos' => __DIR__ . '/includes/libs/rdbms/database/position/MySQLMasterPos.php',
        'Wikimedia\\Rdbms\\NextSequenceValue' => __DIR__ . '/includes/libs/rdbms/database/utils/NextSequenceValue.php',
index 6e88d68..c09dd38 100644 (file)
@@ -176,8 +176,6 @@ MediaWiki does support the following other DBMSs to varying degrees.
 
 * PostgreSQL
 * SQLite
 
 * 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
 
 More information can be found about each of these databases (known issues,
 level of support, extra configuration) in the "databases" subdirectory in
index 34ac0e1..229958a 100644 (file)
@@ -340,7 +340,7 @@ class Category {
                $dbw->lockForUpdate( 'category', [ 'cat_title' => $this->mName ], __METHOD__ );
 
                // Lock all the `categorylinks` records and gaps for this category;
                $dbw->lockForUpdate( 'category', [ 'cat_title' => $this->mName ], __METHOD__ );
 
                // Lock all the `categorylinks` records and gaps for this category;
-               // this is a separate query due to postgres/oracle limitations
+               // this is a separate query due to postgres limitations
                $dbw->selectRowCount(
                        [ 'categorylinks', 'page' ],
                        '*',
                $dbw->selectRowCount(
                        [ 'categorylinks', 'page' ],
                        '*',
index f2641f4..0363877 100644 (file)
@@ -260,7 +260,6 @@ class WikiMap {
         *
         * @see $wgDBmwschema
         * @see PostgresInstaller
         *
         * @see $wgDBmwschema
         * @see PostgresInstaller
-        * @see MssqlInstaller
         *
         * @param string|DatabaseDomain $domain
         * @return string
         *
         * @param string|DatabaseDomain $domain
         * @return string
index c3b4728..0c6a3d1 100644 (file)
@@ -391,7 +391,7 @@ class RecentChange implements Taggable {
                }
 
                # If our database is strict about IP addresses, use NULL instead of an empty string
                }
 
                # If our database is strict about IP addresses, use NULL instead of an empty string
-               $strictIPs = in_array( $dbw->getType(), [ 'oracle', 'postgres' ] ); // legacy
+               $strictIPs = $dbw->getType() === 'postgres'; // legacy
                if ( $strictIPs && $this->mAttribs['rc_ip'] == '' ) {
                        unset( $this->mAttribs['rc_ip'] );
                }
                if ( $strictIPs && $this->mAttribs['rc_ip'] == '' ) {
                        unset( $this->mAttribs['rc_ip'] );
                }
index 0c17840..80eb2f7 100644 (file)
@@ -168,7 +168,7 @@ abstract class MWLBFactory {
         * @return array
         */
        private static function getDbTypesWithSchemas() {
         * @return array
         */
        private static function getDbTypesWithSchemas() {
-               return [ 'postgres', 'mssql' ];
+               return [ 'postgres' ];
        }
 
        /**
        }
 
        /**
@@ -193,16 +193,6 @@ abstract class MWLBFactory {
                                // Work around the reserved word usage in MediaWiki schema
                                'keywordTableMap' => [ 'user' => 'mwuser', 'text' => 'pagecontent' ]
                        ];
                                // Work around the reserved word usage in MediaWiki schema
                                'keywordTableMap' => [ 'user' => 'mwuser', 'text' => 'pagecontent' ]
                        ];
-               } elseif ( $server['type'] === 'oracle' ) {
-                       $server += [
-                               // Work around the reserved word usage in MediaWiki schema
-                               'keywordTableMap' => [ 'user' => 'mwuser', 'text' => 'pagecontent' ]
-                       ];
-               } elseif ( $server['type'] === 'mssql' ) {
-                       $server += [
-                               'port' => $options->get( 'DBport' ),
-                               'useWindowsAuth' => $options->get( 'DBWindowsAuthentication' )
-                       ];
                }
 
                if ( in_array( $server['type'], self::getDbTypesWithSchemas(), true ) ) {
                }
 
                if ( in_array( $server['type'], self::getDbTypesWithSchemas(), true ) ) {
diff --git a/includes/db/ORAField.php b/includes/db/ORAField.php
deleted file mode 100644 (file)
index df31000..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-<?php
-
-use Wikimedia\Rdbms\Field;
-
-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;
-       }
-}
diff --git a/includes/db/ORAResult.php b/includes/db/ORAResult.php
deleted file mode 100644 (file)
index aafd386..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-<?php
-
-use Wikimedia\Rdbms\IDatabase;
-
-/**
- * The oci8 extension is fairly weak and doesn't support oci_num_rows, among
- * other things. We use a wrapper class to handle that and other
- * Oracle-specific bits, like converting column names back to lowercase.
- * @ingroup Database
- */
-class ORAResult {
-       private $rows;
-       private $cursor;
-       private $nrows;
-
-       private $columns = [];
-
-       private function array_unique_md( $array_in ) {
-               $array_out = [];
-               $array_hashes = [];
-
-               foreach ( $array_in as $item ) {
-                       $hash = md5( serialize( $item ) );
-                       if ( !isset( $array_hashes[$hash] ) ) {
-                               $array_hashes[$hash] = $hash;
-                               $array_out[] = $item;
-                       }
-               }
-
-               return $array_out;
-       }
-
-       /**
-        * @param IDatabase &$db
-        * @param resource $stmt A valid OCI statement identifier
-        * @param bool $unique
-        */
-       function __construct( &$db, $stmt, $unique = false ) {
-               $this->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 = [];
-               foreach ( $row as $k => $v ) {
-                       $lc = $this->columns[$k];
-                       $ret[$lc] = $v;
-                       $ret[$k] = $v;
-               }
-
-               return $ret;
-       }
-}
index d449e8a..4be41a2 100644 (file)
@@ -424,7 +424,7 @@ class JobQueueDB extends JobQueue {
                        if ( $dbw->getType() === 'mysql' ) {
                                // Per https://bugs.mysql.com/bug.php?id=6980, we can't use subqueries on the
                                // same table being changed in an UPDATE query in MySQL (gives Error: 1093).
                        if ( $dbw->getType() === 'mysql' ) {
                                // Per https://bugs.mysql.com/bug.php?id=6980, we can't use subqueries on the
                                // same table being changed in an UPDATE query in MySQL (gives Error: 1093).
-                               // Oracle and Postgre have no such limitation. However, MySQL offers an
+                               // Postgres has no such limitation. However, MySQL offers an
                                // alternative here by supporting ORDER BY + LIMIT for UPDATE queries.
                                $dbw->query( "UPDATE {$dbw->tableName( 'job' )} " .
                                        "SET " .
                                // alternative here by supporting ORDER BY + LIMIT for UPDATE queries.
                                $dbw->query( "UPDATE {$dbw->tableName( 'job' )} " .
                                        "SET " .
index 0318022..084500a 100644 (file)
@@ -1818,7 +1818,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        $this->selectOptionsIncludeLocking( $options ) &&
                        $this->selectFieldsOrOptionsAggregate( $vars, $options )
                ) {
                        $this->selectOptionsIncludeLocking( $options ) &&
                        $this->selectFieldsOrOptionsAggregate( $vars, $options )
                ) {
-                       // Some DB types (postgres/oracle) disallow FOR UPDATE with aggregate
+                       // Some DB types (e.g. postgres) disallow FOR UPDATE with aggregate
                        // functions. Discourage use of such queries to encourage compatibility.
                        call_user_func(
                                $this->deprecationLogger,
                        // functions. Discourage use of such queries to encourage compatibility.
                        call_user_func(
                                $this->deprecationLogger,
index 8768213..6226137 100644 (file)
@@ -99,9 +99,9 @@ interface IDatabase {
        const DBO_DEFAULT = 16;
        /** @var int Use DB persistent connections if possible */
        const DBO_PERSISTENT = 32;
        const DBO_DEFAULT = 16;
        /** @var int Use DB persistent connections if possible */
        const DBO_PERSISTENT = 32;
-       /** @var int DBA session mode; mostly for Oracle */
+       /** @var int DBA session mode; was used by Oracle */
        const DBO_SYSDBA = 64;
        const DBO_SYSDBA = 64;
-       /** @var int Schema file mode; mostly for Oracle */
+       /** @var int Schema file mode; was used by Oracle */
        const DBO_DDLMODE = 128;
        /** @var int Enable SSL/TLS in connection protocol */
        const DBO_SSL = 256;
        const DBO_DDLMODE = 128;
        /** @var int Enable SSL/TLS in connection protocol */
        const DBO_SSL = 256;
@@ -1186,10 +1186,10 @@ interface IDatabase {
        /**
         * Deprecated method, calls should be removed.
         *
        /**
         * Deprecated method, calls should be removed.
         *
-        * This was formerly used for PostgreSQL and Oracle to handle
+        * This was formerly used for PostgreSQL to handle
         * self::insertId() auto-incrementing fields. It is no longer necessary
         * since DatabasePostgres::insertId() has been reimplemented using
         * self::insertId() auto-incrementing fields. It is no longer necessary
         * since DatabasePostgres::insertId() has been reimplemented using
-        * `lastval()` and Oracle has been reimplemented using triggers.
+        * `lastval()`
         *
         * Implementations should return null if inserting `NULL` into an
         * auto-incrementing field works, otherwise it should return an instance of
         *
         * Implementations should return null if inserting `NULL` into an
         * auto-incrementing field works, otherwise it should return an instance of
diff --git a/includes/libs/rdbms/database/resultwrapper/MssqlResultWrapper.php b/includes/libs/rdbms/database/resultwrapper/MssqlResultWrapper.php
deleted file mode 100644 (file)
index ba79be1..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-<?php
-
-namespace Wikimedia\Rdbms;
-
-use stdClass;
-
-class MssqlResultWrapper extends ResultWrapper {
-       /** @var int|null */
-       private $seekTo = null;
-
-       /**
-        * @return stdClass|bool
-        */
-       public function fetchObject() {
-               $res = $this->result;
-
-               if ( $this->seekTo !== null ) {
-                       $result = sqlsrv_fetch_object( $res, stdClass::class, [],
-                               SQLSRV_SCROLL_ABSOLUTE, $this->seekTo );
-                       $this->seekTo = null;
-               } else {
-                       $result = sqlsrv_fetch_object( $res );
-               }
-
-               // 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->seekTo !== null ) {
-                       $result = sqlsrv_fetch_array( $res, SQLSRV_FETCH_BOTH,
-                               SQLSRV_SCROLL_ABSOLUTE, $this->seekTo );
-                       $this->seekTo = null;
-               } else {
-                       $result = sqlsrv_fetch_array( $res );
-               }
-
-               // 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->seekTo = $row;
-               return true;
-       }
-}
diff --git a/includes/libs/rdbms/encasing/MssqlBlob.php b/includes/libs/rdbms/encasing/MssqlBlob.php
deleted file mode 100644 (file)
index 1819a9a..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-<?php
-
-namespace Wikimedia\Rdbms;
-
-class MssqlBlob extends Blob {
-       /** @noinspection PhpMissingParentConstructorInspection */
-
-       /**
-        * @param Blob|string $data
-        */
-       public function __construct( $data ) {
-               if ( $data instanceof MssqlBlob ) {
-                       $this->data = $data->data;
-               } elseif ( $data instanceof Blob ) {
-                       $this->data = $data->fetch();
-               } else {
-                       $this->data = $data;
-               }
-       }
-
-       /**
-        * Returns an unquoted hex representation of a binary string
-        * for insertion into varbinary-type fields
-        * @return string
-        */
-       public function fetch() {
-               if ( $this->data === null ) {
-                       return 'null';
-               }
-
-               $ret = '0x';
-               $dataLength = strlen( $this->data );
-               for ( $i = 0; $i < $dataLength; $i++ ) {
-                       $ret .= bin2hex( pack( 'C', ord( $this->data[$i] ) ) );
-               }
-
-               return $ret;
-       }
-}
diff --git a/includes/libs/rdbms/field/MssqlField.php b/includes/libs/rdbms/field/MssqlField.php
deleted file mode 100644 (file)
index 98cc2b1..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-<?php
-
-namespace Wikimedia\Rdbms;
-
-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;
-       }
-}