diff --git a/src/Umbraco.Core/Persistence/Migrations/MigrationExpressionBase.cs b/src/Umbraco.Core/Persistence/Migrations/MigrationExpressionBase.cs index 7dff959ade..655f2c7673 100644 --- a/src/Umbraco.Core/Persistence/Migrations/MigrationExpressionBase.cs +++ b/src/Umbraco.Core/Persistence/Migrations/MigrationExpressionBase.cs @@ -77,9 +77,9 @@ namespace Umbraco.Core.Persistence.Migrations case TypeCode.UInt64: return val.ToString(); case TypeCode.DateTime: - return SqlSyntax.FormatDateTime((DateTime) val); + return SqlSyntax.GetQuotedValue(SqlSyntax.FormatDateTime((DateTime) val)); default: - return SqlSyntaxContext.SqlSyntaxProvider.GetQuotedValue(val.ToString()); + return SqlSyntax.GetQuotedValue(val.ToString()); } } } diff --git a/src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs b/src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs index 539b00fe42..234cd67386 100644 --- a/src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs +++ b/src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; +using System.Text; using log4net; using Semver; using Umbraco.Core.Configuration; @@ -243,13 +245,43 @@ namespace Umbraco.Core.Persistence.Migrations //TODO: We should output all of these SQL calls to files in a migration folder in App_Data/TEMP // so if people want to executed them manually on another environment, they can. - _logger.Info("Executing sql statement " + i + ": " + sql); - database.Execute(sql); + //The following ensures the multiple statement sare executed one at a time, this is a requirement + // of SQLCE, it's unfortunate but necessary. + // http://stackoverflow.com/questions/13665491/sql-ce-inconsistent-with-multiple-statements + var sb = new StringBuilder(); + using (var reader = new StringReader(sql)) + { + string line; + while ((line = reader.ReadLine()) != null) + { + line = line.Trim(); + if (line.Equals("GO", StringComparison.OrdinalIgnoreCase)) + { + //Execute the SQL up to the point of a GO statement + var exeSql = sb.ToString(); + _logger.Info("Executing sql statement " + i + ": " + exeSql); + database.Execute(exeSql); + + //restart the string builder + sb.Remove(0, sb.Length); + } + else + { + sb.AppendLine(line); + } + } + //execute anything remaining + if (sb.Length > 0) + { + var exeSql = sb.ToString(); + _logger.Info("Executing sql statement " + i + ": " + exeSql); + database.Execute(exeSql); + } + } + i++; } - - transaction.Complete(); //Now that this is all complete, we need to add an entry to the migrations table flagging that migrations 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 7cbfe8b773..ca76b4e03e 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Insert/Expressions/InsertDataExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Insert/Expressions/InsertDataExpression.cs @@ -41,13 +41,16 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Insert.Expressions { if (IsExpressionSupported() == false) return string.Empty; - - var insertItems = new List(); + var sb = new StringBuilder(); if (EnabledIdentityInsert && SqlSyntax.SupportsIdentityInsert()) { sb.AppendLine(string.Format("SET IDENTITY_INSERT {0} ON;", SqlSyntax.GetQuotedTableName(TableName))); + if (SqlSyntax.GetType() != typeof (MySqlSyntaxProvider)) + { + sb.AppendLine("GO"); + } } try @@ -69,16 +72,22 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Insert.Expressions SqlSyntax.GetQuotedTableName(TableName), cols, vals); - insertItems.Add(sql); + sb.AppendLine(string.Format("{0};", sql)); + if (SqlSyntax.GetType() != typeof(MySqlSyntaxProvider)) + { + sb.AppendLine("GO"); + } } - - sb.AppendLine(string.Join(",", insertItems)); } finally { if (EnabledIdentityInsert && SqlSyntax.SupportsIdentityInsert()) { - sb.AppendLine(string.Format(";SET IDENTITY_INSERT {0} OFF;", SqlSyntax.GetQuotedTableName(TableName))); + sb.AppendLine(string.Format("SET IDENTITY_INSERT {0} OFF;", SqlSyntax.GetQuotedTableName(TableName))); + if (SqlSyntax.GetType() != typeof(MySqlSyntaxProvider)) + { + sb.AppendLine("GO"); + } } } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/MigrateAndRemoveTemplateMasterColumn.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/MigrateAndRemoveTemplateMasterColumn.cs index daf6ee5c08..28acaa6042 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/MigrateAndRemoveTemplateMasterColumn.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/MigrateAndRemoveTemplateMasterColumn.cs @@ -38,11 +38,30 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe SqlSyntax.GetQuotedColumnName("master") + @" NOT IN (SELECT nodeId FROM cmsTemplate)"); //Now we can bulk update the parentId column - Execute.Sql(@"UPDATE umbracoNode -SET parentID = COALESCE(t2." + SqlSyntax.GetQuotedColumnName("master") + @", -1) -FROM umbracoNode t1 -INNER JOIN cmsTemplate t2 -ON t1.id = t2.nodeId"); + + //NOTE: This single statement should be used but stupid SQLCE doesn't support Update with a FROM !! + // so now we have to do this by individual rows :( + //Execute.Sql(@"UPDATE umbracoNode + //SET parentID = COALESCE(t2." + SqlSyntax.GetQuotedColumnName("master") + @", -1) + //FROM umbracoNode t1 + //INNER JOIN cmsTemplate t2 + //ON t1.id = t2.nodeId"); + Execute.Code(database => + { + var templateData = database.Fetch("SELECT * FROM cmsTemplate"); + + foreach (var template in templateData) + { + var sql = "SET parentID=@parentId WHERE id=@nodeId"; + + LogHelper.Info("Executing sql statement: UPDATE umbracoNode " + sql); + + database.Update(sql, + new {parentId = template.master ?? -1, nodeId = template.nodeId}); + } + + return string.Empty; + }); //Now we can update the path, but this needs to be done in a delegate callback so that the query runs after the updates just completed Execute.Code(database => diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs index 6832be7d65..dd3f20aa50 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs @@ -203,7 +203,7 @@ ORDER BY TABLE_NAME, INDEX_NAME", /// public override string FormatDateTime(DateTime date, bool includeTime = true) { - return includeTime ? date.ToString("YYYYMMDDHHmmss") : date.ToString("YYYYMMDD"); + return includeTime ? date.ToString("yyyyMMddHHmmss") : date.ToString("yyyyMMdd"); } public override string GetQuotedTableName(string tableName) diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs index 7a56a461bc..f8e423699c 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs @@ -263,7 +263,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax /// public virtual string FormatDateTime(DateTime date, bool includeTime = true) { - return includeTime ? date.ToString("YYYYMMDD HH:mm:ss") : date.ToString("YYYYMMDD"); + return includeTime ? date.ToString("yyyyMMdd HH:mm:ss") : date.ToString("yyyyMMdd"); } public virtual string Format(TableDefinition table)