diff --git a/src/Umbraco.Core/CoreBootManager.cs b/src/Umbraco.Core/CoreBootManager.cs
index 03a5206522..7c28c89bfc 100644
--- a/src/Umbraco.Core/CoreBootManager.cs
+++ b/src/Umbraco.Core/CoreBootManager.cs
@@ -241,11 +241,8 @@ namespace Umbraco.Core
// we're ready to serve content!
ApplicationContext.IsReady = true;
- //And now we can dispose of our startup handlers - save some memory
- ApplicationEventsResolver.Current.Dispose();
//stop the timer and log the output
_timer.Dispose();
-
return this;
}
diff --git a/src/Umbraco.Core/ObjectResolution/ApplicationEventsResolver.cs b/src/Umbraco.Core/ObjectResolution/ApplicationEventsResolver.cs
index 3d1d44133b..a31598bfc8 100644
--- a/src/Umbraco.Core/ObjectResolution/ApplicationEventsResolver.cs
+++ b/src/Umbraco.Core/ObjectResolution/ApplicationEventsResolver.cs
@@ -80,7 +80,7 @@ namespace Umbraco.Core.ObjectResolution
public void Dispose()
{
- Reset();
+ ResetCollections();
}
}
@@ -141,7 +141,7 @@ namespace Umbraco.Core.ObjectResolution
private void DisposeResources()
{
_legacyResolver.Dispose();
- Reset();
+ ResetCollections();
}
}
diff --git a/src/Umbraco.Core/ObjectResolution/ManyObjectsResolverBase.cs b/src/Umbraco.Core/ObjectResolution/ManyObjectsResolverBase.cs
index c19ba000a0..8bb5995891 100644
--- a/src/Umbraco.Core/ObjectResolution/ManyObjectsResolverBase.cs
+++ b/src/Umbraco.Core/ObjectResolution/ManyObjectsResolverBase.cs
@@ -340,7 +340,7 @@ namespace Umbraco.Core.ObjectResolution
/// WARNING! Do not use this unless you know what you are doing, clear all types registered and instances
/// created. Typically only used if a resolver is no longer used in an application and memory is to be GC'd
///
- internal void Reset()
+ internal void ResetCollections()
{
using (new WriteLock(_lock))
{
diff --git a/src/Umbraco.Core/Persistence/DatabaseModelDefinitions/DbIndexDefinition.cs b/src/Umbraco.Core/Persistence/DatabaseModelDefinitions/DbIndexDefinition.cs
new file mode 100644
index 0000000000..e495d61550
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/DatabaseModelDefinitions/DbIndexDefinition.cs
@@ -0,0 +1,13 @@
+namespace Umbraco.Core.Persistence.DatabaseModelDefinitions
+{
+ ///
+ /// Represents a database index definition retreived by querying the database
+ ///
+ 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; }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs b/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs
index 361f1f3949..19822a41be 100644
--- a/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs
+++ b/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs
@@ -124,6 +124,16 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
{
var result = new DatabaseSchemaResult();
+ //get the db index defs
+ result.DbIndexDefinitions = SqlSyntaxContext.SqlSyntaxProvider.GetDefinedIndexes(_database)
+ .Select(x => new DbIndexDefinition()
+ {
+ TableName = x.Item1,
+ IndexName = x.Item2,
+ ColumnName = x.Item3,
+ IsUnique = x.Item4
+ }).ToArray();
+
foreach (var item in OrderedTables.OrderBy(x => x.Key))
{
var tableDefinition = DefinitionFactory.GetTableDefinition(item.Value);
diff --git a/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaResult.cs b/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaResult.cs
index bc7f955902..8cbedf7945 100644
--- a/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaResult.cs
+++ b/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaResult.cs
@@ -29,6 +29,8 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
public List ValidConstraints { get; set; }
+ internal IEnumerable DbIndexDefinitions { get; set; }
+
///
/// Determines the version of the currently installed database.
///
diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AdditionalIndexesAndKeys.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AdditionalIndexesAndKeys.cs
index c4d3c1c572..333cd6351c 100644
--- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AdditionalIndexesAndKeys.cs
+++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixTwoZero/AdditionalIndexesAndKeys.cs
@@ -1,5 +1,9 @@
using System;
+using System.Linq;
using Umbraco.Core.Configuration;
+using Umbraco.Core.Persistence.DatabaseModelDefinitions;
+using Umbraco.Core.Persistence.Migrations.Initial;
+using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero
{
@@ -7,11 +11,35 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero
public class AdditionalIndexesAndKeys : MigrationBase
{
public override void Up()
- {
- //Create.Index("IX_umbracoNodeTrashed").OnTable("umbracoNode").OnColumn("trashed").Ascending().WithOptions().NonClustered();
- //Create.Index("IX_cmsContentVersion_ContentId").OnTable("cmsContentVersion").OnColumn("ContentId").Ascending().WithOptions().NonClustered();
- //Create.Index("IX_cmsDocument_published").OnTable("cmsDocument").OnColumn("published").Ascending().WithOptions().NonClustered();
- //Create.Index("IX_cmsDocument_newest").OnTable("cmsDocument").OnColumn("newest").Ascending().WithOptions().NonClustered();
+ {
+
+ var dbIndexes = SqlSyntaxContext.SqlSyntaxProvider.GetDefinedIndexes(Context.Database)
+ .Select(x => new DbIndexDefinition()
+ {
+ TableName = x.Item1,
+ IndexName = x.Item2,
+ ColumnName = x.Item3,
+ IsUnique = x.Item4
+ }).ToArray();
+
+ //do not create any indexes if they already exist in the database
+
+ if (dbIndexes.Any(x => x.IndexName == "IX_umbracoNodeTrashed") == false)
+ {
+ Create.Index("IX_umbracoNodeTrashed").OnTable("umbracoNode").OnColumn("trashed").Ascending().WithOptions().NonClustered();
+ }
+ if (dbIndexes.Any(x => x.IndexName == "IX_cmsContentVersion_ContentId") == false)
+ {
+ Create.Index("IX_cmsContentVersion_ContentId").OnTable("cmsContentVersion").OnColumn("ContentId").Ascending().WithOptions().NonClustered();
+ }
+ if (dbIndexes.Any(x => x.IndexName == "IX_cmsDocument_published") == false)
+ {
+ Create.Index("IX_cmsDocument_published").OnTable("cmsDocument").OnColumn("published").Ascending().WithOptions().NonClustered();
+ }
+ if (dbIndexes.Any(x => x.IndexName == "IX_cmsDocument_newest") == false)
+ {
+ Create.Index("IX_cmsDocument_newest").OnTable("cmsDocument").OnColumn("newest").Ascending().WithOptions().NonClustered();
+ }
}
public override void Down()
diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs
index c62fa1a923..b4c0020305 100644
--- a/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs
+++ b/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs
@@ -59,9 +59,12 @@ namespace Umbraco.Core.Persistence.SqlSyntax
bool SupportsClustered();
bool SupportsIdentityInsert();
bool? SupportsCaseInsensitiveQueries(Database db);
+
IEnumerable GetTablesInSchema(Database db);
IEnumerable GetColumnsInSchema(Database db);
IEnumerable> GetConstraintsPerTable(Database db);
IEnumerable> GetConstraintsPerColumn(Database db);
+
+ IEnumerable> GetDefinedIndexes(Database db);
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs
index 0b8d80a21f..b1554045f0 100644
--- a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs
+++ b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs
@@ -115,6 +115,31 @@ namespace Umbraco.Core.Persistence.SqlSyntax
return list;
}
+ public override IEnumerable> GetDefinedIndexes(Database db)
+ {
+ List> list;
+ try
+ {
+ var indexes =
+ db.Fetch(@"SELECT DISTINCT
+ TABLE_NAME, INDEX_NAME, COLUMN_NAME, CASE NON_UNIQUE WHEN 1 THEN 0 ELSE 1 END AS `UNIQUE`
+FROM INFORMATION_SCHEMA.STATISTICS
+WHERE TABLE_SCHEMA = @TableSchema
+ORDER BY TABLE_NAME, INDEX_NAME",
+ new { TableSchema = db.Connection.Database });
+ list =
+ indexes.Select(
+ item =>
+ new Tuple(item.TABLE_NAME, item.INDEX_NAME, item.COLUMN_NAME, item.UNIQUE == 1))
+ .ToList();
+ }
+ finally
+ {
+ db.CloseSharedConnection();
+ }
+ return list;
+ }
+
public override bool DoesTableExist(Database db, string tableName)
{
long result;
diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs
index d9e9599dab..a0acd8a8a8 100644
--- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs
+++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs
@@ -226,6 +226,16 @@ namespace Umbraco.Core.Persistence.SqlSyntax
indexItem.INDEX_NAME))).ToList();
}
+ public override IEnumerable> GetDefinedIndexes(Database db)
+ {
+ var items =
+ db.Fetch(
+ "SELECT TABLE_NAME, INDEX_NAME, COLUMN_NAME, [UNIQUE] FROM INFORMATION_SCHEMA.INDEXES ORDER BY TABLE_NAME, INDEX_NAME");
+ return
+ items.Select(
+ item => new Tuple(item.TABLE_NAME, item.INDEX_NAME, item.COLUMN_NAME, item.UNIQUE == 1));
+ }
+
public override bool DoesTableExist(Database db, string tableName)
{
var result =
diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs
index 4046a7575d..00311d6af6 100644
--- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs
+++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs
@@ -151,6 +151,21 @@ namespace Umbraco.Core.Persistence.SqlSyntax
return items.Select(item => new Tuple(item.TABLE_NAME, item.COLUMN_NAME, item.CONSTRAINT_NAME)).ToList();
}
+ public override IEnumerable> GetDefinedIndexes(Database db)
+ {
+ var items =
+ db.Fetch(
+ @"select T.name as TABLE_NAME, I.name as INDEX_NAME, AC.Name as COLUMN_NAME,
+CASE WHEN I.is_unique_constraint = 1 OR I.is_unique = 1 THEN 1 ELSE 0 END AS [UNIQUE]
+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]
+order by T.name, I.name");
+ return items.Select(item => new Tuple(item.TABLE_NAME, item.INDEX_NAME, item.COLUMN_NAME,
+ item.UNIQUE == 1)).ToList();
+
+ }
+
public override bool DoesTableExist(Database db, string tableName)
{
var result =
diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs
index 004aabfc70..1ceeddafb7 100644
--- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs
+++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs
@@ -212,6 +212,8 @@ namespace Umbraco.Core.Persistence.SqlSyntax
return new List>();
}
+ public abstract IEnumerable> GetDefinedIndexes(Database db);
+
public virtual bool DoesTableExist(Database db, string tableName)
{
return false;
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index b44d06ceaf..6c1701b424 100644
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -352,6 +352,7 @@
+
diff --git a/src/Umbraco.Core/UmbracoApplicationBase.cs b/src/Umbraco.Core/UmbracoApplicationBase.cs
index dd6c3a8103..c861eca6cd 100644
--- a/src/Umbraco.Core/UmbracoApplicationBase.cs
+++ b/src/Umbraco.Core/UmbracoApplicationBase.cs
@@ -5,6 +5,7 @@ using System.Web.Mvc;
using StackExchange.Profiling;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
+using Umbraco.Core.ObjectResolution;
namespace Umbraco.Core
{
@@ -40,6 +41,9 @@ namespace Umbraco.Core
.Initialize()
.Startup(appContext => OnApplicationStarting(sender, e))
.Complete(appContext => OnApplicationStarted(sender, e));
+
+ //And now we can dispose of our startup handlers - save some memory
+ ApplicationEventsResolver.Current.Dispose();
}
///