You are here

public function Schema::addIndex in Drupal driver for SQL Server and SQL Azure 3.0.x

Same name and namespace in other branches
  1. 8.2 drivers/lib/Drupal/Driver/Database/sqlsrv/Schema.php \Drupal\Driver\Database\sqlsrv\Schema::addIndex()
  2. 8 drivers/lib/Drupal/Driver/Database/sqlsrv/Schema.php \Drupal\Driver\Database\sqlsrv\Schema::addIndex()

Add an index.

@todo remove the $spec argument whenever schema introspection is added.

Parameters

$table: The table to be altered.

$name: The name of the index.

$fields: An array of field names or field information; if field information is passed, it's an array whose first element is the field name and whose second is the maximum length in the index. For example, the following will use the full length of the `foo` field, but limit the `bar` field to 4 characters:

$fields = [
  'foo',
  [
    'bar',
    4,
  ],
];

array $spec: The table specification for the table to be altered. This is used in order to be able to ensure that the index length is not too long. This schema definition can usually be obtained through hook_schema(), or in case the table was created by the Entity API, through the schema handler listed in the entity class definition. For reference, see SqlContentEntityStorageSchema::getDedicatedTableSchema() and SqlContentEntityStorageSchema::getSharedTableFieldSchema().

In order to prevent human error, it is recommended to pass in the complete table specification. However, in the edge case of the complete table specification not being available, we can pass in a partial table definition containing only the fields that apply to the index:

$spec = [
  // Example partial specification for a table:
  'fields' => [
    'example_field' => [
      'description' => 'An example field',
      'type' => 'varchar',
      'length' => 32,
      'not null' => TRUE,
      'default' => '',
    ],
  ],
  'indexes' => [
    'table_example_field' => [
      'example_field',
    ],
  ],
];

Note that the above is a partial table definition and that we would usually pass a complete table definition as obtained through hook_schema() instead.

Throws

\Drupal\Core\Database\SchemaObjectDoesNotExistException If the specified table doesn't exist.

\Drupal\Core\Database\SchemaObjectExistsException If the specified table already has an index by that name.

Overrides Schema::addIndex

See also

Schema API

hook_schema()

3 calls to Schema::addIndex()
Schema::createPrimaryKey in drivers/lib/Drupal/Driver/Database/sqlsrv/Schema.php
Create primary key.
Schema::createTable in drivers/lib/Drupal/Driver/Database/sqlsrv/Schema.php
Create a new table from a Drupal table definition.
Schema::recreateTableKeys in drivers/lib/Drupal/Driver/Database/sqlsrv/Schema.php
Re-create keys associated to a table.

File

drivers/lib/Drupal/Driver/Database/sqlsrv/Schema.php, line 525

Class

Schema

Namespace

Drupal\Driver\Database\sqlsrv

Code

public function addIndex($table, $name, $fields, array $spec = []) {
  if (!$this
    ->tableExists($table)) {
    throw new SchemaObjectDoesNotExistException(t("Cannot add index %name to table %table: table doesn't exist.", [
      '%table' => $table,
      '%name' => $name,
    ]));
  }
  if ($this
    ->indexExists($table, $name)) {
    throw new SchemaObjectExistsException(t("Cannot add index %name to table %table: index already exists.", [
      '%table' => $table,
      '%name' => $name,
    ]));
  }
  $xml_field = NULL;
  foreach ($fields as $field) {
    if (isset($info['columns'][$field]['type']) && $info['columns'][$field]['type'] == 'xml') {
      $xml_field = $field;
      break;
    }
  }
  $sql = $this
    ->createIndexSql($table, $name, $fields, $xml_field);
  $pk_fields = $this
    ->introspectPrimaryKeyFields($table);
  $size = $this
    ->calculateClusteredIndexRowSizeBytes($table, $pk_fields, TRUE);
  if (!empty($xml_field)) {

    // We can create an XML field, but the current primary key index
    // size needs to be under 128bytes.
    if ($size > self::XML_INDEX_BYTES) {

      // Alright the compress the index.
      $this
        ->compressPrimaryKeyIndex($table, self::XML_INDEX_BYTES);
    }
    $this->connection
      ->query($sql);
    $this
      ->resetColumnInformation($table);
  }
  elseif ($size <= self::NONCLUSTERED_INDEX_BYTES) {
    $this->connection
      ->query($sql);
    $this
      ->resetColumnInformation($table);
  }

  // If the field is too large, do not create an index.
}