$this->extensionUpdates[] = array( 'dropField', $tableName, $columnName, $sqlPath, true );
}
+ /**
+ * Drop an index from an extension table
+ *
+ * @since 1.21
+ *
+ * @param $tableName string The table name
+ * @param $indexName string The index name
+ * @param $sqlPath string The path to the SQL change path
+ */
+ public function dropExtensionIndex( $tableName, $indexName, $sqlPath ) {
+ $this->extensionUpdates[] = array( 'dropIndex', $tableName, $indexName, $sqlPath, true );
+ }
+
/**
*
* @since 1.20
$this->extensionUpdates[] = array( 'dropTable', $tableName, $sqlPath, true );
}
+ /**
+ * Rename an index on an extension table
+ *
+ * @since 1.21
+ *
+ * @param $tableName string The table name
+ * @param $oldIndexName string The old index name
+ * @param $newIndexName string The new index name
+ * @param $skipBothIndexExistWarning Boolean: Whether to warn if both the old and the new indexes exist. [facultative; by default, false]
+ * @param $sqlPath string The path to the SQL change path
+ */
+ public function renameExtensionIndex( $tableName, $oldIndexName, $newIndexName, $sqlPath, $skipBothIndexExistWarning = false ) {
+ $this->extensionUpdates[] = array( 'renameIndex', $tableName, $oldIndexName, $newIndexName, $skipBothIndexExistWarning, $sqlPath, true );
+ }
+
+ /**
+ * @since 1.21
+ *
+ * @param $tableName string The table name
+ * @param $fieldName string The field to be modified
+ * @param $sqlPath string The path to the SQL change path
+ */
+ public function modifyExtensionField( $tableName, $fieldName, $sqlPath) {
+ $this->extensionUpdates[] = array( 'modifyField', $tableName, $fieldName, $sqlPath, true );
+ }
+
/**
*
* @since 1.20
$this->db->fieldExists( 'updatelog', 'ul_value', __METHOD__ );
}
+ /**
+ * Returns whether updates should be executed on the database table $name.
+ * Updates will be prevented if the table is a shared table and it is not
+ * specified to run updates on shared tables.
+ *
+ * @param $name String table name
+ * @return bool
+ */
+ protected function doTable( $name ) {
+ global $wgSharedDB, $wgSharedTables;
+
+ // Don't bother to check $wgSharedTables if there isn't a shared database
+ // or the user actually also wants to do updates on the shared database.
+ if ( $wgSharedDB === null || $this->shared ) {
+ return true;
+ }
+
+ return !in_array( $name, $wgSharedTables );
+ }
+
/**
* Before 1.17, we used to handle updates via stuff like
* $wgExtNewTables/Fields/Indexes. This is nasty :) We refactored a lot
*/
protected function getOldGlobalUpdates() {
global $wgExtNewFields, $wgExtNewTables, $wgExtModifiedFields,
- $wgExtNewIndexes, $wgSharedDB, $wgSharedTables;
-
- $doUser = $this->shared ?
- $wgSharedDB && in_array( 'user', $wgSharedTables ) :
- !$wgSharedDB || !in_array( 'user', $wgSharedTables );
+ $wgExtNewIndexes;
$updates = array();
}
foreach ( $wgExtNewFields as $fieldRecord ) {
- if ( $fieldRecord[0] != 'user' || $doUser ) {
- $updates[] = array(
- 'addField', $fieldRecord[0], $fieldRecord[1],
- $fieldRecord[2], true
- );
- }
+ $updates[] = array(
+ 'addField', $fieldRecord[0], $fieldRecord[1],
+ $fieldRecord[2], true
+ );
}
foreach ( $wgExtNewIndexes as $fieldRecord ) {
*
* @return Array
*/
- protected abstract function getCoreUpdateList();
+ abstract protected function getCoreUpdateList();
/**
* Append an SQL fragment to the open file handle.
/**
* Applies a SQL patch
+ *
* @param $path String Path to the patch file
* @param $isFullPath Boolean Whether to treat $path as a relative or not
* @param $msg String Description of the patch
/**
* Add a new table to the database
+ *
* @param $name String Name of the new table
* @param $patch String Path to the patch file
* @param $fullpath Boolean Whether to treat $patch path as a relative or not
* @return Boolean false if this was skipped because schema changes are skipped
*/
protected function addTable( $name, $patch, $fullpath = false ) {
+ if ( !$this->doTable( $name ) ) {
+ return true;
+ }
+
if ( $this->db->tableExists( $name, __METHOD__ ) ) {
$this->output( "...$name table already exists.\n" );
} else {
/**
* Add a new field to an existing table
+ *
* @param $table String Name of the table to modify
* @param $field String Name of the new field
* @param $patch String Path to the patch file
* @return Boolean false if this was skipped because schema changes are skipped
*/
protected function addField( $table, $field, $patch, $fullpath = false ) {
+ if ( !$this->doTable( $table ) ) {
+ return true;
+ }
+
if ( !$this->db->tableExists( $table, __METHOD__ ) ) {
$this->output( "...$table table does not exist, skipping new field patch.\n" );
} elseif ( $this->db->fieldExists( $table, $field, __METHOD__ ) ) {
/**
* Add a new index to an existing table
+ *
* @param $table String Name of the table to modify
* @param $index String Name of the new index
* @param $patch String Path to the patch file
* @return Boolean false if this was skipped because schema changes are skipped
*/
protected function addIndex( $table, $index, $patch, $fullpath = false ) {
+ if ( !$this->doTable( $table ) ) {
+ return true;
+ }
+
if ( !$this->db->tableExists( $table, __METHOD__ ) ) {
$this->output( "...skipping: '$table' table doesn't exist yet.\n" );
- return false;
} else if ( $this->db->indexExists( $table, $index, __METHOD__ ) ) {
$this->output( "...index $index already set on $table table.\n" );
} else {
* @return Boolean false if this was skipped because schema changes are skipped
*/
protected function dropField( $table, $field, $patch, $fullpath = false ) {
+ if ( !$this->doTable( $table ) ) {
+ return true;
+ }
+
if ( $this->db->fieldExists( $table, $field, __METHOD__ ) ) {
return $this->applyPatch( $patch, $fullpath, "Table $table contains $field field. Dropping" );
} else {
* Drop an index from an existing table
*
* @param $table String: Name of the table to modify
- * @param $index String: Name of the old index
+ * @param $index String: Name of the index
* @param $patch String: Path to the patch file
* @param $fullpath Boolean: Whether to treat $patch path as a relative or not
* @return Boolean false if this was skipped because schema changes are skipped
*/
protected function dropIndex( $table, $index, $patch, $fullpath = false ) {
+ if ( !$this->doTable( $table ) ) {
+ return true;
+ }
+
if ( $this->db->indexExists( $table, $index, __METHOD__ ) ) {
return $this->applyPatch( $patch, $fullpath, "Dropping $index index from table $table" );
} else {
return true;
}
+ /**
+ * Rename an index from an existing table
+ *
+ * @param $table String: Name of the table to modify
+ * @param $oldIndex String: Old name of the index
+ * @param $newIndex String: New name of the index
+ * @param $skipBothIndexExistWarning Boolean: Whether to warn if both the old and the new indexes exist.
+ * @param $patch String: Path to the patch file
+ * @param $fullpath Boolean: Whether to treat $patch path as a relative or not
+ * @return Boolean false if this was skipped because schema changes are skipped
+ */
+ protected function renameIndex( $table, $oldIndex, $newIndex, $skipBothIndexExistWarning, $patch, $fullpath = false ) {
+ if ( !$this->doTable( $table ) ) {
+ return true;
+ }
+
+ // First requirement: the table must exist
+ if ( !$this->db->tableExists( $table, __METHOD__ ) ) {
+ $this->output( "...skipping: '$table' table doesn't exist yet.\n" );
+ return true;
+ }
+
+ // Second requirement: the new index must be missing
+ if ( $this->db->indexExists( $table, $newIndex, __METHOD__ ) ) {
+ $this->output( "...index $newIndex already set on $table table.\n" );
+ if ( !$skipBothIndexExistWarning && $this->db->indexExists( $table, $oldIndex, __METHOD__ ) ) {
+ $this->output( "...WARNING: $oldIndex still exists, despite it has been renamed into $newIndex (which also exists).\n" .
+ " $oldIndex should be manually removed if not needed anymore.\n" );
+ }
+ return true;
+ }
+
+ // Third requirement: the old index must exist
+ if ( !$this->db->indexExists( $table, $oldIndex, __METHOD__ ) ) {
+ $this->output( "...skipping: index $oldIndex doesn't exist.\n" );
+ return true;
+ }
+
+ // Requirements have been satisfied, patch can be applied
+ return $this->applyPatch( $patch, $fullpath, "Renaming index $oldIndex into $newIndex to table $table" );
+ }
+
/**
* If the specified table exists, drop it, or execute the
* patch if one is provided.
* @return Boolean false if this was skipped because schema changes are skipped
*/
public function dropTable( $table, $patch = false, $fullpath = false ) {
+ if ( !$this->doTable( $table ) ) {
+ return true;
+ }
+
if ( $this->db->tableExists( $table, __METHOD__ ) ) {
$msg = "Dropping table $table";
* @return Boolean false if this was skipped because schema changes are skipped
*/
public function modifyField( $table, $field, $patch, $fullpath = false ) {
+ if ( !$this->doTable( $table ) ) {
+ return true;
+ }
+
$updateKey = "$table-$field-$patch";
if ( !$this->db->tableExists( $table, __METHOD__ ) ) {
$this->output( "...$table table does not exist, skipping modify field patch.\n" );
} elseif( $this->updateRowExists( $updateKey ) ) {
$this->output( "...$field in table $table already modified by patch $patch.\n" );
} else {
- return $this->applyPatch( $patch, $fullpath, "Modifying $field field of table $table" );
$this->insertUpdateRow( $updateKey );
+ return $this->applyPatch( $patch, $fullpath, "Modifying $field field of table $table" );
}
return true;
}
protected function doUpdateTranscacheField() {
if ( $this->updateRowExists( 'convert transcache field' ) ) {
$this->output( "...transcache tc_time already converted.\n" );
- return;
+ return true;
}
return $this->applyPatch( 'patch-tc-timestamp.sql', false,