diff -u b/core/modules/migrate/src/Plugin/migrate/id_map/Sql.php b/core/modules/migrate/src/Plugin/migrate/id_map/Sql.php --- b/core/modules/migrate/src/Plugin/migrate/id_map/Sql.php +++ b/core/modules/migrate/src/Plugin/migrate/id_map/Sql.php @@ -34,9 +34,9 @@ const SOURCE_IDS_HASH = 'source_ids_hash'; /** - * Source id suffix to ensure source id names are not SQL reserved words. + * Suffix to append to ID properties to avoid SQL reserved words. */ - const SOURCE_ID_SUFFIX = '_x'; + const ID_SUFFIX = '_x'; /** * An event dispatcher instance to use for map events. @@ -469,12 +469,17 @@ $query = $this->getDatabase()->select($this->mapTableName(), 'map'); $query->condition(static::SOURCE_IDS_HASH, $this->getSourceIDsHash($source_id_values)); foreach ($this->sourceIdFields() as $field_name => $source_id) { - $query->addField('map', $source_id, $field_name . static::SOURCE_ID_SUFFIX); + $query->addField('map', $source_id, $field_name . static::ID_SUFFIX); $query->condition("map.$source_id", $source_id_values[$field_name]); } foreach ($this->destinationIdFields() as $field_name => $destination_id) { - $query->addField('map', $destination_id, $field_name . static::SOURCE_ID_SUFFIX); + $query->addField('map', $destination_id, $field_name . static::ID_SUFFIX); } + $query->addField('map', 'source_ids_hash'); + $query->addField('map', 'source_row_status'); + $query->addField('map', 'rollback_action'); + $query->addField('map', 'last_imported'); + $query->addField('map', 'hash'); $result = $query->execute(); return $result->fetchAssoc(); } @@ -485,12 +490,17 @@ public function getRowByDestination(array $destination_id_values) { $query = $this->getDatabase()->select($this->mapTableName(), 'map'); foreach ($this->sourceIdFields() as $field_name => $source_id) { - $query->addField('map', $source_id, $field_name); + $query->addField('map', $source_id, $field_name . static::ID_SUFFIX); } foreach ($this->destinationIdFields() as $field_name => $destination_id) { - $query->addField('map', $destination_id, $field_name); + $query->addField('map', $destination_id, $field_name . static::ID_SUFFIX); $query->condition("map.$destination_id", $destination_id_values[$field_name]); } + $query->addField('map', 'source_ids_hash'); + $query->addField('map', 'source_row_status'); + $query->addField('map', 'rollback_action'); + $query->addField('map', 'last_imported'); + $query->addField('map', 'hash'); $result = $query->execute(); return $result->fetchAssoc(); } only in patch2: unchanged: --- a/core/modules/migrate/tests/src/Unit/MigrateSqlIdMapTest.php +++ b/core/modules/migrate/tests/src/Unit/MigrateSqlIdMapTest.php @@ -7,6 +7,7 @@ use Drupal\migrate\MigrateException; use Drupal\migrate\Plugin\MigrateIdMapInterface; use Drupal\migrate\Row; +use Drupal\migrate\Plugin\migrate\id_map\Sql; /** * Tests the SQL ID map plugin. @@ -127,12 +128,14 @@ protected function getIdMap() { * An associative array with the following keys: * - source_row_status * - rollback_action + * - last_imported * - hash */ protected function idMapDefaults() { $defaults = array( 'source_row_status' => MigrateIdMapInterface::STATUS_IMPORTED, 'rollback_action' => MigrateIdMapInterface::ROLLBACK_DELETE, + 'last_imported' => 0, 'hash' => '', ); // By default, the PDO SQLite driver strongly prefers to return strings @@ -144,6 +147,7 @@ protected function idMapDefaults() { if ($this->database->driver() == 'sqlite') { $defaults['source_row_status'] = (string) $defaults['source_row_status']; $defaults['rollback_action'] = (string) $defaults['rollback_action']; + $defaults['last_imported'] = (string) 0; } return $defaults; } @@ -258,6 +262,25 @@ public function testGetRowsNeedingUpdate() { // Assert the row matches its original source. $source_id = $expected_results[MigrateIdMapInterface::STATUS_NEEDS_UPDATE]['sourceid1']; $test_row = $id_map->getRowBySource(['source_id_property' => $source_id]); + // Convert names + foreach ($test_row as $key => $value) { + switch ($key) { + case 'source_id_property' . SQL::ID_SUFFIX; + $key = 'sourceid1'; + break; + case 'destination_id_property' . SQL::ID_SUFFIX: + $key = 'destid1'; + break; + } + $expected[$key] = $value; + } + // Sort expected to the same order as $result_row. + $test_row = []; + foreach ($row_needing_update[0] as $key => $value) { + if (isset($expected[$key]) || array_key_exists($key, $expected)) { + $test_row[$key] = $expected[$key]; + } + } // $row_needing_update is an array of objects returned from the database, // but $test_row is an array, so the cast is necessary. $this->assertSame($test_row, (array) $row_needing_update[0]); @@ -345,25 +368,64 @@ public function testMessageSave() { */ public function testGetRowBySource() { $this->getDatabase([]); + $this->sourceIds = [ + 'source_id_property1' => [ + 'type' => 'string', + ], + 'source_id_property2' => [ + 'type' => 'string', + ], + ]; $row = [ 'sourceid1' => 'source_id_value_1', 'sourceid2' => 'source_id_value_2', - 'source_ids_hash' => $this->getIdMap()->getSourceIDsHash(['source_id_property' => 'source_id_value_1']), + 'source_ids_hash' => $this->getIdMap()->getSourceIDsHash( + [ + 'source_id_property1' => 'source_id_value_1', + 'source_id_property2' => 'source_id_value_2' + ]), 'destid1' => 'destination_id_value_1', ] + $this->idMapDefaults(); $this->saveMap($row); $row = [ 'sourceid1' => 'source_id_value_3', 'sourceid2' => 'source_id_value_4', - 'source_ids_hash' => $this->getIdMap()->getSourceIDsHash(['source_id_property' => 'source_id_value_3', 'sourceid2' => 'source_id_value_4']), + 'source_ids_hash' => $this->getIdMap()->getSourceIDsHash( + [ + 'source_id_property1' => 'source_id_value_3', + 'source_id_property2' => 'source_id_value_4' + ]), 'destid1' => 'destination_id_value_2', ] + $this->idMapDefaults(); $this->saveMap($row); - $source_id_values = ['source_id_property' => $row['sourceid1'], 'sourceid2' => $row['sourceid2']]; + $expected = [ + 'source_id_property1' . SQL::ID_SUFFIX => 'source_id_value_3', + 'source_id_property2' . SQL::ID_SUFFIX => 'source_id_value_4', + 'source_ids_hash' => $this->getIdMap()->getSourceIDsHash( + [ + 'source_id_property1' => 'source_id_value_3', + 'source_id_property2' => 'source_id_value_4' + ]), + 'destination_id_property' . SQL::ID_SUFFIX => 'destination_id_value_2', + ] + $this->idMapDefaults(); + $source_id_values = [ + 'source_id_property1' => $row['sourceid1'], + 'source_id_property2' => $row['sourceid2'] + ]; $id_map = $this->getIdMap(); $result_row = $id_map->getRowBySource($source_id_values); - $this->assertSame($row, $result_row); - $source_id_values = ['source_id_property' => 'missing_value_1', 'sourceid2' => 'missing_value_2']; + + // Sort expected to the same order as $result_row. + foreach ($result_row as $key => $value) { + if (isset($expected[$key]) || array_key_exists($key, $expected)) { + $expected_results[$key] = $expected[$key]; + } + } + $this->assertSame($expected_results, $result_row); + $source_id_values = [ + 'source_id_property1' => 'missing_value_1', + 'source_id_property2' => 'missing_value_2' + ]; $result_row = $id_map->getRowBySource($source_id_values); $this->assertFalse($result_row); } @@ -434,24 +496,57 @@ public function testLookupDestinationIdMapping($num_source_fields, $num_destinat * Tests the getRowByDestination method. */ public function testGetRowByDestination() { + $this->getDatabase([]); + $this->sourceIds = [ + 'source_id_property1' => [ + 'type' => 'string', + ], + 'source_id_property2' => [ + 'type' => 'string', + ], + ]; $row = [ 'sourceid1' => 'source_id_value_1', 'sourceid2' => 'source_id_value_2', - 'source_ids_hash' => $this->getIdMap()->getSourceIDsHash(['source_id_property' => 'source_id_value_1']), + 'source_ids_hash' => $this->getIdMap()->getSourceIDsHash( + [ + 'source_id_property1' => 'source_id_value_1', + 'source_id_property2' => 'source_id_value_2' + ]), 'destid1' => 'destination_id_value_1', ] + $this->idMapDefaults(); $this->saveMap($row); $row = [ 'sourceid1' => 'source_id_value_3', 'sourceid2' => 'source_id_value_4', - 'source_ids_hash' => $this->getIdMap()->getSourceIDsHash(['source_id_property' => 'source_id_value_3']), + 'source_ids_hash' => $this->getIdMap()->getSourceIDsHash( + [ + 'source_id_property1' => 'source_id_value_3', + 'source_id_property2' => 'source_id_value_4' + ]), 'destid1' => 'destination_id_value_2', - ] + $this->idMapDefaults(); + ] + $this->idMapDefaults(); $this->saveMap($row); + $expected = [ + 'source_id_property1' . SQL::ID_SUFFIX => 'source_id_value_3', + 'source_id_property2' . SQL::ID_SUFFIX => 'source_id_value_4', + 'source_ids_hash' => $this->getIdMap()->getSourceIDsHash( + [ + 'source_id_property1' => 'source_id_value_3', + 'source_id_property2' => 'source_id_value_4' + ]), + 'destination_id_property' . SQL::ID_SUFFIX => 'destination_id_value_2', + ] + $this->idMapDefaults(); $dest_id_values = ['destination_id_property' => $row['destid1']]; $id_map = $this->getIdMap(); $result_row = $id_map->getRowByDestination($dest_id_values); - $this->assertSame($row, $result_row); + // Sort expected_results to the same order as $result_row. + foreach ($result_row as $key => $value) { + if (isset($expected[$key]) || array_key_exists($key, $expected)) { + $expected_results[$key] = $expected[$key]; + } + } + $this->assertSame($expected_results, $result_row); // This value does not exist. $dest_id_values = ['destination_id_property' => 'invalid_destination_id_property']; $id_map = $this->getIdMap();