xandeadx.ru Блог музицирующего веб-девелопера

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. Пример.

Написанное актуально для Drupal 7
Похожие записи

Комментарии RSS

спасибо,
еще бы добавил проверку на 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']

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

Оставить комментарий

Содержимое этого поля является приватным и не будет отображаться публично. Если у вас есть аккаунт в Gravatar, привязанный к этому e-mail адресу, то он будет использован для отображения аватара.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Доступные HTML теги: <a> <i> <b> <strong> <code> <ul> <ol> <li> <blockquote> <em> <s>
  • Строки и параграфы переносятся автоматически.
  • Подсветка кода осуществляется с помощью тегов: <code>, <css>, <html>, <ini>, <javascript>, <sql>, <php>. Поддерживаемые стили выделения кода: <foo>, [foo].

Подробнее о форматировании