/**
  * Rollback the open database transaction
  */
 public function rollback()
 {
     if ($this->transactionDepth === 1) {
         $this->connection->rollback();
     }
     $this->transactionDepth -= 1;
     return $this;
 }
Exemple #2
0
 /**
  * @param int $version target migration version, if not set all not applied available migrations will be applied
  * @param bool $force force apply migration
  * @param bool $down rollback migration
  * @throws MigrationException
  */
 public function migrate($version = null, $force = false, $down = false)
 {
     $migrations = $this->getMigrationClasses($force);
     if (!is_null($version) && !$this->hasMigrationVersions($migrations, $version)) {
         echo sprintf('Migration version %s is not found!', $version);
         return true;
         //            throw new MigrationException(sprintf('Migration version %s is not found!', $version));
     }
     $currentMigrationVersion = $this->migrationVersionTable->getCurrentVersion($this->migrationsDirMd5);
     if (!is_null($version) && $version == $currentMigrationVersion && !$force) {
         throw new MigrationException(sprintf('Migration version %s is current version!', $version));
     }
     $this->connection->beginTransaction();
     try {
         if ($version && $force) {
             foreach ($migrations as $migration) {
                 if ($migration['version'] == $version) {
                     // if existing migration is forced to apply - delete its information from migrated
                     // to avoid duplicate key error
                     if (!$down) {
                         $this->migrationVersionTable->delete($migration['version'], $this->migrationsDirMd5);
                     }
                     $this->applyMigration($migration, $down);
                     break;
                 }
             }
             // target migration version not set or target version is greater than last applied migration -> apply migrations
         } elseif (is_null($version) || !is_null($version) && $version > $currentMigrationVersion) {
             foreach ($migrations as $migration) {
                 if ($migration['version'] > $currentMigrationVersion) {
                     if (is_null($version) || !is_null($version) && $version >= $migration['version']) {
                         $this->applyMigration($migration);
                     }
                 }
             }
             // target migration version is set -> rollback migration
         } elseif (!is_null($version) && $version < $currentMigrationVersion) {
             $migrationsByDesc = $this->sortMigrationsByVersionDesc($migrations);
             foreach ($migrationsByDesc as $migration) {
                 if ($migration['version'] > $version && $migration['version'] <= $currentMigrationVersion) {
                     $this->applyMigration($migration, true);
                 }
             }
         }
         $this->connection->commit();
     } catch (InvalidQueryException $e) {
         $this->connection->rollback();
         $msg = sprintf('%s: "%s"; File: %s; Line #%d', $e->getMessage(), $e->getPrevious()->getMessage(), $e->getFile(), $e->getLine());
         throw new MigrationException($msg);
     } catch (\Exception $e) {
         $this->connection->rollback();
         $msg = sprintf('%s; File: %s; Line #%d', $e->getMessage(), $e->getFile(), $e->getLine());
         throw new MigrationException($msg);
     }
 }
 protected function applyMigration(array $migration, $down = false, $fake = false)
 {
     $this->connection->beginTransaction();
     try {
         /** @var $migrationObject AbstractMigration */
         $migrationObject = new $migration['class']($this->metadata, $this->outputWriter);
         if ($migrationObject instanceof ServiceLocatorAwareInterface) {
             if (is_null($this->serviceLocator)) {
                 throw new \RuntimeException(sprintf('Migration class %s requires a ServiceLocator, but there is no instance available.', get_class($migrationObject)));
             }
             $migrationObject->setServiceLocator($this->serviceLocator);
         }
         if ($migrationObject instanceof AdapterAwareInterface) {
             if (is_null($this->adapter)) {
                 throw new \RuntimeException(sprintf('Migration class %s requires an Adapter, but there is no instance available.', get_class($migrationObject)));
             }
             $migrationObject->setDbAdapter($this->adapter);
         }
         $this->outputWriter->writeLine(sprintf("%sExecute migration class %s %s", $fake ? '[FAKE] ' : '', $migration['class'], $down ? 'down' : 'up'));
         if (!$fake) {
             $sqlList = $down ? $migrationObject->getDownSql() : $migrationObject->getUpSql();
             foreach ($sqlList as $sql) {
                 $this->outputWriter->writeLine("Execute query:\n\n" . $sql);
                 $this->connection->execute($sql);
             }
         }
         if ($down) {
             $this->migrationVersionTable->delete($migration['version']);
         } else {
             $this->migrationVersionTable->save($migration['version'], $migration['source']);
         }
         $this->connection->commit();
     } catch (InvalidQueryException $e) {
         $this->connection->rollback();
         $previousMessage = $e->getPrevious() ? $e->getPrevious()->getMessage() : null;
         $msg = sprintf('%s: "%s"; File: %s; Line #%d', $e->getMessage(), $previousMessage, $e->getFile(), $e->getLine());
         throw new MigrationException($msg, $e->getCode(), $e);
     } catch (\Exception $e) {
         $this->connection->rollback();
         $msg = sprintf('%s; File: %s; Line #%d', $e->getMessage(), $e->getFile(), $e->getLine());
         throw new MigrationException($msg, $e->getCode(), $e);
     }
 }
 protected function tearDown()
 {
     $this->connection->rollback();
     unset($this->mapper);
     unset($this->connection);
 }