You are here

class MigrateSourceMSSQL in Migrate 6.2

Same name and namespace in other branches
  1. 7.2 plugins/sources/sqlsrv.inc \MigrateSourceMSSQL

Implementation of MigrateSource, to handle imports from remote MS SQL Server db servers.

Hierarchy

Expanded class hierarchy of MigrateSourceMSSQL

File

plugins/sources/mssql.inc, line 11
Define a MigrateSource for importing from Microsoft SQL Server databases.

View source
class MigrateSourceMSSQL extends MigrateSource {

  /**
   * Array containing information for connecting to SQL Server:
   *  servername - Hostname of the SQL Server
   *  username - Username to connect as
   *  password - Password for logging in
   *  database (optional) - Database to select after connecting
   *
   * @var array
   */
  protected $configuration;

  /**
   * The active MS SQL Server connection for this source.
   *
   * @var resource
   */
  protected $connection;

  /**
   * The SQL query from which to obtain data. Is a string.
   */
  protected $query;

  /**
   * The result object from executing the query - traversed to process the
   * incoming data.
   */
  protected $result;

  /**
   * By default, mssql_query fetches all results - severe memory problems with
   * big tables. So, we will fetch a batch at a time.
   *
   * @var int
   */
  protected $batchSize;

  /**
   * Return an options array for MS SQL sources.
   *
   * @param int $batch_size
   *  Number of rows to pull at once (defaults to 500).
   * @param boolean $cache_counts
   *  Indicates whether to cache counts of source records.
   */
  public static function options($batch_size, $cache_counts) {
    return compact('batch_size', 'cache_counts');
  }

  /**
   * Simple initialization.
   */
  public function __construct(array $configuration, $query, $count_query, array $fields, array $options = array()) {
    parent::__construct($options);
    $this->query = $query;
    $this->countQuery = $count_query;
    $this->configuration = $configuration;
    $this->fields = $fields;
    $this->batchSize = isset($options['batch_size']) ? $options['batch_size'] : 500;
  }

  /**
   * Return a string representing the source query.
   *
   * @return string
   */
  public function __toString() {
    return $this->query;
  }

  /**
   * Connect lazily to the DB server.
   */
  protected function connect() {
    if (!isset($this->connection)) {
      if (!extension_loaded('mssql')) {
        throw new Exception(t('You must configure the mssql extension in PHP.'));
      }
      if (isset($this->configuration['port'])) {
        $host = $this->configuration['servername'] . ':' . $this->configuration['port'];
      }
      else {
        $host = $this->configuration['servername'];
      }
      $this->connection = mssql_connect($host, $this->configuration['username'], $this->configuration['password'], TRUE);
      if (isset($this->configuration['database'])) {
        return mssql_select_db($this->configuration['database'], $this->connection);
      }
    }
  }

  /**
   * Returns a list of fields available to be mapped from the source query.
   *
   * @return array
   *  Keys: machine names of the fields (to be passed to addFieldMapping)
   *  Values: Human-friendly descriptions of the fields.
   */
  public function fields() {

    // The fields are passed to the constructor for this plugin.
    return $this->fields;
  }

  /**
   * Return a count of all available source records.
   */
  public function computeCount() {
    migrate_instrument_start('MigrateSourceMSSQL count');
    if ($this
      ->connect()) {
      $result = mssql_query($this->countQuery);
      $count = reset(mssql_fetch_object($result));
    }
    else {

      // Do something else?
      $count = FALSE;
    }
    migrate_instrument_stop('MigrateSourceMSSQL count');
    return $count;
  }

  /**
   * Implementation of MigrateSource::performRewind().
   */
  public function performRewind() {

    /*
     * Replace :criteria placeholder with idlist or highwater clauses. We
     * considered supporting both but it is not worth the complexity. Run twice
     * instead.
     */
    if (!empty($this->idList)) {
      $keys = array();
      foreach ($this->activeMap
        ->getSourceKey() as $field_name => $field_schema) {

        // Allow caller to provide an alias to table containing the primary key.
        if (!empty($field_schema['alias'])) {
          $field_name = $field_schema['alias'] . '.' . $field_name;
        }
        $keys[] = $field_name;
      }

      // TODO: Sanitize. not critical as this is admin supplied data in drush.
      $this->query = str_replace(':criteria', $keys[0] . ' IN (' . implode(',', $this->idList) . ')', $this->query);
    }
    else {
      if (isset($this->highwaterField['name']) && ($highwater = $this->activeMigration
        ->getHighwater())) {
        if (empty($this->highwaterField['alias'])) {
          $highwater_name = $this->highwaterField['name'];
        }
        else {
          $highwater_name = $this->highwaterField['alias'] . '.' . $this->highwaterField['name'];
        }
        $this->query = str_replace(':criteria', "{$highwater_name} > '{$highwater}'", $this->query);
      }
      else {

        // No idlist or highwater. Replace :criteria placeholder with harmless WHERE
        // clause instead of empty since we don't know if an AND follows.
        $this->query = str_replace(':criteria', '1=1', $this->query);
      }
    }
    migrate_instrument_start('mssql_query');
    $this
      ->connect();
    $this->result = mssql_query($this->query, $this->connection, $this->batchSize);
    migrate_instrument_stop('mssql_query');
  }

