Fixes: U4-7059 SQL problem upgrading from 7.2.8 to 7.3.0 RC

This commit is contained in:
Shannon
2015-09-07 23:45:55 +02:00
parent 3dc4059036
commit b3664d2391
4 changed files with 106 additions and 25 deletions

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Text;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Persistence.SqlSyntax;
@@ -9,55 +10,79 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Insert.Expressions
{
private readonly List<InsertionDataDefinition> _rows = new List<InsertionDataDefinition>();
[Obsolete("Use the other constructors specifying an ISqlSyntaxProvider instead")]
public InsertDataExpression()
{
}
[Obsolete("Use the other constructors specifying an ISqlSyntaxProvider instead")]
public InsertDataExpression(DatabaseProviders current, DatabaseProviders[] databaseProviders) : base(current, databaseProviders)
{
}
public InsertDataExpression(ISqlSyntaxProvider sqlSyntax) : base(sqlSyntax)
{
}
public InsertDataExpression(DatabaseProviders current, DatabaseProviders[] databaseProviders, ISqlSyntaxProvider sqlSyntax) : base(current, databaseProviders, sqlSyntax)
{
}
public string SchemaName { get; set; }
public string TableName { get; set; }
public bool EnabledIdentityInsert { get; set; }
public List<InsertionDataDefinition> Rows
{
get { return _rows; }
}
public override string ToString()
{
//TODO: This works for single insertion entries, not sure if it is valid for bulk insert operations!!!
if (IsExpressionSupported() == false)
return string.Empty;
var insertItems = new List<string>();
foreach (var item in Rows)
var sb = new StringBuilder();
if (EnabledIdentityInsert && SqlSyntax.SupportsIdentityInsert())
{
var cols = "";
var vals = "";
foreach (var keyVal in item)
{
cols += keyVal.Key + ",";
vals += GetQuotedValue(keyVal.Value) + ",";
}
cols = cols.TrimEnd(',');
vals = vals.TrimEnd(',');
var sql = string.Format(SqlSyntaxContext.SqlSyntaxProvider.InsertData,
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(TableName),
cols, vals);
insertItems.Add(sql);
sb.AppendLine(string.Format("SET IDENTITY_INSERT {0} ON;", SqlSyntax.GetQuotedTableName(TableName)));
}
return string.Join(",", insertItems);
try
{
foreach (var item in Rows)
{
var cols = "";
var vals = "";
foreach (var keyVal in item)
{
cols += keyVal.Key + ",";
vals += GetQuotedValue(keyVal.Value) + ",";
}
cols = cols.TrimEnd(',');
vals = vals.TrimEnd(',');
var sql = string.Format(SqlSyntax.InsertData,
SqlSyntax.GetQuotedTableName(TableName),
cols, vals);
insertItems.Add(sql);
}
sb.AppendLine(string.Join(",", insertItems));
}
finally
{
if (EnabledIdentityInsert && SqlSyntax.SupportsIdentityInsert())
{
sb.AppendLine(string.Format(";SET IDENTITY_INSERT {0} OFF;", SqlSyntax.GetQuotedTableName(TableName)));
}
}
return sb.ToString();
}

View File

@@ -2,6 +2,7 @@
{
public interface IInsertDataSyntax : IFluentSyntax
{
IInsertDataSyntax EnableIdentityInsert();
IInsertDataSyntax Row(object dataAsAnonymousType);
}
}

View File

@@ -14,6 +14,12 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Insert
_expression = expression;
}
public IInsertDataSyntax EnableIdentityInsert()
{
_expression.EnabledIdentityInsert = true;
return this;
}
public IInsertDataSyntax Row(object dataAsAnonymousType)
{
_expression.Rows.Add(GetData(dataAsAnonymousType));

View File

@@ -3,6 +3,8 @@ using System.Data;
using System.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZero
@@ -30,6 +32,53 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe
Delete.FromTable("cmsLanguageText").Row(new { pk = pk });
}
var columns = SqlSyntax.GetColumnsInSchema(Context.Database).Distinct().ToArray();
if (columns.Any(x => x.ColumnName.InvariantEquals("id")
&& x.TableName.InvariantEquals("umbracoLanguage")
&& x.DataType.InvariantEquals("smallint")))
{
//Ensure that the umbracoLanguage PK is INT and not SmallInt (which it might be in older db versions)
// In order to 'change' this to an INT, we have to run a full migration script which is super annoying
Create.Table("umbracoLanguage_TEMP")
.WithColumn("id").AsInt32().NotNullable().Identity()
.WithColumn("languageISOCode").AsString(10).Nullable()
.WithColumn("languageCultureName").AsString(50).Nullable();
var currentData = this.Context.Database.Fetch<LanguageDto>(new Sql().Select("*").From<LanguageDto>(SqlSyntax));
foreach (var languageDto in currentData)
{
Insert.IntoTable("umbracoLanguage_TEMP")
.EnableIdentityInsert()
.Row(new {id = languageDto.Id, languageISOCode = languageDto.IsoCode, languageCultureName = languageDto.CultureName});
}
//ok, all data has been copied over, drop the old table, rename the temp table and re-add constraints.
Delete.Table("umbracoLanguage");
Rename.Table("umbracoLanguage_TEMP").To("umbracoLanguage");
//add the pk
Create.PrimaryKey("PK_language").OnTable("umbracoLanguage").Column("id");
}
var dbIndexes = SqlSyntax.GetDefinedIndexes(Context.Database)
.Select(x => new DbIndexDefinition
{
TableName = x.Item1,
IndexName = x.Item2,
ColumnName = x.Item3,
IsUnique = x.Item4
}).ToArray();
//make sure it doesn't already exist
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_cmsDictionary_id")) == false)
{
Create.Index("IX_cmsDictionary_id").OnTable("cmsDictionary")
.OnColumn("id").Ascending()
.WithOptions().NonClustered()
.WithOptions().Unique();
}
//now we need to create a foreign key
Create.ForeignKey("FK_cmsLanguageText_umbracoLanguage_id").FromTable("cmsLanguageText").ForeignColumn("languageId")
.ToTable("umbracoLanguage").PrimaryColumn("id").OnDeleteOrUpdate(Rule.None);
@@ -52,7 +101,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe
public override void Down()
{
throw new System.NotImplementedException();
throw new NotImplementedException();
}
}
}