Add preliminary MS SQL support
This likely has outstanding bugs but basic wiki operations work just fine in it. Change-Id: I25df82065a307b9abc30c694f8c8afff0996d7c1
This commit is contained in:
parent
3673bbf201
commit
f7174057a4
13 changed files with 2670 additions and 1124 deletions
|
|
@ -94,6 +94,12 @@ production.
|
|||
callbacks for frequently occurring events.
|
||||
* Special:ProtectedPages shows now a table. The timestamp, the reason and
|
||||
the protecting user is also shown.
|
||||
* Added experimental support for using Microsoft SQL Server as the database
|
||||
backend.
|
||||
** Added new Microsoft SQL Server-specific configuration variable
|
||||
$wgDBWindowsAuthentication, which makes the web server authenticate against
|
||||
the database server using Integrated Windows Authentication instead of
|
||||
$wgDBuser/$wgDBpassword.
|
||||
|
||||
=== Bug fixes in 1.23 ===
|
||||
* (bug 41759) The "updated since last visit" markers (on history pages, recent
|
||||
|
|
@ -350,7 +356,7 @@ MediaWiki 1.23 requires PHP 5.3.2 or later.
|
|||
|
||||
MySQL is the recommended DBMS. PostgreSQL or SQLite can also be used, but
|
||||
support for them is somewhat less mature. There is experimental support for
|
||||
Oracle.
|
||||
Oracle and Microsoft SQL Server.
|
||||
|
||||
The supported versions are:
|
||||
|
||||
|
|
@ -358,6 +364,7 @@ The supported versions are:
|
|||
* PostgreSQL 8.3 or later
|
||||
* SQLite 3.3.7 or later
|
||||
* Oracle 9.0.1 or later
|
||||
* Microsoft SQL Server 2005 (9.00.1399)
|
||||
|
||||
== Upgrading ==
|
||||
|
||||
|
|
|
|||
|
|
@ -474,7 +474,8 @@ $wgAutoloadLocalClasses = array(
|
|||
'LoadMonitorMySQL' => 'includes/db/LoadMonitor.php',
|
||||
'LoadMonitorNull' => 'includes/db/LoadMonitor.php',
|
||||
'MssqlField' => 'includes/db/DatabaseMssql.php',
|
||||
'MssqlResult' => 'includes/db/DatabaseMssql.php',
|
||||
'MssqlBlob' => 'includes/db/DatabaseMssql.php',
|
||||
'MssqlResultWrapper' => 'includes/db/DatabaseMssql.php',
|
||||
'MySQLField' => 'includes/db/DatabaseMysqlBase.php',
|
||||
'MySQLMasterPos' => 'includes/db/DatabaseMysqlBase.php',
|
||||
'ORAField' => 'includes/db/DatabaseOracle.php',
|
||||
|
|
@ -611,6 +612,8 @@ $wgAutoloadLocalClasses = array(
|
|||
'InstallDocFormatter' => 'includes/installer/InstallDocFormatter.php',
|
||||
'Installer' => 'includes/installer/Installer.php',
|
||||
'LocalSettingsGenerator' => 'includes/installer/LocalSettingsGenerator.php',
|
||||
'MssqlInstaller' => 'includes/installer/MssqlInstaller.php',
|
||||
'MssqlUpdater' => 'includes/installer/MssqlUpdater.php',
|
||||
'MysqlInstaller' => 'includes/installer/MysqlInstaller.php',
|
||||
'MysqlUpdater' => 'includes/installer/MysqlUpdater.php',
|
||||
'OracleInstaller' => 'includes/installer/OracleInstaller.php',
|
||||
|
|
|
|||
|
|
@ -1585,7 +1585,7 @@ $wgSQLMode = '';
|
|||
/**
|
||||
* Mediawiki schema
|
||||
*/
|
||||
$wgDBmwschema = 'mediawiki';
|
||||
$wgDBmwschema = null;
|
||||
|
||||
/**
|
||||
* To override default SQLite data directory ($docroot/../data)
|
||||
|
|
@ -1805,6 +1805,11 @@ $wgSlaveLagWarning = 10;
|
|||
*/
|
||||
$wgSlaveLagCritical = 30;
|
||||
|
||||
/**
|
||||
* Use Windows Authentication instead of $wgDBuser / $wgDBpassword for MS SQL Server
|
||||
*/
|
||||
$wgDBWindowsAuthentication = false;
|
||||
|
||||
/**@}*/ # End of DB settings }
|
||||
|
||||
/************************************************************************//**
|
||||
|
|
|
|||
|
|
@ -245,6 +245,7 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
|
|||
protected $mTrxPreCommitCallbacks = array();
|
||||
|
||||
protected $mTablePrefix;
|
||||
protected $mSchema;
|
||||
protected $mFlags;
|
||||
protected $mForeign;
|
||||
protected $mErrorCount = 0;
|
||||
|
|
@ -428,6 +429,15 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
|
|||
return wfSetVar( $this->mTablePrefix, $prefix );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get/set the db schema.
|
||||
* @param string $schema The database schema to set, or omitted to leave it unchanged.
|
||||
* @return string The previous db schema.
|
||||
*/
|
||||
public function dbSchema( $schema = null ) {
|
||||
return wfSetVar( $this->mSchema, $schema );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the filehandle to copy write statements to.
|
||||
*
|
||||
|
|
@ -711,7 +721,7 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
|
|||
* @param array $params Parameters passed from DatabaseBase::factory()
|
||||
*/
|
||||
function __construct( $params = null ) {
|
||||
global $wgDBprefix, $wgCommandLineMode, $wgDebugDBTransactions;
|
||||
global $wgDBprefix, $wgDBmwschema, $wgCommandLineMode, $wgDebugDBTransactions;
|
||||
|
||||
$this->mTrxAtomicLevels = new SplStack;
|
||||
|
||||
|
|
@ -722,6 +732,7 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
|
|||
$dbName = $params['dbname'];
|
||||
$flags = $params['flags'];
|
||||
$tablePrefix = $params['tablePrefix'];
|
||||
$schema = $params['schema'];
|
||||
$foreign = $params['foreign'];
|
||||
} else { // legacy calling pattern
|
||||
wfDeprecated( __METHOD__ . " method called without parameter array.", "1.23" );
|
||||
|
|
@ -732,6 +743,7 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
|
|||
$dbName = isset( $args[3] ) ? $args[3] : false;
|
||||
$flags = isset( $args[4] ) ? $args[4] : 0;
|
||||
$tablePrefix = isset( $args[5] ) ? $args[5] : 'get from global';
|
||||
$schema = 'get from global';
|
||||
$foreign = isset( $args[6] ) ? $args[6] : false;
|
||||
}
|
||||
|
||||
|
|
@ -757,6 +769,13 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
|
|||
$this->mTablePrefix = $tablePrefix;
|
||||
}
|
||||
|
||||
/** Get the database schema*/
|
||||
if ( $schema == 'get from global' ) {
|
||||
$this->mSchema = $wgDBmwschema;
|
||||
} else {
|
||||
$this->mSchema = $schema;
|
||||
}
|
||||
|
||||
$this->mForeign = $foreign;
|
||||
|
||||
if ( $user ) {
|
||||
|
|
@ -792,7 +811,7 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
|
|||
*
|
||||
* @param string $dbType A possible DB type
|
||||
* @param array $p An array of options to pass to the constructor.
|
||||
* Valid options are: host, user, password, dbname, flags, tablePrefix, driver
|
||||
* Valid options are: host, user, password, dbname, flags, tablePrefix, schema, driver
|
||||
* @throws MWException If the database driver or extension cannot be found
|
||||
* @return DatabaseBase|null DatabaseBase subclass or null
|
||||
*/
|
||||
|
|
@ -832,6 +851,18 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
|
|||
" no viable database extension found for type '$dbType'" );
|
||||
}
|
||||
|
||||
// Determine schema defaults. Currently Microsoft SQL Server uses $wgDBmwschema,
|
||||
// and everything else doesn't use a schema (e.g. null)
|
||||
// Although postgres and oracle support schemas, we don't use them (yet)
|
||||
// to maintain backwards compatibility
|
||||
$defaultSchemas = array(
|
||||
'mysql' => null,
|
||||
'postgres' => null,
|
||||
'sqlite' => null,
|
||||
'oracle' => null,
|
||||
'mssql' => 'get from global',
|
||||
);
|
||||
|
||||
$class = 'Database' . ucfirst( $driver );
|
||||
if ( class_exists( $class ) && is_subclass_of( $class, 'DatabaseBase' ) ) {
|
||||
$params = array(
|
||||
|
|
@ -841,6 +872,7 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
|
|||
'dbname' => isset( $p['dbname'] ) ? $p['dbname'] : false,
|
||||
'flags' => isset( $p['flags'] ) ? $p['flags'] : 0,
|
||||
'tablePrefix' => isset( $p['tablePrefix'] ) ? $p['tablePrefix'] : 'get from global',
|
||||
'schema' => isset( $p['schema'] ) ? $p['schema'] : $defaultSchemas[$dbType],
|
||||
'foreign' => isset( $p['foreign'] ) ? $p['foreign'] : false
|
||||
);
|
||||
|
||||
|
|
@ -2162,7 +2194,7 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
|
|||
* @return string Full database name
|
||||
*/
|
||||
public function tableName( $name, $format = 'quoted' ) {
|
||||
global $wgSharedDB, $wgSharedPrefix, $wgSharedTables;
|
||||
global $wgSharedDB, $wgSharedPrefix, $wgSharedTables, $wgSharedSchema;
|
||||
# Skip the entire process when we have a string quoted on both ends.
|
||||
# Note that we check the end so that we will still quote any use of
|
||||
# use of `database`.table. But won't break things if someone wants
|
||||
|
|
@ -2186,10 +2218,17 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
|
|||
# We reverse the explode so that database.table and table both output
|
||||
# the correct table.
|
||||
$dbDetails = explode( '.', $name, 2 );
|
||||
if ( count( $dbDetails ) == 2 ) {
|
||||
list( $database, $table ) = $dbDetails;
|
||||
if ( count( $dbDetails ) == 3 ) {
|
||||
list( $database, $schema, $table ) = $dbDetails;
|
||||
# We don't want any prefix added in this case
|
||||
$prefix = '';
|
||||
} elseif ( count( $dbDetails ) == 2 ) {
|
||||
list( $database, $table ) = $dbDetails;
|
||||
# We don't want any prefix added in this case
|
||||
# In dbs that support it, $database may actually be the schema
|
||||
# but that doesn't affect any of the functionality here
|
||||
$prefix = '';
|
||||
$schema = null;
|
||||
} else {
|
||||
list( $table ) = $dbDetails;
|
||||
if ( $wgSharedDB !== null # We have a shared database
|
||||
|
|
@ -2198,19 +2237,30 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
|
|||
&& in_array( $table, $wgSharedTables ) # A shared table is selected
|
||||
) {
|
||||
$database = $wgSharedDB;
|
||||
$schema = $wgSharedSchema === null ? $this->mSchema : $wgSharedSchema;
|
||||
$prefix = $wgSharedPrefix === null ? $this->mTablePrefix : $wgSharedPrefix;
|
||||
} else {
|
||||
$database = null;
|
||||
$schema = $this->mSchema; # Default schema
|
||||
$prefix = $this->mTablePrefix; # Default prefix
|
||||
}
|
||||
}
|
||||
|
||||
# Quote $table and apply the prefix if not quoted.
|
||||
# $tableName might be empty if this is called from Database::replaceVars()
|
||||
$tableName = "{$prefix}{$table}";
|
||||
if ( $format == 'quoted' && !$this->isQuotedIdentifier( $tableName ) ) {
|
||||
if ( $format == 'quoted' && !$this->isQuotedIdentifier( $tableName ) && $tableName !== '' ) {
|
||||
$tableName = $this->addIdentifierQuotes( $tableName );
|
||||
}
|
||||
|
||||
# Quote $schema and merge it with the table name if needed
|
||||
if ( $schema !== null ) {
|
||||
if ( $format == 'quoted' && !$this->isQuotedIdentifier( $schema ) ) {
|
||||
$schema = $this->addIdentifierQuotes( $schema );
|
||||
}
|
||||
$tableName = $schema . '.' . $tableName;
|
||||
}
|
||||
|
||||
# Quote $database and merge it with the table name if needed
|
||||
if ( $database !== null ) {
|
||||
if ( $format == 'quoted' && !$this->isQuotedIdentifier( $database ) ) {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -220,6 +220,7 @@ class DatabaseOracle extends DatabaseBase {
|
|||
'dbname' => isset( $args[3] ) ? $args[3] : false,
|
||||
'flags' => isset( $args[4] ) ? $args[4] : 0,
|
||||
'tablePrefix' => isset( $args[5] ) ? $args[5] : 'get from global',
|
||||
'schema' => 'get from global',
|
||||
'foreign' => isset( $args[6] ) ? $args[6] : false
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ class DatabaseSqlite extends DatabaseBase {
|
|||
'dbname' => isset( $args[3] ) ? $args[3] : false,
|
||||
'flags' => isset( $args[4] ) ? $args[4] : 0,
|
||||
'tablePrefix' => isset( $args[5] ) ? $args[5] : 'get from global',
|
||||
'schema' => 'get from global',
|
||||
'foreign' => isset( $args[6] ) ? $args[6] : false
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ class DBObject {
|
|||
*/
|
||||
class Blob {
|
||||
/** @var string */
|
||||
private $mData;
|
||||
protected $mData;
|
||||
|
||||
function __construct( $data ) {
|
||||
$this->mData = $data;
|
||||
|
|
|
|||
|
|
@ -241,6 +241,7 @@ Consider putting the database somewhere else altogether, for example in <code>/v
|
|||
'config-type-postgres' => 'PostgreSQL',
|
||||
'config-type-sqlite' => 'SQLite',
|
||||
'config-type-oracle' => 'Oracle',
|
||||
'config-type-mssql' => 'Microsoft SQL Server',
|
||||
'config-support-info' => 'MediaWiki supports the following database systems:
|
||||
|
||||
$1
|
||||
|
|
@ -250,10 +251,12 @@ If you do not see the database system you are trying to use listed below, then f
|
|||
'config-dbsupport-postgres' => '* [{{int:version-db-postgres-url}} PostgreSQL] is a popular open source database system as an alternative to MySQL. There may be some minor outstanding bugs, and it is not recommended for use in a production environment. ([http://www.php.net/manual/en/pgsql.installation.php How to compile PHP with PostgreSQL support])',
|
||||
'config-dbsupport-sqlite' => '* [{{int:version-db-sqlite-url}} SQLite] is a lightweight database system that is very well supported. ([http://www.php.net/manual/en/pdo.installation.php How to compile PHP with SQLite support], uses PDO)',
|
||||
'config-dbsupport-oracle' => '* [{{int:version-db-oracle-url}} Oracle] is a commercial enterprise database. ([http://www.php.net/manual/en/oci8.installation.php How to compile PHP with OCI8 support])',
|
||||
'config-dbsupport-mssql' => '* [{{int:version-db-mssql-url}} Microsoft SQL Server] is a commercial enterprise database for Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV support])',
|
||||
'config-header-mysql' => 'MySQL settings',
|
||||
'config-header-postgres' => 'PostgreSQL settings',
|
||||
'config-header-sqlite' => 'SQLite settings',
|
||||
'config-header-oracle' => 'Oracle settings',
|
||||
'config-header-mssql' => 'Microsoft SQL Server settings',
|
||||
'config-invalid-db-type' => 'Invalid database type',
|
||||
'config-missing-db-name' => 'You must enter a value for "Database name"',
|
||||
'config-missing-db-host' => 'You must enter a value for "Database host"',
|
||||
|
|
@ -272,6 +275,7 @@ Use only ASCII letters (a-z, A-Z), numbers (0-9) and underscores (_).',
|
|||
'config-db-sys-create-oracle' => 'Installer only supports using a SYSDBA account for creating a new account.',
|
||||
'config-db-sys-user-exists-oracle' => 'User account "$1" already exists. SYSDBA can only be used for creating of a new account!',
|
||||
'config-postgres-old' => 'PostgreSQL $1 or later is required. You have $2.',
|
||||
'config-mssql-old' => 'Microsoft SQL Server $1 or later is required. You have $2.',
|
||||
'config-sqlite-name-help' => 'Choose a name that identifies your wiki.
|
||||
Do not use spaces or hyphens.
|
||||
This will be used for the SQLite data file name.',
|
||||
|
|
@ -352,6 +356,13 @@ This is more efficient than MySQL's UTF-8 mode, and allows you to use the full r
|
|||
|
||||
In <strong>UTF-8 mode</strong>, MySQL will know what character set your data is in, and can present and convert it appropriately, but it will not let you store characters above the [//en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes Basic Multilingual Plane].",
|
||||
|
||||
'config-mssql-auth' => 'Authentication type:',
|
||||
'config-mssql-install-auth' => 'Select the authentication type that will be used to connect to the database during the installation process.
|
||||
If you select "Windows Authentication", the credentials of whatever user the webserver is running as will be used.',
|
||||
'config-mssql-web-auth' => 'Select the authentication type that the web server will use to connect to the database server, during ordinary operation of the wiki.
|
||||
If you select "Windows Authentication", the credentials of whatever user the webserver is running as will be used.',
|
||||
'config-mssql-sqlauth' => 'SQL Server Authentication',
|
||||
'config-mssql-windowsauth' => 'Windows Authentication',
|
||||
'config-site-name' => 'Name of wiki:',
|
||||
'config-site-name-help' => "This will appear in the title bar of the browser and in various other places.",
|
||||
'config-site-name-blank' => 'Enter a site name.',
|
||||
|
|
@ -705,6 +716,8 @@ Used in help box.',
|
|||
'config-type-postgres' => '{{optional}}',
|
||||
'config-type-sqlite' => '{{optional}}',
|
||||
'config-type-oracle' => '{{optional}}',
|
||||
'config-type-mssql' => '{{optional}}',
|
||||
'config-header-mssql' => 'Used as a section heading on the installer form, inside of a fieldset',
|
||||
'config-support-info' => 'Parameters:
|
||||
* $1 - a list of DBMSs that MediaWiki supports, composed with config-dbsupport-* messages.',
|
||||
'config-support-mysql' => 'Parameters:
|
||||
|
|
@ -723,6 +736,8 @@ Used in help box.',
|
|||
* $1 - database server name
|
||||
See also:
|
||||
* {{msg-mw|Config-db-host-oracle-help}}',
|
||||
'config-support-mssql' => 'Parameters:
|
||||
* $1 - a link to the Microsoft SQL Server home page, the anchor text of which is "Microsoft SQL Server".',
|
||||
'config-invalid-db-name' => 'Used as error message. Parameters:
|
||||
* $1 - database name
|
||||
See also:
|
||||
|
|
@ -740,6 +755,9 @@ If you\'re translating this message to a right-to-left language, consider writin
|
|||
'config-postgres-old' => 'Used as error message. Used as warning. Parameters:
|
||||
* $1 - minimum version
|
||||
* $2 - the version of PostgreSQL that has been installed',
|
||||
'config-mssql-old' => 'Used as an error message. Parameters:
|
||||
* $1 - minimum version
|
||||
* $2 - the version of Microsoft SQL Server that has been installed',
|
||||
'config-sqlite-parent-unwritable-group' => 'Used as SQLite error message. Parameters:
|
||||
* $1 - data directory
|
||||
* $2 - "dirname" part of $1
|
||||
|
|
@ -762,6 +780,11 @@ See also:
|
|||
* $1 - filename',
|
||||
'config-sqlite-cant-create-db' => 'Used as SQLite error message. Parameters:
|
||||
* $1 - filename',
|
||||
'config-mssql-auth' => 'radio button label',
|
||||
'config-mssql-install-auth' => 'Used as the help text for the "Authentication type" radio button when typing in database settings for installation',
|
||||
'config-mssql-web-auth' => 'Used as the help text for the "Authentication type" radio button when typing in database settings for normal wiki usage',
|
||||
'config-mssql-sqlauth' => 'Radio button',
|
||||
'config-mssql-windowsauth' => 'Radio button. The official term is "Integrated Windows Authentication" but Microsoft itself uses "Windows Authentication" elsewhere in Microsoft SQL Server as a synonym.',
|
||||
'config-can-upgrade' => 'Parameters:
|
||||
* $1 - Version or Revision indicator.',
|
||||
'config-upgrade-done' => 'Used as success message. Parameters:
|
||||
|
|
@ -4894,7 +4917,7 @@ Instalación anulada.',
|
|||
'config-using531' => 'MediaWiki no puede utilizarse con PHP $1 debido a un error con los parámetros de referencia para <code>__call()</code> .
|
||||
Actualice el sistema a PHP 5.3.2 o superior, o vuelva a la versión PHP 5.3.0 para resolver este problema.
|
||||
Instalación anulada.',
|
||||
'config-suhosin-max-value-length' => 'Suhosin está instalado y limita el parámetro <code>length</code> GET a $1 bytes.
|
||||
'config-suhosin-max-value-length' => 'Suhosin está instalado y limita el parámetro <code>length</code> GET a $1 bytes.
|
||||
El componente ResourceLoader (gestor de recursos) de MediaWiki trabajará en este límite, pero eso perjudicará el rendimiento.
|
||||
Si es posible, deberías establecer <code>suhosin.get.max_value_length</code> en el valor 1024 o superior en <code>php.ini</code> y establecer <code>$wgResourceLoaderMaxQueryLength</code> en el mismo valor en <code>php.ini</code>.',
|
||||
'config-db-type' => 'Tipo de base de datos',
|
||||
|
|
@ -4932,7 +4955,7 @@ Esta no es la contraseña para la cuenta de MediaWiki; esta es la contraseña pa
|
|||
'config-db-wiki-help' => 'Introduce el nombre de usuario y la contraseña que serán usados para acceder a la base de datos durante la operación normal del wiki.
|
||||
Si esta cuenta no existe y la cuenta de instalación tiene suficientes privilegios, se creará esta cuenta de usuario con los privilegios mínimos necesarios para la operación normal del wiki.',
|
||||
'config-db-prefix' => 'Prefijo para las tablas de la base de datos:',
|
||||
'config-db-prefix-help' => 'Si necesita compartir una base de datos entre múltiples wikis, o entre MediaWiki y otra aplicación web, puede optar por agregar un prefijo a todos los nombres de tabla para evitar conflictos.
|
||||
'config-db-prefix-help' => 'Si necesita compartir una base de datos entre múltiples wikis, o entre MediaWiki y otra aplicación web, puede optar por agregar un prefijo a todos los nombres de tabla para evitar conflictos.
|
||||
No utilice espacios.
|
||||
|
||||
Normalmente se deja este campo vacío.',
|
||||
|
|
@ -15509,7 +15532,7 @@ Jeśli korzystasz ze współdzielonego hostingu, dostawca usługi hostingowej mo
|
|||
|
||||
Możesz utworzyć konto użytkownika bazy danych podczas instalacji MediaWiki. Wówczas należy podać nazwę i hasło użytkownika z rolą SYSDBA w celu użycia go przez instalator do utworzenia nowe konta użytkownika, z którego korzystać będzie MediaWiki.
|
||||
|
||||
Możesz również skorzystać z konta użytkownika bazy danych utworzonego bezpośrednio w Oracle i wówczas wystarczy podać tylko nazwę i hasło tego użytkownika. Konto z rolą SYSDBA nie będzie potrzebne, jednak konto użytkownika powinno mieć uprawnienia do utworzenia obiektów w schemacie bazy danych. Możesz też podać dwa konta - konto dla instalatora, z pomocą którego zostaną obiekty w schemacie bazy danych i drugie konto, z którego będzie MediaWiki korzystać będzie do pracy.
|
||||
Możesz również skorzystać z konta użytkownika bazy danych utworzonego bezpośrednio w Oracle i wówczas wystarczy podać tylko nazwę i hasło tego użytkownika. Konto z rolą SYSDBA nie będzie potrzebne, jednak konto użytkownika powinno mieć uprawnienia do utworzenia obiektów w schemacie bazy danych. Możesz też podać dwa konta - konto dla instalatora, z pomocą którego zostaną obiekty w schemacie bazy danych i drugie konto, z którego będzie MediaWiki korzystać będzie do pracy.
|
||||
|
||||
W podkatalogu "maintenance/oracle" znajduje się skrypt do tworzenia konta użytkownika. Korzystanie z konta użytkownika z ograniczonymi uprawnieniami spowoduje wyłączenie funkcji związanych z aktualizacją oprogramowania MediaWiki.',
|
||||
'config-db-install-account' => 'Konto użytkownika dla instalatora',
|
||||
|
|
@ -15900,7 +15923,7 @@ A la trovrà an LocalSetting.php.",
|
|||
Për agiorné sta instalassion, për piasì fà anvece giré <code>update.php</code>",
|
||||
'config-localsettings-key' => "Ciav d'agiornament:",
|
||||
'config-localsettings-badkey' => "La ciav ch'it l'has dàit a l'é pa giusta.",
|
||||
'config-upgrade-key-missing' => "A l'é stàita trovà n'istalassion esistenta ëd MediaWiki.
|
||||
'config-upgrade-key-missing' => "A l'é stàita trovà n'istalassion esistenta ëd MediaWiki.
|
||||
Për agiorné soa istalassion, për piasì ch'a buta la linia sì-sota al fond ëd sò <code>LocalSettings.php</code>:
|
||||
|
||||
$1",
|
||||
|
|
@ -19593,7 +19616,7 @@ Ang mas masasalimuot na mga kaayusan ng mga karapatan ng tagagamit ay makukuha p
|
|||
'config-license-gfdl' => 'Lisensiyang 1.3 ng Malayang Dokumentasyon ng GNU o mas lalong huli',
|
||||
'config-license-pd' => 'Nasasakupan ng Madla',
|
||||
'config-license-cc-choose' => 'Pumili ng isang pasadyang Lisensiya ng Malikhaing mga Pangkaraniwan',
|
||||
'config-license-help' => "Maraming mga pangmadlang wiki ang naglalagay ng lahat ng mga ambag sa ilalim ng [http://freedomdefined.org/Definition lisensiyang malaya].
|
||||
'config-license-help' => "Maraming mga pangmadlang wiki ang naglalagay ng lahat ng mga ambag sa ilalim ng [http://freedomdefined.org/Definition lisensiyang malaya].
|
||||
Nakakatulong ito sa paglikha ng isang diwa ng pagmamay-ari ng pamayanan at nakapanghihikayat ng ambag na pangmahabang panahon.
|
||||
Sa pangkalahatan, hindi kailangan ang isang wiking pribado o pangsamahan.
|
||||
|
||||
|
|
@ -20023,7 +20046,7 @@ MediaWiki вимагає підтримку UTF-8 для коректної ро
|
|||
'config-mysql-old' => 'Необхідна MySQL $1 або пізніша, а у Вас $2.',
|
||||
'config-db-port' => 'Порт бази даних:',
|
||||
'config-db-schema' => 'Схема для MediaWiki',
|
||||
'config-db-schema-help' => 'Ця схема зазвичай працює добре.
|
||||
'config-db-schema-help' => 'Ця схема зазвичай працює добре.
|
||||
Змінюйте її тільки якщо знаєте, що Вам це потрібно.',
|
||||
'config-pg-test-error' => "Не вдається підключитися до бази даних '''$1''': $2",
|
||||
'config-sqlite-dir' => 'Папка даних SQLite:',
|
||||
|
|
@ -20250,7 +20273,7 @@ GFDL — допустима ліцензія, але у ній важко роз
|
|||
'config-upload-deleted-help' => 'Оберіть папку для архівації видалених файлів.
|
||||
В ідеалі, вона не має бути доступною через інтернет.',
|
||||
'config-logo' => 'URL логотипу:',
|
||||
'config-logo-help' => 'Стандартна схема оформлення MediaWiki містить вільне для логотипу місце над бічною панеллю розміром 135x160 пікселів.
|
||||
'config-logo-help' => 'Стандартна схема оформлення MediaWiki містить вільне для логотипу місце над бічною панеллю розміром 135x160 пікселів.
|
||||
|
||||
Завантажте зображення відповідного розміру і введіть тут його URL.
|
||||
|
||||
|
|
@ -20370,9 +20393,9 @@ $messages['ur'] = array(
|
|||
'config-git' => 'Git ورژن کنٹرول مصنع لطیف ملا: <code>$1</code> ۔',
|
||||
'config-git-bad' => 'GIT ورژن کنٹرول مصنع لطیف نہيں ملا ۔',
|
||||
'config-mysql-only-myisam-dep' => "' ' تنبیہ: ' '[[MyISAM|مائ اسام]] واحد دستیاب 'ذخیرہ جاتی انجن' ہے جو مائی ایس کیو ایل کے لیے ہے ، جو کہ ناموزوں ہے میڈیا وکی کے لیے ،کیوں کہ :
|
||||
* یہ ہموار قطاروں کی سہولت بمشکل فراہم کرتا ہے
|
||||
* یہ ہموار قطاروں کی سہولت بمشکل فراہم کرتا ہے
|
||||
* یہ دوسرے انجنوں کے مقابلے زیادہ بگڑ جاتا ہے
|
||||
* میڈیا وکی کوڈ بیس ہمیشہ سنبھال نہيں پاتا مائی اسام کو ۔
|
||||
* میڈیا وکی کوڈ بیس ہمیشہ سنبھال نہيں پاتا مائی اسام کو ۔
|
||||
|
||||
آپ کا مائی ایس کیو ایل کا نصب ہمیشہ اننو ڈی بی کی سہولت نہيں دے سکتا ، ہو سکتا ہے یہ مزید ترقیاتی کام چاہے", # Fuzzy
|
||||
'config-profile-fishbowl' => 'صرف مجاز ایڈیٹرز',
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ abstract class Installer {
|
|||
'mysql',
|
||||
'postgres',
|
||||
'oracle',
|
||||
'mssql',
|
||||
'sqlite',
|
||||
);
|
||||
|
||||
|
|
|
|||
692
includes/installer/MssqlInstaller.php
Normal file
692
includes/installer/MssqlInstaller.php
Normal file
|
|
@ -0,0 +1,692 @@
|
|||
<?php
|
||||
/**
|
||||
* Microsoft SQL Server-specific installer.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* @file
|
||||
* @ingroup Deployment
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class for setting up the MediaWiki database using Microsoft SQL Server.
|
||||
*
|
||||
* @ingroup Deployment
|
||||
* @since 1.23
|
||||
*/
|
||||
class MssqlInstaller extends DatabaseInstaller {
|
||||
|
||||
protected $globalNames = array(
|
||||
'wgDBserver',
|
||||
'wgDBname',
|
||||
'wgDBuser',
|
||||
'wgDBpassword',
|
||||
'wgDBmwschema',
|
||||
'wgDBprefix',
|
||||
'wgDBWindowsAuthentication',
|
||||
);
|
||||
|
||||
protected $internalDefaults = array(
|
||||
'_InstallUser' => 'sa',
|
||||
'_InstallWindowsAuthentication' => 'sqlauth',
|
||||
'_WebWindowsAuthentication' => 'sqlauth',
|
||||
);
|
||||
|
||||
public $minimumVersion = '9.00.1399'; // SQL Server 2005 RTM (TODO: are SQL Express version numbers different?)
|
||||
|
||||
// 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,
|
||||
'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 );
|
||||
$server = $this->getVar( 'wgDBserver' );
|
||||
$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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to see if the login exists
|
||||
* @param string $user Username to check
|
||||
* @return boolean
|
||||
*/
|
||||
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 boolean
|
||||
*/
|
||||
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 boolean
|
||||
*/
|
||||
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 boolean
|
||||
*/
|
||||
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 $schemaName Catalog name to check
|
||||
* @return boolean
|
||||
*/
|
||||
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}\";";
|
||||
}
|
||||
}
|
||||
46
includes/installer/MssqlUpdater.php
Normal file
46
includes/installer/MssqlUpdater.php
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
/**
|
||||
* Microsoft SQL Server-specific installer.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* @file
|
||||
* @ingroup Deployment
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class for setting up the MediaWiki database using Microsoft SQL Server.
|
||||
*
|
||||
* @ingroup Deployment
|
||||
* @since 1.23
|
||||
*/
|
||||
|
||||
class MssqlUpdater extends DatabaseUpdater {
|
||||
|
||||
/**
|
||||
* @var DatabaseMssql
|
||||
*/
|
||||
protected $db;
|
||||
|
||||
protected function getCoreUpdateList() {
|
||||
return array(
|
||||
array( 'disableContentHandlerUseDB' ),
|
||||
|
||||
// 1.23
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue