You are here

public function DatabaseSchema_sqlsrv::addUniqueKey in Drupal driver for SQL Server and SQL Azure 7.3

Same name and namespace in other branches
  1. 7 sqlsrv/schema.inc \DatabaseSchema_sqlsrv::addUniqueKey()
  2. 7.2 sqlsrv/schema.inc \DatabaseSchema_sqlsrv::addUniqueKey()

Override DatabaseSchema::addUniqueKey().

@status tested

Overrides DatabaseSchema::addUniqueKey

2 calls to DatabaseSchema_sqlsrv::addUniqueKey()
DatabaseSchema_sqlsrv::createTable in sqlsrv/schema.inc
{@Inheritdoc}
DatabaseSchema_sqlsrv::recreateTableKeys in sqlsrv/schema.inc
Re-create keys associated to a table.

File

sqlsrv/schema.inc, line 1594
Database schema code for Microsoft SQL Server database servers.

Class

DatabaseSchema_sqlsrv

Code

public function addUniqueKey($table, $name, $fields) {
  if (!$this
    ->tableExists($table, TRUE)) {
    throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add unique key %name to table %table: table doesn't exist.", array(
      '%table' => $table,
      '%name' => $name,
    )));
  }
  if ($this
    ->uniqueKeyExists($table, $name)) {
    throw new DatabaseSchemaObjectExistsException(t("Cannot add unique key %name to table %table: unique key already exists.", array(
      '%table' => $table,
      '%name' => $name,
    )));
  }
  $this
    ->createTechnicalPrimaryColumn($table);

  // Then, build a expression based on the columns.
  $column_expression = array();
  foreach ($fields as $field) {
    if (is_array($field)) {
      $column_expression[] = 'SUBSTRING(CAST(' . $this->connection
        ->escapeField($field[0]) . ' AS varbinary(max)), 1,' . $field[1] . ')';
    }
    else {
      $column_expression[] = 'CAST(' . $this->connection
        ->escapeField($field) . ' AS varbinary(max))';
    }
  }
  $column_expression = implode(' + ', $column_expression);

  // Build a computed column based on the expression that replaces NULL
  // values with the globally unique identifier generated previously.
  // This is (very) unlikely to result in a collision with any actual value
  // in the columns of the unique key.
  $this->connection
    ->query_direct("ALTER TABLE {{$table}} ADD __unique_{$name} AS CAST(HashBytes('MD4', COALESCE({$column_expression}, CAST({$this->TECHNICAL_PK_COLUMN_NAME} AS varbinary(max)))) AS varbinary(16))");
  $this->connection
    ->query_direct("CREATE UNIQUE INDEX {$name}_unique ON [{{$table}}] (__unique_{$name})");
}