public function DatabaseSchema_sqlsrv::changeField in Drupal driver for SQL Server and SQL Azure 7
Same name and namespace in other branches
- 7.3 sqlsrv/schema.inc \DatabaseSchema_sqlsrv::changeField()
- 7.2 sqlsrv/schema.inc \DatabaseSchema_sqlsrv::changeField()
Override DatabaseSchema::changeField().
@status complete
Overrides DatabaseSchema::changeField
File
- sqlsrv/
schema.inc, line 498 - Database schema code for Microsoft SQL Server database servers.
Class
Code
public function changeField($table, $field, $field_new, $spec, $new_keys = array()) {
if (!$this
->fieldExists($table, $field)) {
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot change the definition of field %table.%name: field doesn't exist.", array(
'%table' => $table,
'%name' => $field,
)));
}
if ($field != $field_new && $this
->fieldExists($table, $field_new)) {
throw new DatabaseSchemaObjectExistsException(t("Cannot rename field %table.%name to %name_new: target field already exists.", array(
'%table' => $table,
'%name' => $field,
'%name_new' => $field_new,
)));
}
// SQL Server supports transactional DDL, so we can just start a transaction
// here and pray for the best.
$transaction = $this->connection
->startTransaction();
// Introspect the schema and save the current primary key if the column
// we are modifying is part of it.
$primary_key_sql = $this
->introspectPrimaryKey($table, $field);
// If there is a generated unique key for this field, we will need to
// add it back in when we are done
$unique_key = $this
->uniqueKeyExists($table, $field);
// Drop the related objects.
$this
->dropFieldRelatedObjects($table, $field);
// Start by renaming the current column.
$this->connection
->query('EXEC sp_rename :old, :new, :type', array(
':old' => $this->connection
->prefixTables('{' . $table . '}.' . $field),
':new' => $field . '_old',
':type' => 'COLUMN',
));
// If the field is declared NOT NULL, we have to first create it NULL insert
// the initial data then switch to NOT NULL.
if (!empty($spec['not null']) && !isset($spec['default'])) {
$fixnull = TRUE;
$spec['not null'] = FALSE;
}
// Create a new field.
$this
->addField($table, $field_new, $spec);
// Migrate the data over.
// Explicitly cast the old value to the new value to avoid conversion errors.
$field_spec = $this
->processField($spec);
$this->connection
->query('UPDATE [{' . $table . '}] SET [' . $field_new . '] = CAST([' . $field . '_old] AS ' . $field_spec['sqlsrv_type'] . ')');
// Switch to NOT NULL now.
if (!empty($fixnull)) {
$spec['not null'] = TRUE;
$this->connection
->query('ALTER TABLE {' . $table . '} ALTER COLUMN ' . $this
->createFieldSql($table, $field_new, $this
->processField($spec), TRUE));
}
// Recreate the primary key.
if ($primary_key_sql) {
$this
->recreatePrimaryKey($table, $primary_key_sql);
}
if ($unique_key) {
$fields = array();
$fields[] = $field;
$this
->addUniqueKey($table, $field, $fields);
}
// Drop the old field.
$this
->dropField($table, $field . '_old');
// Add the new keys.
if (isset($new_keys)) {
$this
->recreateTableKeys($table, $new_keys);
}
}