  /**
   * Implementation of MigrateSource::getNextRow().
   *
   * Returns the next row of the result set as an object, dealing with the
   * difference between the end of the batch and the end of all data.
   */
  public function getNextRow() {
    $row = mssql_fetch_object($this->result);

    // Might be totally out of data, or just out of this batch - request another
    // batch and see
    if (!is_object($row)) {
      mssql_fetch_batch($this->result);
      $row = mssql_fetch_object($this->result);
    }
    if (is_object($row)) {
      return $row;
    }
    else {
      return NULL;
    }
  }

}

Members

Namesort descending Modifiers Type Description Overrides
MigrateSource::$activeMap protected property The MigrateMap class for the current migration.
MigrateSource::$activeMigration protected property The Migration class currently invoking us, during rewind() and next().
MigrateSource::$cacheCounts protected property Whether this instance should cache the source count.
MigrateSource::$cacheKey protected property Key to use for caching counts.
MigrateSource::$currentKey protected property The primary key of the current row
MigrateSource::$currentRow protected property The current row from the quey
MigrateSource::$highwaterField protected property Information on the highwater mark for the current migration, if any.
MigrateSource::$idList protected property List of source IDs to process.
MigrateSource::$mapRowAdded protected property By default, next() will directly read the map row and add it to the data row. A source plugin implementation may do this itself (in particular, the SQL source can incorporate the map table into the query) - if so, it should set this TRUE so we…
MigrateSource::$numIgnored protected property Number of rows intentionally ignored (prepareRow() returned FALSE)
MigrateSource::$numProcessed protected property Number of rows we've at least looked at. 1
MigrateSource::$skipCount protected property Whether this instance should not attempt to count the source.
MigrateSource::count public function Return a count of available source records, from the cache if appropriate. Returns -1 if the source is not countable.
MigrateSource::current public function Implementation of Iterator::current() - called when entering a loop iteration, returning the current row
MigrateSource::getCurrentKey public function
MigrateSource::getIgnored public function
MigrateSource::getProcessed public function
MigrateSource::key public function Implementation of Iterator::key - called when entering a loop iteration, returning the key of the current row. It must be a scalar - we will serialize to fulfill the requirement, but using getCurrentKey() is preferable.
MigrateSource::next public function Implementation of Iterator::next() - subclasses of MigrateSource should implement getNextRow() to retrieve the next valid source rocord to process.
MigrateSource::prepareRow protected function Give the calling migration a shot at manipulating, and possibly rejecting, the source row.
MigrateSource::resetStats public function Reset numIgnored back to 0.
MigrateSource::rewind public function Implementation of Iterator::rewind() - subclasses of MigrateSource should implement performRewind() to do any class-specific setup for iterating source records.
MigrateSource::valid public function Implementation of Iterator::valid() - called at the top of the loop, returning TRUE to process the loop and FALSE to terminate it
MigrateSourceMSSQL::$batchSize protected property By default, mssql_query fetches all results - severe memory problems with big tables. So, we will fetch a batch at a time.
MigrateSourceMSSQL::$configuration protected property Array containing information for connecting to SQL Server: servername - Hostname of the SQL Server username - Username to connect as password - Password for logging in database (optional) - Database to select after connecting
MigrateSourceMSSQL::$connection protected property The active MS SQL Server connection for this source.
MigrateSourceMSSQL::$query protected property The SQL query from which to obtain data. Is a string.
MigrateSourceMSSQL::$result protected property The result object from executing the query - traversed to process the incoming data.
MigrateSourceMSSQL::computeCount public function Return a count of all available source records.
MigrateSourceMSSQL::connect protected function Connect lazily to the DB server.
MigrateSourceMSSQL::fields public function Returns a list of fields available to be mapped from the source query. Overrides MigrateSource::fields
MigrateSourceMSSQL::getNextRow public function Implementation of MigrateSource::getNextRow().
MigrateSourceMSSQL::options public static function Return an options array for MS SQL sources.
MigrateSourceMSSQL::performRewind public function Implementation of MigrateSource::performRewind().
MigrateSourceMSSQL::__construct public function Simple initialization. Overrides MigrateSource::__construct
MigrateSourceMSSQL::__toString public function Return a string representing the source query.