/** * Runs a collection of versions towards the specified goal and using the specified options * * @param DeltaInterface $target * @param OptionsInterface $options * * @return CollectionAfterEvent */ public function run(DeltaInterface $target, OptionsInterface $options) { $current = 1; $collection = $this->getCollection(); $context = CollectionContext::createWithProgress(max($collection->count(), 1), $current); $migrationRunner = $this->migrationRunner->withContext($context); $this->getPublisher()->publish(new CollectionBeforeEvent($target, $options, $collection)); $modified = new Collection(); $comparator = $collection->getComparator(); // IMPROVE: add tests to see if rewind is necessary $collection->first(); // rewind foreach ($collection as $version) { $context->getProgress()->update($current); $result = $migrationRunner->run($version, $options); if ($result) { $modified->add($version); } if ($comparator->compare($version, $target) >= 0) { break; } $current += 1; } $event = new CollectionAfterEvent($target, $options, $modified); $this->getPublisher()->publish($event); return $event; }
/** * @inheritdoc */ public function doResolve($alias, Collection $collection) { // exit early if there's a full match if ($collection->contains($alias)) { return $collection->get($alias); } // lazy id search $length = strlen($alias); $candidate = null; foreach ($collection as $key => $version) { if (substr($key, 0, $length) === $alias) { if (null === $candidate) { // make this version a candidate, but continue searching to see if any other items also meet the // condition (in which case we'd know the $id being searched for is "ambiguous") $candidate = $version; } else { // the $id is ambiguous when used for lazy matching, therefore: $candidate = null; // remove the candidate break; } } } return $candidate; }
/** * doResolve * * @param $alias * @param Collection $collection * * @return DeltaInterface|null */ protected function doResolve($alias, Collection $collection) { if (strtolower($alias) !== self::HEAD) { return null; } $reversed = $collection->getReverse(); foreach ($reversed as $version) { /** @var DeltaInterface $version */ if ($version->isMigrated()) { return $version; } } return null; }
/** * Resolves an alias into a Delta. * * @param string $alias * * @param Collection $collection * @return DeltaInterface|null */ protected function doResolve($alias, Collection $collection) { $result = null; switch (strtolower($alias)) { case self::LAST: case self::LATEST: $result = $collection->last(); break; case self::FIRST: case self::EARLIEST: $result = $collection->first(); break; default: } return $result; }
/** * Returns true if the specified version is valid (can be added) to the collection. Otherwise, it MUST throw * an exception. * * @param DeltaInterface $version * * @return bool * * @throws CollectionException */ public function validate(DeltaInterface $version) { if (!$version->isMigrated()) { throw new CollectionException('Invalid version specified: this collection only accepts deltas that are migrated.'); } return parent::validate($version); }
/** * @inheritdoc */ public function fetchAll() { $definitions = $this->mapper->fetchAll(); $stored = array_map(function (DeltaId $id) { return $id->toString(); }, $this->storage->fetchAll()); $collection = new Collection(); foreach ($definitions as $definition) { /** @var DefinitionInterface $definition */ $migration = $definition->getMigration(); $id = $definition->getId(); $migrated = in_array($id->toString(), $stored); $version = new Delta($migration, $migrated, $id, $this->getMigrationBus()); $collection->add($version); } return $collection->sort($this->comparator); }
/** * @{inheritdoc} * * IMPROVE: this method has an NPath complexity of 400. The configured NPath complexity threshold is 200. * * @SuppressWarnings(PHPMD.NPathComplexity) * * @param string $alias * @param Collection $collection * * @return DeltaInterface|null */ protected function doResolve($alias, Collection $collection) { // parse alias $matches = []; if (!preg_match(self::PATTERN, $alias, $matches)) { return null; } list(, $newAlias, $operator) = $matches; // resolve the new alias (this will allow to resolve e.g. HEAD-1) $absoluteVersion = $collection->get($newAlias); if (null === $absoluteVersion) { return null; } // calculate the offset $count = !isset($matches[3]) ? strlen($operator) : (int) $matches[3]; if (strlen($operator) > 1) { $operator = substr($operator, 0, 1); } $multiplier = $operator === '+' ? 1 : -1; $offset = $count * $multiplier; // find version by absolute getPosition + offset $absolutePos = $collection->getPosition($absoluteVersion); return $collection->getByPosition($absolutePos + $offset); }
/** * Fetches all versions available to all repositories in the stack and returns them as a Linked collection. * * The returned collection contains versions groups sequentially into groups that correspond to each sub-repository. * Each of those groups is sorted with the repository's own comparator. Therefore, its strongly recommended not to * sort or modify the resulting collection. * * @return Collection */ public function fetchAll() { $collection = new Collection(); foreach ($this->getRepositories() as $repo) { /** @var MigrationRepositoryInterface $repo */ $versions = $repo->fetchAll(); $collection->merge($versions); } return $collection; }