123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- <?php
- /**
- * @file
- * Define a MigrateSource class for importing from Oracle databases.
- */
- /**
- * Implementation of MigrateSource, to handle imports from remote Oracle servers.
- */
- class MigrateSourceOracle extends MigrateSource {
- /**
- * Array containing information for connecting to Oracle:
- * username - Username to connect as
- * password - Password for logging in
- * connection_string - See http://us.php.net/manual/en/function.oci-connect.php.
- *
- * @var array
- */
- protected $configuration;
- /**
- * The active Oracle connection for this source.
- *
- * @var resource
- */
- protected $connection;
- public function getConnection() {
- return $this->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;
- }
- }
- }
|