Changeset 1b5faf072403…
Parent 8c6cf6675089…
by Daniel Pupek
Changes to 9 files · Browse files at 1b5faf072403 Showing diff from parent 8c6cf6675089 Diff from another changeset...
@@ -71,6 +71,7 @@ public abstract class Migration
{
private TransformationProvider _transformationProvider;
+ private Migrator _migrator;
private Dictionary<string, string> _parameters;
private Dictionary<string, TransformationProvider> _additionalProviders;
@@ -97,6 +98,8 @@ }
}
+
+
/// <summary>
/// Allow the migrations access to additional providers
/// </summary>
@@ -139,18 +142,60 @@ }
}
- internal void Prepare(Providers.TransformationProvider _provider,Dictionary<string,Providers.TransformationProvider> dictionary,Dictionary<string,string> dictionary_2)
+ #region "Other Migrations"
+
+ /// <summary>
+ /// Used to migrate a SINGLE migration down from another migration. During normal migration processing
+ /// any migrations that are downed by this method will be up'd again after all migrations have run.
+ /// The down for a migration will only be called on the firtst execution. Subsequent calls will
+ /// just return.
+ /// </summary>
+ /// <param name="migrationVersion">Version to migrate down</param>
+ public void MigrateDown(int migrationVersion)
{
- TransformationProvider = _provider;
+ // If the migration isn't in the migrations table then just return
+ if (!Database.HasMigrationRun(migrationVersion))
+ return;
+
+ var currentMigration = _migrator.GetMigration(migrationVersion);
+
+ if (currentMigration == null)
+ throw new MigrationNotFoundException(migrationVersion);
+
+ currentMigration.Down();
+ Database.RemoveMigrationRecord(migrationVersion);
+
+ }
+ /// <summary>
+ /// Used to migrate a migration down from another migration. During normal migration processing
+ /// any migrations that are downed by this method will be up'd again after all migrations have run.
+ /// The down for a migration will only be called on the firtst execution. Subsequent calls will
+ /// just return.
+ /// </summary>
+ /// <typeparam name="TM">Migration to migrate down</typeparam>
+ public void MigrateDown<TM>()
+ {
+ MigrateDown(Migrator.GetMigrationVersion(typeof (TM)));
+ }
+
+ #endregion
+
+ internal void Prepare(TransformationProvider provider, Dictionary<string, TransformationProvider> dictionary, Migrator migrator)
+ {
+ TransformationProvider = provider;
Databases = this._additionalProviders;
Parameters = this._parameters;
TransformationProvider.Timeout = null;
- var guidAttribute = (GuidAttribute)Attribute.GetCustomAttribute(this.GetType().Assembly, typeof(GuidAttribute));
-
- if (guidAttribute == null || guidAttribute.Value == null || guidAttribute.Value.Trim().Equals(String.Empty))
- throw new ArgumentException("No guid identifier detected for migration");
- TransformationProvider.AssemblyId = guidAttribute.Value;
+ this._migrator = migrator;
+
}
}
-
+
+ /// <summary>
+ /// These migrations are run after all other migrations
+ /// </summary>
+ public abstract class IndexMigration : Migration
+ {
+
+ }
}
|
@@ -15,7 +15,8 @@ namespace Migrator
{
/// <summary>
- /// Comparer of Migration by their version attribute.
+ /// Comparer of Migration by their version attribute and Index yType.
+ /// Use to sort a list of migrations by Version with all IndexMigrations at the end
/// </summary>
public class MigrationTypeComparer : IComparer<Type>
{
@@ -34,11 +35,27 @@ {
var attribOfX = (MigrationAttribute) Attribute.GetCustomAttribute( x, typeof(MigrationAttribute));
var attribOfY = (MigrationAttribute) Attribute.GetCustomAttribute( y, typeof(MigrationAttribute));
-
- if (_ascending)
- return attribOfX.Version - attribOfY.Version;
- else
- return attribOfY.Version - attribOfX.Version;
+
+ var bothIndexes = x.IsSubclassOf(typeof(IndexMigration)) && y.IsSubclassOf(typeof(IndexMigration));
+ var bothNotIndexes = !x.IsSubclassOf(typeof(IndexMigration)) && !y.IsSubclassOf(typeof(IndexMigration));
+
+ if (_ascending)
+ {
+ if (bothIndexes || bothNotIndexes)
+ return attribOfX.Version - attribOfY.Version;
+ if (x.IsSubclassOf(typeof(IndexMigration)))
+ return 1;
+ return -1;
+ }
+ else
+ {
+ if (bothIndexes || bothNotIndexes)
+ return attribOfY.Version - attribOfX.Version;
+ if (x.IsSubclassOf(typeof(IndexMigration)))
+ return -1;
+ return 1;
+
+ }
}
}
}
|
|
@@ -0,0 +1,17 @@ + using System;
+
+namespace Migrator
+{
+ /// <summary>
+ /// Thrown when migrate up or down is called on a version that does not exist
+ /// </summary>
+ public class MigrationNotFoundException : Exception
+ {
+ public MigrationNotFoundException(int migrationVersion): base("The migration was not found. Migration version " + migrationVersion.ToString())
+ {
+ VersionNotFound = migrationVersion;
+ }
+
+ public int VersionNotFound { get; private set; }
+ }
+}
\ No newline at end of file |
|
|
@@ -65,34 +65,13 @@ : this(CreateProvider(provider, connectionString), migrationAssembly, logger)
{ }
- /// <summary>
- ///
- /// </summary>
- /// <param name="provider"></param>
- /// <param name="connectionString"></param>
- /// <param name="migrationAssembly"></param>
- /// <param name="trace"></param>
- public Migrator(string provider, string connectionString, Assembly migrationAssembly, bool trace)
- : this(CreateProvider(provider, connectionString), migrationAssembly, new Log4NetLogger())
- { }
-
- /// <summary>
- ///
- /// </summary>
- /// <param name="provider"></param>
- /// <param name="connectionString"></param>
- /// <param name="migrationAssembly"></param>
- public Migrator(string provider, string connectionString, Assembly migrationAssembly)
- : this(CreateProvider(provider, connectionString), migrationAssembly, new Log4NetLogger())
- { }
-
+
/// <summary>
///
/// </summary>
/// <param name="provider"></param>
/// <param name="migrationAssembly"></param>
- /// <param name="trace"></param>
- public Migrator(TransformationProvider provider, Assembly migrationAssembly, bool trace)
+ public Migrator(TransformationProvider provider, Assembly migrationAssembly)
: this(provider, migrationAssembly, new Log4NetLogger())
{ }
@@ -100,7 +79,7 @@ /// Runs Migrations in the executing <c>Assembly</c>
/// </summary>
public Migrator(string provider, string connectionString)
- : this(CreateProvider(provider, connectionString), Assembly.GetExecutingAssembly(), new Log4NetLogger())
+ : this(provider, connectionString ,Assembly.GetExecutingAssembly(), new Log4NetLogger())
{ }
/// <summary>
@@ -248,13 +227,15 @@ #endregion
#region Static Methods
- /// <summary>
- /// Allow a migration to create a TransformationProvider to another database so it can migrate data from that database
- /// </summary>
- /// <param name="providerName"></param>
- /// <param name="constr"></param>
- /// <returns></returns>
- public static TransformationProvider CreateProvider(string providerName, string constr)
+
+ /// <summary>
+ /// Allow a migration to create a TransformationProvider to another database so it can migrate data from that database
+ /// </summary>
+ /// <param name="providerName"></param>
+ /// <param name="constr"></param>
+ /// <param name="migrator"></param>
+ /// <returns></returns>
+ public static TransformationProvider CreateProvider(string providerName, string constr)
{
return new ProviderFactory().Create(providerName, constr);
}
@@ -414,13 +395,28 @@
this._logger.Started(HighestDatabaseVersion, toVersion);
IEnumerable<int> migratedVersions = new List<int>();
-
- if (goingUp)
- migratedVersions = InternalMigrateUpTo(toVersion);
- else
- migratedVersions = InternalMigrateDownTo(toVersion);
-
+ for (;;)
+ {
+ IEnumerable<int> versionsMigratedLastRun;
+
+ if (goingUp)
+ versionsMigratedLastRun = InternalMigrateUpTo(toVersion);
+ else
+ versionsMigratedLastRun = InternalMigrateDownTo(toVersion);
+
+ // Enumerate just once
+ var migratedLastRun = versionsMigratedLastRun as int[] ?? versionsMigratedLastRun.ToArray();
+ // If we migrated no new migrations then break
+ if (!migratedLastRun.Any())
+ break;
+
+ // Add the new set of migrations and continue
+ migratedVersions = migratedVersions.Concat(migratedLastRun);
+
+ _logger.Log("Checking for additional migrations to run.");
+
+ }
this.CommitTransactions();
_logger.Log("{0} migrations were run {1}", migratedVersions.Count(), goingUp ? "UP":"DOWN");
@@ -536,12 +532,15 @@ /// </summary>
/// <param name="toVersion">Version to run UP to</param>
/// <returns></returns>
- private Queue<Migration> GetMigrationsToBeRunUP(int toVersion)
+ internal Queue<Migration> GetMigrationsToBeRunUP(int toVersion)
{
var queue = new Queue<Migration>();
+ var migs = MigrationsTypes.ToList();
+
+ migs.Sort(new MigrationTypeComparer(true));
- foreach (var mtype in MigrationsTypes.OrderBy(GetMigrationVersion))
+ foreach (var mtype in migs)
{
var version = GetMigrationVersion(mtype);
@@ -560,12 +559,15 @@ /// </summary>
/// <param name="toVersion"></param>
/// <returns></returns>
- private Queue<Migration> GetMigrationsToBeRunDown(int toVersion)
+ internal Queue<Migration> GetMigrationsToBeRunDown(int toVersion)
{
var queue = new Queue<Migration>();
+ var migs = MigrationsTypes.ToList();
- foreach (var mtype in MigrationsTypes.OrderByDescending(GetMigrationVersion))
+ migs.Sort(new MigrationTypeComparer(false));
+
+ foreach (var mtype in migs)
{
var version = GetMigrationVersion(mtype);
@@ -721,7 +723,7 @@ return MigrationsTypes.FirstOrDefault(m => GetMigrationVersion(m) == version);
}
- private Migration GetMigration(int version)
+ internal Migration GetMigration(int version)
{
Type t = GetMigrationType(version);
if (t == null)
@@ -740,7 +742,7 @@ private Migration InitializeMigration(Migration migration)
{
// initialize Migration variables injected from the Migrator
- migration.Prepare(_provider, this._additionalProviders, this._parameters);
+ migration.Prepare(_provider, this._additionalProviders, this);
return migration;
}
#endregion
|
@@ -79,6 +79,7 @@ <Compile Include="Mappers\AbstractMapper.cs" />
<Compile Include="Mappers\MySqlMapper.cs" />
<Compile Include="Mappers\SqlMapper.cs" />
+ <Compile Include="MigrationNotFoundException.cs" />
<Compile Include="MigratorSettingsAttribute.cs" />
<Compile Include="PrimaryKey.cs" />
<Compile Include="Providers\SqlParser.cs" />
|
@@ -22,9 +22,12 @@
string providerName = GuessProviderName(name);
- return (TransformationProvider) Activator.CreateInstance(
+ var provider = (TransformationProvider) Activator.CreateInstance(
Type.GetType(string.Format("Migrator.Providers.{0}TransformationProvider, Migrator", providerName), true),
new object[] { connectionString });
+
+ return provider;
+
}
private Dictionary<String, String> _provider_Map = new Dictionary<String, String> {
|
@@ -94,6 +94,7 @@ set { this._timeout = value; }
}
+
#endregion
#region Tables
@@ -836,8 +837,10 @@
#endregion
- #region Data Manipulation
- /// <summary>
+
+
+ #region Data Manipulation
+ /// <summary>
/// Copies rows from one table to another
/// </summary>
/// <param name="fromTable">The name of the table being copied from</param>
|
|
@@ -0,0 +1,4 @@ + <wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
+ <s:Boolean x:Key="/Default/Housekeeping/UnitTestingMru/UnitTestSessionPersistentData/=2AD4CB150C434A419F25B593C19872DC/@KeyIndexDefined">True</s:Boolean>
+ <s:String x:Key="/Default/Housekeeping/UnitTestingMru/UnitTestSessionPersistentData/=2AD4CB150C434A419F25B593C19872DC/Name/@EntryValue">MigratorTest</s:String>
+ <s:String x:Key="/Default/Housekeeping/UnitTestingMru/UnitTestSessionPersistentData/=2AD4CB150C434A419F25B593C19872DC/XmlSerializedElements/@EntryValue"><Session><Elements><UnitTestElement Provider="nUnit" Id="Migrator.Tests.MigratorTest" type="NUnitTestFixtureElement" Project="882B6A93-67B8-45BF-8636-5796B1B1CBF8" /><UnitTestElement Provider="nUnit" Id="Migrator.Tests.MigratorTest.CheckForDuplicatedVersion" ParentId="Migrator.Tests.MigratorTest" type="NUnitTestElement" TypeName="Migrator.Tests.MigratorTest" MethodName="CheckForDuplicatedVersion" Project="882B6A93-67B8-45BF-8636-5796B1B1CBF8" /><UnitTestElement Provider="nUnit" Id="Migrator.Tests.MigratorTest.CurrentVersion" ParentId="Migrator.Tests.MigratorTest" type="NUnitTestElement" TypeName="Migrator.Tests.MigratorTest" MethodName="CurrentVersion" Project="882B6A93-67B8-45BF-8636-5796B1B1CBF8" /><UnitTestElement Provider="nUnit" Id="Migrator.Tests.MigratorTest.LastVersion" ParentId="Migrator.Tests.MigratorTest" type="NUnitTestElement" TypeName="Migrator.Tests.MigratorTest" MethodName="LastVersion" Project="882B6A93-67B8-45BF-8636-5796B1B1CBF8" /><UnitTestElement Provider="nUnit" Id="Migrator.Tests.MigratorTest.MigrateDownwardWithRollback" ParentId="Migrator.Tests.MigratorTest" type="NUnitTestElement" TypeName="Migrator.Tests.MigratorTest" MethodName="MigrateDownwardWithRollback" Project="882B6A93-67B8-45BF-8636-5796B1B1CBF8" /><UnitTestElement Provider="nUnit" Id="Migrator.Tests.MigratorTest.MigrateToCurrentVersion" ParentId="Migrator.Tests.MigratorTest" type="NUnitTestElement" TypeName="Migrator.Tests.MigratorTest" MethodName="MigrateToCurrentVersion" Project="882B6A93-67B8-45BF-8636-5796B1B1CBF8" /><UnitTestElement Provider="nUnit" Id="Migrator.Tests.MigratorTest.MigrateUpward" ParentId="Migrator.Tests.MigratorTest" type="NUnitTestElement" TypeName="Migrator.Tests.MigratorTest" MethodName="MigrateUpward" Project="882B6A93-67B8-45BF-8636-5796B1B1CBF8" /><UnitTestElement Provider="nUnit" Id="Migrator.Tests.MigratorTest.MigrateUpwardWithRollback" ParentId="Migrator.Tests.MigratorTest" type="NUnitTestElement" TypeName="Migrator.Tests.MigratorTest" MethodName="MigrateUpwardWithRollback" Project="882B6A93-67B8-45BF-8636-5796B1B1CBF8" /><UnitTestElement Provider="nUnit" Id="Migrator.Tests.MigratorTest.TestOrder" ParentId="Migrator.Tests.MigratorTest" type="NUnitTestElement" TypeName="Migrator.Tests.MigratorTest" MethodName="TestOrder" Project="882B6A93-67B8-45BF-8636-5796B1B1CBF8" /><UnitTestElement Provider="nUnit" Id="Migrator.Tests.MigratorTest.TestOrderDesc" ParentId="Migrator.Tests.MigratorTest" type="NUnitTestElement" TypeName="Migrator.Tests.MigratorTest" MethodName="TestOrderDesc" Project="882B6A93-67B8-45BF-8636-5796B1B1CBF8" /></Elements></Session></s:String></wpf:ResourceDictionary>
\ No newline at end of file |
|
@@ -10,6 +10,8 @@ #endregion
using System;
using System.Collections;
+using System.Data;
+using System.Linq;
using NUnit.Framework;
using NMock;
using Migrator.Providers;
@@ -31,8 +33,30 @@ [SetUp]
public void SetUp()
{
- _provider = new SqlServerTransformationProvider("");
- _migrator = new Migrator(_provider, typeof(FirstMigration).Assembly, true);
+ var dprovider = new SqlServerTransformationProvider("Server=localhost;Database=Master;Trusted_Connection=True;");
+ var dropsql = @"/****** Object: Database [MigratorTest] Script Date: 04/22/2014 12:55:41 ******/
+ IF EXISTS (SELECT name FROM sys.databases WHERE name = N'MigratorTest')
+ DROP DATABASE [MigratorTest]
+ ";
+ var createSql = @"
+ /****** Object: Database [MigratorTest] Script Date: 04/22/2014 12:55:41 ******/
+ CREATE DATABASE [MigratorTest] ";
+ // dprovider.BeginTransaction();
+ var cmd = dprovider.Connection.CreateCommand();
+ cmd.CommandText = dropsql;
+ cmd.CommandType = CommandType.Text;
+ cmd.ExecuteNonQuery();
+ cmd.Dispose();
+
+ cmd = dprovider.Connection.CreateCommand();
+ cmd.CommandText = createSql;
+ cmd.CommandType = CommandType.Text;
+ cmd.ExecuteNonQuery();
+ cmd.Dispose();
+
+
+ _provider = new SqlServerTransformationProvider("Server=localhost;Database=MigratorTest;Trusted_Connection=True;");
+ _migrator = new Migrator(_provider, typeof(FirstMigration).Assembly);
_upCalled.Clear();
_downCalled.Clear();
@@ -42,31 +66,94 @@ [Test]
public void MigrateUpward()
{
- SetUpCurrentVersion(1);
- _migrator.MigrateTo(3);
+ _migrator.MigrateToLastVersion();
- Assert.AreEqual(3, _migrator.HighestDatabaseVersion);
+ Assert.AreEqual(6, _migrator.HighestDatabaseVersion);
+ Assert.IsTrue(_migrator.HasMigrationRun(5));
- Assert.AreEqual(2, _upCalled.Count);
- Assert.AreEqual(0, _downCalled.Count);
-
- Assert.AreEqual(2, _upCalled[0]);
- Assert.AreEqual(3, _upCalled[1]);
}
[Test]
- public void MigrateBackward()
+ public void TestOrder()
{
- SetUpCurrentVersion(3);
- _migrator.MigrateTo(1);
-
- Assert.AreEqual(0, _upCalled.Count);
- Assert.AreEqual(2, _downCalled.Count);
-
- Assert.AreEqual(3, _downCalled[0]);
- Assert.AreEqual(2, _downCalled[1]);
+ var migs = _migrator.MigrationsTypes.ToList();
+
+ migs.Sort(new MigrationTypeComparer(true));
+
+ Assert.AreEqual(6, migs.Count);
+ for (var i = 0; i < migs.Count; i++)
+ {
+ switch (i)
+ {
+ case 0:
+ //1
+ Assert.AreEqual(1, Migrator.GetMigrationVersion(migs[i]));
+ break;
+ case 1:
+ //3
+ Assert.AreEqual(3, Migrator.GetMigrationVersion(migs[i]));
+ break;
+ case 2:
+ //5
+ Assert.AreEqual(5, Migrator.GetMigrationVersion(migs[i]));
+ break;
+ case 3:
+ //6
+ Assert.AreEqual(6, Migrator.GetMigrationVersion(migs[i]));
+ break;
+ case 4:
+ //2
+ Assert.AreEqual(2, Migrator.GetMigrationVersion(migs[i]));
+ break;
+ case 5:
+ //4
+ Assert.AreEqual(4, Migrator.GetMigrationVersion(migs[i]));
+ break;
+ }
+ }
+
}
-
+
+ [Test]
+ public void TestOrderDesc()
+ {
+ var migs = _migrator.MigrationsTypes.ToList();
+
+ migs.Sort(new MigrationTypeComparer(false));
+
+ Assert.AreEqual(6, migs.Count);
+ for (var i = 0; i < migs.Count; i++)
+ {
+ switch (i)
+ {
+ case 5:
+ //1
+ Assert.AreEqual(1, Migrator.GetMigrationVersion(migs[i]));
+ break;
+ case 4:
+ //3
+ Assert.AreEqual(3, Migrator.GetMigrationVersion(migs[i]));
+ break;
+ case 3:
+ //5
+ Assert.AreEqual(5, Migrator.GetMigrationVersion(migs[i]));
+ break;
+ case 2:
+ //6
+ Assert.AreEqual(6, Migrator.GetMigrationVersion(migs[i]));
+ break;
+ case 1:
+ //2
+ Assert.AreEqual(2, Migrator.GetMigrationVersion(migs[i]));
+ break;
+ case 0:
+ //4
+ Assert.AreEqual(4, Migrator.GetMigrationVersion(migs[i]));
+ break;
+ }
+ }
+
+ }
[Test]
public void MigrateUpwardWithRollback()
{
@@ -147,36 +234,82 @@ #endregion
}
[Migration(1, Ignore = false)]
- public class FirstMigration : AbstractTestMigration { }
+ public class FirstMigration : Migration {
+ public override void Up()
+ {
+
+ }
+
+ public override void Down()
+ {
+
+ }
+ }
[Migration(2, Ignore = false)]
- public class SecondMigration : AbstractTestMigration { }
+ public class SecondMigration : IndexMigration
+ {
+ public override void Up()
+ {
+
+ }
+
+ public override void Down()
+ {
+
+ }
+ }
[Migration(3, Ignore = false)]
- public class ThirdMigration : AbstractTestMigration { }
+ public class ThirdMigration : Migration
+ {
+ public override void Up()
+ {
+
+ }
+
+ public override void Down()
+ {
+
+ }
+ }
[Migration(4, Ignore = false)]
- public class ForthMigration : AbstractTestMigration { }
+ public class ForthMigration : IndexMigration
+ {
+ public override void Up()
+ {
+
+ }
+
+ public override void Down()
+ {
+
+ }
+ }
[Migration(5, Ignore = false)]
- public class BadMigration : AbstractTestMigration
+ public class BadMigration : Migration
{
override public void Up()
{
- throw new Exception("oh uh!");
+ //throw new Exception("oh uh!");
}
override public void Down()
{
- throw new Exception("oh uh!");
+ //throw new Exception("oh uh!");
}
}
+
[Migration(6, Ignore = false)]
- public class SixthMigration : AbstractTestMigration { }
- public class AbstractTestMigration : Migration
+ public class SixthMigration : Migration
{
- override public void Up()
+ public override void Up()
{
- MigratorTest._upCalled.Add(Migrator.GetMigrationVersion(GetType()));
+ MigrateDown(5);
+
}
- override public void Down()
+
+
+ public override void Down()
{
- MigratorTest._downCalled.Add(Migrator.GetMigrationVersion(GetType()));
+
}
}
}
|
Loading...