diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings.cs b/src/Umbraco.Core/Configuration/UmbracoSettings.cs index ebb2e971da..1ca199f8a7 100644 --- a/src/Umbraco.Core/Configuration/UmbracoSettings.cs +++ b/src/Umbraco.Core/Configuration/UmbracoSettings.cs @@ -1222,6 +1222,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/CoreBootManager.cs b/src/Umbraco.Core/CoreBootManager.cs index 29e0b72246..b0007866de 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; @@ -68,18 +67,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; @@ -184,6 +182,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/Events/MacroErrorEventArgs.cs b/src/Umbraco.Core/Events/MacroErrorEventArgs.cs new file mode 100644 index 0000000000..52ac19aae2 --- /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, 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 ItemKey { 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/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/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 4aa5ee7ec4..0ea5e7589d 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs @@ -103,7 +103,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); @@ -120,7 +120,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 @@ -137,11 +137,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 3b77d23450..c70eb820b8 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaResult.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaResult.cs @@ -114,7 +114,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 4a9548d1c7..edf36f90f8 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; @@ -503,6 +504,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/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 1ef57cd631..7c1302648f 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -147,8 +147,10 @@ + + @@ -476,8 +478,10 @@ + - + + diff --git a/src/Umbraco.Tests/BootManagers/CoreBootManagerTests.cs b/src/Umbraco.Tests/BootManagers/CoreBootManagerTests.cs index d792e4b2c0..7b2f8d3dd8 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 @@ -28,6 +29,7 @@ namespace Umbraco.Tests.BootManagers _testApp = null; ApplicationEventsResolver.Reset(); + SqlSyntaxProvidersResolver.Reset(); } /// @@ -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 a882b4767a..b958dba401 100644 --- a/src/Umbraco.Tests/Migrations/FindingMigrationsTest.cs +++ b/src/Umbraco.Tests/Migrations/FindingMigrationsTest.cs @@ -31,7 +31,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 52ade91e10..8aad190fea 100644 --- a/src/Umbraco.Tests/Migrations/TargetVersionSixthMigrationsTest.cs +++ b/src/Umbraco.Tests/Migrations/TargetVersionSixthMigrationsTest.cs @@ -38,7 +38,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 7fc567b007..b496560287 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(); TestHelper.CleanContentDirectories(); diff --git a/src/Umbraco.Tests/Migrations/Upgrades/ValidateOlderSchemaTest.cs b/src/Umbraco.Tests/Migrations/Upgrades/ValidateOlderSchemaTest.cs index adf08bd884..3dcc1a5308 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.Reset(); TestHelper.CleanContentDirectories(); diff --git a/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs b/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs index a2be51720b..c54a9dffee 100644 --- a/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs +++ b/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs @@ -72,7 +72,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 d7d5a3515d..0bb3bf3444 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 = new ContentMapper().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 = new ContentMapper().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 = new ContentMapper().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 = new ContentMapper().Map("Version"); diff --git a/src/Umbraco.Tests/Persistence/Mappers/ContentTypeMapperTest.cs b/src/Umbraco.Tests/Persistence/Mappers/ContentTypeMapperTest.cs index 7a9bd82030..b86eec2a95 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 = new ContentTypeMapper().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 = new ContentTypeMapper().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 = new ContentTypeMapper().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 = new ContentTypeMapper().Map("Description"); diff --git a/src/Umbraco.Tests/Persistence/Mappers/DataTypeDefinitionMapperTest.cs b/src/Umbraco.Tests/Persistence/Mappers/DataTypeDefinitionMapperTest.cs index 9836c7e8e1..54da940208 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 = new DataTypeDefinitionMapper().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 = new DataTypeDefinitionMapper().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 = new DataTypeDefinitionMapper().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 = new DataTypeDefinitionMapper().Map("ControlId"); diff --git a/src/Umbraco.Tests/Persistence/Mappers/DictionaryMapperTest.cs b/src/Umbraco.Tests/Persistence/Mappers/DictionaryMapperTest.cs index 59743c22d7..f62957493e 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 = new DictionaryMapper().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 = new DictionaryMapper().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 = new DictionaryMapper().Map("ItemKey"); diff --git a/src/Umbraco.Tests/Persistence/Mappers/DictionaryTranslationMapperTest.cs b/src/Umbraco.Tests/Persistence/Mappers/DictionaryTranslationMapperTest.cs index 03c9aec4ba..906eef79be 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 = new DictionaryTranslationMapper().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 = new DictionaryTranslationMapper().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 = new DictionaryTranslationMapper().Map("Value"); diff --git a/src/Umbraco.Tests/Persistence/Mappers/LanguageMapperTest.cs b/src/Umbraco.Tests/Persistence/Mappers/LanguageMapperTest.cs index 84dc7d883f..6fa2df4720 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 = new LanguageMapper().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 = new LanguageMapper().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 = new LanguageMapper().Map("CultureName"); diff --git a/src/Umbraco.Tests/Persistence/Mappers/MediaMapperTest.cs b/src/Umbraco.Tests/Persistence/Mappers/MediaMapperTest.cs index 71609eb9dd..485df588ca 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 = new MediaMapper().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 = new MediaMapper().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 = new MediaMapper().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 = new MediaMapper().Map("Version"); diff --git a/src/Umbraco.Tests/Persistence/Mappers/PropertyGroupMapperTest.cs b/src/Umbraco.Tests/Persistence/Mappers/PropertyGroupMapperTest.cs index b3d27b8e65..52f6b0b058 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 = new PropertyGroupMapper().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 = new PropertyGroupMapper().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 = new PropertyGroupMapper().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 = new PropertyGroupMapper().Map("Name"); diff --git a/src/Umbraco.Tests/Persistence/Mappers/PropertyTypeMapperTest.cs b/src/Umbraco.Tests/Persistence/Mappers/PropertyTypeMapperTest.cs index 06ed3044ad..3d4a88d4d5 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 = new PropertyTypeMapper().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 = new PropertyTypeMapper().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 = new PropertyTypeMapper().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 = new PropertyTypeMapper().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 = new PropertyTypeMapper().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 = new PropertyTypeMapper().Map("DataTypeDatabaseType"); diff --git a/src/Umbraco.Tests/Persistence/Mappers/RelationMapperTest.cs b/src/Umbraco.Tests/Persistence/Mappers/RelationMapperTest.cs index ce0cbf1325..d7191e0936 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 = new RelationMapper().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 = new RelationMapper().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 = new RelationMapper().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 = new RelationMapper().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 = new RelationMapper().Map("RelationTypeId"); diff --git a/src/Umbraco.Tests/Persistence/Mappers/RelationTypeMapperTest.cs b/src/Umbraco.Tests/Persistence/Mappers/RelationTypeMapperTest.cs index 06c5ccdab4..9860cfeb0f 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 = new RelationTypeMapper().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 = new RelationTypeMapper().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 = new RelationTypeMapper().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 = new RelationTypeMapper().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 6f38e05e88..bb91263d57 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 fe324bc33c..74f09897d1 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 b8525c4222..dad49ea54d 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 8176d340ab..67f769bc34 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"); @@ -106,14 +111,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; RepositoryResolver.Reset(); + SqlSyntaxProvidersResolver.Reset(); Resolution.Reset(); TestHelper.CleanContentDirectories(); diff --git a/src/Umbraco.Tests/TestHelpers/BaseDatabaseTest.cs b/src/Umbraco.Tests/TestHelpers/BaseDatabaseTest.cs index 2289c13ddf..0870862cc1 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; @@ -55,6 +56,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 @@ -62,7 +66,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/Web.Debug.config.transformed b/src/Umbraco.Web.UI/Web.Debug.config.transformed new file mode 100644 index 0000000000..22653b7bcc --- /dev/null +++ b/src/Umbraco.Web.UI/Web.Debug.config.transformed @@ -0,0 +1,274 @@ + + + +
+
+ +
+ +
+
+
+
+
+
+ +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Umbraco.Web.UI/bin.zip b/src/Umbraco.Web.UI/bin.zip new file mode 100644 index 0000000000..fe6fdc2309 Binary files /dev/null and b/src/Umbraco.Web.UI/bin.zip differ diff --git a/src/Umbraco.Web.UI/config/umbracoSettings.Release.config b/src/Umbraco.Web.UI/config/umbracoSettings.Release.config index d3eb0e2477..bdb473c0b0 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 e1e02de465..ec5d8aed9d 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.UI/fonts/museo/museo.css b/src/Umbraco.Web.UI/fonts/museo/museo.css new file mode 100644 index 0000000000..f3d025d612 --- /dev/null +++ b/src/Umbraco.Web.UI/fonts/museo/museo.css @@ -0,0 +1,20 @@ +/* Generated by Font Squirrel (http://www.fontsquirrel.com) on November 13, 2010 */ + + + +@font-face { + font-family: 'Museo700'; + src: url('museo700-regular-webfont.eot'); + src: url('museo700-regular-webfont.woff') format('woff'), url('museo700-regular-webfont.ttf') format('truetype'),url('museo700-regular-webfont.svgz#webfont2nqRdrT9') format('svg'), url('museo700-regular-webfont.svg#webfont2nqRdrT9') format('svg'); + font-weight: normal; + font-style: normal; +} + +@font-face { + font-family: 'Museo300'; + src: url('museo300-regular-webfont.eot'); + src: url('museo300-regular-webfont.woff') format('woff'), url('museo300-regular-webfont.svgz#webfontMsAuFuwO') format('svg'), url('museo300-regular-webfont.svg#webfontMsAuFuwO') format('svg'); + font-weight: normal; + font-style: normal; +} + diff --git a/src/Umbraco.Web.UI/fonts/museo/museo300-regular-webfont.eot b/src/Umbraco.Web.UI/fonts/museo/museo300-regular-webfont.eot new file mode 100644 index 0000000000..743780a9b3 Binary files /dev/null and b/src/Umbraco.Web.UI/fonts/museo/museo300-regular-webfont.eot differ diff --git a/src/Umbraco.Web.UI/fonts/museo/museo300-regular-webfont.svg b/src/Umbraco.Web.UI/fonts/museo/museo300-regular-webfont.svg new file mode 100644 index 0000000000..31072e68ff --- /dev/null +++ b/src/Umbraco.Web.UI/fonts/museo/museo300-regular-webfont.svg @@ -0,0 +1,253 @@ + + + + +This is a custom SVG webfont generated by Font Squirrel. +Copyright : Copyright c 2008 by Jos Buivengaexljbris All rights reserved +Designer : Jos Buivenga +Foundry : Jos Buivenga +Foundry URL : httpwwwjosbuivengademonnl + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Umbraco.Web.UI/fonts/museo/museo300-regular-webfont.svgz b/src/Umbraco.Web.UI/fonts/museo/museo300-regular-webfont.svgz new file mode 100644 index 0000000000..5487f553f0 Binary files /dev/null and b/src/Umbraco.Web.UI/fonts/museo/museo300-regular-webfont.svgz differ diff --git a/src/Umbraco.Web.UI/fonts/museo/museo300-regular-webfont.ttf b/src/Umbraco.Web.UI/fonts/museo/museo300-regular-webfont.ttf new file mode 100644 index 0000000000..9074ccd0c2 Binary files /dev/null and b/src/Umbraco.Web.UI/fonts/museo/museo300-regular-webfont.ttf differ diff --git a/src/Umbraco.Web.UI/fonts/museo/museo300-regular-webfont.woff b/src/Umbraco.Web.UI/fonts/museo/museo300-regular-webfont.woff new file mode 100644 index 0000000000..2f8b2da12d Binary files /dev/null and b/src/Umbraco.Web.UI/fonts/museo/museo300-regular-webfont.woff differ diff --git a/src/Umbraco.Web.UI/fonts/museo/museo700-regular-webfont.eot b/src/Umbraco.Web.UI/fonts/museo/museo700-regular-webfont.eot new file mode 100644 index 0000000000..5244d9c2a8 Binary files /dev/null and b/src/Umbraco.Web.UI/fonts/museo/museo700-regular-webfont.eot differ diff --git a/src/Umbraco.Web.UI/fonts/museo/museo700-regular-webfont.svg b/src/Umbraco.Web.UI/fonts/museo/museo700-regular-webfont.svg new file mode 100644 index 0000000000..cf8245e031 --- /dev/null +++ b/src/Umbraco.Web.UI/fonts/museo/museo700-regular-webfont.svg @@ -0,0 +1,253 @@ + + + + +This is a custom SVG webfont generated by Font Squirrel. +Copyright : Copyright c 2008 by Jos Buivengaexljbris All rights reserved +Designer : Jos Buivenga +Foundry : Jos Buivenga +Foundry URL : httpwwwjosbuivengademonnl + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Umbraco.Web.UI/fonts/museo/museo700-regular-webfont.svgz b/src/Umbraco.Web.UI/fonts/museo/museo700-regular-webfont.svgz new file mode 100644 index 0000000000..d09aca8535 Binary files /dev/null and b/src/Umbraco.Web.UI/fonts/museo/museo700-regular-webfont.svgz differ diff --git a/src/Umbraco.Web.UI/fonts/museo/museo700-regular-webfont.ttf b/src/Umbraco.Web.UI/fonts/museo/museo700-regular-webfont.ttf new file mode 100644 index 0000000000..beb4426491 Binary files /dev/null and b/src/Umbraco.Web.UI/fonts/museo/museo700-regular-webfont.ttf differ diff --git a/src/Umbraco.Web.UI/fonts/museo/museo700-regular-webfont.woff b/src/Umbraco.Web.UI/fonts/museo/museo700-regular-webfont.woff new file mode 100644 index 0000000000..2a58318708 Binary files /dev/null and b/src/Umbraco.Web.UI/fonts/museo/museo700-regular-webfont.woff differ diff --git a/src/Umbraco.Web.UI/usercontrols/Blog/AjaxCommentForm.ascx b/src/Umbraco.Web.UI/usercontrols/Blog/AjaxCommentForm.ascx new file mode 100644 index 0000000000..f2318ca9a4 --- /dev/null +++ b/src/Umbraco.Web.UI/usercontrols/Blog/AjaxCommentForm.ascx @@ -0,0 +1,108 @@ +<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="AjaxCommentForm.ascx.cs" Inherits="Runway.Blog.usercontrols.AjaxCommentForm" %> + + + +

