You are here

public function MigrateSourceSQL::performRewind in Migrate 6.2

Same name and namespace in other branches
  1. 7.2 plugins/sources/sql.inc \MigrateSourceSQL::performRewind()

Implementation of MigrateSource::performRewind().

We could simply execute the query and be functionally correct, but we will take advantage of the PDO-based API to optimize the query up-front.

File

plugins/sources/sql.inc, line 237
Define a MigrateSource for importing from Drupal connections

Class

MigrateSourceSQL
Implementation of MigrateSource, to handle imports from Drupal connections.

Code

public function performRewind() {
  $this->result = NULL;
  $this->query = clone $this->originalQuery;

  // Get the key values, for potential use in joining to the map table, or
  // enforcing idlist.
  $keys = array();
  foreach ($this->activeMap
    ->getSourceKey() as $field_name => $field_schema) {
    if (isset($field_schema['alias'])) {
      $field_name = $field_schema['alias'] . '.' . $field_name;
    }
    $keys[] = $field_name;
  }

  // The rules for determining what conditions to add to the query are as
  // follows (applying first applicable rule)
  // 1. If idlist is provided, then only process items in that list (AND key
  //    IN (idlist)). Only applicable with single-value keys.
  if ($this->idList) {
    $this->query
      ->condition($keys[0], $this->idList, 'IN');
  }
  else {

    // 2. If the map is joinable, join it. We will want to accept all rows
    //    which are either not in the map, or marked in the map as NEEDS_UPDATE.
    //    Note that if highwater fields are in play, we want to accept all rows
    //    above the highwater mark in addition to those selected by the map
    //    conditions, so we need to OR them together (but AND with any existing
    //    conditions in the query). So, ultimately the SQL condition will look
    //    like (original conditions) AND (map IS NULL OR map needs update
    //      OR above highwater).
    $conditions = db_or();
    $condition_added = FALSE;
    if ($this->mapJoinable) {

      // Build the join to the map table. Because the source key could have
      // multiple fields, we need to build things up.
      $count = 1;
      foreach ($this->activeMap
        ->getSourceKey() as $field_name => $field_schema) {
        if (isset($field_schema['alias'])) {
          $field_name = $field_schema['alias'] . '.' . $field_name;
        }
        $map_key = 'sourceid' . $count++;
        if (!isset($map_join)) {
          $map_join = '';
        }
        else {
          $map_join .= ' AND ';
        }
        $map_join .= "{$field_name} = map.{$map_key}";
      }
      $alias = $this->query
        ->leftJoin($this->activeMap
        ->getQualifiedMapTable(), 'map', $map_join);
      $conditions
        ->isNull($alias . '.sourceid1');
      $conditions
        ->condition($alias . '.needs_update', MigrateMap::STATUS_NEEDS_UPDATE);
      $condition_added = TRUE;

      // And as long as we have the map table, add its data to the row.
      $count = 1;
      foreach ($this->activeMap
        ->getSourceKey() as $field_name => $field_schema) {
        $map_key = 'sourceid' . $count++;
        $this->query
          ->addField($alias, $map_key, "migrate_map_{$map_key}");
      }
      $count = 1;
      foreach ($this->activeMap
        ->getDestinationKey() as $field_name => $field_schema) {
        $map_key = 'destid' . $count++;
        $this->query
          ->addField($alias, $map_key, "migrate_map_{$map_key}");
      }
      $this->query
        ->addField($alias, 'needs_update', 'migrate_map_needs_update');
    }

    // 3. If we are using highwater marks, also include rows above the mark.
    //    But, include all rows if the highwater mark is not set.
    if (isset($this->highwaterField['name']) && $this->activeMigration
      ->getHighwater() !== '') {
      if (isset($this->highwaterField['alias'])) {
        $highwater = $this->highwaterField['alias'] . '.' . $this->highwaterField['name'];
      }
      else {
        $highwater = $this->highwaterField['name'];
      }
      $conditions
        ->condition($highwater, $this->activeMigration
        ->getHighwater(), '>');
      $condition_added = TRUE;
    }
    if ($condition_added) {
      $this->query
        ->condition($conditions);
    }
  }
  migrate_instrument_start('MigrateSourceSQL execute');
  $this->result = $this->query
    ->execute();
  migrate_instrument_stop('MigrateSourceSQL execute');
}