Snapshot of incremental work

Sequence of events during setup functions at this point
Committing this point prior to cleaning up changes to ensure a working arrangement isn't lost

--HG--
branch : dev
This commit is contained in:
Louis DeJardin
2010-02-15 12:06:05 -08:00
parent f9c4d6dfdd
commit 53b96f3248
14 changed files with 121 additions and 86 deletions

View File

@@ -1,7 +1,5 @@
using System;
using System.Data.SqlClient;
using System.Data.SqlClient;
using System.IO;
using System.Threading;
using NUnit.Framework;
using Orchard.Data.Migrations;
using Orchard.Environment;
@@ -9,7 +7,7 @@ using Orchard.Tests.Records;
namespace Orchard.Tests.Data.Migrations {
[TestFixture]
public class DatabaseMigrationManagerTests {
public class DatabaseManagerTests {
private string _tempDataFolder;
[SetUp]
@@ -45,41 +43,28 @@ namespace Orchard.Tests.Data.Migrations {
}
}
[Test]
public void MigrationManagerShouldCreateEmptySQLiteDatabaseAtGivenLocation() {
var manager = (IDatabaseMigrationManager)new DatabaseMigrationManager();
var coordinator = manager.CreateCoordinator("SQLite", _tempDataFolder, "");
coordinator.CreateDatabase();
Assert.That(File.Exists(Path.Combine(_tempDataFolder, "Orchard.db")), Is.True);
}
[Test, ExpectedException(typeof(NotImplementedException))]
public void MigrationManagerShouldNotImplementTheCreationOfSqlServer() {
var manager = (IDatabaseMigrationManager)new DatabaseMigrationManager();
var coordinator = manager.CreateCoordinator("SqlServer", _tempDataFolder, "");
coordinator.CreateDatabase();
}
[Test]
public void SQLiteSchemaShouldBeGeneratedAndUsable() {
var manager = (IDatabaseMigrationManager) new DatabaseMigrationManager();
var coordinator = manager.CreateCoordinator("SQLite", _tempDataFolder, "");
var manager = (IDatabaseManager)new DatabaseManager();
var coordinator = manager.CreateCoordinator(new DatabaseParameters {
Provider = "SQLite",
DataFolder = _tempDataFolder
});
var recordDescriptors = new[] {
new RecordDescriptor {Prefix = "Hello", Type = typeof (Foo)}
};
coordinator.UpdateSchema(recordDescriptors);
var sessionFactory = coordinator.BuildSessionFactory(new SessionFactoryBuilderParameters {
UpdateSchema = true,
RecordDescriptors = recordDescriptors
});
var sessionFactory = coordinator.BuildSessionFactory(recordDescriptors);
var session = sessionFactory.OpenSession();
var foo = new Foo {Name = "hi there"};
var foo = new Foo { Name = "hi there" };
session.Save(foo);
session.Flush();
session.Close();
@@ -95,16 +80,22 @@ namespace Orchard.Tests.Data.Migrations {
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;");
var manager = (IDatabaseManager)new DatabaseManager();
var coordinator = manager.CreateCoordinator(new DatabaseParameters {
Provider = "SQLite",
DataFolder = _tempDataFolder,
ConnectionString = "Data Source=.\\SQLEXPRESS;AttachDbFileName=" + databasePath + ";Integrated Security=True;User Instance=True;",
});
var recordDescriptors = new[] {
new RecordDescriptor {Prefix = "Hello", Type = typeof (Foo)}
};
coordinator.UpdateSchema(recordDescriptors);
var sessionFactory = coordinator.BuildSessionFactory(recordDescriptors);
var sessionFactory = coordinator.BuildSessionFactory(new SessionFactoryBuilderParameters {
UpdateSchema = true,
RecordDescriptors = recordDescriptors
});
var session = sessionFactory.OpenSession();
var foo = new Foo { Name = "hi there" };

View File

@@ -19,7 +19,7 @@ namespace Orchard.Tests {
//var persistenceModel = AutoMap.Source(new Types(types))
// .Alterations(alt => AddAlterations(alt, types))
// .Conventions.AddFromAssemblyOf<DataModule>();
var persistenceModel = DatabaseCoordinatorBase.CreatePersistenceModel(types.Select(t => new RecordDescriptor { Prefix = "Test", Type = t }));
var persistenceModel = AbstractSessionFactoryBuilder.CreatePersistenceModel(types.Select(t => new RecordDescriptor { Prefix = "Test", Type = t }));
return Fluently.Configure()
.Database(SQLiteConfiguration.Standard.UsingFile(fileName).ShowSql())

View File

@@ -135,7 +135,7 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="DataUtility.cs" />
<Compile Include="Data\Migrations\DatabaseMigrationManagerTests.cs" />
<Compile Include="Data\Migrations\DatabaseManagerTests.cs" />
<Compile Include="Data\RepositoryTests.cs" />
<Compile Include="Data\StubLocator.cs" />
<Compile Include="Environment\Configuration\AppDataFolderTests.cs" />

View File

@@ -36,6 +36,14 @@ namespace Orchard.Web {
//TODO: what's the failed initialization story - IoC failure in app start can leave you with a zombie appdomain
}
protected void Application_BeginRequest() {
_host.BeginRequest();
}
protected void Application_EndRequest() {
_host.EndRequest();
}
private void CheckMvcVersion(Version requiredVersion) {
Assembly loadedMvcAssembly = typeof(System.Web.Mvc.Controller).Assembly;
Version loadedMvcVersion = ReadAssemblyFileVersion(loadedMvcAssembly);
@@ -81,9 +89,6 @@ namespace Orchard.Web {
return new Version(attribute.Version);
}
protected void Application_EndRequest() {
_host.EndRequest();
}
protected void MvcSingletons(ContainerBuilder builder) {
builder.Register(ControllerBuilder.Current);

View File

@@ -82,7 +82,7 @@ namespace Orchard.Setup.Controllers {
String.Empty, String.Empty, String.Empty,
true));
/*
// set site name and settings
var siteService = finiteEnvironment.Resolve<ISiteService>();
var siteSettings = siteService.GetSiteSettings().As<SiteSettings>();
@@ -105,7 +105,7 @@ namespace Orchard.Setup.Controllers {
var authenticationService = finiteEnvironment.Resolve<IAuthenticationService>();
authenticationService.SignIn(user, true);
*/
}
catch {
finiteEnvironment.Resolve<ITransactionManager>().Cancel();

View File

@@ -2,10 +2,10 @@
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);
public ISessionFactoryBuilder CreateCoordinator(DatabaseParameters databaseParameters) {
if (string.Equals(databaseParameters.Provider, "SQLite", StringComparison.InvariantCultureIgnoreCase))
return new SQLiteSessionFactoryBuilder(databaseParameters.DataFolder, databaseParameters.ConnectionString);
return new SqlServerSessionFactoryBuilder(databaseParameters.DataFolder, databaseParameters.ConnectionString);
}
}
}

View File

@@ -2,11 +2,11 @@ using System.IO;
using FluentNHibernate.Cfg.Db;
namespace Orchard.Data.Migrations {
public class SQLiteDatabaseCoordinator : DatabaseCoordinatorBase {
public class SQLiteSessionFactoryBuilder : AbstractSessionFactoryBuilder {
private readonly string _dataFolder;
private readonly string _connectionString;
public SQLiteDatabaseCoordinator(string dataFolder, string connectionString) {
public SQLiteSessionFactoryBuilder(string dataFolder, string connectionString) {
_dataFolder = dataFolder;
_connectionString = connectionString;
}

View File

@@ -2,11 +2,11 @@ using System;
using FluentNHibernate.Cfg.Db;
namespace Orchard.Data.Migrations {
public class SqlServerDatabaseCoordinator : DatabaseCoordinatorBase {
public class SqlServerSessionFactoryBuilder : AbstractSessionFactoryBuilder {
private readonly string _dataFolder;
private readonly string _connectionString;
public SqlServerDatabaseCoordinator(string dataFolder, string connectionString) {
public SqlServerSessionFactoryBuilder(string dataFolder, string connectionString) {
_dataFolder = dataFolder;
_connectionString = connectionString;
}

View File

@@ -4,6 +4,7 @@ using NHibernate;
using Orchard.Data.Migrations;
using Orchard.Environment;
using Orchard.Environment.Configuration;
using Orchard.Logging;
namespace Orchard.Data {
public interface ISessionFactoryHolder : ISingletonDependency {
@@ -28,14 +29,19 @@ namespace Orchard.Data {
_compositionStrategy = compositionStrategy;
_databaseManager = databaseManager;
_appDataFolder = appDataFolder;
Logger = NullLogger.Instance;
}
public ILogger Logger { get; set; }
public void UpdateSchema() {
lock (this) {
if (_sessionFactory == null) {
_sessionFactory = BuildSessionFactory(true);
if (_sessionFactory != null) {
Logger.Error("UpdateSchema can not be called after a session factory was created");
throw new OrchardException("UpdateSchema can not be called after a session factory was created");
}
_sessionFactory = BuildSessionFactory(true);
}
}
@@ -49,8 +55,9 @@ namespace Orchard.Data {
}
private ISessionFactory BuildSessionFactory(bool updateSchema) {
var shellPath = _appDataFolder.CreateDirectory(Path.Combine("Sites", _shellSettings.Name));
Logger.Debug("Building session factory");
var shellPath = _appDataFolder.CreateDirectory(Path.Combine("Sites", _shellSettings.Name));
var coordinator = _databaseManager.CreateCoordinator(new DatabaseParameters {
Provider = _shellSettings.DataProvider,

View File

@@ -1,5 +1,6 @@
using System;
using NHibernate;
using Orchard.Logging;
namespace Orchard.Data {
public class SessionLocator : ISessionLocator {
@@ -12,13 +13,22 @@ namespace Orchard.Data {
ITransactionManager transactionManager) {
_sessionFactoryHolder = sessionFactoryHolder;
_transactionManager = transactionManager;
Logger = NullLogger.Instance;
}
public ILogger Logger { get; set; }
public ISession For(Type entityType) {
if (_session==null) {
_transactionManager.Demand();
Logger.Debug("Acquiring session for {0}", entityType);
if (_session == null) {
var sessionFactory = _sessionFactoryHolder.GetSessionFactory();
_transactionManager.Demand();
Logger.Information("Openning database session");
_session = sessionFactory.OpenSession();
}
return _session;

View File

@@ -42,11 +42,17 @@ namespace Orchard.Environment {
_controllerBuilder.SetControllerFactory(new OrchardControllerFactory());
ServiceLocator.SetLocator(t => _containerProvider.RequestContainer.Resolve(t));
Initialize();
CreateAndActivateShell();
}
void IOrchardHost.Reinitialize() {
Initialize();
_current = null;
//CreateAndActivateShell();
}
void IOrchardHost.BeginRequest() {
BeginRequest();
}
void IOrchardHost.EndRequest() {
@@ -58,19 +64,30 @@ namespace Orchard.Environment {
return new StandaloneEnvironment(shellContainer);
}
protected virtual void Initialize() {
var shellContainer = CreateShellContainer();
var shell = shellContainer.Resolve<IOrchardShell>();
shell.Activate();
_current = shell;
protected virtual void CreateAndActivateShell() {
lock (this) {
if (_current != null) {
return;
}
// Fire off one-time install events on an alternate container
HackInstallSimulation();
var shellContainer = CreateShellContainer();
var shell = shellContainer.Resolve<IOrchardShell>();
shell.Activate();
_current = shell;
// Activate extensions inside shell container
HackSimulateExtensionActivation(shellContainer);
// Fire off one-time install events on an alternate container
HackInstallSimulation();
// Activate extensions inside shell container
HackSimulateExtensionActivation(shellContainer);
}
}
protected virtual void BeginRequest() {
if (_current == null) {
CreateAndActivateShell();
}
}
protected virtual void EndRequest() {
_containerProvider.DisposeRequestContainer();
@@ -103,19 +120,19 @@ namespace Orchard.Environment {
}
private void HackInstallSimulation() {
//var tempContainer = CreateShellContainer();
//var containerProvider = new FiniteContainerProvider(tempContainer);
//try {
// var requestContainer = containerProvider.RequestContainer;
var tempContainer = CreateShellContainer();
var containerProvider = new FiniteContainerProvider(tempContainer);
try {
var requestContainer = containerProvider.RequestContainer;
// var hackInstallationGenerator = requestContainer.Resolve<IHackInstallationGenerator>();
// hackInstallationGenerator.GenerateInstallEvents();
//}
//finally {
// // shut everything down again
// containerProvider.DisposeRequestContainer();
// tempContainer.Dispose();
//}
var hackInstallationGenerator = requestContainer.Resolve<IHackInstallationGenerator>();
hackInstallationGenerator.GenerateInstallEvents();
}
finally {
// shut everything down again
containerProvider.DisposeRequestContainer();
tempContainer.Dispose();
}
}
private void HackSimulateExtensionActivation(IContainer shellContainer) {

View File

@@ -7,16 +7,21 @@ namespace Orchard.Environment {
/// </summary>
void Initialize();
/// <summary>
/// Called each time a request ends to deterministically commit and dispose outstanding activity
/// </summary>
void EndRequest();
/// <summary>
/// Called when configuration changes requires the shell topology to be reloaded and applied
/// </summary>
void Reinitialize();
/// <summary>
/// Called each time a request begins to offer a just-in-time reinitialization point
/// </summary>
void BeginRequest();
/// <summary>
/// Called each time a request ends to deterministically commit and dispose outstanding activity
/// </summary>
void EndRequest();
/// <summary>
/// Can be used to build an temporary self-contained instance of a shell's configured code.
/// Services may be resolved from within this instance to configure and initialize it's storage.

View File

@@ -52,7 +52,7 @@ namespace Orchard.Environment.ShellBuilders {
builder.Register<PageClassBuilder>().As<IPageClassBuilder>().ContainerScoped();
builder.Register<Notifier>().As<INotifier>().ContainerScoped();
builder.Register<NotifyFilter>().As<IFilterProvider>().ContainerScoped();
builder.Register<DatabaseMigrationManager>().As<IDatabaseMigrationManager>().ContainerScoped();
builder.Register<DatabaseManager>().As<IDatabaseManager>().ContainerScoped();
// safe mode specific implementations of needed service interfaces
builder.Register<NullHackInstallationGenerator>().As<IHackInstallationGenerator>().ContainerScoped();

View File

@@ -133,12 +133,12 @@
<Compile Include="ContentManagement\Handlers\RemoveContentContext.cs" />
<Compile Include="ContentManagement\Handlers\VersionContentContext.cs" />
<Compile Include="Data\Conventions\RecordTableNameConvention.cs" />
<Compile Include="Data\Migrations\DatabaseCoordinatorBase.cs" />
<Compile Include="Data\Migrations\DatabaseMigrationManager.cs" />
<Compile Include="Data\Migrations\IDatabaseCoordinator.cs" />
<Compile Include="Data\Migrations\IDatabaseMigrationManager.cs" />
<Compile Include="Data\Migrations\SQLiteDatabaseCoordinator.cs" />
<Compile Include="Data\Migrations\SqlServerDatabaseCoordinator.cs" />
<Compile Include="Data\Migrations\AbstractSessionFactoryBuilder.cs" />
<Compile Include="Data\Migrations\DatabaseManager.cs" />
<Compile Include="Data\Migrations\IDatabaseManager.cs" />
<Compile Include="Data\Migrations\ISessionFactoryBuilder.cs" />
<Compile Include="Data\Migrations\SQLiteSessionFactoryBuilder.cs" />
<Compile Include="Data\Migrations\SqlServerSessionFactoryBuilder.cs" />
<Compile Include="Data\SessionFactoryHolder.cs" />
<Compile Include="Environment\Configuration\AppDataFolder.cs" />
<Compile Include="Environment\Configuration\ShellSettingsLoader.cs" />