From ef4246478d7ea9b3c3ac9fe0288e2a089649bec4 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 18 Dec 2013 15:30:40 +1100 Subject: [PATCH 1/4] Fixes: U4-2294 6.1.0: umbracoServer table can't be created on MySQL <5.6.5 --- src/Umbraco.Core/Models/Rdbms/ServerRegistrationDto.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Umbraco.Core/Models/Rdbms/ServerRegistrationDto.cs b/src/Umbraco.Core/Models/Rdbms/ServerRegistrationDto.cs index e9c79ae57e..9833d9ab74 100644 --- a/src/Umbraco.Core/Models/Rdbms/ServerRegistrationDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/ServerRegistrationDto.cs @@ -30,7 +30,6 @@ namespace Umbraco.Core.Models.Rdbms public DateTime DateRegistered { get; set; } [Column("lastNotifiedDate")] - [Constraint(Default = "getdate()")] public DateTime LastNotified { get; set; } [Column("isActive")] From a21aa079ff0c746bd8679088acea0d2900789222 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 18 Dec 2013 17:22:00 +1100 Subject: [PATCH 2/4] Adds ability to use the query builder with string matches based on an NText column --- .../Persistence/PetaPocoExtensions.cs | 14 ++-- .../Querying/BaseExpressionHelper.cs | 8 +- .../Querying/ModelToSqlExpressionHelper.cs | 60 +++++++++++++- .../Querying/SqlStringExtensions.cs | 30 +++++++ .../Persistence/Querying/TextColumnType.cs | 8 ++ .../SqlSyntax/ISqlSyntaxProvider.cs | 6 ++ .../Persistence/SqlSyntax/MySqlSyntax.cs | 10 +++ .../SqlSyntax/MySqlSyntaxProvider.cs | 8 -- .../Persistence/SqlSyntax/SqlCeSyntax.cs | 10 +++ .../SqlSyntax/SqlCeSyntaxProvider.cs | 65 +++++++++++++-- .../Persistence/SqlSyntax/SqlServerSyntax.cs | 10 +++ .../SqlSyntax/SqlServerSyntaxProvider.cs | 79 +++++++++++++------ .../SqlSyntax/SqlServerVersionName.cs | 16 ++++ .../SqlSyntax/SqlSyntaxProviderBase.cs | 25 ++++++ src/Umbraco.Core/StringExtensions.cs | 5 ++ src/Umbraco.Core/Umbraco.Core.csproj | 6 ++ 16 files changed, 307 insertions(+), 53 deletions(-) create mode 100644 src/Umbraco.Core/Persistence/Querying/SqlStringExtensions.cs create mode 100644 src/Umbraco.Core/Persistence/Querying/TextColumnType.cs create mode 100644 src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntax.cs create mode 100644 src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntax.cs create mode 100644 src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntax.cs create mode 100644 src/Umbraco.Core/Persistence/SqlSyntax/SqlServerVersionName.cs diff --git a/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs b/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs index 7ae81aaa16..cf3fd1511f 100644 --- a/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs +++ b/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs @@ -21,14 +21,18 @@ namespace Umbraco.Core.Persistence /// /// This will escape single @ symbols for peta poco values so it doesn't think it's a parameter /// - /// /// /// - public static string EscapeAtSymbols(this Database db, string value) + public static string EscapeAtSymbols(string value) { - //this fancy regex will only match a single @ not a double, etc... - var regex = new Regex("(?(this Database db) diff --git a/src/Umbraco.Core/Persistence/Querying/BaseExpressionHelper.cs b/src/Umbraco.Core/Persistence/Querying/BaseExpressionHelper.cs index ac84b5cee3..73fa98b275 100644 --- a/src/Umbraco.Core/Persistence/Querying/BaseExpressionHelper.cs +++ b/src/Umbraco.Core/Persistence/Querying/BaseExpressionHelper.cs @@ -64,13 +64,7 @@ namespace Umbraco.Core.Persistence.Querying public virtual string EscapeAtArgument(string exp) { - /*if (exp.StartsWith("@")) - return string.Concat("@", exp);*/ - - if (exp.Contains("@")) - return exp.Replace("@", "@@"); - - return exp; + return PetaPocoExtensions.EscapeAtSymbols(exp); } public virtual bool ShouldQuoteValue(Type fieldType) diff --git a/src/Umbraco.Core/Persistence/Querying/ModelToSqlExpressionHelper.cs b/src/Umbraco.Core/Persistence/Querying/ModelToSqlExpressionHelper.cs index 738cc8a23c..611d9c63a3 100644 --- a/src/Umbraco.Core/Persistence/Querying/ModelToSqlExpressionHelper.cs +++ b/src/Umbraco.Core/Persistence/Querying/ModelToSqlExpressionHelper.cs @@ -2,9 +2,11 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Globalization; +using System.Linq; using System.Linq.Expressions; using System.Text; using Umbraco.Core.Persistence.Mappers; +using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Querying { @@ -226,6 +228,39 @@ namespace Umbraco.Core.Persistence.Querying } + private string HandleStringComparison(string col, string val, string verb, TextColumnType columnType) + { + switch (verb) + { + case "Equals": + return SqlSyntaxContext.SqlSyntaxProvider.GetStringColumnEqualComparison(col, EscapeAtArgument(RemoveQuote(val)), columnType); + case "StartsWith": + return SqlSyntaxContext.SqlSyntaxProvider.GetStringColumnStartsWithComparison(col, EscapeAtArgument(RemoveQuote(val)), columnType); + case "EndsWith": + return SqlSyntaxContext.SqlSyntaxProvider.GetStringColumnEndsWithComparison(col, EscapeAtArgument(RemoveQuote(val)), columnType); + case "Contains": + return SqlSyntaxContext.SqlSyntaxProvider.GetStringColumnContainsComparison(col, EscapeAtArgument(RemoveQuote(val)), columnType); + case "InvariantEquals": + case "SqlEquals": + //recurse + return HandleStringComparison(col, val, "Equals", columnType); + case "InvariantStartsWith": + case "SqlStartsWith": + //recurse + return HandleStringComparison(col, val, "StartsWith", columnType); + case "InvariantEndsWith": + case "SqlEndsWith": + //recurse + return HandleStringComparison(col, val, "EndsWith", columnType); + case "InvariantContains": + case "SqlContains": + //recurse + return HandleStringComparison(col, val, "Contains", columnType); + default: + throw new ArgumentOutOfRangeException("verb"); + } + } + protected virtual string VisitMethodCall(MethodCallExpression m) { List args = this.VisitExpressionList(m.Arguments); @@ -245,12 +280,31 @@ namespace Umbraco.Core.Persistence.Querying return string.Format("upper({0})", r); case "ToLower": return string.Format("lower({0})", r); + case "StartsWith": - return string.Format("upper({0}) like '{1}%'", r, EscapeAtArgument(RemoveQuote(args[0].ToString().ToUpper()))); case "EndsWith": - return string.Format("upper({0}) like '%{1}'", r, EscapeAtArgument(RemoveQuote(args[0].ToString()).ToUpper())); case "Contains": - return string.Format("{0} like '%{1}%'", r, EscapeAtArgument(RemoveQuote(args[0].ToString()).ToUpper())); + case "Equals": + case "SqlStartsWith": + case "SqlEndsWith": + case "SqlContains": + case "SqlEquals": + case "InvariantStartsWith": + case "InvariantEndsWith": + case "InvariantContains": + case "InvariantEquals": + //default + var colType = TextColumnType.NVarchar; + //then check if this arg has been passed in + if (m.Arguments.Count > 1) + { + var colTypeArg = m.Arguments.FirstOrDefault(x => x is ConstantExpression && x.Type == typeof(TextColumnType)); + if (colTypeArg != null) + { + colType = (TextColumnType) ((ConstantExpression) colTypeArg).Value; + } + } + return HandleStringComparison(r.ToString(), args[0].ToString(), m.Method.Name, colType); case "Substring": var startIndex = Int32.Parse(args[0].ToString()) + 1; if (args.Count == 2) diff --git a/src/Umbraco.Core/Persistence/Querying/SqlStringExtensions.cs b/src/Umbraco.Core/Persistence/Querying/SqlStringExtensions.cs new file mode 100644 index 0000000000..82c158a9c6 --- /dev/null +++ b/src/Umbraco.Core/Persistence/Querying/SqlStringExtensions.cs @@ -0,0 +1,30 @@ +using System; + +namespace Umbraco.Core.Persistence.Querying +{ + /// + /// String extension methods used specifically to translate into SQL + /// + internal static class SqlStringExtensions + { + public static bool SqlContains(this string str, string txt, TextColumnType columnType) + { + return str.InvariantContains(txt); + } + + public static bool SqlEquals(this string str, string txt, TextColumnType columnType) + { + return str.InvariantEquals(txt); + } + + public static bool SqlStartsWith(this string str, string txt, TextColumnType columnType) + { + return str.InvariantStartsWith(txt); + } + + public static bool SqlEndsWith(this string str, string txt, TextColumnType columnType) + { + return str.InvariantEndsWith(txt); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Querying/TextColumnType.cs b/src/Umbraco.Core/Persistence/Querying/TextColumnType.cs new file mode 100644 index 0000000000..f33022fcbe --- /dev/null +++ b/src/Umbraco.Core/Persistence/Querying/TextColumnType.cs @@ -0,0 +1,8 @@ +namespace Umbraco.Core.Persistence.Querying +{ + public enum TextColumnType + { + NVarchar, + NText + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs index e2a13d1fef..9fbf0456b6 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/ISqlSyntaxProvider.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.DatabaseModelDefinitions; +using Umbraco.Core.Persistence.Querying; namespace Umbraco.Core.Persistence.SqlSyntax { @@ -10,6 +11,11 @@ namespace Umbraco.Core.Persistence.SqlSyntax /// public interface ISqlSyntaxProvider { + string GetStringColumnEqualComparison(string column, string value, TextColumnType columnType); + string GetStringColumnStartsWithComparison(string column, string value, TextColumnType columnType); + string GetStringColumnEndsWithComparison(string column, string value, TextColumnType columnType); + string GetStringColumnContainsComparison(string column, string value, TextColumnType columnType); + string GetQuotedTableName(string tableName); string GetQuotedColumnName(string columnName); string GetQuotedName(string name); diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntax.cs b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntax.cs new file mode 100644 index 0000000000..00b07ae15a --- /dev/null +++ b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntax.cs @@ -0,0 +1,10 @@ +namespace Umbraco.Core.Persistence.SqlSyntax +{ + /// + /// Static class that provides simple access to the MySql SqlSyntax Provider + /// + internal static class MySqlSyntax + { + public static ISqlSyntaxProvider Provider { get { return new MySqlSyntaxProvider(); } } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs index 8f466e3829..5f5d412ab3 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs @@ -6,14 +6,6 @@ using Umbraco.Core.Persistence.DatabaseModelDefinitions; namespace Umbraco.Core.Persistence.SqlSyntax { - /// - /// Static class that provides simple access to the MySql SqlSyntax Provider - /// - internal static class MySqlSyntax - { - public static ISqlSyntaxProvider Provider { get { return new MySqlSyntaxProvider(); } } - } - /// /// Represents an SqlSyntaxProvider for MySql /// diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntax.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntax.cs new file mode 100644 index 0000000000..29660355fe --- /dev/null +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntax.cs @@ -0,0 +1,10 @@ +namespace Umbraco.Core.Persistence.SqlSyntax +{ + /// + /// Static class that provides simple access to the Sql CE SqlSyntax Provider + /// + internal static class SqlCeSyntax + { + public static ISqlSyntaxProvider Provider { get { return new SqlCeSyntaxProvider(); } } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs index 106b45ffed..d908f5c9b6 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlCeSyntaxProvider.cs @@ -3,17 +3,10 @@ using System.Collections.Generic; using System.Linq; using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.DatabaseModelDefinitions; +using Umbraco.Core.Persistence.Querying; namespace Umbraco.Core.Persistence.SqlSyntax { - /// - /// Static class that provides simple access to the Sql CE SqlSyntax Provider - /// - internal static class SqlCeSyntax - { - public static ISqlSyntaxProvider Provider { get { return new SqlCeSyntaxProvider(); } } - } - /// /// Represents an SqlSyntaxProvider for Sql Ce /// @@ -67,6 +60,62 @@ namespace Umbraco.Core.Persistence.SqlSyntax return indexType; } + 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 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 string.Format("{0} LIKE '{1}%'", column, value); + default: + throw new ArgumentOutOfRangeException("columnType"); + } + } + + 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 string.Format("{0} LIKE '%{1}'", column, value); + default: + throw new ArgumentOutOfRangeException("columnType"); + } + } + + 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 string.Format("{0} LIKE '%{1}%'", column, value); + default: + throw new ArgumentOutOfRangeException("columnType"); + } + } + public override string GetQuotedTableName(string tableName) { return string.Format("[{0}]", tableName); diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntax.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntax.cs new file mode 100644 index 0000000000..a2f000e4b8 --- /dev/null +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntax.cs @@ -0,0 +1,10 @@ +namespace Umbraco.Core.Persistence.SqlSyntax +{ + /// + /// Static class that provides simple access to the Sql Server SqlSyntax Provider + /// + internal static class SqlServerSyntax + { + public static ISqlSyntaxProvider Provider { get { return new SqlServerSyntaxProvider(); } } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs index 3e37674ddf..24177c61d5 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs @@ -2,31 +2,10 @@ using System.Collections.Generic; using System.Linq; using Umbraco.Core.Persistence.DatabaseModelDefinitions; +using Umbraco.Core.Persistence.Querying; namespace Umbraco.Core.Persistence.SqlSyntax { - /// - /// Static class that provides simple access to the Sql Server SqlSyntax Provider - /// - internal static class SqlServerSyntax - { - public static ISqlSyntaxProvider Provider { get { return new SqlServerSyntaxProvider(); } } - } - - /// - /// Represents the version name of SQL server (i.e. the year 2008, 2005, etc...) - /// - internal enum SqlServerVersionName - { - Invalid = -1, - V7 = 0, - V2000 = 1, - V2005 = 2, - V2008 = 3, - V2012 = 4, - Other = 5 - } - /// /// Represents an SqlSyntaxProvider for Sql Server /// @@ -55,6 +34,62 @@ namespace Umbraco.Core.Persistence.SqlSyntax /// internal Lazy VersionName { get; set; } + 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 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 string.Format("{0} LIKE '{1}%'", column, value); + default: + throw new ArgumentOutOfRangeException("columnType"); + } + } + + 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 string.Format("{0} LIKE '%{1}'", column, value); + default: + throw new ArgumentOutOfRangeException("columnType"); + } + } + + 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 string.Format("{0} LIKE '%{1}%'", column, value); + default: + throw new ArgumentOutOfRangeException("columnType"); + } + } + public override string GetQuotedTableName(string tableName) { return string.Format("[{0}]", tableName); diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerVersionName.cs b/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerVersionName.cs new file mode 100644 index 0000000000..37870a9536 --- /dev/null +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlServerVersionName.cs @@ -0,0 +1,16 @@ +namespace Umbraco.Core.Persistence.SqlSyntax +{ + /// + /// Represents the version name of SQL server (i.e. the year 2008, 2005, etc...) + /// + internal enum SqlServerVersionName + { + Invalid = -1, + V7 = 0, + V2000 = 1, + V2005 = 2, + V2008 = 3, + V2012 = 4, + Other = 5 + } +} \ 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 e86222ac50..8505d1e553 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/SqlSyntaxProviderBase.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Text; using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.DatabaseModelDefinitions; +using Umbraco.Core.Persistence.Querying; namespace Umbraco.Core.Persistence.SqlSyntax { @@ -102,6 +103,30 @@ namespace Umbraco.Core.Persistence.SqlSyntax DbTypeMap.Set(DbType.Binary, BlobColumnDefinition); } + 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 string.Format("upper({0}) = '{1}'", column, value.ToUpper()); + } + + 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 string.Format("upper({0}) like '{1}%'", column, value.ToUpper()); + } + + 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 string.Format("upper({0}) like '%{1}'", column, value.ToUpper()); + } + + 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 string.Format("upper({0}) like '%{1}%'", column, value.ToUpper()); + } + public virtual string GetQuotedTableName(string tableName) { return string.Format("\"{0}\"", tableName); diff --git a/src/Umbraco.Core/StringExtensions.cs b/src/Umbraco.Core/StringExtensions.cs index 1832e6906b..d14dbc7c6b 100644 --- a/src/Umbraco.Core/StringExtensions.cs +++ b/src/Umbraco.Core/StringExtensions.cs @@ -465,6 +465,11 @@ namespace Umbraco.Core return compare.StartsWith(compareTo, StringComparison.InvariantCultureIgnoreCase); } + public static bool InvariantEndsWith(this string compare, string compareTo) + { + return compare.EndsWith(compareTo, StringComparison.InvariantCultureIgnoreCase); + } + public static bool InvariantContains(this string compare, string compareTo) { return compare.IndexOf(compareTo, StringComparison.OrdinalIgnoreCase) >= 0; diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 0ce3f0bf9a..48e9d5c5be 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -200,6 +200,12 @@ + + + + + + From fec55e9d1c45f64b64e1509677b692e9b4968dc9 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 18 Dec 2013 17:37:46 +1100 Subject: [PATCH 3/4] Updates IMemberService with methods to search on string properties with an option to define how to match the string property, adds all supporting unit tests. --- .../Querying/StringPropertyMatchType.cs | 13 + .../Repositories/MemberRepository.cs | 2 +- src/Umbraco.Core/Services/IMemberService.cs | 24 +- src/Umbraco.Core/Services/MediaService.cs | 41 +-- src/Umbraco.Core/Services/MemberService.cs | 135 ++++++++- src/Umbraco.Core/Umbraco.Core.csproj | 1 + .../Services/MemberServiceTests.cs | 258 ++++++++++++++++++ 7 files changed, 439 insertions(+), 35 deletions(-) create mode 100644 src/Umbraco.Core/Persistence/Querying/StringPropertyMatchType.cs diff --git a/src/Umbraco.Core/Persistence/Querying/StringPropertyMatchType.cs b/src/Umbraco.Core/Persistence/Querying/StringPropertyMatchType.cs new file mode 100644 index 0000000000..f4245b931a --- /dev/null +++ b/src/Umbraco.Core/Persistence/Querying/StringPropertyMatchType.cs @@ -0,0 +1,13 @@ +namespace Umbraco.Core.Persistence.Querying +{ + /// + /// Determines how to match a string property value + /// + public enum StringPropertyMatchType + { + Exact, + Contains, + StartsWith, + EndsWith + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs index 723645b89c..ba28e68f02 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs @@ -440,7 +440,7 @@ namespace Umbraco.Core.Persistence.Repositories public bool Exists(string username) { var sql = new Sql(); - var escapedUserName = Database.EscapeAtSymbols(username); + var escapedUserName = PetaPocoExtensions.EscapeAtSymbols(username); sql.Select("COUNT(*)") .From() .Where(x => x.LoginName == escapedUserName); diff --git a/src/Umbraco.Core/Services/IMemberService.cs b/src/Umbraco.Core/Services/IMemberService.cs index ff758236a4..bd6544dc29 100644 --- a/src/Umbraco.Core/Services/IMemberService.cs +++ b/src/Umbraco.Core/Services/IMemberService.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Umbraco.Core.Models; +using Umbraco.Core.Persistence.Querying; namespace Umbraco.Core.Services { @@ -22,10 +23,13 @@ namespace Umbraco.Core.Services IEnumerable GetMembersByMemberType(int memberTypeId); IEnumerable GetMembersByGroup(string memberGroupName); IEnumerable GetAllMembers(params int[] ids); - - //TODO: Need to get all members that start with a certain letter - + void DeleteMembersOfType(int memberTypeId); + + IEnumerable GetMembersByPropertyValue(string propertyTypeAlias, string value, StringPropertyMatchType matchType = StringPropertyMatchType.Exact); + IEnumerable GetMembersByPropertyValue(string propertyTypeAlias, int value); + IEnumerable GetMembersByPropertyValue(string propertyTypeAlias, bool value); + IEnumerable GetMembersByPropertyValue(string propertyTypeAlias, DateTime value); } /// @@ -43,6 +47,14 @@ namespace Umbraco.Core.Services /// bool Exists(string username); + /// + /// Creates and persists a new member + /// + /// + /// + /// + /// + /// IMember CreateMember(string username, string email, string password, string memberTypeAlias); IMember GetById(object id); @@ -55,6 +67,10 @@ namespace Umbraco.Core.Services void Save(IMember membershipUser, bool raiseEvents = true); - IEnumerable FindMembersByEmail(string emailStringToMatch); + void Save(IEnumerable members, bool raiseEvents = true); + + IEnumerable FindMembersByEmail(string emailStringToMatch, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith); + + IEnumerable FindMembersByUsername(string login, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith); } } \ No newline at end of file diff --git a/src/Umbraco.Core/Services/MediaService.cs b/src/Umbraco.Core/Services/MediaService.cs index 4fe58904a2..fefb70d4cb 100644 --- a/src/Umbraco.Core/Services/MediaService.cs +++ b/src/Umbraco.Core/Services/MediaService.cs @@ -760,30 +760,31 @@ namespace Umbraco.Core.Services if (Saving.IsRaisedEventCancelled(new SaveEventArgs(medias), this)) return; } + using (new WriteLock(Locker)) + { + var uow = _uowProvider.GetUnitOfWork(); + using (var repository = _repositoryFactory.CreateMediaRepository(uow)) + { + foreach (var media in medias) + { + media.CreatorId = userId; + repository.AddOrUpdate(media); + } - var mediaXml = new Dictionary>(); - var uow = _uowProvider.GetUnitOfWork(); - using (var repository = _repositoryFactory.CreateMediaRepository(uow)) - { - foreach (var media in medias) - { - media.CreatorId = userId; - repository.AddOrUpdate(media); - } + //commit the whole lot in one go + uow.Commit(); - //commit the whole lot in one go - uow.Commit(); + foreach (var media in medias) + { + CreateAndSaveMediaXml(media.ToXml(), media.Id, uow.Database); + } + } - foreach (var media in medias) - { - CreateAndSaveMediaXml(media.ToXml(), media.Id, uow.Database); - } - } + if (raiseEvents) + Saved.RaiseEvent(new SaveEventArgs(medias, false), this); - if(raiseEvents) - Saved.RaiseEvent(new SaveEventArgs(medias, false), this); - - Audit.Add(AuditTypes.Save, "Save Media items performed by user", userId, -1); + Audit.Add(AuditTypes.Save, "Save Media items performed by user", userId, -1); + } } /// diff --git a/src/Umbraco.Core/Services/MemberService.cs b/src/Umbraco.Core/Services/MemberService.cs index 803bfabd31..0f4cd7c242 100644 --- a/src/Umbraco.Core/Services/MemberService.cs +++ b/src/Umbraco.Core/Services/MemberService.cs @@ -183,16 +183,61 @@ namespace Umbraco.Core.Services /// Does a search for members that contain the specified string in their email address /// /// + /// /// - public IEnumerable FindMembersByEmail(string emailStringToMatch) + public IEnumerable FindMembersByEmail(string emailStringToMatch, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith) { var uow = _uowProvider.GetUnitOfWork(); using (var repository = _repositoryFactory.CreateMemberRepository(uow)) { var query = new Query(); + switch (matchType) + { + case StringPropertyMatchType.Exact: + query.Where(member => member.Email.Equals(emailStringToMatch)); + break; + case StringPropertyMatchType.Contains: + query.Where(member => member.Email.Contains(emailStringToMatch)); + break; + case StringPropertyMatchType.StartsWith: + query.Where(member => member.Email.StartsWith(emailStringToMatch)); + break; + case StringPropertyMatchType.EndsWith: + query.Where(member => member.Email.EndsWith(emailStringToMatch)); + break; + default: + throw new ArgumentOutOfRangeException("matchType"); + } - query.Where(member => member.Email.Contains(emailStringToMatch)); + return repository.GetByQuery(query); + } + } + + public IEnumerable FindMembersByUsername(string login, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith) + { + var uow = _uowProvider.GetUnitOfWork(); + using (var repository = _repositoryFactory.CreateMemberRepository(uow)) + { + var query = new Query(); + + switch (matchType) + { + case StringPropertyMatchType.Exact: + query.Where(member => member.Username.Equals(login)); + break; + case StringPropertyMatchType.Contains: + query.Where(member => member.Username.Contains(login)); + break; + case StringPropertyMatchType.StartsWith: + query.Where(member => member.Username.StartsWith(login)); + break; + case StringPropertyMatchType.EndsWith: + query.Where(member => member.Username.EndsWith(login)); + break; + default: + throw new ArgumentOutOfRangeException("matchType"); + } return repository.GetByQuery(query); } @@ -203,17 +248,51 @@ namespace Umbraco.Core.Services /// /// /// + /// /// - public IEnumerable GetMembersByPropertyValue(string propertyTypeAlias, string value) + public IEnumerable GetMembersByPropertyValue(string propertyTypeAlias, string value, StringPropertyMatchType matchType = StringPropertyMatchType.Exact) { using (var repository = _repositoryFactory.CreateMemberRepository(_uowProvider.GetUnitOfWork())) { - var query = - Query.Builder.Where( - x => - ((Member)x).PropertyTypeAlias == propertyTypeAlias && - (((Member)x).LongStringPropertyValue.Contains(value) || - ((Member)x).ShortStringPropertyValue.Contains(value))); + IQuery query; + + switch (matchType) + { + case StringPropertyMatchType.Exact: + query = + Query.Builder.Where( + x => + ((Member) x).PropertyTypeAlias == propertyTypeAlias && + (((Member)x).LongStringPropertyValue.SqlEquals(value, TextColumnType.NText) || + ((Member)x).ShortStringPropertyValue.SqlEquals(value, TextColumnType.NVarchar))); + break; + case StringPropertyMatchType.Contains: + query = + Query.Builder.Where( + x => + ((Member) x).PropertyTypeAlias == propertyTypeAlias && + (((Member)x).LongStringPropertyValue.SqlContains(value, TextColumnType.NText) || + ((Member)x).ShortStringPropertyValue.SqlContains(value, TextColumnType.NVarchar))); + break; + case StringPropertyMatchType.StartsWith: + query = + Query.Builder.Where( + x => + ((Member) x).PropertyTypeAlias == propertyTypeAlias && + (((Member)x).LongStringPropertyValue.SqlStartsWith(value, TextColumnType.NText) || + ((Member)x).ShortStringPropertyValue.SqlStartsWith(value, TextColumnType.NVarchar))); + break; + case StringPropertyMatchType.EndsWith: + query = + Query.Builder.Where( + x => + ((Member) x).PropertyTypeAlias == propertyTypeAlias && + (((Member)x).LongStringPropertyValue.SqlEndsWith(value, TextColumnType.NText) || + ((Member)x).ShortStringPropertyValue.SqlEndsWith(value, TextColumnType.NVarchar))); + break; + default: + throw new ArgumentOutOfRangeException("matchType"); + } var members = repository.GetByQuery(query); return members; @@ -352,7 +431,7 @@ namespace Umbraco.Core.Services { using (var repository = _repositoryFactory.CreateMemberRepository(_uowProvider.GetUnitOfWork())) { - var query = Query.Builder.Where(x => x.Email == email); + var query = Query.Builder.Where(x => x.Email.Equals(email)); var member = repository.GetByQuery(query).FirstOrDefault(); return member; @@ -381,12 +460,17 @@ namespace Umbraco.Core.Services /// public void Delete(IMember member) { + if (Deleting.IsRaisedEventCancelled(new DeleteEventArgs(member), this)) + return; + var uow = _uowProvider.GetUnitOfWork(); using (var repository = _repositoryFactory.CreateMemberRepository(uow)) { repository.Delete(member); uow.Commit(); } + + Deleted.RaiseEvent(new DeleteEventArgs(member, false), this); } /// @@ -416,6 +500,37 @@ namespace Umbraco.Core.Services Saved.RaiseEvent(new SaveEventArgs(member, false), this); } + public void Save(IEnumerable members, bool raiseEvents = true) + { + if (raiseEvents) + { + if (Saving.IsRaisedEventCancelled(new SaveEventArgs(members), this)) + return; + } + using (new WriteLock(Locker)) + { + var uow = _uowProvider.GetUnitOfWork(); + using (var repository = _repositoryFactory.CreateMemberRepository(uow)) + { + foreach (var member in members) + { + repository.AddOrUpdate(member); + } + + //commit the whole lot in one go + uow.Commit(); + + foreach (var member in members) + { + CreateAndSaveMemberXml(member.ToXml(), member.Id, uow.Database); + } + } + + if (raiseEvents) + Saved.RaiseEvent(new SaveEventArgs(members, false), this); + } + } + #endregion /// diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 48e9d5c5be..7d400f5abc 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -201,6 +201,7 @@ + diff --git a/src/Umbraco.Tests/Services/MemberServiceTests.cs b/src/Umbraco.Tests/Services/MemberServiceTests.cs index 7ddbe972ec..54fa355ce5 100644 --- a/src/Umbraco.Tests/Services/MemberServiceTests.cs +++ b/src/Umbraco.Tests/Services/MemberServiceTests.cs @@ -1,6 +1,9 @@ +using System.Linq; using NUnit.Framework; using Umbraco.Core.Models; using Umbraco.Core.Models.Rdbms; +using Umbraco.Core.Persistence.Querying; +using Umbraco.Core.Services; using Umbraco.Tests.TestHelpers.Entities; namespace Umbraco.Tests.Services @@ -46,5 +49,260 @@ namespace Umbraco.Tests.Services var xml = DatabaseContext.Database.FirstOrDefault("WHERE nodeId = @Id", new { Id = member.Id }); Assert.IsNotNull(xml); } + + [Test] + public void Exists_By_Username() + { + IMemberType memberType = MockedContentTypes.CreateSimpleMemberType(); + ServiceContext.MemberTypeService.Save(memberType); + IMember member = MockedMember.CreateSimpleMember(memberType, "test", "test@test.com", "pass", "test"); + ServiceContext.MemberService.Save(member); + + Assert.IsTrue(ServiceContext.MemberService.Exists("test")); + Assert.IsFalse(ServiceContext.MemberService.Exists("notFound")); + } + + [Test] + public void Exists_By_Id() + { + IMemberType memberType = MockedContentTypes.CreateSimpleMemberType(); + ServiceContext.MemberTypeService.Save(memberType); + IMember member = MockedMember.CreateSimpleMember(memberType, "test", "test@test.com", "pass", "test"); + ServiceContext.MemberService.Save(member); + + Assert.IsTrue(ServiceContext.MemberService.Exists(member.Id)); + Assert.IsFalse(ServiceContext.MemberService.Exists(9876)); + } + + [Test] + public void Get_By_Email() + { + IMemberType memberType = MockedContentTypes.CreateSimpleMemberType(); + ServiceContext.MemberTypeService.Save(memberType); + IMember member = MockedMember.CreateSimpleMember(memberType, "test", "test@test.com", "pass", "test"); + ServiceContext.MemberService.Save(member); + + Assert.IsNotNull(ServiceContext.MemberService.GetByEmail(member.Email)); + Assert.IsNull(ServiceContext.MemberService.GetByEmail("do@not.find")); + } + + [Test] + public void Get_By_Username() + { + IMemberType memberType = MockedContentTypes.CreateSimpleMemberType(); + ServiceContext.MemberTypeService.Save(memberType); + IMember member = MockedMember.CreateSimpleMember(memberType, "test", "test@test.com", "pass", "test"); + ServiceContext.MemberService.Save(member); + + Assert.IsNotNull(ServiceContext.MemberService.GetByUsername(member.Username)); + Assert.IsNull(ServiceContext.MemberService.GetByUsername("notFound")); + } + + [Test] + public void Get_By_Object_Id() + { + IMemberType memberType = MockedContentTypes.CreateSimpleMemberType(); + ServiceContext.MemberTypeService.Save(memberType); + IMember member = MockedMember.CreateSimpleMember(memberType, "test", "test@test.com", "pass", "test"); + ServiceContext.MemberService.Save(member); + + Assert.IsNotNull(ServiceContext.MemberService.GetById((object)member.Id)); + Assert.IsNull(ServiceContext.MemberService.GetById((object)9876)); + } + + [Test] + public void Find_By_Email_Starts_With() + { + IMemberType memberType = MockedContentTypes.CreateSimpleMemberType(); + ServiceContext.MemberTypeService.Save(memberType); + var members = MockedMember.CreateSimpleMember(memberType, 10); + ServiceContext.MemberService.Save(members); + //don't find this + var customMember = MockedMember.CreateSimpleMember(memberType, "hello", "hello@test.com", "hello","hello"); + ServiceContext.MemberService.Save(customMember); + + var found = ServiceContext.MemberService.FindMembersByEmail("tes", StringPropertyMatchType.StartsWith); + + Assert.AreEqual(10, found.Count()); + } + + [Test] + public void Find_By_Email_Ends_With() + { + IMemberType memberType = MockedContentTypes.CreateSimpleMemberType(); + ServiceContext.MemberTypeService.Save(memberType); + var members = MockedMember.CreateSimpleMember(memberType, 10); + ServiceContext.MemberService.Save(members); + //include this + var customMember = MockedMember.CreateSimpleMember(memberType, "hello", "hello@test.com", "hello", "hello"); + ServiceContext.MemberService.Save(customMember); + + var found = ServiceContext.MemberService.FindMembersByEmail("test.com", StringPropertyMatchType.EndsWith); + + Assert.AreEqual(11, found.Count()); + } + + [Test] + public void Find_By_Email_Contains() + { + IMemberType memberType = MockedContentTypes.CreateSimpleMemberType(); + ServiceContext.MemberTypeService.Save(memberType); + var members = MockedMember.CreateSimpleMember(memberType, 10); + ServiceContext.MemberService.Save(members); + //include this + var customMember = MockedMember.CreateSimpleMember(memberType, "hello", "hello@test.com", "hello", "hello"); + ServiceContext.MemberService.Save(customMember); + + var found = ServiceContext.MemberService.FindMembersByEmail("test", StringPropertyMatchType.Contains); + + Assert.AreEqual(11, found.Count()); + } + + [Test] + public void Find_By_Email_Exact() + { + IMemberType memberType = MockedContentTypes.CreateSimpleMemberType(); + ServiceContext.MemberTypeService.Save(memberType); + var members = MockedMember.CreateSimpleMember(memberType, 10); + ServiceContext.MemberService.Save(members); + //include this + var customMember = MockedMember.CreateSimpleMember(memberType, "hello", "hello@test.com", "hello", "hello"); + ServiceContext.MemberService.Save(customMember); + + var found = ServiceContext.MemberService.FindMembersByEmail("hello@test.com", StringPropertyMatchType.Exact); + + Assert.AreEqual(1, found.Count()); + } + + [Test] + public void Find_By_Login_Starts_With() + { + IMemberType memberType = MockedContentTypes.CreateSimpleMemberType(); + ServiceContext.MemberTypeService.Save(memberType); + var members = MockedMember.CreateSimpleMember(memberType, 10); + ServiceContext.MemberService.Save(members); + //don't find this + var customMember = MockedMember.CreateSimpleMember(memberType, "hello", "hello@test.com", "hello", "hello"); + ServiceContext.MemberService.Save(customMember); + + var found = ServiceContext.MemberService.FindMembersByUsername("tes", StringPropertyMatchType.StartsWith); + + Assert.AreEqual(10, found.Count()); + } + + [Test] + public void Find_By_Login_Ends_With() + { + IMemberType memberType = MockedContentTypes.CreateSimpleMemberType(); + ServiceContext.MemberTypeService.Save(memberType); + var members = MockedMember.CreateSimpleMember(memberType, 10); + ServiceContext.MemberService.Save(members); + //include this + var customMember = MockedMember.CreateSimpleMember(memberType, "hello", "hello@test.com", "hello", "hello"); + ServiceContext.MemberService.Save(customMember); + + var found = ServiceContext.MemberService.FindMembersByUsername("llo", StringPropertyMatchType.EndsWith); + + Assert.AreEqual(1, found.Count()); + } + + [Test] + public void Find_By_Login_Contains() + { + IMemberType memberType = MockedContentTypes.CreateSimpleMemberType(); + ServiceContext.MemberTypeService.Save(memberType); + var members = MockedMember.CreateSimpleMember(memberType, 10); + ServiceContext.MemberService.Save(members); + //include this + var customMember = MockedMember.CreateSimpleMember(memberType, "hello", "hello@test.com", "hello", "hellotest"); + ServiceContext.MemberService.Save(customMember); + + var found = ServiceContext.MemberService.FindMembersByUsername("test", StringPropertyMatchType.Contains); + + Assert.AreEqual(11, found.Count()); + } + + [Test] + public void Find_By_Login_Exact() + { + IMemberType memberType = MockedContentTypes.CreateSimpleMemberType(); + ServiceContext.MemberTypeService.Save(memberType); + var members = MockedMember.CreateSimpleMember(memberType, 10); + ServiceContext.MemberService.Save(members); + //include this + var customMember = MockedMember.CreateSimpleMember(memberType, "hello", "hello@test.com", "hello", "hello"); + ServiceContext.MemberService.Save(customMember); + + var found = ServiceContext.MemberService.FindMembersByUsername("hello", StringPropertyMatchType.Exact); + + Assert.AreEqual(1, found.Count()); + } + + [Test] + public void Get_By_Property_Value_Exact() + { + IMemberType memberType = MockedContentTypes.CreateSimpleMemberType(); + ServiceContext.MemberTypeService.Save(memberType); + var members = MockedMember.CreateSimpleMember(memberType, 10); + ServiceContext.MemberService.Save(members); + var customMember = MockedMember.CreateSimpleMember(memberType, "hello", "hello@test.com", "hello", "hello"); + ServiceContext.MemberService.Save(customMember); + + var found = ServiceContext.MemberService.GetMembersByPropertyValue( + "title", "hello member", StringPropertyMatchType.Exact); + + Assert.AreEqual(1, found.Count()); + } + + [Test] + public void Get_By_Property_Value_Contains() + { + IMemberType memberType = MockedContentTypes.CreateSimpleMemberType(); + ServiceContext.MemberTypeService.Save(memberType); + var members = MockedMember.CreateSimpleMember(memberType, 10); + ServiceContext.MemberService.Save(members); + var customMember = MockedMember.CreateSimpleMember(memberType, "hello", "hello@test.com", "hello", "hello"); + ServiceContext.MemberService.Save(customMember); + + var found = ServiceContext.MemberService.GetMembersByPropertyValue( + "title", " member", StringPropertyMatchType.Contains); + + Assert.AreEqual(11, found.Count()); + } + + [Test] + public void Get_By_Property_Value_Starts_With() + { + IMemberType memberType = MockedContentTypes.CreateSimpleMemberType(); + ServiceContext.MemberTypeService.Save(memberType); + var members = MockedMember.CreateSimpleMember(memberType, 10); + ServiceContext.MemberService.Save(members); + var customMember = MockedMember.CreateSimpleMember(memberType, "hello", "hello@test.com", "hello", "hello"); + ServiceContext.MemberService.Save(customMember); + + var found = ServiceContext.MemberService.GetMembersByPropertyValue( + "title", "Member No", StringPropertyMatchType.StartsWith); + + Assert.AreEqual(10, found.Count()); + } + + [Test] + public void Get_By_Property_Value_Ends_With() + { + IMemberType memberType = MockedContentTypes.CreateSimpleMemberType(); + ServiceContext.MemberTypeService.Save(memberType); + var members = MockedMember.CreateSimpleMember(memberType, 10); + ServiceContext.MemberService.Save(members); + var customMember = MockedMember.CreateSimpleMember(memberType, "hello", "hello@test.com", "hello", "hello"); + customMember.SetValue("title", "title of mine"); + ServiceContext.MemberService.Save(customMember); + + var found = ServiceContext.MemberService.GetMembersByPropertyValue( + "title", "mine", StringPropertyMatchType.EndsWith); + + Assert.AreEqual(1, found.Count()); + } + + } } \ No newline at end of file From 4ab32dd270f77f09d27e9d87a376c62516fbdcca Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 18 Dec 2013 18:09:54 +1100 Subject: [PATCH 4/4] moves classes into sep files --- src/Umbraco.Core/Services/IMemberService.cs | 42 ---------------- .../Services/IMembershipMemberService.cs | 48 +++++++++++++++++++ src/Umbraco.Core/Umbraco.Core.csproj | 1 + 3 files changed, 49 insertions(+), 42 deletions(-) create mode 100644 src/Umbraco.Core/Services/IMembershipMemberService.cs diff --git a/src/Umbraco.Core/Services/IMemberService.cs b/src/Umbraco.Core/Services/IMemberService.cs index bd6544dc29..0be5211532 100644 --- a/src/Umbraco.Core/Services/IMemberService.cs +++ b/src/Umbraco.Core/Services/IMemberService.cs @@ -31,46 +31,4 @@ namespace Umbraco.Core.Services IEnumerable GetMembersByPropertyValue(string propertyTypeAlias, bool value); IEnumerable GetMembersByPropertyValue(string propertyTypeAlias, DateTime value); } - - /// - /// Defines part of the MemberService, which is specific to methods used by the membership provider. - /// - /// - /// Idea is to have this is an isolated interface so that it can be easily 'replaced' in the membership provider impl. - /// - internal interface IMembershipMemberService : IService - { - /// - /// Checks if a member with the username exists - /// - /// - /// - bool Exists(string username); - - /// - /// Creates and persists a new member - /// - /// - /// - /// - /// - /// - IMember CreateMember(string username, string email, string password, string memberTypeAlias); - - IMember GetById(object id); - - IMember GetByEmail(string email); - - IMember GetByUsername(string login); - - void Delete(IMember membershipUser); - - void Save(IMember membershipUser, bool raiseEvents = true); - - void Save(IEnumerable members, bool raiseEvents = true); - - IEnumerable FindMembersByEmail(string emailStringToMatch, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith); - - IEnumerable FindMembersByUsername(string login, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith); - } } \ No newline at end of file diff --git a/src/Umbraco.Core/Services/IMembershipMemberService.cs b/src/Umbraco.Core/Services/IMembershipMemberService.cs new file mode 100644 index 0000000000..18edae2bea --- /dev/null +++ b/src/Umbraco.Core/Services/IMembershipMemberService.cs @@ -0,0 +1,48 @@ +using System.Collections.Generic; +using Umbraco.Core.Models; +using Umbraco.Core.Persistence.Querying; + +namespace Umbraco.Core.Services +{ + /// + /// Defines part of the MemberService, which is specific to methods used by the membership provider. + /// + /// + /// Idea is to have this is an isolated interface so that it can be easily 'replaced' in the membership provider impl. + /// + internal interface IMembershipMemberService : IService + { + /// + /// Checks if a member with the username exists + /// + /// + /// + bool Exists(string username); + + /// + /// Creates and persists a new member + /// + /// + /// + /// + /// + /// + IMember CreateMember(string username, string email, string password, string memberTypeAlias); + + IMember GetById(object id); + + IMember GetByEmail(string email); + + IMember GetByUsername(string login); + + void Delete(IMember membershipUser); + + void Save(IMember membershipUser, bool raiseEvents = true); + + void Save(IEnumerable members, bool raiseEvents = true); + + IEnumerable FindMembersByEmail(string emailStringToMatch, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith); + + IEnumerable FindMembersByUsername(string login, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith); + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 7d400f5abc..02b36c8e85 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -764,6 +764,7 @@ +