Хук hook_update_N()
производит единоразовое выполнение кода, необходимое для обновления модуля на более новую версию.
В основном в этом хуке изменяют схему бд, но ничто не мешает выполнить в нём любой другой код.
N
в имени функции должно быть четырёхзначным числом, сформированным по следующему правилу:
- Первая цифра — номер мажорной версии Drupal. Например для Drupal 6.x это будет цифра
6
, для Drupal 7.x соответственно цифра7
- Вторая цифра — номер мажорной версии модуля. Например для модуля с версией 7.x-1.x это будет цифра
1
, для модуля с версией 7.x-2.x соответственно цифра2
.0
означает, что хук нужно выполнить только при обновлении ядра Drupal до версии, указанной первой цифрой. - Третья и четвёртая цифра — порядковый номер обновления, начиная с
00
Примеры именования функции:
/**
* Первое обновление модуля в рамках версии 7.x-1.x
*/
function modulename_update_7100() {
//
}
/**
* Второе обновление модуля в рамках версии 7.x-1.x
*/
function modulename_update_7101() {
//
}
/**
* Первое обновление модуля в рамках версии 7.x-2.x
*/
function modulename_update_7200() {
//
}
Примеры реализации хука:
/**
* Добавление нового поля newcol в таблицу {mytable1}.
*/
function modulename_update_7100() {
db_add_field('mytable1', 'newcol', array(
'type' => 'varchar',
'description' => "New Col",
'length' => 20,
'not null' => FALSE,
));
}
/**
* Создание новой таблицы {mytable2}.
*/
function mymodule_update_7101() {
db_create_table('mytable2', array(
'fields' => array(
'field1' => array(
'type' => 'serial',
'not null' => TRUE,
),
'field2' => array(
'type' => 'varchar',
'length' => '255',
'not null' => TRUE,
'default' => '',
),
),
));
}
/**
* Переименование колонки {mytable}.field1 в {mytable}.field2.
*/
function mymodule_update_7103() {
db_change_field('mytable', 'field1', 'field2', array(/* описание колонки */);
}
/**
* Изменение типа колонки {mytable}.myfield с varchar на text.
*/
function mymodule_update_7104() {
db_change_field('mytable', 'myfield', 'myfield', array(
'type' => 'text',
'size' => 'normal',
'not null' => TRUE,
);
}
Длительные обновления, не помещающиеся в max_execution_time
, должны быть разбиты на части и запускаться с помощью Batch API (пример).
Написанное актуально для
Drupal 7
Комментарии
спасибо,
еще бы добавил проверку на db_field_exists перед добавлением
Важный нюанс в случае использования сочетания hook_install() hook_update_N() и batch api
В случае вызова из hook_update_N() индекс финиша пишется так:
$sandbox['#finished']
В случае вызова из hook_install() как в классическом batch api:
$sandbox['finished']
Почему так не знаю.