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; /** * Character set to use in retrieving data. * * @var string */ protected $characterSet; /** * Return an options array for Oracle sources. * * @param string $character_set * Character set to use in retrieving data. Defaults to 'UTF8'. * @param boolean $cache_counts * Indicates whether to cache counts of source records. */ static public function options($character_set = 'UTF8', $cache_counts = FALSE) { return compact('character_set', '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; if (empty($options['character_set'])) { $this->characterSet = 'UTF8'; } else { $this->characterSet = $options['character_set']; } } /** * 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('oci8')) { throw new Exception(t('You must configure the oci8 extension in PHP.')); } $this->connection = oci_connect($this->configuration['username'], $this->configuration['password'], $this->configuration['connection_string'], $this->characterSet); } if ($this->connection) { return TRUE; } else { $e = oci_error(); throw new Exception($e['message']); return FALSE; } } /** * 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('MigrateSourceOracle count'); if ($this->connect()) { $statement = oci_parse($this->connection, $this->countQuery); if (!$statement) { $e = oci_error($this->connection); throw new Exception($e['message'] . "\n" . $e['sqltext']); } $result = oci_execute($statement); if (!$result) { $e = oci_error($statement); throw new Exception($e['message'] . "\n" . $e['sqltext']); } $count_array = oci_fetch_array($statement); $count = reset($count_array); } else { // Do something else? $count = FALSE; } migrate_instrument_stop('MigrateSourceOracle count'); return $count; } /** * Implementation of MigrateSource::performRewind(). */ public function performRewind() { $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; } /* * 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)) { // 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('oracle_query'); $this->connect(); $this->result = oci_parse($this->connection, $this->query); if (!$this->result) { $e = oci_error($this->connection); throw new Exception($e['message'] . "\n" . $e['sqltext']); } $status = oci_execute($this->result); if (!$status) { $e = oci_error($this->result); throw new Exception($e['message'] . "\n" . $e['sqltext']); } migrate_instrument_stop('oracle_query'); } /** * Implementation of MigrateSource::getNextRow(). * * Returns the next row of the result set as an object, making sure NULLs are * represented as PHP NULLs and that LOBs are returned directly without special * handling. */ public function getNextRow() { $row = oci_fetch_array($this->result, OCI_ASSOC | OCI_RETURN_NULLS | OCI_RETURN_LOBS); if (!empty($row)) { return (object)$row; } else { return FALSE; } } }