Skip to content

Commit

Permalink
Merge pull request #38 from absynce/custom-migration-attributes
Browse files Browse the repository at this point in the history
Custom migration attributes
  • Loading branch information
absynce committed Jan 21, 2016
2 parents 5f917f2 + b4ed82a commit c7a8680
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 4 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ changes. This project adheres to [Semantic Versioning](http://semver.org).
versions of Raven ignore multiple separators and others do not. This change
could cause migrations to be run multiple times in some cases if the ids are not
changed first.
- Added - Ability to inherit from `MigrationAttribute` to specify custom migration
versions.

## [1.2.0]
- Added new way to change a collection with
Expand Down
45 changes: 45 additions & 0 deletions RavenMigrations.Tests/RunnerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,24 @@ public void Can_call_migrations_that_are_not_direct_subclasses_of_Migration()
}
}
}

[Fact]
public void Can_call_migrations_with_custom_attributes()
{
using (var store = NewDocumentStore())
{
new TestDocumentIndex().Execute(store);

Runner.Run(store);
WaitForIndexing(store);

using (var session = store.OpenSession())
{
var customMigration = session.Load<object>("migrated-using-custom-migration-attribute");
customMigration.Should().NotBeNull();
}
}
}
}

public class TestDocument
Expand Down Expand Up @@ -359,10 +377,37 @@ public override void Up()
}
}

[MigrationVersion(6, 0, 0, 0)]
public class Uses_Custom_Migration_Attribute : Migration
{
public override void Up()
{
using (var session = DocumentStore.OpenSession())
{
session.Store(new { Id = "migrated-using-custom-migration-attribute" });
session.SaveChanges();
}
}
}

public abstract class BaseMigration : Migration
{
public override void Up()
{
}
}

public class MigrationVersionAttribute : MigrationAttribute
{
public MigrationVersionAttribute(int major, int minor, int patch, int migration, params string [] profiles)
:base(CreateVersionNumber(major, minor, patch, migration), profiles)
{

}

private static long CreateVersionNumber(int major, int minor, int patch, int migration)
{
return major*1000000000000L + minor*100000000L + patch*1000000L + migration;
}
}
}
2 changes: 1 addition & 1 deletion RavenMigrations/RavenMigrationHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public static string GetMigrationIdFromName(this Migration migration, char seper
public static MigrationAttribute GetMigrationAttribute(this Type type)
{
var attribute = Attribute.GetCustomAttributes(type)
.FirstOrDefault(x => x.GetType().IsAssignableFrom(typeof(MigrationAttribute)));
.FirstOrDefault(x => x is MigrationAttribute);
return (MigrationAttribute)attribute;
}

Expand Down
37 changes: 34 additions & 3 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ In every migration you have access to the document store, so you are able to do

### Runner

Raven Migrations comes with a migration runner. It scans all provided assemblies for any classes implementing the **Migration** base class and then orders them according to their migration value.
Raven Migrations comes with a migration runner. It scans all provided assemblies for any classes implementing the **Migration** base class and then orders them according to their migration value.

After each migration is executed, a document of type **MigrationDocument** is inserted into your database, to insure the next time the runner is executed that migration is not executed again. When a migration is rolled back the document is removed.

Expand Down Expand Up @@ -127,7 +127,7 @@ Raven Migrations lets you migrate at the **RavenJObject** level, giving full acc
Alter.Collection("People", (doc, metadata) => { ... });
```

Batching changes is taken care of with the default batch size being 128. You can change the batch size if needed:
Batching changes is taken care of with the default batch size being 128. You can change the batch size if needed:
```
public void Collection(string tag, Action<RavenJObject, RavenJObject> action, int pageSize = 128)
```
Expand Down Expand Up @@ -234,6 +234,38 @@ Let's say that you refactor and move ```Person``` to another assembly. So that
}
```

### Custom migration attributes

If the `long` version number does not fit your versioning scheme, a custom
attribute can inherit from `MigrationAttribute`.

Example implementation for semantic versions:
```
public class MigrationVersionAttribute : MigrationAttribute
{
public MigrationVersionAttribute(int major, int minor, int patch, int migration, params string [] profiles)
:base(CreateVersionNumber(major, minor, patch, migration), profiles)
{
}
private static long CreateVersionNumber(int major, int minor, int patch, int migration)
{
return major*100000000000L + minor*10000000L + patch*1000L + migration;
}
}
}
```

Example usage in a migration:
```
[MigrationVersion(6, 9, 11, 1)]
public class CustomVersionMigration : Migration
{
public override void Up() { /* ... */ }
}
```

## Integration

We suggest you run the migrations at the start of your application to ensure that any new changes you have made apply to your application before you application starts. If you do not want to do it here, you can choose to do it out of band using a seperate application.
Expand Down Expand Up @@ -269,4 +301,3 @@ Thanks goes to [Sean Kearon](https://github.com/seankearon) who helped dog food

This project strives to adhere to the [semver](http://semver.org) guidelines. See the [contributing](./CONTRIBUTING.md) and [maintaining](./MAINTAINING.md)
guides for more on this.

0 comments on commit c7a8680

Please sign in to comment.