From caad0afed8319ebcd0c70b12a3768c5841e4697c Mon Sep 17 00:00:00 2001 From: Casey Neehouse Date: Thu, 7 Mar 2013 21:00:31 +0500 Subject: [PATCH 1/8] Corrects u4-1870 - Refactor Load Content SQL to check if ID is in published list versus using a join that can cause duplicate entries. --- src/Umbraco.Web/umbraco.presentation/content.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Umbraco.Web/umbraco.presentation/content.cs b/src/Umbraco.Web/umbraco.presentation/content.cs index b762e3ba85..990bdef64a 100644 --- a/src/Umbraco.Web/umbraco.presentation/content.cs +++ b/src/Umbraco.Web/umbraco.presentation/content.cs @@ -1091,8 +1091,7 @@ namespace umbraco string sql = @"select umbracoNode.id, umbracoNode.parentId, umbracoNode.sortOrder, cmsContentXml.xml from umbracoNode inner join cmsContentXml on cmsContentXml.nodeId = umbracoNode.id and umbracoNode.nodeObjectType = @type -inner join cmsDocument on cmsDocument.nodeId = umbracoNode.id -where cmsDocument.published = 1 +where umbracoNode.id in (select cmsDocument.nodeId from cmsDocument where cmsDocument.published = 1) order by umbracoNode.level, umbracoNode.sortOrder"; lock (DbReadSyncLock) From d1b05332c58d5b6081981d43da3c2a25547ed2f8 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Thu, 7 Mar 2013 20:28:13 -0100 Subject: [PATCH 2/8] Manually adds fix for U4-1869 from 6.0.3 branch --- src/Umbraco.Core/IO/IOHelper.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/Umbraco.Core/IO/IOHelper.cs b/src/Umbraco.Core/IO/IOHelper.cs index a53ae8d924..aaf5298447 100644 --- a/src/Umbraco.Core/IO/IOHelper.cs +++ b/src/Umbraco.Core/IO/IOHelper.cs @@ -8,6 +8,7 @@ using System.IO; using System.Configuration; using System.Web; using System.Text.RegularExpressions; +using System.Xml; using Umbraco.Core.Configuration; using Umbraco.Core.Logging; @@ -228,6 +229,20 @@ namespace Umbraco.Core.IO filePath = String.Empty; } + //Break up the file in name and extension before applying the UrlReplaceCharacters + var fileNamePart = filePath.Substring(0, filePath.LastIndexOf('.')); + var ext = filePath.Substring(filePath.LastIndexOf('.')); + + //Because the file usually is downloadable as well we check characters against 'UmbracoSettings.UrlReplaceCharacters' + XmlNode replaceChars = UmbracoSettings.UrlReplaceCharacters; + foreach (XmlNode n in replaceChars.SelectNodes("char")) + { + if (n.Attributes.GetNamedItem("org") != null && n.Attributes.GetNamedItem("org").Value != "") + fileNamePart = fileNamePart.Replace(n.Attributes.GetNamedItem("org").Value, XmlHelper.GetNodeValue(n)); + } + + filePath = string.Concat(fileNamePart, ext); + // Adapted from: http://stackoverflow.com/a/4827510/5018 // Combined both Reserved Characters and Character Data // from http://en.wikipedia.org/wiki/Percent-encoding From 928d92fce43e4c9487e7bf133f0f95ee78b18fae Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Sat, 9 Mar 2013 10:43:34 -0100 Subject: [PATCH 3/8] Making the Sql Syntax Providers public and changing a few names and bits for consistency. Adding resolver for the syntax providers and wiring it up in the boot manager. --- src/Umbraco.Core/CoreBootManager.cs | 18 +++--- src/Umbraco.Core/DatabaseContext.cs | 33 +++++------ .../Persistence/Mappers/BaseMapper.cs | 4 +- .../Initial/DatabaseSchemaCreation.cs | 8 +-- .../Initial/DatabaseSchemaResult.cs | 2 +- .../Expressions/AlterColumnExpression.cs | 6 +- .../AlterDefaultConstraintExpression.cs | 6 +- .../Expressions/CreateConstraintExpression.cs | 10 ++-- .../Expressions/CreateTableExpression.cs | 2 +- .../Expressions/DeleteColumnExpression.cs | 6 +- .../Expressions/DeleteConstraintExpression.cs | 6 +- .../Expressions/DeleteDataExpression.cs | 10 ++-- .../DeleteDefaultConstraintExpression.cs | 2 +- .../Expressions/DeleteForeignKeyExpression.cs | 12 ++-- .../Expressions/DeleteIndexExpression.cs | 6 +- .../Expressions/DeleteTableExpression.cs | 4 +- .../Expressions/CreateColumnExpression.cs | 6 +- .../Expressions/CreateForeignKeyExpression.cs | 2 +- .../Expressions/CreateIndexExpression.cs | 2 +- .../Expressions/RenameColumnExpression.cs | 2 +- .../Expressions/RenameTableExpression.cs | 2 +- .../Expressions/UpdateDataExpression.cs | 12 ++-- .../Persistence/PetaPocoExtensions.cs | 24 ++++---- .../Persistence/PetaPocoSqlExtensions.cs | 28 +++++----- .../Querying/PocoToSqlExpressionHelper.cs | 4 +- .../Persistence/SqlSyntax/DbTypes.cs | 2 +- .../SqlSyntax/MySqlSyntaxProvider.cs | 11 ++-- .../SqlSyntax/SqlCeSyntaxProvider.cs | 12 ++-- .../SqlSyntax/SqlServerSyntaxProvider.cs | 11 ++-- .../{SyntaxConfig.cs => SqlSyntaxContext.cs} | 6 +- .../SqlSyntax/SqlSyntaxProviderAttribute.cs | 21 +++++++ .../SqlSyntax/SqlSyntaxProviderBase.cs | 2 +- .../SqlSyntax/SqlSyntaxProvidersResolver.cs | 55 +++++++++++++++++++ src/Umbraco.Core/PluginManager.cs | 10 ++++ src/Umbraco.Core/TypeFinder.cs | 1 - src/Umbraco.Core/Umbraco.Core.csproj | 4 +- .../BootManagers/CoreBootManagerTests.cs | 8 +++ .../Migrations/AlterMigrationTests.cs | 2 +- .../Migrations/FindingMigrationsTest.cs | 2 +- .../TargetVersionSixthMigrationsTest.cs | 2 +- .../Migrations/Upgrades/BaseUpgradeTest.cs | 4 +- .../Upgrades/ValidateOlderSchemaTest.cs | 4 +- .../Persistence/DatabaseContextTests.cs | 2 +- .../Persistence/Mappers/ContentMapperTest.cs | 8 +-- .../Mappers/ContentTypeMapperTest.cs | 8 +-- .../Mappers/DataTypeDefinitionMapperTest.cs | 8 +-- .../Mappers/DictionaryMapperTest.cs | 6 +- .../DictionaryTranslationMapperTest.cs | 6 +- .../Persistence/Mappers/LanguageMapperTest.cs | 6 +- .../Persistence/Mappers/MediaMapperTest.cs | 8 +-- .../Mappers/PropertyGroupMapperTest.cs | 8 +-- .../Mappers/PropertyTypeMapperTest.cs | 12 ++-- .../Persistence/Mappers/RelationMapperTest.cs | 10 ++-- .../Mappers/RelationTypeMapperTest.cs | 8 +-- .../Persistence/MySqlDatabaseCreationTest.cs | 2 +- .../Persistence/MySqlTableByTableTest.cs | 2 +- .../Persistence/SqlCeTableByTableTest.cs | 4 +- .../Persistence/SqlTableByTableTest.cs | 4 +- .../SyntaxProvider/SqlSyntaxProviderTests.cs | 12 ++-- .../TestHelpers/BaseDatabaseFactoryTest.cs | 10 +++- .../TestHelpers/BaseDatabaseTest.cs | 6 +- .../TestHelpers/BaseUsingSqlCeSyntax.cs | 4 +- .../config/ClientDependency.config | 2 +- 63 files changed, 308 insertions(+), 202 deletions(-) rename src/Umbraco.Core/Persistence/SqlSyntax/{SyntaxConfig.cs => SqlSyntaxContext.cs} (72%) create mode 100644 src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderAttribute.cs create mode 100644 src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProvidersResolver.cs diff --git a/src/Umbraco.Core/CoreBootManager.cs b/src/Umbraco.Core/CoreBootManager.cs index a26a5b7b6d..000d662bcb 100644 --- a/src/Umbraco.Core/CoreBootManager.cs +++ b/src/Umbraco.Core/CoreBootManager.cs @@ -1,7 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; using Umbraco.Core.Configuration; using Umbraco.Core.Logging; using Umbraco.Core.ObjectResolution; @@ -10,6 +8,7 @@ using Umbraco.Core.Persistence.Mappers; using Umbraco.Core.Persistence.Migrations; using Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix; using Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixZeroOne; +using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Core.Persistence.UnitOfWork; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Publishing; @@ -65,18 +64,17 @@ namespace Umbraco.Core //create the ApplicationContext ApplicationContext = ApplicationContext.Current = new ApplicationContext(dbContext, serviceContext); - //initialize the DatabaseContext - dbContext.Initialize(); - InitializeApplicationEventsResolver(); InitializeResolvers(); - + + //initialize the DatabaseContext + dbContext.Initialize(); + //now we need to call the initialize methods ApplicationEventsResolver.Current.ApplicationEventHandlers .ForEach(x => x.OnApplicationInitialized(UmbracoApplication, ApplicationContext)); - _isInitialized = true; return this; @@ -169,6 +167,12 @@ namespace Umbraco.Core RepositoryResolver.Current = new RepositoryResolver( new RepositoryFactory()); + SqlSyntaxProvidersResolver.Current = new SqlSyntaxProvidersResolver( + PluginManager.Current.ResolveSqlSyntaxProviders()) + { + CanResolveBeforeFrozen = true + }; + CacheRefreshersResolver.Current = new CacheRefreshersResolver( () => PluginManager.Current.ResolveCacheRefreshers()); diff --git a/src/Umbraco.Core/DatabaseContext.cs b/src/Umbraco.Core/DatabaseContext.cs index e33b63b01b..420831d299 100644 --- a/src/Umbraco.Core/DatabaseContext.cs +++ b/src/Umbraco.Core/DatabaseContext.cs @@ -337,21 +337,22 @@ namespace Umbraco.Core internal void Initialize(string providerName) { - if (providerName.StartsWith("MySql")) - { - SyntaxConfig.SqlSyntaxProvider = MySqlSyntax.Provider; - } - else if (providerName.Contains("SqlServerCe")) - { - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; - } - else - { - SyntaxConfig.SqlSyntaxProvider = SqlServerSyntax.Provider; - } - _providerName = providerName; - _configured = true; + + try + { + SqlSyntaxContext.SqlSyntaxProvider = + SqlSyntaxProvidersResolver.Current.GetByProviderNameOrDefault(providerName); + + _configured = true; + } + catch (Exception e) + { + _configured = false; + + LogHelper.Info("Initialization of the DatabaseContext failed with following error: " + e.Message); + LogHelper.Info(e.StackTrace); + } } internal DatabaseSchemaResult ValidateDatabaseSchema() @@ -388,7 +389,7 @@ namespace Umbraco.Core var message = string.Empty; var database = new UmbracoDatabase(_connectionString, ProviderName); - var supportsCaseInsensitiveQueries = SyntaxConfig.SqlSyntaxProvider.SupportsCaseInsensitiveQueries(database); + var supportsCaseInsensitiveQueries = SqlSyntaxContext.SqlSyntaxProvider.SupportsCaseInsensitiveQueries(database); if (supportsCaseInsensitiveQueries == false) { message = "

 

The database you're trying to use does not support case insensitive queries.
We currently do not support these types of databases.

" + @@ -411,7 +412,7 @@ namespace Umbraco.Core } else { - if (SyntaxConfig.SqlSyntaxProvider == MySqlSyntaxProvider.Instance) + if (SqlSyntaxContext.SqlSyntaxProvider.GetType() == typeof(MySqlSyntaxProvider)) { message = "

 

Congratulations, the database step ran successfully!

" + "

Note: You're using MySQL and the database instance you're connecting to seems to support case insensitive queries.

