public function Schema::addField in Drupal driver for SQL Server and SQL Azure 8.2
Same name and namespace in other branches
- 8 drivers/lib/Drupal/Driver/Database/sqlsrv/Schema.php \Drupal\Driver\Database\sqlsrv\Schema::addField()
- 3.0.x drivers/lib/Drupal/Driver/Database/sqlsrv/Schema.php \Drupal\Driver\Database\sqlsrv\Schema::addField()
Override DatabaseSchema::addField().
@status complete
Overrides Schema::addField
1 call to Schema::addField()
- Schema::changeField in drivers/
lib/ Drupal/ Driver/ Database/ sqlsrv/ Schema.php - Override DatabaseSchema::changeField().
File
- drivers/
lib/ Drupal/ Driver/ Database/ sqlsrv/ Schema.php, line 683 - Definition of Drupal\Driver\Database\sqlsrv\Schema
Class
Namespace
Drupal\Driver\Database\sqlsrvCode
public function addField($table, $field, $spec, $new_keys = []) {
if (!$this
->tableExists($table)) {
throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add field %table.%field: table doesn't exist.", array(
'%field' => $field,
'%table' => $table,
)));
}
if ($this
->fieldExists($table, $field)) {
throw new DatabaseSchemaObjectExistsException(t("Cannot add field %table.%field: field already exists.", array(
'%field' => $field,
'%table' => $table,
)));
}
/** @var Transaction $transaction */
$transaction = $this->connection
->startTransaction(null, DatabaseTransactionSettings::GetDDLCompatibleDefaults());
// Prepare the specifications.
$spec = $this
->processField($spec);
// Clear column information for table.
$this
->getTableIntrospectionInvalidate($table);
// Use already prefixed table name.
$table_prefixed = $this->connection
->prefixTable($table);
// If the field is declared NOT NULL, we have to first create it NULL insert
// the initial data (or populate default values) and then switch to NOT NULL.
$fixnull = false;
if (!empty($spec['not null'])) {
$fixnull = true;
$spec['not null'] = false;
}
// Create the field.
// Because the default values of fields can contain string literals
// with braces, we CANNOT allow the driver to prefix tables because the algorithm
// to do so is a crappy str_replace.
$query = "ALTER TABLE {$table_prefixed} ADD ";
$query .= $this
->createFieldSql($table, $field, $spec);
$this->connection
->query_direct($query, [], array(
'prefix_tables' => false,
));
// Clear column information for table.
$this
->getTableIntrospectionInvalidate($table);
// Load the initial data.
if (isset($spec['initial'])) {
$this->connection
->update($table)
->fields(array(
$field => $spec['initial'],
))
->execute();
}
// Switch to NOT NULL now.
if ($fixnull === true) {
// There is no warranty that the old data did not have NULL values, we need to populate
// nulls with the default value because this won't be done by MSSQL by default.
if (isset($spec['default'])) {
$default_expression = $this->connection
->Scheme()
->DefaultValueExpression($spec['sqlsrv_type'], $spec['default']);
$this->connection
->query_direct("UPDATE [{$table_prefixed}] SET [{$field}] = {$default_expression} WHERE [{$field}] IS NULL", [], array(
'prefix_tables' => false,
));
}
// Now it's time to make this non-nullable.
$spec['not null'] = true;
$this->connection
->query_direct("ALTER TABLE [{$table_prefixed}] ALTER COLUMN " . $this
->createFieldSql($table, $field, $spec, true), [], array(
'prefix_tables' => false,
));
}
// Add the new keys.
if (isset($new_keys)) {
$this
->recreateTableKeys($table, $new_keys);
}
// Commit.
$transaction
->commit();
// Add column comment.
if (!empty($spec['description'])) {
$comment = $this
->prepareComment($spec['description'], Scheme::COMMENT_MAX_BYTES);
$this
->CommentCreateOrUpdate($comment, $table, $field);
}
// Clear column information for table.
$this
->getTableIntrospectionInvalidate($table);
}