You are here

hosting_package.install in Hostmaster (Aegir) 6

Install, update and uninstall for the package management module.

File

modules/hosting/package/hosting_package.install
View source
<?php

/**
 * @file
 *   Install, update and uninstall for the package management module.
 */

/**
 * Implementation of hook_schema().
 */
function hosting_package_schema() {
  $schema['hosting_package'] = array(
    'fields' => array(
      'vid' => array(
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'nid' => array(
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'package_type' => array(
        'type' => 'varchar',
        'length' => 16,
        'not null' => TRUE,
        'default' => '',
      ),
      'short_name' => array(
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'old_short_name' => array(
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'description' => array(
        'type' => 'text',
        'size' => 'big',
        'not null' => TRUE,
      ),
    ),
    'primary key' => array(
      'vid',
    ),
    'indexes' => array(
      'hosting_package_nid_idx' => array(
        'nid',
      ),
    ),
  );
  $schema['hosting_package_instance'] = array(
    'fields' => array(
      'iid' => array(
        'type' => 'serial',
        'not null' => TRUE,
      ),
      'rid' => array(
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'package_id' => array(
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'filename' => array(
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'schema_version' => array(
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'version' => array(
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'version_code' => array(
        'type' => 'int',
        'size' => 'big',
        'not null' => TRUE,
        'default' => 0,
      ),
      'status' => array(
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
    ),
    'primary key' => array(
      'iid',
    ),
    'indexes' => array(
      'hosting_package_rid_idx' => array(
        'rid',
      ),
      'hosting_package_id_idx' => array(
        'package_id',
      ),
    ),
  );
  $schema['hosting_package_languages'] = array(
    'fields' => array(
      'iid' => array(
        'type' => 'int',
        'not null' => TRUE,
      ),
      'language' => array(
        'type' => 'varchar',
        'length' => 12,
        'not null' => TRUE,
        'default' => '',
      ),
    ),
  );
  return $schema;
}

/**
 * Implementation of hook_install().
 */
function hosting_package_install() {

  // Create tables.
  drupal_install_schema('hosting_package');
}

/**
 * Add package description to hosting_package table
 */
function hosting_package_update_1() {
  $ret = array();
  $ret[] = update_sql("ALTER TABLE {hosting_package} ADD COLUMN description longtext NOT NULL default ''");
  return $ret;
}

/**
 * Add localization support for installed sites
 */
function hosting_package_update_2() {
  $ret = array();
  $ret[] = update_sql("CREATE TABLE {hosting_package_languages} (\n    vid int NOT NULL,\n    nid int(10) UNSIGNED NOT NULL,\n    language VARCHAR(12) NOT NULL DEFAULT ''\n  )  /*!40100 DEFAULT CHARACTER SET UTF8 */");
  return $ret;
}

/**
 * No limit on short_name length
 */
function hosting_package_update_3() {
  $ret = array();
  $ret[] = update_sql("ALTER TABLE {hosting_package} MODIFY COLUMN short_name longtext NOT NULL default ''");
  return $ret;
}

/**
 * Package languages are associated to package instances, not packages
 */
function hosting_package_update_4() {
  include_once drupal_get_path('module', 'hosting_task') . '/hosting_task.module';
  $ret = array();
  $ret[] = update_sql("DROP TABLE {hosting_package_languages}");
  $ret[] = update_sql("CREATE TABLE {hosting_package_languages} (\n    iid int UNSIGNED NOT NULL,\n    language VARCHAR(12) NOT NULL DEFAULT ''\n  )  /*!40100 DEFAULT CHARACTER SET UTF8 */");

  // Re-verify all existing platforms
  $result = db_query("SELECT nid FROM {node} WHERE type='platform' AND status=1");
  while ($platform = db_fetch_object($result)) {
    hosting_add_task($platform->nid, 'verify');
  }
  return $ret;
}

/**
 * Denormalize package and package release node types
 */
function hosting_package_update_5() {
  $ret = array();
  $ret[] = update_sql("ALTER TABLE {hosting_package_instance} ADD COLUMN package_id int(10) NOT NULL default '0'");
  $ret[] = update_sql("ALTER TABLE {hosting_package_instance} ADD COLUMN version longtext NOT NULL default ''");
  $ret[] = update_sql("ALTER TABLE {hosting_package_instance} ADD COLUMN filename longtext NOT NULL default ''");
  $ret[] = update_sql("ALTER TABLE {hosting_package_instance} ADD COLUMN schema_version int(10) NOT NULL default '0'");
  $ret[] = update_sql("ALTER TABLE {hosting_package_instance} ADD COLUMN status int(1) NOT NULL default '0'");

  // Now we replace the release ID of platform node types with instance types.
  // This needs to be done from the package module, even though it modifies the
  // hosting_platform table, so we can be _SURE_ that the order of execution is correct.
  $platforms = _hosting_get_platforms();
  foreach ($platforms as $nid => $name) {
    $platform = db_fetch_object(db_query("SELECT release_id FROM {hosting_platform} WHERE nid=%d", $nid));
    $release = db_fetch_object(db_query("SELECT * FROM {hosting_package_release} WHERE nid = %d", $platform->release_id));
    $instance = new stdClass();
    $instance->rid = $nid;
    $instance->package_id = $release->package;
    $instance->version = $release->version;

    // A future step will fill these in from the packages.
    $instance->filename = '';
    $instance->schema_version = 0;
    hosting_package_instance_save($instance);
    hosting_add_task($nid, 'verify');
  }
  $ret[] = update_sql("ALTER TABLE {hosting_platform} DROP COLUMN release_id");

  // Now we iterate through all the package
  $result = db_query("SELECT * FROM {hosting_package_release}");
  while ($release = db_fetch_object($result)) {
    db_query("UPDATE {hosting_package_instance} SET version='%s', schema_version=%d, package_id=%d WHERE release_id=%d", $release->version, $release->schema_version, $release->package, $release->nid);
  }
  $ret[] = update_sql("DELETE FROM {node_revisions} WHERE nid IN (SELECT nid FROM {node} WHERE type='package_release')");
  $ret[] = update_sql("DELETE FROM {node} WHERE type='package_release'");
  $ret[] = update_sql("ALTER TABLE {hosting_package_instance} DROP COLUMN release_id");
  $ret[] = update_sql("ALTER TABLE {hosting_package_instance} DROP COLUMN path");
  $ret[] = update_sql("DROP TABLE {hosting_package_release}");
  return $ret;
}

// Rebuild the package instance database and re-verify all sites.
function hosting_package_update_6() {
  $ret = array();
  $ret[] = update_sql("DELETE FROM {hosting_package_instance}");
  $ret[] = update_sql("UPDATE {sequences} SET id=1 WHERE name='{hosting_package_instance}_iid'");
  $result = db_query("SELECT nid FROM {node} WHERE type='platform' AND status=1");
  while ($platform = db_fetch_object($result)) {
    hosting_add_task($platform->nid, 'verify');
  }
  $result = db_query("SELECT nid FROM {node} WHERE type='site' AND status=1");
  while ($site = db_fetch_object($result)) {
    hosting_add_task($site->nid, 'verify');
  }
  return $ret;
}

/**
 * Turn the iid column of hosting_package_instance into a serial field
 *
 * Required by Drupal 6 update.
 */
function hosting_package_update_7() {
  $ret = array();
  db_drop_primary_key($ret, 'hosting_package_instance');
  db_field_set_no_default($ret, 'hosting_package_instance', 'iid');
  db_change_field($ret, 'hosting_package_instance', 'iid', 'iid', array(
    'type' => 'serial',
    'not null' => TRUE,
  ), array(
    'primary key' => array(
      'iid',
    ),
  ));
  return $ret;
}
function hosting_package_update_8() {
  include_once drupal_get_path('module', 'hosting_package') . '/hosting_package.instance.inc';
  $ret = array();
  db_add_field($ret, 'hosting_package_instance', 'version_code', array(
    'type' => 'int',
    'size' => 'big',
    'not null' => TRUE,
    'default' => 0,
  ));

  // The contents of update 9 was originally inside this function,
  // but due to an error in the regular expression the code needs to be
  // executed again, as such it has been moved.
  return $ret;
}

/**
 * Regenerate the package version codes to fix a error related to the regular expression
 */
function hosting_package_update_9() {
  $ret = array();

  // This code was originally in update 8, but was moved here to avoid people executing the same functionality
  // twice.
  $result = db_query("SELECT iid, version FROM {hosting_package_instance}");
  while ($obj = db_fetch_object($result)) {
    $code = hosting_package_instance_version_code($obj->version);
    db_query("UPDATE {hosting_package_instance} SET version_code = %f WHERE iid = %d", $code, $obj->iid);
  }
  return $ret;
}

// Re-verify all platforms and sites
function hosting_package_update_10() {

  /**
   * This update is no longer necessary as all platforms and sites are re-verified in later updates.
   * because the module weight of hosting_package is lower than hosting_site, creating verify tasks
   * at this point would break the upgrade process because it would attempt to re-create the node access
   * rules, which would in turn try to load the node with it's schema not yet updated.
   *
   * we can safely remove this because we re-verify everything in hosting_update_6000()
   */

  // the task database schema needs to be changed before hosting_add_task will work.
  $ret = hosting_task_update_6000();
  return $ret;
}

// Remove duplicate packages introduced by a double validation of the main platform in 0.4 alpha 1. See #584188
function hosting_package_update_6001() {

  // the task database schema needs to be changed before hosting_add_task will work.
  $ret = hosting_task_update_6000();

  // There appear to be two types of duplication that can be encountered. So we try and find traces of either here
  $duplicate = array();
  $result = db_query("SELECT DISTINCT(package_id) FROM {hosting_package_instance} GROUP BY rid, filename HAVING count(*) > 1 ORDER BY package_id;");
  while ($instance = db_fetch_array($result)) {
    $duplicate[$instance['package_id']] = $instance['package_id'];
  }
  $result = db_query("SELECT nid FROM {hosting_package} WHERE nid NOT IN (SELECT package_id FROM {hosting_package_instance});");
  while ($package = db_fetch_array($result)) {
    $duplicate[$package['nid']] = $package['nid'];
  }

  // We'll only actually execute this fix if duplicates were found (i.e users upgrading from 0.3 should never encounter this)
  if (count($duplicate)) {
    foreach ($duplicate as $nid) {
      $ret[] = array(
        'success' => TRUE,
        'query' => "Delete package " . $nid,
      );
      node_delete($nid);
    }

    // Schedule re-verify of all existing platforms
    $result = db_query("SELECT nid FROM {node} WHERE type='platform' AND status=1");
    while ($platform = db_fetch_object($result)) {
      $ret[] = array(
        'success' => TRUE,
        'query' => "Re-verify scheduled for platform " . $platform->nid,
      );
      hosting_add_task($platform->nid, 'verify');
    }
  }
  return $ret;
}

/**
 * Add the new old_short_name field which will be used to manage
 * cases where install profiles change names during migrations,
 * such as drupal 6 'default' profile to drupal 7 'standard' profile.
 *
 * This needs to happen before any interaction with the packaging system
 * can be made.
 */
function hosting_package_update_6002() {
  $ret = array();
  if (!variable_get('hosting_package_update_6002_run', FALSE)) {
    db_add_field($ret, 'hosting_package', 'old_short_name', array(
      'type' => 'text',
      'size' => 'big',
      'not null' => TRUE,
      'default' => '',
    ));
    variable_set('hosting_package_update_6002_run', TRUE);
  }
  return $ret;
}

/**
 * The hostmaster and/or hostslave profiles no longer need to be status 0
 * as it prevents the main aegir site node from being edited. Instead,
 * just hide the hostmaster/hostslave profiles in the site node form when
 * creating new sites. See #599758
 */
function hosting_package_update_6003() {
  $ret = array();
  $ret[] = update_sql("UPDATE {hosting_package} h JOIN {node} n ON n.nid = h.nid SET status = 1 WHERE h.short_name = 'hostmaster' OR h.short_name = 'hostslave'");
  return $ret;
}
function hosting_package_update_6004() {
  if (!variable_get('hosting_package_update_6004_run', false)) {

    // we want to enforce that the hostmaster site is always referred to as @hostmaster
    $own_site = db_result(db_query("SELECT s.nid FROM {hosting_site} s LEFT JOIN {hosting_package} p ON s.profile=p.nid WHERE p.short_name='hostmaster'"));
    $records[$own_site] = 'hostmaster';
    foreach ($records as $nid => $name) {
      hosting_context_register($nid, $name);
    }
    variable_set('hosting_package_update_6004_run', true);
  }
}

/**
 * Remove DEFAULT value on a LONGTEXT fields and use VARCHAR on
 * smaller fields to optimise queries.
 *
 * This was breaking in MariaDB and preventing installation. On MySQL
 * it was silently ignored, so the installation works, but the
 * defaults are not in the table anyway.
 *
 * See #969326 and #934864
 */
function hosting_package_update_6005() {
  $ret = array();
  db_change_field($ret, 'hosting_package', 'short_name', 'short_name', array(
    'type' => 'varchar',
    'length' => 255,
    'not null' => TRUE,
    'default' => '',
  ));
  db_change_field($ret, 'hosting_package', 'old_short_name', 'old_short_name', array(
    'type' => 'varchar',
    'length' => 255,
    'not null' => TRUE,
    'default' => '',
  ));
  db_change_field($ret, 'hosting_package', 'description', 'description', array(
    'type' => 'text',
    'size' => 'big',
    'not null' => TRUE,
  ));
  db_change_field($ret, 'hosting_package_instance', 'filename', 'filename', array(
    'type' => 'varchar',
    'length' => 255,
    'not null' => TRUE,
    'default' => '',
  ));
  db_change_field($ret, 'hosting_package_instance', 'version', 'version', array(
    'type' => 'varchar',
    'length' => 255,
    'not null' => TRUE,
    'default' => '',
  ));
  return $ret;
}

/**
 * #1033072 - Add indexes on package tables to improve performance
 * with huge package sets
 *
 * When hosting_package_instance hits > 150k rows, the code in
 * hosting_package.instance.inc degrades really badly, yielding
 * queries of 10-20 seconds and yielding to frontend requests of 1 to
 * 5 minutes for the migrate dialog.
 *
 * The indexes created here improves that performance notably, the
 * queries going down to 0.1s and the requests down to < 10s.
 *
 * @see _hosting_package_temporary_table()
 * @see hosting_package_comparison()
 */
function hosting_package_update_6006() {
  $ret = array();
  db_add_index($ret, 'hosting_package_instance', 'hosting_package_id_idx', array(
    'package_id',
  ));
  db_add_index($ret, 'hosting_package_instance', 'hosting_package_rid_idx', array(
    'rid',
  ));
  db_add_index($ret, 'hosting_package', 'hosting_package_nid_idx', array(
    'nid',
  ));
  return $ret;
}

Functions

Namesort descending Description
hosting_package_install Implementation of hook_install().
hosting_package_schema Implementation of hook_schema().
hosting_package_update_1 Add package description to hosting_package table
hosting_package_update_10
hosting_package_update_2 Add localization support for installed sites
hosting_package_update_3 No limit on short_name length
hosting_package_update_4 Package languages are associated to package instances, not packages
hosting_package_update_5 Denormalize package and package release node types
hosting_package_update_6
hosting_package_update_6001
hosting_package_update_6002 Add the new old_short_name field which will be used to manage cases where install profiles change names during migrations, such as drupal 6 'default' profile to drupal 7 'standard' profile.
hosting_package_update_6003 The hostmaster and/or hostslave profiles no longer need to be status 0 as it prevents the main aegir site node from being edited. Instead, just hide the hostmaster/hostslave profiles in the site node form when creating new sites. See #599758
hosting_package_update_6004
hosting_package_update_6005 Remove DEFAULT value on a LONGTEXT fields and use VARCHAR on smaller fields to optimise queries.
hosting_package_update_6006 #1033072 - Add indexes on package tables to improve performance with huge package sets
hosting_package_update_7 Turn the iid column of hosting_package_instance into a serial field
hosting_package_update_8
hosting_package_update_9 Regenerate the package version codes to fix a error related to the regular expression