public function DatabaseSchema_sqlsrv::addField in Drupal driver for SQL Server and SQL Azure 7.3
Same name and namespace in other branches
- 7 sqlsrv/schema.inc \DatabaseSchema_sqlsrv::addField()
- 7.2 sqlsrv/schema.inc \DatabaseSchema_sqlsrv::addField()
Override DatabaseSchema::addField().
@status complete
Overrides DatabaseSchema::addField
1 call to DatabaseSchema_sqlsrv::addField()
- DatabaseSchema_sqlsrv::changeField in sqlsrv/
schema.inc - Override DatabaseSchema::changeField().
File
- sqlsrv/
schema.inc, line 995 - Database schema code for Microsoft SQL Server database servers.
Class
Code
public function addField($table, $field, $spec, $new_keys = array()) {
if (!$this
->tableExists($table, TRUE)) {
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 DatabaseTransaction_sqlsrv $transaction */
$transaction = $this->connection
->startTransaction(NULL, DatabaseTransactionSettings::GetDDLCompatibleDefaults());
// Prepare the specifications.
$spec = $this
->processField($spec);
// Clear column information for table.
$this
->queryColumnInformationInvalidate($table);
// Use already prefixed table name.
$table_prefixed = $this->connection
->prefixTables('{' . $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 (isset($spec['not null']) && $spec['not null'] == TRUE) {
$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(), array(
'prefix_tables' => FALSE,
));
// Clear column information for table.
$this
->queryColumnInformationInvalidate($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
->defaultValueExpression($spec['sqlsrv_type'], $spec['default']);
$this->connection
->query_direct("UPDATE [{$table_prefixed}] SET [{$field}] = {$default_expression} WHERE [{$field}] IS NULL", array(), 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(), array(
'prefix_tables' => FALSE,
));
}
// Add the new keys.
if (isset($new_keys)) {
$this
->recreateTableKeys($table, $new_keys);
}
// Commit.
$transaction
->commit();
// Clear column information for table.
$this
->queryColumnInformationInvalidate($table);
}