Exemplo n.º 1
0
 public function testVersionString()
 {
     $mock = $this->getMockBuilder(\stdClass::class)->setMethods(['fetchColumn'])->disableOriginalConstructor()->getMock();
     $mock->expects($this->once())->method('fetchColumn')->will($this->returnValue("3.0.2"));
     $this->adapter->expects($this->once())->method('query')->with("show variables like 'version'")->will($this->returnValue($mock));
     $this->assertEquals("3.0.2", $this->helper->versionString());
 }
Exemplo n.º 2
0
 public function test()
 {
     $this->adapter->expects($this->atLeastOnce())->method('hasTable')->will($this->returnValueMap([['users', true], ['users_new', true]]));
     $this->adapter->expects($this->atLeastOnce())->method('quoteTableName')->will($this->returnCallback(function ($name) {
         return "`{$name}`";
     }));
     $this->adapter->expects($this->once())->method('query')->with('RENAME TABLE `users` TO `users_archive`, `users_new` TO `users`');
     $this->origin->expects($this->atLeastOnce())->method('getName')->will($this->returnValue('users'));
     $this->destination->expects($this->atLeastOnce())->method('getName')->will($this->returnValue('users_new'));
     $this->switcher->run();
 }
Exemplo n.º 3
0
 public function testRun()
 {
     /** @var Column[] $originColumns */
     $originColumns = [new Column(), new Column(), new Column()];
     $originColumns[0]->setName('id');
     $originColumns[1]->setName('name');
     $originColumns[2]->setName('something');
     /** @var Column[] $destinationColumns */
     $destinationColumns = [new Column(), new Column(), new Column()];
     $destinationColumns[0]->setName('id');
     $destinationColumns[1]->setName('name');
     $destinationColumns[2]->setName('something_else');
     $this->origin->expects($this->atLeastOnce())->method('getName')->will($this->returnValue('users'));
     $this->origin->expects($this->atLeastOnce())->method('getColumns')->will($this->returnValue($originColumns));
     $this->destination->expects($this->atLeastOnce())->method('getName')->will($this->returnValue('users_new'));
     $this->destination->expects($this->atLeastOnce())->method('getColumns')->will($this->returnValue($destinationColumns));
     $this->destination->expects($this->atLeastOnce())->method('getRenamedColumns')->will($this->returnValue([]));
     $matcher = $this->atLeastOnce();
     $this->adapter->expects($matcher)->method('fetchRow')->will($this->returnCallback(function ($query) use($matcher) {
         switch ($matcher->getInvocationCount()) {
             case 1:
                 $this->assertEquals("SELECT MIN(id) FROM 'users'", $query);
                 return [1];
             case 2:
                 $this->assertEquals("SELECT MAX(id) FROM 'users'", $query);
                 return [500];
             default:
                 return null;
                 break;
         }
     }));
     $matcher = $this->atLeastOnce();
     $this->adapter->expects($matcher)->method('query')->will($this->returnCallback(function ($query) use($matcher) {
         switch ($matcher->getInvocationCount()) {
             case 1:
                 $this->assertEquals("SELECT `COLUMN_NAME` FROM `information_schema`.`COLUMNS` WHERE (`TABLE_SCHEMA` = '') AND (`TABLE_NAME` = 'users') AND (`COLUMN_KEY` = 'PRI');", $query);
                 return 'id';
             case 2:
                 $this->assertEquals("INSERT IGNORE INTO 'users_new' (`id`,`name`) SELECT 'users'.`id`,'users'.`name` FROM 'users' WHERE 'users'.`id` BETWEEN 1 AND 200", $query);
                 break;
             case 3:
                 $this->assertEquals("INSERT IGNORE INTO 'users_new' (`id`,`name`) SELECT 'users'.`id`,'users'.`name` FROM 'users' WHERE 'users'.`id` BETWEEN 201 AND 400", $query);
                 break;
             case 4:
                 $this->assertEquals("INSERT IGNORE INTO 'users_new' (`id`,`name`) SELECT 'users'.`id`,'users'.`name` FROM 'users' WHERE 'users'.`id` BETWEEN 401 AND 500", $query);
                 break;
             default:
                 $this->fail('Unexpected query: ' . $query);
                 break;
         }
     }));
     $chunker = new Chunker($this->adapter, $this->origin, $this->destination, $this->sqlHelper, ['stride' => 200]);
     $chunker->run();
 }
 protected function setUp()
 {
     parent::setUp();
     $options = ['host' => getenv('LHM_DATABASE_HOST') ?: 'localhost', 'name' => getenv('LHM_DATABASE_NAME') ?: 'lhm_php_test', 'user' => getenv('LHM_DATABASE_USER') ?: 'root', 'pass' => getenv('LHM_DATABASE_PASSWORD') ?: null, 'port' => getenv('LHM_DATABASE_PORT') ?: 3306];
     $this->adapter = new MysqlAdapter($options, new NullOutput());
     $this->adapter->setOptions($options);
     // ensure the database is empty for each test
     $this->adapter->dropDatabase($options['name']);
     $this->adapter->createDatabase($options['name']);
     // leave the adapter in a disconnected state for each test
     $this->adapter->disconnect();
 }
