diff --git a/Migrator-vs2010.sln b/Migrator-vs2010.sln
index a0c0e945..5f03a6c7 100644
--- a/Migrator-vs2010.sln
+++ b/Migrator-vs2010.sln
@@ -1,81 +1,49 @@
-
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Runners", "Runners", "{1CC77E58-4B1E-4D3F-86EA-5078883434FC}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{9844714F-717A-4C16-97A9-9995BB1B4A8B}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{8FF5F3DF-DF83-470C-ADFE-C0FF2B858F0F}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extras", "Extras", "{02B014BC-CC35-466F-A2F4-C5B5AC830653}"
- ProjectSection(SolutionItems) = preProject
- doc\CHANGES.txt = doc\CHANGES.txt
- default.build = default.build
- local.properties-example = local.properties-example
- src\MigratorDotNet.snk = src\MigratorDotNet.snk
- doc\README.txt = doc\README.txt
- doc\TODO.txt = doc\TODO.txt
- EndProjectSection
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Migrator-vs2010", "src\Migrator\Migrator-vs2010.csproj", "{1FEE70A4-AAD7-4C60-BE60-3F7DC03A8C4D}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Migrator.Framework-vs2010", "src\Migrator.Framework\Migrator.Framework-vs2010.csproj", "{5270F048-E580-486C-B14C-E5B9F6E539D4}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Migrator.Providers-vs2010", "src\Migrator.Providers\Migrator.Providers-vs2010.csproj", "{D58C68E4-D789-40F7-9078-C9F587D4363C}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Migrator.Console-vs2010", "src\Migrator.Console\Migrator.Console-vs2010.csproj", "{FBE3A83A-D0F8-4D72-AF8D-9EF772569A31}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Migrator.MSBuild-vs2010", "src\Migrator.MSBuild\Migrator.MSBuild-vs2010.csproj", "{A145FFA9-5FE6-4636-93B8-0C110D132BF3}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Migrator.NAnt-vs2010", "src\Migrator.NAnt\Migrator.NAnt-vs2010.csproj", "{CDD39DB7-C9C0-4ECA-AD36-1B4D0BF59101}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Migrator.Tests-vs2010", "src\Migrator.Tests\Migrator.Tests-vs2010.csproj", "{882B6A93-67B8-45BF-8636-5796B1B1CBF8}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {1FEE70A4-AAD7-4C60-BE60-3F7DC03A8C4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {1FEE70A4-AAD7-4C60-BE60-3F7DC03A8C4D}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {1FEE70A4-AAD7-4C60-BE60-3F7DC03A8C4D}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {1FEE70A4-AAD7-4C60-BE60-3F7DC03A8C4D}.Release|Any CPU.Build.0 = Release|Any CPU
- {5270F048-E580-486C-B14C-E5B9F6E539D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {5270F048-E580-486C-B14C-E5B9F6E539D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {5270F048-E580-486C-B14C-E5B9F6E539D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {5270F048-E580-486C-B14C-E5B9F6E539D4}.Release|Any CPU.Build.0 = Release|Any CPU
- {D58C68E4-D789-40F7-9078-C9F587D4363C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {D58C68E4-D789-40F7-9078-C9F587D4363C}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {D58C68E4-D789-40F7-9078-C9F587D4363C}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {D58C68E4-D789-40F7-9078-C9F587D4363C}.Release|Any CPU.Build.0 = Release|Any CPU
- {FBE3A83A-D0F8-4D72-AF8D-9EF772569A31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {FBE3A83A-D0F8-4D72-AF8D-9EF772569A31}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {FBE3A83A-D0F8-4D72-AF8D-9EF772569A31}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {FBE3A83A-D0F8-4D72-AF8D-9EF772569A31}.Release|Any CPU.Build.0 = Release|Any CPU
- {A145FFA9-5FE6-4636-93B8-0C110D132BF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {A145FFA9-5FE6-4636-93B8-0C110D132BF3}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {A145FFA9-5FE6-4636-93B8-0C110D132BF3}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {A145FFA9-5FE6-4636-93B8-0C110D132BF3}.Release|Any CPU.Build.0 = Release|Any CPU
- {CDD39DB7-C9C0-4ECA-AD36-1B4D0BF59101}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {CDD39DB7-C9C0-4ECA-AD36-1B4D0BF59101}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {CDD39DB7-C9C0-4ECA-AD36-1B4D0BF59101}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {CDD39DB7-C9C0-4ECA-AD36-1B4D0BF59101}.Release|Any CPU.Build.0 = Release|Any CPU
- {882B6A93-67B8-45BF-8636-5796B1B1CBF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {882B6A93-67B8-45BF-8636-5796B1B1CBF8}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {882B6A93-67B8-45BF-8636-5796B1B1CBF8}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {882B6A93-67B8-45BF-8636-5796B1B1CBF8}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(NestedProjects) = preSolution
- {FBE3A83A-D0F8-4D72-AF8D-9EF772569A31} = {1CC77E58-4B1E-4D3F-86EA-5078883434FC}
- {A145FFA9-5FE6-4636-93B8-0C110D132BF3} = {1CC77E58-4B1E-4D3F-86EA-5078883434FC}
- {CDD39DB7-C9C0-4ECA-AD36-1B4D0BF59101} = {1CC77E58-4B1E-4D3F-86EA-5078883434FC}
- {1FEE70A4-AAD7-4C60-BE60-3F7DC03A8C4D} = {9844714F-717A-4C16-97A9-9995BB1B4A8B}
- {5270F048-E580-486C-B14C-E5B9F6E539D4} = {9844714F-717A-4C16-97A9-9995BB1B4A8B}
- {D58C68E4-D789-40F7-9078-C9F587D4363C} = {9844714F-717A-4C16-97A9-9995BB1B4A8B}
- {882B6A93-67B8-45BF-8636-5796B1B1CBF8} = {8FF5F3DF-DF83-470C-ADFE-C0FF2B858F0F}
- EndGlobalSection
-EndGlobal
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{9844714F-717A-4C16-97A9-9995BB1B4A8B}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extras", "Extras", "{02B014BC-CC35-466F-A2F4-C5B5AC830653}"
+ ProjectSection(SolutionItems) = preProject
+ doc\CHANGES.txt = doc\CHANGES.txt
+ default.build = default.build
+ local.properties-example = local.properties-example
+ src\MigratorDotNet.snk = src\MigratorDotNet.snk
+ doc\README.txt = doc\README.txt
+ doc\TODO.txt = doc\TODO.txt
+ EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Migrator-vs2010", "src\Migrator\Migrator-vs2010.csproj", "{1FEE70A4-AAD7-4C60-BE60-3F7DC03A8C4D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Migrator.Framework-vs2010", "src\Migrator.Framework\Migrator.Framework-vs2010.csproj", "{5270F048-E580-486C-B14C-E5B9F6E539D4}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Migrator.Providers-vs2010", "src\Migrator.Providers\Migrator.Providers-vs2010.csproj", "{D58C68E4-D789-40F7-9078-C9F587D4363C}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {1FEE70A4-AAD7-4C60-BE60-3F7DC03A8C4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1FEE70A4-AAD7-4C60-BE60-3F7DC03A8C4D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1FEE70A4-AAD7-4C60-BE60-3F7DC03A8C4D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1FEE70A4-AAD7-4C60-BE60-3F7DC03A8C4D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5270F048-E580-486C-B14C-E5B9F6E539D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5270F048-E580-486C-B14C-E5B9F6E539D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5270F048-E580-486C-B14C-E5B9F6E539D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5270F048-E580-486C-B14C-E5B9F6E539D4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D58C68E4-D789-40F7-9078-C9F587D4363C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D58C68E4-D789-40F7-9078-C9F587D4363C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D58C68E4-D789-40F7-9078-C9F587D4363C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D58C68E4-D789-40F7-9078-C9F587D4363C}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {1FEE70A4-AAD7-4C60-BE60-3F7DC03A8C4D} = {9844714F-717A-4C16-97A9-9995BB1B4A8B}
+ {5270F048-E580-486C-B14C-E5B9F6E539D4} = {9844714F-717A-4C16-97A9-9995BB1B4A8B}
+ {D58C68E4-D789-40F7-9078-C9F587D4363C} = {9844714F-717A-4C16-97A9-9995BB1B4A8B}
+ EndGlobalSection
+EndGlobal
diff --git a/src/Migrator.Framework/ITransformationProvider.cs b/src/Migrator.Framework/ITransformationProvider.cs
index 46d77199..11f4c5a9 100644
--- a/src/Migrator.Framework/ITransformationProvider.cs
+++ b/src/Migrator.Framework/ITransformationProvider.cs
@@ -17,8 +17,8 @@ public interface ITransformationProvider : IDisposable
///
/// The list of Migrations currently applied to the database.
- ///
- List AppliedMigrations { get; }
+ ///
+ List> AppliedMigrations { get; }
ILogger Logger { get; set; }
@@ -346,14 +346,16 @@ void GenerateForeignKey(string foreignTable, string foreignColumn, string primar
///
/// Marks a Migration version number as having been applied
///
- /// The version number of the migration that was applied
- void MigrationApplied(long version);
+ /// The version number of the migration that was applied
+ /// Scope of migrations
+ void MigrationApplied(long version, string scope);
///
/// Marks a Migration version number as having been rolled back from the database
///
- /// The version number of the migration that was removed
- void MigrationUnApplied(long version);
+ /// The version number of the migration that was removed
+ /// Scope of migrations
+ void MigrationUnApplied(long version, string scope);
///
/// Remove an existing column from a table
diff --git a/src/Migrator.Framework/MigrationAttribute.cs b/src/Migrator.Framework/MigrationAttribute.cs
index c424dac1..2d2659d3 100644
--- a/src/Migrator.Framework/MigrationAttribute.cs
+++ b/src/Migrator.Framework/MigrationAttribute.cs
@@ -11,8 +11,9 @@
#endregion
-using System;
-
+using System;
+using System.Collections.Generic;
+
namespace Migrator.Framework
{
///
@@ -20,15 +21,23 @@ namespace Migrator.Framework
///
public class MigrationAttribute : Attribute
{
+ private string _scopeAssembly;
private long _version;
- private bool _ignore = false;
-
- ///
- /// Describe the migration
- ///
- /// The unique version of the migration.
- public MigrationAttribute(long version)
- {
+ private bool _ignore = false;
+
+ ///
+ /// Describe the migration
+ ///
+ /// The unique version of the migration.
+ /// Scope assembly
+ public MigrationAttribute(long version)
+ : this(version, null)
+ {
+ }
+
+ public MigrationAttribute(long version, string scopeAssembly)
+ {
+ _scopeAssembly = scopeAssembly;
Version = version;
}
@@ -41,6 +50,32 @@ public long Version
private set { _version = value; }
}
+ private string GetScopeId(Type t)
+ {
+ if (_scopeAssembly != null && _scopeAssembly.Length == 0)
+ return "00000000000000000000000000000000";
+ var x = new System.Security.Cryptography.MD5CryptoServiceProvider();
+ var bs = System.Text.Encoding.UTF8.GetBytes(_scopeAssembly ?? t.Assembly.GetName().Name);
+ bs = x.ComputeHash(bs);
+ var s = new System.Text.StringBuilder();
+ foreach (var b in bs)
+ s.Append(b.ToString("x2").ToUpper());
+ return s.ToString();
+ }
+
+ private Type _vType;
+ private KeyValuePair _v;
+
+ public KeyValuePair GetVersion(Type t)
+ {
+ if (t != _vType)
+ {
+ _v = new KeyValuePair(GetScopeId(t), Version);
+ _vType = t;
+ }
+ return _v;
+ }
+
///
/// Set to true to ignore this migration.
///
diff --git a/src/Migrator.Providers/Migrator.Providers-vs2010.csproj b/src/Migrator.Providers/Migrator.Providers-vs2010.csproj
index a41a9696..9c26d9fb 100644
--- a/src/Migrator.Providers/Migrator.Providers-vs2010.csproj
+++ b/src/Migrator.Providers/Migrator.Providers-vs2010.csproj
@@ -1,160 +1,161 @@
-
-
-
- Debug
- AnyCPU
- 9.0.30729
- 2.0
- {D58C68E4-D789-40F7-9078-C9F587D4363C}
- Library
- Migrator.Providers
- Migrator.Providers
-
-
- 3.5
-
-
- false
- true
- MigratorDotNet.snk
- v2.0
- publish\
- true
- Disk
- false
- Foreground
- 7
- Days
- false
- false
- true
- 0
- 1.0.0.%2a
- false
- true
-
-
- true
- full
- false
- bin\Debug\
- TRACE;DEBUG;DOTNET2
- prompt
- 4
- AllRules.ruleset
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
- AllRules.ruleset
-
-
-
- False
- ..\..\lib\Mono.Data.Sqlite.dll
-
-
- False
- ..\..\lib\Npgsql\net-2.0\Mono.Security.dll
-
-
- False
- ..\..\lib\MySql.Data.dll
-
-
- False
- ..\..\lib\NAnt.Core.dll
-
-
- False
- ..\..\lib\Npgsql\net-2.0\Npgsql.dll
-
-
- False
- ..\..\lib\Oracle.DataAccess.dll
-
-
-
-
- False
- ..\..\lib\System.Data.SQLite.DLL
-
-
- ..\..\lib\System.Data.SqlServerCe.dll
- False
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {5270F048-E580-486C-B14C-E5B9F6E539D4}
- Migrator.Framework-vs2008
-
-
-
-
-
-
-
- False
- .NET Framework 3.5 SP1 Client Profile
- false
-
-
- False
- .NET Framework 2.0 %28x86%29
- true
-
-
- False
- .NET Framework 3.0 %28x86%29
- false
-
-
- False
- .NET Framework 3.5
- false
-
-
- False
- .NET Framework 3.5 SP1
- false
-
-
-
-
-
-
+
+
+
+ Debug
+ AnyCPU
+ 9.0.30729
+ 2.0
+ {D58C68E4-D789-40F7-9078-C9F587D4363C}
+ Library
+ Migrator.Providers
+ Migrator.Providers
+
+
+ 3.5
+
+
+ false
+ true
+ MigratorDotNet.snk
+ v2.0
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ TRACE;DEBUG;DOTNET2
+ prompt
+ 4
+ AllRules.ruleset
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ AllRules.ruleset
+
+
+
+ False
+ ..\..\lib\Mono.Data.Sqlite.dll
+
+
+ False
+ ..\..\lib\Npgsql\net-2.0\Mono.Security.dll
+
+
+ False
+ ..\..\lib\MySql.Data.dll
+
+
+ False
+ ..\..\lib\NAnt.Core.dll
+
+
+ False
+ ..\..\lib\Npgsql\net-2.0\Npgsql.dll
+
+
+ False
+ ..\..\lib\Oracle.DataAccess.dll
+
+
+
+
+ False
+ ..\..\lib\System.Data.SQLite.DLL
+
+
+ ..\..\lib\System.Data.SqlServerCe.dll
+ False
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {5270F048-E580-486C-B14C-E5B9F6E539D4}
+ Migrator.Framework-vs2008
+
+
+
+
+
+
+
+ False
+ .NET Framework 3.5 SP1 Client Profile
+ false
+
+
+ False
+ .NET Framework 2.0 %28x86%29
+ true
+
+
+ False
+ .NET Framework 3.0 %28x86%29
+ false
+
+
+ False
+ .NET Framework 3.5
+ false
+
+
+ False
+ .NET Framework 3.5 SP1
+ false
+
+
+
+
+
+
+ -->
\ No newline at end of file
diff --git a/src/Migrator.Providers/NoOpTransformationProvider.cs b/src/Migrator.Providers/NoOpTransformationProvider.cs
index 48f66665..1c86999c 100644
--- a/src/Migrator.Providers/NoOpTransformationProvider.cs
+++ b/src/Migrator.Providers/NoOpTransformationProvider.cs
@@ -283,19 +283,19 @@ public ITransformationProvider this[string provider]
get { return this; }
}
- public void MigrationApplied(long version)
+ public void MigrationApplied(long version, string scope = null)
{
//no op
- }
-
- public void MigrationUnApplied(long version)
+ }
+
+ public void MigrationUnApplied(long version, string scope = null)
{
//no op
- }
-
- public List AppliedMigrations
- {
- get { return new List(); }
+ }
+
+ public List> AppliedMigrations
+ {
+ get { return new List>(); }
}
protected void CreateSchemaInfoTable()
diff --git a/src/Migrator.Providers/ProviderGlobalSettings.cs b/src/Migrator.Providers/ProviderGlobalSettings.cs
new file mode 100644
index 00000000..d05515d4
--- /dev/null
+++ b/src/Migrator.Providers/ProviderGlobalSettings.cs
@@ -0,0 +1,18 @@
+namespace Migrator.Providers
+{
+ public class ProviderGlobalSettings
+ {
+ public static string TableSchemaInfo { get; set; }
+ public static string ColumnScope { get; set; }
+ public static string ColumnVersion { get; set; }
+ public static string GlobalScopeId { get; set; }
+
+ static ProviderGlobalSettings()
+ {
+ TableSchemaInfo = "DbSchemaInfo";
+ ColumnScope = "Scope";
+ ColumnVersion = "Version";
+ GlobalScopeId = "00000000000000000000000000000000";
+ }
+ }
+}
diff --git a/src/Migrator.Providers/TransformationProvider.cs b/src/Migrator.Providers/TransformationProvider.cs
index 96478074..9ef33718 100644
--- a/src/Migrator.Providers/TransformationProvider.cs
+++ b/src/Migrator.Providers/TransformationProvider.cs
@@ -29,8 +29,8 @@ public abstract class TransformationProvider : ITransformationProvider
{
private ILogger _logger;
protected IDbConnection _connection;
- private IDbTransaction _transaction;
- private List _appliedMigrations;
+ private IDbTransaction _transaction;
+ private List> _appliedMigrations;
protected readonly string _connectionString;
protected Dialect _dialect;
@@ -738,53 +738,75 @@ public void Commit()
///
/// The list of Migrations currently applied to the database.
- ///
- public List AppliedMigrations
+ ///
+ public List> AppliedMigrations
{
get
{
if(_appliedMigrations == null)
- {
- _appliedMigrations = new List();
- CreateSchemaInfoTable();
- using(IDataReader reader = Select("version","SchemaInfo")){
+ {
+ _appliedMigrations = new List>();
+ CreateSchemaInfoTable();
+ using (IDataReader reader = Select("*", ProviderGlobalSettings.TableSchemaInfo))
+ {
while(reader.Read()){
- _appliedMigrations.Add(Convert.ToInt64(reader.GetValue(0)));
+ _appliedMigrations.Add(new KeyValuePair(Convert.ToString(reader.GetValue(0)), Convert.ToInt64(reader.GetValue(1))));
}
}
}
return _appliedMigrations;
}
- }
-
- ///
- /// Marks a Migration version number as having been applied
- ///
- /// The version number of the migration that was applied
- public void MigrationApplied(long version)
- {
- CreateSchemaInfoTable();
- Insert("SchemaInfo",new string[]{"version"},new string[]{version.ToString()});
- _appliedMigrations.Add(version);
- }
-
- ///
- /// Marks a Migration version number as having been rolled back from the database
- ///
- /// The version number of the migration that was removed
- public void MigrationUnApplied(long version)
- {
- CreateSchemaInfoTable();
- Delete("SchemaInfo", "version", version.ToString());
- _appliedMigrations.Remove(version);
+ }
+
+ ///
+ /// Marks a Migration version number as having been applied
+ ///
+ /// The version number of the migration that was applied
+ /// Scope of migrations
+ public void MigrationApplied(long version, string scope)
+ {
+ CreateSchemaInfoTable();
+ var scopeFixed = FixScope(scope);
+ Insert(ProviderGlobalSettings.TableSchemaInfo, new string[] { ProviderGlobalSettings.ColumnScope, ProviderGlobalSettings.ColumnVersion }, new string[] { scopeFixed, version.ToString() });
+ _appliedMigrations.Add(new KeyValuePair(scopeFixed, version));
+ }
+
+ ///
+ /// Marks a Migration version number as having been rolled back from the database
+ ///
+ /// The version number of the migration that was removed
+ /// Scope of migrations
+ public void MigrationUnApplied(long version, string scope)
+ {
+ CreateSchemaInfoTable();
+ var scopeFixed = FixScope(scope);
+ Delete(ProviderGlobalSettings.TableSchemaInfo, new string[] { ProviderGlobalSettings.ColumnScope, ProviderGlobalSettings.ColumnVersion }, new string[] { scopeFixed, version.ToString() });
+ KeyValuePair? toDelete = null;
+ foreach (var appliedMigration in _appliedMigrations)
+ {
+ if (appliedMigration.Value == version && appliedMigration.Key.CompareTo(scopeFixed) == 0)
+ {
+ toDelete = appliedMigration;
+ break;
+ }
+ }
+ if (toDelete.HasValue)
+ _appliedMigrations.Remove(toDelete.Value);
}
+ private static string FixScope(string scope)
+ {
+ return (String.IsNullOrEmpty(scope) || scope.Length != 32) ? ProviderGlobalSettings.GlobalScopeId : scope;
+ }
+
protected void CreateSchemaInfoTable()
{
- EnsureHasConnection();
- if (!TableExists("SchemaInfo"))
- {
- AddTable("SchemaInfo", new Column("Version", DbType.Int64, ColumnProperty.PrimaryKey));
+ EnsureHasConnection();
+ if (!TableExists(ProviderGlobalSettings.TableSchemaInfo))
+ {
+ AddTable(ProviderGlobalSettings.TableSchemaInfo,
+ new Column(ProviderGlobalSettings.ColumnScope, DbType.StringFixedLength, 32, ColumnProperty.Indexed),
+ new Column(ProviderGlobalSettings.ColumnVersion, DbType.Int64, ColumnProperty.Indexed));
}
}
diff --git a/src/Migrator/BaseMigrate.cs b/src/Migrator/BaseMigrate.cs
index 5d1847c4..a82e6784 100644
--- a/src/Migrator/BaseMigrate.cs
+++ b/src/Migrator/BaseMigrate.cs
@@ -9,20 +9,28 @@ public abstract class BaseMigrate
protected ILogger _logger;
protected List _availableMigrations;
protected List _original;
+ protected string _scope;
protected long _current;
protected bool _dryrun;
- protected BaseMigrate(List availableMigrations, ITransformationProvider provider, ILogger logger)
+ protected BaseMigrate(string scope, List availableMigrations, ITransformationProvider provider, ILogger logger)
{
_provider = provider;
- _availableMigrations = availableMigrations;
- _original = new List (_provider.AppliedMigrations.ToArray()); //clone
+ _availableMigrations = availableMigrations;
+ _scope = scope;
+ _original = new List(); //clone
+ foreach (var appliedMigration in _provider.AppliedMigrations)
+ {
+ if (scope == appliedMigration.Key)
+ _original.Add(appliedMigration.Value);
+ }
+ _original.Sort();
_logger = logger;
}
- public static BaseMigrate GetInstance(List availableMigrations, ITransformationProvider provider, ILogger logger)
+ public static BaseMigrate GetInstance(string scope, List availableMigrations, ITransformationProvider provider, ILogger logger)
{
- return new MigrateAnywhere(availableMigrations, provider, logger);
+ return new MigrateAnywhere(scope, availableMigrations, provider, logger);
}
public List AppliedVersions
@@ -65,8 +73,8 @@ protected long NextMigration()
int migrationSearch = _availableMigrations.IndexOf(Current)+1;
// See if we can find a migration that matches the requirement
- while(migrationSearch < _availableMigrations.Count
- && _provider.AppliedMigrations.Contains(_availableMigrations[migrationSearch]))
+ while(migrationSearch < _availableMigrations.Count
+ && AppliedMigrationsContains(_availableMigrations[migrationSearch]))
{
migrationSearch++;
}
@@ -91,8 +99,8 @@ protected long PreviousMigration()
int migrationSearch = _availableMigrations.IndexOf(Current)-1;
// See if we can find a migration that matches the requirement
- while(migrationSearch > -1
- && !_provider.AppliedMigrations.Contains(_availableMigrations[migrationSearch]))
+ while(migrationSearch > -1
+ && !AppliedMigrationsContains(_availableMigrations[migrationSearch]))
{
migrationSearch--;
}
@@ -106,5 +114,15 @@ protected long PreviousMigration()
// found one.
return _availableMigrations[migrationSearch];
}
+
+ private bool AppliedMigrationsContains(long version)
+ {
+ foreach (var appliedMigration in _provider.AppliedMigrations)
+ {
+ if (appliedMigration.Key == _scope && appliedMigration.Value == version)
+ return true;
+ }
+ return false;
+ }
}
}
diff --git a/src/Migrator/MigrateAnywhere.cs b/src/Migrator/MigrateAnywhere.cs
index eb1bde01..41d257cf 100644
--- a/src/Migrator/MigrateAnywhere.cs
+++ b/src/Migrator/MigrateAnywhere.cs
@@ -11,12 +11,18 @@ public class MigrateAnywhere : BaseMigrate
{
private bool _goForward;
- public MigrateAnywhere(List availableMigrations, ITransformationProvider provider, ILogger logger)
- : base(availableMigrations, provider, logger)
+ public MigrateAnywhere(string scope, List availableMigrations, ITransformationProvider provider, ILogger logger)
+ : base(scope, availableMigrations, provider, logger)
{
_current = 0;
- if (provider.AppliedMigrations.Count > 0) {
- _current = provider.AppliedMigrations[provider.AppliedMigrations.Count - 1];
+ if (provider.AppliedMigrations.Count > 0) {
+ foreach (var appliedMigration in provider.AppliedMigrations)
+ {
+ if (appliedMigration.Key != scope)
+ continue;
+ if (_current < appliedMigration.Value)
+ _current = appliedMigration.Value;
+ }
}
_goForward = false;
}
@@ -61,9 +67,20 @@ public override bool Continue(long version)
public override void Migrate(IMigration migration)
{
_provider.BeginTransaction();
- MigrationAttribute attr = (MigrationAttribute)Attribute.GetCustomAttribute(migration.GetType(), typeof(MigrationAttribute));
-
- if (_provider.AppliedMigrations.Contains(attr.Version)) {
+ MigrationAttribute attr = (MigrationAttribute)Attribute.GetCustomAttribute(migration.GetType(), typeof(MigrationAttribute));
+
+ var v = attr.GetVersion(migration.GetType());
+ var contains = false;
+
+ foreach (var appliedMigration in _provider.AppliedMigrations)
+ {
+ if (appliedMigration.Key != v.Key || appliedMigration.Value != v.Value) continue;
+ contains = true;
+ break;
+ }
+
+ if (contains)
+ {
RemoveMigration(migration, attr);
} else {
ApplyMigration(migration, attr);
@@ -76,8 +93,9 @@ private void ApplyMigration(IMigration migration, MigrationAttribute attr)
_logger.MigrateUp(Current, migration.Name);
if(! DryRun)
{
- migration.Up();
- _provider.MigrationApplied(attr.Version);
+ migration.Up();
+ var v = attr.GetVersion(migration.GetType());
+ _provider.MigrationApplied(v.Value, v.Key);
_provider.Commit();
migration.AfterUp();
}
@@ -89,8 +107,9 @@ private void RemoveMigration(IMigration migration, MigrationAttribute attr)
_logger.MigrateDown(Current, migration.Name);
if (! DryRun)
{
- migration.Down();
- _provider.MigrationUnApplied(attr.Version);
+ migration.Down();
+ var v = attr.GetVersion(migration.GetType());
+ _provider.MigrationUnApplied(v.Value, v.Key);
_provider.Commit();
migration.AfterDown();
}
diff --git a/src/Migrator/MigrationComparer.cs b/src/Migrator/MigrationComparer.cs
index a1f7281f..f85d26fc 100644
--- a/src/Migrator/MigrationComparer.cs
+++ b/src/Migrator/MigrationComparer.cs
@@ -30,14 +30,29 @@ public MigrationTypeComparer(bool ascending)
public int Compare(Type x, Type y)
{
MigrationAttribute attribOfX = (MigrationAttribute) Attribute.GetCustomAttribute(x, typeof(MigrationAttribute));
- MigrationAttribute attribOfY = (MigrationAttribute) Attribute.GetCustomAttribute(y, typeof(MigrationAttribute));
-
- if (_ascending)
- return attribOfX.Version.CompareTo(attribOfY.Version);
- else
- return attribOfY.Version.CompareTo(attribOfX.Version);
-
-
+ MigrationAttribute attribOfY = (MigrationAttribute) Attribute.GetCustomAttribute(y, typeof(MigrationAttribute));
+
+ var vX = attribOfX.GetVersion(x);
+ var vY = attribOfY.GetVersion(y);
+
+ var c = vX.Key.CompareTo(vY.Key);
+
+ if (_ascending)
+ {
+ if (c != 0)
+ return c;
+ }
+ else
+ {
+ if (c != 0)
+ return -c;
+ }
+
+ return _ascending
+ ? attribOfX.Version.CompareTo(attribOfY.Version)
+ : attribOfY.Version.CompareTo(attribOfX.Version);
+
+
}
}
}
diff --git a/src/Migrator/MigrationLoader.cs b/src/Migrator/MigrationLoader.cs
index 397ed43c..8d3f9e63 100644
--- a/src/Migrator/MigrationLoader.cs
+++ b/src/Migrator/MigrationLoader.cs
@@ -46,13 +46,20 @@ public List MigrationsTypes
///
/// Returns the last version of the migrations.
///
- public long LastVersion
+ public IEnumerable> LastVersions
{
- get
- {
+ get
+ {
+ var list = new Dictionary();
if (_migrationsTypes.Count == 0)
- return 0;
- return GetMigrationVersion(_migrationsTypes[_migrationsTypes.Count - 1]);
+ return list;
+ foreach (var type in _migrationsTypes)
+ {
+ var v = GetMigrationVersion(type);
+ if (!list.ContainsKey(v.Key) || list[v.Key] < v.Value)
+ list[v.Key] = v.Value;
+ }
+ return list;
}
}
@@ -61,14 +68,14 @@ public long LastVersion
///
/// CheckForDuplicatedVersion
public void CheckForDuplicatedVersion()
- {
- List versions = new List();
+ {
+ var versions = new List>();
foreach (Type t in _migrationsTypes)
{
- long version = GetMigrationVersion(t);
+ var version = GetMigrationVersion(t);
if (versions.Contains(version))
- throw new DuplicatedVersionException(version);
+ throw new DuplicatedVersionException(version.Value);
versions.Add(version);
}
@@ -102,27 +109,39 @@ public static List GetMigrationTypes(Assembly asm)
/// MigrationAttribute.
///
/// Migration type.
- /// Version number sepcified in the attribute
- public static long GetMigrationVersion(Type t)
- {
- MigrationAttribute attrib = (MigrationAttribute)
- Attribute.GetCustomAttribute(t, typeof(MigrationAttribute));
-
- return attrib.Version;
- }
-
- public List GetAvailableMigrations()
+ /// Version number sepcified in the attribute
+ public static KeyValuePair GetMigrationVersion(Type t)
+ {
+ var attrib = (MigrationAttribute)
+ Attribute.GetCustomAttribute(t, typeof (MigrationAttribute));
+ return attrib.GetVersion(t);
+ }
+
+ public List> GetAvailableMigrations()
{
//List availableMigrations = new List();
- _migrationsTypes.Sort(new MigrationTypeComparer(true));
- return _migrationsTypes.ConvertAll(new Converter(GetMigrationVersion));
- }
-
- public IMigration GetMigration(long version)
+ _migrationsTypes.Sort(new MigrationTypeComparer(true));
+ return _migrationsTypes.ConvertAll(GetMigrationVersion);
+ }
+
+ public List GetAvailableMigrations(string scope)
+ {
+ var all = GetAvailableMigrations();
+ var list = new List();
+ foreach (var keyValuePair in all)
+ {
+ if (keyValuePair.Key == scope)
+ list.Add(keyValuePair.Value);
+ }
+ return list;
+ }
+
+ public IMigration GetMigration(string scope, long version)
{
- foreach (Type t in _migrationsTypes)
- {
- if (GetMigrationVersion(t) == version)
+ foreach (Type t in _migrationsTypes)
+ {
+ var v = GetMigrationVersion(t);
+ if (v.Key == scope && v.Value == version)
{
IMigration migration = (IMigration)Activator.CreateInstance(t);
migration.Database = _provider;
diff --git a/src/Migrator/Migrator.cs b/src/Migrator/Migrator.cs
index c41c204e..1d86d649 100644
--- a/src/Migrator/Migrator.cs
+++ b/src/Migrator/Migrator.cs
@@ -79,16 +79,39 @@ public List MigrationsTypes
///
/// Run all migrations up to the latest. Make no changes to database if
/// dryrun is true.
- ///
- public void MigrateToLastVersion()
- {
- MigrateTo(_migrationLoader.LastVersion);
+ ///
+ public void MigrateToLastVersion(string scope)
+ {
+ foreach (var version in _migrationLoader.LastVersions)
+ {
+ if (version.Key != scope)
+ continue;
+ MigrateTo(version.Key, version.Value);
+ break;
+ }
+ }
+
+ public IEnumerable Scopes
+ {
+ get
+ {
+ foreach (var version in _migrationLoader.LastVersions)
+ yield return version.Key;
+ }
+ }
+
+ public void MigrateAllScopesToLastVersion()
+ {
+ foreach (var version in _migrationLoader.LastVersions)
+ {
+ MigrateTo(version.Key, version.Value);
+ }
}
///
/// Returns the current migrations applied to the database.
///
- public List AppliedMigrations
+ public List> AppliedMigrations
{
get { return _provider.AppliedMigrations; }
}
@@ -110,20 +133,21 @@ public virtual bool DryRun
{
get { return _dryrun; }
set { _dryrun = value; }
- }
-
- ///
- /// Migrate the database to a specific version.
- /// Runs all migration between the actual version and the
- /// specified version.
- /// If version is greater then the current version,
- /// the Up() method will be invoked.
- /// If version lower then the current version,
- /// the Down() method of previous migration will be invoked.
- /// If dryrun is set, don't write any changes to the database.
- ///
- /// The version that must became the current one
- public void MigrateTo(long version)
+ }
+
+ ///
+ /// Migrate the database to a specific version.
+ /// Runs all migration between the actual version and the
+ /// specified version.
+ /// If version is greater then the current version,
+ /// the Up() method will be invoked.
+ /// If version lower then the current version,
+ /// the Down() method of previous migration will be invoked.
+ /// If dryrun is set, don't write any changes to the database.
+ ///
+ /// Scope of versions
+ /// The version that must became the current one
+ public void MigrateTo(string scope, long version)
{
if (_migrationLoader.MigrationsTypes.Count == 0)
@@ -133,13 +157,13 @@ public void MigrateTo(long version)
}
bool firstRun = true;
- BaseMigrate migrate = BaseMigrate.GetInstance(_migrationLoader.GetAvailableMigrations(), _provider, _logger);
+ BaseMigrate migrate = BaseMigrate.GetInstance(scope, _migrationLoader.GetAvailableMigrations(scope), _provider, _logger);
migrate.DryRun = DryRun;
Logger.Started(migrate.AppliedVersions, version);
while (migrate.Continue(version))
- {
- IMigration migration = _migrationLoader.GetMigration(migrate.Current);
+ {
+ IMigration migration = _migrationLoader.GetMigration(scope, migrate.Current);
if (null == migration)
{
_logger.Skipping(migrate.Current);