Как удалить уникальный ключ в крючке обновления
У меня есть первичный ключ и уникальный ключ в схеме моих модулей. Мне нужно удалить уникальный ключ.
Удалить индекс an просто:
function draggableviews_update_7205() {
if (db_index_exists('draggableviews_structure', 'entity_id')) {
db_drop_index('draggableviews_structure', 'entity_id', array('entity_id'));
}
}
Существует функция db_index_exists(). Существует функция db_drop_unique_key() и db_add_unique_key(), но нет функции db_unique_key_exist().
Как удалить уникальный ключ в крючке обновления?
2 answers
Все классы основных схем (mysql, pgsql и sqlite) проверяют наличие ограничения перед фактическим удалением, поэтому вам не нужно проверять себя. Если вы это сделаете, то на самом деле вы напрасно удваиваете объем операций с БД.
Чтобы охватить все возможные варианты, ваш код может выглядеть примерно так:
try {
if (db_drop_unique_key($table, $name)) {
// Constraint was found and removed.
}
else {
// Constraint was not found, nothing was altered.
}
}
catch (PDOException $e) {
// Constraint was found, but something went wrong, see $e->getMessage() for more info.
throw new DrupalUpdateException($e->getMessage);
}
Кстати, ограничение уникальности обрабатывается классами основных схем так же, как и индекс, поэтому db_index_exists()
можно использовать и для их проверки.
Функция удаления уникального ключа заключается в db_drop_unique_key()
. Вам не нужно сначала проверять, существует ли уникальный ключ, так как все классы баз данных, реализованные в Drupal, сначала проверяют, существует ли уникальный ключ.
// DatabaseSchema_mysql
public function dropUniqueKey($table, $name) {
if (!$this->indexExists($table, $name)) {
return FALSE;
}
$this->connection->query('ALTER TABLE {' . $table . '} DROP KEY `' . $name . '`');
return TRUE;
}
// DatabaseSchema_pqsql
public function dropUniqueKey($table, $name) {
if (!$this->constraintExists($table, $name . '_key')) {
return FALSE;
}
$this->connection->query('ALTER TABLE {' . $table . '} DROP CONSTRAINT "' . $this->prefixNonTable($table, $name, 'key') . '"');
return TRUE;
}
// DatabaseSchema_sqlite
public function dropUniqueKey($table, $name) {
if (!$this->indexExists($table, $name)) {
return FALSE;
}
$info = $this->getPrefixInfo($table);
$this->connection->query('DROP INDEX ' . $info['schema'] . '.' . $info['table'] . '_' . $name);
return TRUE;
}
Нет ни db_unique_key_exists()
, ни db_primary_key_exists()
, и они вам действительно не нужны, так как методы, используемые для их удаления, сначала проверяют, существуют ли они.
Что касается использования db_index_exists()
, вы не можете использовать его для уникальных/первичных ключей, потому что он не гарантирует совместимость со всеми ядрами баз данных. Фактически, компонент database engine для PostgreSQL использует DatabaseSchema_pgsql::constraintExists()
чтобы проверить, существует ли уникальный/первичный ключ.
// DatabaseSchema_pgsql
public function dropPrimaryKey($table) {
if (!$this->constraintExists($table, 'pkey')) {
return FALSE;
}
$this->connection->query('ALTER TABLE {' . $table . '} DROP CONSTRAINT ' . $this->prefixNonTable($table, 'pkey'));
return TRUE;
}