<?php
+
/**
* @defgroup Database Database
*
protected $mTrxPreCommitCallbacks = array();
protected $mTablePrefix;
+ protected $mSchema;
protected $mFlags;
protected $mForeign;
protected $mErrorCount = 0;
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.
*
* @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;
$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" );
$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;
}
$this->mTablePrefix = $tablePrefix;
}
+ /** Get the database schema*/
+ if ( $schema == 'get from global' ) {
+ $this->mSchema = $wgDBmwschema;
+ } else {
+ $this->mSchema = $schema;
+ }
+
$this->mForeign = $foreign;
if ( $user ) {
*
* @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
*/
" 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(
'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
);
}
/**
- * Make UPDATE options for the DatabaseBase::update function
+ * Make UPDATE options array for DatabaseBase::makeUpdateOptions
*
- * @param array $options The options passed to DatabaseBase::update
- * @return string
+ * @param array $options
+ * @return array
*/
- protected function makeUpdateOptions( $options ) {
+ protected function makeUpdateOptionsArray( $options ) {
if ( !is_array( $options ) ) {
$options = array( $options );
}
$opts[] = 'IGNORE';
}
+ return $opts;
+ }
+
+ /**
+ * Make UPDATE options for the DatabaseBase::update function
+ *
+ * @param array $options The options passed to DatabaseBase::update
+ * @return string
+ */
+ protected function makeUpdateOptions( $options ) {
+ $opts = $this->makeUpdateOptionsArray( $options );
+
return implode( ' ', $opts );
}
* @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
# We reverse the explode so that database.table and table both output
# the correct table.
$dbDetails = explode( '.', $name, 2 );
- if ( count( $dbDetails ) == 2 ) {
+ 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
&& 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 ) ) {
}
$retJOIN[] = $tableClause;
- // Is there an INDEX clause for this table?
} elseif ( isset( $use_index[$alias] ) ) {
+ // Is there an INDEX clause for this table?
$tableClause = $this->tableNameWithAlias( $table, $alias );
$tableClause .= ' ' . $this->useIndexClause(
- implode( ',', (array)$use_index[$alias] ) );
+ implode( ',', (array)$use_index[$alias] )
+ );
$ret[] = $tableClause;
} else {
* @param string $delTable The table to delete from.
* @param string $joinTable The other table.
* @param string $delVar The variable to join on, in the first table.
- * @param string$joinVar The variable to join on, in the second table.
+ * @param string $joinVar The variable to join on, in the second table.
* @param array $conds Condition array of field names mapped to variables,
* ANDed together in the WHERE clause
* @param string $fname Calling function name (use __METHOD__) for logs/profiling