" + diff --git a/src/Umbraco.Core/Persistence/Mappers/BaseMapper.cs b/src/Umbraco.Core/Persistence/Mappers/BaseMapper.cs index 86d5e026d8..76ac6af949 100644 --- a/src/Umbraco.Core/Persistence/Mappers/BaseMapper.cs +++ b/src/Umbraco.Core/Persistence/Mappers/BaseMapper.cs @@ -30,8 +30,8 @@ namespace Umbraco.Core.Persistence.Mappers string columnName = columnAttribute.Name; string columnMap = string.Format("{0}.{1}", - SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName), - SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(columnName)); + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName), + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(columnName)); return columnMap; } } diff --git a/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs b/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs index 756d97ff13..7d9d59c08c 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs @@ -102,7 +102,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial } //Check tables in configured database against tables in schema - var tablesInDatabase = SyntaxConfig.SqlSyntaxProvider.GetTablesInSchema(_database).ToList(); + var tablesInDatabase = SqlSyntaxContext.SqlSyntaxProvider.GetTablesInSchema(_database).ToList(); var tablesInSchema = result.TableDefinitions.Select(x => x.Name).ToList(); //Add valid and invalid table differences to the result object var validTableDifferences = tablesInDatabase.Intersect(tablesInSchema); @@ -117,7 +117,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial } //Check columns in configured database against columns in schema - var columnsInDatabase = SyntaxConfig.SqlSyntaxProvider.GetColumnsInSchema(_database); + var columnsInDatabase = SqlSyntaxContext.SqlSyntaxProvider.GetColumnsInSchema(_database); var columnsPerTableInDatabase = columnsInDatabase.Select(x => string.Concat(x.TableName, ",", x.ColumnName)).ToList(); var columnsPerTableInSchema = result.TableDefinitions.SelectMany(x => x.Columns.Select(y => string.Concat(y.TableName, ",", y.Name))).ToList(); //Add valid and invalid column differences to the result object @@ -134,11 +134,11 @@ namespace Umbraco.Core.Persistence.Migrations.Initial //MySql doesn't conform to the "normal" naming of constraints, so there is currently no point in doing these checks. //NOTE: At a later point we do other checks for MySql, but ideally it should be necessary to do special checks for different providers. - if (SyntaxConfig.SqlSyntaxProvider is MySqlSyntaxProvider) + if (SqlSyntaxContext.SqlSyntaxProvider is MySqlSyntaxProvider) return result; //Check constraints in configured database against constraints in schema - var constraintsInDatabase = SyntaxConfig.SqlSyntaxProvider.GetConstraintsPerColumn(_database).DistinctBy(x => x.Item3).ToList(); + var constraintsInDatabase = SqlSyntaxContext.SqlSyntaxProvider.GetConstraintsPerColumn(_database).DistinctBy(x => x.Item3).ToList(); var foreignKeysInDatabase = constraintsInDatabase.Where(x => x.Item3.StartsWith("FK_")).Select(x => x.Item3).ToList(); var primaryKeysInDatabase = constraintsInDatabase.Where(x => x.Item3.StartsWith("PK_")).Select(x => x.Item3).ToList(); var indexesInDatabase = constraintsInDatabase.Where(x => x.Item3.StartsWith("IX_")).Select(x => x.Item3).ToList(); diff --git a/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaResult.cs b/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaResult.cs index 7cf0b2eb5f..442ec94abd 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaResult.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaResult.cs @@ -111,7 +111,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial sb.AppendLine(" "); } - if (SyntaxConfig.SqlSyntaxProvider is MySqlSyntaxProvider) + if (SqlSyntaxContext.SqlSyntaxProvider is MySqlSyntaxProvider) { sb.AppendLine("Please note that the constraints could not be validated because the current dataprovider is MySql."); } diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Expressions/AlterColumnExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Expressions/AlterColumnExpression.cs index 2a88a51337..db58b7f918 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Expressions/AlterColumnExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Expressions/AlterColumnExpression.cs @@ -21,9 +21,9 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Expressions public override string ToString() { - return string.Format(SyntaxConfig.SqlSyntaxProvider.AlterColumn, - SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(TableName), - SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(Column.Name)); + return string.Format(SqlSyntaxContext.SqlSyntaxProvider.AlterColumn, + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(TableName), + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(Column.Name)); } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Expressions/AlterDefaultConstraintExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Expressions/AlterDefaultConstraintExpression.cs index 2d0dd81150..cd99b6754f 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Expressions/AlterDefaultConstraintExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Expressions/AlterDefaultConstraintExpression.cs @@ -22,9 +22,9 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Expressions { //NOTE Should probably investigate if Deleting a Default Constraint is different from deleting a 'regular' constraint - return string.Format(SyntaxConfig.SqlSyntaxProvider.DeleteConstraint, - SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(TableName), - SyntaxConfig.SqlSyntaxProvider.GetQuotedName(ConstraintName)); + return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteConstraint, + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(TableName), + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedName(ConstraintName)); } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Expressions/CreateConstraintExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Expressions/CreateConstraintExpression.cs index ba2b29e873..b575a89c49 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Expressions/CreateConstraintExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Expressions/CreateConstraintExpression.cs @@ -17,7 +17,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Create.Expressions { var constraintType = (Constraint.IsPrimaryKeyConstraint) ? "PRIMARY KEY" : "UNIQUE"; - if (Constraint.IsPrimaryKeyConstraint && SyntaxConfig.SqlSyntaxProvider.SupportsClustered()) + if (Constraint.IsPrimaryKeyConstraint && SqlSyntaxContext.SqlSyntaxProvider.SupportsClustered()) constraintType += " CLUSTERED"; if (Constraint.IsNonUniqueConstraint) @@ -27,12 +27,12 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Create.Expressions for (int i = 0; i < Constraint.Columns.Count; i++) { - columns[i] = SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(Constraint.Columns.ElementAt(i)); + columns[i] = SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(Constraint.Columns.ElementAt(i)); } - return string.Format(SyntaxConfig.SqlSyntaxProvider.CreateConstraint, - SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(Constraint.TableName), - SyntaxConfig.SqlSyntaxProvider.GetQuotedName(Constraint.ConstraintName), + return string.Format(SqlSyntaxContext.SqlSyntaxProvider.CreateConstraint, + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(Constraint.TableName), + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedName(Constraint.ConstraintName), constraintType, string.Join(", ", columns)); } diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Expressions/CreateTableExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Expressions/CreateTableExpression.cs index 31eadf27e8..4ca4db5989 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Expressions/CreateTableExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Expressions/CreateTableExpression.cs @@ -24,7 +24,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Create.Expressions { var table = new TableDefinition{Name = TableName, SchemaName = SchemaName, Columns = Columns}; - return string.Format(SyntaxConfig.SqlSyntaxProvider.Format(table)); + return string.Format(SqlSyntaxContext.SqlSyntaxProvider.Format(table)); } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteColumnExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteColumnExpression.cs index bbeaa3ffa2..c9f8c8d04d 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteColumnExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteColumnExpression.cs @@ -31,9 +31,9 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions foreach (string columnName in ColumnNames) { if (ColumnNames.First() != columnName) sb.AppendLine(";"); - sb.AppendFormat(SyntaxConfig.SqlSyntaxProvider.DropColumn, - SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(TableName), - SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(columnName)); + sb.AppendFormat(SqlSyntaxContext.SqlSyntaxProvider.DropColumn, + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(TableName), + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(columnName)); } return sb.ToString(); diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteConstraintExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteConstraintExpression.cs index 075d6c5d1b..1f20f6bbb9 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteConstraintExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteConstraintExpression.cs @@ -14,9 +14,9 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions public override string ToString() { - return string.Format(SyntaxConfig.SqlSyntaxProvider.DeleteConstraint, - SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(Constraint.TableName), - SyntaxConfig.SqlSyntaxProvider.GetQuotedName(Constraint.ConstraintName)); + return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteConstraint, + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(Constraint.TableName), + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedName(Constraint.ConstraintName)); } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteDataExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteDataExpression.cs index 23c4388d50..2131a7b106 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteDataExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteDataExpression.cs @@ -32,7 +32,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions if (IsAllRows) { - deleteItems.Add(string.Format(SyntaxConfig.SqlSyntaxProvider.DeleteData, SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(TableName), "1 = 1")); + deleteItems.Add(string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteData, SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(TableName), "1 = 1")); } else { @@ -42,13 +42,13 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions foreach (KeyValuePair item in row) { whereClauses.Add(string.Format("{0} {1} {2}", - SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(item.Key), + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(item.Key), item.Value == null ? "IS" : "=", - SyntaxConfig.SqlSyntaxProvider.GetQuotedValue(item.Value.ToString()))); + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedValue(item.Value.ToString()))); } - deleteItems.Add(string.Format(SyntaxConfig.SqlSyntaxProvider.DeleteData, - SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(TableName), + deleteItems.Add(string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteData, + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(TableName), String.Join(" AND ", whereClauses.ToArray()))); } } diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteDefaultConstraintExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteDefaultConstraintExpression.cs index 72e86f4d1d..43677d23e3 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteDefaultConstraintExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteDefaultConstraintExpression.cs @@ -22,7 +22,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions if (IsExpressionSupported() == false) return string.Empty; - return string.Format(SyntaxConfig.SqlSyntaxProvider.DeleteDefaultConstraint, + return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteDefaultConstraint, TableName, ColumnName); } diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteForeignKeyExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteForeignKeyExpression.cs index 5cb3ef3bfa..df79f7c8f7 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteForeignKeyExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteForeignKeyExpression.cs @@ -33,10 +33,10 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions if (string.IsNullOrEmpty(ForeignKey.Name)) ForeignKey.Name = string.Format("{0}_ibfk_1", ForeignKey.ForeignTable.ToLower()); - return string.Format(SyntaxConfig.SqlSyntaxProvider.DeleteConstraint, - SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(ForeignKey.ForeignTable), + return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteConstraint, + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(ForeignKey.ForeignTable), "FOREIGN KEY ", - SyntaxConfig.SqlSyntaxProvider.GetQuotedName(ForeignKey.Name)); + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedName(ForeignKey.Name)); } if (string.IsNullOrEmpty(ForeignKey.Name)) @@ -44,9 +44,9 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions ForeignKey.Name = string.Format("FK_{0}_{1}", ForeignKey.ForeignTable, ForeignKey.PrimaryTable); } - return string.Format(SyntaxConfig.SqlSyntaxProvider.DeleteConstraint, - SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(ForeignKey.ForeignTable), - SyntaxConfig.SqlSyntaxProvider.GetQuotedName(ForeignKey.Name)); + return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DeleteConstraint, + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(ForeignKey.ForeignTable), + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedName(ForeignKey.Name)); } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteIndexExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteIndexExpression.cs index e27bf23693..3e1a959925 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteIndexExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteIndexExpression.cs @@ -19,9 +19,9 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions public override string ToString() { - return string.Format(SyntaxConfig.SqlSyntaxProvider.DropIndex, - SyntaxConfig.SqlSyntaxProvider.GetQuotedName(Index.Name), - SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(Index.TableName)); + return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DropIndex, + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedName(Index.Name), + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(Index.TableName)); } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteTableExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteTableExpression.cs index 2ae2d36474..2fff4e75e0 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteTableExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Delete/Expressions/DeleteTableExpression.cs @@ -17,8 +17,8 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Delete.Expressions public override string ToString() { - return string.Format(SyntaxConfig.SqlSyntaxProvider.DropTable, - SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(TableName)); + return string.Format(SqlSyntaxContext.SqlSyntaxProvider.DropTable, + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(TableName)); } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateColumnExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateColumnExpression.cs index 28df1fbb2b..5c7bf3c0b7 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateColumnExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateColumnExpression.cs @@ -28,9 +28,9 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Expressions if (string.IsNullOrEmpty(Column.TableName)) Column.TableName = TableName; - return string.Format(SyntaxConfig.SqlSyntaxProvider.AddColumn, - SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(Column.TableName), - SyntaxConfig.SqlSyntaxProvider.Format(Column)); + return string.Format(SqlSyntaxContext.SqlSyntaxProvider.AddColumn, + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(Column.TableName), + SqlSyntaxContext.SqlSyntaxProvider.Format(Column)); } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateForeignKeyExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateForeignKeyExpression.cs index ef523ade12..c6c0c437ef 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateForeignKeyExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateForeignKeyExpression.cs @@ -23,7 +23,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Expressions if (IsExpressionSupported() == false) return string.Empty; - return SyntaxConfig.SqlSyntaxProvider.Format(ForeignKey); + return SqlSyntaxContext.SqlSyntaxProvider.Format(ForeignKey); } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateIndexExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateIndexExpression.cs index 5495556d3c..aa33263346 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateIndexExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Expressions/CreateIndexExpression.cs @@ -19,7 +19,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Expressions public override string ToString() { - return SyntaxConfig.SqlSyntaxProvider.Format(Index); + return SqlSyntaxContext.SqlSyntaxProvider.Format(Index); } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/Expressions/RenameColumnExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/Expressions/RenameColumnExpression.cs index 17d4055f80..4f626e2117 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/Expressions/RenameColumnExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/Expressions/RenameColumnExpression.cs @@ -52,7 +52,7 @@ SELECT CONCAT( if (IsExpressionSupported() == false) return string.Empty; - return SyntaxConfig.SqlSyntaxProvider.FormatColumnRename(TableName, OldName, NewName); + return SqlSyntaxContext.SqlSyntaxProvider.FormatColumnRename(TableName, OldName, NewName); } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/Expressions/RenameTableExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/Expressions/RenameTableExpression.cs index 349db29c47..956cc32bfc 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/Expressions/RenameTableExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Rename/Expressions/RenameTableExpression.cs @@ -22,7 +22,7 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Rename.Expressions if (IsExpressionSupported() == false) return string.Empty; - return SyntaxConfig.SqlSyntaxProvider.FormatTableRename(OldName, NewName); + return SqlSyntaxContext.SqlSyntaxProvider.FormatTableRename(OldName, NewName); } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Update/Expressions/UpdateDataExpression.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Update/Expressions/UpdateDataExpression.cs index 9baa3501cf..a5a3204974 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Update/Expressions/UpdateDataExpression.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Update/Expressions/UpdateDataExpression.cs @@ -31,8 +31,8 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Update.Expressions foreach (var item in Set) { updateItems.Add(string.Format("{0} = {1}", - SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(item.Key), - SyntaxConfig.SqlSyntaxProvider.GetQuotedValue(item.Value.ToString()))); + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(item.Key), + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedValue(item.Value.ToString()))); } if (IsAllRows) @@ -44,13 +44,13 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Update.Expressions foreach (var item in Where) { whereClauses.Add(string.Format("{0} {1} {2}", - SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(item.Key), + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(item.Key), item.Value == null ? "IS" : "=", - SyntaxConfig.SqlSyntaxProvider.GetQuotedValue(item.Value.ToString()))); + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedValue(item.Value.ToString()))); } } - return string.Format(SyntaxConfig.SqlSyntaxProvider.UpdateData, - SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(TableName), + return string.Format(SqlSyntaxContext.SqlSyntaxProvider.UpdateData, + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(TableName), string.Join(", ", updateItems.ToArray()), string.Join(" AND ", whereClauses.ToArray())); } diff --git a/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs b/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs index ff0b158aeb..bebbb43013 100644 --- a/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs +++ b/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs @@ -33,10 +33,10 @@ namespace Umbraco.Core.Persistence var tableDefinition = DefinitionFactory.GetTableDefinition(modelType); var tableName = tableDefinition.Name; - string createSql = SyntaxConfig.SqlSyntaxProvider.Format(tableDefinition); - string createPrimaryKeySql = SyntaxConfig.SqlSyntaxProvider.FormatPrimaryKey(tableDefinition); - var foreignSql = SyntaxConfig.SqlSyntaxProvider.Format(tableDefinition.ForeignKeys); - var indexSql = SyntaxConfig.SqlSyntaxProvider.Format(tableDefinition.Indexes); + string createSql = SqlSyntaxContext.SqlSyntaxProvider.Format(tableDefinition); + string createPrimaryKeySql = SqlSyntaxContext.SqlSyntaxProvider.FormatPrimaryKey(tableDefinition); + var foreignSql = SqlSyntaxContext.SqlSyntaxProvider.Format(tableDefinition.ForeignKeys); + var indexSql = SqlSyntaxContext.SqlSyntaxProvider.Format(tableDefinition.Indexes); var tableExist = db.TableExist(tableName); if (overwrite && tableExist) @@ -65,18 +65,18 @@ namespace Umbraco.Core.Persistence var e = new TableCreationEventArgs(); //Turn on identity insert if db provider is not mysql - if (SyntaxConfig.SqlSyntaxProvider.SupportsIdentityInsert() && tableDefinition.Columns.Any(x => x.IsIdentity)) - db.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} ON ", SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName)))); + if (SqlSyntaxContext.SqlSyntaxProvider.SupportsIdentityInsert() && tableDefinition.Columns.Any(x => x.IsIdentity)) + db.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} ON ", SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName)))); //Call the NewTable-event to trigger the insert of base/default data NewTable(tableName, db, e); //Turn off identity insert if db provider is not mysql - if (SyntaxConfig.SqlSyntaxProvider.SupportsIdentityInsert() && tableDefinition.Columns.Any(x => x.IsIdentity)) - db.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} OFF;", SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName)))); + if (SqlSyntaxContext.SqlSyntaxProvider.SupportsIdentityInsert() && tableDefinition.Columns.Any(x => x.IsIdentity)) + db.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} OFF;", SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName)))); //Special case for MySql - if (SyntaxConfig.SqlSyntaxProvider is MySqlSyntaxProvider && tableName.Equals("umbracoUser")) + if (SqlSyntaxContext.SqlSyntaxProvider is MySqlSyntaxProvider && tableName.Equals("umbracoUser")) { db.Update("SET id = @IdAfter WHERE id = @IdBefore AND userLogin = @Login", new { IdAfter = 0, IdBefore = 1, Login = "admin" }); } @@ -120,18 +120,18 @@ namespace Umbraco.Core.Persistence public static void DropTable(this Database db, string tableName) { - var sql = new Sql(string.Format("DROP TABLE {0}", SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName))); + var sql = new Sql(string.Format("DROP TABLE {0}", SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName))); db.Execute(sql); } public static bool TableExist(this Database db, string tableName) { - return SyntaxConfig.SqlSyntaxProvider.DoesTableExist(db, tableName); + return SqlSyntaxContext.SqlSyntaxProvider.DoesTableExist(db, tableName); } public static bool TableExist(this UmbracoDatabase db, string tableName) { - return SyntaxConfig.SqlSyntaxProvider.DoesTableExist(db, tableName); + return SqlSyntaxContext.SqlSyntaxProvider.DoesTableExist(db, tableName); } public static void CreateDatabaseSchema(this Database db) diff --git a/src/Umbraco.Core/Persistence/PetaPocoSqlExtensions.cs b/src/Umbraco.Core/Persistence/PetaPocoSqlExtensions.cs index eabae317fc..378ade59dd 100644 --- a/src/Umbraco.Core/Persistence/PetaPocoSqlExtensions.cs +++ b/src/Umbraco.Core/Persistence/PetaPocoSqlExtensions.cs @@ -17,7 +17,7 @@ namespace Umbraco.Core.Persistence var tableNameAttribute = type.FirstAttribute(); string tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value; - return sql.From(SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName)); + return sql.From(SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName)); } public static Sql Where(this Sql sql, Expression> predicate) @@ -38,8 +38,8 @@ namespace Umbraco.Core.Persistence string tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value; var syntax = string.Format("{0}.{1}", - SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName), - SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(columnName)); + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName), + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(columnName)); return sql.OrderBy(syntax); } @@ -54,8 +54,8 @@ namespace Umbraco.Core.Persistence string tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value; var syntax = string.Format("{0}.{1} DESC", - SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName), - SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(columnName)); + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName), + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(columnName)); return sql.OrderBy(syntax); } @@ -65,7 +65,7 @@ namespace Umbraco.Core.Persistence var column = ExpressionHelper.FindProperty(columnMember) as PropertyInfo; var columnName = column.FirstAttribute().Name; - return sql.GroupBy(SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(columnName)); + return sql.GroupBy(SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(columnName)); } public static Sql.SqlJoinClause InnerJoin(this Sql sql) @@ -74,7 +74,7 @@ namespace Umbraco.Core.Persistence var tableNameAttribute = type.FirstAttribute(); string tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value; - return sql.InnerJoin(SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName)); + return sql.InnerJoin(SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName)); } public static Sql.SqlJoinClause LeftJoin(this Sql sql) @@ -83,7 +83,7 @@ namespace Umbraco.Core.Persistence var tableNameAttribute = type.FirstAttribute(); string tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value; - return sql.LeftJoin(SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName)); + return sql.LeftJoin(SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName)); } public static Sql.SqlJoinClause LeftOuterJoin(this Sql sql) @@ -92,7 +92,7 @@ namespace Umbraco.Core.Persistence var tableNameAttribute = type.FirstAttribute(); string tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value; - return sql.LeftOuterJoin(SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName)); + return sql.LeftOuterJoin(SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName)); } public static Sql.SqlJoinClause RightJoin(this Sql sql) @@ -101,7 +101,7 @@ namespace Umbraco.Core.Persistence var tableNameAttribute = type.FirstAttribute(); string tableName = tableNameAttribute == null ? string.Empty : tableNameAttribute.Value; - return sql.RightJoin(SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName)); + return sql.RightJoin(SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(tableName)); } public static Sql On(this Sql.SqlJoinClause sql, Expression> leftMember, @@ -118,10 +118,10 @@ namespace Umbraco.Core.Persistence var rightColumnName = right.FirstAttribute().Name; string onClause = string.Format("{0}.{1} = {2}.{3}", - SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(leftTableName), - SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(leftColumnName), - SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(rightTableName), - SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(rightColumnName)); + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(leftTableName), + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(leftColumnName), + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(rightTableName), + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(rightColumnName)); return sql.On(onClause); } } diff --git a/src/Umbraco.Core/Persistence/Querying/PocoToSqlExpressionHelper.cs b/src/Umbraco.Core/Persistence/Querying/PocoToSqlExpressionHelper.cs index 39b0239844..dc5b608e25 100644 --- a/src/Umbraco.Core/Persistence/Querying/PocoToSqlExpressionHelper.cs +++ b/src/Umbraco.Core/Persistence/Querying/PocoToSqlExpressionHelper.cs @@ -487,8 +487,8 @@ namespace Umbraco.Core.Persistence.Querying { var column = pocoData.Columns.FirstOrDefault(x => x.Value.PropertyInfo.Name == name); return string.Format("{0}.{1}", - SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(pocoData.TableInfo.TableName), - SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(column.Value.ColumnName)); + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedTableName(pocoData.TableInfo.TableName), + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(column.Value.ColumnName)); } protected string RemoveQuote(string exp) diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/DbTypes.cs b/src/Umbraco.Core/Persistence/SqlSyntax/DbTypes.cs index 18f8c71493..507db230cc 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/DbTypes.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/DbTypes.cs @@ -4,7 +4,7 @@ using System.Data; namespace Umbraco.Core.Persistence.SqlSyntax { - internal class DbTypes + public class DbTypes where TSyntax : ISqlSyntaxProvider { public DbType DbType; diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs index ef825ca4cc..389650d606 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs @@ -7,21 +7,20 @@ using Umbraco.Core.Persistence.DatabaseModelDefinitions; namespace Umbraco.Core.Persistence.SqlSyntax { /// - /// Static class that provides simple access to the MySql SqlSyntax Providers singleton + /// Static class that provides simple access to the MySql SqlSyntax Provider /// internal static class MySqlSyntax { - public static ISqlSyntaxProvider Provider { get { return MySqlSyntaxProvider.Instance; } } + public static ISqlSyntaxProvider Provider { get { return new MySqlSyntaxProvider(); } } } /// /// Represents an SqlSyntaxProvider for MySql /// - internal class MySqlSyntaxProvider : SqlSyntaxProviderBase + [SqlSyntaxProviderAttribute("MySql.Data.MySqlClient")] + public class MySqlSyntaxProvider : SqlSyntaxProviderBase { - public static MySqlSyntaxProvider Instance = new MySqlSyntaxProvider(); - - private MySqlSyntaxProvider() + public MySqlSyntaxProvider() { DefaultStringLength = 255; StringLengthColumnDefinitionFormat = StringLengthUnicodeColumnDefinitionFormat; diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs index 06d37c9df0..703019412c 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs @@ -1,28 +1,26 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.DatabaseModelDefinitions; namespace Umbraco.Core.Persistence.SqlSyntax { /// - /// Static class that provides simple access to the Sql CE SqlSyntax Providers singleton + /// Static class that provides simple access to the Sql CE SqlSyntax Provider /// internal static class SqlCeSyntax { - public static ISqlSyntaxProvider Provider { get { return SqlCeSyntaxProvider.Instance; } } + public static ISqlSyntaxProvider Provider { get { return new SqlCeSyntaxProvider(); } } } /// /// Represents an SqlSyntaxProvider for Sql Ce /// - internal class SqlCeSyntaxProvider : SqlSyntaxProviderBase + [SqlSyntaxProviderAttribute("System.Data.SqlServerCe.4.0")] + public class SqlCeSyntaxProvider : SqlSyntaxProviderBase { - public static SqlCeSyntaxProvider Instance = new SqlCeSyntaxProvider(); - - private SqlCeSyntaxProvider() + public SqlCeSyntaxProvider() { StringLengthColumnDefinitionFormat = StringLengthUnicodeColumnDefinitionFormat; StringColumnDefinition = string.Format(StringLengthColumnDefinitionFormat, DefaultStringLength); diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs index 7167026d9a..2de2209ab4 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs @@ -6,21 +6,20 @@ using Umbraco.Core.Persistence.DatabaseModelDefinitions; namespace Umbraco.Core.Persistence.SqlSyntax { /// - /// Static class that provides simple access to the Sql Server SqlSyntax Providers singleton + /// Static class that provides simple access to the Sql Server SqlSyntax Provider /// internal static class SqlServerSyntax { - public static ISqlSyntaxProvider Provider { get { return SqlServerSyntaxProvider.Instance; } } + public static ISqlSyntaxProvider Provider { get { return new SqlServerSyntaxProvider(); } } } /// /// Represents an SqlSyntaxProvider for Sql Server /// - internal class SqlServerSyntaxProvider : SqlSyntaxProviderBase + [SqlSyntaxProviderAttribute("System.Data.SqlClient")] + public class SqlServerSyntaxProvider : SqlSyntaxProviderBase { - public static SqlServerSyntaxProvider Instance = new SqlServerSyntaxProvider(); - - private SqlServerSyntaxProvider() + public SqlServerSyntaxProvider() { StringLengthColumnDefinitionFormat = StringLengthUnicodeColumnDefinitionFormat; StringColumnDefinition = string.Format(StringLengthColumnDefinitionFormat, DefaultStringLength); diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SyntaxConfig.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxContext.cs similarity index 72% rename from src/Umbraco.Core/Persistence/SqlSyntax/SyntaxConfig.cs rename to src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxContext.cs index eafeb46f83..9fe69a4ca9 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/SyntaxConfig.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxContext.cs @@ -3,9 +3,9 @@ namespace Umbraco.Core.Persistence.SqlSyntax { /// - /// Singleton to handle the configuration of an SqlSyntaxProvider + /// Singleton to handle the configuration of a SqlSyntaxProvider /// - internal static class SyntaxConfig + public static class SqlSyntaxContext { private static ISqlSyntaxProvider _sqlSyntaxProvider; @@ -16,7 +16,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax if(_sqlSyntaxProvider == null) { throw new ArgumentNullException("SqlSyntaxProvider", - "You must set the singleton 'Umbraco.Core.Persistence.SqlSyntax.SyntaxConfig' to use an sql syntax provider"); + "You must set the singleton 'Umbraco.Core.Persistence.SqlSyntax.SqlSyntaxContext' to use an sql syntax provider"); } return _sqlSyntaxProvider; } diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderAttribute.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderAttribute.cs new file mode 100644 index 0000000000..a4b40ba78c --- /dev/null +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderAttribute.cs @@ -0,0 +1,21 @@ +using System; + +namespace Umbraco.Core.Persistence.SqlSyntax +{ + /// + /// Attribute for implementations of an ISqlSyntaxProvider + /// + [AttributeUsage(AttributeTargets.Class)] + public class SqlSyntaxProviderAttribute : Attribute + { + public SqlSyntaxProviderAttribute(string providerName) + { + ProviderName = providerName; + } + + /// + /// Gets or sets the ProviderName that corresponds to the sql syntax in a provider. + /// + public string ProviderName { get; set; } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs index 70aa97d949..cbdc4804b4 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs @@ -15,7 +15,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax /// All Sql Syntax provider implementations should derive from this abstract class. /// /// - internal abstract class SqlSyntaxProviderBase : ISqlSyntaxProvider + public abstract class SqlSyntaxProviderBase : ISqlSyntaxProvider where TSyntax : ISqlSyntaxProvider { protected SqlSyntaxProviderBase() diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProvidersResolver.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProvidersResolver.cs new file mode 100644 index 0000000000..8db914801d --- /dev/null +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProvidersResolver.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Umbraco.Core.ObjectResolution; + +namespace Umbraco.Core.Persistence.SqlSyntax +{ + /// + /// A resolver to return all ISqlSyntaxProvider objects + /// + internal sealed class SqlSyntaxProvidersResolver : ManyObjectsResolverBase + { + /// + /// Constructor + /// + /// + internal SqlSyntaxProvidersResolver(IEnumerable syntaxProviders) + : base(syntaxProviders) + { + + } + + /// + /// Gets the implementations. + /// + public IEnumerable SqlSyntaxProviders + { + get + { + return Values; + } + } + + /// + /// Gets a by its attributed provider. + /// + /// ProviderName from the ConnectionString settings + /// that corresponds to the attributed provider or the default Sql Server Syntax Provider. + public ISqlSyntaxProvider GetByProviderNameOrDefault(string providerName) + { + var provider = + Values.FirstOrDefault( + x => + x.GetType() + .FirstAttribute() + .ProviderName.ToLowerInvariant() + .Equals(providerName.ToLowerInvariant())); + + if (provider != null) + return provider; + + return Values.First(x => x.GetType() == typeof (SqlServerSyntaxProvider)); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/PluginManager.cs b/src/Umbraco.Core/PluginManager.cs index f0514af628..f8d8ba79a0 100644 --- a/src/Umbraco.Core/PluginManager.cs +++ b/src/Umbraco.Core/PluginManager.cs @@ -12,6 +12,7 @@ using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Migrations; +using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Core.PropertyEditors; using umbraco.interfaces; using File = System.IO.File; @@ -477,6 +478,15 @@ namespace Umbraco.Core return ResolveTypes(); } + /// + /// Returns all SqlSyntaxProviders with the SqlSyntaxProviderAttribute + /// + /// + internal IEnumerable ResolveSqlSyntaxProviders() + { + return ResolveTypesWithAttribute(); + } + /// /// Gets/sets which assemblies to scan when type finding, generally used for unit testing, if not explicitly set /// this will search all assemblies known to have plugins and exclude ones known to not have them. diff --git a/src/Umbraco.Core/TypeFinder.cs b/src/Umbraco.Core/TypeFinder.cs index e25b092e11..6b7627e257 100644 --- a/src/Umbraco.Core/TypeFinder.cs +++ b/src/Umbraco.Core/TypeFinder.cs @@ -232,7 +232,6 @@ namespace Umbraco.Core "NuGet.", "RouteDebugger,", "SqlCE4Umbraco,", - "Umbraco.Core,", "umbraco.datalayer,", "umbraco.interfaces,", "umbraco.providers,", diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 68c718fd71..99f3caa9c8 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -451,8 +451,10 @@ + - + + diff --git a/src/Umbraco.Tests/BootManagers/CoreBootManagerTests.cs b/src/Umbraco.Tests/BootManagers/CoreBootManagerTests.cs index 0227e68908..dc9ed68b85 100644 --- a/src/Umbraco.Tests/BootManagers/CoreBootManagerTests.cs +++ b/src/Umbraco.Tests/BootManagers/CoreBootManagerTests.cs @@ -6,6 +6,7 @@ using System.Web; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.ObjectResolution; +using Umbraco.Core.Persistence.SqlSyntax; using umbraco.interfaces; namespace Umbraco.Tests.BootManagers @@ -27,6 +28,7 @@ namespace Umbraco.Tests.BootManagers { _testApp = null; ApplicationEventsResolver.Reset(); + SqlSyntaxProvidersResolver.Reset(); Resolution.IsFrozen = false; } @@ -67,6 +69,12 @@ namespace Umbraco.Tests.BootManagers protected override void InitializeResolvers() { //Do nothing as we don't want to initialize all resolvers in this test + //We only include this resolver to not cause trouble for the database context + SqlSyntaxProvidersResolver.Current = new SqlSyntaxProvidersResolver( + PluginManager.Current.ResolveSqlSyntaxProviders()) + { + CanResolveBeforeFrozen = true + }; } } diff --git a/src/Umbraco.Tests/Migrations/AlterMigrationTests.cs b/src/Umbraco.Tests/Migrations/AlterMigrationTests.cs index a752e94662..657a924f9f 100644 --- a/src/Umbraco.Tests/Migrations/AlterMigrationTests.cs +++ b/src/Umbraco.Tests/Migrations/AlterMigrationTests.cs @@ -14,7 +14,7 @@ namespace Umbraco.Tests.Migrations [SetUp] public void SetUp() { - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; } [Test] diff --git a/src/Umbraco.Tests/Migrations/FindingMigrationsTest.cs b/src/Umbraco.Tests/Migrations/FindingMigrationsTest.cs index 7601aa2f59..b266c7cd49 100644 --- a/src/Umbraco.Tests/Migrations/FindingMigrationsTest.cs +++ b/src/Umbraco.Tests/Migrations/FindingMigrationsTest.cs @@ -32,7 +32,7 @@ namespace Umbraco.Tests.Migrations Resolution.Freeze(); - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; } [Test] diff --git a/src/Umbraco.Tests/Migrations/TargetVersionSixthMigrationsTest.cs b/src/Umbraco.Tests/Migrations/TargetVersionSixthMigrationsTest.cs index beb1d2058d..2f27e1ffb0 100644 --- a/src/Umbraco.Tests/Migrations/TargetVersionSixthMigrationsTest.cs +++ b/src/Umbraco.Tests/Migrations/TargetVersionSixthMigrationsTest.cs @@ -39,7 +39,7 @@ namespace Umbraco.Tests.Migrations Resolution.Freeze(); - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; } [Test] diff --git a/src/Umbraco.Tests/Migrations/Upgrades/BaseUpgradeTest.cs b/src/Umbraco.Tests/Migrations/Upgrades/BaseUpgradeTest.cs index b0ce8042b7..c995895c75 100644 --- a/src/Umbraco.Tests/Migrations/Upgrades/BaseUpgradeTest.cs +++ b/src/Umbraco.Tests/Migrations/Upgrades/BaseUpgradeTest.cs @@ -49,7 +49,7 @@ namespace Umbraco.Tests.Migrations.Upgrades DatabaseSpecificSetUp(); - SyntaxConfig.SqlSyntaxProvider = GetSyntaxProvider(); + SqlSyntaxContext.SqlSyntaxProvider = GetSyntaxProvider(); } [Test] @@ -91,7 +91,7 @@ namespace Umbraco.Tests.Migrations.Upgrades public virtual void TearDown() { PluginManager.Current = null; - SyntaxConfig.SqlSyntaxProvider = null; + SqlSyntaxContext.SqlSyntaxProvider = null; MigrationResolver.Reset(); Resolution.IsFrozen = false; diff --git a/src/Umbraco.Tests/Migrations/Upgrades/ValidateOlderSchemaTest.cs b/src/Umbraco.Tests/Migrations/Upgrades/ValidateOlderSchemaTest.cs index 0f531c7720..14958e4565 100644 --- a/src/Umbraco.Tests/Migrations/Upgrades/ValidateOlderSchemaTest.cs +++ b/src/Umbraco.Tests/Migrations/Upgrades/ValidateOlderSchemaTest.cs @@ -72,13 +72,13 @@ namespace Umbraco.Tests.Migrations.Upgrades var engine = new SqlCeEngine(settings.ConnectionString); engine.CreateDatabase(); - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; } [TearDown] public virtual void TearDown() { - SyntaxConfig.SqlSyntaxProvider = null; + SqlSyntaxContext.SqlSyntaxProvider = null; Resolution.IsFrozen = false; TestHelper.CleanContentDirectories(); diff --git a/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs b/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs index b5fc8bcc4b..a20943a645 100644 --- a/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs +++ b/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs @@ -75,7 +75,7 @@ namespace Umbraco.Tests.Persistence var engine = new SqlCeEngine(settings.ConnectionString); engine.CreateDatabase(); - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntaxProvider.Instance; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; //Create the umbraco database _dbContext.Database.CreateDatabaseSchema(false); diff --git a/src/Umbraco.Tests/Persistence/Mappers/ContentMapperTest.cs b/src/Umbraco.Tests/Persistence/Mappers/ContentMapperTest.cs index 83dced8d28..7663ad8a55 100644 --- a/src/Umbraco.Tests/Persistence/Mappers/ContentMapperTest.cs +++ b/src/Umbraco.Tests/Persistence/Mappers/ContentMapperTest.cs @@ -11,7 +11,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Id_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = ContentMapper.Instance.Map("Id"); @@ -24,7 +24,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Trashed_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = ContentMapper.Instance.Map("Trashed"); @@ -37,7 +37,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Published_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = ContentMapper.Instance.Map("Published"); @@ -50,7 +50,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Version_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = ContentMapper.Instance.Map("Version"); diff --git a/src/Umbraco.Tests/Persistence/Mappers/ContentTypeMapperTest.cs b/src/Umbraco.Tests/Persistence/Mappers/ContentTypeMapperTest.cs index 47b201d750..153896b265 100644 --- a/src/Umbraco.Tests/Persistence/Mappers/ContentTypeMapperTest.cs +++ b/src/Umbraco.Tests/Persistence/Mappers/ContentTypeMapperTest.cs @@ -11,7 +11,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Id_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = ContentTypeMapper.Instance.Map("Id"); @@ -24,7 +24,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Name_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = ContentTypeMapper.Instance.Map("Name"); @@ -37,7 +37,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Thumbnail_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = ContentTypeMapper.Instance.Map("Thumbnail"); @@ -50,7 +50,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Description_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = ContentTypeMapper.Instance.Map("Description"); diff --git a/src/Umbraco.Tests/Persistence/Mappers/DataTypeDefinitionMapperTest.cs b/src/Umbraco.Tests/Persistence/Mappers/DataTypeDefinitionMapperTest.cs index dfaa1ccd09..7db9f8e9da 100644 --- a/src/Umbraco.Tests/Persistence/Mappers/DataTypeDefinitionMapperTest.cs +++ b/src/Umbraco.Tests/Persistence/Mappers/DataTypeDefinitionMapperTest.cs @@ -11,7 +11,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Id_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = DataTypeDefinitionMapper.Instance.Map("Id"); @@ -24,7 +24,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Key_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = DataTypeDefinitionMapper.Instance.Map("Key"); @@ -37,7 +37,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_DatabaseType_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = DataTypeDefinitionMapper.Instance.Map("DatabaseType"); @@ -50,7 +50,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_ControlId_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = DataTypeDefinitionMapper.Instance.Map("ControlId"); diff --git a/src/Umbraco.Tests/Persistence/Mappers/DictionaryMapperTest.cs b/src/Umbraco.Tests/Persistence/Mappers/DictionaryMapperTest.cs index 02c19f47f5..4f3e8faa07 100644 --- a/src/Umbraco.Tests/Persistence/Mappers/DictionaryMapperTest.cs +++ b/src/Umbraco.Tests/Persistence/Mappers/DictionaryMapperTest.cs @@ -11,7 +11,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Id_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = DictionaryMapper.Instance.Map("Id"); @@ -24,7 +24,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Key_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = DictionaryMapper.Instance.Map("Key"); @@ -37,7 +37,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_ItemKey_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = DictionaryMapper.Instance.Map("ItemKey"); diff --git a/src/Umbraco.Tests/Persistence/Mappers/DictionaryTranslationMapperTest.cs b/src/Umbraco.Tests/Persistence/Mappers/DictionaryTranslationMapperTest.cs index bfec65989d..b9d4cd2e7e 100644 --- a/src/Umbraco.Tests/Persistence/Mappers/DictionaryTranslationMapperTest.cs +++ b/src/Umbraco.Tests/Persistence/Mappers/DictionaryTranslationMapperTest.cs @@ -11,7 +11,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Key_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = DictionaryTranslationMapper.Instance.Map("Key"); @@ -24,7 +24,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Language_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = DictionaryTranslationMapper.Instance.Map("Language"); @@ -37,7 +37,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Value_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = DictionaryTranslationMapper.Instance.Map("Value"); diff --git a/src/Umbraco.Tests/Persistence/Mappers/LanguageMapperTest.cs b/src/Umbraco.Tests/Persistence/Mappers/LanguageMapperTest.cs index 0e98405bb2..0cfd8be715 100644 --- a/src/Umbraco.Tests/Persistence/Mappers/LanguageMapperTest.cs +++ b/src/Umbraco.Tests/Persistence/Mappers/LanguageMapperTest.cs @@ -11,7 +11,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Id_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = LanguageMapper.Instance.Map("Id"); @@ -24,7 +24,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_IsoCode_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = LanguageMapper.Instance.Map("IsoCode"); @@ -37,7 +37,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_CultureName_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = LanguageMapper.Instance.Map("CultureName"); diff --git a/src/Umbraco.Tests/Persistence/Mappers/MediaMapperTest.cs b/src/Umbraco.Tests/Persistence/Mappers/MediaMapperTest.cs index a7c9682ab9..5e892a0faf 100644 --- a/src/Umbraco.Tests/Persistence/Mappers/MediaMapperTest.cs +++ b/src/Umbraco.Tests/Persistence/Mappers/MediaMapperTest.cs @@ -11,7 +11,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Id_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = MediaMapper.Instance.Map("Id"); @@ -24,7 +24,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Trashed_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = MediaMapper.Instance.Map("Trashed"); @@ -37,7 +37,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_UpdateDate_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = MediaMapper.Instance.Map("UpdateDate"); @@ -50,7 +50,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Version_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = MediaMapper.Instance.Map("Version"); diff --git a/src/Umbraco.Tests/Persistence/Mappers/PropertyGroupMapperTest.cs b/src/Umbraco.Tests/Persistence/Mappers/PropertyGroupMapperTest.cs index 1fad331023..e13e5f70b3 100644 --- a/src/Umbraco.Tests/Persistence/Mappers/PropertyGroupMapperTest.cs +++ b/src/Umbraco.Tests/Persistence/Mappers/PropertyGroupMapperTest.cs @@ -11,7 +11,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Id_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = PropertyGroupMapper.Instance.Map("Id"); @@ -24,7 +24,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_ParentId_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = PropertyGroupMapper.Instance.Map("ParentId"); @@ -37,7 +37,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_SortOrder_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = PropertyGroupMapper.Instance.Map("SortOrder"); @@ -50,7 +50,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Name_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = PropertyGroupMapper.Instance.Map("Name"); diff --git a/src/Umbraco.Tests/Persistence/Mappers/PropertyTypeMapperTest.cs b/src/Umbraco.Tests/Persistence/Mappers/PropertyTypeMapperTest.cs index f7bfbd71ad..b02fd2f3fb 100644 --- a/src/Umbraco.Tests/Persistence/Mappers/PropertyTypeMapperTest.cs +++ b/src/Umbraco.Tests/Persistence/Mappers/PropertyTypeMapperTest.cs @@ -11,7 +11,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Id_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = PropertyTypeMapper.Instance.Map("Id"); @@ -24,7 +24,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Alias_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = PropertyTypeMapper.Instance.Map("Alias"); @@ -37,7 +37,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_DataTypeDefinitionId_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = PropertyTypeMapper.Instance.Map("DataTypeDefinitionId"); @@ -50,7 +50,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_SortOrder_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = PropertyTypeMapper.Instance.Map("SortOrder"); @@ -63,7 +63,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_DataTypeControlId_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = PropertyTypeMapper.Instance.Map("DataTypeId"); @@ -76,7 +76,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_DataTypeDatabaseType_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = PropertyTypeMapper.Instance.Map("DataTypeDatabaseType"); diff --git a/src/Umbraco.Tests/Persistence/Mappers/RelationMapperTest.cs b/src/Umbraco.Tests/Persistence/Mappers/RelationMapperTest.cs index 179ae7a25d..eb0f070992 100644 --- a/src/Umbraco.Tests/Persistence/Mappers/RelationMapperTest.cs +++ b/src/Umbraco.Tests/Persistence/Mappers/RelationMapperTest.cs @@ -11,7 +11,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Id_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = RelationMapper.Instance.Map("Id"); @@ -24,7 +24,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_ChildId_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = RelationMapper.Instance.Map("ChildId"); @@ -37,7 +37,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Datetime_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = RelationMapper.Instance.Map("CreateDate"); @@ -50,7 +50,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Comment_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = RelationMapper.Instance.Map("Comment"); @@ -63,7 +63,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_RelationType_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = RelationMapper.Instance.Map("RelationTypeId"); diff --git a/src/Umbraco.Tests/Persistence/Mappers/RelationTypeMapperTest.cs b/src/Umbraco.Tests/Persistence/Mappers/RelationTypeMapperTest.cs index 2fde906148..dae666b036 100644 --- a/src/Umbraco.Tests/Persistence/Mappers/RelationTypeMapperTest.cs +++ b/src/Umbraco.Tests/Persistence/Mappers/RelationTypeMapperTest.cs @@ -11,7 +11,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Id_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = RelationTypeMapper.Instance.Map("Id"); @@ -24,7 +24,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_Alias_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = RelationTypeMapper.Instance.Map("Alias"); @@ -37,7 +37,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_ChildObjectType_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = RelationTypeMapper.Instance.Map("ChildObjectType"); @@ -50,7 +50,7 @@ namespace Umbraco.Tests.Persistence.Mappers public void Can_Map_IsBidirectional_Property() { // Arrange - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; // Act string column = RelationTypeMapper.Instance.Map("IsBidirectional"); diff --git a/src/Umbraco.Tests/Persistence/MySqlDatabaseCreationTest.cs b/src/Umbraco.Tests/Persistence/MySqlDatabaseCreationTest.cs index 9a10c262fa..0895d1722b 100644 --- a/src/Umbraco.Tests/Persistence/MySqlDatabaseCreationTest.cs +++ b/src/Umbraco.Tests/Persistence/MySqlDatabaseCreationTest.cs @@ -22,7 +22,7 @@ namespace Umbraco.Tests.Persistence public override ISqlSyntaxProvider SyntaxProvider { - get { return MySqlSyntaxProvider.Instance; } + get { return MySqlSyntax.Provider; } } #endregion diff --git a/src/Umbraco.Tests/Persistence/MySqlTableByTableTest.cs b/src/Umbraco.Tests/Persistence/MySqlTableByTableTest.cs index dafee93703..3073f67d88 100644 --- a/src/Umbraco.Tests/Persistence/MySqlTableByTableTest.cs +++ b/src/Umbraco.Tests/Persistence/MySqlTableByTableTest.cs @@ -38,7 +38,7 @@ namespace Umbraco.Tests.Persistence //assign the service context new ServiceContext(new PetaPocoUnitOfWorkProvider(), new FileUnitOfWorkProvider(), new PublishingStrategy())) { IsReady = true }; - SyntaxConfig.SqlSyntaxProvider = MySqlSyntaxProvider.Instance; + SqlSyntaxContext.SqlSyntaxProvider = MySqlSyntax.Provider; _database = new Database("Server = 169.254.120.3; Database = testdb; Uid = umbraco; Pwd = umbraco", "MySql.Data.MySqlClient"); diff --git a/src/Umbraco.Tests/Persistence/SqlCeTableByTableTest.cs b/src/Umbraco.Tests/Persistence/SqlCeTableByTableTest.cs index 5c562b5815..3720e8bd99 100644 --- a/src/Umbraco.Tests/Persistence/SqlCeTableByTableTest.cs +++ b/src/Umbraco.Tests/Persistence/SqlCeTableByTableTest.cs @@ -51,7 +51,7 @@ namespace Umbraco.Tests.Persistence //assign the service context new ServiceContext(new PetaPocoUnitOfWorkProvider(), new FileUnitOfWorkProvider(), new PublishingStrategy())) { IsReady = true }; - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntax.Provider; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; _database = new Database("Datasource=|DataDirectory|test.sdf", "System.Data.SqlServerCe.4.0"); @@ -62,7 +62,7 @@ namespace Umbraco.Tests.Persistence { AppDomain.CurrentDomain.SetData("DataDirectory", null); - SyntaxConfig.SqlSyntaxProvider = null; + SqlSyntaxContext.SqlSyntaxProvider = null; //reset the app context ApplicationContext.Current = null; diff --git a/src/Umbraco.Tests/Persistence/SqlTableByTableTest.cs b/src/Umbraco.Tests/Persistence/SqlTableByTableTest.cs index 711ec7b808..45390f6ff4 100644 --- a/src/Umbraco.Tests/Persistence/SqlTableByTableTest.cs +++ b/src/Umbraco.Tests/Persistence/SqlTableByTableTest.cs @@ -38,7 +38,7 @@ namespace Umbraco.Tests.Persistence //assign the service context new ServiceContext(new PetaPocoUnitOfWorkProvider(), new FileUnitOfWorkProvider(), new PublishingStrategy())) { IsReady = true }; - SyntaxConfig.SqlSyntaxProvider = SqlServerSyntaxProvider.Instance; + SqlSyntaxContext.SqlSyntaxProvider = SqlServerSyntax.Provider; _database = new Database(@"server=.\SQLEXPRESS;database=EmptyForTest;user id=umbraco;password=umbraco", "System.Data.SqlClient"); @@ -49,7 +49,7 @@ namespace Umbraco.Tests.Persistence { AppDomain.CurrentDomain.SetData("DataDirectory", null); - SyntaxConfig.SqlSyntaxProvider = null; + SqlSyntaxContext.SqlSyntaxProvider = null; //reset the app context ApplicationContext.Current = null; diff --git a/src/Umbraco.Tests/Persistence/SyntaxProvider/SqlSyntaxProviderTests.cs b/src/Umbraco.Tests/Persistence/SyntaxProvider/SqlSyntaxProviderTests.cs index ce6a735d2a..3909a17847 100644 --- a/src/Umbraco.Tests/Persistence/SyntaxProvider/SqlSyntaxProviderTests.cs +++ b/src/Umbraco.Tests/Persistence/SyntaxProvider/SqlSyntaxProviderTests.cs @@ -12,7 +12,7 @@ namespace Umbraco.Tests.Persistence.SyntaxProvider [SetUp] public void SetUp() { - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntaxProvider.Instance; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; } [Test] @@ -21,10 +21,10 @@ namespace Umbraco.Tests.Persistence.SyntaxProvider var type = typeof (NodeDto); var definition = DefinitionFactory.GetTableDefinition(type); - string create = SyntaxConfig.SqlSyntaxProvider.Format(definition); - string primaryKey = SyntaxConfig.SqlSyntaxProvider.FormatPrimaryKey(definition); - var indexes = SyntaxConfig.SqlSyntaxProvider.Format(definition.Indexes); - var keys = SyntaxConfig.SqlSyntaxProvider.Format(definition.ForeignKeys); + string create = SqlSyntaxContext.SqlSyntaxProvider.Format(definition); + string primaryKey = SqlSyntaxContext.SqlSyntaxProvider.FormatPrimaryKey(definition); + var indexes = SqlSyntaxContext.SqlSyntaxProvider.Format(definition.Indexes); + var keys = SqlSyntaxContext.SqlSyntaxProvider.Format(definition.ForeignKeys); Console.WriteLine(create); Console.WriteLine(primaryKey); @@ -42,7 +42,7 @@ namespace Umbraco.Tests.Persistence.SyntaxProvider [TearDown] public void TearDown() { - SyntaxConfig.SqlSyntaxProvider = null; + SqlSyntaxContext.SqlSyntaxProvider = null; } } } \ No newline at end of file diff --git a/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs b/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs index f9637050c3..34767c8e48 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.ComponentModel; using System.Configuration; using System.Data.SqlServerCe; using System.IO; @@ -64,6 +66,9 @@ namespace Umbraco.Tests.TestHelpers RepositoryResolver.Current = new RepositoryResolver( new RepositoryFactory()); + SqlSyntaxProvidersResolver.Current = new SqlSyntaxProvidersResolver( + new List{ typeof(MySqlSyntaxProvider), typeof(SqlCeSyntaxProvider), typeof(SqlServerSyntaxProvider) }) { CanResolveBeforeFrozen = true}; + //Get the connectionstring settings from config var settings = ConfigurationManager.ConnectionStrings[Core.Configuration.GlobalSettings.UmbracoConnectionName]; ConfigurationManager.AppSettings.Set(Core.Configuration.GlobalSettings.UmbracoConnectionName, @"datalayer=SQLCE4Umbraco.SqlCEHelper,SQLCE4Umbraco;data source=|DataDirectory|\UmbracoPetaPocoTests.sdf"); @@ -100,14 +105,15 @@ namespace Umbraco.Tests.TestHelpers //reset the app context ApplicationContext.ApplicationCache.ClearAllCache(); - SyntaxConfig.SqlSyntaxProvider = null; - + SqlSyntaxContext.SqlSyntaxProvider = null; + //legacy API database connection close - because a unit test using PetaPoco db-layer can trigger the usage of SqlHelper we need to ensure that a possible connection is closed. SqlCeContextGuardian.CloseBackgroundConnection(); ApplicationContext.Current = null; Resolution.IsFrozen = false; RepositoryResolver.Reset(); + SqlSyntaxProvidersResolver.Reset(); TestHelper.CleanContentDirectories(); diff --git a/src/Umbraco.Tests/TestHelpers/BaseDatabaseTest.cs b/src/Umbraco.Tests/TestHelpers/BaseDatabaseTest.cs index beab2c6d2a..326705b45f 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseDatabaseTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseDatabaseTest.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Data.SqlServerCe; using System.IO; using NUnit.Framework; @@ -53,6 +54,9 @@ namespace Umbraco.Tests.TestHelpers RepositoryResolver.Current = new RepositoryResolver( new RepositoryFactory()); + SqlSyntaxProvidersResolver.Current = new SqlSyntaxProvidersResolver( + new List { typeof(MySqlSyntaxProvider), typeof(SqlCeSyntaxProvider), typeof(SqlServerSyntaxProvider) }) { CanResolveBeforeFrozen = true }; + Resolution.Freeze(); ApplicationContext.Current = new ApplicationContext( //assign the db context @@ -60,7 +64,7 @@ namespace Umbraco.Tests.TestHelpers //assign the service context new ServiceContext(new PetaPocoUnitOfWorkProvider(), new FileUnitOfWorkProvider(), new PublishingStrategy())) { IsReady = true }; - SyntaxConfig.SqlSyntaxProvider = SyntaxProvider; + SqlSyntaxContext.SqlSyntaxProvider = SyntaxProvider; //Create the umbraco database _database = new Database(ConnectionString, ProviderName); diff --git a/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs b/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs index d7424c311d..7d2e2c55f9 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs @@ -9,7 +9,7 @@ namespace Umbraco.Tests.TestHelpers [SetUp] public virtual void Initialize() { - SyntaxConfig.SqlSyntaxProvider = SqlCeSyntaxProvider.Instance; + SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; SetUp(); } @@ -20,7 +20,7 @@ namespace Umbraco.Tests.TestHelpers [TearDown] public virtual void TearDown() { - SyntaxConfig.SqlSyntaxProvider = null; + SqlSyntaxContext.SqlSyntaxProvider = null; } } } \ No newline at end of file diff --git a/src/Umbraco.Web.UI/config/ClientDependency.config b/src/Umbraco.Web.UI/config/ClientDependency.config index 66aae40a0b..ae566d63db 100644 --- a/src/Umbraco.Web.UI/config/ClientDependency.config +++ b/src/Umbraco.Web.UI/config/ClientDependency.config @@ -10,7 +10,7 @@ NOTES: * Compression/Combination/Minification is not enabled unless debug="false" is specified on the 'compiliation' element in the web.config * A new version will invalidate both client and server cache and create new persisted files --> - + From fd58017e97e948516d9e9b642f1bfce1f8bc382c Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Mon, 11 Mar 2013 18:49:45 +0600 Subject: [PATCH 4/8] imported patches for pull request spudstuff/u4497 --- .../Configuration/UmbracoSettings.cs | 34 +++++ src/Umbraco.Core/MacroErrorBehaviour.cs | 23 +++ src/Umbraco.Core/Umbraco.Core.csproj | 1 + .../config/umbracoSettings.Release.config | 8 ++ .../config/umbracoSettings.config | 7 + src/Umbraco.Web/umbraco.presentation/macro.cs | 136 +++++++++++++----- .../umbraco/templateControls/Macro.cs | 1 + .../RazorCore/RazorMacroEngine.cs | 6 +- src/umbraco.businesslogic/UmbracoSettings.cs | 18 ++- .../businesslogic/events/EventArgs.cs | 34 ++++- 10 files changed, 223 insertions(+), 45 deletions(-) create mode 100644 src/Umbraco.Core/MacroErrorBehaviour.cs diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings.cs b/src/Umbraco.Core/Configuration/UmbracoSettings.cs index c24810c57c..e3c15b1a10 100644 --- a/src/Umbraco.Core/Configuration/UmbracoSettings.cs +++ b/src/Umbraco.Core/Configuration/UmbracoSettings.cs @@ -1215,6 +1215,40 @@ namespace Umbraco.Core.Configuration } } + private static MacroErrorBehaviour? _macroErrorBehaviour; + + /// + /// This configuration setting defines how to handle macro errors: + /// - Inline - Show error within macro as text (default and current Umbraco 'normal' behavior) + /// - Silent - Suppress error and hide macro + /// - Throw - Throw an exception and invoke the global error handler (if one is defined, if not you'll get a YSOD) + /// + /// MacroErrorBehaviour enum defining how to handle macro errors. + public static MacroErrorBehaviour MacroErrorBehaviour + { + get + { + if (_macroErrorBehaviour == null) + { + try + { + var behaviour = MacroErrorBehaviour.Inline; + var value = GetKey("/settings/content/MacroErrors"); + if (value != null) + { + Enum.TryParse(value, true, out behaviour); + } + _macroErrorBehaviour = behaviour; + } + catch (Exception ex) + { + LogHelper.Error("Could not load /settings/content/MacroErrors from umbracosettings.config", ex); + _macroErrorBehaviour = MacroErrorBehaviour.Inline; + } + } + return _macroErrorBehaviour.Value; + } + } /// /// Configuration regarding webservices diff --git a/src/Umbraco.Core/MacroErrorBehaviour.cs b/src/Umbraco.Core/MacroErrorBehaviour.cs new file mode 100644 index 0000000000..50d9faa19c --- /dev/null +++ b/src/Umbraco.Core/MacroErrorBehaviour.cs @@ -0,0 +1,23 @@ +namespace Umbraco.Core +{ + public enum MacroErrorBehaviour + { + /// + /// Default umbraco behavior - show an inline error within the + /// macro but allow the page to continue rendering. + /// + Inline, + + /// + /// Silently eat the error and do not display the offending macro. + /// + Silent, + + /// + /// Throw an exception which can be caught by the global error handler + /// defined in Application_OnError. If no such error handler is defined + /// then you'll see the Yellow Screen Of Death (YSOD) error page. + /// + Throw + } +} diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index f20e9e573a..ab878ff025 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -71,6 +71,7 @@ + diff --git a/src/Umbraco.Web.UI/config/umbracoSettings.Release.config b/src/Umbraco.Web.UI/config/umbracoSettings.Release.config index 5144e8bfac..669f213dc7 100644 --- a/src/Umbraco.Web.UI/config/umbracoSettings.Release.config +++ b/src/Umbraco.Web.UI/config/umbracoSettings.Release.config @@ -86,6 +86,14 @@ false + + + inline diff --git a/src/Umbraco.Web.UI/config/umbracoSettings.config b/src/Umbraco.Web.UI/config/umbracoSettings.config index 1fafe2f61b..62a6e424a6 100644 --- a/src/Umbraco.Web.UI/config/umbracoSettings.config +++ b/src/Umbraco.Web.UI/config/umbracoSettings.config @@ -81,6 +81,13 @@ 1800 + + inline diff --git a/src/Umbraco.Web/umbraco.presentation/macro.cs b/src/Umbraco.Web/umbraco.presentation/macro.cs index 771e1350ca..5c24da5362 100644 --- a/src/Umbraco.Web/umbraco.presentation/macro.cs +++ b/src/Umbraco.Web/umbraco.presentation/macro.cs @@ -18,17 +18,15 @@ using System.Xml.Xsl; using Umbraco.Core; using Umbraco.Core.IO; using Umbraco.Core.Logging; -using Umbraco.Web; using Umbraco.Web.Macros; using Umbraco.Web.Templates; using umbraco.BusinessLogic; -using umbraco.BusinessLogic.Utils; +using umbraco.cms.businesslogic; using umbraco.cms.businesslogic.macro; using umbraco.cms.businesslogic.member; using umbraco.DataLayer; using umbraco.NodeFactory; using umbraco.presentation.templateControls; -using umbraco.presentation.xslt.Exslt; using Content = umbraco.cms.businesslogic.Content; using Macro = umbraco.cms.businesslogic.macro.Macro; @@ -429,8 +427,25 @@ namespace umbraco { renderFailed = true; Exceptions.Add(e); - LogHelper.WarnWithException("Error loading userControl (" + Model.TypeName + ")", true, e); - macroControl = new LiteralControl("Error loading userControl '" + Model.TypeName + "'"); + LogHelper.WarnWithException("Error loading userControl (" + Model.TypeName + ")", true, e); + + // Invoke any error handlers for this macro + var macroErrorEventArgs = new MacroErrorEventArgs {Name = Model.Name, Alias = Model.Alias, File = Model.TypeName, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour}; + OnError(macroErrorEventArgs); + + // Check how to handle the error for this macro. + // (note the error event above may have changed the default behaviour as defined in settings) + switch (macroErrorEventArgs.Behaviour) + { + case MacroErrorBehaviour.Inline: + macroControl = new LiteralControl("Error loading userControl '" + Model.TypeName + "'"); + break; + case MacroErrorBehaviour.Silent: + macroControl = new LiteralControl(""); + break; + case MacroErrorBehaviour.Throw: + throw; + } break; } case (int)MacroTypes.CustomControl: @@ -451,11 +466,24 @@ namespace umbraco LogHelper.WarnWithException("Error loading customControl (Assembly: " + Model.TypeAssembly + ", Type: '" + Model.TypeName + "'", true, e); - - macroControl = - new LiteralControl("Error loading customControl (Assembly: " + Model.TypeAssembly + - ", Type: '" + - Model.TypeName + "'"); + + // Invoke any error handlers for this macro + var macroErrorEventArgs = new MacroErrorEventArgs {Name = Model.Name, Alias = Model.Alias, File = Model.TypeAssembly, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour}; + OnError(macroErrorEventArgs); + + // Check how to handle the error for this macro. + // (note the error event above may have changed the default behaviour as defined in settings) + switch (macroErrorEventArgs.Behaviour) + { + case MacroErrorBehaviour.Inline: + macroControl = new LiteralControl("Error loading customControl (Assembly: " + Model.TypeAssembly + ", Type: '" + Model.TypeName + "'"); + break; + case MacroErrorBehaviour.Silent: + macroControl = new LiteralControl(""); + break; + case MacroErrorBehaviour.Throw: + throw; + } break; } case (int)MacroTypes.XSLT: @@ -487,24 +515,23 @@ namespace umbraco true, e); - var result = - new LiteralControl("Error loading MacroEngine script (file: " + ScriptFile + ")"); - - /* - string args = "
    "; - foreach(object key in attributes.Keys) - args += "
  • " + key.ToString() + ": " + attributes[key] + "
  • "; - - foreach (object key in pageElements.Keys) - args += "
  • " + key.ToString() + ": " + pageElements[key] + "
  • "; - - args += "
"; - - result.Text += args; - */ - - macroControl = result; + // Invoke any error handlers for this macro + var macroErrorEventArgs = new MacroErrorEventArgs {Name = Model.Name, Alias = Model.Alias, File = ScriptFile, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour}; + OnError(macroErrorEventArgs); + // Check how to handle the error for this macro. + // (note the error event above may have changed the default behaviour as defined in settings) + switch (macroErrorEventArgs.Behaviour) + { + case MacroErrorBehaviour.Inline: + macroControl = new LiteralControl("Error loading MacroEngine script (file: " + ScriptFile + ")"); + break; + case MacroErrorBehaviour.Silent: + macroControl = new LiteralControl(""); + break; + case MacroErrorBehaviour.Throw: + throw; + } break; } default: @@ -801,7 +828,26 @@ namespace umbraco { Exceptions.Add(e); LogHelper.WarnWithException("Error loading XSLT " + Model.Xslt, true, e); - return new LiteralControl("Error reading XSLT file: \\xslt\\" + XsltFile); + Control macroControl = null; + + // Invoke any error handlers for this macro + var macroErrorEventArgs = new MacroErrorEventArgs {Name = Model.Name, Alias = Model.Alias, File = Model.Xslt, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour}; + OnError(macroErrorEventArgs); + + // Check how to handle the error for this macro. + // (note the error event above may have changed the default behaviour as defined in settings) + switch (macroErrorEventArgs.Behaviour) + { + case MacroErrorBehaviour.Inline: + macroControl = new LiteralControl("Error reading XSLT file: \\xslt\\" + XsltFile); + break; + case MacroErrorBehaviour.Silent: + macroControl = new LiteralControl(""); + break; + case MacroErrorBehaviour.Throw: + throw; + } + return macroControl; } } } @@ -1505,7 +1551,7 @@ namespace umbraco } if (!File.Exists(IOHelper.MapPath(userControlPath))) - return new LiteralControl(string.Format("UserControl {0} does not exist.", fileName)); + throw new UmbracoException(string.Format("UserControl {0} does not exist.", fileName)); var oControl = (UserControl)new UserControl().LoadControl(userControlPath); @@ -1531,11 +1577,7 @@ namespace umbraco catch (Exception e) { LogHelper.WarnWithException(string.Format("Error creating usercontrol ({0})", fileName), true, e); - - return new LiteralControl( - string.Format( - "
Error creating control ({0}).
Maybe file doesn't exists or the usercontrol has a cache directive, which is not allowed! See the tracestack for more information!
", - fileName)); + throw; } } @@ -1802,5 +1844,31 @@ namespace umbraco value = false; return false; } + + #region Events + + /// + /// The macro error event handler. + /// + public delegate void ErrorEventHandler(object sender, MacroErrorEventArgs e); + + /// + /// Occurs when a macro error is raised. + /// + public static event ErrorEventHandler Error; + + /// + /// Raises the event. + /// + /// The instance containing the event data. + protected virtual void OnError(MacroErrorEventArgs e) + { + if (Error != null) + { + Error(this, e); + } + } + + #endregion } } \ No newline at end of file diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/templateControls/Macro.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/templateControls/Macro.cs index dc94b66cd8..db27764b80 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/templateControls/Macro.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/templateControls/Macro.cs @@ -183,6 +183,7 @@ namespace umbraco.presentation.templateControls System.Web.HttpContext.Current.Trace.Warn("Template", "Result of macro " + tempMacro.Name + " is null"); } catch (Exception ee) { System.Web.HttpContext.Current.Trace.Warn("Template", "Error adding macro " + tempMacro.Name, ee); + throw; } } } diff --git a/src/umbraco.MacroEngines/RazorCore/RazorMacroEngine.cs b/src/umbraco.MacroEngines/RazorCore/RazorMacroEngine.cs index e30d8c5dca..83304f7ab2 100644 --- a/src/umbraco.MacroEngines/RazorCore/RazorMacroEngine.cs +++ b/src/umbraco.MacroEngines/RazorCore/RazorMacroEngine.cs @@ -171,11 +171,7 @@ namespace umbraco.MacroEngines Success = false; ResultException = exception; HttpContext.Current.Trace.Warn("umbracoMacro", string.Format("Error Loading Razor Script (file: {0}) {1} {2}", macro.Name, exception.Message, exception.StackTrace)); - var loading = string.Format("
Error loading Razor Script {0}
", macro.ScriptName); - if (GlobalSettings.DebugMode) - loading = loading + exception.Message; - loading = loading + "
"; - return loading; + throw; } } diff --git a/src/umbraco.businesslogic/UmbracoSettings.cs b/src/umbraco.businesslogic/UmbracoSettings.cs index 22133c3945..c7db9fdeb1 100644 --- a/src/umbraco.businesslogic/UmbracoSettings.cs +++ b/src/umbraco.businesslogic/UmbracoSettings.cs @@ -1,11 +1,7 @@ using System; -using System.Diagnostics; -using System.IO; using System.Linq; -using System.Web; -using System.Web.Caching; using System.Xml; -using umbraco.BusinessLogic; +using Umbraco.Core; using System.Collections.Generic; using umbraco.MacroEngines; @@ -554,6 +550,18 @@ namespace umbraco get { return Umbraco.Core.Configuration.UmbracoSettings.ResolveUrlsFromTextString; } } + /// + /// This configuration setting defines how to handle macro errors: + /// - Inline - Show error within macro as text (default and current Umbraco 'normal' behavior) + /// - Silent - Suppress error and hide macro + /// - Throw - Throw an exception and invoke the global error handler (if one is defined, if not you'll get a YSOD) + /// + /// MacroErrorBehaviour enum defining how to handle macro errors. + public static MacroErrorBehaviour MacroErrorBehaviour + { + get { return Umbraco.Core.Configuration.UmbracoSettings.MacroErrorBehaviour; } + } + /// /// Configuration regarding webservices /// diff --git a/src/umbraco.cms/businesslogic/events/EventArgs.cs b/src/umbraco.cms/businesslogic/events/EventArgs.cs index 3514065cee..87942060f6 100644 --- a/src/umbraco.cms/businesslogic/events/EventArgs.cs +++ b/src/umbraco.cms/businesslogic/events/EventArgs.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Text; +using Umbraco.Core; using umbraco.cms.businesslogic.member; using umbraco.cms.businesslogic.web; @@ -61,5 +62,36 @@ namespace umbraco.cms.businesslogic { { public bool CancelChildren { get; set; } } - + + // Provides information on the macro that caused an error + public class MacroErrorEventArgs : System.EventArgs + { + /// + /// Name of the faulting macro. + /// + public string Name { get; set; } + + /// + /// Alias of the faulting macro. + /// + public string Alias { get; set; } + + /// + /// Filename of the faulting macro. + /// + public string File { get; set; } + + /// + /// Exception raised. + /// + public Exception Exception { get; set; } + + /// + /// Gets or sets the desired behaviour when a matching macro causes an error. See + /// for definitions. By setting this in your event + /// you can override the default behaviour defined in UmbracoSettings.config. + /// + /// Macro error behaviour enum. + public MacroErrorBehaviour Behaviour { get; set; } + } } From 28c55320a1ac272edd64306910a56a3dec91b416 Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Mon, 11 Mar 2013 20:11:11 +0600 Subject: [PATCH 5/8] Updates the pull request for handling macro errors. Backports fixes for partial view macros from 6.x - U4-1488, U4-1844, U4-1730, U4-1843 --- .../Events/MacroErrorEventArgs.cs | 39 +++ src/Umbraco.Core/Umbraco.Core.csproj | 1 + .../Macros/PartialViewMacroController.cs | 58 +++-- .../Macros/PartialViewMacroEngine.cs | 238 +++++++++--------- .../Macros/PartialViewMacroPage.cs | 28 ++- .../Models/PartialViewMacroModel.cs | 52 +++- src/Umbraco.Web/Mvc/Constants.cs | 13 +- src/Umbraco.Web/Mvc/ControllerExtensions.cs | 84 ++++--- src/Umbraco.Web/Mvc/SurfaceController.cs | 178 +++++++------ src/Umbraco.Web/Mvc/UmbracoViewPage.cs | 185 ++++++++------ src/Umbraco.Web/umbraco.presentation/macro.cs | 13 +- .../businesslogic/events/EventArgs.cs | 32 +-- 12 files changed, 518 insertions(+), 403 deletions(-) create mode 100644 src/Umbraco.Core/Events/MacroErrorEventArgs.cs diff --git a/src/Umbraco.Core/Events/MacroErrorEventArgs.cs b/src/Umbraco.Core/Events/MacroErrorEventArgs.cs new file mode 100644 index 0000000000..a5fbd959f1 --- /dev/null +++ b/src/Umbraco.Core/Events/MacroErrorEventArgs.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Umbraco.Core.Events +{ + // Provides information on the macro that caused an error + public class MacroErrorEventArgs : System.EventArgs + { + /// + /// Name of the faulting macro. + /// + public string Name { get; set; } + + /// + /// Alias of the faulting macro. + /// + public string Alias { get; set; } + + /// + /// Filename of the faulting macro. + /// + public string File { get; set; } + + /// + /// Exception raised. + /// + public Exception Exception { get; set; } + + /// + /// Gets or sets the desired behaviour when a matching macro causes an error. See + /// for definitions. By setting this in your event + /// you can override the default behaviour defined in UmbracoSettings.config. + /// + /// Macro error behaviour enum. + public MacroErrorBehaviour Behaviour { get; set; } + } +} diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index ab878ff025..9d79e46418 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -69,6 +69,7 @@ + diff --git a/src/Umbraco.Web/Macros/PartialViewMacroController.cs b/src/Umbraco.Web/Macros/PartialViewMacroController.cs index c01731e989..765846c5c5 100644 --- a/src/Umbraco.Web/Macros/PartialViewMacroController.cs +++ b/src/Umbraco.Web/Macros/PartialViewMacroController.cs @@ -7,33 +7,37 @@ using System.Linq; namespace Umbraco.Web.Macros { - /// - /// Controller to render macro content for Parital View Macros - /// - internal class PartialViewMacroController : Controller - { - private readonly UmbracoContext _umbracoContext; - private readonly MacroModel _macro; - private readonly INode _currentPage; - - public PartialViewMacroController(UmbracoContext umbracoContext, MacroModel macro, INode currentPage) - { - _umbracoContext = umbracoContext; - _macro = macro; - _currentPage = currentPage; - } + /// + /// Controller to render macro content for Parital View Macros + /// + internal class PartialViewMacroController : Controller + { + private readonly UmbracoContext _umbracoContext; + private readonly MacroModel _macro; + private readonly INode _currentPage; - /// - /// Child action to render a macro - /// - /// - [ChildActionOnly] - public PartialViewResult Index() - { - var model = new PartialViewMacroModel(_currentPage.ConvertFromNode(), - _macro.Properties.ToDictionary(x => x.Key, x => (object)x.Value)); - return PartialView(_macro.ScriptName, model); - } + public PartialViewMacroController(UmbracoContext umbracoContext, MacroModel macro, INode currentPage) + { + _umbracoContext = umbracoContext; + _macro = macro; + _currentPage = currentPage; + } - } + /// + /// Child action to render a macro + /// + /// + [ChildActionOnly] + public PartialViewResult Index() + { + var model = new PartialViewMacroModel( + _currentPage.ConvertFromNode(), + _macro.Id, + _macro.Alias, + _macro.Name, + _macro.Properties.ToDictionary(x => x.Key, x => (object)x.Value)); + return PartialView(_macro.ScriptName, model); + } + + } } \ No newline at end of file diff --git a/src/Umbraco.Web/Macros/PartialViewMacroEngine.cs b/src/Umbraco.Web/Macros/PartialViewMacroEngine.cs index 2b56940e4c..ee0f5f9c3f 100644 --- a/src/Umbraco.Web/Macros/PartialViewMacroEngine.cs +++ b/src/Umbraco.Web/Macros/PartialViewMacroEngine.cs @@ -12,51 +12,53 @@ using Umbraco.Core.IO; using umbraco.cms.businesslogic.macro; using umbraco.interfaces; using Umbraco.Web.Mvc; +using Umbraco.Core; +using System.Web.Mvc.Html; namespace Umbraco.Web.Macros { - /// - /// A macro engine using MVC Partial Views to execute - /// - public class PartialViewMacroEngine : IMacroEngine - { - private readonly Func _getHttpContext; - private readonly Func _getUmbracoContext; + /// + /// A macro engine using MVC Partial Views to execute + /// + public class PartialViewMacroEngine : IMacroEngine + { + private readonly Func _getHttpContext; + private readonly Func _getUmbracoContext; - public const string EngineName = "Partial View Macro Engine"; + public const string EngineName = "Partial View Macro Engine"; - public PartialViewMacroEngine() - { - _getHttpContext = () => - { - if (HttpContext.Current == null) - throw new InvalidOperationException("The " + this.GetType() + " cannot execute with a null HttpContext.Current reference"); - return new HttpContextWrapper(HttpContext.Current); - }; + public PartialViewMacroEngine() + { + _getHttpContext = () => + { + if (HttpContext.Current == null) + throw new InvalidOperationException("The " + this.GetType() + " cannot execute with a null HttpContext.Current reference"); + return new HttpContextWrapper(HttpContext.Current); + }; - _getUmbracoContext = () => - { - if (UmbracoContext.Current == null) - throw new InvalidOperationException("The " + this.GetType() + " cannot execute with a null UmbracoContext.Current reference"); - return UmbracoContext.Current; - }; - } + _getUmbracoContext = () => + { + if (UmbracoContext.Current == null) + throw new InvalidOperationException("The " + this.GetType() + " cannot execute with a null UmbracoContext.Current reference"); + return UmbracoContext.Current; + }; + } - /// - /// Constructor generally used for unit testing - /// - /// - /// - internal PartialViewMacroEngine(HttpContextBase httpContext, UmbracoContext umbracoContext) - { - _getHttpContext = () => httpContext; - _getUmbracoContext = () => umbracoContext; - } + /// + /// Constructor generally used for unit testing + /// + /// + /// + internal PartialViewMacroEngine(HttpContextBase httpContext, UmbracoContext umbracoContext) + { + _getHttpContext = () => httpContext; + _getUmbracoContext = () => umbracoContext; + } - public string Name - { - get { return EngineName; } - } + public string Name + { + get { return EngineName; } + } //NOTE: We do not return any supported extensions because we don't want the MacroEngineFactory to return this // macro engine when searching for engines via extension. Those types of engines are reserved for files that are @@ -65,7 +67,6 @@ namespace Umbraco.Web.Macros public IEnumerable SupportedExtensions { get { return Enumerable.Empty(); } - //get { return new[] {"cshtml", "vbhtml"}; } } //NOTE: We do not return any supported extensions because we don't want the MacroEngineFactory to return this @@ -75,92 +76,99 @@ namespace Umbraco.Web.Macros public IEnumerable SupportedUIExtensions { get { return Enumerable.Empty(); } - //get { return new[] { "cshtml", "vbhtml" }; } + } + public Dictionary SupportedProperties + { + get { throw new NotSupportedException(); } } - public Dictionary SupportedProperties - { - get { throw new NotSupportedException(); } - } + public bool Validate(string code, string tempFileName, INode currentPage, out string errorMessage) + { + var temp = GetVirtualPathFromPhysicalPath(tempFileName); + try + { + CompileAndInstantiate(temp); + } + catch (Exception exception) + { + errorMessage = exception.Message; + return false; + } + errorMessage = string.Empty; + return true; + } - public bool Validate(string code, string tempFileName, INode currentPage, out string errorMessage) - { - var temp = GetVirtualPathFromPhysicalPath(tempFileName); - try - { - CompileAndInstantiate(temp); - } - catch (Exception exception) - { - errorMessage = exception.Message; - return false; - } - errorMessage = string.Empty; - return true; - } + public string Execute(MacroModel macro, INode currentPage) + { + if (macro == null) throw new ArgumentNullException("macro"); + if (currentPage == null) throw new ArgumentNullException("currentPage"); + if (macro.ScriptName.IsNullOrWhiteSpace()) throw new ArgumentException("The ScriptName property of the macro object cannot be null or empty"); - public string Execute(MacroModel macro, INode currentPage) - { - if (macro == null) throw new ArgumentNullException("macro"); - if (currentPage == null) throw new ArgumentNullException("currentPage"); + if (!macro.ScriptName.StartsWith(SystemDirectories.MvcViews + "/MacroPartials/") + && (!Regex.IsMatch(macro.ScriptName, "~/App_Plugins/.+?/Views/MacroPartials", RegexOptions.Compiled))) + { + throw new InvalidOperationException("Cannot render the Partial View Macro with file: " + macro.ScriptName + ". All Partial View Macros must exist in the " + SystemDirectories.MvcViews + "/MacroPartials/ folder"); + } - if (!macro.ScriptName.StartsWith(SystemDirectories.MvcViews + "/MacroPartials/") - && (!Regex.IsMatch(macro.ScriptName, "~/App_Plugins/.+?/Views/MacroPartials", RegexOptions.Compiled))) - { - throw new InvalidOperationException("Cannot render the Partial View Macro with file: " + macro.ScriptName + ". All Partial View Macros must exist in the " + SystemDirectories.MvcViews + "/MacroPartials/ folder"); - } + var http = _getHttpContext(); + var umbCtx = _getUmbracoContext(); + var routeVals = new RouteData(); + routeVals.Values.Add("controller", "PartialViewMacro"); + routeVals.Values.Add("action", "Index"); + routeVals.DataTokens.Add("umbraco-context", umbCtx); //required for UmbracoViewPage - var http = _getHttpContext(); - var umbCtx = _getUmbracoContext(); - var routeVals = new RouteData(); - routeVals.Values.Add("controller", "PartialViewMacro"); - routeVals.Values.Add("action", "Index"); - routeVals.DataTokens.Add("umbraco-context", umbCtx); //required for UmbracoViewPage + //lets render this controller as a child action if we are currently executing using MVC + //(otherwise don't do this since we're using webforms) + var mvcHandler = http.CurrentHandler as MvcHandler; + var viewContext = new ViewContext { ViewData = new ViewDataDictionary() }; ; + if (mvcHandler != null) + { + //try and extract the current view context from the route values, this would be set in the UmbracoViewPage. + if (mvcHandler.RequestContext.RouteData.DataTokens.ContainsKey(Constants.DataTokenCurrentViewContext)) + { + viewContext = (ViewContext)mvcHandler.RequestContext.RouteData.DataTokens[Constants.DataTokenCurrentViewContext]; + } + routeVals.DataTokens.Add("ParentActionViewContext", viewContext); + } - ////lets render this controller as a child action if we are currently executing using MVC - ////(otherwise don't do this since we're using webforms) - //var mvcHandler = http.CurrentHandler as MvcHandler; - //if (mvcHandler != null) - //{ - // routeVals.DataTokens.Add("ParentActionViewContext", - // //If we could get access to the currently executing controller we could do this but this is nearly - // //impossible. The only way to do that would be to store the controller instance in the route values - // //in the base class of the UmbracoController.... but not sure the reprocussions of that, i think it could - // //work but is a bit nasty. - // new ViewContext()); - //} + var request = new RequestContext(http, routeVals); + string output; + using (var controller = new PartialViewMacroController(umbCtx, macro, currentPage)) + { + //bubble up the model state from the main view context to our custom controller. + //when merging we'll create a new dictionary, otherwise you might run into an enumeration error + // caused from ModelStateDictionary + controller.ModelState.Merge(new ModelStateDictionary(viewContext.ViewData.ModelState)); + controller.ControllerContext = new ControllerContext(request, controller); + //call the action to render + var result = controller.Index(); + output = controller.RenderViewResultAsString(result); + } - var request = new RequestContext(http, routeVals); - string output; - using (var controller = new PartialViewMacroController(umbCtx, macro, currentPage)) - { - controller.ControllerContext = new ControllerContext(request, controller); - var result = controller.Index(); - output = controller.RenderViewResultAsString(result); - } + return output; + } - return output; - } + private string GetVirtualPathFromPhysicalPath(string physicalPath) + { + string rootpath = _getHttpContext().Server.MapPath("~/"); + physicalPath = physicalPath.Replace(rootpath, ""); + physicalPath = physicalPath.Replace("\\", "/"); + return "~/" + physicalPath; + } - private string GetVirtualPathFromPhysicalPath(string physicalPath) - { - string rootpath = _getHttpContext().Server.MapPath("~/"); - physicalPath = physicalPath.Replace(rootpath, ""); - physicalPath = physicalPath.Replace("\\", "/"); - return "~/" + physicalPath; - } + private static PartialViewMacroPage CompileAndInstantiate(string virtualPath) + { + //Compile Razor - We Will Leave This To ASP.NET Compilation Engine & ASP.NET WebPages + //Security in medium trust is strict around here, so we can only pass a virtual file path + //ASP.NET Compilation Engine caches returned types + //Changed From BuildManager As Other Properties Are Attached Like Context Path/ + var webPageBase = WebPageBase.CreateInstanceFromVirtualPath(virtualPath); + var webPage = webPageBase as PartialViewMacroPage; + if (webPage == null) + throw new InvalidCastException("All Partial View Macro views must inherit from " + typeof(PartialViewMacroPage).FullName); + return webPage; + } + + } - private static PartialViewMacroPage CompileAndInstantiate(string virtualPath) - { - //Compile Razor - We Will Leave This To ASP.NET Compilation Engine & ASP.NET WebPages - //Security in medium trust is strict around here, so we can only pass a virtual file path - //ASP.NET Compilation Engine caches returned types - //Changed From BuildManager As Other Properties Are Attached Like Context Path/ - var webPageBase = WebPageBase.CreateInstanceFromVirtualPath(virtualPath); - var webPage = webPageBase as PartialViewMacroPage; - if (webPage == null) - throw new InvalidCastException("All Partial View Macro views must inherit from " + typeof(PartialViewMacroPage).FullName); - return webPage; - } - } } diff --git a/src/Umbraco.Web/Macros/PartialViewMacroPage.cs b/src/Umbraco.Web/Macros/PartialViewMacroPage.cs index a64e48663f..8f5c11b044 100644 --- a/src/Umbraco.Web/Macros/PartialViewMacroPage.cs +++ b/src/Umbraco.Web/Macros/PartialViewMacroPage.cs @@ -1,14 +1,28 @@ using System.Web.Mvc; +using Umbraco.Core.Models; using Umbraco.Web.Models; using Umbraco.Web.Mvc; namespace Umbraco.Web.Macros { - /// - /// The base view class that PartialViewMacro views need to inherit from - /// - public abstract class PartialViewMacroPage : UmbracoViewPage - { - - } + /// + /// The base view class that PartialViewMacro views need to inherit from + /// + public abstract class PartialViewMacroPage : UmbracoViewPage + { + protected override void InitializePage() + { + base.InitializePage(); + //set the model to the current node if it is not set, this is generally not the case + if (Model != null) + { + CurrentPage = Model.Content.AsDynamic(); + } + } + + /// + /// Returns the a DynamicPublishedContent object + /// + public dynamic CurrentPage { get; private set; } + } } \ No newline at end of file diff --git a/src/Umbraco.Web/Models/PartialViewMacroModel.cs b/src/Umbraco.Web/Models/PartialViewMacroModel.cs index 7d690d30e4..c2110ad5f9 100644 --- a/src/Umbraco.Web/Models/PartialViewMacroModel.cs +++ b/src/Umbraco.Web/Models/PartialViewMacroModel.cs @@ -1,23 +1,49 @@ +using System; using System.Collections.Generic; +using System.ComponentModel; using Umbraco.Core.Models; namespace Umbraco.Web.Models { - /// - /// The model used when rendering Partial View Macros - /// - public class PartialViewMacroModel - { + /// + /// The model used when rendering Partial View Macros + /// + public class PartialViewMacroModel + { - public PartialViewMacroModel(IPublishedContent page, IDictionary macroParams) - { - CurrentPage = page; - MacroParameters = macroParams; - } + public PartialViewMacroModel(IPublishedContent page, + int macroId, + string macroAlias, + string macroName, + IDictionary macroParams) + { + Content = page; + MacroParameters = macroParams; + MacroName = macroName; + MacroAlias = macroAlias; + MacroId = macroId; + } - public IPublishedContent CurrentPage { get; private set; } + [EditorBrowsable(EditorBrowsableState.Never)] + [Obsolete("Use the constructor accepting the macro id instead")] + public PartialViewMacroModel(IPublishedContent page, IDictionary macroParams) + { + Content = page; + MacroParameters = macroParams; + } - public IDictionary MacroParameters { get; private set; } + [EditorBrowsable(EditorBrowsableState.Never)] + [Obsolete("Use the Content property instead")] + public IPublishedContent CurrentPage + { + get { return Content; } + } - } + public IPublishedContent Content { get; private set; } + public string MacroName { get; private set; } + public string MacroAlias { get; private set; } + public int MacroId { get; private set; } + public IDictionary MacroParameters { get; private set; } + + } } \ No newline at end of file diff --git a/src/Umbraco.Web/Mvc/Constants.cs b/src/Umbraco.Web/Mvc/Constants.cs index 1ec35e4928..57c7921a99 100644 --- a/src/Umbraco.Web/Mvc/Constants.cs +++ b/src/Umbraco.Web/Mvc/Constants.cs @@ -1,7 +1,12 @@ namespace Umbraco.Web.Mvc { - internal static class Constants - { - public const string ViewLocation = "~/Views"; - } + /// + /// constants + /// + internal static class Constants + { + internal const string ViewLocation = "~/Views"; + + internal const string DataTokenCurrentViewContext = "umbraco-current-view-context"; + } } \ No newline at end of file diff --git a/src/Umbraco.Web/Mvc/ControllerExtensions.cs b/src/Umbraco.Web/Mvc/ControllerExtensions.cs index 59900e6489..8ec66ab1c8 100644 --- a/src/Umbraco.Web/Mvc/ControllerExtensions.cs +++ b/src/Umbraco.Web/Mvc/ControllerExtensions.cs @@ -97,56 +97,58 @@ namespace Umbraco.Web.Mvc } } - /// - /// Normally in MVC the way that the View object gets assigned to the result is to Execute the ViewResult, this however - /// will write to the Response output stream which isn't what we want. Instead, this method will use the same logic inside - /// of MVC to assign the View object to the result but without executing it. This also ensures that the ViewData and the TempData - /// is assigned from the controller. - /// This is only relavent for view results of PartialViewResult or ViewResult. - /// - /// - /// - internal static void EnsureViewObjectDataOnResult(this ControllerBase controller, ViewResultBase result) - { - result.ViewData.ModelState.Merge(controller.ViewData.ModelState); + /// + /// Normally in MVC the way that the View object gets assigned to the result is to Execute the ViewResult, this however + /// will write to the Response output stream which isn't what we want. Instead, this method will use the same logic inside + /// of MVC to assign the View object to the result but without executing it. This also ensures that the ViewData and the TempData + /// is assigned from the controller. + /// This is only relavent for view results of PartialViewResult or ViewResult. + /// + /// + /// + internal static void EnsureViewObjectDataOnResult(this ControllerBase controller, ViewResultBase result) + { + //when merging we'll create a new dictionary, otherwise you might run into an enumeration error + // caused from ModelStateDictionary + result.ViewData.ModelState.Merge(new ModelStateDictionary(controller.ViewData.ModelState)); - // Temporarily copy the dictionary to avoid enumerator-modification errors - var newViewDataDict = new ViewDataDictionary(controller.ViewData); - foreach (var d in newViewDataDict) - result.ViewData[d.Key] = d.Value; + // Temporarily copy the dictionary to avoid enumerator-modification errors + var newViewDataDict = new ViewDataDictionary(controller.ViewData); + foreach (var d in newViewDataDict) + result.ViewData[d.Key] = d.Value; - result.TempData = controller.TempData; + result.TempData = controller.TempData; - if (result.View != null) return; + if (result.View != null) return; - if (string.IsNullOrEmpty(result.ViewName)) - result.ViewName = controller.ControllerContext.RouteData.GetRequiredString("action"); + if (string.IsNullOrEmpty(result.ViewName)) + result.ViewName = controller.ControllerContext.RouteData.GetRequiredString("action"); - if (result.View != null) return; + if (result.View != null) return; - if (result is PartialViewResult) - { - var viewEngineResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, result.ViewName); + if (result is PartialViewResult) + { + var viewEngineResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, result.ViewName); - if (viewEngineResult.View == null) - { - throw new InvalidOperationException("Could not find the view " + result.ViewName + ", the following locations were searched: " + Environment.NewLine + string.Join(Environment.NewLine, viewEngineResult.SearchedLocations)); - } + if (viewEngineResult.View == null) + { + throw new InvalidOperationException("Could not find the view " + result.ViewName + ", the following locations were searched: " + Environment.NewLine + string.Join(Environment.NewLine, viewEngineResult.SearchedLocations)); + } - result.View = viewEngineResult.View; - } - else if (result is ViewResult) - { - var vr = (ViewResult)result; - var viewEngineResult = ViewEngines.Engines.FindView(controller.ControllerContext, vr.ViewName, vr.MasterName); + result.View = viewEngineResult.View; + } + else if (result is ViewResult) + { + var vr = (ViewResult)result; + var viewEngineResult = ViewEngines.Engines.FindView(controller.ControllerContext, vr.ViewName, vr.MasterName); - if (viewEngineResult.View == null) - { - throw new InvalidOperationException("Could not find the view " + vr.ViewName + ", the following locations were searched: " + Environment.NewLine + string.Join(Environment.NewLine, viewEngineResult.SearchedLocations)); - } + if (viewEngineResult.View == null) + { + throw new InvalidOperationException("Could not find the view " + vr.ViewName + ", the following locations were searched: " + Environment.NewLine + string.Join(Environment.NewLine, viewEngineResult.SearchedLocations)); + } - result.View = viewEngineResult.View; - } - } + result.View = viewEngineResult.View; + } + } } } diff --git a/src/Umbraco.Web/Mvc/SurfaceController.cs b/src/Umbraco.Web/Mvc/SurfaceController.cs index 463162694f..0e0b7b5827 100644 --- a/src/Umbraco.Web/Mvc/SurfaceController.cs +++ b/src/Umbraco.Web/Mvc/SurfaceController.cs @@ -8,89 +8,119 @@ using Umbraco.Core; namespace Umbraco.Web.Mvc { - /// - /// The base controller that all Presentation Add-in controllers should inherit from - /// - [MergeModelStateToChildAction] - public abstract class SurfaceController : PluginController - { + /// + /// The base controller that all Presentation Add-in controllers should inherit from + /// + [MergeModelStateToChildAction] + public abstract class SurfaceController : PluginController + { - /// - /// Default constructor - /// - /// - protected SurfaceController(UmbracoContext umbracoContext) - : base(umbracoContext) - { - } + /// + /// Default constructor + /// + /// + protected SurfaceController(UmbracoContext umbracoContext) + : base(umbracoContext) + { + } - /// - /// Empty constructor, uses Singleton to resolve the UmbracoContext - /// - protected SurfaceController() - : base(UmbracoContext.Current) - { - } + /// + /// Empty constructor, uses Singleton to resolve the UmbracoContext + /// + protected SurfaceController() + : base(UmbracoContext.Current) + { + } - /// - /// Redirects to the Umbraco page with the given id - /// - /// - /// - protected RedirectToUmbracoPageResult RedirectToUmbracoPage(int pageId) - { - return new RedirectToUmbracoPageResult(pageId, UmbracoContext); - } + /// + /// Redirects to the Umbraco page with the given id + /// + /// + /// + protected RedirectToUmbracoPageResult RedirectToUmbracoPage(int pageId) + { + return new RedirectToUmbracoPageResult(pageId, UmbracoContext); + } - /// - /// Redirects to the Umbraco page with the given id - /// - /// - /// - protected RedirectToUmbracoPageResult RedirectToUmbracoPage(IPublishedContent publishedContent) - { - return new RedirectToUmbracoPageResult(publishedContent, UmbracoContext); - } + /// + /// Redirects to the Umbraco page with the given id + /// + /// + /// + protected RedirectToUmbracoPageResult RedirectToUmbracoPage(IPublishedContent publishedContent) + { + return new RedirectToUmbracoPageResult(publishedContent, UmbracoContext); + } - /// - /// Redirects to the currently rendered Umbraco page - /// - /// - protected RedirectToUmbracoPageResult RedirectToCurrentUmbracoPage() - { - return new RedirectToUmbracoPageResult(CurrentPage, UmbracoContext); - } + /// + /// Redirects to the currently rendered Umbraco page + /// + /// + protected RedirectToUmbracoPageResult RedirectToCurrentUmbracoPage() + { + return new RedirectToUmbracoPageResult(CurrentPage, UmbracoContext); + } - /// - /// Returns the currently rendered Umbraco page - /// - /// - protected UmbracoPageResult CurrentUmbracoPage() - { - return new UmbracoPageResult(); - } + /// + /// Returns the currently rendered Umbraco page + /// + /// + protected UmbracoPageResult CurrentUmbracoPage() + { + return new UmbracoPageResult(); + } - /// - /// Gets the current page. - /// - protected IPublishedContent CurrentPage - { - get - { - var routeData = ControllerContext.IsChildAction - ? ControllerContext.ParentActionViewContext.RouteData - : ControllerContext.RouteData; - - if (!routeData.DataTokens.ContainsKey("umbraco-route-def")) + /// + /// Gets the current page. + /// + protected IPublishedContent CurrentPage + { + get + { + var routeDefAttempt = TryGetRouteDefinitionFromAncestorViewContexts(); + if (!routeDefAttempt.Success) { - throw new InvalidOperationException("Cannot find the Umbraco route definition in the route values, the request must be made in the context of an Umbraco request"); + throw routeDefAttempt.Error; } - var routeDef = (RouteDefinition)routeData.DataTokens["umbraco-route-def"]; - return routeDef.PublishedContentRequest.PublishedContent; - } - } + var routeDef = routeDefAttempt.Result; + return routeDef.PublishedContentRequest.PublishedContent; + } + } - - } + /// + /// we need to recursively find the route definition based on the parent view context + /// + /// + /// + /// We may have Child Actions within Child actions so we need to recursively look this up. + /// see: http://issues.umbraco.org/issue/U4-1844 + /// + private Attempt TryGetRouteDefinitionFromAncestorViewContexts() + { + ControllerContext currentContext = ControllerContext; + while (currentContext != null) + { + var currentRouteData = currentContext.RouteData; + if (currentRouteData.DataTokens.ContainsKey("umbraco-route-def")) + { + return new Attempt(true, (RouteDefinition)currentRouteData.DataTokens["umbraco-route-def"]); + } + if (currentContext.IsChildAction) + { + //assign current context to parent + currentContext = currentContext.ParentActionViewContext; + } + else + { + //exit the loop + currentRouteData = null; + } + } + return new Attempt( + new InvalidOperationException("Cannot find the Umbraco route definition in the route values, the request must be made in the context of an Umbraco request")); + } + + + } } \ No newline at end of file diff --git a/src/Umbraco.Web/Mvc/UmbracoViewPage.cs b/src/Umbraco.Web/Mvc/UmbracoViewPage.cs index ff926fd4b4..d08deb5393 100644 --- a/src/Umbraco.Web/Mvc/UmbracoViewPage.cs +++ b/src/Umbraco.Web/Mvc/UmbracoViewPage.cs @@ -4,94 +4,113 @@ using Umbraco.Web.Routing; namespace Umbraco.Web.Mvc { - /// - /// The View that umbraco front-end views inherit from - /// - public abstract class UmbracoViewPage : WebViewPage - { - protected UmbracoViewPage() - { + /// + /// The View that umbraco front-end views inherit from + /// + public abstract class UmbracoViewPage : WebViewPage + { + protected UmbracoViewPage() + { - } - - /// - /// Returns the current UmbracoContext - /// - public UmbracoContext UmbracoContext - { - get - { - //we should always try to return the context from the data tokens just in case its a custom context and not - //using the UmbracoContext.Current. - //we will fallback to the singleton if necessary. - if (ViewContext.RouteData.DataTokens.ContainsKey("umbraco-context")) - { - return (UmbracoContext)ViewContext.RouteData.DataTokens.GetRequiredObject("umbraco-context"); - } - //next check if it is a child action and see if the parent has it set in data tokens - if (ViewContext.IsChildAction) - { - if (ViewContext.ParentActionViewContext.RouteData.DataTokens.ContainsKey("umbraco-context")) - { - return (UmbracoContext)ViewContext.ParentActionViewContext.RouteData.DataTokens.GetRequiredObject("umbraco-context"); - } - } - - //lastly, we will use the singleton, the only reason this should ever happen is is someone is rendering a page that inherits from this - //class and are rendering it outside of the normal Umbraco routing process. Very unlikely. - return UmbracoContext.Current; - } - } + } - /// - /// Returns the current ApplicationContext - /// - public ApplicationContext ApplicationContext - { - get { return UmbracoContext.Application; } - } + /// + /// Returns the current UmbracoContext + /// + public UmbracoContext UmbracoContext + { + get + { + //we should always try to return the context from the data tokens just in case its a custom context and not + //using the UmbracoContext.Current. + //we will fallback to the singleton if necessary. + if (ViewContext.RouteData.DataTokens.ContainsKey("umbraco-context")) + { + return (UmbracoContext)ViewContext.RouteData.DataTokens.GetRequiredObject("umbraco-context"); + } + //next check if it is a child action and see if the parent has it set in data tokens + if (ViewContext.IsChildAction) + { + if (ViewContext.ParentActionViewContext.RouteData.DataTokens.ContainsKey("umbraco-context")) + { + return (UmbracoContext)ViewContext.ParentActionViewContext.RouteData.DataTokens.GetRequiredObject("umbraco-context"); + } + } - /// - /// Returns the current PublishedContentRequest - /// - internal PublishedContentRequest PublishedContentRequest - { - get - { - //we should always try to return the object from the data tokens just in case its a custom object and not - //using the UmbracoContext.Current. - //we will fallback to the singleton if necessary. - if (ViewContext.RouteData.DataTokens.ContainsKey("umbraco-doc-request")) - { - return (PublishedContentRequest)ViewContext.RouteData.DataTokens.GetRequiredObject("umbraco-doc-request"); - } - //next check if it is a child action and see if the parent has it set in data tokens - if (ViewContext.IsChildAction) - { - if (ViewContext.ParentActionViewContext.RouteData.DataTokens.ContainsKey("umbraco-doc-request")) - { - return (PublishedContentRequest)ViewContext.ParentActionViewContext.RouteData.DataTokens.GetRequiredObject("umbraco-doc-request"); - } - } + //lastly, we will use the singleton, the only reason this should ever happen is is someone is rendering a page that inherits from this + //class and are rendering it outside of the normal Umbraco routing process. Very unlikely. + return UmbracoContext.Current; + } + } - //lastly, we will use the singleton, the only reason this should ever happen is is someone is rendering a page that inherits from this - //class and are rendering it outside of the normal Umbraco routing process. Very unlikely. - return UmbracoContext.Current.PublishedContentRequest; - } - } + /// + /// Returns the current ApplicationContext + /// + public ApplicationContext ApplicationContext + { + get { return UmbracoContext.Application; } + } - private UmbracoHelper _helper; + /// + /// Returns the current PublishedContentRequest + /// + internal PublishedContentRequest PublishedContentRequest + { + get + { + //we should always try to return the object from the data tokens just in case its a custom object and not + //using the UmbracoContext.Current. + //we will fallback to the singleton if necessary. + if (ViewContext.RouteData.DataTokens.ContainsKey("umbraco-doc-request")) + { + return (PublishedContentRequest)ViewContext.RouteData.DataTokens.GetRequiredObject("umbraco-doc-request"); + } + //next check if it is a child action and see if the parent has it set in data tokens + if (ViewContext.IsChildAction) + { + if (ViewContext.ParentActionViewContext.RouteData.DataTokens.ContainsKey("umbraco-doc-request")) + { + return (PublishedContentRequest)ViewContext.ParentActionViewContext.RouteData.DataTokens.GetRequiredObject("umbraco-doc-request"); + } + } - /// - /// Gets an UmbracoHelper - /// - /// - /// This constructs the UmbracoHelper with the content model of the page routed to - /// - public virtual UmbracoHelper Umbraco - { - get { return _helper ?? (_helper = new UmbracoHelper(UmbracoContext)); } - } + //lastly, we will use the singleton, the only reason this should ever happen is is someone is rendering a page that inherits from this + //class and are rendering it outside of the normal Umbraco routing process. Very unlikely. + return UmbracoContext.Current.PublishedContentRequest; + } + } - } + private UmbracoHelper _helper; + + /// + /// Gets an UmbracoHelper + /// + /// + /// This constructs the UmbracoHelper with the content model of the page routed to + /// + public virtual UmbracoHelper Umbraco + { + get { return _helper ?? (_helper = new UmbracoHelper(UmbracoContext)); } + } + + /// + /// Ensure that the current view context is added to the route data tokens so we can extract it if we like + /// + /// + /// Currently this is required by mvc macro engines + /// + protected override void InitializePage() + { + base.InitializePage(); + if (!ViewContext.IsChildAction) + { + if (!ViewContext.RouteData.DataTokens.ContainsKey(Constants.DataTokenCurrentViewContext)) + { + ViewContext.RouteData.DataTokens.Add(Constants.DataTokenCurrentViewContext, this.ViewContext); + } + } + + } + + } } \ No newline at end of file diff --git a/src/Umbraco.Web/umbraco.presentation/macro.cs b/src/Umbraco.Web/umbraco.presentation/macro.cs index 5c24da5362..cb57e35a43 100644 --- a/src/Umbraco.Web/umbraco.presentation/macro.cs +++ b/src/Umbraco.Web/umbraco.presentation/macro.cs @@ -16,8 +16,10 @@ using System.Web.UI.WebControls; using System.Xml; using System.Xml.Xsl; using Umbraco.Core; +using Umbraco.Core.Events; using Umbraco.Core.IO; using Umbraco.Core.Logging; +using Umbraco.Web; using Umbraco.Web.Macros; using Umbraco.Web.Templates; using umbraco.BusinessLogic; @@ -1847,21 +1849,16 @@ namespace umbraco #region Events - /// - /// The macro error event handler. - /// - public delegate void ErrorEventHandler(object sender, MacroErrorEventArgs e); - /// /// Occurs when a macro error is raised. /// - public static event ErrorEventHandler Error; + public static event EventHandler Error; /// - /// Raises the event. + /// Raises the event. /// /// The instance containing the event data. - protected virtual void OnError(MacroErrorEventArgs e) + protected void OnError(MacroErrorEventArgs e) { if (Error != null) { diff --git a/src/umbraco.cms/businesslogic/events/EventArgs.cs b/src/umbraco.cms/businesslogic/events/EventArgs.cs index 87942060f6..09836a8101 100644 --- a/src/umbraco.cms/businesslogic/events/EventArgs.cs +++ b/src/umbraco.cms/businesslogic/events/EventArgs.cs @@ -63,35 +63,5 @@ namespace umbraco.cms.businesslogic { public bool CancelChildren { get; set; } } - // Provides information on the macro that caused an error - public class MacroErrorEventArgs : System.EventArgs - { - /// - /// Name of the faulting macro. - /// - public string Name { get; set; } - - /// - /// Alias of the faulting macro. - /// - public string Alias { get; set; } - - /// - /// Filename of the faulting macro. - /// - public string File { get; set; } - - /// - /// Exception raised. - /// - public Exception Exception { get; set; } - - /// - /// Gets or sets the desired behaviour when a matching macro causes an error. See - /// for definitions. By setting this in your event - /// you can override the default behaviour defined in UmbracoSettings.config. - /// - /// Macro error behaviour enum. - public MacroErrorBehaviour Behaviour { get; set; } - } + } From d07212c89bdaf0b8c10a228f539f10f579cc0a9b Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Mon, 11 Mar 2013 21:06:02 +0600 Subject: [PATCH 6/8] Fixed changes with new MacroErrors config and how macros are rendered so it supports all macro types and also fixes up a bit of code in the umbraco.macro class. --- .../Events/MacroErrorEventArgs.cs | 4 +- .../config/umbracoSettings.config | 2 +- src/Umbraco.Web/umbraco.presentation/macro.cs | 215 +++++++----------- 3 files changed, 83 insertions(+), 138 deletions(-) diff --git a/src/Umbraco.Core/Events/MacroErrorEventArgs.cs b/src/Umbraco.Core/Events/MacroErrorEventArgs.cs index a5fbd959f1..52ac19aae2 100644 --- a/src/Umbraco.Core/Events/MacroErrorEventArgs.cs +++ b/src/Umbraco.Core/Events/MacroErrorEventArgs.cs @@ -19,9 +19,9 @@ namespace Umbraco.Core.Events public string Alias { get; set; } /// - /// Filename of the faulting macro. + /// Filename, file path, fully qualified class name, or other key used by the macro engine to do it's processing of the faulting macro. /// - public string File { get; set; } + public string ItemKey { get; set; } /// /// Exception raised. diff --git a/src/Umbraco.Web.UI/config/umbracoSettings.config b/src/Umbraco.Web.UI/config/umbracoSettings.config index 62a6e424a6..c8872d1c19 100644 --- a/src/Umbraco.Web.UI/config/umbracoSettings.config +++ b/src/Umbraco.Web.UI/config/umbracoSettings.config @@ -87,7 +87,7 @@ - throw - Throw an exception which can be caught by the global error handler defined in Application_OnError. If no such error handler is defined then you'll see the Yellow Screen Of Death (YSOD) error page. Note the error can also be handled by the umbraco.macro.Error event, where you can log/alarm with your own code and change the behaviour per event. --> - inline + inline diff --git a/src/Umbraco.Web/umbraco.presentation/macro.cs b/src/Umbraco.Web/umbraco.presentation/macro.cs index cb57e35a43..fd6bb43c45 100644 --- a/src/Umbraco.Web/umbraco.presentation/macro.cs +++ b/src/Umbraco.Web/umbraco.presentation/macro.cs @@ -373,6 +373,18 @@ namespace umbraco switch (macroType) { case (int)MacroTypes.PartialView: + + //error handler for partial views, is an action because we need to re-use it twice below + Action handleError = e => + { + LogHelper.WarnWithException("Error loading Partial View (file: " + ScriptFile + ")", true, e); + + // Invoke any error handlers for this macro + var macroErrorEventArgs = new MacroErrorEventArgs { Name = Model.Name, Alias = Model.Alias, ItemKey = Model.ScriptName, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour }; + + macroControl = RaiseAndHandleErrorForBehavior("Error loading Partial View script (file: " + ScriptFile + ")", macroErrorEventArgs); + }; + TraceInfo("umbracoMacro", "Partial View added (" + Model.TypeName + ")"); try { @@ -380,41 +392,16 @@ namespace umbraco macroControl = new LiteralControl(result.Result); if (result.ResultException != null) { - // we'll throw the error if we run in release mode, show details if we're in release mode! renderFailed = true; - if (HttpContext.Current != null && !HttpContext.Current.IsDebuggingEnabled) - throw result.ResultException; + Exceptions.Add(result.ResultException); + handleError(result.ResultException); } - break; } catch (Exception e) { renderFailed = true; Exceptions.Add(e); - - LogHelper.WarnWithException("Error loading MacroEngine script (file: " + ScriptFile + ", Type: '" + Model.TypeName + "'", - true, - e); - - var result = - new LiteralControl("Error loading MacroEngine script (file: " + ScriptFile + ")"); - - /* - string args = "
    "; - foreach(object key in attributes.Keys) - args += "
  • " + key.ToString() + ": " + attributes[key] + "
  • "; - - foreach (object key in pageElements.Keys) - args += "
  • " + key.ToString() + ": " + pageElements[key] + "
  • "; - - args += "
"; - - result.Text += args; - */ - - macroControl = result; - - break; + handleError(e); } break; @@ -432,31 +419,17 @@ namespace umbraco LogHelper.WarnWithException("Error loading userControl (" + Model.TypeName + ")", true, e); // Invoke any error handlers for this macro - var macroErrorEventArgs = new MacroErrorEventArgs {Name = Model.Name, Alias = Model.Alias, File = Model.TypeName, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour}; - OnError(macroErrorEventArgs); + var macroErrorEventArgs = new MacroErrorEventArgs {Name = Model.Name, Alias = Model.Alias, ItemKey = Model.TypeName, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour}; + + macroControl = RaiseAndHandleErrorForBehavior("Error loading userControl '" + Model.TypeName + "'", macroErrorEventArgs); - // Check how to handle the error for this macro. - // (note the error event above may have changed the default behaviour as defined in settings) - switch (macroErrorEventArgs.Behaviour) - { - case MacroErrorBehaviour.Inline: - macroControl = new LiteralControl("Error loading userControl '" + Model.TypeName + "'"); - break; - case MacroErrorBehaviour.Silent: - macroControl = new LiteralControl(""); - break; - case MacroErrorBehaviour.Throw: - throw; - } break; } case (int)MacroTypes.CustomControl: try { - TraceInfo("umbracoMacro", - "Custom control added (" + Model.TypeName + ")"); - TraceInfo("umbracoMacro", - "ScriptAssembly (" + Model.TypeAssembly + ")"); + TraceInfo("umbracoMacro", "Custom control added (" + Model.TypeName + ")"); + TraceInfo("umbracoMacro", "ScriptAssembly (" + Model.TypeAssembly + ")"); macroControl = loadControl(Model.TypeAssembly, ScriptType, Model, pageElements); break; } @@ -465,27 +438,13 @@ namespace umbraco renderFailed = true; Exceptions.Add(e); - LogHelper.WarnWithException("Error loading customControl (Assembly: " + - Model.TypeAssembly + - ", Type: '" + Model.TypeName + "'", true, e); + LogHelper.WarnWithException("Error loading customControl (Assembly: " + Model.TypeAssembly + ", Type: '" + Model.TypeName + "'", true, e); // Invoke any error handlers for this macro - var macroErrorEventArgs = new MacroErrorEventArgs {Name = Model.Name, Alias = Model.Alias, File = Model.TypeAssembly, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour}; - OnError(macroErrorEventArgs); + var macroErrorEventArgs = new MacroErrorEventArgs {Name = Model.Name, Alias = Model.Alias, ItemKey = Model.TypeAssembly, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour}; + + macroControl = RaiseAndHandleErrorForBehavior("Error loading customControl (Assembly: " + Model.TypeAssembly + ", Type: '" + Model.TypeName + "'", macroErrorEventArgs); - // Check how to handle the error for this macro. - // (note the error event above may have changed the default behaviour as defined in settings) - switch (macroErrorEventArgs.Behaviour) - { - case MacroErrorBehaviour.Inline: - macroControl = new LiteralControl("Error loading customControl (Assembly: " + Model.TypeAssembly + ", Type: '" + Model.TypeName + "'"); - break; - case MacroErrorBehaviour.Silent: - macroControl = new LiteralControl(""); - break; - case MacroErrorBehaviour.Throw: - throw; - } break; } case (int)MacroTypes.XSLT: @@ -494,8 +453,7 @@ namespace umbraco case (int)MacroTypes.Script: try { - TraceInfo("umbracoMacro", - "MacroEngine script added (" + ScriptFile + ")"); + TraceInfo("umbracoMacro", "MacroEngine script added (" + ScriptFile + ")"); ScriptingMacroResult result = loadMacroScript(Model); macroControl = new LiteralControl(result.Result); if (result.ResultException != null) @@ -512,35 +470,18 @@ namespace umbraco renderFailed = true; Exceptions.Add(e); - LogHelper.WarnWithException( - "Error loading MacroEngine script (file: " + ScriptFile + ", Type: '" + Model.TypeName + "'", - true, - e); + LogHelper.WarnWithException("Error loading MacroEngine script (file: " + ScriptFile + ", Type: '" + Model.TypeName + "'", true, e); // Invoke any error handlers for this macro - var macroErrorEventArgs = new MacroErrorEventArgs {Name = Model.Name, Alias = Model.Alias, File = ScriptFile, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour}; - OnError(macroErrorEventArgs); + var macroErrorEventArgs = new MacroErrorEventArgs {Name = Model.Name, Alias = Model.Alias, ItemKey = ScriptFile, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour}; + + macroControl = RaiseAndHandleErrorForBehavior("Error loading MacroEngine script (file: " + ScriptFile + ")", macroErrorEventArgs); - // Check how to handle the error for this macro. - // (note the error event above may have changed the default behaviour as defined in settings) - switch (macroErrorEventArgs.Behaviour) - { - case MacroErrorBehaviour.Inline: - macroControl = new LiteralControl("Error loading MacroEngine script (file: " + ScriptFile + ")"); - break; - case MacroErrorBehaviour.Silent: - macroControl = new LiteralControl(""); - break; - case MacroErrorBehaviour.Throw: - throw; - } break; } default: if (GlobalSettings.DebugMode) - macroControl = - new LiteralControl("<Macro: " + Name + " (" + ScriptAssembly + "," + ScriptType + - ")>"); + macroControl = new LiteralControl("<Macro: " + Name + " (" + ScriptAssembly + "," + ScriptType + ")>"); break; } @@ -630,6 +571,28 @@ namespace umbraco return macroControl; } + /// + /// Raises the error event and based on the error behavior either return a control to display or throw the exception + /// + /// + /// + /// + private Control RaiseAndHandleErrorForBehavior(string msg, MacroErrorEventArgs args) + { + OnError(args); + + switch (args.Behaviour) + { + case MacroErrorBehaviour.Inline: + return new LiteralControl(msg); + case MacroErrorBehaviour.Silent: + return new LiteralControl(""); + case MacroErrorBehaviour.Throw: + default: + throw args.Exception; + } + } + /// /// check that the file has not recently changed /// @@ -798,66 +761,48 @@ namespace umbraco "

" + HttpContext.Current.Server.HtmlEncode(macroXML.OuterXml) + "

"); } - else + + try { + var xsltFile = getXslt(XsltFile); + try { - XslCompiledTransform xsltFile = getXslt(XsltFile); + Control result = CreateControlsFromText(GetXsltTransformResult(macroXML, xsltFile)); - try - { - Control result = CreateControlsFromText(GetXsltTransformResult(macroXML, xsltFile)); + TraceInfo("umbracoMacro", "After performing transformation"); - TraceInfo("umbracoMacro", "After performing transformation"); - - return result; - } - catch (Exception e) - { - Exceptions.Add(e); - LogHelper.WarnWithException("Error parsing XSLT file", e); - // inner exception code by Daniel Lindstr?m from SBBS.se - Exception ie = e; - while (ie != null) - { - TraceWarn("umbracoMacro InnerException", ie.Message, ie); - ie = ie.InnerException; - } - return new LiteralControl("Error parsing XSLT file: \\xslt\\" + XsltFile); - } + return result; } catch (Exception e) { Exceptions.Add(e); - LogHelper.WarnWithException("Error loading XSLT " + Model.Xslt, true, e); - Control macroControl = null; - - // Invoke any error handlers for this macro - var macroErrorEventArgs = new MacroErrorEventArgs {Name = Model.Name, Alias = Model.Alias, File = Model.Xslt, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour}; - OnError(macroErrorEventArgs); - - // Check how to handle the error for this macro. - // (note the error event above may have changed the default behaviour as defined in settings) - switch (macroErrorEventArgs.Behaviour) + LogHelper.WarnWithException("Error parsing XSLT file", e); + // inner exception code by Daniel Lindstr?m from SBBS.se + Exception ie = e; + while (ie != null) { - case MacroErrorBehaviour.Inline: - macroControl = new LiteralControl("Error reading XSLT file: \\xslt\\" + XsltFile); - break; - case MacroErrorBehaviour.Silent: - macroControl = new LiteralControl(""); - break; - case MacroErrorBehaviour.Throw: - throw; + TraceWarn("umbracoMacro InnerException", ie.Message, ie); + ie = ie.InnerException; } - return macroControl; + + var macroErrorEventArgs = new MacroErrorEventArgs {Name = Model.Name, Alias = Model.Alias, ItemKey = Model.Xslt, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour}; + return RaiseAndHandleErrorForBehavior("Error parsing XSLT file: \\xslt\\" + XsltFile, macroErrorEventArgs); } } + catch (Exception e) + { + Exceptions.Add(e); + LogHelper.WarnWithException("Error loading XSLT " + Model.Xslt, true, e); + + // Invoke any error handlers for this macro + var macroErrorEventArgs = new MacroErrorEventArgs {Name = Model.Name, Alias = Model.Alias, ItemKey = Model.Xslt, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour}; + return RaiseAndHandleErrorForBehavior("Error reading XSLT file: \\xslt\\" + XsltFile, macroErrorEventArgs); + } } - else - { - TraceWarn("macro", "Xslt is empty"); - return new LiteralControl(string.Empty); - } + + TraceWarn("macro", "Xslt is empty"); + return new LiteralControl(string.Empty); } /// From 187af3e361567ea9ee60145162644eea148b769f Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Mon, 11 Mar 2013 21:23:35 +0600 Subject: [PATCH 7/8] Fixed merge issue --- src/Umbraco.Web/Mvc/SurfaceController.cs | 35 +----------------------- 1 file changed, 1 insertion(+), 34 deletions(-) diff --git a/src/Umbraco.Web/Mvc/SurfaceController.cs b/src/Umbraco.Web/Mvc/SurfaceController.cs index 3471b43c32..a4470e7fea 100644 --- a/src/Umbraco.Web/Mvc/SurfaceController.cs +++ b/src/Umbraco.Web/Mvc/SurfaceController.cs @@ -120,40 +120,7 @@ namespace Umbraco.Web.Mvc return new Attempt( new InvalidOperationException("Cannot find the Umbraco route definition in the route values, the request must be made in the context of an Umbraco request")); } - - /// - /// we need to recursively find the route definition based on the parent view context - /// - /// - /// - /// We may have Child Actions within Child actions so we need to recursively look this up. - /// see: http://issues.umbraco.org/issue/U4-1844 - /// - private Attempt TryGetRouteDefinitionFromAncestorViewContexts() - { - ControllerContext currentContext = ControllerContext; - while (currentContext != null) - { - var currentRouteData = currentContext.RouteData; - if (currentRouteData.DataTokens.ContainsKey("umbraco-route-def")) - { - return new Attempt(true, (RouteDefinition)currentRouteData.DataTokens["umbraco-route-def"]); - } - if (currentContext.IsChildAction) - { - //assign current context to parent - currentContext = currentContext.ParentActionViewContext; - } - else - { - //exit the loop - currentRouteData = null; - } - } - return new Attempt( - new InvalidOperationException("Cannot find the Umbraco route definition in the route values, the request must be made in the context of an Umbraco request")); - } - + } } \ No newline at end of file From 68c4255a51c5da15b5776e26cbe6a1d1f39564d1 Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Mon, 11 Mar 2013 21:49:04 +0600 Subject: [PATCH 8/8] updates proper error handling for razor script macros --- src/Umbraco.Web/umbraco.presentation/macro.cs | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/Umbraco.Web/umbraco.presentation/macro.cs b/src/Umbraco.Web/umbraco.presentation/macro.cs index fd6bb43c45..41535a5a61 100644 --- a/src/Umbraco.Web/umbraco.presentation/macro.cs +++ b/src/Umbraco.Web/umbraco.presentation/macro.cs @@ -451,6 +451,18 @@ namespace umbraco macroControl = loadMacroXSLT(this, Model, pageElements); break; case (int)MacroTypes.Script: + + //error handler for partial views, is an action because we need to re-use it twice below + Action handleMacroScriptError = e => + { + LogHelper.WarnWithException("Error loading MacroEngine script (file: " + ScriptFile + ", Type: '" + Model.TypeName + "'", true, e); + + // Invoke any error handlers for this macro + var macroErrorEventArgs = new MacroErrorEventArgs { Name = Model.Name, Alias = Model.Alias, ItemKey = ScriptFile, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour }; + + macroControl = RaiseAndHandleErrorForBehavior("Error loading MacroEngine script (file: " + ScriptFile + ")", macroErrorEventArgs); + }; + try { TraceInfo("umbracoMacro", "MacroEngine script added (" + ScriptFile + ")"); @@ -458,10 +470,9 @@ namespace umbraco macroControl = new LiteralControl(result.Result); if (result.ResultException != null) { - // we'll throw the error if we run in release mode, show details if we're in release mode! renderFailed = true; - if (HttpContext.Current != null && !HttpContext.Current.IsDebuggingEnabled) - throw result.ResultException; + Exceptions.Add(result.ResultException); + handleMacroScriptError(result.ResultException); } break; } @@ -470,12 +481,7 @@ namespace umbraco renderFailed = true; Exceptions.Add(e); - LogHelper.WarnWithException("Error loading MacroEngine script (file: " + ScriptFile + ", Type: '" + Model.TypeName + "'", true, e); - - // Invoke any error handlers for this macro - var macroErrorEventArgs = new MacroErrorEventArgs {Name = Model.Name, Alias = Model.Alias, ItemKey = ScriptFile, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour}; - - macroControl = RaiseAndHandleErrorForBehavior("Error loading MacroEngine script (file: " + ScriptFile + ")", macroErrorEventArgs); + handleMacroScriptError(e); break; }