Drupal → Использование hook_update_N()
Хук 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. Пример.
Комментарии
спасибо,
еще бы добавил проверку на db_field_exists перед добавлением
Важный нюанс в случае использования сочетания hook_install() hook_update_N() и batch api
В случае вызова из hook_update_N() индекс финиша пишется так:
$sandbox['#finished']
В случае вызова из hook_install() как в классическом batch api:
$sandbox['finished']
Почему так не знаю.
Оставить комментарий