Skip to content
This repository has been archived by the owner on Apr 18, 2023. It is now read-only.

Commit

Permalink
Merge pull request #5 from baleen/timeline-last-migrated
Browse files Browse the repository at this point in the history
Collection Resolvers
  • Loading branch information
gsomoza committed Sep 15, 2015
2 parents b3c363c + fce8417 commit dc809b2
Show file tree
Hide file tree
Showing 24 changed files with 1,148 additions and 80 deletions.
28 changes: 28 additions & 0 deletions lib/Exception/ResolverException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/

namespace Baleen\Migrations\Exception;

/**
* Class ResolverException
* @author Gabriel Somoza <gabriel@strategery.io>
*/
class ResolverException extends CollectionException
{
}
9 changes: 7 additions & 2 deletions lib/Migration/Options.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,13 @@ class Options
*
* @throws InvalidArgumentException
*/
public function __construct($direction, $forced = false, $dryRun = false, $exceptionOnSkip = true, $custom = [])
{
public function __construct(
$direction = self::DIRECTION_UP,
$forced = false,
$dryRun = false,
$exceptionOnSkip = true,
$custom = []
) {
$this->allowedDirections = [
self::DIRECTION_UP,
self::DIRECTION_DOWN,
Expand Down
6 changes: 2 additions & 4 deletions lib/Storage/FileStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,7 @@ public function save(Version $version)
{
$result = false;
$stored = $this->fetchAll();
$exists = $stored->get($version);
if (!$exists) {
if (!$stored->has($version)) {
$stored->add($version);
$result = $this->saveCollection($stored);
}
Expand All @@ -140,8 +139,7 @@ public function delete(Version $version)
{
$result = false;
$stored = $this->fetchAll();
$exists = $stored->get($version);
if ($exists) {
if ($stored->has($version)) {
$stored->remove($version);
$result = $this->saveCollection($stored);
}
Expand Down
21 changes: 9 additions & 12 deletions lib/Timeline.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
use Baleen\Migrations\Exception\TimelineException;
use Baleen\Migrations\Migration\Options;
use Baleen\Migrations\Timeline\AbstractTimeline;
use Baleen\Migrations\Version\Collection\Resolver\FirstLastResolver;
use Baleen\Migrations\Version\Collection\SortableVersions;

/**
Expand All @@ -36,7 +37,7 @@ class Timeline extends AbstractTimeline
{
/**
* @param Version|string $goalVersion
* @param Options $options
* @param Options $options
*
* @return SortableVersions A collection of modified versions
*
Expand All @@ -55,7 +56,7 @@ public function upTowards($goalVersion, Options $options = null)

/**
* @param Version|string $goalVersion
* @param Options $options
* @param Options $options
*
* @return SortableVersions A collection of modified versions
*
Expand All @@ -69,12 +70,8 @@ public function downTowards($goalVersion, Options $options = null)
}
$options->setDirection(Options::DIRECTION_DOWN); // make sure its right

// reverse aliases because we're also reversing the collection
if ($goalVersion === SortableVersions::FIRST) {
$goalVersion = SortableVersions::LAST;
} elseif ($goalVersion === SortableVersions::LAST) {
$goalVersion = SortableVersions::FIRST;
}
// get the goal version now, before reversing the collection
$goalVersion = $this->versions->get($goalVersion);

return $this->runCollection($goalVersion, $options, $this->versions->getReverse());
}
Expand Down Expand Up @@ -106,10 +103,10 @@ public function goTowards($goalVersion, Options $options = null)
}

/**
* @param \Baleen\Migrations\Version $version
* @param Options $options
* @param Progress $progress Provides contextual information about current progress if this
* migration is one of many that are being run in batch.
* @param Version|string $version
* @param Options $options
* @param Progress $progress Provides contextual information about current progress if this
* migration is one of many that are being run in batch.
*
* @return Version|false
*
Expand Down
16 changes: 16 additions & 0 deletions lib/Timeline/AbstractTimeline.php
Original file line number Diff line number Diff line change
Expand Up @@ -151,4 +151,20 @@ protected function runCollection($goalVersion, Options $options, LinkedVersions

return $modified;
}

/**
* @inheritdoc
*/
public function getLastMigratedVersion()
{
$last = null;
foreach ($this->versions->getReverse() as $version) {
/** @var Version $version */
if ($version->isMigrated()) {
$last = $version;
break;
}
}
return $last;
}
}
9 changes: 9 additions & 0 deletions lib/Timeline/TimelineInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

use Baleen\Migrations\Event\Timeline\Progress;
use Baleen\Migrations\Migration\Options;
use Baleen\Migrations\Version;

/**
* The Timeline is responsible of emitting MigrateCommands based on how the user wants to navigate the timeline
Expand Down Expand Up @@ -57,11 +58,19 @@ public function downTowards($version, Options $options);
public function goTowards($goalVersion, Options $options);

/**
* Runs a single migration in the specified direction.
*
* @param \Baleen\Migrations\Version $version
* @param \Baleen\Migrations\Migration\Options $options
* @param Progress $progress
*
* @return
*/
public function runSingle($version, Options $options, Progress $progress);

/**
* Returns the latest version that has been migrated (a.k.a. the HEAD), or NULL if no version has been migrated.
* @return Version|null
*/
public function getLastMigratedVersion();
}
117 changes: 111 additions & 6 deletions lib/Version/Collection/IndexedVersions.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
use Baleen\Migrations\Exception\CollectionException;
use Baleen\Migrations\Exception\InvalidArgumentException;
use Baleen\Migrations\Version;
use Baleen\Migrations\Version\Collection\Resolver\DefaultResolverStackFactory;
use Baleen\Migrations\Version\Collection\Resolver\ResolverInterface;
use EBT\Collection\CollectionDirectAccessInterface;
use EBT\Collection\CountableTrait;
use EBT\Collection\DirectAccessTrait;
Expand All @@ -20,23 +22,35 @@
*
* @method Version current()
* @method Version[] getItems()
* @method Version get($index, $defaultValue = null)
* @method Version baseGet($index, $defaultValue = null)
*/
class IndexedVersions implements CollectionDirectAccessInterface
{
use CountableTrait, EmptyTrait, IterableTrait, GetItemsTrait, DirectAccessTrait;
use CountableTrait, EmptyTrait, IterableTrait, GetItemsTrait;
use DirectAccessTrait {
get as _get;
has as _has;
}

/**
* @var array
*/
protected $items = array();

/** @var ResolverInterface */
protected $resolver;

/** @var string[] */
protected $cache = [];

/**
* @param array $versions
*
* @param ResolverInterface $resolver
* @throws CollectionException
* @throws InvalidArgumentException
*/
public function __construct($versions = array())
public function __construct($versions = array(), ResolverInterface $resolver = null)
{
if (!is_array($versions)) {
if ($versions instanceof \Traversable) {
Expand All @@ -47,11 +61,93 @@ public function __construct($versions = array())
);
}
}
if (null !== $resolver) {
$this->setResolver($resolver);
}
foreach ($versions as $version) {
$this->add($version);
}
}

/**
* @param ResolverInterface $resolver
*/
public function setResolver(ResolverInterface $resolver)
{
$this->resolver = $resolver;
}

/**
* @return ResolverInterface
*/
public function getResolver()
{
if (null === $this->resolver) {
$factory = new DefaultResolverStackFactory();
$this->resolver = $factory->create();
}
return $this->resolver;
}

/**
* @param mixed $index
* @param mixed $defaultValue Will be returned if the index is not present at collection.
* @param bool $resolve Whether to use the resolver or not.
* @param bool $cache Whether to use the cache or not. Forced to false if $resolve = false.
* @return Version|null Null if not present
*/
public function get($index, $defaultValue = null, $resolve = true, $cache = true)
{
$index = (string) $index;

$result = null;

if ($resolve) {
$result = $this->resolve($index, $cache);
}

if (null === $result) {
$result = $this->_get($index, $defaultValue);
}

return $result;
}

/**
* Resolves an alias in to a version
* @param $alias
* @param bool|true $cache
* @return Version|null
*/
protected function resolve($alias, $cache = true)
{
$result = null;
if ($cache && !empty($this->cache[$alias])) {
$result = $this->cache[$alias];
} else {
$result = $this->getResolver()->resolve($alias, $this);
if ($cache) {
$this->cache[$alias] = $result;
}
}
return $result;
}

/**
* Returns whether the index exists in the collection
*
* @param $index
* @param bool $resolve
*
* @return bool
*/
public function has($index, $resolve = false)
{
$index = (string) $index;

return $this->get($index, null, $resolve) !== null;
}

/**
* Returns true if the specified version is valid (can be added) to the collection. Otherwise, it MUST throw
* an exception.
Expand All @@ -73,6 +169,14 @@ public function validate(Version $version)
return true; // if there are no exceptions then result is true
}

/**
* invalidateCache
*/
protected function invalidateCache()
{
$this->cache = [];
}

/**
* @param mixed $version
*
Expand All @@ -83,6 +187,7 @@ public function add($version)
if ($this->validate($version)) {
/* @var Version $version */
$this->items[$version->getId()] = $version;
$this->invalidateCache();
} else {
// this should never happen
throw new CollectionException(
Expand All @@ -98,6 +203,7 @@ public function remove($version)
{
if ($this->has($version)) {
unset($this->items[(string) $version]);
$this->invalidateCache();
}
}

Expand All @@ -109,10 +215,9 @@ public function remove($version)
public function addOrReplace(Version $version)
{
if ($this->has($version)) {
$this->items[$version->getId()] = $version; // replace
} else {
$this->add($version);
$this->remove($version);
}
$this->add($version);
}

/**
Expand Down

0 comments on commit dc809b2

Please sign in to comment.