diff --git a/src/Orchard.Web/Modules/Orchard.ImportExport/Services/SetupService.cs b/src/Orchard.Web/Modules/Orchard.ImportExport/Services/SetupService.cs index c125a21c9..ffb149108 100644 --- a/src/Orchard.Web/Modules/Orchard.ImportExport/Services/SetupService.cs +++ b/src/Orchard.Web/Modules/Orchard.ImportExport/Services/SetupService.cs @@ -20,6 +20,7 @@ using Orchard.Logging; using Orchard.Recipes.Services; using Orchard.Security; using Orchard.Settings; +using Orchard.Tasks.Locking.Services; using Orchard.Utility.Extensions; namespace Orchard.ImportExport.Services @@ -101,6 +102,10 @@ namespace Orchard.ImportExport.Services schemaBuilder.AlterTable("Orchard_Framework_DataMigrationRecord", table => table.AddUniqueConstraint("UC_DMR_DataMigrationClass_Version", "DataMigrationClass", "Version")); + // Create the distributed lock record schema. + var distributedLockSchemaBuilder = new DistributedLockSchemaBuilder(_shellSettings, schemaBuilder); + distributedLockSchemaBuilder.CreateSchema(); + var dataMigrationManager = environment.Resolve(); dataMigrationManager.Update("Settings"); diff --git a/src/Orchard.Web/Modules/Orchard.Setup/Services/SetupService.cs b/src/Orchard.Web/Modules/Orchard.Setup/Services/SetupService.cs index 16b3e465b..dfff5b008 100644 --- a/src/Orchard.Web/Modules/Orchard.Setup/Services/SetupService.cs +++ b/src/Orchard.Web/Modules/Orchard.Setup/Services/SetupService.cs @@ -23,6 +23,7 @@ using Orchard.Recipes.Models; using Orchard.Recipes.Services; using Orchard.Security; using Orchard.Settings; +using Orchard.Tasks.Locking.Services; using Orchard.Utility.Extensions; namespace Orchard.Setup.Services { @@ -154,6 +155,10 @@ namespace Orchard.Setup.Services { schemaBuilder.AlterTable("Orchard_Framework_DataMigrationRecord", table => table.AddUniqueConstraint("UC_DMR_DataMigrationClass_Version", "DataMigrationClass", "Version")); + // Create the distributed lock record schema. + var distributedLockSchemaBuilder = new DistributedLockSchemaBuilder(_shellSettings, schemaBuilder); + distributedLockSchemaBuilder.CreateSchema(); + var dataMigrationManager = environment.Resolve(); dataMigrationManager.Update("Settings"); diff --git a/src/Orchard/Data/Migration/AutomaticDataMigrations.cs b/src/Orchard/Data/Migration/AutomaticDataMigrations.cs index 7c0693540..887e0a941 100644 --- a/src/Orchard/Data/Migration/AutomaticDataMigrations.cs +++ b/src/Orchard/Data/Migration/AutomaticDataMigrations.cs @@ -1,6 +1,9 @@ using System; using System.Linq; +using Orchard.Data.Migration.Interpreters; +using Orchard.Data.Migration.Schema; using Orchard.Environment; +using Orchard.Environment.Configuration; using Orchard.Environment.Features; using Orchard.Logging; using Orchard.Tasks.Locking.Services; @@ -13,15 +16,21 @@ namespace Orchard.Data.Migration { private readonly IDataMigrationManager _dataMigrationManager; private readonly IFeatureManager _featureManager; private readonly IDistributedLockService _distributedLockService; + private readonly IDataMigrationInterpreter _dataMigrationInterpreter; + private readonly ShellSettings _shellSettings; public AutomaticDataMigrations( IDataMigrationManager dataMigrationManager, + IDataMigrationInterpreter dataMigrationInterpreter, IFeatureManager featureManager, - IDistributedLockService distributedLockService) { + IDistributedLockService distributedLockService, + ShellSettings shellSettings) { _dataMigrationManager = dataMigrationManager; _featureManager = featureManager; _distributedLockService = distributedLockService; + _shellSettings = shellSettings; + _dataMigrationInterpreter = dataMigrationInterpreter; Logger = NullLogger.Instance; } @@ -30,6 +39,7 @@ namespace Orchard.Data.Migration { public void Activated() { IDistributedLock @lock; + EnsureDistributedLockSchema(); if(_distributedLockService.TryAcquireLock(GetType().FullName, TimeSpan.FromMinutes(30), TimeSpan.FromMilliseconds(250), out @lock)) { using (@lock) { // Let's make sure that the basic set of features is enabled. If there are any that are not enabled, then let's enable them first. @@ -58,5 +68,15 @@ namespace Orchard.Data.Migration { public void Terminating() { // No-op. } + + /// + /// This ensures that the framework migrations have run for the distributed locking feature, as existing Orchard installations will not have the required tables when upgrading. + /// + private void EnsureDistributedLockSchema() { + // Ensure the distributed lock record schema exists. + var schemaBuilder = new SchemaBuilder(_dataMigrationInterpreter); + var distributedLockSchemaBuilder = new DistributedLockSchemaBuilder(_shellSettings, schemaBuilder); + distributedLockSchemaBuilder.EnsureSchema(); + } } } diff --git a/src/Orchard/Orchard.Framework.csproj b/src/Orchard/Orchard.Framework.csproj index 6e2f60292..11adc4cf9 100644 --- a/src/Orchard/Orchard.Framework.csproj +++ b/src/Orchard/Orchard.Framework.csproj @@ -399,7 +399,7 @@ - + diff --git a/src/Orchard/Tasks/Locking/Migrations/FrameworkMigrations.cs b/src/Orchard/Tasks/Locking/Migrations/FrameworkMigrations.cs deleted file mode 100644 index 2a43a2e19..000000000 --- a/src/Orchard/Tasks/Locking/Migrations/FrameworkMigrations.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using Orchard.Data.Migration; - -namespace Orchard.Tasks.Locking.Migrations { - public class FrameworkMigrations : DataMigrationImpl { - - public int Create() { - SchemaBuilder.CreateTable("DistributedLockRecord", table => table - .Column("Id", column => column.PrimaryKey().Identity()) - .Column("Name", column => column.NotNull().WithLength(512).Unique()) - .Column("MachineName", column => column.WithLength(256)) - .Column("CreatedUtc") - .Column("ValidUntilUtc", column => column.Nullable())); - - SchemaBuilder.AlterTable("DistributedLockRecord", table => { - table.CreateIndex("IDX_DistributedLockRecord_Name", "Name"); - }); - - return 1; - } - } -} \ No newline at end of file diff --git a/src/Orchard/Tasks/Locking/Services/DistributedLockSchemaBuilder.cs b/src/Orchard/Tasks/Locking/Services/DistributedLockSchemaBuilder.cs new file mode 100644 index 000000000..8a577d8a1 --- /dev/null +++ b/src/Orchard/Tasks/Locking/Services/DistributedLockSchemaBuilder.cs @@ -0,0 +1,47 @@ +using System; +using Orchard.Data.Migration.Schema; +using Orchard.Environment.Configuration; + +namespace Orchard.Tasks.Locking.Services { + public class DistributedLockSchemaBuilder { + private readonly ShellSettings _shellSettings; + private readonly SchemaBuilder _schemaBuilder; + private const string TableName = "Orchard_Framework_DistributedLockRecord"; + + public DistributedLockSchemaBuilder(ShellSettings shellSettings, SchemaBuilder schemaBuilder) { + _shellSettings = shellSettings; + _schemaBuilder = schemaBuilder; + } + + public void EnsureSchema() { + if (SchemaExists()) + return; + + CreateSchema(); + } + + public void CreateSchema() { + _schemaBuilder.CreateTable(TableName, table => table + .Column("Id", column => column.PrimaryKey().Identity()) + .Column("Name", column => column.NotNull().WithLength(512).Unique()) + .Column("MachineName", column => column.WithLength(256)) + .Column("CreatedUtc") + .Column("ValidUntilUtc", column => column.Nullable())); + + _schemaBuilder.AlterTable(TableName, table => { + table.CreateIndex("IDX_DistributedLockRecord_Name", "Name"); + }); + } + + public bool SchemaExists() { + try { + var tablePrefix = String.IsNullOrEmpty(_shellSettings.DataTablePrefix) ? "" : _shellSettings.DataTablePrefix + "_"; + _schemaBuilder.ExecuteSql(String.Format("select * from {0}{1}", tablePrefix, TableName)); + return true; + } + catch { + return false; + } + } + } +} \ No newline at end of file