Exemplo n.º 5
0
 public function test()
 {
     $this->adapter->expects($this->atLeastOnce())->method('hasTable')->will($this->returnValueMap([['users', true], ['users_new', true]]));
     $this->adapter->expects($this->atLeastOnce())->method('quoteTableName')->will($this->returnCallback(function ($name) {
         return "`{$name}`";
     }));
     $expected = ["set @lhm_auto_commit = @@session.autocommit /* large hadron migration (php) */", "set session autocommit = 0 /* large hadron migration (php) */", "LOCK TABLE `users` write, `users_new` write /* large hadron migration (php) */", "ALTER TABLE  `users` rename `users_archive` /* large hadron migration (php) */", "ALTER TABLE `users_new` rename `users` /* large hadron migration (php) */", "COMMIT /* large hadron migration (php) */", "UNLOCK TABLES /* large hadron migration (php) */", "set session autocommit = @lhm_auto_commit /* large hadron migration (php) */"];
     $matcher = $this->any();
     $this->adapter->expects($matcher)->method('query')->will($this->returnCallback(function ($query) use($matcher, $expected) {
         $this->assertEquals($expected[$matcher->getInvocationCount() - 1], $query);
     }));
     $this->origin->expects($this->atLeastOnce())->method('getName')->will($this->returnValue('users'));
     $this->destination->expects($this->atLeastOnce())->method('getName')->will($this->returnValue('users_new'));
     $this->switcher->run();
 }
Exemplo n.º 6
0
 public function testCreateDeleteTrigger()
 {
     $this->origin->expects($this->atLeastOnce())->method('getName')->will($this->returnValue('users'));
     $this->destination->expects($this->atLeastOnce())->method('getName')->will($this->returnValue('users_new'));
     $this->adapter->expects($this->once())->method('query')->will($this->returnValue("id"));
     $this->assertEquals(implode("\n ", ['CREATE TRIGGER lhmt_delete_users', "AFTER DELETE ON 'users' FOR EACH ROW", "DELETE IGNORE FROM 'users_new' /* large hadron migration (php) */", "WHERE 'users_new'.`id` = OLD.`id`"]), $this->entangler->createDeleteTrigger());
 }
Exemplo n.º 7
0
 /**
  * Execute the switch
  */
 protected function execute()
 {
     $sqlHelper = $this->getSqlHelper();
     foreach ($this->statements() as $statement) {
         $this->adapter->query($sqlHelper->tagged($statement));
     }
 }
Exemplo n.º 8
0
 /**
  * @param integer $lowest
  * @param integer $highest
  * @return string
  */
 protected function copy($lowest, $highest)
 {
     $originName = $this->adapter->quoteTableName($this->origin->getName());
     $destinationName = $this->adapter->quoteTableName($this->destination->getName());
     $destinationColumns = implode(',', $this->sqlHelper->quoteColumns($this->intersection->destination()));
     $originColumns = implode(',', $this->sqlHelper->typedColumns($originName, $this->sqlHelper->quoteColumns($this->intersection->origin())));
     return implode(" ", ["INSERT IGNORE INTO {$destinationName} ({$destinationColumns})", "SELECT {$originColumns} FROM {$originName}", "WHERE {$originName}.{$this->primaryKey} BETWEEN {$lowest} AND {$highest}"]);
 }
