mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 03:25:23 +08:00
Data migration for developers
- NHibernate auto-update is explicitly run by the user (dev) through a DevTool Controller Action or Command - Generate the create method from the nhib schema --HG-- branch : dev
This commit is contained in:
@@ -12,7 +12,7 @@ namespace Orchard.Specs.Hosting {
|
|||||||
class TraceEnabledBuilder : SQLiteDataServicesProvider {
|
class TraceEnabledBuilder : SQLiteDataServicesProvider {
|
||||||
public TraceEnabledBuilder(string dataFolder, string connectionString) : base(dataFolder, connectionString) {
|
public TraceEnabledBuilder(string dataFolder, string connectionString) : base(dataFolder, connectionString) {
|
||||||
}
|
}
|
||||||
protected override IPersistenceConfigurer GetPersistenceConfigurer(bool createDatabase) {
|
public override IPersistenceConfigurer GetPersistenceConfigurer(bool createDatabase) {
|
||||||
var config = (SQLiteConfiguration)base.GetPersistenceConfigurer(createDatabase);
|
var config = (SQLiteConfiguration)base.GetPersistenceConfigurer(createDatabase);
|
||||||
//config.ShowSql();
|
//config.ShowSql();
|
||||||
return config;
|
return config;
|
||||||
|
@@ -64,12 +64,12 @@ namespace Orchard.Tests.Data.Builders {
|
|||||||
var parameters = new SessionFactoryParameters {
|
var parameters = new SessionFactoryParameters {
|
||||||
Provider = "SQLite",
|
Provider = "SQLite",
|
||||||
DataFolder = _tempDataFolder,
|
DataFolder = _tempDataFolder,
|
||||||
UpdateSchema = true,
|
|
||||||
RecordDescriptors = recordDescriptors
|
RecordDescriptors = recordDescriptors
|
||||||
};
|
};
|
||||||
var sessionFactory = manager
|
var sessionFactory = manager
|
||||||
.CreateProvider(parameters)
|
.CreateProvider(parameters)
|
||||||
.BuildSessionFactory(parameters);
|
.BuildConfiguration(parameters)
|
||||||
|
.BuildSessionFactory();
|
||||||
|
|
||||||
|
|
||||||
var session = sessionFactory.OpenSession();
|
var session = sessionFactory.OpenSession();
|
||||||
@@ -102,12 +102,12 @@ namespace Orchard.Tests.Data.Builders {
|
|||||||
Provider = "SqlServer",
|
Provider = "SqlServer",
|
||||||
DataFolder = _tempDataFolder,
|
DataFolder = _tempDataFolder,
|
||||||
ConnectionString = "Data Source=.\\SQLEXPRESS;AttachDbFileName=" + databasePath + ";Integrated Security=True;User Instance=True;",
|
ConnectionString = "Data Source=.\\SQLEXPRESS;AttachDbFileName=" + databasePath + ";Integrated Security=True;User Instance=True;",
|
||||||
UpdateSchema = true,
|
|
||||||
RecordDescriptors = recordDescriptors,
|
RecordDescriptors = recordDescriptors,
|
||||||
};
|
};
|
||||||
var sessionFactory = manager
|
var sessionFactory = manager
|
||||||
.CreateProvider(parameters)
|
.CreateProvider(parameters)
|
||||||
.BuildSessionFactory(parameters);
|
.BuildConfiguration(parameters)
|
||||||
|
.BuildSessionFactory();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@@ -59,7 +59,6 @@ namespace Orchard.Tests.DataMigration {
|
|||||||
builder.RegisterInstance(_folders).As<IExtensionFolders>();
|
builder.RegisterInstance(_folders).As<IExtensionFolders>();
|
||||||
builder.RegisterType<ExtensionManager>().As<IExtensionManager>();
|
builder.RegisterType<ExtensionManager>().As<IExtensionManager>();
|
||||||
builder.RegisterType<DataMigrationManager>().As<IDataMigrationManager>();
|
builder.RegisterType<DataMigrationManager>().As<IDataMigrationManager>();
|
||||||
builder.RegisterType<DefaultDataMigrationGenerator>().As<IDataMigrationGenerator>();
|
|
||||||
builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>));
|
builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>));
|
||||||
_session = _sessionFactory.OpenSession();
|
_session = _sessionFactory.OpenSession();
|
||||||
builder.RegisterInstance(new DefaultContentManagerTests.TestSessionLocator(_session)).As<ISessionLocator>();
|
builder.RegisterInstance(new DefaultContentManagerTests.TestSessionLocator(_session)).As<ISessionLocator>();
|
||||||
|
@@ -3,27 +3,80 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Web.Hosting;
|
using System.Web.Hosting;
|
||||||
using Orchard.Commands;
|
using Orchard.Commands;
|
||||||
|
using Orchard.Data.Migration;
|
||||||
|
using Orchard.Data.Migration.Generator;
|
||||||
|
using Orchard.Data.Migration.Interpreters;
|
||||||
|
using Orchard.DevTools.Services;
|
||||||
using Orchard.Environment.Extensions;
|
using Orchard.Environment.Extensions;
|
||||||
|
|
||||||
namespace Orchard.DevTools.Commands {
|
namespace Orchard.DevTools.Commands {
|
||||||
[OrchardFeature("Scaffolding")]
|
[OrchardFeature("Scaffolding")]
|
||||||
public class ScaffoldingCommands : DefaultOrchardCommandHandler {
|
public class ScaffoldingCommands : DefaultOrchardCommandHandler {
|
||||||
private readonly IExtensionManager _extensionManager;
|
private readonly IExtensionManager _extensionManager;
|
||||||
|
private readonly IDataMigrationManager _dataMigrationManager;
|
||||||
|
private readonly IDataMigrationInterpreter _dataMigrationInterpreter;
|
||||||
|
private readonly ISchemaCommandGenerator _schemaCommandGenerator;
|
||||||
|
|
||||||
public ScaffoldingCommands(IExtensionManager extensionManager) {
|
public ScaffoldingCommands(IExtensionManager extensionManager,
|
||||||
|
IDataMigrationManager dataMigrationManager,
|
||||||
|
IDataMigrationInterpreter dataMigrationInterpreter,
|
||||||
|
ISchemaCommandGenerator schemaCommandGenerator) {
|
||||||
_extensionManager = extensionManager;
|
_extensionManager = extensionManager;
|
||||||
|
_dataMigrationManager = dataMigrationManager;
|
||||||
|
_dataMigrationInterpreter = dataMigrationInterpreter;
|
||||||
|
_schemaCommandGenerator = schemaCommandGenerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
[OrchardSwitch]
|
[OrchardSwitch]
|
||||||
public bool IncludeInSolution { get; set; }
|
public bool IncludeInSolution { get; set; }
|
||||||
|
|
||||||
|
[CommandHelp("scaffolding create datamigration <feature-name> \r\n\t" + "Create a new Data Migration class")]
|
||||||
|
[CommandName("scaffolding create datamigration")]
|
||||||
|
public void CreateDataMigration(string featureName) {
|
||||||
|
Context.Output.WriteLine(T("Creating Data Migration for {0}", featureName));
|
||||||
|
|
||||||
|
foreach ( var extension in _extensionManager.AvailableExtensions() ) {
|
||||||
|
if ( extension.ExtensionType == "Module" && extension.Features.Any(f => String.Equals(f.Name, featureName, StringComparison.OrdinalIgnoreCase)) ) {
|
||||||
|
string dataMigrationsPath = HostingEnvironment.MapPath("~/Modules/" + extension.Name + "/DataMigrations/");
|
||||||
|
string dataMigrationPath = dataMigrationsPath + extension.DisplayName + "DataMigration.cs";
|
||||||
|
string templatesPath = HostingEnvironment.MapPath("~/Modules/Orchard.DevTools/ScaffoldingTemplates/");
|
||||||
|
if ( !Directory.Exists(dataMigrationsPath) ) {
|
||||||
|
Directory.CreateDirectory(dataMigrationsPath);
|
||||||
|
}
|
||||||
|
if ( File.Exists(dataMigrationPath) ) {
|
||||||
|
Context.Output.WriteLine(T("Data migration already exists in target Module {0}.", extension.Name));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var commands = _schemaCommandGenerator.GetCreateFeatureCommands(featureName, false).ToList();
|
||||||
|
|
||||||
|
var stringWriter = new StringWriter();
|
||||||
|
var interpreter = new ScaffoldingCommandInterpreter(stringWriter);
|
||||||
|
|
||||||
|
foreach ( var command in commands ) {
|
||||||
|
interpreter.Visit(command);
|
||||||
|
stringWriter.WriteLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
string dataMigrationText = File.ReadAllText(templatesPath + "DataMigration.txt");
|
||||||
|
dataMigrationText = dataMigrationText.Replace("$$FeatureName$$", featureName);
|
||||||
|
dataMigrationText = dataMigrationText.Replace("$$ClassName$$", extension.DisplayName);
|
||||||
|
dataMigrationText = dataMigrationText.Replace("$$Commands$$", stringWriter.ToString());
|
||||||
|
File.WriteAllText(dataMigrationPath, dataMigrationText);
|
||||||
|
Context.Output.WriteLine(T("Data migration created successfully in Module {0}", extension.DisplayName));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Context.Output.WriteLine(T("Creating data migration failed: target Feature {0} could not be found.", featureName));
|
||||||
|
}
|
||||||
|
|
||||||
[CommandHelp("scaffolding create module <module-name> [/IncludeInSolution:true|false]\r\n\t" + "Create a new Orchard module")]
|
[CommandHelp("scaffolding create module <module-name> [/IncludeInSolution:true|false]\r\n\t" + "Create a new Orchard module")]
|
||||||
[CommandName("scaffolding create module")]
|
[CommandName("scaffolding create module")]
|
||||||
[OrchardSwitches("IncludeInSolution")]
|
[OrchardSwitches("IncludeInSolution")]
|
||||||
public void CreateModule(string moduleName) {
|
public void CreateModule(string moduleName) {
|
||||||
Context.Output.WriteLine(T("Creating Module {0}", moduleName));
|
Context.Output.WriteLine(T("Creating Module {0}", moduleName));
|
||||||
|
|
||||||
if (_extensionManager.AvailableExtensions().Any(extension => extension.ExtensionType == "Module" && String.Equals(moduleName, extension.DisplayName, StringComparison.OrdinalIgnoreCase))) {
|
if ( _extensionManager.AvailableExtensions().Any(extension => extension.ExtensionType == "Module" && String.Equals(moduleName, extension.DisplayName, StringComparison.OrdinalIgnoreCase)) ) {
|
||||||
Context.Output.WriteLine(T("Creating Module {0} failed: a module of the same name already exists", moduleName));
|
Context.Output.WriteLine(T("Creating Module {0} failed: a module of the same name already exists", moduleName));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,23 @@
|
|||||||
|
using System.Web.Mvc;
|
||||||
|
using Orchard.Data.Migration.Generator;
|
||||||
|
using Orchard.DevTools.ViewModels;
|
||||||
|
|
||||||
|
namespace Orchard.DevTools.Controllers {
|
||||||
|
[ValidateInput(false)]
|
||||||
|
public class DataMigrationController : Controller {
|
||||||
|
private readonly ISchemaCommandGenerator _schemaCommandGenerator;
|
||||||
|
|
||||||
|
public DataMigrationController(ISchemaCommandGenerator schemaCommandGenerator) {
|
||||||
|
_schemaCommandGenerator = schemaCommandGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionResult Index() {
|
||||||
|
var model = new DataMigrationIndexViewModel ();
|
||||||
|
|
||||||
|
_schemaCommandGenerator.UpdateDatabase();
|
||||||
|
|
||||||
|
return View(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -73,6 +73,7 @@
|
|||||||
<Compile Include="Commands\ProfilingCommands.cs" />
|
<Compile Include="Commands\ProfilingCommands.cs" />
|
||||||
<Compile Include="Commands\ScaffoldingCommands.cs" />
|
<Compile Include="Commands\ScaffoldingCommands.cs" />
|
||||||
<Compile Include="Controllers\ContentController.cs" />
|
<Compile Include="Controllers\ContentController.cs" />
|
||||||
|
<Compile Include="Controllers\DataMigrationController.cs" />
|
||||||
<Compile Include="Controllers\HomeController.cs" />
|
<Compile Include="Controllers\HomeController.cs" />
|
||||||
<Compile Include="Controllers\MetadataController.cs" />
|
<Compile Include="Controllers\MetadataController.cs" />
|
||||||
<Compile Include="Handlers\DebugLinkHandler.cs" />
|
<Compile Include="Handlers\DebugLinkHandler.cs" />
|
||||||
@@ -80,9 +81,12 @@
|
|||||||
<Compile Include="Models\Simple.cs" />
|
<Compile Include="Models\Simple.cs" />
|
||||||
<Compile Include="Permissions.cs" />
|
<Compile Include="Permissions.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Content Include="ScaffoldingTemplates\DataMigration.txt" />
|
||||||
|
<Compile Include="Services\ScaffoldingCommandInterpreter.cs" />
|
||||||
<Compile Include="Settings\DevToolsSettings.cs" />
|
<Compile Include="Settings\DevToolsSettings.cs" />
|
||||||
<Compile Include="ViewModels\ContentIndexViewModel.cs" />
|
<Compile Include="ViewModels\ContentIndexViewModel.cs" />
|
||||||
<Compile Include="ViewModels\ContentDetailsViewModel.cs" />
|
<Compile Include="ViewModels\ContentDetailsViewModel.cs" />
|
||||||
|
<Compile Include="ViewModels\DataMigrationIndexViewModel.cs" />
|
||||||
<Compile Include="ViewModels\MetadataIndexViewModel.cs" />
|
<Compile Include="ViewModels\MetadataIndexViewModel.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -92,6 +96,7 @@
|
|||||||
<Content Include="ScaffoldingTemplates\ModuleCsProj.txt" />
|
<Content Include="ScaffoldingTemplates\ModuleCsProj.txt" />
|
||||||
<Content Include="ScaffoldingTemplates\ModuleManifest.txt" />
|
<Content Include="ScaffoldingTemplates\ModuleManifest.txt" />
|
||||||
<Content Include="ScaffoldingTemplates\ModuleWebConfig.txt" />
|
<Content Include="ScaffoldingTemplates\ModuleWebConfig.txt" />
|
||||||
|
<Content Include="Views\DataMigration\Index.aspx" />
|
||||||
<Content Include="Views\DefinitionTemplates\DevToolsSettings.ascx" />
|
<Content Include="Views\DefinitionTemplates\DevToolsSettings.ascx" />
|
||||||
<Content Include="Views\Home\_RenderableAction.ascx" />
|
<Content Include="Views\Home\_RenderableAction.ascx" />
|
||||||
<Content Include="Views\Home\Simple.aspx" />
|
<Content Include="Views\Home\Simple.aspx" />
|
||||||
|
@@ -0,0 +1,13 @@
|
|||||||
|
using System.Data;
|
||||||
|
using Orchard.Data.Migration;
|
||||||
|
|
||||||
|
namespace $$FeatureName$$.DataMigrations {
|
||||||
|
public class $$ClassName$$DataMigration : DataMigrationImpl {
|
||||||
|
|
||||||
|
public int Create() {
|
||||||
|
$$Commands$$
|
||||||
|
|
||||||
|
return 0100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,78 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using Orchard.Data.Migration.Interpreters;
|
||||||
|
using Orchard.Data.Migration.Schema;
|
||||||
|
|
||||||
|
namespace Orchard.DevTools.Services {
|
||||||
|
public class ScaffoldingCommandInterpreter : AbstractDataMigrationInterpreter {
|
||||||
|
private readonly TextWriter _output;
|
||||||
|
|
||||||
|
public ScaffoldingCommandInterpreter(TextWriter output) {
|
||||||
|
_output = output;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Visit(CreateTableCommand command) {
|
||||||
|
_output.WriteLine("// Creating table {0}", command.Name);
|
||||||
|
_output.WriteLine("\t\t\tSchemaBuilder.CreateTable(\"{0}\", table => table", command.Name);
|
||||||
|
|
||||||
|
foreach ( var createColumn in command.TableCommands.OfType<CreateColumnCommand>() ) {
|
||||||
|
var type = createColumn.DbType.ToString();
|
||||||
|
var field = createColumn.ColumnName;
|
||||||
|
var options = new List<string>();
|
||||||
|
|
||||||
|
if ( createColumn.IsPrimaryKey ) {
|
||||||
|
options.Add(string.Format("WithLength({0})", createColumn.Length));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( createColumn.IsUnique ) {
|
||||||
|
options.Add("Unique()");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( createColumn.IsNotNull ) {
|
||||||
|
options.Add("NotNull()");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( createColumn.IsPrimaryKey ) {
|
||||||
|
options.Add("PrimaryKey()");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( createColumn.Length.HasValue ) {
|
||||||
|
options.Add(string.Format("WithLength({0})", createColumn.Length ));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( createColumn.Precision > 0 ) {
|
||||||
|
options.Add(string.Format("WithPrecision({0})", createColumn.Precision));
|
||||||
|
options.Add(string.Format("WithScale({0})", createColumn.Scale));
|
||||||
|
}
|
||||||
|
|
||||||
|
_output.WriteLine("\t\t\t\t.Column(\"{0}\", DbType.{1}{2})", field, type, options.Any() ? ", column => column." + string.Join(".", options) : string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
_output.WriteLine("\t\t\t);");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Visit(AlterTableCommand command) {
|
||||||
|
_output.WriteLine("// Altering table {0}", command.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Visit(DropTableCommand command) {
|
||||||
|
_output.WriteLine("// Dropping table {0}", command.Name);
|
||||||
|
_output.WriteLine("\t\t\tSchemaBuilder.DropTable(\"{0}\", command.Name);");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Visit(SqlStatementCommand command) {
|
||||||
|
_output.WriteLine("// Executing sql statement\n\n {0}", command.Sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Visit(CreateForeignKeyCommand command) {
|
||||||
|
_output.WriteLine("// Creating foreign key {0}", command.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Visit(DropForeignKeyCommand command) {
|
||||||
|
_output.WriteLine("// Dropping foreign key {0}", command.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,6 @@
|
|||||||
|
using Orchard.Mvc.ViewModels;
|
||||||
|
|
||||||
|
namespace Orchard.DevTools.ViewModels {
|
||||||
|
public class DataMigrationIndexViewModel : BaseViewModel {
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,9 @@
|
|||||||
|
<%@ Page Language="C#" Inherits="Orchard.Mvc.ViewPage<Orchard.DevTools.ViewModels.DataMigrationIndexViewModel>" %>
|
||||||
|
|
||||||
|
<style title="text/css">
|
||||||
|
ul
|
||||||
|
{
|
||||||
|
margin-left: 12px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<h1>Data Migration</h1>
|
@@ -3,8 +3,6 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Orchard.Commands;
|
using Orchard.Commands;
|
||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
using Orchard.Indexing;
|
|
||||||
using Orchard.Security;
|
|
||||||
using Orchard.Tasks.Indexing;
|
using Orchard.Tasks.Indexing;
|
||||||
|
|
||||||
namespace Orchard.Indexing.Commands {
|
namespace Orchard.Indexing.Commands {
|
||||||
|
@@ -5,7 +5,6 @@ namespace Orchard.Indexing.DataMigrations {
|
|||||||
public class IndexingDataMigration : DataMigrationImpl {
|
public class IndexingDataMigration : DataMigrationImpl {
|
||||||
|
|
||||||
public int Create() {
|
public int Create() {
|
||||||
|
|
||||||
SchemaBuilder.CreateTable("IndexingTaskRecord", table => table
|
SchemaBuilder.CreateTable("IndexingTaskRecord", table => table
|
||||||
.Column<int>("Id", column => column.PrimaryKey())
|
.Column<int>("Id", column => column.PrimaryKey())
|
||||||
.Column<int>("Action")
|
.Column<int>("Action")
|
||||||
|
@@ -64,7 +64,7 @@
|
|||||||
<Compile Include="AdminMenu.cs" />
|
<Compile Include="AdminMenu.cs" />
|
||||||
<Compile Include="Commands\IndexingCommands.cs" />
|
<Compile Include="Commands\IndexingCommands.cs" />
|
||||||
<Compile Include="Controllers\AdminController.cs" />
|
<Compile Include="Controllers\AdminController.cs" />
|
||||||
<Compile Include="DataMigrations\IndexingDataMigration.cs" />
|
<Compile Include="DataMigrations\_IndexingDataMigration.cs" />
|
||||||
<Compile Include="Handlers\CreateIndexingTaskHandler.cs" />
|
<Compile Include="Handlers\CreateIndexingTaskHandler.cs" />
|
||||||
<Compile Include="Models\IndexingTask.cs" />
|
<Compile Include="Models\IndexingTask.cs" />
|
||||||
<Compile Include="Models\IndexingTaskRecord.cs" />
|
<Compile Include="Models\IndexingTaskRecord.cs" />
|
||||||
|
@@ -1,24 +1,33 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using Orchard.Commands;
|
using Orchard.Commands;
|
||||||
|
using Orchard.Data.Migration.Generator;
|
||||||
|
using Orchard.Data.Migration.Interpreters;
|
||||||
|
|
||||||
namespace Orchard.Data.Migration.Commands {
|
namespace Orchard.Data.Migration.Commands {
|
||||||
public class DataMigrationCommands : DefaultOrchardCommandHandler {
|
public class DataMigrationCommands : DefaultOrchardCommandHandler {
|
||||||
private readonly IDataMigrationManager _dataMigrationManager;
|
private readonly IDataMigrationManager _dataMigrationManager;
|
||||||
|
private readonly IDataMigrationInterpreter _dataMigrationInterpreter;
|
||||||
|
private readonly ISchemaCommandGenerator _schemaCommandGenerator;
|
||||||
|
|
||||||
public DataMigrationCommands(
|
public DataMigrationCommands(
|
||||||
IDataMigrationManager dataMigrationManager) {
|
IDataMigrationManager dataMigrationManager,
|
||||||
|
IDataMigrationInterpreter dataMigrationInterpreter,
|
||||||
|
ISchemaCommandGenerator schemaCommandGenerator
|
||||||
|
) {
|
||||||
_dataMigrationManager = dataMigrationManager;
|
_dataMigrationManager = dataMigrationManager;
|
||||||
|
_dataMigrationInterpreter = dataMigrationInterpreter;
|
||||||
|
_schemaCommandGenerator = schemaCommandGenerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
[OrchardSwitch]
|
[OrchardSwitch]
|
||||||
public string Feature { get; set; }
|
public bool Drop { get; set; }
|
||||||
|
|
||||||
[CommandName("upgrade database")]
|
[CommandName("upgrade database")]
|
||||||
[CommandHelp("upgrade database /Feature:<feature> \r\n\t" + "Upgrades or create the database tables for the named <feature>")]
|
[CommandHelp("upgrade database <feature-name> \r\n\t" + "Upgrades or create the database tables for the <feature-name>")]
|
||||||
[OrchardSwitches("Feature")]
|
public string UpgradeDatabase(string featureName) {
|
||||||
public string UpgradeDatabase() {
|
|
||||||
try {
|
try {
|
||||||
_dataMigrationManager.Update(Feature);
|
_dataMigrationManager.Update(featureName);
|
||||||
}
|
}
|
||||||
catch ( Exception ex ) {
|
catch ( Exception ex ) {
|
||||||
Context.Output.WriteLine(T("An error occured while upgrading the database: " + ex.Message));
|
Context.Output.WriteLine(T("An error occured while upgrading the database: " + ex.Message));
|
||||||
@@ -27,5 +36,45 @@ namespace Orchard.Data.Migration.Commands {
|
|||||||
|
|
||||||
return "Database upgraded";
|
return "Database upgraded";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[CommandName("update database")]
|
||||||
|
[CommandHelp("update database \r\n\t" + "Automatically updates the database schema for the enabled features")]
|
||||||
|
public string UpdateDatabase() {
|
||||||
|
try {
|
||||||
|
_schemaCommandGenerator.UpdateDatabase();
|
||||||
|
}
|
||||||
|
catch ( Exception ex ) {
|
||||||
|
Context.Output.WriteLine(T("An error occured while updating the database: " + ex.Message));
|
||||||
|
return "Update terminated.";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Database updated";
|
||||||
|
}
|
||||||
|
|
||||||
|
[CommandName("create tables")]
|
||||||
|
[CommandHelp("create tables <feature-name> [/Drop:true|false] \r\n\t" + "Creates the database tables for the <feature-name> and optionaly drops them before if specified")]
|
||||||
|
[OrchardSwitches("Drop")]
|
||||||
|
public string CreateTables(string featureName) {
|
||||||
|
var stringInterpreter = new StringCommandInterpreter(Context.Output);
|
||||||
|
try {
|
||||||
|
var commands = _schemaCommandGenerator.GetCreateFeatureCommands(featureName, Drop).ToList();
|
||||||
|
if ( commands.Any() ) {
|
||||||
|
|
||||||
|
foreach (var command in commands) {
|
||||||
|
stringInterpreter.Visit(command);
|
||||||
|
_dataMigrationInterpreter.Visit(command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return "There are no tables to create for this feature.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( Exception ex ) {
|
||||||
|
Context.Output.WriteLine(T("An error occured while creating the tables: " + ex.Message));
|
||||||
|
return "Tables creation terminated.";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Tables created";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -3,10 +3,15 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using FluentNHibernate.Cfg;
|
||||||
|
using NHibernate.Tool.hbm2ddl;
|
||||||
|
using Orchard.Data.Migration.Generator;
|
||||||
using Orchard.Data.Migration.Interpreters;
|
using Orchard.Data.Migration.Interpreters;
|
||||||
using Orchard.Data.Migration.Records;
|
using Orchard.Data.Migration.Records;
|
||||||
using Orchard.Data.Migration.Schema;
|
using Orchard.Data.Migration.Schema;
|
||||||
|
using Orchard.Data.Providers;
|
||||||
using Orchard.Environment.Extensions;
|
using Orchard.Environment.Extensions;
|
||||||
|
using Orchard.Environment.ShellBuilders.Models;
|
||||||
using Orchard.Environment.State;
|
using Orchard.Environment.State;
|
||||||
using Orchard.Logging;
|
using Orchard.Logging;
|
||||||
|
|
||||||
@@ -19,16 +24,21 @@ namespace Orchard.Data.Migration {
|
|||||||
private readonly IRepository<DataMigrationRecord> _dataMigrationRepository;
|
private readonly IRepository<DataMigrationRecord> _dataMigrationRepository;
|
||||||
private readonly IExtensionManager _extensionManager;
|
private readonly IExtensionManager _extensionManager;
|
||||||
private readonly IDataMigrationInterpreter _interpreter;
|
private readonly IDataMigrationInterpreter _interpreter;
|
||||||
|
private readonly ISchemaCommandGenerator _generator;
|
||||||
|
|
||||||
public DataMigrationManager(
|
public DataMigrationManager(
|
||||||
IEnumerable<IDataMigration> dataMigrations,
|
IEnumerable<IDataMigration> dataMigrations,
|
||||||
IRepository<DataMigrationRecord> dataMigrationRepository,
|
IRepository<DataMigrationRecord> dataMigrationRepository,
|
||||||
IExtensionManager extensionManager,
|
IExtensionManager extensionManager,
|
||||||
IDataMigrationInterpreter interpreter) {
|
IDataMigrationInterpreter interpreter,
|
||||||
|
ISchemaCommandGenerator generator
|
||||||
|
) {
|
||||||
_dataMigrations = dataMigrations;
|
_dataMigrations = dataMigrations;
|
||||||
_dataMigrationRepository = dataMigrationRepository;
|
_dataMigrationRepository = dataMigrationRepository;
|
||||||
_extensionManager = extensionManager;
|
_extensionManager = extensionManager;
|
||||||
_interpreter = interpreter;
|
_interpreter = interpreter;
|
||||||
|
_generator = generator;
|
||||||
|
|
||||||
Logger = NullLogger.Instance;
|
Logger = NullLogger.Instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +103,7 @@ namespace Orchard.Data.Migration {
|
|||||||
|
|
||||||
var migrations = GetDataMigrations(feature);
|
var migrations = GetDataMigrations(feature);
|
||||||
|
|
||||||
// apply update methods to each migration class for the module
|
// apply update methods to each migration class for the module))))
|
||||||
foreach ( var migration in migrations ) {
|
foreach ( var migration in migrations ) {
|
||||||
// copy the objet for the Linq query
|
// copy the objet for the Linq query
|
||||||
var tempMigration = migration;
|
var tempMigration = migration;
|
||||||
@@ -149,7 +159,7 @@ namespace Orchard.Data.Migration {
|
|||||||
|
|
||||||
// apply update methods to each migration class for the module
|
// apply update methods to each migration class for the module
|
||||||
foreach (var migration in migrations) {
|
foreach (var migration in migrations) {
|
||||||
// copy the objet for the Linq query
|
// copy the object for the Linq query
|
||||||
var tempMigration = migration;
|
var tempMigration = migration;
|
||||||
|
|
||||||
// get current version for this migration
|
// get current version for this migration
|
||||||
|
@@ -1,14 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Orchard.Data.Migration.Schema;
|
|
||||||
using Orchard.Environment.ShellBuilders.Models;
|
|
||||||
|
|
||||||
namespace Orchard.Data.Migration {
|
|
||||||
public class DefaultDataMigrationGenerator : IDataMigrationGenerator {
|
|
||||||
public IEnumerable<ISchemaBuilderCommand> CreateCommands(IEnumerable<RecordBlueprint> records) {
|
|
||||||
|
|
||||||
|
|
||||||
return Enumerable.Empty<ISchemaBuilderCommand>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -0,0 +1,24 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Orchard.Data.Migration.Schema;
|
||||||
|
|
||||||
|
namespace Orchard.Data.Migration.Generator {
|
||||||
|
public interface ISchemaCommandGenerator : IDependency {
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a set of <see cref="SchemaCommand"/> instances to execute in order to create the tables requiered by the specified feature.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="feature">The name of the feature from which the tables need to be created.</param>
|
||||||
|
/// <param name="drop">Whether to generate drop commands for the created tables.</param>
|
||||||
|
IEnumerable<SchemaCommand> GetCreateFeatureCommands(string feature, bool drop);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Automatically updates the tables in the database.
|
||||||
|
/// </summary>
|
||||||
|
void UpdateDatabase();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates the tables in the database.
|
||||||
|
/// </summary>
|
||||||
|
void CreateDatabase();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,97 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using NHibernate.Cfg;
|
||||||
|
using NHibernate.Mapping;
|
||||||
|
using NHibernate.Tool.hbm2ddl;
|
||||||
|
using Orchard.Data.Migration.Schema;
|
||||||
|
using Orchard.Data.Providers;
|
||||||
|
using NHibernate.Dialect;
|
||||||
|
using Orchard.Environment.Extensions;
|
||||||
|
|
||||||
|
namespace Orchard.Data.Migration.Generator {
|
||||||
|
public class SchemaCommandGenerator : ISchemaCommandGenerator {
|
||||||
|
private readonly IDataServicesProviderFactory _dataServicesProviderFactory;
|
||||||
|
private readonly ISessionFactoryHolder _sessionFactoryHolder;
|
||||||
|
|
||||||
|
public SchemaCommandGenerator(
|
||||||
|
IDataServicesProviderFactory dataServicesProviderFactory,
|
||||||
|
ISessionFactoryHolder sessionFactoryHolder) {
|
||||||
|
_dataServicesProviderFactory = dataServicesProviderFactory;
|
||||||
|
_sessionFactoryHolder = sessionFactoryHolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<SchemaCommand> GetCreateFeatureCommands(string feature, bool drop) {
|
||||||
|
var parameters = _sessionFactoryHolder.GetSessionFactoryParameters();
|
||||||
|
|
||||||
|
if (!parameters.RecordDescriptors.Any()) {
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var configuration = _dataServicesProviderFactory.CreateProvider(parameters).BuildConfiguration(parameters);
|
||||||
|
var dialect = Dialect.GetDialect(configuration.Properties);
|
||||||
|
var mapping = configuration.BuildMapping();
|
||||||
|
|
||||||
|
// get the tables using reflection
|
||||||
|
var tablesField = typeof(Configuration).GetField("tables", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
var tables = ((IDictionary<string, Table>) tablesField.GetValue(configuration)).Values;
|
||||||
|
|
||||||
|
|
||||||
|
foreach(var table in tables.Where(t => parameters.RecordDescriptors.Any(rd => rd.Feature.Descriptor.Name == feature && rd.TableName == t.Name))) {
|
||||||
|
if(drop) {
|
||||||
|
yield return new DropTableCommand(table.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
var command = new CreateTableCommand(table.Name);
|
||||||
|
|
||||||
|
foreach(var column in table.ColumnIterator) {
|
||||||
|
var table1 = table;
|
||||||
|
var column1 = column;
|
||||||
|
var sqlType = column1.GetSqlTypeCode(mapping);
|
||||||
|
command.Column(column.Name, sqlType.DbType,
|
||||||
|
action => {
|
||||||
|
if (table1.PrimaryKey.Columns.Any(c => c.Name == column1.Name)) {
|
||||||
|
action.PrimaryKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (column1.IsLengthDefined()) {
|
||||||
|
action.WithLength(column1.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (column1.IsPrecisionDefined()) {
|
||||||
|
action.WithPrecision((byte) column1.Precision);
|
||||||
|
action.WithScale((byte) column1.Scale);
|
||||||
|
}
|
||||||
|
if (column1.IsNullable) {
|
||||||
|
action.Nullable();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( column1.IsUnique ) {
|
||||||
|
action.Unique();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(column1.DefaultValue != null) {
|
||||||
|
action.WithDefault(column1.DefaultValue);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
yield return command;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateDatabase() {
|
||||||
|
var parameters = _sessionFactoryHolder.GetSessionFactoryParameters();
|
||||||
|
var configuration = _dataServicesProviderFactory.CreateProvider(parameters).BuildConfiguration(parameters);
|
||||||
|
new SchemaUpdate(configuration).Execute(false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CreateDatabase() {
|
||||||
|
var parameters = _sessionFactoryHolder.GetSessionFactoryParameters();
|
||||||
|
var configuration = _dataServicesProviderFactory.CreateProvider(parameters).BuildConfiguration(parameters);
|
||||||
|
new SchemaExport(configuration).Execute(false, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -1,11 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using FluentNHibernate.Cfg;
|
|
||||||
using Orchard.Data.Migration.Schema;
|
|
||||||
using Orchard.Environment.ShellBuilders.Models;
|
|
||||||
|
|
||||||
namespace Orchard.Data.Migration {
|
|
||||||
// Builds and runs the representative migration create calls
|
|
||||||
public interface IDataMigrationGenerator : IDependency {
|
|
||||||
IEnumerable<ISchemaBuilderCommand> CreateCommands(IEnumerable<RecordBlueprint> records);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -0,0 +1,41 @@
|
|||||||
|
using Orchard.Data.Migration.Schema;
|
||||||
|
|
||||||
|
namespace Orchard.Data.Migration.Interpreters {
|
||||||
|
public abstract class AbstractDataMigrationInterpreter {
|
||||||
|
|
||||||
|
public void Visit(ISchemaBuilderCommand command) {
|
||||||
|
var schemaCommand = command as SchemaCommand;
|
||||||
|
if (schemaCommand == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ( schemaCommand.Type ) {
|
||||||
|
case SchemaCommandType.CreateTable:
|
||||||
|
Visit((CreateTableCommand)schemaCommand);
|
||||||
|
break;
|
||||||
|
case SchemaCommandType.AlterTable:
|
||||||
|
Visit((AlterTableCommand)schemaCommand);
|
||||||
|
break;
|
||||||
|
case SchemaCommandType.DropTable:
|
||||||
|
Visit((DropTableCommand)schemaCommand);
|
||||||
|
break;
|
||||||
|
case SchemaCommandType.SqlStatement:
|
||||||
|
Visit((SqlStatementCommand)schemaCommand);
|
||||||
|
break;
|
||||||
|
case SchemaCommandType.CreateForeignKey:
|
||||||
|
Visit((CreateForeignKeyCommand)schemaCommand);
|
||||||
|
break;
|
||||||
|
case SchemaCommandType.DropForeignKey:
|
||||||
|
Visit((DropForeignKeyCommand)schemaCommand);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void Visit(CreateTableCommand command);
|
||||||
|
public abstract void Visit(AlterTableCommand command);
|
||||||
|
public abstract void Visit(DropTableCommand command);
|
||||||
|
public abstract void Visit(SqlStatementCommand command);
|
||||||
|
public abstract void Visit(CreateForeignKeyCommand command);
|
||||||
|
public abstract void Visit(DropForeignKeyCommand command);
|
||||||
|
}
|
||||||
|
}
|
@@ -7,25 +7,40 @@ using NHibernate;
|
|||||||
using NHibernate.Dialect;
|
using NHibernate.Dialect;
|
||||||
using NHibernate.SqlTypes;
|
using NHibernate.SqlTypes;
|
||||||
using Orchard.Data.Migration.Schema;
|
using Orchard.Data.Migration.Schema;
|
||||||
|
using Orchard.Data.Providers;
|
||||||
using Orchard.Environment.Configuration;
|
using Orchard.Environment.Configuration;
|
||||||
using Orchard.Logging;
|
using Orchard.Logging;
|
||||||
|
|
||||||
namespace Orchard.Data.Migration.Interpreters {
|
namespace Orchard.Data.Migration.Interpreters {
|
||||||
public class DefaultDataMigrationInterpreter : IDataMigrationInterpreter {
|
public class DefaultDataMigrationInterpreter : AbstractDataMigrationInterpreter, IDataMigrationInterpreter {
|
||||||
private readonly ShellSettings _shellSettings;
|
private readonly ShellSettings _shellSettings;
|
||||||
private readonly IEnumerable<ICommandInterpreter> _commandInterpreters;
|
private readonly IEnumerable<ICommandInterpreter> _commandInterpreters;
|
||||||
private readonly ISession _session;
|
private readonly ISession _session;
|
||||||
private readonly Dialect _dialect;
|
private readonly Dialect _dialect;
|
||||||
private readonly List<string> _sqlStatements;
|
private readonly List<string> _sqlStatements;
|
||||||
|
private readonly IDataServicesProviderFactory _dataServicesProviderFactory;
|
||||||
|
private readonly ISessionFactoryHolder _sessionFactoryHolder;
|
||||||
|
|
||||||
private const char Space = ' ' ;
|
private const char Space = ' ' ;
|
||||||
|
|
||||||
public DefaultDataMigrationInterpreter(ShellSettings shellSettings, ISessionLocator sessionLocator, IEnumerable<ICommandInterpreter> commandInterpreters) {
|
public DefaultDataMigrationInterpreter(
|
||||||
|
ShellSettings shellSettings,
|
||||||
|
ISessionLocator sessionLocator,
|
||||||
|
IEnumerable<ICommandInterpreter> commandInterpreters,
|
||||||
|
IDataServicesProviderFactory dataServicesProviderFactory,
|
||||||
|
ISessionFactoryHolder sessionFactoryHolder) {
|
||||||
_shellSettings = shellSettings;
|
_shellSettings = shellSettings;
|
||||||
_commandInterpreters = commandInterpreters;
|
_commandInterpreters = commandInterpreters;
|
||||||
_session = sessionLocator.For(typeof(DefaultDataMigrationInterpreter));
|
_session = sessionLocator.For(typeof(DefaultDataMigrationInterpreter));
|
||||||
_sqlStatements = new List<string>();
|
_sqlStatements = new List<string>();
|
||||||
_dialect = _shellSettings.DataProvider == "SQLite" ? (Dialect) new SQLiteDialect() : new MsSql2008Dialect();
|
_dataServicesProviderFactory = dataServicesProviderFactory;
|
||||||
|
_sessionFactoryHolder = sessionFactoryHolder;
|
||||||
|
|
||||||
Logger = NullLogger.Instance;
|
Logger = NullLogger.Instance;
|
||||||
|
|
||||||
|
var parameters = _sessionFactoryHolder.GetSessionFactoryParameters();
|
||||||
|
var configuration = _dataServicesProviderFactory.CreateProvider(parameters).BuildConfiguration(parameters);
|
||||||
|
_dialect = Dialect.GetDialect(configuration.Properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ILogger Logger { get; set; }
|
public ILogger Logger { get; set; }
|
||||||
@@ -34,35 +49,7 @@ namespace Orchard.Data.Migration.Interpreters {
|
|||||||
get { return _sqlStatements; }
|
get { return _sqlStatements; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Visit(ISchemaBuilderCommand command) {
|
public override void Visit(CreateTableCommand command) {
|
||||||
var schemaCommand = command as SchemaCommand;
|
|
||||||
if (schemaCommand == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ( schemaCommand.Type ) {
|
|
||||||
case SchemaCommandType.CreateTable:
|
|
||||||
Visit((CreateTableCommand)schemaCommand);
|
|
||||||
break;
|
|
||||||
case SchemaCommandType.AlterTable:
|
|
||||||
Visit((AlterTableCommand)schemaCommand);
|
|
||||||
break;
|
|
||||||
case SchemaCommandType.DropTable:
|
|
||||||
Visit((DropTableCommand)schemaCommand);
|
|
||||||
break;
|
|
||||||
case SchemaCommandType.SqlStatement:
|
|
||||||
Visit((SqlStatementCommand)schemaCommand);
|
|
||||||
break;
|
|
||||||
case SchemaCommandType.CreateForeignKey:
|
|
||||||
Visit((CreateForeignKeyCommand)schemaCommand);
|
|
||||||
break;
|
|
||||||
case SchemaCommandType.DropForeignKey:
|
|
||||||
Visit((DropForeignKeyCommand)schemaCommand);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Visit(CreateTableCommand command) {
|
|
||||||
|
|
||||||
if ( ExecuteCustomInterpreter(command) ) {
|
if ( ExecuteCustomInterpreter(command) ) {
|
||||||
return;
|
return;
|
||||||
@@ -103,7 +90,7 @@ namespace Orchard.Data.Migration.Interpreters {
|
|||||||
RunPendingStatements();
|
RunPendingStatements();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Visit(DropTableCommand command) {
|
public override void Visit(DropTableCommand command) {
|
||||||
if ( ExecuteCustomInterpreter(command) ) {
|
if ( ExecuteCustomInterpreter(command) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -116,7 +103,7 @@ namespace Orchard.Data.Migration.Interpreters {
|
|||||||
RunPendingStatements();
|
RunPendingStatements();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Visit(AlterTableCommand command) {
|
public override void Visit(AlterTableCommand command) {
|
||||||
if ( ExecuteCustomInterpreter(command) ) {
|
if ( ExecuteCustomInterpreter(command) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -229,18 +216,21 @@ namespace Orchard.Data.Migration.Interpreters {
|
|||||||
_dialect.QuoteForColumnName(command.IndexName));
|
_dialect.QuoteForColumnName(command.IndexName));
|
||||||
_sqlStatements.Add(builder.ToString());
|
_sqlStatements.Add(builder.ToString());
|
||||||
}
|
}
|
||||||
public void Visit(SqlStatementCommand command) {
|
|
||||||
if (command.Providers.Count == 0 || command.Providers.Contains(_shellSettings.DataProvider) ) {
|
|
||||||
if (ExecuteCustomInterpreter(command)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_sqlStatements.Add(command.Sql);
|
|
||||||
|
|
||||||
RunPendingStatements();
|
public override void Visit(SqlStatementCommand command) {
|
||||||
|
if (command.Providers.Count != 0 && !command.Providers.Contains(_shellSettings.DataProvider)) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ExecuteCustomInterpreter(command)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_sqlStatements.Add(command.Sql);
|
||||||
|
|
||||||
|
RunPendingStatements();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Visit(CreateForeignKeyCommand command) {
|
public override void Visit(CreateForeignKeyCommand command) {
|
||||||
if ( ExecuteCustomInterpreter(command) ) {
|
if ( ExecuteCustomInterpreter(command) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -261,7 +251,7 @@ namespace Orchard.Data.Migration.Interpreters {
|
|||||||
RunPendingStatements();
|
RunPendingStatements();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Visit(DropForeignKeyCommand command) {
|
public override void Visit(DropForeignKeyCommand command) {
|
||||||
if ( ExecuteCustomInterpreter(command) ) {
|
if ( ExecuteCustomInterpreter(command) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,36 @@
|
|||||||
|
using System.IO;
|
||||||
|
using Orchard.Data.Migration.Schema;
|
||||||
|
|
||||||
|
namespace Orchard.Data.Migration.Interpreters {
|
||||||
|
public class StringCommandInterpreter : AbstractDataMigrationInterpreter {
|
||||||
|
private readonly TextWriter _output;
|
||||||
|
|
||||||
|
public StringCommandInterpreter(TextWriter output) {
|
||||||
|
_output = output;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Visit(CreateTableCommand command) {
|
||||||
|
_output.WriteLine("Creating table {0}", command.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Visit(AlterTableCommand command) {
|
||||||
|
_output.WriteLine("Altering table {0}", command.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Visit(DropTableCommand command) {
|
||||||
|
_output.WriteLine("Dropping table {0}", command.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Visit(SqlStatementCommand command) {
|
||||||
|
_output.WriteLine("Executing sql statement\n\n {0}", command.Sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Visit(CreateForeignKeyCommand command) {
|
||||||
|
_output.WriteLine("Creating foreign key {0}", command.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Visit(DropForeignKeyCommand command) {
|
||||||
|
_output.WriteLine("Dropping foreign key {0}", command.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -19,25 +19,7 @@ namespace Orchard.Data.Migration.Schema {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public CreateTableCommand Column<T>(string columnName, Action<CreateColumnCommand> column = null) {
|
public CreateTableCommand Column<T>(string columnName, Action<CreateColumnCommand> column = null) {
|
||||||
var dbType = System.Data.DbType.Object;
|
var dbType = SchemaUtils.ToDbType(typeof (T));
|
||||||
switch(System.Type.GetTypeCode(typeof(T))) {
|
|
||||||
case TypeCode.String :
|
|
||||||
dbType = DbType.String;
|
|
||||||
break;
|
|
||||||
case TypeCode.Int32:
|
|
||||||
dbType = DbType.Int32;
|
|
||||||
break;
|
|
||||||
case TypeCode.DateTime:
|
|
||||||
dbType = DbType.DateTime;
|
|
||||||
break;
|
|
||||||
case TypeCode.Boolean:
|
|
||||||
dbType = DbType.Boolean;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Enum.TryParse(System.Type.GetTypeCode(typeof (T)).ToString(), true, out dbType);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Column(columnName, dbType, column);
|
return Column(columnName, dbType, column);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,5 +32,7 @@ namespace Orchard.Data.Migration.Schema {
|
|||||||
/// TODO: Call Column() with necessary information for content part records
|
/// TODO: Call Column() with necessary information for content part records
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
30
src/Orchard/Data/Migration/Schema/SchemaUtils.cs
Normal file
30
src/Orchard/Data/Migration/Schema/SchemaUtils.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using System;
|
||||||
|
using System.Data;
|
||||||
|
|
||||||
|
namespace Orchard.Data.Migration.Schema {
|
||||||
|
public static class SchemaUtils {
|
||||||
|
public static DbType ToDbType(Type type) {
|
||||||
|
DbType dbType;
|
||||||
|
switch ( System.Type.GetTypeCode(type) ) {
|
||||||
|
case TypeCode.String:
|
||||||
|
dbType = DbType.String;
|
||||||
|
break;
|
||||||
|
case TypeCode.Int32:
|
||||||
|
dbType = DbType.Int32;
|
||||||
|
break;
|
||||||
|
case TypeCode.DateTime:
|
||||||
|
dbType = DbType.DateTime;
|
||||||
|
break;
|
||||||
|
case TypeCode.Boolean:
|
||||||
|
dbType = DbType.Boolean;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Enum.TryParse(Type.GetTypeCode(type).ToString(), true, out dbType);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dbType;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -16,30 +16,16 @@ using Orchard.Environment.ShellBuilders.Models;
|
|||||||
namespace Orchard.Data.Providers {
|
namespace Orchard.Data.Providers {
|
||||||
public abstract class AbstractDataServicesProvider : IDataServicesProvider {
|
public abstract class AbstractDataServicesProvider : IDataServicesProvider {
|
||||||
|
|
||||||
protected abstract IPersistenceConfigurer GetPersistenceConfigurer(bool createDatabase);
|
public abstract IPersistenceConfigurer GetPersistenceConfigurer(bool createDatabase);
|
||||||
|
|
||||||
public ISessionFactory BuildSessionFactory(SessionFactoryParameters parameters) {
|
public Configuration BuildConfiguration(SessionFactoryParameters parameters) {
|
||||||
var database = GetPersistenceConfigurer(parameters.CreateDatabase);
|
var database = GetPersistenceConfigurer(parameters.CreateDatabase);
|
||||||
var persistenceModel = CreatePersistenceModel(parameters.RecordDescriptors);
|
var persistenceModel = CreatePersistenceModel(parameters.RecordDescriptors);
|
||||||
|
|
||||||
var sessionFactory = Fluently.Configure()
|
return Fluently.Configure()
|
||||||
.Database(database)
|
.Database(database)
|
||||||
.Mappings(m => m.AutoMappings.Add(persistenceModel))
|
.Mappings(m => m.AutoMappings.Add(persistenceModel))
|
||||||
.ExposeConfiguration(config => Initialization(parameters, config))
|
.BuildConfiguration();
|
||||||
.BuildSessionFactory();
|
|
||||||
|
|
||||||
return sessionFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void Initialization(SessionFactoryParameters parameters, Configuration configuration) {
|
|
||||||
if (parameters.CreateDatabase) {
|
|
||||||
var export = new SchemaExport(configuration);
|
|
||||||
export.Execute(false/*script*/, true/*export*/, false/*justDrop*/);
|
|
||||||
}
|
|
||||||
else if (parameters.UpdateSchema) {
|
|
||||||
var update = new SchemaUpdate(configuration);
|
|
||||||
update.Execute(false/*script*/, true /*doUpdate*/);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AutoPersistenceModel CreatePersistenceModel(IEnumerable<RecordBlueprint> recordDescriptors) {
|
public static AutoPersistenceModel CreatePersistenceModel(IEnumerable<RecordBlueprint> recordDescriptors) {
|
||||||
@@ -65,8 +51,5 @@ namespace Orchard.Data.Providers {
|
|||||||
|
|
||||||
public IEnumerable<Type> GetTypes() { return _recordDescriptors.Select(descriptor => descriptor.Type); }
|
public IEnumerable<Type> GetTypes() { return _recordDescriptors.Select(descriptor => descriptor.Type); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,10 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
using FluentNHibernate.Cfg;
|
using FluentNHibernate.Cfg;
|
||||||
|
using FluentNHibernate.Cfg.Db;
|
||||||
using NHibernate;
|
using NHibernate;
|
||||||
using NHibernate.Cfg;
|
using NHibernate.Cfg;
|
||||||
|
|
||||||
namespace Orchard.Data.Providers {
|
namespace Orchard.Data.Providers {
|
||||||
public interface IDataServicesProvider : ITransientDependency {
|
public interface IDataServicesProvider : ITransientDependency {
|
||||||
ISessionFactory BuildSessionFactory(SessionFactoryParameters sessionFactoryParameters);
|
Configuration BuildConfiguration(SessionFactoryParameters sessionFactoryParameters);
|
||||||
|
IPersistenceConfigurer GetPersistenceConfigurer(bool createDatabase);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -15,7 +15,7 @@ namespace Orchard.Data.Providers {
|
|||||||
get { return "SQLite"; }
|
get { return "SQLite"; }
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IPersistenceConfigurer GetPersistenceConfigurer(bool createDatabase) {
|
public override IPersistenceConfigurer GetPersistenceConfigurer(bool createDatabase) {
|
||||||
var persistence = SQLiteConfiguration.Standard;
|
var persistence = SQLiteConfiguration.Standard;
|
||||||
if (string.IsNullOrEmpty(_connectionString)) {
|
if (string.IsNullOrEmpty(_connectionString)) {
|
||||||
var dataFile = Path.Combine(_dataFolder, "Orchard.db");
|
var dataFile = Path.Combine(_dataFolder, "Orchard.db");
|
||||||
|
@@ -5,6 +5,5 @@ namespace Orchard.Data.Providers {
|
|||||||
public class SessionFactoryParameters : DataServiceParameters {
|
public class SessionFactoryParameters : DataServiceParameters {
|
||||||
public IEnumerable<RecordBlueprint> RecordDescriptors { get; set; }
|
public IEnumerable<RecordBlueprint> RecordDescriptors { get; set; }
|
||||||
public bool CreateDatabase { get; set; }
|
public bool CreateDatabase { get; set; }
|
||||||
public bool UpdateSchema { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,7 +16,7 @@ namespace Orchard.Data.Providers {
|
|||||||
get { return "SqlServer"; }
|
get { return "SqlServer"; }
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IPersistenceConfigurer GetPersistenceConfigurer(bool createDatabase) {
|
public override IPersistenceConfigurer GetPersistenceConfigurer(bool createDatabase) {
|
||||||
var persistence = MsSqlConfiguration.MsSql2008;
|
var persistence = MsSqlConfiguration.MsSql2008;
|
||||||
if (string.IsNullOrEmpty(_connectionString)) {
|
if (string.IsNullOrEmpty(_connectionString)) {
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
@@ -13,8 +13,7 @@ using Orchard.Logging;
|
|||||||
namespace Orchard.Data {
|
namespace Orchard.Data {
|
||||||
public interface ISessionFactoryHolder : ISingletonDependency {
|
public interface ISessionFactoryHolder : ISingletonDependency {
|
||||||
ISessionFactory GetSessionFactory();
|
ISessionFactory GetSessionFactory();
|
||||||
void CreateDatabase();
|
SessionFactoryParameters GetSessionFactoryParameters();
|
||||||
void UpdateSchema();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SessionFactoryHolder : ISessionFactoryHolder {
|
public class SessionFactoryHolder : ISessionFactoryHolder {
|
||||||
@@ -42,61 +41,41 @@ namespace Orchard.Data {
|
|||||||
public Localizer T { get; set; }
|
public Localizer T { get; set; }
|
||||||
public ILogger Logger { get; set; }
|
public ILogger Logger { get; set; }
|
||||||
|
|
||||||
public void CreateDatabase() {
|
|
||||||
lock (this) {
|
|
||||||
if (_sessionFactory != null) {
|
|
||||||
Logger.Error("CreateSchema can not be called after a session factory was created");
|
|
||||||
throw new OrchardCoreException(T("CreateSchema can not be called after a session factory was created"));
|
|
||||||
}
|
|
||||||
|
|
||||||
_sessionFactory = BuildSessionFactory(true /*createDatabase*/, false /*updateSchema*/);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateSchema() {
|
|
||||||
lock (this) {
|
|
||||||
if (_sessionFactory != null) {
|
|
||||||
Logger.Error("UpdateSchema can not be called after a session factory was created");
|
|
||||||
throw new OrchardCoreException(T("UpdateSchema can not be called after a session factory was created"));
|
|
||||||
}
|
|
||||||
|
|
||||||
_sessionFactory = BuildSessionFactory(false /*createDatabase*/, true /*updateSchema*/);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ISessionFactory GetSessionFactory() {
|
public ISessionFactory GetSessionFactory() {
|
||||||
lock (this) {
|
lock (this) {
|
||||||
if (_sessionFactory == null) {
|
if (_sessionFactory == null) {
|
||||||
_sessionFactory = BuildSessionFactory(false /*createDatabase*/, false /*updateSchema*/);
|
_sessionFactory = BuildSessionFactory();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return _sessionFactory;
|
return _sessionFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ISessionFactory BuildSessionFactory(bool createDatabase, bool updateSchema) {
|
private ISessionFactory BuildSessionFactory() {
|
||||||
Logger.Debug("Building session factory");
|
Logger.Debug("Building session factory");
|
||||||
|
|
||||||
|
var parameters = GetSessionFactoryParameters();
|
||||||
|
|
||||||
|
var sessionFactory = _dataServicesProviderFactory
|
||||||
|
.CreateProvider(parameters)
|
||||||
|
.BuildConfiguration(parameters)
|
||||||
|
.BuildSessionFactory();
|
||||||
|
|
||||||
|
return sessionFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SessionFactoryParameters GetSessionFactoryParameters() {
|
||||||
var shellPath = _appDataFolder.Combine("Sites", _shellSettings.Name);
|
var shellPath = _appDataFolder.Combine("Sites", _shellSettings.Name);
|
||||||
_appDataFolder.CreateDirectory(shellPath);
|
_appDataFolder.CreateDirectory(shellPath);
|
||||||
|
|
||||||
var shellFolder = _appDataFolder.MapPath(shellPath);
|
var shellFolder = _appDataFolder.MapPath(shellPath);
|
||||||
|
|
||||||
var parameters = new SessionFactoryParameters {
|
return new SessionFactoryParameters {
|
||||||
Provider = _shellSettings.DataProvider,
|
Provider = _shellSettings.DataProvider,
|
||||||
DataFolder = shellFolder,
|
DataFolder = shellFolder,
|
||||||
ConnectionString = _shellSettings.DataConnectionString,
|
ConnectionString = _shellSettings.DataConnectionString,
|
||||||
CreateDatabase = createDatabase,
|
|
||||||
UpdateSchema = updateSchema,
|
|
||||||
RecordDescriptors = _shellBlueprint.Records,
|
RecordDescriptors = _shellBlueprint.Records,
|
||||||
};
|
};
|
||||||
|
|
||||||
var sessionFactory = _dataServicesProviderFactory
|
|
||||||
.CreateProvider(parameters)
|
|
||||||
.BuildSessionFactory(parameters);
|
|
||||||
|
|
||||||
return sessionFactory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -359,13 +359,18 @@
|
|||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="ContentManagement\DataMigrations\FrameworkDataMigration.cs" />
|
<Compile Include="ContentManagement\DataMigrations\FrameworkDataMigration.cs" />
|
||||||
|
<Compile Include="Data\Migration\Generator\ISchemaCommandGenerator.cs" />
|
||||||
|
<Compile Include="Data\Migration\Interpreters\AbstractDataMigrationInterpreter.cs" />
|
||||||
<Compile Include="Data\Migration\Interpreters\ICommandInterpreter.cs" />
|
<Compile Include="Data\Migration\Interpreters\ICommandInterpreter.cs" />
|
||||||
<Compile Include="Data\Migration\Interpreters\DefaultDataMigrationInterpreter.cs" />
|
<Compile Include="Data\Migration\Interpreters\DefaultDataMigrationInterpreter.cs" />
|
||||||
<Compile Include="Data\Migration\Interpreters\IDataMigrationInterpreter.cs" />
|
<Compile Include="Data\Migration\Interpreters\IDataMigrationInterpreter.cs" />
|
||||||
<Compile Include="Data\Migration\Interpreters\SqLiteCommandInterpreter.cs" />
|
<Compile Include="Data\Migration\Interpreters\SqLiteCommandInterpreter.cs" />
|
||||||
|
<Compile Include="Data\Migration\Interpreters\StringCommandInterpreter.cs" />
|
||||||
<Compile Include="Data\Migration\Schema\AddColumnCommand.cs" />
|
<Compile Include="Data\Migration\Schema\AddColumnCommand.cs" />
|
||||||
<Compile Include="Data\Migration\Schema\ISchemaBuilderCommand.cs" />
|
<Compile Include="Data\Migration\Schema\ISchemaBuilderCommand.cs" />
|
||||||
<Compile Include="Data\Migration\Schema\IShellSettings.cs" />
|
<Compile Include="Data\Migration\Schema\IShellSettings.cs" />
|
||||||
|
<Compile Include="Data\Migration\Generator\SchemaCommandGenerator.cs" />
|
||||||
|
<Compile Include="Data\Migration\Schema\SchemaUtils.cs" />
|
||||||
<Compile Include="Data\Migration\Schema\SqlStatementCommand.cs" />
|
<Compile Include="Data\Migration\Schema\SqlStatementCommand.cs" />
|
||||||
<Compile Include="Data\Migration\Schema\CreateColumnCommand.cs" />
|
<Compile Include="Data\Migration\Schema\CreateColumnCommand.cs" />
|
||||||
<Compile Include="Data\Migration\Schema\CreateForeignKeyCommand.cs" />
|
<Compile Include="Data\Migration\Schema\CreateForeignKeyCommand.cs" />
|
||||||
@@ -379,8 +384,6 @@
|
|||||||
<Compile Include="Data\Migration\Commands\DataMigrationCommands.cs" />
|
<Compile Include="Data\Migration\Commands\DataMigrationCommands.cs" />
|
||||||
<Compile Include="Data\Migration\Schema\SchemaBuilder.cs" />
|
<Compile Include="Data\Migration\Schema\SchemaBuilder.cs" />
|
||||||
<Compile Include="Data\Migration\DataMigrationCoordinator.cs" />
|
<Compile Include="Data\Migration\DataMigrationCoordinator.cs" />
|
||||||
<Compile Include="Data\Migration\DefaultDataMigrationGenerator.cs" />
|
|
||||||
<Compile Include="Data\Migration\IDataMigrationGenerator.cs" />
|
|
||||||
<Compile Include="Data\Migration\DataMigration.cs" />
|
<Compile Include="Data\Migration\DataMigration.cs" />
|
||||||
<Compile Include="Data\Migration\DataMigrationManager.cs" />
|
<Compile Include="Data\Migration\DataMigrationManager.cs" />
|
||||||
<Compile Include="Data\Migration\Records\DataMigrationRecord.cs" />
|
<Compile Include="Data\Migration\Records\DataMigrationRecord.cs" />
|
||||||
|
Reference in New Issue
Block a user