diff -u b/core/includes/database.inc b/core/includes/database.inc --- b/core/includes/database.inc +++ b/core/includes/database.inc @@ -654,12 +654,11 @@ * The name of the index. * @param $fields * An array of field names. - * - * @deprecated in Drupal 8.0.x-dev and will be removed before Drupal 9.0.0. - * Use \Drupal\Core\Database\Schema::addNormalizedIndex() instead. + * @param array $spec + * A table specification. */ -function db_add_index($table, $name, $fields) { - return Database::getConnection()->schema()->addIndex($table, $name, $fields); +function db_add_index($table, $name, $fields, array $spec) { + return Database::getConnection()->schema()->addIndex($table, $name, $fields, $spec); } /** diff -u b/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php b/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php --- b/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php +++ b/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php @@ -9,7 +9,6 @@ use Drupal\Core\Database\Database; use Drupal\Core\Database\Query\Condition; -use Drupal\Core\Database\SchemaIndexNotInSpecException; use Drupal\Core\Database\SchemaObjectExistsException; use Drupal\Core\Database\SchemaObjectDoesNotExistException; use Drupal\Core\Database\Schema as DatabaseSchema; @@ -300,13 +299,13 @@ * Shortens indexes to 191 characters if they apply to utf8mb4-encoded * fields, in order to comply with the InnoDB index limitation of 756 bytes. * - * @param $spec + * @param array $spec * The table specification. * * @return array * List of shortened indexes. */ - protected function getNormalizedIndexes($spec) { + protected function getNormalizedIndexes(array $spec) { $indexes = parent::getNormalizedIndexes($spec); foreach ($indexes as $index_name => $index_fields) { foreach ($index_fields as $index_key => $index_field) { @@ -487,28 +486,14 @@ return TRUE; } - public function addIndex($table, $name, $fields) { - if (!$this->tableExists($table)) { - throw new SchemaObjectDoesNotExistException(t("Cannot add index @name to table @table: table doesn't exist.", array('@table' => $table, '@name' => $name))); - } - if ($this->indexExists($table, $name)) { - throw new SchemaObjectExistsException(t("Cannot add index @name to table @table: index already exists.", array('@table' => $table, '@name' => $name))); - } - - $this->connection->query('ALTER TABLE {' . $table . '} ADD INDEX `' . $name . '` (' . $this->createKeySql($fields) . ')'); - } - - public function addNormalizedIndex($table, $name, $spec) { + /** + * {@inheritdoc} + */ + public function addIndex($table, $name, $fields, array $spec) { + $spec['indexes'][$name] = $fields; $indexes = $this->getNormalizedIndexes($spec); - if (!isset($indexes[$name])) { - throw new SchemaIndexNotInSpecException(t("The index @name doesn't exist in the @table table specification.", array('@table' => $table, '@name' => $name))); - } - if (!$this->tableExists($table)) { - throw new SchemaObjectDoesNotExistException(t("Cannot add index @name to table @table: table doesn't exist.", array('@table' => $table, '@name' => $name))); - } - if ($this->indexExists($table, $name)) { - throw new SchemaObjectExistsException(t("Cannot add index @name to table @table: index already exists.", array('@table' => $table, '@name' => $name))); - } + + $this->validateIndex($table, $name); $this->connection->query('ALTER TABLE {' . $table . '} ADD INDEX `' . $name . '` (' . $this->createKeySql($indexes[$name]) . ')'); } diff -u b/core/lib/Drupal/Core/Database/Driver/pgsql/Schema.php b/core/lib/Drupal/Core/Database/Driver/pgsql/Schema.php --- b/core/lib/Drupal/Core/Database/Driver/pgsql/Schema.php +++ b/core/lib/Drupal/Core/Database/Driver/pgsql/Schema.php @@ -10,7 +10,6 @@ use Drupal\Component\Utility\Unicode; use Drupal\Core\Database\Database; use Drupal\Core\Database\Query\Condition; -use Drupal\Core\Database\SchemaIndexNotInSpecException; use Drupal\Core\Database\SchemaObjectExistsException; use Drupal\Core\Database\SchemaObjectDoesNotExistException; use Drupal\Core\Database\Schema as DatabaseSchema; @@ -638,34 +637,17 @@ return TRUE; } - public function addIndex($table, $name, $fields) { - if (!$this->tableExists($table)) { - throw new SchemaObjectDoesNotExistException(t("Cannot add index @name to table @table: table doesn't exist.", array('@table' => $table, '@name' => $name))); - } - if ($this->indexExists($table, $name)) { - throw new SchemaObjectExistsException(t("Cannot add index @name to table @table: index already exists.", array('@table' => $table, '@name' => $name))); - } + /** + * {@inheritdoc} + */ + public function addIndex($table, $name, $fields, array $spec) { + $spec['indexes'][$name] = $fields; + $this->validateIndex($table, $name); $this->connection->query($this->_createIndexSql($table, $name, $fields)); $this->resetTableInformation($table); } - public function addNormalizedIndex($table, $name, $spec) { - $indexes = $this->getNormalizedIndexes($spec); - if (!isset($indexes[$name])) { - throw new SchemaIndexNotInSpecException(t("The index @name doesn't exist in the @table table specification.", array('@table' => $table, '@name' => $name))); - } - if (!$this->tableExists($table)) { - throw new SchemaObjectDoesNotExistException(t("Cannot add index @name to table @table: table doesn't exist.", array('@table' => $table, '@name' => $name))); - } - if ($this->indexExists($table, $name)) { - throw new SchemaObjectExistsException(t("Cannot add index @name to table @table: index already exists.", array('@table' => $table, '@name' => $name))); - } - - $this->connection->query($this->_createIndexSql($table, $name, $indexes[$name])); - $this->resetTableInformation($table); - } - public function dropIndex($table, $name) { if (!$this->indexExists($table, $name)) { return FALSE; diff -u b/core/lib/Drupal/Core/Database/Driver/sqlite/Schema.php b/core/lib/Drupal/Core/Database/Driver/sqlite/Schema.php --- b/core/lib/Drupal/Core/Database/Driver/sqlite/Schema.php +++ b/core/lib/Drupal/Core/Database/Driver/sqlite/Schema.php @@ -8,7 +8,6 @@ namespace Drupal\Core\Database\Driver\sqlite; use Drupal\Component\Utility\Unicode; -use Drupal\Core\Database\SchemaIndexNotInSpecException; use Drupal\Core\Database\SchemaObjectExistsException; use Drupal\Core\Database\SchemaObjectDoesNotExistException; use Drupal\Core\Database\Schema as DatabaseSchema; @@ -583,35 +582,14 @@ return $key_definition; } - public function addIndex($table, $name, $fields) { - if (!$this->tableExists($table)) { - throw new SchemaObjectDoesNotExistException(t("Cannot add index @name to table @table: table doesn't exist.", array('@table' => $table, '@name' => $name))); - } - if ($this->indexExists($table, $name)) { - throw new SchemaObjectExistsException(t("Cannot add index @name to table @table: index already exists.", array('@table' => $table, '@name' => $name))); - } - - $schema['indexes'][$name] = $fields; - $statements = $this->createIndexSql($table, $schema); - foreach ($statements as $statement) { - $this->connection->query($statement); - } - } - - public function addNormalizedIndex($table, $name, $spec) { - $indexes = $this->getNormalizedIndexes($spec); - if (!isset($indexes[$name])) { - throw new SchemaIndexNotInSpecException(t("The index @name doesn't exist in the @table table specification.", array('@table' => $table, '@name' => $name))); - } - if (!$this->tableExists($table)) { - throw new SchemaObjectDoesNotExistException(t("Cannot add index @name to table @table: table doesn't exist.", array('@table' => $table, '@name' => $name))); - } - if ($this->indexExists($table, $name)) { - throw new SchemaObjectExistsException(t("Cannot add index @name to table @table: index already exists.", array('@table' => $table, '@name' => $name))); - } + /** + * {@inheritdoc} + */ + public function addIndex($table, $name, $fields, array $spec) { + $spec['indexes'][$name] = $fields; + $this->validateIndex($table, $name); - $schema['indexes'][$name] = $indexes[$name]; - $statements = $this->createIndexSql($table, $schema); + $statements = $this->createIndexSql($table, $spec); foreach ($statements as $statement) { $this->connection->query($statement); } diff -u b/core/lib/Drupal/Core/Database/Schema.php b/core/lib/Drupal/Core/Database/Schema.php --- b/core/lib/Drupal/Core/Database/Schema.php +++ b/core/lib/Drupal/Core/Database/Schema.php @@ -413,49 +413,53 @@ * @code * $fields = ['foo', ['bar', 4]]; * @endcode + * @param array $spec + * A table specification, which is used in order to be able to ensure that + * the index length is not too long. * * @throws \Drupal\Core\Database\SchemaObjectDoesNotExistException * If the specified table doesn't exist. * @throws \Drupal\Core\Database\SchemaObjectExistsException * If the specified table already has an index by that name. - * - * @deprecated in Drupal 8.0.x-dev and will be removed before Drupal 9.0.0. - * Use \Drupal\Core\Database\Schema::addNormalizedIndex() instead. */ - abstract public function addIndex($table, $name, $fields); + abstract public function addIndex($table, $name, $fields, array $spec); + /** - * Add an index based on a table specification. + * Validates whether the index is valid. * - * Normalizes the index to database requirements, limiting the - * length if necessary. + * This method ensures that the table exists, that the new index was specified + * and that there is no index with the same name yet. * - * @param $table - * The table to be altered. - * @param $name + * @param string $table + * The table of the index name. + * @param string $name * The name of the index. - * @param $spec - * A table specification. * - * @throws \Drupal\Core\Database\SchemaIndexNotInSpecException - * If the specified index doesn't exist in the table spec. * @throws \Drupal\Core\Database\SchemaObjectDoesNotExistException * If the specified table doesn't exist. * @throws \Drupal\Core\Database\SchemaObjectExistsException * If the specified table already has an index by that name. */ - abstract public function addNormalizedIndex($table, $name, $spec); + protected function validateIndex($table, $name) { + if (!$this->tableExists($table)) { + throw new SchemaObjectDoesNotExistException("Cannot add index '$name' to table '$table': table doesn't exist."); + } + if ($this->indexExists($table, $name)) { + throw new SchemaObjectExistsException("Cannot add index '$name' to table '$table': index already exists."); + } + } /** * Gets normalized indexes from a table specification. * - * @param $spec + * @param array $spec * The table specification. * * @return array * List of shortened indexes. */ - protected function getNormalizedIndexes($spec) { + protected function getNormalizedIndexes(array $spec) { return isset($spec['indexes']) ? $spec['indexes'] : []; } reverted: --- b/core/lib/Drupal/Core/Database/SchemaIndexNotInSpecException.php +++ /dev/null @@ -1,13 +0,0 @@ -getEntitySchemaData($entity_type, $entity_schema) as $table_name => $schema) { if (!empty($schema['indexes'])) { foreach ($schema['indexes'] as $name => $specifier) { - $schema_handler->addNormalizedIndex($table_name, $name, $schema); + $schema_handler->addIndex($table_name, $name, $specifier, $schema); } } if (!empty($schema['unique keys'])) { @@ -1140,7 +1140,7 @@ // Check if the index exists because it might already have been // created as part of the earlier entity type update event. if (!$schema_handler->indexExists($table_name, $name)) { - $schema_handler->addNormalizedIndex($table_name, $name, $schema[$table_name]); + $schema_handler->addIndex($table_name, $name, $specifier, $schema); } } } @@ -1286,7 +1286,6 @@ } $table = $table_mapping->getDedicatedDataTableName($storage_definition); $revision_table = $table_mapping->getDedicatedRevisionTableName($storage_definition); - $schema_copy = $schema; foreach ($schema['indexes'] as $name => $columns) { if (!isset($original_schema['indexes'][$name]) || $columns != $original_schema['indexes'][$name]) { $real_name = $this->getFieldIndexName($storage_definition, $name); @@ -1304,9 +1303,8 @@ $real_columns[] = $table_mapping->getFieldColumnName($storage_definition, $column_name); } } - $schema_copy['indexes'][$real_name] = $real_columns; - $this->database->schema()->addNormalizedIndex($table, $real_name, $schema_copy); - $this->database->schema()->addNormalizedIndex($revision_table, $real_name, $schema_copy); + $this->database->schema()->addIndex($table, $real_name, $real_columns, $schema); + $this->database->schema()->addIndex($revision_table, $real_name, $real_columns, $schema); } } $this->saveFieldSchemaData($storage_definition, $this->getDedicatedTableSchema($storage_definition)); @@ -1383,7 +1381,7 @@ // Create new indexes and unique keys. if (!empty($schema[$table_name]['indexes'])) { foreach ($schema[$table_name]['indexes'] as $name => $specifier) { - $schema_handler->addNormalizedIndex($table_name, $name, $schema[$table_name]); + $schema_handler->addIndex($table_name, $name, $specifier, $schema[$table_name]); } } if (!empty($schema[$table_name]['unique keys'])) { diff -u b/core/modules/system/src/Tests/Database/SchemaTest.php b/core/modules/system/src/Tests/Database/SchemaTest.php --- b/core/modules/system/src/Tests/Database/SchemaTest.php +++ b/core/modules/system/src/Tests/Database/SchemaTest.php @@ -99,7 +99,7 @@ $index_exists = Database::getConnection()->schema()->indexExists('test_table', 'test_field'); $this->assertIdentical($index_exists, FALSE, 'Fake index does not exists'); // Add index. - db_add_index('test_table', 'test_field', array('test_field')); + db_add_index('test_table', 'test_field', array('test_field'), $table_specification); // Test for created index and test for the boolean result of indexExists(). $index_exists = Database::getConnection()->schema()->indexExists('test_table', 'test_field'); $this->assertIdentical($index_exists, TRUE, 'Index created.'); @@ -296,9 +296,28 @@ db_create_table('test_table_index_length', $table_specification); // Add a separate index. - $table_specification_new = $table_specification; - $table_specification_new['indexes']['test_separate'] = [['test_field_text', 200]]; - Database::getConnection()->schema()->addNormalizedIndex('test_table_index_length', 'test_separate', $table_specification_new); + $schema_object = Database::getConnection()->schema(); + $schema_object->addIndex('test_table_index_length', 'test_separate', [['test_field_text', 200]], $table_specification); + $table_specification_with_new_index = $table_specification; + $table_specification_with_new_index['indexes']['test_separate'] = [['test_field_text', 200]]; + + // Ensure that the exceptions of addIndex are thrown as expected. + + try { + $schema_object->addIndex('test_table_index_length', 'test_separate', [['test_field_text', 200]], $table_specification); + $this->fail('\Drupal\Core\Database\SchemaObjectExistsException exception missed.'); + } + catch (SchemaObjectExistsException $e) { + $this->pass('\Drupal\Core\Database\SchemaObjectExistsException thrown when index already exists.'); + } + + try { + $schema_object->addIndex('test_table_non_existing', 'test_separate', [['test_field_text', 200]], $table_specification); + $this->fail('\Drupal\Core\Database\SchemaObjectDoesNotExistException exception missed.'); + } + catch (SchemaObjectDoesNotExistException $e) { + $this->pass('\Drupal\Core\Database\SchemaObjectDoesNotExistException thrown when index already exists.'); + } // Get index information. $results = db_query('SHOW INDEX FROM {test_table_index_length}'); @@ -328,7 +347,7 @@ // Count the number of columns defined in the indexes. $column_count = 0; - foreach ($table_specification_new['indexes'] as $index) { + foreach ($table_specification_with_new_index['indexes'] as $index) { foreach ($index as $field) { $column_count++; } only in patch2: unchanged: --- a/core/modules/system/tests/modules/update_test_schema/update_test_schema.install +++ b/core/modules/system/tests/modules/update_test_schema/update_test_schema.install @@ -35,7 +35,14 @@ function update_test_schema_schema() { * Schema version 8001. */ function update_test_schema_update_8001() { + $table = [ + 'fields' => [ + 'a' => ['type' => 'int', 'not null' => TRUE], + 'b' => ['type' => 'blob', 'not null' => FALSE], + ], + ]; + // Add a column. - db_add_index('update_test_schema_table', 'test', ['a']); + db_add_index('update_test_schema_table', 'test', ['a'], $table); } }