Fixes upgrade issues with SQLCE and DateTime:
* DateTime's during migrations are formatted in a very explicit way * Migration's that need to execute multiple statements are fixed in SQLCE by splitting on GO
This commit is contained in:
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<MigrationRunner>("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<MigrationRunner>("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<MigrationRunner>("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
|
||||
|
||||
@@ -41,13 +41,16 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Insert.Expressions
|
||||
{
|
||||
if (IsExpressionSupported() == false)
|
||||
return string.Empty;
|
||||
|
||||
var insertItems = new List<string>();
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<dynamic>("SELECT * FROM cmsTemplate");
|
||||
|
||||
foreach (var template in templateData)
|
||||
{
|
||||
var sql = "SET parentID=@parentId WHERE id=@nodeId";
|
||||
|
||||
LogHelper.Info<MigrateAndRemoveTemplateMasterColumn>("Executing sql statement: UPDATE umbracoNode " + sql);
|
||||
|
||||
database.Update<NodeDto>(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 =>
|
||||
|
||||
@@ -203,7 +203,7 @@ ORDER BY TABLE_NAME, INDEX_NAME",
|
||||
/// </remarks>
|
||||
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)
|
||||
|
||||
@@ -263,7 +263,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
/// </remarks>
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user