/** * @param callable $migration Closure that receives the table to operate on. * * <example> * $migration->execute(function($table) { * $table * ->removeColumn('name') * ->save(); * }); * </example> */ public function execute(callable $migration) { $this->logger->info("Starting LHM run on table={$this->origin->getName()}"); $sqlHelper = new SqlHelper($this->adapter); if (!isset($options['atomic_switch'])) { if ($sqlHelper->supportsAtomicSwitch()) { $this->options['atomic_switch'] = true; } else { $version = $sqlHelper->versionString(); throw new \RuntimeException("Using mysql {$version}. You must explicitly set `options['atomic_switch']` (re SqlHelper::supportsAtomicSwitch)"); } } if (!$this->destination) { $this->destination = $this->temporaryTable(); } $this->setSessionLockWaitTimeouts(); $entangler = new Entangler($this->adapter, $this->origin, $this->destination, $sqlHelper); $entangler->setLogger($this->logger); if ($this->options['atomic_switch']) { $switcher = new AtomicSwitcher($this->adapter, $this->origin, $this->destination, $this->options); } else { $switcher = new LockedSwitcher($this->adapter, $this->origin, $this->destination, $this->options); } $switcher->setLogger($this->logger); $chunker = new Chunker($this->adapter, $this->origin, $this->destination, $sqlHelper, $this->options); $chunker->setLogger($this->logger); $migration($this->destination); $entangler->run(function () use($chunker, $switcher) { $chunker->run(); $switcher->run(); }); }
public function testSupportsAtomicSwitch() { $versions = ['3.0.1' => true, '4.0.1' => false, '4.2.2' => true, '4.20.1' => true, '5.0.20' => false, '5.0.57' => true, '5.1.3' => false, '5.4.2' => false, '5.4.4' => true, '5.5.2' => false, '5.5.3' => true, '5.5.4' => true, '6.0.3' => false, '6.0.10' => false, '6.0.11' => true, '6.0.12' => true]; $expectedIterator = new \ArrayIterator($versions); $matcherIterator = new \ArrayIterator(array_keys($versions)); $matcher = $this->any(); $this->adapter->expects($matcher)->method('query')->with("show variables like 'version'")->will($this->returnCallback(function () use($matcherIterator) { $value = $matcherIterator->current(); $matcherIterator->next(); $mock = $this->getMockBuilder(\stdClass::class)->setMethods(['fetchColumn'])->disableOriginalConstructor()->getMock(); $mock->expects($this->once())->method('fetchColumn')->will($this->returnValue($value)); return $mock; })); foreach ($expectedIterator as $version => $expected) { $this->assertEquals($expected, $this->helper->supportsAtomicSwitch()); } }