mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-09-18 09:44:20 +08:00
Merge
--HG-- branch : dev
This commit is contained in:
@@ -102,8 +102,17 @@ namespace Orchard.Tests.DataMigration {
|
||||
);
|
||||
}
|
||||
|
||||
[Test, Ignore("Fix pending")]
|
||||
[Test]
|
||||
public void DropTableCommandShouldBeHandled() {
|
||||
_schemaBuilder
|
||||
.CreateTable("User", table => table
|
||||
.Column("Id", DbType.Int32, column => column.PrimaryKey().Identity())
|
||||
.Column("Firstname", DbType.String, column => column.WithLength(255))
|
||||
.Column("Lastname", DbType.String, column => column.WithLength(100).NotNull())
|
||||
.Column("SN", DbType.AnsiString, column => column.WithLength(40).Unique())
|
||||
.Column("Salary", DbType.Decimal, column => column.WithPrecision(9).WithScale(2))
|
||||
.Column("Gender", DbType.Decimal, column => column.WithDefault("''"))
|
||||
);
|
||||
|
||||
_schemaBuilder
|
||||
.DropTable("User");
|
||||
|
@@ -4,10 +4,13 @@ using System.ComponentModel.DataAnnotations;
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Web;
|
||||
using Autofac;
|
||||
using Autofac.Features.Metadata;
|
||||
using NHibernate;
|
||||
using NUnit.Framework;
|
||||
using Orchard.Caching;
|
||||
using Orchard.ContentManagement.Records;
|
||||
using Orchard.Data;
|
||||
using Orchard.Data.Conventions;
|
||||
@@ -20,16 +23,20 @@ using Orchard.DevTools.Services;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Environment.Extensions.Folders;
|
||||
using Orchard.Environment.Extensions.Loaders;
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
using Orchard.Environment.ShellBuilders;
|
||||
using Orchard.Environment.ShellBuilders.Models;
|
||||
using Orchard.FileSystems.AppData;
|
||||
using Orchard.FileSystems.Dependencies;
|
||||
using Orchard.Tests.ContentManagement;
|
||||
using Orchard.Data.Providers;
|
||||
using Orchard.Tests.DataMigration.Orchard.Tests.DataMigration.Records;
|
||||
using Orchard.Tests.FileSystems.AppData;
|
||||
|
||||
namespace Orchard.Tests.DataMigration {
|
||||
[TestFixture]
|
||||
public class SchemaCommandGeneratorTests {
|
||||
public class SchemaCommandGeneratorTests {
|
||||
private IContainer _container;
|
||||
private StubFolders _folders;
|
||||
private ISchemaCommandGenerator _generator;
|
||||
@@ -49,7 +56,7 @@ namespace Orchard.Tests.DataMigration {
|
||||
|
||||
var databaseFileName = System.IO.Path.GetTempFileName();
|
||||
_sessionFactory = DataUtility.CreateSessionFactory(
|
||||
databaseFileName, types );
|
||||
databaseFileName, types);
|
||||
|
||||
var builder = new ContainerBuilder();
|
||||
_folders = new StubFolders();
|
||||
@@ -60,25 +67,28 @@ namespace Orchard.Tests.DataMigration {
|
||||
new Dictionary<string, object> {{"ProviderName", "SqlCe"}})
|
||||
});
|
||||
|
||||
builder.RegisterInstance(new ShellSettings { Name = "Default", DataTablePrefix = "TEST_", DataProvider = "SqlCe"});
|
||||
builder.RegisterInstance(new ShellSettings { Name = "Default", DataTablePrefix = "TEST", DataProvider = "SqlCe" });
|
||||
builder.RegisterInstance(AppDataFolderTests.CreateAppDataFolder(Path.GetDirectoryName(databaseFileName))).As<IAppDataFolder>();
|
||||
builder.RegisterType<SessionConfigurationCache>().As<ISessionConfigurationCache>();
|
||||
builder.RegisterType<SqlCeDataServicesProvider>().As<IDataServicesProvider>();
|
||||
builder.RegisterInstance(manager).As<IDataServicesProviderFactory>();
|
||||
builder.RegisterType<NullInterpreter>().As<IDataMigrationInterpreter>();
|
||||
builder.RegisterType<SessionFactoryHolder>().As<ISessionFactoryHolder>();
|
||||
builder.RegisterType<CompositionStrategy>().As<ICompositionStrategy>();
|
||||
builder.RegisterInstance(_folders).As<IExtensionFolders>();
|
||||
builder.RegisterType<StubLoaders>().As<IExtensionLoader>();
|
||||
builder.RegisterType<ExtensionManager>().As<IExtensionManager>();
|
||||
builder.RegisterType<SchemaCommandGenerator>().As<ISchemaCommandGenerator>();
|
||||
builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>));
|
||||
_session = _sessionFactory.OpenSession();
|
||||
builder.RegisterInstance(new DefaultContentManagerTests.TestSessionLocator(_session)).As<ISessionLocator>();
|
||||
|
||||
builder.RegisterInstance(new ShellBlueprint() { Records = types.Select(t => new RecordBlueprint { Feature = new Feature() { Descriptor = new FeatureDescriptor() { Name = "Feature1" } }, TableName = "TEST_" + t.Name, Type = t })});
|
||||
builder.RegisterInstance(new ShellBlueprint());
|
||||
|
||||
_container = builder.Build();
|
||||
_generator = _container.Resolve<ISchemaCommandGenerator>();
|
||||
|
||||
_folders.Manifests.Add("Module1", @"
|
||||
_folders.Manifests.Add("Feature1", @"
|
||||
name: Module1
|
||||
version: 0.1
|
||||
orchardversion: 1
|
||||
@@ -96,7 +106,7 @@ features:
|
||||
public IDictionary<string, string> Manifests { get; set; }
|
||||
|
||||
public IEnumerable<ExtensionDescriptor> AvailableExtensions() {
|
||||
foreach (var e in Manifests) {
|
||||
foreach ( var e in Manifests ) {
|
||||
string name = e.Key;
|
||||
var parseResult = ExtensionFolders.ParseManifest(Manifests[name]);
|
||||
yield return ExtensionFolders.GetDescriptorForExtension("~/", name, "Module", parseResult);
|
||||
@@ -104,27 +114,96 @@ features:
|
||||
}
|
||||
}
|
||||
|
||||
public class StubLoaders : IExtensionLoader {
|
||||
#region Implementation of IExtensionLoader
|
||||
|
||||
public int Order {
|
||||
get { return 1; }
|
||||
}
|
||||
|
||||
public string Name {
|
||||
get { return this.GetType().Name; }
|
||||
}
|
||||
|
||||
public Assembly LoadReference(DependencyReferenceDescriptor reference) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void ReferenceActivated(ExtensionLoadingContext context, ExtensionReferenceProbeEntry referenceEntry) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void ReferenceDeactivated(ExtensionLoadingContext context, ExtensionReferenceProbeEntry referenceEntry) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool IsCompatibleWithModuleReferences(ExtensionDescriptor extension, IEnumerable<ExtensionProbeEntry> references) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public ExtensionProbeEntry Probe(ExtensionDescriptor descriptor) {
|
||||
return new ExtensionProbeEntry { Descriptor = descriptor, Loader = this };
|
||||
}
|
||||
|
||||
public IEnumerable<ExtensionReferenceProbeEntry> ProbeReferences(ExtensionDescriptor extensionDescriptor) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public ExtensionEntry Load(ExtensionDescriptor descriptor) {
|
||||
return new ExtensionEntry { Descriptor = descriptor, ExportedTypes = new[] { typeof(BlogRecord), typeof(BodyRecord), typeof(BlogArchiveRecord) } };
|
||||
}
|
||||
|
||||
public void ExtensionActivated(ExtensionLoadingContext ctx, ExtensionDescriptor extension) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void ExtensionDeactivated(ExtensionLoadingContext ctx, ExtensionDescriptor extension) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void ExtensionRemoved(ExtensionLoadingContext ctx, DependencyDescriptor dependency) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Monitor(ExtensionDescriptor extension, Action<IVolatileToken> monitor) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetWebFormAssemblyDirective(DependencyDescriptor dependency) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetWebFormVirtualDependencies(DependencyDescriptor dependency) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetFileDependencies(DependencyDescriptor dependency, string virtualPath) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ShouldCreateCreateTableCommands() {
|
||||
var commands = _generator.GetCreateFeatureCommands("Feature1", false).ToList();
|
||||
Assert.That(commands, Is.Not.Null);
|
||||
Assert.That(commands.Count(), Is.EqualTo(6));
|
||||
Assert.That(commands.Count(), Is.EqualTo(3));
|
||||
|
||||
var blogRecord = commands.Where(c => c.Name == "TEST_BlogRecord").First();
|
||||
var blogRecord = commands.Where(c => c.Name == "TEST_Feature1_BlogRecord").First();
|
||||
|
||||
Assert.That(blogRecord.TableCommands.OfType<CreateColumnCommand>().Any(c => c.ColumnName == "Id" && !c.IsIdentity && c.IsPrimaryKey && c.DbType == DbType.Int32));
|
||||
Assert.That(blogRecord.TableCommands.OfType<CreateColumnCommand>().Any(c => c.ColumnName == "Description" && c.DbType == DbType.String));
|
||||
Assert.That(blogRecord.TableCommands.OfType<CreateColumnCommand>().Any(c => c.ColumnName == "PostCount" && c.DbType == DbType.Int32));
|
||||
|
||||
var blogArchiveRecord = commands.Where(c => c.Name == "TEST_BlogArchiveRecord").First();
|
||||
var blogArchiveRecord = commands.Where(c => c.Name == "TEST_Feature1_BlogArchiveRecord").First();
|
||||
Assert.That(blogArchiveRecord.TableCommands.OfType<CreateColumnCommand>().Any(c => c.ColumnName == "Id" && c.IsPrimaryKey && c.DbType == DbType.Int32));
|
||||
Assert.That(blogArchiveRecord.TableCommands.OfType<CreateColumnCommand>().Any(c => c.ColumnName == "Year" && c.DbType == DbType.Int32));
|
||||
Assert.That(blogArchiveRecord.TableCommands.OfType<CreateColumnCommand>().Any(c => c.ColumnName == "Month" && c.DbType == DbType.Int32));
|
||||
Assert.That(blogArchiveRecord.TableCommands.OfType<CreateColumnCommand>().Any(c => c.ColumnName == "PostCount" && c.DbType == DbType.Int32));
|
||||
Assert.That(blogArchiveRecord.TableCommands.OfType<CreateColumnCommand>().Any(c => c.ColumnName == "Blog_id" && c.DbType == DbType.Int32));
|
||||
|
||||
var bodyRecord = commands.Where(c => c.Name == "TEST_BodyRecord").First();
|
||||
var bodyRecord = commands.Where(c => c.Name == "TEST_Feature1_BodyRecord").First();
|
||||
Assert.That(bodyRecord.TableCommands.OfType<CreateColumnCommand>().Any(c => c.ColumnName == "Id" && c.IsPrimaryKey && c.DbType == DbType.Int32));
|
||||
Assert.That(bodyRecord.TableCommands.OfType<CreateColumnCommand>().Any(c => c.ColumnName == "Text" && c.DbType == DbType.String && c.Length == 10000));
|
||||
Assert.That(bodyRecord.TableCommands.OfType<CreateColumnCommand>().Any(c => c.ColumnName == "Format" && c.DbType == DbType.String && c.Length == 42));
|
||||
@@ -136,25 +215,25 @@ features:
|
||||
|
||||
var commands = _generator.GetCreateFeatureCommands("Feature1", false).ToList();
|
||||
Assert.That(commands, Is.Not.Null);
|
||||
Assert.That(commands.Count(), Is.EqualTo(6));
|
||||
Assert.That(commands.Count(), Is.EqualTo(3));
|
||||
|
||||
var sw = new StringWriter();
|
||||
var interpreter = new ScaffoldingCommandInterpreter(sw);
|
||||
|
||||
var blogRecord = commands.Where(c => c.Name == "TEST_BlogRecord").First();
|
||||
var blogArchiveRecord = commands.Where(c => c.Name == "TEST_BlogArchiveRecord").First();
|
||||
var bodyRecord = commands.Where(c => c.Name == "TEST_BodyRecord").First();
|
||||
var blogRecord = commands.Where(c => c.Name == "TEST_Feature1_BlogRecord").First();
|
||||
var blogArchiveRecord = commands.Where(c => c.Name == "TEST_Feature1_BlogArchiveRecord").First();
|
||||
var bodyRecord = commands.Where(c => c.Name == "TEST_Feature1_BodyRecord").First();
|
||||
|
||||
sw.GetStringBuilder().Clear();
|
||||
interpreter.Visit(blogRecord);
|
||||
Assert.That(sw.ToString().Contains("SchemaBuilder.CreateTable(\"TEST_BlogRecord"));
|
||||
Assert.That(sw.ToString().Contains("SchemaBuilder.CreateTable(\"TEST_Feature1_BlogRecord"));
|
||||
Assert.That(sw.ToString().Contains(".ContentPartRecord()"));
|
||||
Assert.That(sw.ToString().Contains(".Column(\"Description\", DbType.String)"));
|
||||
Assert.That(sw.ToString().Contains(".Column(\"PostCount\", DbType.Int32)"));
|
||||
|
||||
sw.GetStringBuilder().Clear();
|
||||
interpreter.Visit(blogArchiveRecord);
|
||||
Assert.That(sw.ToString().Contains("SchemaBuilder.CreateTable(\"TEST_BlogArchiveRecord"));
|
||||
Assert.That(sw.ToString().Contains("SchemaBuilder.CreateTable(\"TEST_Feature1_BlogArchiveRecord"));
|
||||
Assert.That(sw.ToString().Contains(".Column(\"Id\", DbType.Int32, column => column.PrimaryKey().Identity())"));
|
||||
Assert.That(sw.ToString().Contains(".Column(\"Year\", DbType.Int32)"));
|
||||
Assert.That(sw.ToString().Contains(".Column(\"Month\", DbType.Int32)"));
|
||||
@@ -163,7 +242,7 @@ features:
|
||||
|
||||
sw.GetStringBuilder().Clear();
|
||||
interpreter.Visit(bodyRecord);
|
||||
Assert.That(sw.ToString().Contains("SchemaBuilder.CreateTable(\"TEST_BodyRecord"));
|
||||
Assert.That(sw.ToString().Contains("SchemaBuilder.CreateTable(\"TEST_Feature1_BodyRecord"));
|
||||
Assert.That(sw.ToString().Contains(".ContentPartVersionRecord()"));
|
||||
Assert.That(sw.ToString().Contains(".Column(\"Text\", DbType.String, column => column.Unlimited())"));
|
||||
Assert.That(sw.ToString().Contains(".Column(\"Format\", DbType.String, column => column.WithLength(42))"));
|
||||
@@ -172,23 +251,26 @@ features:
|
||||
}
|
||||
|
||||
|
||||
public class BlogRecord : ContentPartRecord {
|
||||
public virtual string Description { get; set; }
|
||||
public virtual int PostCount { get; set; }
|
||||
}
|
||||
// namespace is needed as the shell composition strategy will filter records using it also
|
||||
namespace Orchard.Tests.DataMigration.Records {
|
||||
public class BlogRecord : ContentPartRecord {
|
||||
public virtual string Description { get; set; }
|
||||
public virtual int PostCount { get; set; }
|
||||
}
|
||||
|
||||
public class BodyRecord : ContentPartVersionRecord {
|
||||
[StringLengthMax]
|
||||
public virtual string Text { get; set; }
|
||||
[StringLength(42)]
|
||||
public virtual string Format { get; set; }
|
||||
}
|
||||
public class BodyRecord : ContentPartVersionRecord {
|
||||
[StringLengthMax]
|
||||
public virtual string Text { get; set; }
|
||||
[StringLength(42)]
|
||||
public virtual string Format { get; set; }
|
||||
}
|
||||
|
||||
public class BlogArchiveRecord {
|
||||
public virtual int Id { get; set; }
|
||||
public virtual BlogRecord Blog { get; set; }
|
||||
public virtual int Year { get; set; }
|
||||
public virtual int Month { get; set; }
|
||||
public virtual int PostCount { get; set; }
|
||||
public class BlogArchiveRecord {
|
||||
public virtual int Id { get; set; }
|
||||
public virtual BlogRecord Blog { get; set; }
|
||||
public virtual int Year { get; set; }
|
||||
public virtual int Month { get; set; }
|
||||
public virtual int PostCount { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -6,6 +6,7 @@ using Orchard.Commands;
|
||||
using Orchard.Data.Migration.Generator;
|
||||
using Orchard.DevTools.Services;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Environment.State;
|
||||
|
||||
namespace Orchard.DevTools.Commands {
|
||||
[OrchardFeature("Scaffolding")]
|
||||
|
@@ -105,10 +105,10 @@ namespace Orchard.Setup.Services {
|
||||
Features = context.EnabledFeatures.Select(name => new ShellFeature { Name = name })
|
||||
};
|
||||
|
||||
var shellToplogy = _compositionStrategy.Compose(shellSettings, shellDescriptor);
|
||||
var shellBlueprint = _compositionStrategy.Compose(shellSettings, shellDescriptor);
|
||||
|
||||
// initialize database explicitly, and store shell descriptor
|
||||
var bootstrapLifetimeScope = _shellContainerFactory.CreateContainer(shellSettings, shellToplogy);
|
||||
var bootstrapLifetimeScope = _shellContainerFactory.CreateContainer(shellSettings, shellBlueprint);
|
||||
using ( var environment = new StandaloneEnvironment(bootstrapLifetimeScope) ) {
|
||||
|
||||
// check if the database is already created (in case an exception occured in the second phase)
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
@@ -9,27 +10,65 @@ using Orchard.ContentManagement.Records;
|
||||
using Orchard.Data.Migration.Schema;
|
||||
using Orchard.Data.Providers;
|
||||
using NHibernate.Dialect;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Environment.Descriptor.Models;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
using Orchard.Environment.ShellBuilders;
|
||||
using Orchard.Environment.ShellBuilders.Models;
|
||||
using Orchard.Environment.State;
|
||||
|
||||
namespace Orchard.Data.Migration.Generator {
|
||||
public class SchemaCommandGenerator : ISchemaCommandGenerator {
|
||||
private readonly ISessionFactoryHolder _sessionFactoryHolder;
|
||||
private readonly IExtensionManager _extensionManager;
|
||||
private readonly ICompositionStrategy _compositionStrategy;
|
||||
private readonly ShellSettings _shellSettings;
|
||||
private readonly IDataServicesProviderFactory _dataServicesProviderFactory;
|
||||
|
||||
public SchemaCommandGenerator(
|
||||
ISessionFactoryHolder sessionFactoryHolder) {
|
||||
ISessionFactoryHolder sessionFactoryHolder,
|
||||
IExtensionManager extensionManager,
|
||||
ICompositionStrategy compositionStrategy,
|
||||
ShellSettings shellSettings,
|
||||
IDataServicesProviderFactory dataServicesProviderFactory) {
|
||||
_sessionFactoryHolder = sessionFactoryHolder;
|
||||
_extensionManager = extensionManager;
|
||||
_compositionStrategy = compositionStrategy;
|
||||
_shellSettings = shellSettings;
|
||||
_dataServicesProviderFactory = dataServicesProviderFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates SchemaCommand instances in order to create the schema for a specific feature
|
||||
/// </summary>
|
||||
public IEnumerable<SchemaCommand> GetCreateFeatureCommands(string feature, bool drop) {
|
||||
var parameters = _sessionFactoryHolder.GetSessionFactoryParameters();
|
||||
var dependencies = ShellStateCoordinator.OrderByDependencies(_extensionManager.AvailableExtensions()
|
||||
.SelectMany(ext => ext.Features))
|
||||
.Where(f => String.Equals(f.Name, feature, StringComparison.OrdinalIgnoreCase))
|
||||
.Where(f => f.Dependencies != null)
|
||||
.SelectMany(f => f.Dependencies)
|
||||
.ToList();
|
||||
|
||||
if (!parameters.RecordDescriptors.Any()) {
|
||||
var shellDescriptor = new ShellDescriptor {
|
||||
Features = dependencies.Select(name => new ShellFeature { Name = name }).Union(new[] { new ShellFeature { Name = feature }, new ShellFeature { Name = "Orchard.Framework" } })
|
||||
};
|
||||
|
||||
var shellBlueprint = _compositionStrategy.Compose(_shellSettings, shellDescriptor);
|
||||
|
||||
if ( !shellBlueprint.Records.Any() ) {
|
||||
yield break;
|
||||
}
|
||||
|
||||
var configuration = _sessionFactoryHolder.GetConfiguration();
|
||||
//var features = dependencies.Select(name => new ShellFeature {Name = name}).Union(new[] {new ShellFeature {Name = feature}, new ShellFeature {Name = "Orchard.Framework"}});
|
||||
|
||||
var parameters = _sessionFactoryHolder.GetSessionFactoryParameters();
|
||||
parameters.RecordDescriptors = shellBlueprint.Records;
|
||||
|
||||
var configuration = _dataServicesProviderFactory
|
||||
.CreateProvider(parameters)
|
||||
.BuildConfiguration(parameters);
|
||||
|
||||
Dialect.GetDialect(configuration.Properties);
|
||||
var mapping = configuration.BuildMapping();
|
||||
|
||||
|
@@ -45,7 +45,7 @@ namespace Orchard.Environment.Extensions {
|
||||
|
||||
public IEnumerable<Feature> LoadFeatures(IEnumerable<FeatureDescriptor> featureDescriptors) {
|
||||
return featureDescriptors
|
||||
.Select(featureDescriptor => LoadFeature(featureDescriptor))
|
||||
.Select(LoadFeature)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user