Drupal → Использование hook_update_N()

16.04.2012

Хук 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
Похожие записи

Комментарии

Alex Milkovsky
22.11.2012, 00:43

спасибо,
еще бы добавил проверку на db_field_exists перед добавлением

if (!db_field_exists('mytable1', 'newcol')) {
db_add_field('mytable1', 'newcol', array(
    'type' => 'varchar',
    'description' => "New Col",
    'length' => 20,
    'not null' => FALSE,
  ));
}

Важный нюанс в случае использования сочетания hook_install() hook_update_N() и batch api

В случае вызова из hook_update_N() индекс финиша пишется так:
$sandbox['#finished']

В случае вызова из hook_install() как в классическом batch api:
$sandbox['finished']

Почему так не знаю.