You are here

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

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

Override DatabaseSchema::addUniqueKey().

@status tested

Overrides DatabaseSchema::addUniqueKey

3 calls to DatabaseSchema_sqlsrv::addUniqueKey()
DatabaseSchema_sqlsrv::changeField in sqlsrv/schema.inc
Override DatabaseSchema::changeField().
DatabaseSchema_sqlsrv::createTable in sqlsrv/schema.inc
Create a new table from a Drupal table definition.
DatabaseSchema_sqlsrv::recreateTableKeys in sqlsrv/schema.inc
Re-create keys associated to a table.

File

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

Class

DatabaseSchema_sqlsrv

Code

public function addUniqueKey($table, $name, $fields) {
  if (!$this
    ->tableExists($table)) {
    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(' . $field[0] . ' AS varbinary(max)),1,' . $field[1] . ')';
    }
    else {
      $column_expression[] = 'CAST(' . $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('ALTER TABLE {' . $table . '} ADD __unique_' . $name . " AS CAST(HashBytes('MD4', COALESCE(" . $column_expression . ", CAST(__pk AS varbinary(max)))) AS varbinary(16))");
  $this->connection
    ->query('CREATE UNIQUE INDEX ' . $name . '_unique ON [{' . $table . '}] (__unique_' . $name . ')');
}