Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e6597d47e3 | |||
| 89f69bd2a8 | |||
| 8087fc4c9a | |||
| f665f8af89 | |||
| c4163e94c0 | |||
| 62855d021f | |||
| 49430ca0a5 | |||
| 9d75e36eb4 | |||
| 5068b8ae9f | |||
| cdf3581721 | |||
| 0c6cca44d8 | |||
| f18b0aa774 | |||
| b9e8dd8b86 | |||
| 45d8d302c9 | |||
| e0ce9f1a77 | |||
| d7a0886097 |
@@ -6,17 +6,17 @@ namespace Umbraco.Core.Persistence.DatabaseModelDefinitions
|
||||
{
|
||||
public ConstraintDefinition(ConstraintType type)
|
||||
{
|
||||
constraintType = type;
|
||||
_constraintType = type;
|
||||
}
|
||||
|
||||
private ConstraintType constraintType;
|
||||
public bool IsPrimaryKeyConstraint { get { return ConstraintType.PrimaryKey == constraintType; } }
|
||||
public bool IsUniqueConstraint { get { return ConstraintType.Unique == constraintType; } }
|
||||
public bool IsNonUniqueConstraint { get { return ConstraintType.NonUnique == constraintType; } }
|
||||
private readonly ConstraintType _constraintType;
|
||||
public bool IsPrimaryKeyConstraint => ConstraintType.PrimaryKey == _constraintType;
|
||||
public bool IsUniqueConstraint => ConstraintType.Unique == _constraintType;
|
||||
public bool IsNonUniqueConstraint => ConstraintType.NonUnique == _constraintType;
|
||||
|
||||
public string SchemaName { get; set; }
|
||||
public string ConstraintName { get; set; }
|
||||
public string TableName { get; set; }
|
||||
public ICollection<string> Columns = new HashSet<string>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Persistence.DatabaseModelDefinitions
|
||||
{
|
||||
/// <summary>
|
||||
@@ -5,9 +7,17 @@ namespace Umbraco.Core.Persistence.DatabaseModelDefinitions
|
||||
/// </summary>
|
||||
internal class DbIndexDefinition
|
||||
{
|
||||
public virtual string IndexName { get; set; }
|
||||
public virtual string TableName { get; set; }
|
||||
public virtual string ColumnName { get; set; }
|
||||
public virtual bool IsUnique { get; set; }
|
||||
public DbIndexDefinition(Tuple<string, string, string, bool> data)
|
||||
{
|
||||
TableName = data.Item1;
|
||||
IndexName = data.Item2;
|
||||
ColumnName = data.Item3;
|
||||
IsUnique = data.Item4;
|
||||
}
|
||||
|
||||
public string IndexName { get; }
|
||||
public string TableName { get; }
|
||||
public string ColumnName { get; }
|
||||
public bool IsUnique { get; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,13 +159,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
|
||||
//get the db index defs
|
||||
result.DbIndexDefinitions = _sqlSyntaxProvider.GetDefinedIndexes(_database)
|
||||
.Select(x => new DbIndexDefinition()
|
||||
{
|
||||
TableName = x.Item1,
|
||||
IndexName = x.Item2,
|
||||
ColumnName = x.Item3,
|
||||
IsUnique = x.Item4
|
||||
}).ToArray();
|
||||
.Select(x => new DbIndexDefinition(x)).ToArray();
|
||||
|
||||
foreach (var item in OrderedTables.OrderBy(x => x.Key))
|
||||
{
|
||||
@@ -184,6 +178,14 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This validates the Primary/Foreign keys in the database
|
||||
/// </summary>
|
||||
/// <param name="result"></param>
|
||||
/// <remarks>
|
||||
/// This does not validate any database constraints that are not PKs or FKs because Umbraco does not create a database with non PK/FK contraints.
|
||||
/// Any unique "constraints" in the database are done with unique indexes.
|
||||
/// </remarks>
|
||||
private void ValidateDbConstraints(DatabaseSchemaResult result)
|
||||
{
|
||||
//MySql doesn't conform to the "normal" naming of constraints, so there is currently no point in doing these checks.
|
||||
@@ -196,8 +198,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
var constraintsInDatabase = _sqlSyntaxProvider.GetConstraintsPerColumn(_database).DistinctBy(x => x.Item3).ToList();
|
||||
var foreignKeysInDatabase = constraintsInDatabase.Where(x => x.Item3.InvariantStartsWith("FK_")).Select(x => x.Item3).ToList();
|
||||
var primaryKeysInDatabase = constraintsInDatabase.Where(x => x.Item3.InvariantStartsWith("PK_")).Select(x => x.Item3).ToList();
|
||||
var indexesInDatabase = constraintsInDatabase.Where(x => x.Item3.InvariantStartsWith("IX_")).Select(x => x.Item3).ToList();
|
||||
var indexesInSchema = result.TableDefinitions.SelectMany(x => x.Indexes.Select(y => y.Name)).ToList();
|
||||
|
||||
var unknownConstraintsInDatabase =
|
||||
constraintsInDatabase.Where(
|
||||
x =>
|
||||
@@ -212,7 +213,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
// In theory you could have: FK_ or fk_ ...or really any standard that your development department (or developer) chooses to use.
|
||||
foreach (var unknown in unknownConstraintsInDatabase)
|
||||
{
|
||||
if (foreignKeysInSchema.InvariantContains(unknown) || primaryKeysInSchema.InvariantContains(unknown) || indexesInSchema.InvariantContains(unknown))
|
||||
if (foreignKeysInSchema.InvariantContains(unknown) || primaryKeysInSchema.InvariantContains(unknown))
|
||||
{
|
||||
result.ValidConstraints.Add(unknown);
|
||||
}
|
||||
@@ -254,23 +255,6 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
result.Errors.Add(new Tuple<string, string>("Constraint", primaryKey));
|
||||
}
|
||||
|
||||
//Constaints:
|
||||
|
||||
//NOTE: SD: The colIndex checks above should really take care of this but I need to keep this here because it was here before
|
||||
// and some schema validation checks might rely on this data remaining here!
|
||||
//Add valid and invalid index differences to the result object
|
||||
var validIndexDifferences = indexesInDatabase.Intersect(indexesInSchema, StringComparer.InvariantCultureIgnoreCase);
|
||||
foreach (var index in validIndexDifferences)
|
||||
{
|
||||
result.ValidConstraints.Add(index);
|
||||
}
|
||||
var invalidIndexDifferences =
|
||||
indexesInDatabase.Except(indexesInSchema, StringComparer.InvariantCultureIgnoreCase)
|
||||
.Union(indexesInSchema.Except(indexesInDatabase, StringComparer.InvariantCultureIgnoreCase));
|
||||
foreach (var index in invalidIndexDifferences)
|
||||
{
|
||||
result.Errors.Add(new Tuple<string, string>("Constraint", index));
|
||||
}
|
||||
}
|
||||
|
||||
private void ValidateDbColumns(DatabaseSchemaResult result)
|
||||
|
||||
+2
-8
@@ -28,13 +28,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven
|
||||
public override void Up()
|
||||
{
|
||||
var dbIndexes = _skipIndexCheck ? new DbIndexDefinition[]{} : SqlSyntax.GetDefinedIndexes(Context.Database)
|
||||
.Select(x => new DbIndexDefinition()
|
||||
{
|
||||
TableName = x.Item1,
|
||||
IndexName = x.Item2,
|
||||
ColumnName = x.Item3,
|
||||
IsUnique = x.Item4
|
||||
}).ToArray();
|
||||
.Select(x => new DbIndexDefinition(x)).ToArray();
|
||||
|
||||
//make sure it doesn't already exist
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_cmsMacroProperty_Alias")) == false)
|
||||
@@ -54,4 +48,4 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven
|
||||
Delete.Index("IX_cmsMacroProperty_Alias").OnTable("cmsMacroProperty");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-8
@@ -30,13 +30,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven
|
||||
public override void Up()
|
||||
{
|
||||
var dbIndexes = _forTesting ? new DbIndexDefinition[] { } : SqlSyntax.GetDefinedIndexes(Context.Database)
|
||||
.Select(x => new DbIndexDefinition()
|
||||
{
|
||||
TableName = x.Item1,
|
||||
IndexName = x.Item2,
|
||||
ColumnName = x.Item3,
|
||||
IsUnique = x.Item4
|
||||
}).ToArray();
|
||||
.Select(x => new DbIndexDefinition(x)).ToArray();
|
||||
|
||||
//make sure it doesn't already exist
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_cmsMacro_Alias")) == false)
|
||||
@@ -75,4 +69,4 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven
|
||||
Delete.Index("IX_cmsMacro_Alias").OnTable("cmsMacro");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-8
@@ -18,13 +18,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven
|
||||
public override void Up()
|
||||
{
|
||||
var dbIndexes = SqlSyntax.GetDefinedIndexes(Context.Database)
|
||||
.Select(x => new DbIndexDefinition()
|
||||
{
|
||||
TableName = x.Item1,
|
||||
IndexName = x.Item2,
|
||||
ColumnName = x.Item3,
|
||||
IsUnique = x.Item4
|
||||
}).ToArray();
|
||||
.Select(x => new DbIndexDefinition(x)).ToArray();
|
||||
|
||||
//add a foreign key to the parent id column too!
|
||||
|
||||
@@ -54,4 +48,4 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven
|
||||
throw new DataLossException("Cannot downgrade from a version 7 database to a prior version, the database schema has already been modified");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-8
@@ -26,13 +26,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven
|
||||
// it is absolutely required to exist in order to have it as a foreign key reference, so we'll need to check it's existence
|
||||
// this came to light from this issue: http://issues.umbraco.org/issue/U4-4133
|
||||
var dbIndexes = SqlSyntax.GetDefinedIndexes(Context.Database)
|
||||
.Select(x => new DbIndexDefinition()
|
||||
{
|
||||
TableName = x.Item1,
|
||||
IndexName = x.Item2,
|
||||
ColumnName = x.Item3,
|
||||
IsUnique = x.Item4
|
||||
}).ToArray();
|
||||
.Select(x => new DbIndexDefinition(x)).ToArray();
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_cmsContent")) == false)
|
||||
{
|
||||
Create.Index("IX_cmsContent").OnTable("cmsContent").OnColumn("nodeId").Ascending().WithOptions().Unique();
|
||||
@@ -95,4 +89,4 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven
|
||||
//don't do anything, these keys should have always existed!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenEightZe
|
||||
{
|
||||
Execute.Code(database =>
|
||||
{
|
||||
var dbIndexes = SqlSyntax.GetDefinedIndexesDefinitions(Context.Database);
|
||||
var dbIndexes = SqlSyntax.GetDefinedIndexesDefinitions(database);
|
||||
|
||||
//make sure it doesn't already exist
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_cmsPropertyTypeAlias")) == false)
|
||||
|
||||
+2
-8
@@ -62,13 +62,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe
|
||||
}
|
||||
|
||||
var dbIndexes = SqlSyntax.GetDefinedIndexes(Context.Database)
|
||||
.Select(x => new DbIndexDefinition
|
||||
{
|
||||
TableName = x.Item1,
|
||||
IndexName = x.Item2,
|
||||
ColumnName = x.Item3,
|
||||
IsUnique = x.Item4
|
||||
}).ToArray();
|
||||
.Select(x => new DbIndexDefinition(x)).ToArray();
|
||||
|
||||
//make sure it doesn't already exist
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_cmsDictionary_id")) == false)
|
||||
@@ -104,4 +98,4 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-8
@@ -120,13 +120,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe
|
||||
|
||||
|
||||
var dbIndexes = SqlSyntax.GetDefinedIndexes(Context.Database)
|
||||
.Select(x => new DbIndexDefinition()
|
||||
{
|
||||
TableName = x.Item1,
|
||||
IndexName = x.Item2,
|
||||
ColumnName = x.Item3,
|
||||
IsUnique = x.Item4
|
||||
}).ToArray();
|
||||
.Select(x => new DbIndexDefinition(x)).ToArray();
|
||||
|
||||
//in some databases there's an index (IX_Master) on the master column which needs to be dropped first
|
||||
var foundIndex = dbIndexes.FirstOrDefault(x => x.TableName.InvariantEquals("cmsTemplate") && x.ColumnName.InvariantEquals("master"));
|
||||
@@ -167,4 +161,4 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe
|
||||
return path;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-8
@@ -15,13 +15,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe
|
||||
public override void Up()
|
||||
{
|
||||
var indexes = SqlSyntax.GetDefinedIndexes(Context.Database)
|
||||
.Select(x => new DbIndexDefinition()
|
||||
{
|
||||
TableName = x.Item1,
|
||||
IndexName = x.Item2,
|
||||
ColumnName = x.Item3,
|
||||
IsUnique = x.Item4
|
||||
}).ToArray();
|
||||
.Select(x => new DbIndexDefinition(x)).ToArray();
|
||||
|
||||
// drop the index if it exists
|
||||
if (indexes.Any(x => x.IndexName.InvariantEquals("IX_umbracoNodeUniqueID")))
|
||||
@@ -38,4 +32,4 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe
|
||||
public override void Down()
|
||||
{ }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+16
-17
@@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.DatabaseAnnotations;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenTwelveZero
|
||||
@@ -16,20 +13,22 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenTwelveZ
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
var exists = Context.Database.FirstOrDefault<RelationTypeDto>("WHERE alias=@alias", new { alias = Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteAlias });
|
||||
if (exists == null)
|
||||
var relationTypeCount = Context.Database.ExecuteScalar<int>("SELECT COUNT(*) FROM umbracoRelationType WHERE alias=@alias",
|
||||
new { alias = Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteAlias });
|
||||
|
||||
if (relationTypeCount > 0)
|
||||
return;
|
||||
|
||||
var uniqueId = (Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteAlias + "____" + Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteName).ToGuid();
|
||||
Insert.IntoTable("umbracoRelationType").Row(new
|
||||
{
|
||||
var uniqueId = (Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteAlias + "____" + Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteName).ToGuid();
|
||||
Insert.IntoTable("umbracoRelationType").Row(new
|
||||
{
|
||||
typeUniqueId = uniqueId,
|
||||
alias = Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteAlias,
|
||||
name = Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteName,
|
||||
childObjectType = Constants.ObjectTypes.MediaType,
|
||||
parentObjectType = Constants.ObjectTypes.MediaType,
|
||||
dual = false
|
||||
});
|
||||
}
|
||||
typeUniqueId = uniqueId,
|
||||
alias = Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteAlias,
|
||||
name = Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteName,
|
||||
childObjectType = Constants.ObjectTypes.MediaType,
|
||||
parentObjectType = Constants.ObjectTypes.MediaType,
|
||||
dual = false
|
||||
});
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
|
||||
+30
-14
@@ -15,21 +15,35 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenTwelveZ
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
var dbIndexes = SqlSyntax.GetDefinedIndexes(Context.Database)
|
||||
.Select(x => new DbIndexDefinition()
|
||||
{
|
||||
TableName = x.Item1,
|
||||
IndexName = x.Item2,
|
||||
ColumnName = x.Item3,
|
||||
IsUnique = x.Item4
|
||||
}).ToArray();
|
||||
|
||||
//Ensure the index exists before dropping it
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_umbracoLanguage_languageISOCode")))
|
||||
Execute.Code(database =>
|
||||
{
|
||||
Delete.Index("IX_umbracoLanguage_languageISOCode").OnTable("umbracoLanguage");
|
||||
}
|
||||
|
||||
var localContext = new LocalMigrationContext(Context.CurrentDatabaseProvider, database, SqlSyntax, Logger);
|
||||
// Some people seem to have a constraint in their DB instead of an index, we'd need to drop that one
|
||||
// See: https://our.umbraco.com/forum/using-umbraco-and-getting-started/93282-upgrade-from-711-to-712-fails
|
||||
var constraints = SqlSyntax.GetConstraintsPerTable(database).Distinct().ToArray();
|
||||
if (constraints.Any(x => x.Item2.InvariantEquals("IX_umbracoLanguage_languageISOCode")))
|
||||
{
|
||||
localContext.Delete.UniqueConstraint("IX_umbracoLanguage_languageISOCode").FromTable("umbracoLanguage");
|
||||
return localContext.GetSql();
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
Execute.Code(database =>
|
||||
{
|
||||
var localContext = new LocalMigrationContext(Context.CurrentDatabaseProvider, database, SqlSyntax, Logger);
|
||||
|
||||
//Now check for indexes of that name and drop that if it exists
|
||||
var dbIndexes = SqlSyntax.GetDefinedIndexes(database)
|
||||
.Select(x => new DbIndexDefinition(x)).ToArray();
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_umbracoLanguage_languageISOCode")))
|
||||
{
|
||||
localContext.Delete.Index("IX_umbracoLanguage_languageISOCode").OnTable("umbracoLanguage");
|
||||
return localContext.GetSql();
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
Alter.Table("umbracoLanguage")
|
||||
.AlterColumn("languageISOCode")
|
||||
.AsString(14)
|
||||
@@ -38,6 +52,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenTwelveZ
|
||||
Create.Index("IX_umbracoLanguage_languageISOCode")
|
||||
.OnTable("umbracoLanguage")
|
||||
.OnColumn("languageISOCode")
|
||||
.Ascending()
|
||||
.WithOptions()
|
||||
.Unique();
|
||||
}
|
||||
|
||||
|
||||
+3
-9
@@ -48,14 +48,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenTwoZero
|
||||
//Some very old schemas don't have an index on the cmsContentType.nodeId column, I'm not actually sure when it was added but
|
||||
// it is absolutely required to exist in order to add other foreign keys and much better for perf, so we'll need to check it's existence
|
||||
// this came to light from this issue: http://issues.umbraco.org/issue/U4-4133
|
||||
var dbIndexes = SqlSyntaxContext.SqlSyntaxProvider.GetDefinedIndexes(Context.Database)
|
||||
.Select(x => new DbIndexDefinition()
|
||||
{
|
||||
TableName = x.Item1,
|
||||
IndexName = x.Item2,
|
||||
ColumnName = x.Item3,
|
||||
IsUnique = x.Item4
|
||||
}).ToArray();
|
||||
var dbIndexes = SqlSyntax.GetDefinedIndexes(Context.Database)
|
||||
.Select(x => new DbIndexDefinition(x)).ToArray();
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_cmsContentType")) == false)
|
||||
{
|
||||
Create.Index("IX_cmsContentType").OnTable("cmsContentType").OnColumn("nodeId").Ascending().WithOptions().Unique();
|
||||
@@ -82,4 +76,4 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenTwoZero
|
||||
throw new DataLossException("Cannot downgrade from a version 7.2 database to a prior version, the database schema has already been modified");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-8
@@ -20,13 +20,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero
|
||||
{
|
||||
|
||||
var dbIndexes = SqlSyntax.GetDefinedIndexes(Context.Database)
|
||||
.Select(x => new DbIndexDefinition()
|
||||
{
|
||||
TableName = x.Item1,
|
||||
IndexName = x.Item2,
|
||||
ColumnName = x.Item3,
|
||||
IsUnique = x.Item4
|
||||
}).ToArray();
|
||||
.Select(x => new DbIndexDefinition(x)).ToArray();
|
||||
|
||||
//do not create any indexes if they already exist in the database
|
||||
|
||||
@@ -118,4 +112,4 @@ DROP TABLE ""umbracoUserLogins_temp""");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,8 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
string TruncateTable { get; }
|
||||
string CreateConstraint { get; }
|
||||
string DeleteConstraint { get; }
|
||||
|
||||
[Obsolete("This is never used, use the Format(ForeignKeyDefinition) instead")]
|
||||
string CreateForeignKeyConstraint { get; }
|
||||
string DeleteDefaultConstraint { get; }
|
||||
string FormatDateTime(DateTime date, bool includeTime = true);
|
||||
@@ -78,9 +80,32 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
|
||||
IEnumerable<string> GetTablesInSchema(Database db);
|
||||
IEnumerable<ColumnInfo> GetColumnsInSchema(Database db);
|
||||
|
||||
/// <summary>
|
||||
/// Returns all constraints defined in the database (Primary keys, foreign keys, unique constraints...) (does not include indexes)
|
||||
/// </summary>
|
||||
/// <param name="db"></param>
|
||||
/// <returns>
|
||||
/// A Tuple containing: TableName, ConstraintName
|
||||
/// </returns>
|
||||
IEnumerable<Tuple<string, string>> GetConstraintsPerTable(Database db);
|
||||
|
||||
/// <summary>
|
||||
/// Returns all constraints defined in the database (Primary keys, foreign keys, unique constraints...) (does not include indexes)
|
||||
/// </summary>
|
||||
/// <param name="db"></param>
|
||||
/// <returns>
|
||||
/// A Tuple containing: TableName, ColumnName, ConstraintName
|
||||
/// </returns>
|
||||
IEnumerable<Tuple<string, string, string>> GetConstraintsPerColumn(Database db);
|
||||
|
||||
/// <summary>
|
||||
/// Returns all defined Indexes in the database excluding primary keys
|
||||
/// </summary>
|
||||
/// <param name="db"></param>
|
||||
/// <returns>
|
||||
/// A Tuple containing: TableName, IndexName, ColumnName, IsUnique
|
||||
/// </returns>
|
||||
IEnumerable<Tuple<string, string, string, bool>> GetDefinedIndexes(Database db);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,6 +78,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<Tuple<string, string>> GetConstraintsPerTable(Database db)
|
||||
{
|
||||
List<Tuple<string, string>> list;
|
||||
@@ -100,6 +101,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<Tuple<string, string, string>> GetConstraintsPerColumn(Database db)
|
||||
{
|
||||
List<Tuple<string, string, string>> list;
|
||||
@@ -126,6 +128,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<Tuple<string, string, string, bool>> GetDefinedIndexes(Database db)
|
||||
{
|
||||
List<Tuple<string, string, string, bool>> list;
|
||||
@@ -401,4 +404,4 @@ ORDER BY TABLE_NAME, INDEX_NAME",
|
||||
return PetaPocoExtensions.EscapeAtSymbols(MySql.Data.MySqlClient.MySqlHelper.EscapeString(val));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
/// <summary>
|
||||
/// Represents an SqlSyntaxProvider for Sql Ce
|
||||
/// </summary>
|
||||
[SqlSyntaxProviderAttribute(Constants.DatabaseProviders.SqlCe)]
|
||||
[SqlSyntaxProvider(Constants.DatabaseProviders.SqlCe)]
|
||||
public class SqlCeSyntaxProvider : MicrosoftSqlSyntaxProviderBase<SqlCeSyntaxProvider>
|
||||
{
|
||||
public SqlCeSyntaxProvider()
|
||||
@@ -123,40 +123,27 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
item.IS_NULLABLE, item.DATA_TYPE)).ToList();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<Tuple<string, string>> GetConstraintsPerTable(Database db)
|
||||
{
|
||||
var items = db.Fetch<dynamic>("SELECT TABLE_NAME, CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS");
|
||||
var indexItems = db.Fetch<dynamic>("SELECT TABLE_NAME, INDEX_NAME FROM INFORMATION_SCHEMA.INDEXES");
|
||||
return
|
||||
items.Select(item => new Tuple<string, string>(item.TABLE_NAME, item.CONSTRAINT_NAME))
|
||||
.Union(
|
||||
indexItems.Select(
|
||||
indexItem => new Tuple<string, string>(indexItem.TABLE_NAME, indexItem.INDEX_NAME)))
|
||||
.ToList();
|
||||
return items.Select(item => new Tuple<string, string>(item.TABLE_NAME, item.CONSTRAINT_NAME)).ToList();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<Tuple<string, string, string>> GetConstraintsPerColumn(Database db)
|
||||
{
|
||||
var items =
|
||||
db.Fetch<dynamic>(
|
||||
"SELECT CONSTRAINT_NAME, TABLE_NAME, COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE");
|
||||
var indexItems = db.Fetch<dynamic>("SELECT INDEX_NAME, TABLE_NAME, COLUMN_NAME FROM INFORMATION_SCHEMA.INDEXES");
|
||||
return
|
||||
items.Select(
|
||||
item => new Tuple<string, string, string>(item.TABLE_NAME, item.COLUMN_NAME, item.CONSTRAINT_NAME))
|
||||
.Union(
|
||||
indexItems.Select(
|
||||
indexItem =>
|
||||
new Tuple<string, string, string>(indexItem.TABLE_NAME, indexItem.COLUMN_NAME,
|
||||
indexItem.INDEX_NAME))).ToList();
|
||||
var items = db.Fetch<dynamic>("SELECT TABLE_NAME, COLUMN_NAME, CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE");
|
||||
return items.Select(item => new Tuple<string, string, string>(item.TABLE_NAME, item.COLUMN_NAME, item.CONSTRAINT_NAME)).ToList();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<Tuple<string, string, string, bool>> GetDefinedIndexes(Database db)
|
||||
{
|
||||
var items =
|
||||
db.Fetch<dynamic>(
|
||||
@"SELECT TABLE_NAME, INDEX_NAME, COLUMN_NAME, [UNIQUE] FROM INFORMATION_SCHEMA.INDEXES
|
||||
WHERE INDEX_NAME NOT LIKE 'PK_%'
|
||||
WHERE PRIMARY_KEY=0
|
||||
ORDER BY TABLE_NAME, INDEX_NAME");
|
||||
return
|
||||
items.Select(
|
||||
@@ -215,4 +202,4 @@ ORDER BY TABLE_NAME, INDEX_NAME");
|
||||
public override string DropIndex { get { return "DROP INDEX {1}.{0}"; } }
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +88,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
item.IS_NULLABLE, item.DATA_TYPE)).ToList();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<Tuple<string, string>> GetConstraintsPerTable(Database db)
|
||||
{
|
||||
var items =
|
||||
@@ -96,6 +97,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
return items.Select(item => new Tuple<string, string>(item.TABLE_NAME, item.CONSTRAINT_NAME)).ToList();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<Tuple<string, string, string>> GetConstraintsPerColumn(Database db)
|
||||
{
|
||||
var items =
|
||||
@@ -104,6 +106,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
return items.Select(item => new Tuple<string, string, string>(item.TABLE_NAME, item.COLUMN_NAME, item.CONSTRAINT_NAME)).ToList();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<Tuple<string, string, string, bool>> GetDefinedIndexes(Database db)
|
||||
{
|
||||
var items =
|
||||
@@ -113,7 +116,7 @@ CASE WHEN I.is_unique_constraint = 1 OR I.is_unique = 1 THEN 1 ELSE 0 END AS [U
|
||||
from sys.tables as T inner join sys.indexes as I on T.[object_id] = I.[object_id]
|
||||
inner join sys.index_columns as IC on IC.[object_id] = I.[object_id] and IC.[index_id] = I.[index_id]
|
||||
inner join sys.all_columns as AC on IC.[object_id] = AC.[object_id] and IC.[column_id] = AC.[column_id]
|
||||
WHERE I.name NOT LIKE 'PK_%'
|
||||
WHERE I.is_primary_key = 0
|
||||
order by T.name, I.name");
|
||||
return items.Select(item => new Tuple<string, string, string, bool>(item.TABLE_NAME, item.INDEX_NAME, item.COLUMN_NAME,
|
||||
item.UNIQUE == 1)).ToList();
|
||||
@@ -183,4 +186,4 @@ order by T.name, I.name");
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -537,10 +537,11 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
|
||||
public virtual string CreateConstraint { get { return "ALTER TABLE {0} ADD CONSTRAINT {1} {2} ({3})"; } }
|
||||
public virtual string DeleteConstraint { get { return "ALTER TABLE {0} DROP CONSTRAINT {1}"; } }
|
||||
|
||||
public virtual string CreateForeignKeyConstraint { get { return "ALTER TABLE {0} ADD CONSTRAINT {1} FOREIGN KEY ({2}) REFERENCES {3} ({4}){5}{6}"; } }
|
||||
|
||||
public virtual string ConvertIntegerToOrderableString { get { return "REPLACE(STR({0}, 8), SPACE(1), '0')"; } }
|
||||
public virtual string ConvertDateToOrderableString { get { return "CONVERT(nvarchar, {0}, 102)"; } }
|
||||
public virtual string ConvertDecimalToOrderableString { get { return "REPLACE(STR({0}, 20, 9), SPACE(1), '0')"; } }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,13 +9,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
public static IEnumerable<DbIndexDefinition> GetDefinedIndexesDefinitions(this ISqlSyntaxProvider sql, Database db)
|
||||
{
|
||||
return sql.GetDefinedIndexes(db)
|
||||
.Select(x => new DbIndexDefinition()
|
||||
{
|
||||
TableName = x.Item1,
|
||||
IndexName = x.Item2,
|
||||
ColumnName = x.Item3,
|
||||
IsUnique = x.Item4
|
||||
}).ToArray();
|
||||
.Select(x => new DbIndexDefinition(x)).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -57,4 +51,4 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
In,
|
||||
NotIn
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-4
@@ -42,18 +42,19 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
return null;
|
||||
}
|
||||
|
||||
var isMultipleDataType = IsMultipleDataType(propertyType.DataTypeId, propertyType.PropertyEditorAlias);
|
||||
|
||||
var selectedValues = (string[]) source;
|
||||
|
||||
if (selectedValues.Any())
|
||||
{
|
||||
if (IsMultipleDataType(propertyType.DataTypeId, propertyType.PropertyEditorAlias))
|
||||
{
|
||||
if (isMultipleDataType)
|
||||
return selectedValues;
|
||||
}
|
||||
|
||||
return selectedValues.First();
|
||||
}
|
||||
|
||||
return source;
|
||||
return isMultipleDataType ? source : string.Empty;
|
||||
}
|
||||
|
||||
public Type GetPropertyValueType(PublishedPropertyType propertyType)
|
||||
|
||||
@@ -761,6 +761,8 @@ function tinyMceService($log, imageHelper, $http, $timeout, macroResource, macro
|
||||
* @param {string} input the string to parse
|
||||
*/
|
||||
getAnchorNames: function (input) {
|
||||
if (!input) return [];
|
||||
|
||||
var anchorPattern = /<a id=\\"(.*?)\\">/gi;
|
||||
var matches = input.match(anchorPattern);
|
||||
var anchors = [];
|
||||
@@ -771,7 +773,9 @@ function tinyMceService($log, imageHelper, $http, $timeout, macroResource, macro
|
||||
});
|
||||
}
|
||||
|
||||
return anchors;
|
||||
return anchors.filter(function(val, i, self) {
|
||||
return self.indexOf(val) === i;
|
||||
});
|
||||
},
|
||||
|
||||
insertLinkInEditor: function (editor, target, anchorElm) {
|
||||
|
||||
@@ -212,3 +212,14 @@
|
||||
position: relative;
|
||||
transform: translate(-50%, -25%);
|
||||
}
|
||||
|
||||
|
||||
// this resolves the layout issue introduced in nested content in 7.12 with the addition of the input for link anchors
|
||||
// the attribute selector ensures the change only applies to the linkpicker overlay
|
||||
.form-horizontal .umb-nested-content--narrow [ng-controller*="Umbraco.Overlays.LinkPickerController"] .controls-row {
|
||||
margin-left:0!important;
|
||||
|
||||
.umb-textarea, .umb-textstring {
|
||||
width:100%;
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
placeholder="@general_url"
|
||||
class="umb-editor umb-textstring"
|
||||
ng-model="target.url"
|
||||
ng-disabled="target.id" />
|
||||
ng-disabled="target.id || target.udi" />
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group label="@defaultdialogs_anchorLinkPicker" class="umb-property--push">
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
placeholder="@general_url"
|
||||
class="umb-editor umb-textstring"
|
||||
ng-model="model.target.url"
|
||||
ng-disabled="model.target.id" />
|
||||
ng-disabled="model.target.id || model.target.udi" />
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group label="@defaultdialogs_anchorLinkPicker" class="umb-property--push">
|
||||
|
||||
+3
-1
@@ -162,7 +162,9 @@ angular.module("umbraco").controller("Umbraco.Overlays.TreePickerController",
|
||||
|
||||
tree = args.tree;
|
||||
|
||||
if (node && node.path) {
|
||||
var nodeHasPath = typeof node !== "undefined" && typeof node.path !== "undefined";
|
||||
var startNodeNotDefined = typeof dialogOptions.startNodeId === "undefined" || dialogOptions.startNodeId === "" || dialogOptions.startNodeId === "-1";
|
||||
if (startNodeNotDefined && nodeHasPath) {
|
||||
$scope.dialogTreeEventHandler.syncTree({ path: node.path, activate: false });
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -17,11 +17,13 @@ namespace Umbraco.Web.HealthCheck.Checks.DataIntegrity
|
||||
{
|
||||
private readonly DatabaseContext _databaseContext;
|
||||
private readonly ILocalizedTextService _textService;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public DatabaseSchemaValidationHealthCheck(HealthCheckContext healthCheckContext) : base(healthCheckContext)
|
||||
{
|
||||
_databaseContext = HealthCheckContext.ApplicationContext.DatabaseContext;
|
||||
_textService = healthCheckContext.ApplicationContext.Services.TextService;
|
||||
_logger = healthCheckContext.ApplicationContext.ProfilingLogger.Logger;
|
||||
}
|
||||
|
||||
public override HealthCheckStatus ExecuteAction(HealthCheckAction action)
|
||||
@@ -39,10 +41,10 @@ namespace Umbraco.Web.HealthCheck.Checks.DataIntegrity
|
||||
{
|
||||
var results = _databaseContext.ValidateDatabaseSchema();
|
||||
|
||||
LogHelper.Warn(typeof(DatabaseSchemaValidationHealthCheck), _textService.Localize("databaseSchemaValidationCheckDatabaseLogMessage"));
|
||||
_logger.Warn(typeof(DatabaseSchemaValidationHealthCheck), _textService.Localize("databaseSchemaValidationCheckDatabaseLogMessage"));
|
||||
foreach(var error in results.Errors)
|
||||
{
|
||||
LogHelper.Warn(typeof(DatabaseSchemaValidationHealthCheck), error.Item1 + ": " + error.Item2);
|
||||
_logger.Warn(typeof(DatabaseSchemaValidationHealthCheck), error.Item1 + ": " + error.Item2);
|
||||
}
|
||||
|
||||
if(results.Errors.Count > 0)
|
||||
|
||||
@@ -13,12 +13,15 @@ namespace Umbraco.Web.Scheduling
|
||||
internal class KeepAlive : RecurringTaskBase
|
||||
{
|
||||
private readonly ApplicationContext _appContext;
|
||||
private static HttpClient _httpClient;
|
||||
|
||||
public KeepAlive(IBackgroundTaskRunner<RecurringTaskBase> runner, int delayMilliseconds, int periodMilliseconds,
|
||||
public KeepAlive(IBackgroundTaskRunner<RecurringTaskBase> runner, int delayMilliseconds, int periodMilliseconds,
|
||||
ApplicationContext appContext)
|
||||
: base(runner, delayMilliseconds, periodMilliseconds)
|
||||
{
|
||||
_appContext = appContext;
|
||||
if (_httpClient == null)
|
||||
_httpClient = new HttpClient();
|
||||
}
|
||||
|
||||
private ILogger Logger { get { return _appContext.ProfilingLogger.Logger; } }
|
||||
@@ -26,7 +29,7 @@ namespace Umbraco.Web.Scheduling
|
||||
public override async Task<bool> PerformRunAsync(CancellationToken token)
|
||||
{
|
||||
if (_appContext == null) return true; // repeat...
|
||||
|
||||
|
||||
switch (_appContext.GetCurrentServerRole())
|
||||
{
|
||||
case ServerRole.Slave:
|
||||
@@ -58,11 +61,9 @@ namespace Umbraco.Web.Scheduling
|
||||
}
|
||||
|
||||
var url = umbracoAppUrl + "/ping.aspx";
|
||||
using (var wc = new HttpClient())
|
||||
{
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, url);
|
||||
var result = await wc.SendAsync(request, token);
|
||||
}
|
||||
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, url);
|
||||
var result = await _httpClient.SendAsync(request, token);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -78,4 +79,4 @@ namespace Umbraco.Web.Scheduling
|
||||
get { return true; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{FD962632-1
|
||||
..\apidocs\docfx.json = ..\apidocs\docfx.json
|
||||
..\apidocs\index.md = ..\apidocs\index.md
|
||||
..\LICENSE.md = ..\LICENSE.md
|
||||
..\README.md = ..\README.md
|
||||
..\apidocs\toc.yml = ..\apidocs\toc.yml
|
||||
EndProjectSection
|
||||
EndProject
|
||||
@@ -21,9 +20,6 @@ EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NuSpecs", "NuSpecs", "{227C3B55-80E5-4E7E-A802-BE16C5128B9D}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
..\build\build.ps1 = ..\build\build.ps1
|
||||
..\build\InstallGit.cmd = ..\build\InstallGit.cmd
|
||||
..\build\RevertToCleanInstall.bat = ..\build\RevertToCleanInstall.bat
|
||||
..\build\RevertToEmptyInstall.bat = ..\build\RevertToEmptyInstall.bat
|
||||
..\build\setversion.ps1 = ..\build\setversion.ps1
|
||||
..\build\NuSpecs\UmbracoCms.Core.nuspec = ..\build\NuSpecs\UmbracoCms.Core.nuspec
|
||||
..\build\NuSpecs\UmbracoCms.nuspec = ..\build\NuSpecs\UmbracoCms.nuspec
|
||||
|
||||
Reference in New Issue
Block a user