Implementing the MigrationRunner, which will be used for database upgrades.

Refactoring a few bits in the syntax of the migration models.
Adding an extension of the PluginManager to find migrations by Type and Attribute.
This commit is contained in:
Morten Christensen
2012-11-30 18:48:20 -01:00
parent d05a8e0390
commit 213451e442
11 changed files with 123 additions and 16 deletions

View File

@@ -9,6 +9,7 @@ using System.Xml.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Migrations;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core
@@ -296,7 +297,7 @@ namespace Umbraco.Core
_configured = true;
}
internal Result CreateDatabaseSchemaAndData()
internal Result CreateDatabaseSchemaAndDataOrUpgrade()
{
if (_configured == false || (string.IsNullOrEmpty(_connectionString) || string.IsNullOrEmpty(ProviderName)))
{
@@ -306,7 +307,19 @@ namespace Umbraco.Core
try
{
var database = new Database(_connectionString, ProviderName);
database.CreateDatabaseSchema();
//If Configuration Status is empty its a new install - otherwise upgrade the existing
if (string.IsNullOrEmpty(GlobalSettings.ConfigurationStatus))
{
database.CreateDatabaseSchema();
}
else
{
var configuredVersion = new Version(GlobalSettings.ConfigurationStatus);
var targetVersion = UmbracoVersion.Current;
var runner = new MigrationRunner(configuredVersion, targetVersion);
var upgraded = runner.Execute(database, true);
}
return new Result { Message = "Installation completed!", Success = true, Percentage = "100" };
}
catch (Exception ex)

View File

@@ -0,0 +1,71 @@
using System;
using System.Linq;
using Umbraco.Core.Logging;
namespace Umbraco.Core.Persistence.Migrations
{
/// <summary>
/// Represents the Migration Runner, which is used to apply migrations to
/// the umbraco database.
/// </summary>
public class MigrationRunner
{
private readonly Version _configuredVersion;
private readonly Version _targetVersion;
public MigrationRunner(Version configuredVersion, Version targetVersion)
{
_configuredVersion = configuredVersion;
_targetVersion = targetVersion;
}
/// <summary>
/// Executes the migrations against the database.
/// </summary>
/// <param name="database">The PetaPoco Database, which the migrations will be run against</param>
/// <param name="isUpgrade">Boolean indicating whether this is an upgrade or downgrade</param>
/// <returns>True if migrations were applied, otherwise False</returns>
public bool Execute(Database database, bool isUpgrade)
{
LogHelper.Info<MigrationRunner>("Initializing database migration");
var foundMigrations = PluginManager.Current.FindMigrations();
var migrations = (from migration in foundMigrations
let migrationAttribute = migration.GetType().FirstAttribute<MigrationAttribute>()
where migrationAttribute != null
where
migrationAttribute.TargetVersion > _configuredVersion &&
migrationAttribute.TargetVersion <= _targetVersion
select migration);
//Loop through migrations to generate sql
var context = new MigrationContext();
foreach (MigrationBase migration in migrations)
{
if (isUpgrade)
{
migration.GetUpExpressions(context);
}
else
{
migration.GetDownExpressions(context);
}
}
//Transactional execution of the sql that was generated from the found migrationsS
using (Transaction transaction = database.GetTransaction())
{
foreach (var expression in context.Expressions)
{
var sql = expression.ToString();
LogHelper.Info<MigrationRunner>("Executing sql: " + sql);
database.Execute(sql);
}
transaction.Complete();
}
return true;
}
}
}

View File

@@ -18,12 +18,6 @@ namespace Umbraco.Core.Persistence.Migrations.Model
public virtual bool IsNullable { get; set; }
public virtual bool IsUnique { get; set; }
public virtual string TableName { get; set; }
public virtual ColumnModificationType ModificationType { get; set; }
}
public enum ColumnModificationType
{
Create,
Alter
public virtual ModificationType ModificationType { get; set; }
}
}

View File

@@ -0,0 +1,13 @@
namespace Umbraco.Core.Persistence.Migrations.Model
{
public enum ModificationType
{
Create,
Alter,
Drop,
Rename,
Insert,
Update,
Delete
}
}

View File