Exemplo n.º 9
0
 /**
  * @param array $columns List of column names
  * @return array
  */
 public function quoteColumns(array $columns)
 {
     $quoted = [];
     foreach ($columns as $column) {
         $quoted[] = $this->adapter->quoteColumnName($column);
     }
     return $quoted;
 }
Exemplo n.º 10
0
 /**
  * @throws \RuntimeException
  */
 protected function validate()
 {
     if (!$this->adapter->hasTable($this->origin->getName())) {
         throw new \RuntimeException("Table `{$this->origin->getName()}` does not exists.");
     }
     if (!$this->adapter->hasTable($this->destination->getName())) {
         throw new \RuntimeException("Table `{$this->destination->getName()}` does not exists.");
     }
 }
Exemplo n.º 11
0
 public function testInsertData()
 {
     $row = array('column1' => 'value3');
     $this->mock->expects($this->once())->method('insert')->with($this->callback(function ($table) {
         return $table->getName() == 'pre_table_suf';
     }, $this->equalTo($row)));
     $table = new Table('table', array(), $this->adapter);
     $table->insert($row)->save();
 }
Exemplo n.º 12
0
 /**
  * @return Table
  * @throws \RuntimeException
  */
 public function temporaryTable()
 {
     if ($this->destination) {
         return $this->destination;
     }
     $temporaryTableName = $this->temporaryTableName();
     if ($this->adapter->hasTable($temporaryTableName)) {
         throw new \RuntimeException("The table `{$temporaryTableName}` already exists.");
     }
     $this->getLogger()->info("Creating temporary table `{$temporaryTableName}` from `{$this->origin->getName()}`");
     $this->adapter->query("CREATE TABLE {$temporaryTableName} LIKE {$this->origin->getName()}");
     return new \Lhm\Table($temporaryTableName, [], $this->adapter);
 }
Exemplo n.º 13
0
 /**
  * Execute the atomic rename.
  */
 protected function execute()
 {
     $retries = 0;
     while ($retries < $this->options['max_retries']) {
         $retries++;
         try {
             foreach ($this->statements() as $statement) {
                 $this->getLogger()->debug("Executing statement `{$statement}`");
                 $this->adapter->query($statement);
             }
             return;
         } catch (\Exception $e) {
             if ($this->shouldRetryException($e)) {
                 $this->getLogger()->warning($e->getMessage());
                 sleep($this->options['retry_sleep_time']);
                 //TODO log the retry
                 continue;
             }
             throw $e;
         }
     }
 }
Exemplo n.º 14
0
 public function testAddTableWithForeignKey()
 {
     $this->mock->expects($this->any())->method('isValidColumnType')->with($this->callback(function ($column) {
         return in_array($column->getType(), array('string', 'integer'));
     }))->will($this->returnValue(true));
     $table = new Table('table', array(), $this->adapter);
     $table->addColumn('bar', 'string')->addColumn('relation', 'integer')->addForeignKey('relation', 'target_table', array('id'));
     $this->mock->expects($this->once())->method('createTable')->with($this->callback(function ($table) {
         if ($table->getName() !== 'pre_table_suf') {
             throw new \Exception(sprintf('Table::getName was not prefixed/suffixed properly: "%s"', $table->getName()));
         }
         $fks = $table->getForeignKeys();
         if (count($fks) !== 1) {
             throw new \Exception(sprintf('Table::getForeignKeys count was incorrect: %d', count($fks)));
         }
         foreach ($fks as $fk) {
             if ($fk->getReferencedTable()->getName() !== 'pre_target_table_suf') {
                 throw new \Exception(sprintf('ForeignKey::getReferencedTable was not prefixed/suffixed properly: "%s"', $fk->getReferencedTable->getName()));
             }
         }
         return true;
     }));
     $table->create();
 }
Exemplo n.º 15
0
 /**
  * Drops the specified database.
  *
  * @param string $name Database Name
  * @return void
  */
 public function dropDatabase($name)
 {
     $this->adapter->dropDatabase($name);
 }
Exemplo n.º 16
0
 /**
  * {@inheritdoc}
  */
 public function getOutput()
 {
     return $this->adapter->getOutput();
 }
Exemplo n.º 17
0
 /**
  * Closes the database connection.
  *
  * @return void
  */
 public function disconnect()
 {
     $this->adapter->disconnect();
 }