+ <%= CommentsClosedMessage %> +

+
+ + +
+ + +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ " /> +
+
+ + + + + + + +
\ No newline at end of file diff --git a/src/Umbraco.Web.UI/usercontrols/Blog/BlogInstaller.ascx b/src/Umbraco.Web.UI/usercontrols/Blog/BlogInstaller.ascx new file mode 100644 index 0000000000..a2a92bd769 --- /dev/null +++ b/src/Umbraco.Web.UI/usercontrols/Blog/BlogInstaller.ascx @@ -0,0 +1,42 @@ +<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="BlogInstaller.ascx.cs" Inherits="Runway.Blog.usercontrols.BlogInstaller" %> +<%@ Register Namespace="umbraco.uicontrols" Assembly="controls" TagPrefix="umb" %> + + +

+ Installation complete! you can now go to the content section and start blogging directly from the dashboard. +

+ +

+ Or you can view your blog +

+
+ + + + +

+ Runway Blog has been installed +

+
    +
  • Document types and templates have been added
  • +
  • Macros and xslt-files have been setup
  • +
  • A test blog has been created
  • +
+

+ All you need to do now is give it a name and a description, and you can start blogging right away. +

+
+ + + + + + + + + + + + + +
\ No newline at end of file diff --git a/src/Umbraco.Web.UI/usercontrols/Blog/CommentModeration.ascx b/src/Umbraco.Web.UI/usercontrols/Blog/CommentModeration.ascx new file mode 100644 index 0000000000..6ed0e6ba8f --- /dev/null +++ b/src/Umbraco.Web.UI/usercontrols/Blog/CommentModeration.ascx @@ -0,0 +1,147 @@ +<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="CommentModeration.ascx.cs" Inherits="Runway.Blog.Dashboard.CommentModeration" %> +<%@ Register Assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" + Namespace="System.Web.UI" TagPrefix="asp" %> +<%@ Register Namespace="umbraco.uicontrols" Assembly="controls" TagPrefix="umb" %> + + + + + + + + + + + +
+ +
+Delete Selected +
+ +Approved | +Spam | +All + + +
+ +
+ + +
+ + + + +
+ Delete + | +
+ +
+ +
+ +
+