@@ -0,0 +1,13 @@
using System.Collections.Generic;
namespace Umbraco.Core.Persistence.Migrations
{
internal static class PluginManagerExtension
{
public static IEnumerable<IMigration> FindMigrations(this PluginManager resolver)
{
var types = resolver.ResolveTypesWithAttribute<IMigration, MigrationAttribute>();
return resolver.CreateInstances<IMigration>(types);
}
}
}

View File

@@ -6,7 +6,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Expressions
{
public AlterColumnExpression()
{
Column = new ColumnDefinition() { ModificationType = ColumnModificationType.Alter };
Column = new ColumnDefinition() { ModificationType = ModificationType.Alter };
}
public virtual string SchemaName { get; set; }

View File

@@ -28,7 +28,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Table
public IAlterTableColumnOptionSyntax WithDefaultValue(object value)
{
if (CurrentColumn.ModificationType == ColumnModificationType.Alter)
if (CurrentColumn.ModificationType == ModificationType.Alter)
{
var dc = new AlterDefaultConstraintExpression
{
@@ -213,7 +213,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Table
public IAlterTableColumnSyntax AddColumn(string name)
{
var column = new ColumnDefinition { Name = name, ModificationType = ColumnModificationType.Create };
var column = new ColumnDefinition { Name = name, ModificationType = ModificationType.Create };
var createColumn = new CreateColumnExpression
{
Column = column,
@@ -229,7 +229,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Table
public IAlterTableColumnSyntax AlterColumn(string name)
{
var column = new ColumnDefinition { Name = name, ModificationType = ColumnModificationType.Alter };
var column = new ColumnDefinition { Name = name, ModificationType = ModificationType.Alter };
var alterColumn = new AlterColumnExpression
{
Column = column,

View File

@@ -8,7 +8,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Expressions
{
public CreateColumnExpression()
{
Column = new ColumnDefinition { ModificationType = ColumnModificationType.Create };
Column = new ColumnDefinition { ModificationType = ModificationType.Create };
}
public virtual string SchemaName { get; set; }

View File

@@ -371,7 +371,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
protected virtual string FormatNullable(Migrations.Model.ColumnDefinition column)
{
return !column.IsNullable ? "NOT NULL" : string.Empty;
return column.IsNullable ? string.Empty : "NOT NULL";
}
protected virtual string FormatDefaultValue(Migrations.Model.ColumnDefinition column)

View File

@@ -196,12 +196,15 @@
<Compile Include="Persistence\Migrations\MigrationAttribute.cs" />
<Compile Include="Persistence\Migrations\MigrationBase.cs" />
<Compile Include="Persistence\Migrations\MigrationContext.cs" />
<Compile Include="Persistence\Migrations\MigrationRunner.cs" />
<Compile Include="Persistence\Migrations\Model\ColumnDefinition.cs" />
<Compile Include="Persistence\Migrations\Model\ModificationType.cs" />
<Compile Include="Persistence\Migrations\Model\ForeignKeyDefinition.cs" />
<Compile Include="Persistence\Migrations\Model\IndexColumnDefinition.cs" />
<Compile Include="Persistence\Migrations\Model\IndexDefinition.cs" />
<Compile Include="Persistence\Migrations\Model\SystemMethods.cs" />
<Compile Include="Persistence\Migrations\Model\TableDefinition.cs" />
<Compile Include="Persistence\Migrations\PluginManagerExtension.cs" />
<Compile Include="Persistence\Migrations\Syntax\Alter\AlterSyntaxBuilder.cs" />
<Compile Include="Persistence\Migrations\Syntax\Alter\Column\AlterColumnSyntaxBuilder.cs" />
<Compile Include="Persistence\Migrations\Syntax\Alter\Column\IAlterColumnOptionForeignKeyCascadeSyntax.cs" />

View File

@@ -58,7 +58,7 @@ namespace umbraco.presentation.install.utills
{
LogHelper.Info<p>("Running 'installOrUpgrade' service");
var result = DatabaseContext.Current.CreateDatabaseSchemaAndData();
var result = DatabaseContext.Current.CreateDatabaseSchemaAndDataOrUpgrade();
var js = new JavaScriptSerializer();
var jsonResult = js.Serialize(result);