Chris@0: sourceDatabase->schema()->createTable('high_water_node', [ Chris@0: 'fields' => [ Chris@0: 'id' => [ Chris@0: 'description' => 'Serial', Chris@0: 'type' => 'serial', Chris@0: 'unsigned' => TRUE, Chris@0: 'not null' => TRUE, Chris@0: ], Chris@0: 'changed' => [ Chris@0: 'description' => 'Highwater', Chris@0: 'type' => 'int', Chris@0: 'unsigned' => TRUE, Chris@0: ], Chris@0: 'title' => [ Chris@0: 'description' => 'Title', Chris@0: 'type' => 'varchar', Chris@0: 'length' => 128, Chris@0: 'not null' => TRUE, Chris@0: 'default' => '', Chris@0: ], Chris@0: ], Chris@0: 'primary key' => [ Chris@0: 'id', Chris@0: ], Chris@0: 'description' => 'Contains nodes to import', Chris@0: ]); Chris@0: Chris@0: // Add 3 items to source table. Chris@0: $this->sourceDatabase->insert('high_water_node') Chris@0: ->fields([ Chris@0: 'title', Chris@0: 'changed', Chris@0: ]) Chris@0: ->values([ Chris@0: 'title' => 'Item 1', Chris@0: 'changed' => 1, Chris@0: ]) Chris@0: ->values([ Chris@0: 'title' => 'Item 2', Chris@0: 'changed' => 2, Chris@0: ]) Chris@0: ->values([ Chris@0: 'title' => 'Item 3', Chris@0: 'changed' => 3, Chris@0: ]) Chris@0: ->execute(); Chris@0: Chris@0: $this->installEntitySchema('node'); Chris@0: $this->installEntitySchema('user'); Chris@0: $this->installSchema('node', 'node_access'); Chris@0: Chris@0: $this->executeMigration('high_water_test'); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests high water property of SqlBase. Chris@0: */ Chris@0: public function testHighWater() { Chris@0: // Assert all of the nodes have been imported. Chris@0: $this->assertNodeExists('Item 1'); Chris@0: $this->assertNodeExists('Item 2'); Chris@0: $this->assertNodeExists('Item 3'); Chris@0: Chris@0: // Update Item 1 setting its high_water_property to value that is below Chris@0: // current high water mark. Chris@0: $this->sourceDatabase->update('high_water_node') Chris@0: ->fields([ Chris@0: 'title' => 'Item 1 updated', Chris@0: 'changed' => 2, Chris@0: ]) Chris@0: ->condition('title', 'Item 1') Chris@0: ->execute(); Chris@0: Chris@0: // Update Item 2 setting its high_water_property to value equal to Chris@0: // current high water mark. Chris@0: $this->sourceDatabase->update('high_water_node') Chris@0: ->fields([ Chris@0: 'title' => 'Item 2 updated', Chris@0: 'changed' => 3, Chris@0: ]) Chris@0: ->condition('title', 'Item 2') Chris@0: ->execute(); Chris@0: Chris@0: // Update Item 3 setting its high_water_property to value that is above Chris@0: // current high water mark. Chris@0: $this->sourceDatabase->update('high_water_node') Chris@0: ->fields([ Chris@0: 'title' => 'Item 3 updated', Chris@0: 'changed' => 4, Chris@0: ]) Chris@0: ->condition('title', 'Item 3') Chris@0: ->execute(); Chris@0: Chris@0: // Execute migration again. Chris@0: $this->executeMigration('high_water_test'); Chris@0: Chris@0: // Item with lower highwater should not be updated. Chris@0: $this->assertNodeExists('Item 1'); Chris@0: $this->assertNodeDoesNotExist('Item 1 updated'); Chris@0: Chris@0: // Item with equal highwater should not be updated. Chris@0: $this->assertNodeExists('Item 2'); Chris@0: $this->assertNodeDoesNotExist('Item 2 updated'); Chris@0: Chris@0: // Item with greater highwater should be updated. Chris@0: $this->assertNodeExists('Item 3 updated'); Chris@0: $this->assertNodeDoesNotExist('Item 3'); Chris@0: } Chris@0: Chris@0: /** Chris@17: * Tests that the high water value can be 0. Chris@17: */ Chris@17: public function testZeroHighwater() { Chris@17: // Assert all of the nodes have been imported. Chris@17: $this->assertNodeExists('Item 1'); Chris@17: $this->assertNodeExists('Item 2'); Chris@17: $this->assertNodeExists('Item 3'); Chris@17: $migration = $this->container->get('plugin.manager.migration')->CreateInstance('high_water_test', []); Chris@17: $source = $migration->getSourcePlugin(); Chris@17: $source->rewind(); Chris@17: $count = 0; Chris@17: while ($source->valid()) { Chris@17: $count++; Chris@17: $source->next(); Chris@17: } Chris@17: Chris@17: // Expect no rows as everything is below the high water mark. Chris@17: $this->assertSame(0, $count); Chris@17: Chris@17: // Test resetting the high water mark to 0. Chris@17: $this->container->get('keyvalue')->get('migrate:high_water')->set('high_water_test', 0); Chris@17: $migration = $this->container->get('plugin.manager.migration')->CreateInstance('high_water_test', []); Chris@17: $source = $migration->getSourcePlugin(); Chris@17: $source->rewind(); Chris@17: $count = 0; Chris@17: while ($source->valid()) { Chris@17: $count++; Chris@17: $source->next(); Chris@17: } Chris@17: $this->assertSame(3, $count); Chris@17: } Chris@17: Chris@17: /** Chris@17: * Tests that deleting the high water value causes all rows to be reimported. Chris@17: */ Chris@17: public function testNullHighwater() { Chris@17: // Assert all of the nodes have been imported. Chris@17: $this->assertNodeExists('Item 1'); Chris@17: $this->assertNodeExists('Item 2'); Chris@17: $this->assertNodeExists('Item 3'); Chris@17: $migration = $this->container->get('plugin.manager.migration')->CreateInstance('high_water_test', []); Chris@17: $source = $migration->getSourcePlugin(); Chris@17: $source->rewind(); Chris@17: $count = 0; Chris@17: while ($source->valid()) { Chris@17: $count++; Chris@17: $source->next(); Chris@17: } Chris@17: Chris@17: // Expect no rows as everything is below the high water mark. Chris@17: $this->assertSame(0, $count); Chris@17: Chris@17: // Test resetting the high water mark. Chris@17: $this->container->get('keyvalue')->get('migrate:high_water')->delete('high_water_test'); Chris@17: $migration = $this->container->get('plugin.manager.migration')->CreateInstance('high_water_test', []); Chris@17: $source = $migration->getSourcePlugin(); Chris@17: $source->rewind(); Chris@17: $count = 0; Chris@17: while ($source->valid()) { Chris@17: $count++; Chris@17: $source->next(); Chris@17: } Chris@17: $this->assertSame(3, $count); Chris@17: } Chris@17: Chris@17: /** Chris@0: * Tests high water property of SqlBase when rows marked for update. Chris@0: */ Chris@0: public function testHighWaterUpdate() { Chris@0: // Assert all of the nodes have been imported. Chris@0: $this->assertNodeExists('Item 1'); Chris@0: $this->assertNodeExists('Item 2'); Chris@0: $this->assertNodeExists('Item 3'); Chris@0: Chris@0: // Update Item 1 setting its high_water_property to value that is below Chris@0: // current high water mark. Chris@0: $this->sourceDatabase->update('high_water_node') Chris@0: ->fields([ Chris@0: 'title' => 'Item 1 updated', Chris@0: 'changed' => 2, Chris@0: ]) Chris@0: ->condition('title', 'Item 1') Chris@0: ->execute(); Chris@0: Chris@0: // Update Item 2 setting its high_water_property to value equal to Chris@0: // current high water mark. Chris@0: $this->sourceDatabase->update('high_water_node') Chris@0: ->fields([ Chris@0: 'title' => 'Item 2 updated', Chris@0: 'changed' => 3, Chris@0: ]) Chris@0: ->condition('title', 'Item 2') Chris@0: ->execute(); Chris@0: Chris@0: // Update Item 3 setting its high_water_property to value that is above Chris@0: // current high water mark. Chris@0: $this->sourceDatabase->update('high_water_node') Chris@0: ->fields([ Chris@0: 'title' => 'Item 3 updated', Chris@0: 'changed' => 4, Chris@0: ]) Chris@0: ->condition('title', 'Item 3') Chris@0: ->execute(); Chris@0: Chris@0: // Set all rows as needing an update. Chris@0: $id_map = $this->getMigration('high_water_test')->getIdMap(); Chris@0: $id_map->prepareUpdate(); Chris@0: Chris@0: $this->executeMigration('high_water_test'); Chris@0: Chris@0: // Item with lower highwater should be updated. Chris@0: $this->assertNodeExists('Item 1 updated'); Chris@0: $this->assertNodeDoesNotExist('Item 1'); Chris@0: Chris@0: // Item with equal highwater should be updated. Chris@0: $this->assertNodeExists('Item 2 updated'); Chris@0: $this->assertNodeDoesNotExist('Item 2'); Chris@0: Chris@0: // Item with greater highwater should be updated. Chris@0: $this->assertNodeExists('Item 3 updated'); Chris@0: $this->assertNodeDoesNotExist('Item 3'); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Assert that node with given title exists. Chris@0: * Chris@0: * @param string $title Chris@0: * Title of the node. Chris@0: */ Chris@0: protected function assertNodeExists($title) { Chris@0: self::assertTrue($this->nodeExists($title)); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Assert that node with given title does not exist. Chris@0: * Chris@0: * @param string $title Chris@0: * Title of the node. Chris@0: */ Chris@0: protected function assertNodeDoesNotExist($title) { Chris@0: self::assertFalse($this->nodeExists($title)); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Checks if node with given title exists. Chris@0: * Chris@0: * @param string $title Chris@0: * Title of the node. Chris@0: * Chris@0: * @return bool Chris@0: */ Chris@0: protected function nodeExists($title) { Chris@0: $query = \Drupal::entityQuery('node'); Chris@0: $result = $query Chris@0: ->condition('title', $title) Chris@0: ->range(0, 1) Chris@0: ->execute(); Chris@0: Chris@0: return !empty($result); Chris@0: } Chris@0: Chris@0: }