From 64af0a610b5014597f95577663e5e4d38442ddf0 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Thu, 27 Dec 2012 18:52:47 -0100 Subject: [PATCH] Refactoring migrations by adding an abstract class to all expressions that allow for processing prior to returning an sql statement. Refactoring the current sql syntax providers to better work with sql ce, sql server and mysql. Adding migrations for v4.8 and v6.0. Adding test cases for upgrading from 4.7 to 6.0 for the 3 database providers - sql ce, sql server and mysql. Adding product name to the MigrationAttribute, which adds more flexibility to the MigrationRunner. Fixing schema creation for mysql, which broke during a previous refactor task. --- .../Configuration/GlobalSettings.cs | 1 + src/Umbraco.Core/DatabaseContext.cs | 2 +- src/Umbraco.Core/Models/Rdbms/AppTreeDto.cs | 2 +- .../Models/Rdbms/Member2MemberGroupDto.cs | 2 +- .../Models/Rdbms/PreviewXmlDto.cs | 2 +- .../Models/Rdbms/TagRelationshipDto.cs | 2 +- src/Umbraco.Core/Models/Rdbms/User2AppDto.cs | 2 +- .../Models/Rdbms/User2NodeNotifyDto.cs | 2 +- .../Models/Rdbms/User2NodePermissionDto.cs | 2 +- .../Migrations/IMigrationContext.cs | 10 ++ .../Migrations/IMigrationExpression.cs | 10 ++ .../Migrations/Initial/BaseDataCreation.cs | 6 + .../Initial/DatabaseSchemaCreation.cs | 4 +- .../Migrations/MigrationAttribute.cs | 8 +- .../Persistence/Migrations/MigrationBase.cs | 6 + .../Migrations/MigrationContext.cs | 16 +-- .../Migrations/MigrationExpressionBase.cs | 33 +++++ .../Persistence/Migrations/MigrationRunner.cs | 40 ++++-- .../Expressions/AlterColumnExpression.cs | 7 +- .../AlterDefaultConstraintExpression.cs | 10 +- .../Alter/Expressions/AlterTableExpression.cs | 6 +- .../Migrations/Syntax/Create/CreateBuilder.cs | 16 ++- .../Expressions/CreateConstraintExpression.cs | 2 +- .../Expressions/CreateTableExpression.cs | 13 +- .../Syntax/Create/ICreateBuilder.cs | 1 + .../Migrations/Syntax/Delete/DeleteBuilder.cs | 20 ++- .../Expressions/DeleteColumnExpression.cs | 11 +- .../Expressions/DeleteConstraintExpression.cs | 2 +- .../Expressions/DeleteDataExpression.cs | 11 +- .../DeleteDefaultConstraintExpression.cs | 18 ++- .../Expressions/DeleteForeignKeyExpression.cs | 30 +++- .../Expressions/DeleteIndexExpression.cs | 7 +- .../Expressions/DeleteTableExpression.cs | 10 +- .../ExecuteSqlStatementExpression.cs | 10 +- .../Expressions/CreateColumnExpression.cs | 13 +- .../Expressions/CreateForeignKeyExpression.cs | 11 +- .../Expressions/CreateIndexExpression.cs | 7 +- .../Syntax/IfDatabase/IIfDatabaseBuilder.cs | 13 ++ .../Syntax/IfDatabase/IfDatabaseBuilder.cs | 33 +++++ .../Expressions/InsertDataExpression.cs | 11 +- .../Expressions/RenameColumnExpression.cs | 43 +++++- .../Expressions/RenameTableExpression.cs | 14 +- .../Migrations/Syntax/Rename/RenameBuilder.cs | 12 +- .../Expressions/UpdateDataExpression.cs | 10 +- .../RemoveUmbracoAppConstraints.cs | 7 +- .../TargetVersionSixth/DeleteAppTables.cs | 6 +- .../EnsureAppsTreesUpdated.cs | 3 +- .../MoveMasterContentTypeData.cs | 8 +- .../NewCmsContentType2ContentTypeTable.cs | 6 +- .../RemoveMasterContentTypeColumn.cs | 10 +- .../TargetVersionSixth/RenameCmsTabTable.cs | 6 +- .../TargetVersionSixth/RenameTabIdColumn.cs | 63 +++++++- ...teCmsContentTypeAllowedContentTypeTable.cs | 6 +- .../UpdateCmsContentTypeTable.cs | 6 +- .../UpdateCmsContentVersionTable.cs | 6 +- .../UpdateCmsPropertyTypeGroupTable.cs | 8 +- .../Persistence/PetaPocoExtensions.cs | 21 ++- .../SqlSyntax/ISqlSyntaxProvider.cs | 1 + .../SqlSyntax/MySqlSyntaxProvider.cs | 83 ++++++++--- .../SqlSyntax/SqlCeSyntaxProvider.cs | 11 +- .../SqlSyntax/SqlServerSyntaxProvider.cs | 19 +-- .../SqlSyntax/SqlSyntaxProviderBase.cs | 5 + src/Umbraco.Core/Umbraco.Core.csproj | 5 + .../Migrations/AlterMigrationTests.cs | 4 +- .../Migrations/FindingMigrationsTest.cs | 3 +- .../Migrations/SqlCeUpgradeTest.cs | 136 ------------------ .../Stubs/AlterUserTableMigrationStub.cs | 2 +- .../Migrations/Stubs/FourNineMigration.cs | 6 +- .../TargetVersionSixthMigrationsTest.cs | 6 +- .../Migrations/Upgrades/BaseUpgradeTest.cs | 102 +++++++++++++ .../Migrations/Upgrades/MySqlUpgradeTest.cs | 40 ++++++ .../Migrations/Upgrades/SqlCeUpgradeTest.cs | 59 ++++++++ .../Upgrades/SqlServerUpgradeTest.cs | 38 +++++ .../Persistence/MySqlDatabaseCreationTest.cs | 2 +- .../Persistence/MySqlTableByTableTest.cs | 2 +- .../SyntaxProvider/SqlSyntaxProviderTests.cs | 4 +- src/Umbraco.Tests/Umbraco.Tests.csproj | 5 +- 77 files changed, 875 insertions(+), 305 deletions(-) create mode 100644 src/Umbraco.Core/Persistence/Migrations/IMigrationContext.cs create mode 100644 src/Umbraco.Core/Persistence/Migrations/IMigrationExpression.cs create mode 100644 src/Umbraco.Core/Persistence/Migrations/MigrationExpressionBase.cs create mode 100644 src/Umbraco.Core/Persistence/Migrations/Syntax/IfDatabase/IIfDatabaseBuilder.cs create mode 100644 src/Umbraco.Core/Persistence/Migrations/Syntax/IfDatabase/IfDatabaseBuilder.cs delete mode 100644 src/Umbraco.Tests/Migrations/SqlCeUpgradeTest.cs create mode 100644 src/Umbraco.Tests/Migrations/Upgrades/BaseUpgradeTest.cs create mode 100644 src/Umbraco.Tests/Migrations/Upgrades/MySqlUpgradeTest.cs create mode 100644 src/Umbraco.Tests/Migrations/Upgrades/SqlCeUpgradeTest.cs create mode 100644 src/Umbraco.Tests/Migrations/Upgrades/SqlServerUpgradeTest.cs diff --git a/src/Umbraco.Core/Configuration/GlobalSettings.cs b/src/Umbraco.Core/Configuration/GlobalSettings.cs index d46eb76a2a..8e17689ea1 100644 --- a/src/Umbraco.Core/Configuration/GlobalSettings.cs +++ b/src/Umbraco.Core/Configuration/GlobalSettings.cs @@ -163,6 +163,7 @@ namespace Umbraco.Core.Configuration } public const string UmbracoConnectionName = "umbracoDbDSN"; + public const string UmbracoMigrationName = "Umbraco"; /// /// Gets or sets the configuration status. This will return the version number of the currently installed umbraco instance. diff --git a/src/Umbraco.Core/DatabaseContext.cs b/src/Umbraco.Core/DatabaseContext.cs index f4659bf6c3..75931ba89b 100644 --- a/src/Umbraco.Core/DatabaseContext.cs +++ b/src/Umbraco.Core/DatabaseContext.cs @@ -309,7 +309,7 @@ namespace Umbraco.Core { var configuredVersion = new Version(GlobalSettings.ConfigurationStatus); var targetVersion = UmbracoVersion.Current; - var runner = new MigrationRunner(configuredVersion, targetVersion); + var runner = new MigrationRunner(configuredVersion, targetVersion, GlobalSettings.UmbracoMigrationName); var upgraded = runner.Execute(database, true); } diff --git a/src/Umbraco.Core/Models/Rdbms/AppTreeDto.cs b/src/Umbraco.Core/Models/Rdbms/AppTreeDto.cs index cab38fa201..a1308ac4dd 100644 --- a/src/Umbraco.Core/Models/Rdbms/AppTreeDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/AppTreeDto.cs @@ -20,7 +20,7 @@ namespace Umbraco.Core.Models.Rdbms public byte SortOrder { get; set; } [Column("appAlias")] - [PrimaryKeyColumn(AutoIncrement = false, Clustered = true, Name = "PK_umbracoAppTree", OnColumns = "[appAlias], [treeAlias]")] + [PrimaryKeyColumn(AutoIncrement = false, Clustered = true, Name = "PK_umbracoAppTree", OnColumns = "appAlias, treeAlias")] public string AppAlias { get; set; } [Column("treeAlias")] diff --git a/src/Umbraco.Core/Models/Rdbms/Member2MemberGroupDto.cs b/src/Umbraco.Core/Models/Rdbms/Member2MemberGroupDto.cs index 89e07c25ea..888f331364 100644 --- a/src/Umbraco.Core/Models/Rdbms/Member2MemberGroupDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/Member2MemberGroupDto.cs @@ -9,7 +9,7 @@ namespace Umbraco.Core.Models.Rdbms internal class Member2MemberGroupDto { [Column("Member")] - [PrimaryKeyColumn(AutoIncrement = false, Name = "PK_cmsMember2MemberGroup", OnColumns = "[Member], [MemberGroup]")] + [PrimaryKeyColumn(AutoIncrement = false, Name = "PK_cmsMember2MemberGroup", OnColumns = "Member, MemberGroup")] [ForeignKey(typeof(MemberDto))] public int Member { get; set; } diff --git a/src/Umbraco.Core/Models/Rdbms/PreviewXmlDto.cs b/src/Umbraco.Core/Models/Rdbms/PreviewXmlDto.cs index 20a3d1d532..f0f3ebffd0 100644 --- a/src/Umbraco.Core/Models/Rdbms/PreviewXmlDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/PreviewXmlDto.cs @@ -10,7 +10,7 @@ namespace Umbraco.Core.Models.Rdbms internal class PreviewXmlDto { [Column("nodeId")] - [PrimaryKeyColumn(AutoIncrement = false, Name = "", OnColumns = "[nodeId], [versionId]")] + [PrimaryKeyColumn(AutoIncrement = false, Name = "", OnColumns = "nodeId, versionId")] [ForeignKey(typeof(ContentDto), Column = "nodeId")] public int NodeId { get; set; } diff --git a/src/Umbraco.Core/Models/Rdbms/TagRelationshipDto.cs b/src/Umbraco.Core/Models/Rdbms/TagRelationshipDto.cs index e18cbeeb12..8f64c9ba9c 100644 --- a/src/Umbraco.Core/Models/Rdbms/TagRelationshipDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/TagRelationshipDto.cs @@ -9,7 +9,7 @@ namespace Umbraco.Core.Models.Rdbms internal class TagRelationshipDto { [Column("nodeId")] - [PrimaryKeyColumn(AutoIncrement = false, Name = "PK_cmsTagRelationship", OnColumns = "[nodeId], [tagId]")] + [PrimaryKeyColumn(AutoIncrement = false, Name = "PK_cmsTagRelationship", OnColumns = "nodeId, tagId")] [ForeignKey(typeof(NodeDto))] public int NodeId { get; set; } diff --git a/src/Umbraco.Core/Models/Rdbms/User2AppDto.cs b/src/Umbraco.Core/Models/Rdbms/User2AppDto.cs index 57ab00a3a3..eafc6be230 100644 --- a/src/Umbraco.Core/Models/Rdbms/User2AppDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/User2AppDto.cs @@ -9,7 +9,7 @@ namespace Umbraco.Core.Models.Rdbms internal class User2AppDto { [Column("user")] - [PrimaryKeyColumn(AutoIncrement = false, Name = "PK_user2app", OnColumns = "[user], [app]")] + [PrimaryKeyColumn(AutoIncrement = false, Name = "PK_user2app", OnColumns = "user, app")] [ForeignKey(typeof(UserDto))] public int UserId { get; set; } diff --git a/src/Umbraco.Core/Models/Rdbms/User2NodeNotifyDto.cs b/src/Umbraco.Core/Models/Rdbms/User2NodeNotifyDto.cs index 2163ca32c3..298ad920d9 100644 --- a/src/Umbraco.Core/Models/Rdbms/User2NodeNotifyDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/User2NodeNotifyDto.cs @@ -9,7 +9,7 @@ namespace Umbraco.Core.Models.Rdbms internal class User2NodeNotifyDto { [Column("userId")] - [PrimaryKeyColumn(AutoIncrement = false, Name = "PK_umbracoUser2NodeNotify", OnColumns = "[userId], [nodeId], [action]")] + [PrimaryKeyColumn(AutoIncrement = false, Name = "PK_umbracoUser2NodeNotify", OnColumns = "userId, nodeId, action")] [ForeignKey(typeof(UserDto))] public int UserId { get; set; } diff --git a/src/Umbraco.Core/Models/Rdbms/User2NodePermissionDto.cs b/src/Umbraco.Core/Models/Rdbms/User2NodePermissionDto.cs index 5ddd6dd07a..1e6662735f 100644 --- a/src/Umbraco.Core/Models/Rdbms/User2NodePermissionDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/User2NodePermissionDto.cs @@ -9,7 +9,7 @@ namespace Umbraco.Core.Models.Rdbms internal class User2NodePermissionDto { [Column("userId")] - [PrimaryKeyColumn(AutoIncrement = false, Name = "PK_umbracoUser2NodePermission", OnColumns = "[userId], [nodeId], [permission]")] + [PrimaryKeyColumn(AutoIncrement = false, Name = "PK_umbracoUser2NodePermission", OnColumns = "userId, nodeId, permission")] [ForeignKey(typeof(UserDto))] public int UserId { get; set; } diff --git a/src/Umbraco.Core/Persistence/Migrations/IMigrationContext.cs b/src/Umbraco.Core/Persistence/Migrations/IMigrationContext.cs new file mode 100644 index 0000000000..616c7b16c5 --- /dev/null +++ b/src/Umbraco.Core/Persistence/Migrations/IMigrationContext.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace Umbraco.Core.Persistence.Migrations +{ + public interface IMigrationContext + { + ICollection Expressions { get; set; } + DatabaseProviders CurrentDatabaseProvider { get; } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/IMigrationExpression.cs b/src/Umbraco.Core/Persistence/Migrations/IMigrationExpression.cs new file mode 100644 index 0000000000..c8d36de915 --- /dev/null +++ b/src/Umbraco.Core/Persistence/Migrations/IMigrationExpression.cs @@ -0,0 +1,10 @@ +namespace Umbraco.Core.Persistence.Migrations +{ + /// + /// Marker interface for migration expressions + /// + public interface IMigrationExpression + { + string Process(Database database); + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs b/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs index e68ca4947d..dd0d237769 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs @@ -1,4 +1,5 @@ using System; +using Umbraco.Core.Logging; using Umbraco.Core.Models.Rdbms; namespace Umbraco.Core.Persistence.Migrations.Initial @@ -22,6 +23,8 @@ namespace Umbraco.Core.Persistence.Migrations.Initial /// Name of the table to create base data for public void InitializeBaseData(string tableName) { + LogHelper.Info(string.Format("Creating data in table {0}", tableName)); + if(tableName.Equals("umbracoNode")) { CreateUmbracNodeData(); @@ -90,6 +93,8 @@ namespace Umbraco.Core.Persistence.Migrations.Initial { CreateCmsTaskTypeData(); } + + LogHelper.Info(string.Format("Done creating data in table {0}", tableName)); } private void CreateUmbracNodeData() @@ -136,6 +141,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial private void CreateUmbracoUserData() { _database.Insert("umbracoUser", "id", false, new UserDto { Id = 0, Disabled = false, NoConsole = false, Type = 1, ContentStartId = -1, MediaStartId = -1, UserName = "Administrator", Login = "admin", Password = "default", Email = "", UserLanguage = "en", DefaultPermissions = null, DefaultToLiveEditing = false }); + _database.Update("SET id = @IdAfter WHERE id = @IdBefore AND userLogin = @Login", new { IdAfter = 0, IdBefore = 1, Login = "admin" }); } private void CreateUmbracoUserTypeData() diff --git a/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs b/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs index 5f39881e92..4e2f60eb3c 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs @@ -72,8 +72,8 @@ namespace Umbraco.Core.Persistence.Migrations.Initial _database.CreateTable(); _database.CreateTable(); - _database.CreateTable(); - _database.CreateTable(); + //_database.CreateTable(); + //_database.CreateTable(); _database.CreateTable(); _database.CreateTable(); diff --git a/src/Umbraco.Core/Persistence/Migrations/MigrationAttribute.cs b/src/Umbraco.Core/Persistence/Migrations/MigrationAttribute.cs index 70484942fc..b7e16614e6 100644 --- a/src/Umbraco.Core/Persistence/Migrations/MigrationAttribute.cs +++ b/src/Umbraco.Core/Persistence/Migrations/MigrationAttribute.cs @@ -9,10 +9,11 @@ namespace Umbraco.Core.Persistence.Migrations [AttributeUsage(AttributeTargets.Class)] public class MigrationAttribute : Attribute { - public MigrationAttribute(string targetVersion, int sortOrder) + public MigrationAttribute(string targetVersion, int sortOrder, string product) { TargetVersion = new Version(targetVersion); SortOrder = sortOrder; + ProductName = product; } /// @@ -24,5 +25,10 @@ namespace Umbraco.Core.Persistence.Migrations /// Gets or sets the sort order, which is the order this migration will be run in. /// public int SortOrder { get; private set; } + + /// + /// Gets or sets the name of the product, which this migration belongs to. + /// + public string ProductName { get; set; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/MigrationBase.cs b/src/Umbraco.Core/Persistence/Migrations/MigrationBase.cs index f6a54b326b..725cb2c7a0 100644 --- a/src/Umbraco.Core/Persistence/Migrations/MigrationBase.cs +++ b/src/Umbraco.Core/Persistence/Migrations/MigrationBase.cs @@ -2,6 +2,7 @@ using Umbraco.Core.Persistence.Migrations.Syntax.Create; using Umbraco.Core.Persistence.Migrations.Syntax.Delete; using Umbraco.Core.Persistence.Migrations.Syntax.Execute; +using Umbraco.Core.Persistence.Migrations.Syntax.IfDatabase; using Umbraco.Core.Persistence.Migrations.Syntax.Insert; using Umbraco.Core.Persistence.Migrations.Syntax.Rename; using Umbraco.Core.Persistence.Migrations.Syntax.Update; @@ -61,5 +62,10 @@ namespace Umbraco.Core.Persistence.Migrations { get { return new UpdateBuilder(_context); } } + + public IIfDatabaseBuilder IfDatabase(params DatabaseProviders[] databaseProviders) + { + return new IfDatabaseBuilder(_context, databaseProviders); + } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/MigrationContext.cs b/src/Umbraco.Core/Persistence/Migrations/MigrationContext.cs index 8fac51a11b..90779e4317 100644 --- a/src/Umbraco.Core/Persistence/Migrations/MigrationContext.cs +++ b/src/Umbraco.Core/Persistence/Migrations/MigrationContext.cs @@ -5,22 +5,14 @@ namespace Umbraco.Core.Persistence.Migrations { internal class MigrationContext : IMigrationContext { - public MigrationContext() + public MigrationContext(DatabaseProviders databaseProvider) { Expressions = new Collection(); + CurrentDatabaseProvider = databaseProvider; } - public virtual ICollection Expressions { get; set; } - } + public ICollection Expressions { get; set; } - public interface IMigrationContext - { - ICollection Expressions { get; set; } + public DatabaseProviders CurrentDatabaseProvider { get; private set; } } - - /// - /// Marker interface for migration expressions - /// - public interface IMigrationExpression - {} } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/MigrationExpressionBase.cs b/src/Umbraco.Core/Persistence/Migrations/MigrationExpressionBase.cs new file mode 100644 index 0000000000..3b8b62258e --- /dev/null +++ b/src/Umbraco.Core/Persistence/Migrations/MigrationExpressionBase.cs @@ -0,0 +1,33 @@ +using System.Linq; + +namespace Umbraco.Core.Persistence.Migrations +{ + public abstract class MigrationExpressionBase : IMigrationExpression + { + protected MigrationExpressionBase() + { + } + + protected MigrationExpressionBase(DatabaseProviders current, DatabaseProviders[] databaseProviders) + { + SupportedDatabaseProviders = databaseProviders; + CurrentDatabaseProvider = current; + } + + public virtual DatabaseProviders[] SupportedDatabaseProviders { get; private set; } + public virtual DatabaseProviders CurrentDatabaseProvider { get; private set; } + + public bool IsExpressionSupported() + { + if (SupportedDatabaseProviders == null || SupportedDatabaseProviders.Any() == false) + return true; + + return SupportedDatabaseProviders.Any(x => x == CurrentDatabaseProvider); + } + + public virtual string Process(Database database) + { + return this.ToString(); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs b/src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs index 098b5272b3..4a341e4521 100644 --- a/src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs +++ b/src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs @@ -13,11 +13,13 @@ namespace Umbraco.Core.Persistence.Migrations { private readonly Version _configuredVersion; private readonly Version _targetVersion; + private readonly string _productName; - public MigrationRunner(Version configuredVersion, Version targetVersion) + public MigrationRunner(Version configuredVersion, Version targetVersion, string productName) { _configuredVersion = configuredVersion; _targetVersion = targetVersion; + _productName = productName; } /// @@ -25,8 +27,20 @@ namespace Umbraco.Core.Persistence.Migrations /// /// The PetaPoco Database, which the migrations will be run against /// Boolean indicating whether this is an upgrade or downgrade - /// True if migrations were applied, otherwise False - public bool Execute(Database database, bool isUpgrade) + /// True if migrations were applied, otherwise False + public bool Execute(Database database, bool isUpgrade = true) + { + return Execute(database, database.GetDatabaseProvider(), isUpgrade); + } + + /// + /// Executes the migrations against the database. + /// + /// The PetaPoco Database, which the migrations will be run against + /// + /// Boolean indicating whether this is an upgrade or downgrade + /// True if migrations were applied, otherwise False + public bool Execute(Database database, DatabaseProviders databaseProvider, bool isUpgrade = true) { LogHelper.Info("Initializing database migration"); @@ -36,7 +50,7 @@ namespace Umbraco.Core.Persistence.Migrations : OrderedDowngradeMigrations(foundMigrations); //Loop through migrations to generate sql - var context = new MigrationContext(); + var context = new MigrationContext(databaseProvider); foreach (MigrationBase migration in migrations) { if (isUpgrade) @@ -52,11 +66,19 @@ namespace Umbraco.Core.Persistence.Migrations //Transactional execution of the sql that was generated from the found migrations using (Transaction transaction = database.GetTransaction()) { + int i = 1; foreach (var expression in context.Expressions) { - var sql = expression.ToString(); - LogHelper.Info("Executing sql: " + sql); + var sql = expression.Process(database); + if (string.IsNullOrEmpty(sql)) + { + i++; + continue; + } + + LogHelper.Info("Executing sql statement " + i + ": " + sql); database.Execute(sql); + i++; } transaction.Complete(); @@ -72,7 +94,8 @@ namespace Umbraco.Core.Persistence.Migrations where migrationAttribute != null where migrationAttribute.TargetVersion > _configuredVersion && - migrationAttribute.TargetVersion <= _targetVersion + migrationAttribute.TargetVersion <= _targetVersion && + migrationAttribute.ProductName == _productName orderby migrationAttribute.SortOrder ascending select migration); return migrations; @@ -85,7 +108,8 @@ namespace Umbraco.Core.Persistence.Migrations where migrationAttribute != null where migrationAttribute.TargetVersion > _configuredVersion && - migrationAttribute.TargetVersion <= _targetVersion + migrationAttribute.TargetVersion <= _targetVersion && + migrationAttribute.ProductName == _productName orderby migrationAttribute.SortOrder descending select migration); return migrations; diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Expressions/AlterColumnExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Expressions/AlterColumnExpression.cs index ba13bbcbfe..2a88a51337 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Expressions/AlterColumnExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Expressions/AlterColumnExpression.cs @@ -3,13 +3,18 @@ using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Expressions { - public class AlterColumnExpression : IMigrationExpression + public class AlterColumnExpression : MigrationExpressionBase { public AlterColumnExpression() { Column = new ColumnDefinition() { ModificationType = ModificationType.Alter }; } + public AlterColumnExpression(DatabaseProviders current, DatabaseProviders[] databaseProviders) : base(current, databaseProviders) + { + Column = new ColumnDefinition() { ModificationType = ModificationType.Alter }; + } + public virtual string SchemaName { get; set; } public virtual string TableName { get; set; } public virtual ColumnDefinition Column { get; set; } diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Expressions/AlterDefaultConstraintExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Expressions/AlterDefaultConstraintExpression.cs index c4c28119ea..2d0dd81150 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Expressions/AlterDefaultConstraintExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Expressions/AlterDefaultConstraintExpression.cs @@ -2,8 +2,16 @@ using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Expressions { - public class AlterDefaultConstraintExpression : IMigrationExpression + public class AlterDefaultConstraintExpression : MigrationExpressionBase { + public AlterDefaultConstraintExpression() + { + } + + public AlterDefaultConstraintExpression(DatabaseProviders current, DatabaseProviders[] databaseProviders) : base(current, databaseProviders) + { + } + public virtual string SchemaName { get; set; } public virtual string TableName { get; set; } public virtual string ColumnName { get; set; } diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Expressions/AlterTableExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Expressions/AlterTableExpression.cs index b9482e07e9..360b699cd8 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Expressions/AlterTableExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Expressions/AlterTableExpression.cs @@ -1,11 +1,15 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Expressions { - public class AlterTableExpression : IMigrationExpression + public class AlterTableExpression : MigrationExpressionBase { public AlterTableExpression() { } + public AlterTableExpression(DatabaseProviders current, DatabaseProviders[] databaseProviders) : base(current, databaseProviders) + { + } + public virtual string SchemaName { get; set; } public virtual string TableName { get; set; } diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/CreateBuilder.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/CreateBuilder.cs index 4e1595b1b5..590995188f 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/CreateBuilder.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/CreateBuilder.cs @@ -12,10 +12,12 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Create public class CreateBuilder : ICreateBuilder { private readonly IMigrationContext _context; + private readonly DatabaseProviders[] _databaseProviders; - public CreateBuilder(IMigrationContext context) + public CreateBuilder(IMigrationContext context, params DatabaseProviders[] databaseProviders) { _context = context; + _databaseProviders = databaseProviders; } public ICreateTableWithColumnSyntax Table(string tableName) @@ -27,21 +29,27 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Create public ICreateColumnOnTableSyntax Column(string columnName) { - var expression = new CreateColumnExpression { Column = { Name = columnName } }; + var expression = _databaseProviders == null + ? new CreateColumnExpression { Column = { Name = columnName } } + : new CreateColumnExpression(_context.CurrentDatabaseProvider, _databaseProviders) { Column = { Name = columnName } }; _context.Expressions.Add(expression); return new CreateColumnBuilder(expression, _context); } public ICreateForeignKeyFromTableSyntax ForeignKey() { - var expression = new CreateForeignKeyExpression(); + var expression = _databaseProviders == null + ? new CreateForeignKeyExpression() + : new CreateForeignKeyExpression(_context.CurrentDatabaseProvider, _databaseProviders); _context.Expressions.Add(expression); return new CreateForeignKeyBuilder(expression); } public ICreateForeignKeyFromTableSyntax ForeignKey(string foreignKeyName) { - var expression = new CreateForeignKeyExpression { ForeignKey = { Name = foreignKeyName } }; + var expression = _databaseProviders == null + ? new CreateForeignKeyExpression { ForeignKey = { Name = foreignKeyName } } + : new CreateForeignKeyExpression(_context.CurrentDatabaseProvider, _databaseProviders) { ForeignKey = { Name = foreignKeyName } }; _context.Expressions.Add(expression); return new CreateForeignKeyBuilder(expression); } diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Expressions/CreateConstraintExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Expressions/CreateConstraintExpression.cs index 011ff83146..ba2b29e873 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Expressions/CreateConstraintExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Expressions/CreateConstraintExpression.cs @@ -4,7 +4,7 @@ using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Syntax.Create.Expressions { - public class CreateConstraintExpression : IMigrationExpression + public class CreateConstraintExpression : MigrationExpressionBase { public CreateConstraintExpression(ConstraintType type) { diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Expressions/CreateTableExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Expressions/CreateTableExpression.cs index 8400eeca42..31eadf27e8 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Expressions/CreateTableExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Expressions/CreateTableExpression.cs @@ -4,22 +4,27 @@ using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Syntax.Create.Expressions { - public class CreateTableExpression : IMigrationExpression + public class CreateTableExpression : MigrationExpressionBase { public CreateTableExpression() { Columns = new List(); } + public CreateTableExpression(DatabaseProviders current, DatabaseProviders[] databaseProviders) : base(current, databaseProviders) + { + Columns = new List(); + } + public virtual string SchemaName { get; set; } public virtual string TableName { get; set; } public virtual IList Columns { get; set; } public override string ToString() { - return string.Format(SyntaxConfig.SqlSyntaxProvider.CreateTable, - SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(TableName), - SyntaxConfig.SqlSyntaxProvider.Format(Columns)); + var table = new TableDefinition{Name = TableName, SchemaName = SchemaName, Columns = Columns}; + + return string.Format(SyntaxConfig.SqlSyntaxProvider.Format(table)); } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/ICreateBuilder.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/ICreateBuilder.cs index 47cb9fc993..e079127705 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/ICreateBuilder.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/ICreateBuilder.cs @@ -22,5 +22,6 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Create ICreateConstraintOnTableSyntax UniqueConstraint(); ICreateConstraintOnTableSyntax UniqueConstraint(string constraintName); + ICreateConstraintOnTableSyntax Constraint(string constraintName); } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/DeleteBuilder.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/DeleteBuilder.cs index 60e6761713..03ceaa6a4e 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/DeleteBuilder.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/DeleteBuilder.cs @@ -11,10 +11,12 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete public class DeleteBuilder : IDeleteBuilder { private readonly IMigrationContext _context; + private readonly DatabaseProviders[] _databaseProviders; - public DeleteBuilder(IMigrationContext context) + public DeleteBuilder(IMigrationContext context, params DatabaseProviders[] databaseProviders) { _context = context; + _databaseProviders = databaseProviders; } public void Table(string tableName) @@ -25,21 +27,27 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete public IDeleteColumnFromTableSyntax Column(string columnName) { - var expression = new DeleteColumnExpression { ColumnNames = { columnName } }; + var expression = _databaseProviders == null + ? new DeleteColumnExpression { ColumnNames = { columnName } } + : new DeleteColumnExpression(_context.CurrentDatabaseProvider, _databaseProviders) { ColumnNames = { columnName } }; _context.Expressions.Add(expression); return new DeleteColumnBuilder(expression); } public IDeleteForeignKeyFromTableSyntax ForeignKey() { - var expression = new DeleteForeignKeyExpression(); + var expression = _databaseProviders == null + ? new DeleteForeignKeyExpression() + : new DeleteForeignKeyExpression(_context.CurrentDatabaseProvider, _databaseProviders); _context.Expressions.Add(expression); return new DeleteForeignKeyBuilder(expression); } public IDeleteForeignKeyOnTableSyntax ForeignKey(string foreignKeyName) { - var expression = new DeleteForeignKeyExpression { ForeignKey = { Name = foreignKeyName } }; + var expression = _databaseProviders == null + ? new DeleteForeignKeyExpression { ForeignKey = { Name = foreignKeyName } } + : new DeleteForeignKeyExpression(_context.CurrentDatabaseProvider, _databaseProviders) { ForeignKey = { Name = foreignKeyName } }; _context.Expressions.Add(expression); return new DeleteForeignKeyBuilder(expression); } @@ -87,7 +95,9 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete public IDeleteDefaultConstraintOnTableSyntax DefaultConstraint() { - var expression = new DeleteDefaultConstraintExpression(); + var expression = _databaseProviders == null + ? new DeleteDefaultConstraintExpression() + : new DeleteDefaultConstraintExpression(_context.CurrentDatabaseProvider, _databaseProviders); _context.Expressions.Add(expression); return new DeleteDefaultConstraintBuilder(expression); } diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteColumnExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteColumnExpression.cs index a8ec8f3edc..bbeaa3ffa2 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteColumnExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteColumnExpression.cs @@ -5,19 +5,28 @@ using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions { - public class DeleteColumnExpression : IMigrationExpression + public class DeleteColumnExpression : MigrationExpressionBase { public DeleteColumnExpression() { ColumnNames = new List(); } + public DeleteColumnExpression(DatabaseProviders current, DatabaseProviders[] databaseProviders) + : base(current, databaseProviders) + { + ColumnNames = new List(); + } + public virtual string SchemaName { get; set; } public virtual string TableName { get; set; } public ICollection ColumnNames { get; set; } public override string ToString() { + if (IsExpressionSupported() == false) + return string.Empty; + var sb = new StringBuilder(); foreach (string columnName in ColumnNames) { diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteConstraintExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteConstraintExpression.cs index 7833f92ac4..075d6c5d1b 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteConstraintExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteConstraintExpression.cs @@ -3,7 +3,7 @@ using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions { - public class DeleteConstraintExpression : IMigrationExpression + public class DeleteConstraintExpression : MigrationExpressionBase { public DeleteConstraintExpression(ConstraintType type) { diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteDataExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteDataExpression.cs index a37abf0650..23c4388d50 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteDataExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteDataExpression.cs @@ -5,9 +5,18 @@ using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions { - public class DeleteDataExpression : IMigrationExpression + public class DeleteDataExpression : MigrationExpressionBase { private readonly List _rows = new List(); + + public DeleteDataExpression() + { + } + + public DeleteDataExpression(DatabaseProviders current, DatabaseProviders[] databaseProviders) : base(current, databaseProviders) + { + } + public virtual string SchemaName { get; set; } public string TableName { get; set; } public virtual bool IsAllRows { get; set; } diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteDefaultConstraintExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteDefaultConstraintExpression.cs index c84d5922da..72e86f4d1d 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteDefaultConstraintExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteDefaultConstraintExpression.cs @@ -2,17 +2,29 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions { - public class DeleteDefaultConstraintExpression : IMigrationExpression + public class DeleteDefaultConstraintExpression : MigrationExpressionBase { + public DeleteDefaultConstraintExpression() + { + } + + public DeleteDefaultConstraintExpression(DatabaseProviders current, DatabaseProviders[] databaseProviders) + : base(current, databaseProviders) + { + } + public virtual string SchemaName { get; set; } public virtual string TableName { get; set; } public virtual string ColumnName { get; set; } public override string ToString() { + if (IsExpressionSupported() == false) + return string.Empty; + return string.Format(SyntaxConfig.SqlSyntaxProvider.DeleteDefaultConstraint, - SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(TableName), - SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(ColumnName)); + TableName, + ColumnName); } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteForeignKeyExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteForeignKeyExpression.cs index 8fb4f9e0f7..5cb3ef3bfa 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteForeignKeyExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteForeignKeyExpression.cs @@ -4,23 +4,49 @@ using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions { - public class DeleteForeignKeyExpression : IMigrationExpression + public class DeleteForeignKeyExpression : MigrationExpressionBase { public DeleteForeignKeyExpression() { ForeignKey = new ForeignKeyDefinition(); } + public DeleteForeignKeyExpression(DatabaseProviders current, DatabaseProviders[] databaseProviders) + : base(current, databaseProviders) + { + ForeignKey = new ForeignKeyDefinition(); + } + public virtual ForeignKeyDefinition ForeignKey { get; set; } public override string ToString() { + if (IsExpressionSupported() == false) + return string.Empty; + if (ForeignKey.ForeignTable == null) throw new ArgumentNullException("Table name not specified, ensure you have appended the OnTable extension. Format should be Delete.ForeignKey(KeyName).OnTable(TableName)"); + if(CurrentDatabaseProvider == DatabaseProviders.MySql) + { + //MySql naming "convention" for foreignkeys, which aren't explicitly named + if (string.IsNullOrEmpty(ForeignKey.Name)) + ForeignKey.Name = string.Format("{0}_ibfk_1", ForeignKey.ForeignTable.ToLower()); + + return string.Format(SyntaxConfig.SqlSyntaxProvider.DeleteConstraint, + SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(ForeignKey.ForeignTable), + "FOREIGN KEY ", + SyntaxConfig.SqlSyntaxProvider.GetQuotedName(ForeignKey.Name)); + } + + if (string.IsNullOrEmpty(ForeignKey.Name)) + { + ForeignKey.Name = string.Format("FK_{0}_{1}", ForeignKey.ForeignTable, ForeignKey.PrimaryTable); + } + return string.Format(SyntaxConfig.SqlSyntaxProvider.DeleteConstraint, SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(ForeignKey.ForeignTable), - SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(ForeignKey.Name)); + SyntaxConfig.SqlSyntaxProvider.GetQuotedName(ForeignKey.Name)); } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteIndexExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteIndexExpression.cs index 38fe9c3563..e27bf23693 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteIndexExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteIndexExpression.cs @@ -3,13 +3,18 @@ using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions { - public class DeleteIndexExpression : IMigrationExpression + public class DeleteIndexExpression : MigrationExpressionBase { public DeleteIndexExpression() { Index = new IndexDefinition(); } + public DeleteIndexExpression(DatabaseProviders current, DatabaseProviders[] databaseProviders) : base(current, databaseProviders) + { + Index = new IndexDefinition(); + } + public virtual IndexDefinition Index { get; set; } public override string ToString() diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteTableExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteTableExpression.cs index 017244060f..2ae2d36474 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteTableExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteTableExpression.cs @@ -2,8 +2,16 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions { - public class DeleteTableExpression : IMigrationExpression + public class DeleteTableExpression : MigrationExpressionBase { + public DeleteTableExpression() + { + } + + public DeleteTableExpression(DatabaseProviders current, DatabaseProviders[] databaseProviders) : base(current, databaseProviders) + { + } + public virtual string SchemaName { get; set; } public virtual string TableName { get; set; } diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Execute/Expressions/ExecuteSqlStatementExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Execute/Expressions/ExecuteSqlStatementExpression.cs index ce679805f9..a7d3c4432e 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Execute/Expressions/ExecuteSqlStatementExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Execute/Expressions/ExecuteSqlStatementExpression.cs @@ -1,7 +1,15 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Execute.Expressions { - public class ExecuteSqlStatementExpression : IMigrationExpression + public class ExecuteSqlStatementExpression : MigrationExpressionBase { + public ExecuteSqlStatementExpression() + { + } + + public ExecuteSqlStatementExpression(DatabaseProviders current, DatabaseProviders[] databaseProviders) : base(current, databaseProviders) + { + } + public virtual string SqlStatement { get; set; } public override string ToString() diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateColumnExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateColumnExpression.cs index 10ab641cf8..28df1fbb2b 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateColumnExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateColumnExpression.cs @@ -3,24 +3,33 @@ using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Syntax.Expressions { - public class CreateColumnExpression : IMigrationExpression + public class CreateColumnExpression : MigrationExpressionBase { public CreateColumnExpression() { Column = new ColumnDefinition { ModificationType = ModificationType.Create }; } + public CreateColumnExpression(DatabaseProviders current, DatabaseProviders[] databaseProviders) + : base(current, databaseProviders) + { + Column = new ColumnDefinition { ModificationType = ModificationType.Create }; + } + public virtual string SchemaName { get; set; } public virtual string TableName { get; set; } public virtual ColumnDefinition Column { get; set; } public override string ToString() { + if (IsExpressionSupported() == false) + return string.Empty; + if (string.IsNullOrEmpty(Column.TableName)) Column.TableName = TableName; return string.Format(SyntaxConfig.SqlSyntaxProvider.AddColumn, - SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(TableName), + SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(Column.TableName), SyntaxConfig.SqlSyntaxProvider.Format(Column)); } } diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateForeignKeyExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateForeignKeyExpression.cs index c9666654b0..ef523ade12 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateForeignKeyExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateForeignKeyExpression.cs @@ -3,17 +3,26 @@ using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Syntax.Expressions { - public class CreateForeignKeyExpression : IMigrationExpression + public class CreateForeignKeyExpression : MigrationExpressionBase { public CreateForeignKeyExpression() { ForeignKey = new ForeignKeyDefinition(); } + public CreateForeignKeyExpression(DatabaseProviders current, DatabaseProviders[] databaseProviders) + : base(current, databaseProviders) + { + ForeignKey = new ForeignKeyDefinition(); + } + public virtual ForeignKeyDefinition ForeignKey { get; set; } public override string ToString() { + if (IsExpressionSupported() == false) + return string.Empty; + return SyntaxConfig.SqlSyntaxProvider.Format(ForeignKey); } } diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateIndexExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateIndexExpression.cs index d15d1a0d97..5495556d3c 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateIndexExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateIndexExpression.cs @@ -3,13 +3,18 @@ using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Syntax.Expressions { - public class CreateIndexExpression : IMigrationExpression + public class CreateIndexExpression : MigrationExpressionBase { public CreateIndexExpression() { Index = new IndexDefinition(); } + public CreateIndexExpression(DatabaseProviders current, DatabaseProviders[] databaseProviders) : base(current, databaseProviders) + { + Index = new IndexDefinition(); + } + public virtual IndexDefinition Index { get; set; } public override string ToString() diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/IfDatabase/IIfDatabaseBuilder.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/IfDatabase/IIfDatabaseBuilder.cs new file mode 100644 index 0000000000..050af489a9 --- /dev/null +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/IfDatabase/IIfDatabaseBuilder.cs @@ -0,0 +1,13 @@ +using Umbraco.Core.Persistence.Migrations.Syntax.Create; +using Umbraco.Core.Persistence.Migrations.Syntax.Delete; +using Umbraco.Core.Persistence.Migrations.Syntax.Rename; + +namespace Umbraco.Core.Persistence.Migrations.Syntax.IfDatabase +{ + public interface IIfDatabaseBuilder : IFluentSyntax + { + ICreateBuilder Create { get; } + IDeleteBuilder Delete { get; } + IRenameBuilder Rename { get; } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/IfDatabase/IfDatabaseBuilder.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/IfDatabase/IfDatabaseBuilder.cs new file mode 100644 index 0000000000..6657cb9cf4 --- /dev/null +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/IfDatabase/IfDatabaseBuilder.cs @@ -0,0 +1,33 @@ +using Umbraco.Core.Persistence.Migrations.Syntax.Create; +using Umbraco.Core.Persistence.Migrations.Syntax.Delete; +using Umbraco.Core.Persistence.Migrations.Syntax.Rename; + +namespace Umbraco.Core.Persistence.Migrations.Syntax.IfDatabase +{ + public class IfDatabaseBuilder : IIfDatabaseBuilder + { + private readonly IMigrationContext _context; + private readonly DatabaseProviders[] _databaseProviders; + + public IfDatabaseBuilder(IMigrationContext context, params DatabaseProviders[] databaseProviders) + { + _context = context; + _databaseProviders = databaseProviders; + } + + public ICreateBuilder Create + { + get { return new CreateBuilder(_context, _databaseProviders); } + } + + public IDeleteBuilder Delete + { + get { return new DeleteBuilder(_context, _databaseProviders); } + } + + public IRenameBuilder Rename + { + get { return new RenameBuilder(_context, _databaseProviders); } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Insert/Expressions/InsertDataExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Insert/Expressions/InsertDataExpression.cs index b8ca81ce56..36ceb86139 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Insert/Expressions/InsertDataExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Insert/Expressions/InsertDataExpression.cs @@ -3,9 +3,18 @@ using Umbraco.Core.Persistence.DatabaseModelDefinitions; namespace Umbraco.Core.Persistence.Migrations.Syntax.Insert.Expressions { - public class InsertDataExpression : IMigrationExpression + public class InsertDataExpression : MigrationExpressionBase { private readonly List _rows = new List(); + + public InsertDataExpression() + { + } + + public InsertDataExpression(DatabaseProviders current, DatabaseProviders[] databaseProviders) : base(current, databaseProviders) + { + } + public string SchemaName { get; set; } public string TableName { get; set; } diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/Expressions/RenameColumnExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/Expressions/RenameColumnExpression.cs index 795b65c0ef..17d4055f80 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/Expressions/RenameColumnExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/Expressions/RenameColumnExpression.cs @@ -2,15 +2,56 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Rename.Expressions { - public class RenameColumnExpression : IMigrationExpression + public class RenameColumnExpression : MigrationExpressionBase { + public RenameColumnExpression() + { + } + + public RenameColumnExpression(DatabaseProviders current, DatabaseProviders[] databaseProviders) + : base(current, databaseProviders) + { + } + public virtual string SchemaName { get; set; } public virtual string TableName { get; set; } public virtual string OldName { get; set; } public virtual string NewName { get; set; } + public override string Process(Database database) + { + if (CurrentDatabaseProvider == DatabaseProviders.MySql) + { + string columnDefinitionSql = string.Format(@" +SELECT CONCAT( + CAST(COLUMN_TYPE AS CHAR), + IF(ISNULL(CHARACTER_SET_NAME), + '', + CONCAT(' CHARACTER SET ', CHARACTER_SET_NAME)), + IF(ISNULL(COLLATION_NAME), + '', + CONCAT(' COLLATE ', COLLATION_NAME)), + ' ', + IF(IS_NULLABLE = 'NO', 'NOT NULL ', ''), + IF(IS_NULLABLE = 'NO' AND COLUMN_DEFAULT IS NULL, + '', + CONCAT('DEFAULT ', QUOTE(COLUMN_DEFAULT), ' ')), + UPPER(extra)) + FROM INFORMATION_SCHEMA.COLUMNS + WHERE TABLE_NAME = '{0}' AND COLUMN_NAME = '{1}'", TableName, OldName); + + var columnDefinition = database.ExecuteScalar(columnDefinitionSql); + return this.ToString() + " " + columnDefinition; + } + + return this.ToString(); + } + public override string ToString() { + if (IsExpressionSupported() == false) + return string.Empty; + return SyntaxConfig.SqlSyntaxProvider.FormatColumnRename(TableName, OldName, NewName); } } diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/Expressions/RenameTableExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/Expressions/RenameTableExpression.cs index 3e3c5d8aee..349db29c47 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/Expressions/RenameTableExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/Expressions/RenameTableExpression.cs @@ -2,14 +2,26 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Rename.Expressions { - public class RenameTableExpression : IMigrationExpression + public class RenameTableExpression : MigrationExpressionBase { + public RenameTableExpression() + { + } + + public RenameTableExpression(DatabaseProviders current, DatabaseProviders[] databaseProviders) + : base(current, databaseProviders) + { + } + public virtual string SchemaName { get; set; } public virtual string OldName { get; set; } public virtual string NewName { get; set; } public override string ToString() { + if (IsExpressionSupported() == false) + return string.Empty; + return SyntaxConfig.SqlSyntaxProvider.FormatTableRename(OldName, NewName); } } diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/RenameBuilder.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/RenameBuilder.cs index 3034de1215..7116935d77 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/RenameBuilder.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/RenameBuilder.cs @@ -7,22 +7,28 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Rename public class RenameBuilder : IRenameBuilder { private readonly IMigrationContext _context; + private readonly DatabaseProviders[] _databaseProviders; - public RenameBuilder(IMigrationContext context) + public RenameBuilder(IMigrationContext context, params DatabaseProviders[] databaseProviders) { _context = context; + _databaseProviders = databaseProviders; } public IRenameTableSyntax Table(string oldName) { - var expression = new RenameTableExpression { OldName = oldName }; + var expression = _databaseProviders == null + ? new RenameTableExpression {OldName = oldName} + : new RenameTableExpression(_context.CurrentDatabaseProvider, _databaseProviders) { OldName = oldName }; _context.Expressions.Add(expression); return new RenameTableBuilder(expression); } public IRenameColumnTableSyntax Column(string oldName) { - var expression = new RenameColumnExpression { OldName = oldName }; + var expression = _databaseProviders == null + ? new RenameColumnExpression {OldName = oldName} + : new RenameColumnExpression(_context.CurrentDatabaseProvider, _databaseProviders) { OldName = oldName }; _context.Expressions.Add(expression); return new RenameColumnBuilder(expression); } diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Update/Expressions/UpdateDataExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Update/Expressions/UpdateDataExpression.cs index cac88440e8..c3cfbcda0f 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Update/Expressions/UpdateDataExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Update/Expressions/UpdateDataExpression.cs @@ -3,8 +3,16 @@ using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Syntax.Update.Expressions { - public class UpdateDataExpression : IMigrationExpression + public class UpdateDataExpression : MigrationExpressionBase { + public UpdateDataExpression() + { + } + + public UpdateDataExpression(DatabaseProviders current, DatabaseProviders[] databaseProviders) : base(current, databaseProviders) + { + } + public string SchemaName { get; set; } public string TableName { get; set; } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionFourEightZero/RemoveUmbracoAppConstraints.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionFourEightZero/RemoveUmbracoAppConstraints.cs index ecc6c06347..22c656abe6 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionFourEightZero/RemoveUmbracoAppConstraints.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionFourEightZero/RemoveUmbracoAppConstraints.cs @@ -1,15 +1,16 @@ using System.Data; +using Umbraco.Core.Configuration; namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionFourEightZero { - [MigrationAttribute("4.8.0", 0)] + [MigrationAttribute("4.8.0", 0, GlobalSettings.UmbracoMigrationName)] public class RemoveUmbracoAppConstraints : MigrationBase { public override void Up() { - Delete.ForeignKey("FK_umbracoUser2app_umbracoApp").OnTable("umbracoUser2app"); + Delete.ForeignKey().FromTable("umbracoUser2app").ForeignColumn("app").ToTable("umbracoApp").PrimaryColumn("appAlias"); - Delete.ForeignKey("FK_umbracoAppTree_umbracoApp").OnTable("umbracoAppTree"); + Delete.ForeignKey().FromTable("umbracoAppTree").ForeignColumn("appAlias").ToTable("umbracoApp").PrimaryColumn("appAlias"); } public override void Down() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/DeleteAppTables.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/DeleteAppTables.cs index afc25de1ef..4b41295d3b 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/DeleteAppTables.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/DeleteAppTables.cs @@ -1,6 +1,8 @@ -namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth +using Umbraco.Core.Configuration; + +namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth { - [MigrationAttribute("6.0.0", 10)] + [MigrationAttribute("6.0.0", 10, GlobalSettings.UmbracoMigrationName)] public class DeleteAppTables : MigrationBase { public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/EnsureAppsTreesUpdated.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/EnsureAppsTreesUpdated.cs index 46cc68981d..09f5191f68 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/EnsureAppsTreesUpdated.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/EnsureAppsTreesUpdated.cs @@ -1,8 +1,9 @@ using System; +using Umbraco.Core.Configuration; namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth { - [MigrationAttribute("6.0.0", 9)] + [MigrationAttribute("6.0.0", 9, GlobalSettings.UmbracoMigrationName)] public class EnsureAppsTreesUpdated : MigrationBase { public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/MoveMasterContentTypeData.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/MoveMasterContentTypeData.cs index f75abfb65e..235f7a0a8a 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/MoveMasterContentTypeData.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/MoveMasterContentTypeData.cs @@ -1,12 +1,14 @@ -namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth +using Umbraco.Core.Configuration; + +namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth { - [MigrationAttribute("6.0.0", 5)] + [MigrationAttribute("6.0.0", 5, GlobalSettings.UmbracoMigrationName)] public class MoveMasterContentTypeData : MigrationBase { public override void Up() { Execute.Sql( - "INSERT INTO [cmsContentType2ContentType] (parentContentTypeId, childContentTypeId) SELECT masterContentType, nodeId FROM [cmsContentType] WHERE not [masterContentType] is null and [masterContentType] != 0"); + "INSERT INTO cmsContentType2ContentType (parentContentTypeId, childContentTypeId) SELECT masterContentType, nodeId FROM cmsContentType WHERE not masterContentType is null and masterContentType != 0"); } public override void Down() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/NewCmsContentType2ContentTypeTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/NewCmsContentType2ContentTypeTable.cs index 20c301f0c6..3366691e0d 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/NewCmsContentType2ContentTypeTable.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/NewCmsContentType2ContentTypeTable.cs @@ -1,6 +1,8 @@ -namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth +using Umbraco.Core.Configuration; + +namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth { - [MigrationAttribute("6.0.0", 4)] + [MigrationAttribute("6.0.0", 4, GlobalSettings.UmbracoMigrationName)] public class NewCmsContentType2ContentTypeTable : MigrationBase { public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/RemoveMasterContentTypeColumn.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/RemoveMasterContentTypeColumn.cs index 3741a945f1..7dc9b1bb19 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/RemoveMasterContentTypeColumn.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/RemoveMasterContentTypeColumn.cs @@ -1,13 +1,15 @@ -namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth +using Umbraco.Core.Configuration; + +namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth { - [MigrationAttribute("6.0.0", 6)] + [MigrationAttribute("6.0.0", 6, GlobalSettings.UmbracoMigrationName)] public class RemoveMasterContentTypeColumn : MigrationBase { public override void Up() { //NOTE Don't think we can remove this column yet as it seems to be used by some starterkits - //Delete.UniqueConstraint("DF_cmsContentType_masterContentType").FromTable("cmsContentType"); - Delete.DefaultConstraint().OnTable("cmsContentType").OnColumn("masterContentType"); + IfDatabase(DatabaseProviders.SqlAzure, DatabaseProviders.SqlServer, DatabaseProviders.SqlServerCE) + .Delete.DefaultConstraint().OnTable("cmsContentType").OnColumn("masterContentType"); Delete.Column("masterContentType").FromTable("cmsContentType"); } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/RenameCmsTabTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/RenameCmsTabTable.cs index bf52c3c090..9aaeb6b1a5 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/RenameCmsTabTable.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/RenameCmsTabTable.cs @@ -1,6 +1,8 @@ -namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth +using Umbraco.Core.Configuration; + +namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth { - [MigrationAttribute("6.0.0", 0)] + [MigrationAttribute("6.0.0", 0, GlobalSettings.UmbracoMigrationName)] public class RenameCmsTabTable : MigrationBase { public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/RenameTabIdColumn.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/RenameTabIdColumn.cs index 7a07df5842..31e8f18a0a 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/RenameTabIdColumn.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/RenameTabIdColumn.cs @@ -1,16 +1,75 @@ -namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth +using System.Data; +using Umbraco.Core.Configuration; + +namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth { - [MigrationAttribute("6.0.0", 7)] + [MigrationAttribute("6.0.0", 7, GlobalSettings.UmbracoMigrationName)] public class RenameTabIdColumn : MigrationBase { public override void Up() { + //Conditional Create-column for Sql Ce databases + IfDatabase(DatabaseProviders.SqlServerCE) + .Create.Column("propertyTypeGroupId").OnTable("cmsPropertyType").AsInt16().Nullable(); + + //Conditional Create-foreign for Sql Ce databases + IfDatabase(DatabaseProviders.SqlServerCE) + .Create.ForeignKey("FK_cmsPropertyType_cmsPropertyTypeGroup") + .FromTable("cmsPropertyType").ForeignColumn("propertyTypeGroupId") + .ToTable("cmsPropertyTypeGroup").PrimaryColumn("id").OnDeleteOrUpdate(Rule.None); + + //Conditional Delete-foreignkey for MySql databases + IfDatabase(DatabaseProviders.MySql) + .Delete.ForeignKey().FromTable("cmsPropertyType").ForeignColumn("tabId").ToTable("cmsPropertyTypeGroup").PrimaryColumn("id"); + Rename.Column("tabId").OnTable("cmsPropertyType").To("propertyTypeGroupId"); + + //Conditional Create-foreign for MySql databases + IfDatabase(DatabaseProviders.MySql) + .Create.ForeignKey("FK_cmsPropertyType_cmsPropertyTypeGroup") + .FromTable("cmsPropertyType").ForeignColumn("propertyTypeGroupId") + .ToTable("cmsPropertyTypeGroup").PrimaryColumn("id").OnDeleteOrUpdate(Rule.None); + + //Conditional Delete-foreignkey for Sql Ce databases + IfDatabase(DatabaseProviders.SqlServerCE) + .Delete.ForeignKey("FK_cmsPropertyType_cmsTab").OnTable("cmsPropertyType"); + + //Conditional Delete-column for Sql Ce databases + IfDatabase(DatabaseProviders.SqlServerCE) + .Delete.Column("tabId").FromTable("cmsPropertyType"); } public override void Down() { + //Conditional Create-column for Sql Ce databases + IfDatabase(DatabaseProviders.SqlServerCE) + .Create.Column("tabId").OnTable("cmsPropertyType").AsInt16().Nullable(); + + //Conditional Create-foreign for Sql Ce databases + IfDatabase(DatabaseProviders.SqlServerCE) + .Create.ForeignKey("FK_cmsPropertyType_cmsTab") + .FromTable("cmsPropertyType").ForeignColumn("tabId") + .ToTable("cmsTab").PrimaryColumn("id").OnDeleteOrUpdate(Rule.None); + + //Conditional Delete-foreignkey for MySql databases + IfDatabase(DatabaseProviders.MySql) + .Delete.ForeignKey().FromTable("cmsPropertyType").ForeignColumn("propertyTypeGroupId").ToTable("cmsPropertyTypeGroup").PrimaryColumn("id"); + Rename.Column("propertyTypeGroupId").OnTable("cmsPropertyType").To("tabId"); + + //Conditional Create-foreign for MySql databases + IfDatabase(DatabaseProviders.MySql) + .Create.ForeignKey("FK_cmsPropertyType_cmsPropertyTypeGroup") + .FromTable("cmsPropertyType").ForeignColumn("tabId") + .ToTable("cmsPropertyTypeGroup").PrimaryColumn("id").OnDeleteOrUpdate(Rule.None); + + //Conditional Delete-foreignkey for Sql Ce databases + IfDatabase(DatabaseProviders.SqlServerCE) + .Delete.ForeignKey("FK_cmsPropertyType_cmsPropertyTypeGroup").OnTable("cmsPropertyType"); + + //Conditional Delete-column for Sql Ce databases + IfDatabase(DatabaseProviders.SqlServerCE) + .Delete.Column("propertyTypeGroupId").FromTable("propertyTypeGroupId"); } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/UpdateCmsContentTypeAllowedContentTypeTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/UpdateCmsContentTypeAllowedContentTypeTable.cs index 901e8b5613..3b5d86ad79 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/UpdateCmsContentTypeAllowedContentTypeTable.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/UpdateCmsContentTypeAllowedContentTypeTable.cs @@ -1,6 +1,8 @@ -namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth +using Umbraco.Core.Configuration; + +namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth { - [MigrationAttribute("6.0.0", 3)] + [MigrationAttribute("6.0.0", 3, GlobalSettings.UmbracoMigrationName)] public class UpdateCmsContentTypeAllowedContentTypeTable : MigrationBase { public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/UpdateCmsContentTypeTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/UpdateCmsContentTypeTable.cs index a7dd07f38e..35f0e76c36 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/UpdateCmsContentTypeTable.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/UpdateCmsContentTypeTable.cs @@ -1,6 +1,8 @@ -namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth +using Umbraco.Core.Configuration; + +namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth { - [MigrationAttribute("6.0.0", 2)] + [MigrationAttribute("6.0.0", 2, GlobalSettings.UmbracoMigrationName)] public class UpdateCmsContentTypeTable : MigrationBase { public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/UpdateCmsContentVersionTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/UpdateCmsContentVersionTable.cs index 4ba6286215..55d1234022 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/UpdateCmsContentVersionTable.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/UpdateCmsContentVersionTable.cs @@ -1,6 +1,8 @@ -namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth +using Umbraco.Core.Configuration; + +namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth { - [MigrationAttribute("6.0.0", 8)] + [MigrationAttribute("6.0.0", 8, GlobalSettings.UmbracoMigrationName)] public class UpdateCmsContentVersionTable : MigrationBase { public override void Up() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/UpdateCmsPropertyTypeGroupTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/UpdateCmsPropertyTypeGroupTable.cs index 1e89861938..62938eb1d3 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/UpdateCmsPropertyTypeGroupTable.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixth/UpdateCmsPropertyTypeGroupTable.cs @@ -1,17 +1,15 @@ using System.Data; +using Umbraco.Core.Configuration; namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth { - [MigrationAttribute("6.0.0", 1)] + [MigrationAttribute("6.0.0", 1, GlobalSettings.UmbracoMigrationName)] public class UpdateCmsPropertyTypeGroupTable : MigrationBase { public override void Up() { Alter.Table("cmsPropertyTypeGroup").AddColumn("parentGroupId").AsInt16().Nullable(); - Create.UniqueConstraint("df_cmsPropertyTypeGroup_parentGroupId") - .OnTable("cmsPropertyTypeGroup").Column("parentGroupId"); - Create.ForeignKey("FK_cmsPropertyTypeGroup_cmsPropertyTypeGroup") .FromTable("cmsPropertyTypeGroup").ForeignColumn("parentGroupId") .ToTable("cmsPropertyTypeGroup").PrimaryColumn("id").OnDeleteOrUpdate(Rule.None); @@ -21,8 +19,6 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixth { Delete.ForeignKey("FK_cmsPropertyTypeGroup_cmsPropertyTypeGroup").OnTable("cmsPropertyTypeGroup"); - Delete.UniqueConstraint("df_cmsPropertyTypeGroup_parentGroupId").FromTable("cmsPropertyTypeGroup"); - Delete.Column("parentGroupId").FromTable("cmsPropertyTypeGroup"); } } diff --git a/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs b/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs index 33e6bd76e9..fba115a508 100644 --- a/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs +++ b/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs @@ -43,7 +43,7 @@ namespace Umbraco.Core.Persistence db.DropTable(tableName); } - if (!tableExist) + if (tableExist == false) { using (var transaction = db.GetTransaction()) { @@ -64,14 +64,14 @@ namespace Umbraco.Core.Persistence var e = new TableCreationEventArgs(); //Turn on identity insert if db provider is not mysql - if (ApplicationContext.Current.DatabaseContext.ProviderName.Contains("MySql") == false && tableDefinition.Columns.Any(x => x.IsIdentity)) + if (SyntaxConfig.SqlSyntaxProvider.SupportsIdentityInsert() && tableDefinition.Columns.Any(x => x.IsIdentity)) db.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} ON ", SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName)))); //Call the NewTable-event to trigger the insert of base/default data NewTable(tableName, db, e); //Turn off identity insert if db provider is not mysql - if (ApplicationContext.Current.DatabaseContext.ProviderName.Contains("MySql") == false && tableDefinition.Columns.Any(x => x.IsIdentity)) + if (SyntaxConfig.SqlSyntaxProvider.SupportsIdentityInsert() && tableDefinition.Columns.Any(x => x.IsIdentity)) db.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} OFF;", SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName)))); } @@ -89,16 +89,6 @@ namespace Umbraco.Core.Persistence LogHelper.Info(string.Format("Create Index sql {0}:\n {1}", createdIndex, sql)); } - //Specific to Sql Ce - look for changes to Identity Seed - //if (ApplicationContext.Current.DatabaseContext.ProviderName.Contains("SqlServerCe")) - //{ - // var seedSql = SyntaxConfig.SqlSyntaxProvider.ToAlterIdentitySeedStatements(tableDefinition); - // foreach (var sql in seedSql) - // { - // int createdSeed = db.Execute(new Sql(sql)); - // } - //} - transaction.Complete(); } } @@ -144,6 +134,11 @@ namespace Umbraco.Core.Persistence NewTable -= PetaPocoExtensions_NewTable; } + public static DatabaseProviders GetDatabaseProvider(this Database db) + { + return ApplicationContext.Current.DatabaseContext.DatabaseProvider; + } + private static void PetaPocoExtensions_NewTable(string tableName, Database db, TableCreationEventArgs e) { var baseDataCreation = new BaseDataCreation(db); diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs index f98218f159..02426fba52 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs @@ -46,5 +46,6 @@ namespace Umbraco.Core.Persistence.SqlSyntax string FormatColumnRename(string tableName, string oldName, string newName); string FormatTableRename(string oldName, string newName); bool SupportsClustered(); + bool SupportsIdentityInsert(); } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs index 32236bc667..2f03003899 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs @@ -29,13 +29,35 @@ namespace Umbraco.Core.Persistence.SqlSyntax AutoIncrementDefinition = "AUTO_INCREMENT"; IntColumnDefinition = "int(11)"; BoolColumnDefinition = "tinyint(1)"; + DateTimeColumnDefinition = "TIMESTAMP"; TimeColumnDefinition = "time"; DecimalColumnDefinition = "decimal(38,6)"; - GuidColumnDefinition = "char(32)"; + GuidColumnDefinition = "char(36)"; InitColumnTypeMap(); - DefaultValueFormat = " DEFAULT '{0}'"; + DefaultValueFormat = "DEFAULT '{0}'"; + } + + public override bool DoesTableExist(Database db, string tableName) + { + db.OpenSharedConnection(); + var result = + db.ExecuteScalar("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES " + + "WHERE TABLE_NAME = @TableName AND " + + "TABLE_SCHEMA = @TableSchema", new { TableName = tableName, TableSchema = db.Connection.Database }); + + return result > 0; + } + + public override bool SupportsClustered() + { + return true; + } + + public override bool SupportsIdentityInsert() + { + return false; } public override string GetQuotedTableName(string tableName) @@ -65,6 +87,24 @@ namespace Umbraco.Core.Persistence.SqlSyntax return "NVARCHAR"; } + public override string Format(TableDefinition table) + { + string primaryKey = string.Empty; + var columnDefinition = table.Columns.FirstOrDefault(x => x.IsPrimaryKey); + if (columnDefinition != null && columnDefinition.PrimaryKeyColumns.Contains(",") == false) + { + string columns = string.IsNullOrEmpty(columnDefinition.PrimaryKeyColumns) + ? GetQuotedColumnName(columnDefinition.Name) + : columnDefinition.PrimaryKeyColumns; + + primaryKey = string.Format(", \nPRIMARY KEY {0} ({1})", columnDefinition.IsIndexed ? "CLUSTERED" : "NONCLUSTERED", columns); + } + + var statement = string.Format(CreateTable, GetQuotedTableName(table.Name), Format(table.Columns), primaryKey); + + return statement; + } + public override string Format(IndexDefinition index) { string name = string.IsNullOrEmpty(index.Name) @@ -81,20 +121,25 @@ namespace Umbraco.Core.Persistence.SqlSyntax columns); } - public override bool DoesTableExist(Database db, string tableName) + public override string Format(ForeignKeyDefinition foreignKey) { - db.OpenSharedConnection(); - var result = - db.ExecuteScalar("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES " + - "WHERE TABLE_NAME = @TableName AND " + - "TABLE_SCHEMA = @TableSchema", new { TableName = tableName, TableSchema = db.Connection.Database }); - - return result > 0; + return string.Format(CreateForeignKeyConstraint, + GetQuotedTableName(foreignKey.ForeignTable), + GetQuotedColumnName(foreignKey.ForeignColumns.First()), + GetQuotedTableName(foreignKey.PrimaryTable), + GetQuotedColumnName(foreignKey.PrimaryColumns.First()), + FormatCascade("DELETE", foreignKey.OnDelete), + FormatCascade("UPDATE", foreignKey.OnUpdate)); } - public override bool SupportsClustered() + public override string FormatPrimaryKey(TableDefinition table) { - return false; + return string.Empty; + } + + protected override string FormatConstraint(ColumnDefinition column) + { + return string.Empty; } protected override string FormatIdentity(ColumnDefinition column) @@ -125,9 +170,6 @@ namespace Umbraco.Core.Persistence.SqlSyntax protected override string FormatPrimaryKey(ColumnDefinition column) { - if(column.IsPrimaryKey) - return "PRIMARY KEY"; - return string.Empty; } @@ -158,12 +200,17 @@ namespace Umbraco.Core.Persistence.SqlSyntax public override string AlterColumn { get { return "ALTER TABLE {0} MODIFY COLUMN {1}"; } } + //CREATE TABLE {0} ({1}) ENGINE = INNODB versus CREATE TABLE {0} ({1}) ENGINE = MYISAM ? + public override string CreateTable { get { return "CREATE TABLE {0} ({1}{2})"; } } + + public override string CreateIndex { get { return "CREATE INDEX {0} ON {1} ({2})"; } } + + public override string CreateForeignKeyConstraint { get { return "ALTER TABLE {0} ADD FOREIGN KEY ({1}) REFERENCES {2} ({3}){4}{5}"; } } + public override string DeleteConstraint { get { return "ALTER TABLE {0} DROP {1}{2}"; } } public override string DropIndex { get { return "DROP INDEX {0} ON {1}"; } } - public override string CreateTable { get { return "CREATE TABLE {0} ({1}) ENGINE = INNODB"; } } - - public override string CreateIndex { get { return "CREATE INDEX {0} ON {1} ({2})"; } } + public override string RenameColumn { get { return "ALTER TABLE {0} CHANGE {1} {2}"; } } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs index b3947f4f8a..a4f2a9d7ce 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs @@ -76,12 +76,11 @@ namespace Umbraco.Core.Persistence.SqlSyntax public override string FormatColumnRename(string tableName, string oldName, string newName) { - var sb = new StringBuilder(); + //NOTE Sql CE doesn't support renaming a column, so a new column needs to be created, then copy data and finally remove old column + //This assumes that the new column has been created, and that the old column will be deleted after this statement has run. //http://stackoverflow.com/questions/3967353/microsoft-sql-compact-edition-rename-column - //Create new column - sb.AppendFormat("UPDATE {0} SET {1} = {2}", tableName, newName, oldName); - //Delete old column - return sb.ToString(); + + return string.Format("UPDATE {0} SET {1} = {2}", tableName, newName, oldName); } public override string FormatTableRename(string oldName, string newName) @@ -153,7 +152,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax { get { - return "ALTER TABLE {0} ALTER COLUMN {1} DROP DEFAULT"; + return "ALTER TABLE [{0}] ALTER COLUMN [{1}] DROP DEFAULT"; } } diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs index 995320a037..b97033c17c 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs @@ -97,24 +97,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax public override string DeleteDefaultConstraint { - get - { - return "DECLARE @default sysname, @sql nvarchar(max);\r\n\r\n" + - "-- get name of default constraint\r\n" + - "SELECT @default = name\r\n" + - "FROM sys.default_constraints\r\n" + - "WHERE parent_object_id = object_id('{0}')\r\n" + "" + - "AND type = 'D'\r\n" + "" + - "AND parent_column_id = (\r\n" + "" + - "SELECT column_id\r\n" + - "FROM sys.columns\r\n" + - "WHERE object_id = object_id('{0}')\r\n" + - "AND name = '{1}'\r\n" + - ");\r\n\r\n" + - "-- create alter table command to drop contraint as string and run it\r\n" + - "SET @sql = N'ALTER TABLE {0} DROP CONSTRAINT ' + @default;\r\n" + - "EXEC sp_executesql @sql;"; - } + get { return "ALTER TABLE [{0}] DROP CONSTRAINT [DF_{0}_{1}]"; } } public override string AddColumn { get { return "ALTER TABLE {0} ADD {1}"; } } diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs index 2eb3013ce2..e2e6cb3e9f 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs @@ -161,6 +161,11 @@ namespace Umbraco.Core.Persistence.SqlSyntax return true; } + public virtual bool SupportsIdentityInsert() + { + return true; + } + public virtual string Format(TableDefinition table) { var statement = string.Format(CreateTable, GetQuotedTableName(table.Name), Format(table.Columns)); diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index cd5b8baaad..81351de603 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -253,11 +253,14 @@ + + + @@ -341,6 +344,8 @@ + + diff --git a/src/Umbraco.Tests/Migrations/AlterMigrationTests.cs b/src/Umbraco.Tests/Migrations/AlterMigrationTests.cs index 8633875dba..3ebe04a48d 100644 --- a/src/Umbraco.Tests/Migrations/AlterMigrationTests.cs +++ b/src/Umbraco.Tests/Migrations/AlterMigrationTests.cs @@ -1,7 +1,7 @@ using System; using System.Linq; using NUnit.Framework; -using Umbraco.Core.ObjectResolution; +using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Migrations; using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Tests.Migrations.Stubs; @@ -21,7 +21,7 @@ namespace Umbraco.Tests.Migrations public void Can_Get_Up_Migration_From_MigrationStub() { // Arrange - var context = new MigrationContext(); + var context = new MigrationContext(DatabaseProviders.SqlServerCE); var stub = new AlterUserTableMigrationStub(); // Act diff --git a/src/Umbraco.Tests/Migrations/FindingMigrationsTest.cs b/src/Umbraco.Tests/Migrations/FindingMigrationsTest.cs index 83e4872c32..c148ec222e 100644 --- a/src/Umbraco.Tests/Migrations/FindingMigrationsTest.cs +++ b/src/Umbraco.Tests/Migrations/FindingMigrationsTest.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using NUnit.Framework; using Umbraco.Core; +using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Migrations; using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Tests.Migrations.Stubs; @@ -60,7 +61,7 @@ namespace Umbraco.Tests.Migrations Assert.That(list.Count, Is.EqualTo(3)); - var context = new MigrationContext(); + var context = new MigrationContext(DatabaseProviders.SqlServerCE); foreach (MigrationBase migration in list) { migration.GetUpExpressions(context); diff --git a/src/Umbraco.Tests/Migrations/SqlCeUpgradeTest.cs b/src/Umbraco.Tests/Migrations/SqlCeUpgradeTest.cs deleted file mode 100644 index 2ea7151503..0000000000 --- a/src/Umbraco.Tests/Migrations/SqlCeUpgradeTest.cs +++ /dev/null @@ -1,136 +0,0 @@ -using System; -using System.Configuration; -using System.Data.SqlServerCe; -using System.IO; -using System.Text.RegularExpressions; -using NUnit.Framework; -using SQLCE4Umbraco; -using Umbraco.Core; -using Umbraco.Core.Configuration; -using Umbraco.Core.ObjectResolution; -using Umbraco.Core.Persistence; -using Umbraco.Core.Persistence.Migrations; -using Umbraco.Core.Persistence.UnitOfWork; -using Umbraco.Core.Publishing; -using Umbraco.Core.Services; -using Umbraco.Tests.TestHelpers; - -namespace Umbraco.Tests.Migrations -{ - [TestFixture] - public class SqlCeUpgradeTest - { - /// Regular expression that finds multiline block comments. - private static readonly Regex m_findComments = new Regex(@"\/\*.*?\*\/", RegexOptions.Singleline | RegexOptions.Compiled); - - [SetUp] - public void Initialize() - { - TestHelper.SetupLog4NetForTests(); - TestHelper.InitializeContentDirectories(); - - string path = TestHelper.CurrentAssemblyDirectory; - AppDomain.CurrentDomain.SetData("DataDirectory", path); - - UmbracoSettings.UseLegacyXmlSchema = false; - - //this ensures its reset - PluginManager.Current = new PluginManager(false); - - //for testing, we'll specify which assemblies are scanned for the PluginTypeResolver - PluginManager.Current.AssembliesToScan = new[] - { - typeof (MigrationRunner).Assembly - }; - - RepositoryResolver.Current = new RepositoryResolver( - new RepositoryFactory()); - - //Delete database file before continueing - string filePath = string.Concat(path, "\\UmbracoPetaPocoTests.sdf"); - if (File.Exists(filePath)) - { - File.Delete(filePath); - } - - //Get the connectionstring settings from config - var settings = ConfigurationManager.ConnectionStrings["umbracoDbDsn"]; - ConfigurationManager.AppSettings.Set("umbracoDbDSN", @"datalayer=SQLCE4Umbraco.SqlCEHelper,SQLCE4Umbraco;data source=|DataDirectory|\UmbracoPetaPocoTests.sdf"); - - //Create the Sql CE database - var engine = new SqlCeEngine(settings.ConnectionString); - engine.CreateDatabase(); - - Resolution.Freeze(); - ApplicationContext.Current = new ApplicationContext( - //assign the db context - new DatabaseContext(new DefaultDatabaseFactory()), - //assign the service context - new ServiceContext(new PetaPocoUnitOfWorkProvider(), new FileUnitOfWorkProvider(), new PublishingStrategy())) { IsReady = true }; - - ApplicationContext.Current.DatabaseContext.Initialize(); - } - - [Test] - public void Can_Upgrade_From_470_To_600() - { - var configuredVersion = new Version("4.7.0"); - var targetVersion = new Version("6.0.0"); - var db = ApplicationContext.Current.DatabaseContext.Database; - - //Create db schema and data from old Total.sql file for Sql Ce - string statements = SqlScripts.SqlResources.SqlCeTotal_480; - // replace block comments by whitespace - statements = m_findComments.Replace(statements, " "); - // execute all non-empty statements - foreach (string statement in statements.Split(";".ToCharArray())) - { - string rawStatement = statement.Trim(); - if (rawStatement.Length > 0) - db.Execute(rawStatement); - } - - //Setup the MigrationRunner - var migrationRunner = new MigrationRunner(configuredVersion, targetVersion); - bool upgraded = migrationRunner.Execute(db, true); - - Assert.That(upgraded, Is.True); - - bool hasTabTable = db.TableExist("cmsTab"); - bool hasPropertyTypeGroupTable = db.TableExist("cmsPropertyTypeGroup"); - bool hasAppTreeTable = db.TableExist("umbracoAppTree"); - - Assert.That(hasTabTable, Is.False); - Assert.That(hasPropertyTypeGroupTable, Is.True); - Assert.That(hasAppTreeTable, Is.False); - } - - [TearDown] - public void TearDown() - { - ApplicationContext.Current.DatabaseContext.Database.Dispose(); - //reset the app context - ApplicationContext.Current.ApplicationCache.ClearAllCache(); - - //legacy API database connection close - SqlCeContextGuardian.CloseBackgroundConnection(); - - PluginManager.Current = null; - - ApplicationContext.Current = null; - Resolution.IsFrozen = false; - RepositoryResolver.Reset(); - - TestHelper.CleanContentDirectories(); - - string path = TestHelper.CurrentAssemblyDirectory; - AppDomain.CurrentDomain.SetData("DataDirectory", null); - - string filePath = string.Concat(path, "\\UmbracoPetaPocoTests.sdf"); - if (File.Exists(filePath)) - { - File.Delete(filePath); - } - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Tests/Migrations/Stubs/AlterUserTableMigrationStub.cs b/src/Umbraco.Tests/Migrations/Stubs/AlterUserTableMigrationStub.cs index 315caf08d7..90828bb89c 100644 --- a/src/Umbraco.Tests/Migrations/Stubs/AlterUserTableMigrationStub.cs +++ b/src/Umbraco.Tests/Migrations/Stubs/AlterUserTableMigrationStub.cs @@ -2,7 +2,7 @@ namespace Umbraco.Tests.Migrations.Stubs { - [MigrationAttribute("6.0.0", 0)] + [MigrationAttribute("6.0.0", 0, "Test")] public class AlterUserTableMigrationStub : MigrationBase { public override void Up() diff --git a/src/Umbraco.Tests/Migrations/Stubs/FourNineMigration.cs b/src/Umbraco.Tests/Migrations/Stubs/FourNineMigration.cs index f26dfbbc15..7226dd0ace 100644 --- a/src/Umbraco.Tests/Migrations/Stubs/FourNineMigration.cs +++ b/src/Umbraco.Tests/Migrations/Stubs/FourNineMigration.cs @@ -2,7 +2,7 @@ namespace Umbraco.Tests.Migrations.Stubs { - [MigrationAttribute("6.0.0", 1)] + [MigrationAttribute("6.0.0", 1, "Test")] public class FourNineMigration : MigrationBase { public override void Up() @@ -16,7 +16,7 @@ namespace Umbraco.Tests.Migrations.Stubs } } - [MigrationAttribute("6.0.0", 2)] + [MigrationAttribute("6.0.0", 2, "Test")] public class FourTenMigration : MigrationBase { public override void Up() @@ -30,7 +30,7 @@ namespace Umbraco.Tests.Migrations.Stubs } } - [MigrationAttribute("4.11.0", 0)] + [MigrationAttribute("4.11.0", 0, "Test")] public class FourElevenMigration : MigrationBase { public override void Up() diff --git a/src/Umbraco.Tests/Migrations/TargetVersionSixthMigrationsTest.cs b/src/Umbraco.Tests/Migrations/TargetVersionSixthMigrationsTest.cs index 5422c3c06d..2b15022dd6 100644 --- a/src/Umbraco.Tests/Migrations/TargetVersionSixthMigrationsTest.cs +++ b/src/Umbraco.Tests/Migrations/TargetVersionSixthMigrationsTest.cs @@ -2,9 +2,11 @@ using System.Linq; using NUnit.Framework; using Umbraco.Core; +using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Migrations; using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Tests.TestHelpers; +using GlobalSettings = Umbraco.Core.Configuration.GlobalSettings; namespace Umbraco.Tests.Migrations { @@ -44,10 +46,10 @@ namespace Umbraco.Tests.Migrations var targetVersion = new Version("6.0.0"); var foundMigrations = PluginManager.Current.FindMigrations(); - var migrationRunner = new MigrationRunner(configuredVersion, targetVersion); + var migrationRunner = new MigrationRunner(configuredVersion, targetVersion, GlobalSettings.UmbracoMigrationName); var migrations = migrationRunner.OrderedUpgradeMigrations(foundMigrations); - var context = new MigrationContext(); + var context = new MigrationContext(DatabaseProviders.SqlServerCE); foreach (MigrationBase migration in migrations) { migration.GetUpExpressions(context); diff --git a/src/Umbraco.Tests/Migrations/Upgrades/BaseUpgradeTest.cs b/src/Umbraco.Tests/Migrations/Upgrades/BaseUpgradeTest.cs new file mode 100644 index 0000000000..54a8232e68 --- /dev/null +++ b/src/Umbraco.Tests/Migrations/Upgrades/BaseUpgradeTest.cs @@ -0,0 +1,102 @@ +using System; +using System.Text.RegularExpressions; +using NUnit.Framework; +using Umbraco.Core; +using Umbraco.Core.Configuration; +using Umbraco.Core.Persistence; +using Umbraco.Core.Persistence.Migrations; +using Umbraco.Core.Persistence.SqlSyntax; +using Umbraco.Tests.TestHelpers; +using GlobalSettings = Umbraco.Core.Configuration.GlobalSettings; + +namespace Umbraco.Tests.Migrations.Upgrades +{ + [TestFixture] + public abstract class BaseUpgradeTest + { + /// Regular expression that finds multiline block comments. + private static readonly Regex m_findComments = new Regex(@"\/\*.*?\*\/", RegexOptions.Singleline | RegexOptions.Compiled); + + [SetUp] + public virtual void Initialize() + { + TestHelper.SetupLog4NetForTests(); + TestHelper.InitializeContentDirectories(); + + Path = TestHelper.CurrentAssemblyDirectory; + AppDomain.CurrentDomain.SetData("DataDirectory", Path); + + UmbracoSettings.UseLegacyXmlSchema = false; + + //this ensures its reset + PluginManager.Current = new PluginManager(false); + + //for testing, we'll specify which assemblies are scanned for the PluginTypeResolver + PluginManager.Current.AssembliesToScan = new[] + { + typeof (MigrationRunner).Assembly + }; + + DatabaseSpecificSetUp(); + + SyntaxConfig.SqlSyntaxProvider = GetSyntaxProvider(); + } + + [Test] + public void Can_Upgrade_From_470_To_600() + { + var configuredVersion = new Version("4.7.0"); + var targetVersion = new Version("6.0.0"); + var provider = GetDatabaseProvider(); + var db = GetConfiguredDatabase(); + + //Create db schema and data from old Total.sql file for Sql Ce + string statements = GetDatabaseSpecificSqlScript(); + // replace block comments by whitespace + statements = m_findComments.Replace(statements, " "); + // execute all non-empty statements + foreach (string statement in statements.Split(";".ToCharArray())) + { + string rawStatement = statement.Trim(); + if (rawStatement.Length > 0) + db.Execute(rawStatement); + } + + //Setup the MigrationRunner + var migrationRunner = new MigrationRunner(configuredVersion, targetVersion, GlobalSettings.UmbracoMigrationName); + bool upgraded = migrationRunner.Execute(db, provider, true); + + Assert.That(upgraded, Is.True); + + bool hasTabTable = db.TableExist("cmsTab"); + bool hasPropertyTypeGroupTable = db.TableExist("cmsPropertyTypeGroup"); + bool hasAppTreeTable = db.TableExist("umbracoAppTree"); + + Assert.That(hasTabTable, Is.False); + Assert.That(hasPropertyTypeGroupTable, Is.True); + Assert.That(hasAppTreeTable, Is.False); + } + + [TearDown] + public virtual void TearDown() + { + PluginManager.Current = null; + SyntaxConfig.SqlSyntaxProvider = null; + + TestHelper.CleanContentDirectories(); + + Path = TestHelper.CurrentAssemblyDirectory; + AppDomain.CurrentDomain.SetData("DataDirectory", null); + + DatabaseSpecificTearDown(); + } + + public string Path { get; set; } + public abstract void DatabaseSpecificSetUp(); + public abstract void DatabaseSpecificTearDown(); + public abstract ISqlSyntaxProvider GetSyntaxProvider(); + public abstract UmbracoDatabase GetConfiguredDatabase(); + public abstract DatabaseProviders GetDatabaseProvider(); + public abstract string GetDatabaseSpecificSqlScript(); + } +} \ No newline at end of file diff --git a/src/Umbraco.Tests/Migrations/Upgrades/MySqlUpgradeTest.cs b/src/Umbraco.Tests/Migrations/Upgrades/MySqlUpgradeTest.cs new file mode 100644 index 0000000000..b8174b2583 --- /dev/null +++ b/src/Umbraco.Tests/Migrations/Upgrades/MySqlUpgradeTest.cs @@ -0,0 +1,40 @@ +using NUnit.Framework; +using Umbraco.Core.Persistence; +using Umbraco.Core.Persistence.SqlSyntax; + +namespace Umbraco.Tests.Migrations.Upgrades +{ + [TestFixture, NUnit.Framework.Ignore] + public class MySqlUpgradeTest : BaseUpgradeTest + { + public override void DatabaseSpecificSetUp() + { + //TODO Create new database here + } + + public override void DatabaseSpecificTearDown() + { + //TODO Remove created database here + } + + public override ISqlSyntaxProvider GetSyntaxProvider() + { + return MySqlSyntax.Provider; + } + + public override UmbracoDatabase GetConfiguredDatabase() + { + return new UmbracoDatabase("Server = 169.254.120.3; Database = upgradetest; Uid = umbraco; Pwd = umbraco", "MySql.Data.MySqlClient"); + } + + public override DatabaseProviders GetDatabaseProvider() + { + return DatabaseProviders.MySql; + } + + public override string GetDatabaseSpecificSqlScript() + { + return SqlScripts.SqlResources.MySqlTotal_480; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Tests/Migrations/Upgrades/SqlCeUpgradeTest.cs b/src/Umbraco.Tests/Migrations/Upgrades/SqlCeUpgradeTest.cs new file mode 100644 index 0000000000..ea734414ab --- /dev/null +++ b/src/Umbraco.Tests/Migrations/Upgrades/SqlCeUpgradeTest.cs @@ -0,0 +1,59 @@ +using System.Configuration; +using System.Data.SqlServerCe; +using System.IO; +using NUnit.Framework; +using Umbraco.Core.Persistence; +using Umbraco.Core.Persistence.SqlSyntax; + +namespace Umbraco.Tests.Migrations.Upgrades +{ + [TestFixture] + public class SqlCeUpgradeTest : BaseUpgradeTest + { + public override void DatabaseSpecificSetUp() + { + //Delete database file before continueing + string filePath = string.Concat(Path, "\\UmbracoPetaPocoTests.sdf"); + if (File.Exists(filePath)) + { + File.Delete(filePath); + } + + //Get the connectionstring settings from config + var settings = ConfigurationManager.ConnectionStrings["umbracoDbDsn"]; + + //Create the Sql CE database + var engine = new SqlCeEngine(settings.ConnectionString); + engine.CreateDatabase(); + } + + public override void DatabaseSpecificTearDown() + { + string filePath = string.Concat(Path, "\\UmbracoPetaPocoTests.sdf"); + if (File.Exists(filePath)) + { + File.Delete(filePath); + } + } + + public override ISqlSyntaxProvider GetSyntaxProvider() + { + return SqlCeSyntax.Provider; + } + + public override UmbracoDatabase GetConfiguredDatabase() + { + return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf", "System.Data.SqlServerCe.4.0"); + } + + public override DatabaseProviders GetDatabaseProvider() + { + return DatabaseProviders.SqlServerCE; + } + + public override string GetDatabaseSpecificSqlScript() + { + return SqlScripts.SqlResources.SqlCeTotal_480; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Tests/Migrations/Upgrades/SqlServerUpgradeTest.cs b/src/Umbraco.Tests/Migrations/Upgrades/SqlServerUpgradeTest.cs new file mode 100644 index 0000000000..dd278254c5 --- /dev/null +++ b/src/Umbraco.Tests/Migrations/Upgrades/SqlServerUpgradeTest.cs @@ -0,0 +1,38 @@ +using NUnit.Framework; +using Umbraco.Core.Persistence; +using Umbraco.Core.Persistence.SqlSyntax; + +namespace Umbraco.Tests.Migrations.Upgrades +{ + [TestFixture, NUnit.Framework.Ignore] + public class SqlServerUpgradeTest : BaseUpgradeTest + { + public override void DatabaseSpecificSetUp() + { + } + + public override void DatabaseSpecificTearDown() + { + } + + public override ISqlSyntaxProvider GetSyntaxProvider() + { + return SqlServerSyntax.Provider; + } + + public override UmbracoDatabase GetConfiguredDatabase() + { + return new UmbracoDatabase(@"server=.\SQLEXPRESS;database=EmptyForTest;user id=umbraco;password=umbraco", "System.Data.SqlClient"); + } + + public override DatabaseProviders GetDatabaseProvider() + { + return DatabaseProviders.SqlServer; + } + + public override string GetDatabaseSpecificSqlScript() + { + return SqlScripts.SqlResources.SqlServerTotal_480; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Tests/Persistence/MySqlDatabaseCreationTest.cs b/src/Umbraco.Tests/Persistence/MySqlDatabaseCreationTest.cs index fc97896061..9a10c262fa 100644 --- a/src/Umbraco.Tests/Persistence/MySqlDatabaseCreationTest.cs +++ b/src/Umbraco.Tests/Persistence/MySqlDatabaseCreationTest.cs @@ -12,7 +12,7 @@ namespace Umbraco.Tests.Persistence public override string ConnectionString { - get { return "Server = 192.168.1.108; Database = testDb; Uid = umbraco; Pwd = umbraco"; } + get { return "Server = 169.254.120.3; Database = testdb; Uid = umbraco; Pwd = umbraco"; } } public override string ProviderName diff --git a/src/Umbraco.Tests/Persistence/MySqlTableByTableTest.cs b/src/Umbraco.Tests/Persistence/MySqlTableByTableTest.cs index a7633474f1..061a2414f6 100644 --- a/src/Umbraco.Tests/Persistence/MySqlTableByTableTest.cs +++ b/src/Umbraco.Tests/Persistence/MySqlTableByTableTest.cs @@ -42,7 +42,7 @@ namespace Umbraco.Tests.Persistence SyntaxConfig.SqlSyntaxProvider = MySqlSyntaxProvider.Instance; - _database = new Database("Server = 192.168.1.108; Database = testDb; Uid = umbraco; Pwd = umbraco", + _database = new Database("Server = 169.254.120.3; Database = testdb; Uid = umbraco; Pwd = umbraco", "MySql.Data.MySqlClient"); } diff --git a/src/Umbraco.Tests/Persistence/SyntaxProvider/SqlSyntaxProviderTests.cs b/src/Umbraco.Tests/Persistence/SyntaxProvider/SqlSyntaxProviderTests.cs index 6172c9d4f7..ce6a735d2a 100644 --- a/src/Umbraco.Tests/Persistence/SyntaxProvider/SqlSyntaxProviderTests.cs +++ b/src/Umbraco.Tests/Persistence/SyntaxProvider/SqlSyntaxProviderTests.cs @@ -41,6 +41,8 @@ namespace Umbraco.Tests.Persistence.SyntaxProvider [TearDown] public void TearDown() - {} + { + SyntaxConfig.SqlSyntaxProvider = null; + } } } \ No newline at end of file diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 654de72da1..b999aeeb16 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -159,8 +159,8 @@ + - True True @@ -171,6 +171,9 @@ + + +