diff --git a/src/Orchard.Tests/Data/Migrations/DatabaseMigrationManagerTests.cs b/src/Orchard.Tests/Data/Migrations/DatabaseMigrationManagerTests.cs index 25c7039dd..760012851 100644 --- a/src/Orchard.Tests/Data/Migrations/DatabaseMigrationManagerTests.cs +++ b/src/Orchard.Tests/Data/Migrations/DatabaseMigrationManagerTests.cs @@ -64,22 +64,6 @@ namespace Orchard.Tests.Data.Migrations { } - [Test] - public void CanConnectShouldBeFalseWhenSqlServerIsInvalid() { - var manager = (IDatabaseMigrationManager)new DatabaseMigrationManager(); - var coordinator = manager.CreateCoordinator("SqlServer", _tempDataFolder, "Data Source=.\\SQLEXPRESS;Initial Catalog=Hello"); - Assert.That(coordinator.CanConnect(), Is.False); - } - - [Test] - public void CanConnectShouldBeTrueWhenValidSqlServerMdfIsTargetted() { - var databasePath = Path.Combine(_tempDataFolder, "Orchard.mdf"); - CreateSqlServerDatabase(databasePath); - - var manager = (IDatabaseMigrationManager)new DatabaseMigrationManager(); - var coordinator = manager.CreateCoordinator("SqlServer", _tempDataFolder, "Data Source=.\\SQLEXPRESS;AttachDbFileName=" + databasePath + ";Integrated Security=True;User Instance=True;"); - Assert.That(coordinator.CanConnect(), Is.True); - } [Test] public void SQLiteSchemaShouldBeGeneratedAndUsable() { diff --git a/src/Orchard/Data/Migrations/DatabaseCoordinatorBase.cs b/src/Orchard/Data/Migrations/AbstractSessionFactoryBuilder.cs similarity index 52% rename from src/Orchard/Data/Migrations/DatabaseCoordinatorBase.cs rename to src/Orchard/Data/Migrations/AbstractSessionFactoryBuilder.cs index 426545c9c..b8ccae2e4 100644 --- a/src/Orchard/Data/Migrations/DatabaseCoordinatorBase.cs +++ b/src/Orchard/Data/Migrations/AbstractSessionFactoryBuilder.cs @@ -7,58 +7,34 @@ using FluentNHibernate.Cfg; using FluentNHibernate.Cfg.Db; using FluentNHibernate.Conventions.Helpers; using NHibernate; +using NHibernate.Cfg; using NHibernate.Tool.hbm2ddl; using Orchard.ContentManagement.Records; using Orchard.Data.Conventions; using Orchard.Environment; namespace Orchard.Data.Migrations { - public abstract class DatabaseCoordinatorBase : IDatabaseCoordinator { + public abstract class AbstractSessionFactoryBuilder : ISessionFactoryBuilder { protected abstract IPersistenceConfigurer GetPersistenceConfigurer(); - public virtual bool CanConnect() { - try { - var sessionFactory = Fluently.Configure() - .Database(GetPersistenceConfigurer()) - .BuildSessionFactory(); - try { - // attempting to open a session validates a connection can be made - var session = sessionFactory.OpenSession(); - session.Close(); - } - finally { - sessionFactory.Close(); - } - return true; - } - catch { - return false; - } - } + public ISessionFactory BuildSessionFactory(SessionFactoryBuilderParameters parameters) { + var database = GetPersistenceConfigurer(); + var persistenceModel = CreatePersistenceModel(parameters.RecordDescriptors); - public virtual void CreateDatabase() { - // creating a session factory appears to be sufficient for causing a database file to be created for inplace providers var sessionFactory = Fluently.Configure() - .Database(GetPersistenceConfigurer()) + .Database(database) + .Mappings(m => m.AutoMappings.Add(persistenceModel)) + .ExposeConfiguration(config => Initialization(parameters, config)) .BuildSessionFactory(); - sessionFactory.Close(); + + return sessionFactory; } - public void UpdateSchema(IEnumerable recordDescriptors) { - var configuration = Fluently.Configure() - .Database(GetPersistenceConfigurer()) - .Mappings(m => m.AutoMappings.Add(CreatePersistenceModel(recordDescriptors))) - .BuildConfiguration(); - - var updater = new SchemaUpdate(configuration); - updater.Execute(true /*script*/, true /*doUpdate*/); - } - - public ISessionFactory BuildSessionFactory(IEnumerable recordDescriptors) { - return Fluently.Configure() - .Database(GetPersistenceConfigurer()) - .Mappings(m => m.AutoMappings.Add(CreatePersistenceModel(recordDescriptors))) - .BuildSessionFactory(); + private static void Initialization(SessionFactoryBuilderParameters parameters, Configuration configuration) { + if (parameters.UpdateSchema) { + var update = new SchemaUpdate(configuration); + update.Execute(false/*script*/, true /*doUpdate*/); + } } public static AutoPersistenceModel CreatePersistenceModel(IEnumerable recordDescriptors) { @@ -84,5 +60,6 @@ namespace Orchard.Data.Migrations { public IEnumerable GetTypes() { return _recordDescriptors.Select(descriptor => descriptor.Type); } } + } } \ No newline at end of file diff --git a/src/Orchard/Data/Migrations/DatabaseManager.cs b/src/Orchard/Data/Migrations/DatabaseManager.cs new file mode 100644 index 000000000..054a7a5a2 --- /dev/null +++ b/src/Orchard/Data/Migrations/DatabaseManager.cs @@ -0,0 +1,11 @@ +using System; + +namespace Orchard.Data.Migrations { + public class DatabaseManager : IDatabaseManager { + public ISessionFactoryBuilder CreateCoordinator(string provider, string dataFolder, string connectionString) { + if (string.Equals(provider, "SQLite", StringComparison.InvariantCultureIgnoreCase)) + return new SQLiteSessionFactoryBuilder(dataFolder, connectionString); + return new SqlServerSessionFactoryBuilder(dataFolder, connectionString); + } + } +} diff --git a/src/Orchard/Data/Migrations/DatabaseMigrationManager.cs b/src/Orchard/Data/Migrations/DatabaseMigrationManager.cs deleted file mode 100644 index bde875b95..000000000 --- a/src/Orchard/Data/Migrations/DatabaseMigrationManager.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace Orchard.Data.Migrations { - public class DatabaseMigrationManager : IDatabaseMigrationManager { - public IDatabaseCoordinator CreateCoordinator(string provider, string dataFolder, string connectionString) { - if (string.Equals(provider, "SQLite", StringComparison.InvariantCultureIgnoreCase)) - return new SQLiteDatabaseCoordinator(dataFolder, connectionString); - return new SqlServerDatabaseCoordinator(dataFolder, connectionString); - } - } -} diff --git a/src/Orchard/Data/Migrations/IDatabaseCoordinator.cs b/src/Orchard/Data/Migrations/IDatabaseCoordinator.cs deleted file mode 100644 index 38239f75f..000000000 --- a/src/Orchard/Data/Migrations/IDatabaseCoordinator.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Collections.Generic; -using NHibernate; -using Orchard.Environment; - -namespace Orchard.Data.Migrations { - public interface IDatabaseCoordinator { - bool CanConnect(); - void CreateDatabase(); - - /// - /// Should only be called in a development or evaluation environment. Automatic schema migration - /// not a really safe practice on production data sources. - /// - /// Set of known records to be applied - void UpdateSchema(IEnumerable recordDescriptors); - - ISessionFactory BuildSessionFactory(IEnumerable recordDescriptors); - } -} diff --git a/src/Orchard/Data/Migrations/IDatabaseManager.cs b/src/Orchard/Data/Migrations/IDatabaseManager.cs new file mode 100644 index 000000000..868832267 --- /dev/null +++ b/src/Orchard/Data/Migrations/IDatabaseManager.cs @@ -0,0 +1,12 @@ +namespace Orchard.Data.Migrations { + + public interface IDatabaseManager : IDependency { + ISessionFactoryBuilder CreateCoordinator(DatabaseParameters databaseParameters); + } + + public class DatabaseParameters { + public string Provider { get; set; } + public string DataFolder { get; set; } + public string ConnectionString { get; set; } + } +} diff --git a/src/Orchard/Data/Migrations/IDatabaseMigrationManager.cs b/src/Orchard/Data/Migrations/IDatabaseMigrationManager.cs deleted file mode 100644 index 964f24360..000000000 --- a/src/Orchard/Data/Migrations/IDatabaseMigrationManager.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace Orchard.Data.Migrations { - public interface IDatabaseMigrationManager : IDependency { - IDatabaseCoordinator CreateCoordinator(string provider, string dataFolder, string connectionString); - } -} diff --git a/src/Orchard/Data/Migrations/ISessionFactoryBuilder.cs b/src/Orchard/Data/Migrations/ISessionFactoryBuilder.cs new file mode 100644 index 000000000..e0430a88d --- /dev/null +++ b/src/Orchard/Data/Migrations/ISessionFactoryBuilder.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using NHibernate; +using Orchard.Environment; + +namespace Orchard.Data.Migrations { + public interface ISessionFactoryBuilder { + ISessionFactory BuildSessionFactory(SessionFactoryBuilderParameters parameters); + } + + public class SessionFactoryBuilderParameters { + public IEnumerable RecordDescriptors { get; set; } + public bool CreateDatabase { get; set; } + public bool UpdateSchema { get; set; } + } +} diff --git a/src/Orchard/Data/Migrations/SQLiteDatabaseCoordinator.cs b/src/Orchard/Data/Migrations/SQLiteSessionFactoryBuilder.cs similarity index 100% rename from src/Orchard/Data/Migrations/SQLiteDatabaseCoordinator.cs rename to src/Orchard/Data/Migrations/SQLiteSessionFactoryBuilder.cs diff --git a/src/Orchard/Data/Migrations/SqlServerDatabaseCoordinator.cs b/src/Orchard/Data/Migrations/SqlServerSessionFactoryBuilder.cs similarity index 100% rename from src/Orchard/Data/Migrations/SqlServerDatabaseCoordinator.cs rename to src/Orchard/Data/Migrations/SqlServerSessionFactoryBuilder.cs diff --git a/src/Orchard/Data/SessionFactoryHolder.cs b/src/Orchard/Data/SessionFactoryHolder.cs index 15ade6961..533141b2c 100644 --- a/src/Orchard/Data/SessionFactoryHolder.cs +++ b/src/Orchard/Data/SessionFactoryHolder.cs @@ -14,45 +14,56 @@ namespace Orchard.Data { public class SessionFactoryHolder : ISessionFactoryHolder { private readonly IShellSettings _shellSettings; private readonly ICompositionStrategy _compositionStrategy; - private readonly IDatabaseMigrationManager _databaseMigrationManager; + private readonly IDatabaseManager _databaseManager; private ISessionFactory _sessionFactory; public SessionFactoryHolder( IShellSettings shellSettings, ICompositionStrategy compositionStrategy, - IDatabaseMigrationManager databaseMigrationManager) { + IDatabaseManager databaseManager) { _shellSettings = shellSettings; _compositionStrategy = compositionStrategy; - _databaseMigrationManager = databaseMigrationManager; + _databaseManager = databaseManager; } public void UpdateSchema() { - var coordinator = GetDatabaseCoordinator(); - coordinator.UpdateSchema(_compositionStrategy.GetRecordDescriptors()); + lock (this) { + if (_sessionFactory == null) { + _sessionFactory = BuildSessionFactory(true); + } + } } public ISessionFactory GetSessionFactory() { - lock(this) { + lock (this) { if (_sessionFactory == null) { - _sessionFactory = BuildSessionFactory(); + _sessionFactory = BuildSessionFactory(false); } } return _sessionFactory; } - private ISessionFactory BuildSessionFactory() { - var coordinator = GetDatabaseCoordinator(); - return coordinator.BuildSessionFactory(_compositionStrategy.GetRecordDescriptors()); - } - - - private IDatabaseCoordinator GetDatabaseCoordinator() { + private ISessionFactory BuildSessionFactory(bool updateSchema) { var sitesPath = HostingEnvironment.MapPath("~/App_Data/Sites"); var shellPath = Path.Combine(sitesPath, _shellSettings.Name); - return _databaseMigrationManager.CreateCoordinator(_shellSettings.DataProvider, shellPath, _shellSettings.DataConnectionString); + + var coordinator = _databaseManager.CreateCoordinator(new DatabaseParameters { + Provider = _shellSettings.DataProvider, + DataFolder = shellPath, + ConnectionString = _shellSettings.DataConnectionString + }); + + var sessionFactory = coordinator.BuildSessionFactory(new SessionFactoryBuilderParameters { + CreateDatabase = false, + UpdateSchema = updateSchema, + RecordDescriptors = _compositionStrategy.GetRecordDescriptors() + }); + + return sessionFactory; } + }