diff --git a/src/Umbraco.Core/Migrations/Expressions/Create/KeysAndIndexes/CreateKeysAndIndexesBuilder.cs b/src/Umbraco.Core/Migrations/Expressions/Create/KeysAndIndexes/CreateKeysAndIndexesBuilder.cs
index 8b5e83cacd..6bf450a9b8 100644
--- a/src/Umbraco.Core/Migrations/Expressions/Create/KeysAndIndexes/CreateKeysAndIndexesBuilder.cs
+++ b/src/Umbraco.Core/Migrations/Expressions/Create/KeysAndIndexes/CreateKeysAndIndexesBuilder.cs
@@ -34,6 +34,16 @@ namespace Umbraco.Core.Migrations.Expressions.Create.KeysAndIndexes
ExecuteSql(sql);
foreach (var sql in syntax.Format(tableDefinition.ForeignKeys))
ExecuteSql(sql);
+
+ // note: we do *not* create the DF_ default constraints
+ /*
+ foreach (var column in tableDefinition.Columns)
+ {
+ var sql = syntax.FormatDefaultConstraint(column);
+ if (!sql.IsNullOrWhiteSpace())
+ ExecuteSql(sql);
+ }
+ */
}
private void ExecuteSql(string sql)
diff --git a/src/Umbraco.Core/Migrations/Expressions/Delete/DefaultConstraint/DeleteDefaultConstraintBuilder.cs b/src/Umbraco.Core/Migrations/Expressions/Delete/DefaultConstraint/DeleteDefaultConstraintBuilder.cs
index 373b375fa8..86b90b9d6d 100644
--- a/src/Umbraco.Core/Migrations/Expressions/Delete/DefaultConstraint/DeleteDefaultConstraintBuilder.cs
+++ b/src/Umbraco.Core/Migrations/Expressions/Delete/DefaultConstraint/DeleteDefaultConstraintBuilder.cs
@@ -10,9 +10,13 @@ namespace Umbraco.Core.Migrations.Expressions.Delete.DefaultConstraint
IDeleteDefaultConstraintOnTableBuilder,
IDeleteDefaultConstraintOnColumnBuilder
{
- public DeleteDefaultConstraintBuilder(DeleteDefaultConstraintExpression expression)
+ private readonly IMigrationContext _context;
+
+ public DeleteDefaultConstraintBuilder(IMigrationContext context, DeleteDefaultConstraintExpression expression)
: base(expression)
- { }
+ {
+ _context = context;
+ }
///
public IDeleteDefaultConstraintOnColumnBuilder OnTable(string tableName)
@@ -24,6 +28,8 @@ namespace Umbraco.Core.Migrations.Expressions.Delete.DefaultConstraint
///
public IExecutableBuilder OnColumn(string columnName)
{
+ var defaultConstraint = _context.SqlContext.SqlSyntax.GetDefaultConstraint(_context.Database, Expression.TableName, columnName);
+ Expression.ConstraintName = defaultConstraint ?? string.Empty;
Expression.ColumnName = columnName;
return new ExecutableBuilder(Expression);
}
diff --git a/src/Umbraco.Core/Migrations/Expressions/Delete/DeleteBuilder.cs b/src/Umbraco.Core/Migrations/Expressions/Delete/DeleteBuilder.cs
index a06ca66f29..9a4f437f62 100644
--- a/src/Umbraco.Core/Migrations/Expressions/Delete/DeleteBuilder.cs
+++ b/src/Umbraco.Core/Migrations/Expressions/Delete/DeleteBuilder.cs
@@ -1,5 +1,4 @@
-using NPoco;
-using Umbraco.Core.Exceptions;
+using Umbraco.Core.Exceptions;
using Umbraco.Core.Migrations.Expressions.Common;
using Umbraco.Core.Migrations.Expressions.Delete.Column;
using Umbraco.Core.Migrations.Expressions.Delete.Constraint;
@@ -30,19 +29,19 @@ namespace Umbraco.Core.Migrations.Expressions.Delete
}
///
- public IExecutableBuilder KeysAndIndexes(bool pk = true, bool fk = true, bool ix = true)
+ public IExecutableBuilder KeysAndIndexes(bool local = true, bool foreign = true)
{
var syntax = _context.SqlContext.SqlSyntax;
var tableDefinition = DefinitionFactory.GetTableDefinition(typeof(TDto), syntax);
- return KeysAndIndexes(tableDefinition.Name, pk, fk, ix);
+ return KeysAndIndexes(tableDefinition.Name, local, foreign);
}
///
- public IExecutableBuilder KeysAndIndexes(string tableName, bool pk = true, bool fk = true, bool ix = true)
+ public IExecutableBuilder KeysAndIndexes(string tableName, bool local = true, bool foreign = true)
{
if (tableName.IsNullOrWhiteSpace())
throw new ArgumentNullOrEmptyException(nameof(tableName));
- return new DeleteKeysAndIndexesBuilder(_context) { TableName = tableName, DeletePrimaryKey = pk, DeleteForeignKeys = fk, DeleteIndexes = ix};
+ return new DeleteKeysAndIndexesBuilder(_context) { TableName = tableName, DeleteLocal = local, DeleteForeign = foreign };
}
///
@@ -111,7 +110,7 @@ namespace Umbraco.Core.Migrations.Expressions.Delete
public IDeleteDefaultConstraintOnTableBuilder DefaultConstraint()
{
var expression = new DeleteDefaultConstraintExpression(_context);
- return new DeleteDefaultConstraintBuilder(expression);
+ return new DeleteDefaultConstraintBuilder(_context, expression);
}
}
}
diff --git a/src/Umbraco.Core/Migrations/Expressions/Delete/Expressions/DeleteDefaultConstraintExpression.cs b/src/Umbraco.Core/Migrations/Expressions/Delete/Expressions/DeleteDefaultConstraintExpression.cs
index 8b0b20c0e2..294190c766 100644
--- a/src/Umbraco.Core/Migrations/Expressions/Delete/Expressions/DeleteDefaultConstraintExpression.cs
+++ b/src/Umbraco.Core/Migrations/Expressions/Delete/Expressions/DeleteDefaultConstraintExpression.cs
@@ -10,12 +10,16 @@ namespace Umbraco.Core.Migrations.Expressions.Delete.Expressions
public virtual string TableName { get; set; }
public virtual string ColumnName { get; set; }
+ public virtual string ConstraintName { get; set; }
protected override string GetSql()
{
- return string.Format(SqlSyntax.DeleteDefaultConstraint,
- SqlSyntax.GetQuotedTableName(TableName),
- SqlSyntax.GetQuotedColumnName(ColumnName));
+ return ConstraintName.IsNullOrWhiteSpace()
+ ? string.Empty
+ : string.Format(SqlSyntax.DeleteDefaultConstraint,
+ SqlSyntax.GetQuotedTableName(TableName),
+ SqlSyntax.GetQuotedColumnName(ColumnName),
+ SqlSyntax.GetQuotedName(ConstraintName));
}
}
}
diff --git a/src/Umbraco.Core/Migrations/Expressions/Delete/IDeleteBuilder.cs b/src/Umbraco.Core/Migrations/Expressions/Delete/IDeleteBuilder.cs
index 1c04fcc716..84e44d0d93 100644
--- a/src/Umbraco.Core/Migrations/Expressions/Delete/IDeleteBuilder.cs
+++ b/src/Umbraco.Core/Migrations/Expressions/Delete/IDeleteBuilder.cs
@@ -21,12 +21,12 @@ namespace Umbraco.Core.Migrations.Expressions.Delete
///
/// Builds a Delete Keys and Indexes expression, and executes.
///
- IExecutableBuilder KeysAndIndexes(bool pk = true, bool fk = true, bool ix = true);
+ IExecutableBuilder KeysAndIndexes(bool local = true, bool foreign = true);
///
/// Builds a Delete Keys and Indexes expression, and executes.
///
- IExecutableBuilder KeysAndIndexes(string tableName, bool pk = true, bool fk = true, bool ix = true);
+ IExecutableBuilder KeysAndIndexes(string tableName, bool local = true, bool foreign = true);
///
/// Specifies the column to delete.
diff --git a/src/Umbraco.Core/Migrations/Expressions/Delete/KeysAndIndexes/DeleteKeysAndIndexesBuilder.cs b/src/Umbraco.Core/Migrations/Expressions/Delete/KeysAndIndexes/DeleteKeysAndIndexesBuilder.cs
index b16748c851..9b13457b76 100644
--- a/src/Umbraco.Core/Migrations/Expressions/Delete/KeysAndIndexes/DeleteKeysAndIndexesBuilder.cs
+++ b/src/Umbraco.Core/Migrations/Expressions/Delete/KeysAndIndexes/DeleteKeysAndIndexesBuilder.cs
@@ -18,11 +18,9 @@ namespace Umbraco.Core.Migrations.Expressions.Delete.KeysAndIndexes
public string TableName { get; set; }
- public bool DeletePrimaryKey { get; set; }
+ public bool DeleteLocal { get; set; }
- public bool DeleteForeignKeys { get; set; }
-
- public bool DeleteIndexes { get; set; }
+ public bool DeleteForeign { get; set; }
///
public void Do()
@@ -30,19 +28,26 @@ namespace Umbraco.Core.Migrations.Expressions.Delete.KeysAndIndexes
_context.BuildingExpression = false;
// drop keys
- if (DeleteForeignKeys || DeletePrimaryKey)
+ if (DeleteLocal || DeleteForeign)
{
- var keys = _context.SqlContext.SqlSyntax.GetConstraintsPerTable(_context.Database).DistinctBy(x => x.Item2).ToList();
- if (DeleteForeignKeys)
- foreach (var key in keys.Where(x => x.Item1 == TableName && x.Item2.StartsWith("FK_")))
+ // table, constraint
+ var tableKeys = _context.SqlContext.SqlSyntax.GetConstraintsPerTable(_context.Database).DistinctBy(x => x.Item2).ToList();
+ if (DeleteForeign)
+ {
+ foreach (var key in tableKeys.Where(x => x.Item1 == TableName && x.Item2.StartsWith("FK_")))
Delete.ForeignKey(key.Item2).OnTable(key.Item1).Do();
- if (DeletePrimaryKey)
- foreach (var key in keys.Where(x => x.Item1 == TableName && x.Item2.StartsWith("PK_")))
+ }
+ if (DeleteLocal)
+ {
+ foreach (var key in tableKeys.Where(x => x.Item1 == TableName && x.Item2.StartsWith("PK_")))
Delete.PrimaryKey(key.Item2).FromTable(key.Item1).Do();
+
+ // note: we do *not* delete the DEFAULT constraints
+ }
}
// drop indexes
- if (DeleteIndexes)
+ if (DeleteLocal)
{
var indexes = _context.SqlContext.SqlSyntax.GetDefinedIndexesDefinitions(_context.Database).DistinctBy(x => x.IndexName).ToList();
foreach (var index in indexes.Where(x => x.TableName == TableName))
diff --git a/src/Umbraco.Core/Migrations/Upgrade/Common/DeleteKeysAndIndexes.cs b/src/Umbraco.Core/Migrations/Upgrade/Common/DeleteKeysAndIndexes.cs
index b62d492348..9e4af17c09 100644
--- a/src/Umbraco.Core/Migrations/Upgrade/Common/DeleteKeysAndIndexes.cs
+++ b/src/Umbraco.Core/Migrations/Upgrade/Common/DeleteKeysAndIndexes.cs
@@ -67,9 +67,9 @@
// delete *all* keys and indexes - because of FKs
// on known v7 tables only
foreach (var table in tables)
- Delete.KeysAndIndexes(table, false, true, false).Do();
+ Delete.KeysAndIndexes(table, false, true).Do();
foreach (var table in tables)
- Delete.KeysAndIndexes(table, true, false, true).Do();
+ Delete.KeysAndIndexes(table, true, false).Do();
}
}
}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/SuperZero.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/SuperZero.cs
index 3f2ba3e31c..64ac20d175 100644
--- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/SuperZero.cs
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/SuperZero.cs
@@ -15,7 +15,12 @@
Database.Execute("set identity_insert umbracoUser on;");
Database.Execute(@"
- insert into umbracoUser select
+ insert into umbracoUser (id,
+ userDisabled, userNoConsole, userName, userLogin, userPassword, passwordConfig,
+ userEmail, userLanguage, securityStampToken, failedLoginAttempts, lastLockoutDate,
+ lastPasswordChangeDate, lastLoginDate, emailConfirmedDate, invitedDate,
+ createDate, updateDate, avatar, tourData)
+ select
-1 id,
userDisabled, userNoConsole, userName, substring(userLogin, 1, len(userLogin) - 2) userLogin, userPassword, passwordConfig,
userEmail, userLanguage, securityStampToken, failedLoginAttempts, lastLockoutDate,
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/VariantsMigration.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/VariantsMigration.cs
index 6b0151723c..8c60d30680 100644
--- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/VariantsMigration.cs
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/VariantsMigration.cs
@@ -213,8 +213,10 @@ WHERE versionId NOT IN (SELECT (versionId) FROM {PreTables.ContentVersion} WHERE
Delete.Column("text").FromTable(PreTables.Document).Do();
Delete.Column("templateId").FromTable(PreTables.Document).Do();
Delete.Column("documentUser").FromTable(PreTables.Document).Do();
+ Delete.DefaultConstraint().OnTable(PreTables.Document).OnColumn("updateDate").Do();
Delete.Column("updateDate").FromTable(PreTables.Document).Do();
Delete.Column("versionId").FromTable(PreTables.Document).Do();
+ Delete.DefaultConstraint().OnTable(PreTables.Document).OnColumn("newest").Do();
Delete.Column("newest").FromTable(PreTables.Document).Do();
// add and populate edited column
diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs
index c352e312ac..39419021e0 100644
--- a/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs
+++ b/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs
@@ -44,7 +44,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
string TruncateTable { get; }
string CreateConstraint { get; }
string DeleteConstraint { get; }
-
+
string DeleteDefaultConstraint { get; }
string FormatDateTime(DateTime date, bool includeTime = true);
string Format(TableDefinition table);
@@ -106,5 +106,14 @@ namespace Umbraco.Core.Persistence.SqlSyntax
/// A Tuple containing: TableName, IndexName, ColumnName, IsUnique
///
IEnumerable> GetDefinedIndexes(IDatabase db);
+
+ ///
+ /// Gets the name of the default constraint on a column.
+ ///
+ /// The database.
+ /// The table name.
+ /// The column name.
+ /// The name of the default constraint, or the empty string if there is no default constraint.
+ string GetDefaultConstraint(IDatabase db, string tableName, string columnName);
}
}
diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs
index 8f39e36fb9..bb91a83da4 100644
--- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs
+++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs
@@ -132,6 +132,16 @@ ORDER BY TABLE_NAME, INDEX_NAME");
item => new Tuple(item.TABLE_NAME, item.INDEX_NAME, item.COLUMN_NAME, item.UNIQUE));
}
+ ///
+ public override string GetDefaultConstraint(IDatabase db, string tableName, string columnName)
+ {
+ // cannot return a true default constraint name (does not exist on SqlCe)
+ // but we won't really need it anyways - just check whether there is a constraint
+ var hasDefault = db.Fetch(@"select column_hasdefault from information_schema.columns
+where table_name=@0 and column_name=@1", tableName, columnName).FirstOrDefault();
+ return hasDefault ? "XXXXX" : string.Empty;
+ }
+
public override bool DoesTableExist(IDatabase db, string tableName)
{
var result =
@@ -175,7 +185,7 @@ ORDER BY TABLE_NAME, INDEX_NAME");
{
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 e51aa547b8..b0f95b0c56 100644
--- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs
+++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs
@@ -225,6 +225,17 @@ order by T.name, I.name");
}
+ ///
+ public override string GetDefaultConstraint(IDatabase db, string tableName, string columnName)
+ {
+ return db.Fetch(@"select con.[name] as [constraintName]
+from sys.default_constraints con
+join sys.columns col on con.object_id=col.default_object_id
+join sys.tables tbl on col.object_id=tbl.object_id
+where tbl.[name]=@0 and col.[name]=@1;", tableName, columnName)
+ .FirstOrDefault() ?? string.Empty;
+ }
+
public override bool DoesTableExist(IDatabase db, string tableName)
{
var result =
@@ -276,7 +287,7 @@ order by T.name, I.name");
return null;
}
- public override string DeleteDefaultConstraint => "ALTER TABLE [{0}] DROP CONSTRAINT [DF_{0}_{1}]";
+ public override string DeleteDefaultConstraint => "ALTER TABLE {0} DROP CONSTRAINT {2}";
public override string DropIndex => "DROP INDEX {0} ON {1}";
diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs
index 5b6a9afb04..210d8e4cf1 100644
--- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs
+++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs
@@ -223,6 +223,8 @@ namespace Umbraco.Core.Persistence.SqlSyntax
public abstract IEnumerable> GetDefinedIndexes(IDatabase db);
+ public abstract string GetDefaultConstraint(IDatabase db, string tableName, string columnName);
+
public virtual bool DoesTableExist(IDatabase db, string tableName)
{
return false;
@@ -552,6 +554,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
public virtual string CreateConstraint => "ALTER TABLE {0} ADD CONSTRAINT {1} {2} ({3})";
public virtual string DeleteConstraint => "ALTER TABLE {0} DROP CONSTRAINT {1}";
public virtual string CreateForeignKeyConstraint => "ALTER TABLE {0} ADD CONSTRAINT {1} FOREIGN KEY ({2}) REFERENCES {3} ({4}){5}{6}";
+ public virtual string CreateDefaultConstraint => "ALTER TABLE {0} ADD CONSTRAINT {1} DEFAULT ({2}) FOR {3}";
public virtual string ConvertIntegerToOrderableString => "REPLACE(STR({0}, 8), SPACE(1), '0')";
public virtual string ConvertDateToOrderableString => "CONVERT(nvarchar, {0}, 102)";
diff --git a/src/Umbraco.Tests/Migrations/AdvancedMigrationTests.cs b/src/Umbraco.Tests/Migrations/AdvancedMigrationTests.cs
index ba5de9dbd3..c13d141fa5 100644
--- a/src/Umbraco.Tests/Migrations/AdvancedMigrationTests.cs
+++ b/src/Umbraco.Tests/Migrations/AdvancedMigrationTests.cs
@@ -219,9 +219,9 @@ namespace Umbraco.Tests.Migrations
// drops *all* tables keys and indexes
var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToList();
foreach (var table in tables)
- Delete.KeysAndIndexes(table, false).Do();
+ Delete.KeysAndIndexes(table, false, true).Do();
foreach (var table in tables)
- Delete.KeysAndIndexes(table, true, false, false).Do();
+ Delete.KeysAndIndexes(table, true, false).Do();
}
}