+ + + +

+ avatar +
+ <%# Server.HtmlEncode(Eval("name").ToString()) %> +
+ <%# Server.HtmlEncode( Eval("website").ToString()) %> | <%# Server.HtmlEncode(Eval("email").ToString()) %> +

+

+ <%# Server.HtmlEncode(Eval("comment").ToString()).Replace("\n","
") %> +

+

+ On <%# GetPageDetails(Eval("nodeid")) %> , <%# Eval("created") %> +

+
+ + + +
+ +
+
+
+
+ + + + + <%# Container.DataItem %> + + + + + +
+
+
+ +
+
\ No newline at end of file diff --git a/src/Umbraco.Web.UI/usercontrols/MemberPicker.ascx b/src/Umbraco.Web.UI/usercontrols/MemberPicker.ascx new file mode 100644 index 0000000000..c73e17174e --- /dev/null +++ b/src/Umbraco.Web.UI/usercontrols/MemberPicker.ascx @@ -0,0 +1,14 @@ +<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="MemberPicker.ascx.cs" Inherits="Training.Level2.usercontrols.MemberPicker" %> + + + + \ No newline at end of file diff --git a/src/Umbraco.Web.UI/usercontrols/Parallel.ascx b/src/Umbraco.Web.UI/usercontrols/Parallel.ascx new file mode 100644 index 0000000000..795df2c126 --- /dev/null +++ b/src/Umbraco.Web.UI/usercontrols/Parallel.ascx @@ -0,0 +1,2 @@ +<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="Parallel.ascx.cs" Inherits="Umbraco.Web.UI.usercontrols.ParallelUserControl" %> + \ No newline at end of file diff --git a/src/Umbraco.Web.UI/usercontrols/Parallel.ascx.cs b/src/Umbraco.Web.UI/usercontrols/Parallel.ascx.cs new file mode 100644 index 0000000000..ea3a38f605 --- /dev/null +++ b/src/Umbraco.Web.UI/usercontrols/Parallel.ascx.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.UI; +using System.Web.UI.WebControls; +using umbraco.cms.businesslogic.web; +using umbraco.BusinessLogic; + +namespace Umbraco.Web.UI.usercontrols +{ + public partial class ParallelUserControl : System.Web.UI.UserControl + { + protected void Page_Load(object sender, EventArgs e) + { + + } + + protected void Button1_Click(object sender, EventArgs e) + { + ParallelDocumentUpdate test = new ParallelDocumentUpdate(); + test.Execute(); + + } + } + + public class ParallelDocumentUpdate + { + private List documents; + public ParallelDocumentUpdate() + { + documents = new List(); + + documents.Add(new myDocument(1079, "name1", "string1", 1, false, DateTime.Now.AddDays(1))); + documents.Add(new myDocument(1080, "name2", "string2", 2, true, DateTime.Now.AddDays(2))); + documents.Add(new myDocument(1082, "name3", "string3", 3, false, DateTime.Now.AddDays(3))); + documents.Add(new myDocument(1083, "name4", "string4", 4, true, DateTime.Now.AddDays(4))); + documents.Add(new myDocument(1084, "name5", "string5", 5, true, DateTime.Now.AddDays(4))); + + } + + public void Execute() + { + + System.Threading.Tasks.Parallel.ForEach(documents, d => + { + Document doc = new Document(d.Id); + doc.Text = d.Name + " " + d.Id.ToString(); + doc.getProperty("string").Value = d.Prop1 + " " + d.Id.ToString(); + doc.getProperty("int").Value = d.Prop2; + doc.getProperty("bool").Value = d.Prop3; + doc.getProperty("date").Value = d.Prop4; + doc.Publish(User.GetUser(0)); + }); + + } + } + + public class myDocument + { + public myDocument(int id, string name, string prop1, int prop2, bool prop3, DateTime prop4) + { + Id = id; + Name = name; + Prop1 = prop1; + Prop2 = prop2; + Prop3 = prop3; + Prop4 = prop4; + } + + public int Id { get; set; } + public string Name { get; set; } + public string Prop1 { get; set; } + public int Prop2 { get; set; } + public bool Prop3 { get; set; } + public DateTime Prop4 { get; set; } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web.UI/usercontrols/Parallel.ascx.designer.cs b/src/Umbraco.Web.UI/usercontrols/Parallel.ascx.designer.cs new file mode 100644 index 0000000000..334046ec2c --- /dev/null +++ b/src/Umbraco.Web.UI/usercontrols/Parallel.ascx.designer.cs @@ -0,0 +1,24 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Umbraco.Web.UI.usercontrols { + + + public partial class ParallelUserControl { + + /// + /// Button1 control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Button Button1; + } +} diff --git a/src/Umbraco.Web.UI/usercontrols/RunwayContactForm/Contact.ascx b/src/Umbraco.Web.UI/usercontrols/RunwayContactForm/Contact.ascx new file mode 100644 index 0000000000..3816d939d0 --- /dev/null +++ b/src/Umbraco.Web.UI/usercontrols/RunwayContactForm/Contact.ascx @@ -0,0 +1,21 @@ +<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="Contact.ascx.cs" Inherits="UmbracoShop.Controls.Contact" %> + + + +
+Your details +

+

+

+
+
+Message +

+

Email send

+
+ + + + + + diff --git a/src/Umbraco.Web/Macros/PartialViewMacroController.cs b/src/Umbraco.Web/Macros/PartialViewMacroController.cs index 913a79e61e..765846c5c5 100644 --- a/src/Umbraco.Web/Macros/PartialViewMacroController.cs +++ b/src/Umbraco.Web/Macros/PartialViewMacroController.cs @@ -7,37 +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(), + 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); - } + _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 595c94bebb..be0d4dc332 100644 --- a/src/Umbraco.Web/Macros/PartialViewMacroEngine.cs +++ b/src/Umbraco.Web/Macros/PartialViewMacroEngine.cs @@ -17,48 +17,48 @@ 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 @@ -77,45 +77,45 @@ namespace Umbraco.Web.Macros { get { return Enumerable.Empty(); } } - 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"); + 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"); - 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) @@ -131,44 +131,44 @@ namespace Umbraco.Web.Macros routeVals.DataTokens.Add("ParentActionViewContext", viewContext); } - var request = new RequestContext(http, routeVals); - string output; - using (var controller = new PartialViewMacroController(umbCtx, macro, currentPage)) - { + 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(); + 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 2cf95cca95..8f5c11b044 100644 --- a/src/Umbraco.Web/Macros/PartialViewMacroPage.cs +++ b/src/Umbraco.Web/Macros/PartialViewMacroPage.cs @@ -5,11 +5,11 @@ 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(); @@ -24,5 +24,5 @@ namespace Umbraco.Web.Macros /// 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 b21b7cdb81..0a3129d876 100644 --- a/src/Umbraco.Web/Models/PartialViewMacroModel.cs +++ b/src/Umbraco.Web/Models/PartialViewMacroModel.cs @@ -5,16 +5,16 @@ 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, - int macroId, - string macroAlias, - string macroName, + public PartialViewMacroModel(IPublishedContent page, + int macroId, + string macroAlias, + string macroName, IDictionary macroParams) { Content = page; @@ -26,11 +26,11 @@ namespace Umbraco.Web.Models [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use the constructor accepting the macro id instead")] - public PartialViewMacroModel(IPublishedContent page, IDictionary macroParams) - { + public PartialViewMacroModel(IPublishedContent page, IDictionary macroParams) + { Content = page; - MacroParameters = macroParams; - } + MacroParameters = macroParams; + } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use the Content property instead")] @@ -43,7 +43,7 @@ namespace Umbraco.Web.Models public string MacroName { get; private set; } public string MacroAlias { get; private set; } public int MacroId { get; private set; } - public IDictionary MacroParameters { 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 4151c412f4..e175ef2ea8 100644 --- a/src/Umbraco.Web/Mvc/Constants.cs +++ b/src/Umbraco.Web/Mvc/Constants.cs @@ -3,10 +3,10 @@ namespace Umbraco.Web.Mvc /// /// constants /// - internal static class 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 b26ed39b79..0e383add83 100644 --- a/src/Umbraco.Web/Mvc/ControllerExtensions.cs +++ b/src/Umbraco.Web/Mvc/ControllerExtensions.cs @@ -97,58 +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) - { + /// + /// 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 b222eb8a39..a4470e7fea 100644 --- a/src/Umbraco.Web/Mvc/SurfaceController.cs +++ b/src/Umbraco.Web/Mvc/SurfaceController.cs @@ -8,75 +8,75 @@ 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 - { + /// + /// Gets the current page. + /// + protected IPublishedContent CurrentPage + { + get + { var routeDefAttempt = TryGetRouteDefinitionFromAncestorViewContexts(); if (!routeDefAttempt.Success) { @@ -84,9 +84,9 @@ namespace Umbraco.Web.Mvc } var routeDef = routeDefAttempt.Result; - return routeDef.PublishedContentRequest.PublishedContent; - } - } + return routeDef.PublishedContentRequest.PublishedContent; + } + } /// /// we need to recursively find the route definition based on the parent view context @@ -120,7 +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")); } + - - } + } } \ No newline at end of file diff --git a/src/Umbraco.Web/Mvc/UmbracoViewPage.cs b/src/Umbraco.Web/Mvc/UmbracoViewPage.cs index 92a46a9858..ba936ee9ee 100644 --- a/src/Umbraco.Web/Mvc/UmbracoViewPage.cs +++ b/src/Umbraco.Web/Mvc/UmbracoViewPage.cs @@ -4,94 +4,94 @@ 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 @@ -112,5 +112,5 @@ namespace Umbraco.Web.Mvc } - } + } } \ No newline at end of file diff --git a/src/Umbraco.Web/umbraco.presentation/content.cs b/src/Umbraco.Web/umbraco.presentation/content.cs index 9ce77c173c..819b70725b 100644 --- a/src/Umbraco.Web/umbraco.presentation/content.cs +++ b/src/Umbraco.Web/umbraco.presentation/content.cs @@ -1099,8 +1099,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) diff --git a/src/Umbraco.Web/umbraco.presentation/macro.cs b/src/Umbraco.Web/umbraco.presentation/macro.cs index 6d08688590..cb97423082 100644 --- a/src/Umbraco.Web/umbraco.presentation/macro.cs +++ b/src/Umbraco.Web/umbraco.presentation/macro.cs @@ -16,19 +16,19 @@ 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; -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; @@ -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; @@ -434,17 +421,20 @@ 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, ItemKey = Model.TypeName, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour}; + + macroControl = RaiseAndHandleErrorForBehavior("Error loading userControl '" + Model.TypeName + "'", macroErrorEventArgs); + 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; } @@ -453,32 +443,41 @@ namespace umbraco renderFailed = true; Exceptions.Add(e); - 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 + "'"); + 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, ItemKey = Model.TypeAssembly, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour}; + + macroControl = RaiseAndHandleErrorForBehavior("Error loading customControl (Assembly: " + Model.TypeAssembly + ", Type: '" + Model.TypeName + "'", macroErrorEventArgs); + break; } case (int)MacroTypes.XSLT: 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 + ")"); + TraceInfo("umbracoMacro", "MacroEngine script added (" + ScriptFile + ")"); ScriptingMacroResult result = loadMacroScript(Model); 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; } @@ -487,36 +486,13 @@ namespace umbraco 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; + handleMacroScriptError(e); break; } default: if (GlobalSettings.DebugMode) - macroControl = - new LiteralControl("<Macro: " + Name + " (" + ScriptAssembly + "," + ScriptType + - ")>"); + macroControl = new LiteralControl("<Macro: " + Name + " (" + ScriptAssembly + "," + ScriptType + ")>"); break; } @@ -606,6 +582,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 /// @@ -774,47 +772,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); - return new LiteralControl("Error reading XSLT file: \\xslt\\" + XsltFile); + 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; + } + + 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); } /// @@ -1502,7 +1501,7 @@ namespace umbraco string userControlPath = IOHelper.FindFile(fileName); 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); @@ -1528,11 +1527,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; } } @@ -1799,5 +1794,26 @@ namespace umbraco value = false; return false; } + + #region Events + + /// + /// Occurs when a macro error is raised. + /// + public static event EventHandler Error; + + /// + /// Raises the event. + /// + /// The instance containing the event data. + protected 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..09836a8101 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,6 @@ namespace umbraco.cms.businesslogic { { public bool CancelChildren { get; set; } } + }