You are here

function location_update_5301 in Location 6.3

Same name and namespace in other branches
  1. 5.3 location.install \location_update_5301()
  2. 7.5 location.install \location_update_5301()
  3. 7.3 location.install \location_update_5301()
  4. 7.4 location.install \location_update_5301()

Location 3.x update 2. Normalize the location table. This allows:

  • Making the loading and saving code cleaner.
  • Fixing a longstanding bug with revisions.
  • Having the same location on multiple nodes/users/both.
  • Garbage collecting unused locations periodically.
  • Having full support for deletions.
  • Full revisions support.

Note that the location_instance table does NOT have a primary key. This is on purpose. It's a N:M join table.

File

./location.install, line 571
Installation / uninstallation routines.

Code

function location_update_5301() {
  $ret = array();
  switch ($GLOBALS['db_type']) {
    case 'mysql':
    case 'mysqli':
      db_query("\n      CREATE TABLE {location_instance} (\n        nid int UNSIGNED DEFAULT NULL,\n        vid int UNSIGNED DEFAULT NULL,\n        uid int UNSIGNED DEFAULT NULL,\n        genid varchar(255) NOT NULL default '',\n        lid int UNSIGNED NOT NULL DEFAULT '0',\n        INDEX {location_instance}_nid_idx (nid),\n        INDEX {location_instance}_vid_idx (vid),\n        INDEX {location_instance}_uid_idx (uid),\n        INDEX {location_instance}_genid_idx (genid),\n        INDEX {location_instance}_lid_idx (lid)\n      ) /*!40100 DEFAULT CHARACTER SET utf8 */");
      break;
    case 'pgsql':
      $ret[] = update_sql("\n      CREATE TABLE {location_instance} (\n        nid int DEFAULT NULL CHECK (nid >= 0 OR nid IS NULL),\n        vid int DEFAULT NULL CHECK (vid >= 0 OR vid IS NULL),\n        uid int DEFAULT NULL CHECK (uid >= 0 OR uid IS NULL),\n        genid varchar(255) NOT NULL default '',\n        lid int NOT NULL DEFAULT '0' CHECK (lid >= 0)\n      )");
      $ret[] = update_sql('CREATE INDEX {location_instance}_nid_idx ON {location_instance} (nid)');
      $ret[] = update_sql('CREATE INDEX {location_instance}_vid_idx ON {location_instance} (vid)');
      $ret[] = update_sql('CREATE INDEX {location_instance}_uid_idx ON {location_instance} (uid)');
      $ret[] = update_sql('CREATE INDEX {location_instance}_lid_idx ON {location_instance} (lid)');
      $ret[] = update_sql('CREATE INDEX {location_instance}_genid_idx ON {location_instance} (genid)');
      break;
  }

  // Synthesise node location data based on what we have.
  // Storage of locations was previously stored against node revision, BUT the
  // data was not properly duplicated by revision (i.e. only the latest revision
  // carried the data.)
  // Joining like this allows us to backfill all the old revisions with the current
  // data, which is not nice but better than having no data at all when viewing
  // old revisions.
  $ret[] = update_sql("INSERT INTO {location_instance} (nid,vid,lid) (SELECT nr.nid, nr.vid, l.lid FROM {node_revisions} nr INNER JOIN {node_revisions} nr2 ON nr.nid = nr2.nid INNER JOIN {location} l ON nr2.vid = l.eid AND l.type = 'node')");

  // Users is much simpler.
  $ret[] = update_sql("INSERT INTO {location_instance} (uid,lid) (SELECT eid, lid FROM {location} WHERE type = 'user')");

  // Aug 18 2008:
  // Save everything else in genid.
  switch ($GLOBALS['db_type']) {
    case 'mysql':
    case 'mysqli':
      $ret[] = update_sql("INSERT INTO {location_instance} (genid, lid) (SELECT CONCAT(type, ':', eid), lid FROM {location} WHERE type <> 'user' AND type <> 'node')");
      break;
    case 'pgsql':
      $ret[] = update_sql("INSERT INTO {location_instance} (genid, lid) (SELECT type||':'||eid, lid FROM {location} WHERE type <> 'user' AND type <> 'node')");
      break;
  }

  // Remove now unused columns.
  $ret[] = update_sql("ALTER TABLE {location} DROP COLUMN type");
  $ret[] = update_sql("ALTER TABLE {location} DROP COLUMN eid");

  // General cleanup.
  variable_del('location_user');

  // Removed in favor of permission check.
  // Variable consolidation (as part of the element based system)
  // We're doing this "raw" so we can be sure we got everything moved over,
  // INCLUDING content types that were deleted in the past.
  // This will let us do better cleanup sometime in the future.
  $data = array();
  $todelete = array();
  foreach (array(
    'name',
    'street',
    'additional',
    'city',
    'province',
    'postal_code',
    'country',
    'phone',
    'fax',
  ) as $field) {
    $result = db_query("SELECT name, value FROM {variable} WHERE name LIKE 'location_%s%%'", $field);
    while ($row = db_fetch_object($result)) {
      $data[substr($row->name, strlen($field) + 10)][$field] = (string) (int) unserialize($row->value);
      $todelete[] = $row->name;
    }
  }
  foreach ($data as $type => $value) {

    // We aren't going to trust that hook_locationapi is operational.
    // So, stick with some conservative defaults.
    $value = array_merge(array(
      'name' => '1',
      'street' => '1',
      // additional is left out of this list intentionally.
      'city' => '0',
      'province' => '0',
      'postal_code' => '0',
      'country' => '1',
    ), $value);
    if (!isset($value['additional'])) {

      // Initialize additional to match street.
      $value['additional'] = $value['street'];
    }
    variable_set('location_fields_' . $type, $value);
  }
  foreach ($todelete as $key) {
    variable_del($key);
  }

  // This update was retrofitted on Aug 18, 2008. Set a flag for use by
  // the next update in order to handle the case where someone has already
  // updated to EXACTLY schema revision 5301 before the retrofit took effect.
  // People who migrated past this point before that date may have the following
  // inconsistencies:
  // A) location_{field}_{type} variables were not collected for content types
  // that had been deleted in the past.
  // B) Any locations with the 'type' field set to something other than 'node'
  // or 'user' did not get entries in {location_instance}.
  variable_set('location_update_5301_retrofit', TRUE);
  return $ret;
}