diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs index 83148d6bdb..13812662bd 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs @@ -272,7 +272,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement if (orderBySystemField == false || orderBy.InvariantEquals(dbfield) == false) { // get alias, if aliased - var matches = VersionableRepositoryBaseAliasRegex.For(SqlContext.SqlSyntax).Matches(sql.SQL); + var matches = SqlContext.SqlSyntax.AliasRegex.Matches(sql.SQL); var match = matches.Cast().FirstOrDefault(m => m.Groups[1].Value.InvariantEquals(dbfield)); if (match != null) dbfield = match.Groups[2].Value; @@ -304,7 +304,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement // note: ContentTypeAlias is not properly managed because it's not part of the query to begin with! // get alias, if aliased - var matches = VersionableRepositoryBaseAliasRegex.For(SqlContext.SqlSyntax).Matches(sql.SQL); + var matches = SqlContext.SqlSyntax.AliasRegex.Matches(sql.SQL); var match = matches.Cast().FirstOrDefault(m => m.Groups[1].Value.InvariantEquals(dbfield)); if (match != null) dbfield = match.Groups[2].Value; diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/VersionableRepositoryBaseAliasRegex.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/VersionableRepositoryBaseAliasRegex.cs deleted file mode 100644 index fba162c5ad..0000000000 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/VersionableRepositoryBaseAliasRegex.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text.RegularExpressions; -using Umbraco.Core.Persistence.SqlSyntax; - -namespace Umbraco.Core.Persistence.Repositories.Implement -{ - internal static class VersionableRepositoryBaseAliasRegex - { - private static readonly Dictionary Regexes = new Dictionary(); - - public static Regex For(ISqlSyntaxProvider sqlSyntax) - { - var type = sqlSyntax.GetType(); - Regex aliasRegex; - if (Regexes.TryGetValue(type, out aliasRegex)) - return aliasRegex; - - var col = Regex.Escape(sqlSyntax.GetQuotedColumnName("column")).Replace("column", @"\w+"); - var fld = Regex.Escape(sqlSyntax.GetQuotedTableName("table") + ".").Replace("table", @"\w+") + col; - aliasRegex = new Regex("(" + fld + @")\s+AS\s+(" + col + ")", RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.IgnoreCase); - Regexes[type] = aliasRegex; - return aliasRegex; - } - } -} diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs index 46426cb869..d027cf44a9 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Text.RegularExpressions; using NPoco; using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.DatabaseModelDefinitions; @@ -19,17 +20,6 @@ namespace Umbraco.Core.Persistence.SqlSyntax string GetStringColumnWildcardComparison(string column, int paramIndex, TextColumnType columnType); string GetConcat(params string[] args); - [Obsolete("Use the overload with the parameter index instead")] - string GetStringColumnEqualComparison(string column, string value, TextColumnType columnType); - [Obsolete("Use the overload with the parameter index instead")] - string GetStringColumnStartsWithComparison(string column, string value, TextColumnType columnType); - [Obsolete("Use the overload with the parameter index instead")] - string GetStringColumnEndsWithComparison(string column, string value, TextColumnType columnType); - [Obsolete("Use the overload with the parameter index instead")] - string GetStringColumnContainsComparison(string column, string value, TextColumnType columnType); - [Obsolete("Use the overload with the parameter index instead")] - string GetStringColumnWildcardComparison(string column, string value, TextColumnType columnType); - string GetQuotedTableName(string tableName); string GetQuotedColumnName(string columnName); string GetQuotedName(string name); @@ -70,6 +60,14 @@ namespace Umbraco.Core.Persistence.SqlSyntax string FormatColumnRename(string tableName, string oldName, string newName); string FormatTableRename(string oldName, string newName); + /// + /// Gets a regex matching aliased fields. + /// + /// + /// Matches "(table.column) AS (alias)" where table, column and alias are properly escaped. + /// + Regex AliasRegex { get; } + Sql SelectTop(Sql sql, int top); bool SupportsClustered(); diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/MicrosoftSqlSyntaxProviderBase.cs b/src/Umbraco.Core/Persistence/SqlSyntax/MicrosoftSqlSyntaxProviderBase.cs index bb4d8269ce..be7b2cf069 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/MicrosoftSqlSyntaxProviderBase.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/MicrosoftSqlSyntaxProviderBase.cs @@ -70,66 +70,6 @@ namespace Umbraco.Core.Persistence.SqlSyntax } } - [Obsolete("Use the overload with the parameter index instead")] - public override string GetStringColumnStartsWithComparison(string column, string value, TextColumnType columnType) - { - switch (columnType) - { - case TextColumnType.NVarchar: - return base.GetStringColumnStartsWithComparison(column, value, columnType); - case TextColumnType.NText: - //MSSQL doesn't allow for upper methods with NText columns - return $"{column} LIKE '{value}%'"; - default: - throw new ArgumentOutOfRangeException(nameof(columnType)); - } - } - - [Obsolete("Use the overload with the parameter index instead")] - public override string GetStringColumnEndsWithComparison(string column, string value, TextColumnType columnType) - { - switch (columnType) - { - case TextColumnType.NVarchar: - return base.GetStringColumnEndsWithComparison(column, value, columnType); - case TextColumnType.NText: - //MSSQL doesn't allow for upper methods with NText columns - return $"{column} LIKE '%{value}'"; - default: - throw new ArgumentOutOfRangeException(nameof(columnType)); - } - } - - [Obsolete("Use the overload with the parameter index instead")] - public override string GetStringColumnContainsComparison(string column, string value, TextColumnType columnType) - { - switch (columnType) - { - case TextColumnType.NVarchar: - return base.GetStringColumnContainsComparison(column, value, columnType); - case TextColumnType.NText: - //MSSQL doesn't allow for upper methods with NText columns - return $"{column} LIKE '%{value}%'"; - default: - throw new ArgumentOutOfRangeException(nameof(columnType)); - } - } - - [Obsolete("Use the overload with the parameter index instead")] - public override string GetStringColumnWildcardComparison(string column, string value, TextColumnType columnType) - { - switch (columnType) - { - case TextColumnType.NVarchar: - return base.GetStringColumnContainsComparison(column, value, columnType); - case TextColumnType.NText: - //MSSQL doesn't allow for upper methods with NText columns - return $"{column} LIKE '{value}'"; - default: - throw new ArgumentOutOfRangeException(nameof(columnType)); - } - } - /// /// This uses a the DbTypeMap created and custom mapping to resolve the SqlDbType /// diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs index 5f58c9c53e..c41cd59f4e 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs @@ -49,21 +49,6 @@ namespace Umbraco.Core.Persistence.SqlSyntax return indexType; } - [Obsolete("Use the overload with the parameter index instead")] - public override string GetStringColumnEqualComparison(string column, string value, TextColumnType columnType) - { - switch (columnType) - { - case TextColumnType.NVarchar: - return base.GetStringColumnEqualComparison(column, value, columnType); - case TextColumnType.NText: - //MSSQL doesn't allow for = comparison with NText columns but allows this syntax - return string.Format("{0} LIKE '{1}'", column, value); - default: - throw new ArgumentOutOfRangeException("columnType"); - } - } - public override string GetConcat(params string[] args) { return "(" + string.Join("+", args) + ")"; diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs index c298955045..f8c937ce8d 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs @@ -4,6 +4,7 @@ using System.Data; using System.Globalization; using System.Linq; using System.Text; +using System.Text.RegularExpressions; using NPoco; using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.DatabaseModelDefinitions; @@ -40,8 +41,17 @@ namespace Umbraco.Core.Persistence.SqlSyntax DecimalColumnDefinition = string.Format(DecimalColumnDefinitionFormat, DefaultDecimalPrecision, DefaultDecimalScale); InitColumnTypeMap(); + + // ReSharper disable VirtualMemberCallInConstructor + // ok to call virtual GetQuotedXxxName here - they don't depend on any state + var col = Regex.Escape(GetQuotedColumnName("column")).Replace("column", @"\w+"); + var fld = Regex.Escape(GetQuotedTableName("table") + ".").Replace("table", @"\w+") + col; + // ReSharper restore VirtualMemberCallInConstructor + AliasRegex = new Regex("(" + fld + @")\s+AS\s+(" + col + ")", RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.IgnoreCase); } + public Regex AliasRegex { get; } + public string GetWildcardPlaceholder() { return "%"; @@ -137,41 +147,6 @@ namespace Umbraco.Core.Persistence.SqlSyntax return $"upper({column}) LIKE upper(@{paramIndex})"; } - [Obsolete("Use the overload with the parameter index instead")] - public virtual string GetStringColumnEqualComparison(string column, string value, TextColumnType columnType) - { - //use the 'upper' method to always ensure strings are matched without case sensitivity no matter what the db setting. - return $"upper({column}) = '{value.ToUpper()}'"; - } - - [Obsolete("Use the overload with the parameter index instead")] - public virtual string GetStringColumnStartsWithComparison(string column, string value, TextColumnType columnType) - { - //use the 'upper' method to always ensure strings are matched without case sensitivity no matter what the db setting. - return $"upper({column}) LIKE '{value.ToUpper()}%'"; - } - - [Obsolete("Use the overload with the parameter index instead")] - public virtual string GetStringColumnEndsWithComparison(string column, string value, TextColumnType columnType) - { - //use the 'upper' method to always ensure strings are matched without case sensitivity no matter what the db setting. - return $"upper({column}) LIKE '%{value.ToUpper()}'"; - } - - [Obsolete("Use the overload with the parameter index instead")] - public virtual string GetStringColumnContainsComparison(string column, string value, TextColumnType columnType) - { - //use the 'upper' method to always ensure strings are matched without case sensitivity no matter what the db setting. - return $"upper({column}) LIKE '%{value.ToUpper()}%'"; - } - - [Obsolete("Use the overload with the parameter index instead")] - public virtual string GetStringColumnWildcardComparison(string column, string value, TextColumnType columnType) - { - //use the 'upper' method to always ensure strings are matched without case sensitivity no matter what the db setting. - return $"upper({column}) LIKE '{value.ToUpper()}'"; - } - public virtual string GetConcat(params string[] args) { return "concat(" + string.Join(",", args) + ")"; diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index afe3dc9c38..4c2dd2df3f 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -1206,7 +1206,6 @@ - diff --git a/src/Umbraco.Tests/Persistence/Repositories/ContentRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/ContentRepositoryTest.cs index 17232d89ef..29de77e6d8 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/ContentRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/ContentRepositoryTest.cs @@ -667,9 +667,9 @@ namespace Umbraco.Tests.Persistence.Repositories } [Test] - public void RegexAliasTest() + public void AliasRegexTest() { - var regex = VersionableRepositoryBaseAliasRegex.For(new SqlServerSyntaxProvider(new Lazy(() => null))); + var regex = new SqlServerSyntaxProvider(new Lazy(() => null)).AliasRegex; Assert.AreEqual(@"(\[\w+]\.\[\w+])\s+AS\s+(\[\w+])", regex.ToString()); const string sql = "SELECT [table].[column1] AS [alias1], [table].[column2] AS [alias2] FROM [table];"; var matches = regex.Matches(sql);