From: <fab...@us...> - 2010-07-31 14:00:06
|
Revision: 5085 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5085&view=rev Author: fabiomaulo Date: 2010-07-31 13:59:59 +0000 (Sat, 31 Jul 2010) Log Message: ----------- Refactoring in order to allow/show a more grained of ILinqToHqlGeneratorsRegistry; In this way the user can choose what reuse, what replace and what override. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Linq/Functions/DefaultLinqToHqlGeneratorsRegistry.cs trunk/nhibernate/src/NHibernate/Linq/Functions/ILinqToHqlGeneratorsRegistry.cs trunk/nhibernate/src/NHibernate/Linq/Functions/QueryableGenerator.cs trunk/nhibernate/src/NHibernate/Linq/Functions/StandardLinqExtensionMethodGenerator.cs trunk/nhibernate/src/NHibernate/Linq/Functions/StringGenerator.cs trunk/nhibernate/src/NHibernate/NHibernate.csproj trunk/nhibernate/src/NHibernate.Test/Linq/LinqToHqlGeneratorsRegistryFactoryTest.cs Added Paths: ----------- trunk/nhibernate/src/NHibernate/Linq/Functions/DateTimePropertiesHqlGenerator.cs trunk/nhibernate/src/NHibernate/Linq/Functions/IRuntimeMethodHqlGenerator.cs trunk/nhibernate/src/NHibernate/Linq/Functions/LinqToHqlGeneratorsRegistryExtensions.cs Removed Paths: ------------- trunk/nhibernate/src/NHibernate/Linq/Functions/BaseHqlGeneratorForType.cs trunk/nhibernate/src/NHibernate/Linq/Functions/DateTimeGenerator.cs trunk/nhibernate/src/NHibernate/Linq/Functions/IHqlGeneratorForType.cs Deleted: trunk/nhibernate/src/NHibernate/Linq/Functions/BaseHqlGeneratorForType.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Functions/BaseHqlGeneratorForType.cs 2010-07-31 11:38:05 UTC (rev 5084) +++ trunk/nhibernate/src/NHibernate/Linq/Functions/BaseHqlGeneratorForType.cs 2010-07-31 13:59:59 UTC (rev 5085) @@ -1,45 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; - -namespace NHibernate.Linq.Functions -{ - public abstract class BaseHqlGeneratorForType : IHqlGeneratorForType - { - protected readonly List<IHqlGeneratorForMethod> MethodRegistry = new List<IHqlGeneratorForMethod>(); - protected readonly List<IHqlGeneratorForProperty> PropertyRegistry = new List<IHqlGeneratorForProperty>(); - - #region IHqlGeneratorForType Members - - public void Register(ILinqToHqlGeneratorsRegistry functionRegistry) - { - foreach (IHqlGeneratorForMethod generator in MethodRegistry) - { - foreach (MethodInfo method in generator.SupportedMethods) - { - functionRegistry.RegisterGenerator(method, generator); - } - } - - foreach (IHqlGeneratorForProperty generator in PropertyRegistry) - { - foreach (MemberInfo property in generator.SupportedProperties) - { - functionRegistry.RegisterGenerator(property, generator); - } - } - } - - public virtual bool SupportsMethod(MethodInfo method) - { - return false; - } - - public virtual IHqlGeneratorForMethod GetMethodGenerator(MethodInfo method) - { - throw new NotSupportedException(); - } - - #endregion - } -} \ No newline at end of file Deleted: trunk/nhibernate/src/NHibernate/Linq/Functions/DateTimeGenerator.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Functions/DateTimeGenerator.cs 2010-07-31 11:38:05 UTC (rev 5084) +++ trunk/nhibernate/src/NHibernate/Linq/Functions/DateTimeGenerator.cs 2010-07-31 13:59:59 UTC (rev 5085) @@ -1,39 +0,0 @@ -using System; -using System.Linq.Expressions; -using System.Reflection; -using NHibernate.Hql.Ast; -using NHibernate.Linq.Visitors; - -namespace NHibernate.Linq.Functions -{ - public class DateTimeGenerator : BaseHqlGeneratorForType - { - public DateTimeGenerator() - { - PropertyRegistry.Add(new DatePartGenerator()); - } - - public class DatePartGenerator : BaseHqlGeneratorForProperty - { - public DatePartGenerator() - { - SupportedProperties = new[] - { - ReflectionHelper.GetProperty((DateTime x) => x.Year), - ReflectionHelper.GetProperty((DateTime x) => x.Month), - ReflectionHelper.GetProperty((DateTime x) => x.Day), - ReflectionHelper.GetProperty((DateTime x) => x.Hour), - ReflectionHelper.GetProperty((DateTime x) => x.Minute), - ReflectionHelper.GetProperty((DateTime x) => x.Second), - ReflectionHelper.GetProperty((DateTime x) => x.Date), - }; - } - - public override HqlTreeNode BuildHql(MemberInfo member, Expression expression, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) - { - return treeBuilder.MethodCall(member.Name.ToLowerInvariant(), - visitor.Visit(expression).AsExpression()); - } - } - } -} \ No newline at end of file Copied: trunk/nhibernate/src/NHibernate/Linq/Functions/DateTimePropertiesHqlGenerator.cs (from rev 5083, trunk/nhibernate/src/NHibernate/Linq/Functions/DateTimeGenerator.cs) =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Functions/DateTimePropertiesHqlGenerator.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Linq/Functions/DateTimePropertiesHqlGenerator.cs 2010-07-31 13:59:59 UTC (rev 5085) @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using System.Reflection; +using NHibernate.Hql.Ast; +using NHibernate.Linq.Visitors; + +namespace NHibernate.Linq.Functions +{ + public class DateTimePropertiesHqlGenerator : IHqlGeneratorForProperty + { + private readonly MemberInfo[] supportedProperties; + + public DateTimePropertiesHqlGenerator() + { + supportedProperties = new[] + { + ReflectionHelper.GetProperty((DateTime x) => x.Year), + ReflectionHelper.GetProperty((DateTime x) => x.Month), + ReflectionHelper.GetProperty((DateTime x) => x.Day), + ReflectionHelper.GetProperty((DateTime x) => x.Hour), + ReflectionHelper.GetProperty((DateTime x) => x.Minute), + ReflectionHelper.GetProperty((DateTime x) => x.Second), + ReflectionHelper.GetProperty((DateTime x) => x.Date), + }; + } + + public IEnumerable<MemberInfo> SupportedProperties + { + get + { + return supportedProperties; + } + } + + public HqlTreeNode BuildHql(MemberInfo member, Expression expression, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) + { + return treeBuilder.MethodCall(member.Name.ToLowerInvariant(), + visitor.Visit(expression).AsExpression()); + } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Linq/Functions/DefaultLinqToHqlGeneratorsRegistry.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Functions/DefaultLinqToHqlGeneratorsRegistry.cs 2010-07-31 11:38:05 UTC (rev 5084) +++ trunk/nhibernate/src/NHibernate/Linq/Functions/DefaultLinqToHqlGeneratorsRegistry.cs 2010-07-31 13:59:59 UTC (rev 5085) @@ -8,22 +8,37 @@ { private readonly Dictionary<MethodInfo, IHqlGeneratorForMethod> registeredMethods = new Dictionary<MethodInfo, IHqlGeneratorForMethod>(); private readonly Dictionary<MemberInfo, IHqlGeneratorForProperty> registeredProperties = new Dictionary<MemberInfo, IHqlGeneratorForProperty>(); - private readonly List<IHqlGeneratorForType> typeGenerators = new List<IHqlGeneratorForType>(); + private readonly List<IRuntimeMethodHqlGenerator> runtimeMethodHqlGenerators = new List<IRuntimeMethodHqlGenerator>(); public DefaultLinqToHqlGeneratorsRegistry() { - Register(new StandardLinqExtensionMethodGenerator()); - Register(new QueryableGenerator()); - Register(new StringGenerator()); - Register(new DateTimeGenerator()); - Register(new ICollectionGenerator()); + RegisterGenerator(new StandardLinqExtensionMethodGenerator()); + RegisterGenerator(new CollectionContainsRuntimeHqlGenerator()); + + this.Merge(new StartsWithGenerator()); + this.Merge(new EndsWithGenerator()); + this.Merge(new ContainsGenerator()); + this.Merge(new EqualsGenerator()); + this.Merge(new ToUpperLowerGenerator()); + this.Merge(new SubStringGenerator()); + this.Merge(new IndexOfGenerator()); + this.Merge(new ReplaceGenerator()); + this.Merge(new LengthGenerator()); + + this.Merge(new AnyHqlGenerator()); + this.Merge(new AllHqlGenerator()); + this.Merge(new MinHqlGenerator()); + this.Merge(new MaxHqlGenerator()); + this.Merge(new CollectionContainsGenerator()); + + this.Merge(new DateTimePropertiesHqlGenerator()); } - protected bool GetMethodGeneratorForType(MethodInfo method, out IHqlGeneratorForMethod methodGenerator) + protected bool GetRuntimeMethodGenerator(MethodInfo method, out IHqlGeneratorForMethod methodGenerator) { methodGenerator = null; - foreach (var typeGenerator in typeGenerators.Where(typeGenerator => typeGenerator.SupportsMethod(method))) + foreach (var typeGenerator in runtimeMethodHqlGenerators.Where(typeGenerator => typeGenerator.SupportsMethod(method))) { methodGenerator = typeGenerator.GetMethodGenerator(method); return true; @@ -41,7 +56,7 @@ if (registeredMethods.TryGetValue(method, out generator)) return true; // Not that either. Let's query each type generator to see if it can handle it - if (GetMethodGeneratorForType(method, out generator)) return true; + if (GetRuntimeMethodGenerator(method, out generator)) return true; return false; } @@ -61,10 +76,9 @@ registeredProperties.Add(property, generator); } - protected void Register(IHqlGeneratorForType typeMethodGenerator) + public void RegisterGenerator(IRuntimeMethodHqlGenerator generator) { - typeGenerators.Add(typeMethodGenerator); - typeMethodGenerator.Register(this); + runtimeMethodHqlGenerators.Add(generator); } } } \ No newline at end of file Deleted: trunk/nhibernate/src/NHibernate/Linq/Functions/IHqlGeneratorForType.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Functions/IHqlGeneratorForType.cs 2010-07-31 11:38:05 UTC (rev 5084) +++ trunk/nhibernate/src/NHibernate/Linq/Functions/IHqlGeneratorForType.cs 2010-07-31 13:59:59 UTC (rev 5085) @@ -1,11 +0,0 @@ -using System.Reflection; - -namespace NHibernate.Linq.Functions -{ - public interface IHqlGeneratorForType - { - void Register(ILinqToHqlGeneratorsRegistry functionRegistry); - bool SupportsMethod(MethodInfo method); - IHqlGeneratorForMethod GetMethodGenerator(MethodInfo method); - } -} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Linq/Functions/ILinqToHqlGeneratorsRegistry.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Functions/ILinqToHqlGeneratorsRegistry.cs 2010-07-31 11:38:05 UTC (rev 5084) +++ trunk/nhibernate/src/NHibernate/Linq/Functions/ILinqToHqlGeneratorsRegistry.cs 2010-07-31 13:59:59 UTC (rev 5085) @@ -8,5 +8,6 @@ bool TryGetGenerator(MemberInfo property, out IHqlGeneratorForProperty generator); void RegisterGenerator(MethodInfo method, IHqlGeneratorForMethod generator); void RegisterGenerator(MemberInfo property, IHqlGeneratorForProperty generator); + void RegisterGenerator(IRuntimeMethodHqlGenerator generator); } } \ No newline at end of file Added: trunk/nhibernate/src/NHibernate/Linq/Functions/IRuntimeMethodHqlGenerator.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Functions/IRuntimeMethodHqlGenerator.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Linq/Functions/IRuntimeMethodHqlGenerator.cs 2010-07-31 13:59:59 UTC (rev 5085) @@ -0,0 +1,10 @@ +using System.Reflection; + +namespace NHibernate.Linq.Functions +{ + public interface IRuntimeMethodHqlGenerator + { + bool SupportsMethod(MethodInfo method); + IHqlGeneratorForMethod GetMethodGenerator(MethodInfo method); + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate/Linq/Functions/LinqToHqlGeneratorsRegistryExtensions.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Functions/LinqToHqlGeneratorsRegistryExtensions.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Linq/Functions/LinqToHqlGeneratorsRegistryExtensions.cs 2010-07-31 13:59:59 UTC (rev 5085) @@ -0,0 +1,34 @@ +using System; +using System.Linq; + +namespace NHibernate.Linq.Functions +{ + public static class LinqToHqlGeneratorsRegistryExtensions + { + public static void Merge(this ILinqToHqlGeneratorsRegistry registry, IHqlGeneratorForMethod generator) + { + if (registry == null) + { + throw new ArgumentNullException("registry"); + } + if (generator == null) + { + throw new ArgumentNullException("generator"); + } + Array.ForEach(generator.SupportedMethods.ToArray(), method=> registry.RegisterGenerator(method, generator)); + } + + public static void Merge(this ILinqToHqlGeneratorsRegistry registry, IHqlGeneratorForProperty generator) + { + if (registry == null) + { + throw new ArgumentNullException("registry"); + } + if (generator == null) + { + throw new ArgumentNullException("generator"); + } + Array.ForEach(generator.SupportedProperties.ToArray(), property => registry.RegisterGenerator(property, generator)); + } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Linq/Functions/QueryableGenerator.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Functions/QueryableGenerator.cs 2010-07-31 11:38:05 UTC (rev 5084) +++ trunk/nhibernate/src/NHibernate/Linq/Functions/QueryableGenerator.cs 2010-07-31 13:59:59 UTC (rev 5085) @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Linq.Expressions; @@ -9,193 +8,165 @@ namespace NHibernate.Linq.Functions { - public class QueryableGenerator : BaseHqlGeneratorForType - { - public QueryableGenerator() - { - // TODO - could use reflection - MethodRegistry.Add(new AnyGenerator()); - MethodRegistry.Add(new AllGenerator()); - MethodRegistry.Add(new MinGenerator()); - MethodRegistry.Add(new MaxGenerator()); - } + public class AnyHqlGenerator : BaseHqlGeneratorForMethod + { + public AnyHqlGenerator() + { + SupportedMethods = new[] + { + ReflectionHelper.GetMethodDefinition(() => Queryable.Any<object>(null)), + ReflectionHelper.GetMethodDefinition(() => Queryable.Any<object>(null, null)), + ReflectionHelper.GetMethodDefinition(() => Enumerable.Any<object>(null)), + ReflectionHelper.GetMethodDefinition(() => Enumerable.Any<object>(null, null)) + }; + } - class AnyGenerator : BaseHqlGeneratorForMethod - { - public AnyGenerator() - { - SupportedMethods = new[] - { - ReflectionHelper.GetMethodDefinition(() => Queryable.Any<object>(null)), - ReflectionHelper.GetMethodDefinition(() => Queryable.Any<object>(null, null)), - ReflectionHelper.GetMethodDefinition(() => Enumerable.Any<object>(null)), - ReflectionHelper.GetMethodDefinition(() => Enumerable.Any<object>(null, null)) - }; - } + public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) + { + HqlAlias alias = null; + HqlWhere where = null; - public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) - { - HqlAlias alias = null; - HqlWhere where = null; + if (arguments.Count > 1) + { + var expr = (LambdaExpression) arguments[1]; - if (arguments.Count > 1) - { - var expr = (LambdaExpression)arguments[1]; + alias = treeBuilder.Alias(expr.Parameters[0].Name); + where = treeBuilder.Where(visitor.Visit(arguments[1]).AsExpression()); + } - alias = treeBuilder.Alias(expr.Parameters[0].Name); - where = treeBuilder.Where(visitor.Visit(arguments[1]).AsExpression()); - } + return treeBuilder.Exists( + treeBuilder.Query( + treeBuilder.SelectFrom( + treeBuilder.From( + treeBuilder.Range( + visitor.Visit(arguments[0]), + alias) + ) + ), + where)); + } + } - return treeBuilder.Exists( - treeBuilder.Query( - treeBuilder.SelectFrom( - treeBuilder.From( - treeBuilder.Range( - visitor.Visit(arguments[0]), - alias) - ) - ), - where)); - } - } + public class AllHqlGenerator : BaseHqlGeneratorForMethod + { + public AllHqlGenerator() + { + SupportedMethods = new[] + { + ReflectionHelper.GetMethodDefinition(() => Queryable.All<object>(null, null)), + ReflectionHelper.GetMethodDefinition(() => Enumerable.All<object>(null, null)) + }; + } - class AllGenerator : BaseHqlGeneratorForMethod - { - public AllGenerator() - { - SupportedMethods = new[] - { - ReflectionHelper.GetMethodDefinition(() => Queryable.All<object>(null, null)), - ReflectionHelper.GetMethodDefinition(() => Enumerable.All<object>(null, null)) - }; - } + public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) + { + // All has two arguments. Arg 1 is the source and arg 2 is the predicate + var predicate = (LambdaExpression) arguments[1]; - public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) - { - // All has two arguments. Arg 1 is the source and arg 2 is the predicate - var predicate = (LambdaExpression)arguments[1]; + return treeBuilder.BooleanNot( + treeBuilder.Exists( + treeBuilder.Query( + treeBuilder.SelectFrom( + treeBuilder.From( + treeBuilder.Range( + visitor.Visit(arguments[0]), + treeBuilder.Alias(predicate.Parameters[0].Name)) + ) + ), + treeBuilder.Where( + treeBuilder.BooleanNot(visitor.Visit(arguments[1]).AsBooleanExpression()) + ) + ) + ) + ); + } + } - return treeBuilder.BooleanNot( - treeBuilder.Exists( - treeBuilder.Query( - treeBuilder.SelectFrom( - treeBuilder.From( - treeBuilder.Range( - visitor.Visit(arguments[0]), - treeBuilder.Alias(predicate.Parameters[0].Name)) - ) - ), - treeBuilder.Where( - treeBuilder.BooleanNot(visitor.Visit(arguments[1]).AsBooleanExpression()) - ) - ) - ) - ); - } - } + public class MinHqlGenerator : BaseHqlGeneratorForMethod + { + public MinHqlGenerator() + { + SupportedMethods = new[] + { + ReflectionHelper.GetMethodDefinition(() => Queryable.Min<object>(null)), + ReflectionHelper.GetMethodDefinition(() => Enumerable.Min<object>(null)) + }; + } - class MinGenerator : BaseHqlGeneratorForMethod - { - public MinGenerator() - { - SupportedMethods = new[] - { - ReflectionHelper.GetMethodDefinition(() => Queryable.Min<object>(null)), - ReflectionHelper.GetMethodDefinition(() => Enumerable.Min<object>(null)) - }; - } + public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) + { + return treeBuilder.Min(visitor.Visit(arguments[1]).AsExpression()); + } + } - public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) - { - return treeBuilder.Min(visitor.Visit(arguments[1]).AsExpression()); - } - } + public class MaxHqlGenerator : BaseHqlGeneratorForMethod + { + public MaxHqlGenerator() + { + SupportedMethods = new[] + { + ReflectionHelper.GetMethodDefinition(() => Queryable.Max<object>(null)), + ReflectionHelper.GetMethodDefinition(() => Enumerable.Max<object>(null)) + }; + } - class MaxGenerator : BaseHqlGeneratorForMethod - { - public MaxGenerator() - { - SupportedMethods = new[] - { - ReflectionHelper.GetMethodDefinition(() => Queryable.Max<object>(null)), - ReflectionHelper.GetMethodDefinition(() => Enumerable.Max<object>(null)) - }; - } + public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) + { + return treeBuilder.Max(visitor.Visit(arguments[1]).AsExpression()); + } + } - public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) - { - return treeBuilder.Max(visitor.Visit(arguments[1]).AsExpression()); - } - } - } + public class CollectionContainsRuntimeHqlGenerator : IRuntimeMethodHqlGenerator + { + private readonly IHqlGeneratorForMethod containsGenerator = new CollectionContainsGenerator(); - public class ICollectionGenerator : BaseHqlGeneratorForType - { - public ICollectionGenerator() - { - // TODO - could use reflection - MethodRegistry.Add(new ContainsGenerator()); - } + #region IRuntimeMethodHqlGenerator Members - public override bool SupportsMethod(MethodInfo method) - { - var declaringType = method.DeclaringType; + public bool SupportsMethod(MethodInfo method) + { + // the check about the name is to make things a little be fasters + return method != null && method.Name == "Contains" && method.IsMethodOf(typeof(ICollection<>)); + } - if (declaringType.IsGenericType) - { - if (declaringType.GetGenericTypeDefinition() == typeof(ICollection<>) || - declaringType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) - { - if (method.Name == "Contains") - { - return true; - } - } - } + public IHqlGeneratorForMethod GetMethodGenerator(MethodInfo method) + { + return containsGenerator; + } - return false; - } + #endregion + } - public override IHqlGeneratorForMethod GetMethodGenerator(MethodInfo method) - { - // TODO - ick - if (method.Name == "Contains") - { - return new ContainsGenerator(); - } + public class CollectionContainsGenerator : BaseHqlGeneratorForMethod + { + public CollectionContainsGenerator() + { + SupportedMethods = new[] + { + ReflectionHelper.GetMethodDefinition(() => Queryable.Contains<object>(null, null)), + ReflectionHelper.GetMethodDefinition(() => Enumerable.Contains<object>(null, null)) + }; + } - throw new NotSupportedException(method.Name); - } + public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) + { + // TODO - alias generator + HqlAlias alias = treeBuilder.Alias("x"); - class ContainsGenerator : BaseHqlGeneratorForMethod - { - public ContainsGenerator() - { - SupportedMethods = new MethodInfo[0]; - } + ParameterExpression param = Expression.Parameter(targetObject.Type, "x"); + HqlWhere where = treeBuilder.Where(visitor.Visit(Expression.Lambda( + Expression.Equal(param, arguments[0]), param)) + .AsExpression()); - public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) - { - // TODO - alias generator - var alias = treeBuilder.Alias("x"); - - var param = Expression.Parameter(targetObject.Type, "x"); - var where = treeBuilder.Where(visitor.Visit(Expression.Lambda( - Expression.Equal(param, arguments[0]), param)) - .AsExpression()); - - return treeBuilder.Exists( - treeBuilder.Query( - treeBuilder.SelectFrom( - treeBuilder.From( - treeBuilder.Range( - visitor.Visit(targetObject), - alias) - ) - ), - where)); - } - } - - } + return treeBuilder.Exists( + treeBuilder.Query( + treeBuilder.SelectFrom( + treeBuilder.From( + treeBuilder.Range( + visitor.Visit(targetObject), + alias) + ) + ), + where)); + } + } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Linq/Functions/StandardLinqExtensionMethodGenerator.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Functions/StandardLinqExtensionMethodGenerator.cs 2010-07-31 11:38:05 UTC (rev 5084) +++ trunk/nhibernate/src/NHibernate/Linq/Functions/StandardLinqExtensionMethodGenerator.cs 2010-07-31 13:59:59 UTC (rev 5085) @@ -8,15 +8,10 @@ namespace NHibernate.Linq.Functions { - public class StandardLinqExtensionMethodGenerator : IHqlGeneratorForType + public class StandardLinqExtensionMethodGenerator : IRuntimeMethodHqlGenerator { - #region IHqlGeneratorForType Members + #region IRuntimeMethodHqlGenerator Members - public void Register(ILinqToHqlGeneratorsRegistry functionRegistry) - { - // nothing to do - } - public bool SupportsMethod(MethodInfo method) { return method.GetCustomAttributes(typeof (LinqExtensionMethodAttribute), false).Any(); @@ -41,21 +36,21 @@ public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) { - var args = visitor.Visit(targetObject) - .Union(arguments.Select(a => visitor.Visit(a))) - .Cast<HqlExpression>(); + IEnumerable<HqlExpression> args = visitor.Visit(targetObject) + .Union(arguments.Select(a => visitor.Visit(a))) + .Cast<HqlExpression>(); return treeBuilder.MethodCall(_name, args); } } - static class UnionExtension + internal static class UnionExtension { public static IEnumerable<HqlTreeNode> Union(this HqlTreeNode first, IEnumerable<HqlTreeNode> rest) { yield return first; - foreach (var x in rest) + foreach (HqlTreeNode x in rest) { yield return x; } Modified: trunk/nhibernate/src/NHibernate/Linq/Functions/StringGenerator.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Functions/StringGenerator.cs 2010-07-31 11:38:05 UTC (rev 5084) +++ trunk/nhibernate/src/NHibernate/Linq/Functions/StringGenerator.cs 2010-07-31 13:59:59 UTC (rev 5085) @@ -6,204 +6,187 @@ namespace NHibernate.Linq.Functions { - public class StringGenerator : BaseHqlGeneratorForType - { - public StringGenerator() - { - // TODO - could use reflection - MethodRegistry.Add(new StartsWithGenerator()); - MethodRegistry.Add(new EndsWithGenerator()); - MethodRegistry.Add(new ContainsGenerator()); - MethodRegistry.Add(new EqualsGenerator()); - MethodRegistry.Add(new ToUpperLowerGenerator()); - MethodRegistry.Add(new SubStringGenerator()); - MethodRegistry.Add(new IndexOfGenerator()); - MethodRegistry.Add(new ReplaceGenerator()); + public class LengthGenerator : BaseHqlGeneratorForProperty + { + public LengthGenerator() + { + SupportedProperties = new[] { ReflectionHelper.GetProperty((string x) => x.Length) }; + } - PropertyRegistry.Add(new LengthGenerator()); - } + public override HqlTreeNode BuildHql(MemberInfo member, Expression expression, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) + { + return treeBuilder.MethodCall("length", visitor.Visit(expression).AsExpression()); + } + } - public class LengthGenerator : BaseHqlGeneratorForProperty - { - public LengthGenerator() - { - SupportedProperties = new[] {ReflectionHelper.GetProperty((string x) => x.Length)}; - } + public class StartsWithGenerator : BaseHqlGeneratorForMethod + { + public StartsWithGenerator() + { + SupportedMethods = new[] { ReflectionHelper.GetMethodDefinition<string>(x => x.StartsWith(null)) }; + } - public override HqlTreeNode BuildHql(MemberInfo member, Expression expression, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) - { - return treeBuilder.MethodCall("length", visitor.Visit(expression).AsExpression()); - } - } + public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) + { + return treeBuilder.Like( + visitor.Visit(targetObject).AsExpression(), + treeBuilder.Concat( + visitor.Visit(arguments[0]).AsExpression(), + treeBuilder.Constant("%"))); + } + } - class StartsWithGenerator : BaseHqlGeneratorForMethod - { - public StartsWithGenerator() - { - SupportedMethods = new[] { ReflectionHelper.GetMethodDefinition<string>(x => x.StartsWith(null)) }; - } + public class EndsWithGenerator : BaseHqlGeneratorForMethod + { + public EndsWithGenerator() + { + SupportedMethods = new[] { ReflectionHelper.GetMethodDefinition<string>(x => x.EndsWith(null)) }; + } - public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) - { - return treeBuilder.Like( - visitor.Visit(targetObject).AsExpression(), - treeBuilder.Concat( - visitor.Visit(arguments[0]).AsExpression(), - treeBuilder.Constant("%"))); - } - } + public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) + { + return treeBuilder.Like( + visitor.Visit(targetObject).AsExpression(), + treeBuilder.Concat( + treeBuilder.Constant("%"), + visitor.Visit(arguments[0]).AsExpression())); + } + } - class EndsWithGenerator : BaseHqlGeneratorForMethod - { - public EndsWithGenerator() - { - SupportedMethods = new[] { ReflectionHelper.GetMethodDefinition<string>(x => x.EndsWith(null)) }; - } + public class ContainsGenerator : BaseHqlGeneratorForMethod + { + public ContainsGenerator() + { + SupportedMethods = new[] { ReflectionHelper.GetMethodDefinition<string>(x => x.Contains(null)) }; + } - public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) - { - return treeBuilder.Like( - visitor.Visit(targetObject).AsExpression(), - treeBuilder.Concat( - treeBuilder.Constant("%"), - visitor.Visit(arguments[0]).AsExpression())); - } - } + public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) + { + return treeBuilder.Like( + visitor.Visit(targetObject).AsExpression(), + treeBuilder.Concat( + treeBuilder.Constant("%"), + visitor.Visit(arguments[0]).AsExpression(), + treeBuilder.Constant("%"))); + } + } - class ContainsGenerator : BaseHqlGeneratorForMethod - { - public ContainsGenerator() - { - SupportedMethods = new[] { ReflectionHelper.GetMethodDefinition<string>(x => x.Contains(null)) }; - } + public class EqualsGenerator : BaseHqlGeneratorForMethod + { + public EqualsGenerator() + { + SupportedMethods = new[] { ReflectionHelper.GetMethodDefinition<string>(x => x.Equals((string)null)) }; + } - public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) - { - return treeBuilder.Like( - visitor.Visit(targetObject).AsExpression(), - treeBuilder.Concat( - treeBuilder.Constant("%"), - visitor.Visit(arguments[0]).AsExpression(), - treeBuilder.Constant("%"))); - } - } + public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) + { + return treeBuilder.Equality( + visitor.Visit(targetObject).AsExpression(), + visitor.Visit(arguments[0]).AsExpression()); + } + } - class EqualsGenerator : BaseHqlGeneratorForMethod - { - public EqualsGenerator() - { - SupportedMethods = new[] { ReflectionHelper.GetMethodDefinition<string>(x => x.Equals((string)null)) }; - } - - public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) - { - return treeBuilder.Equality( - visitor.Visit(targetObject).AsExpression(), - visitor.Visit(arguments[0]).AsExpression()); - } - } - - class ToUpperLowerGenerator : BaseHqlGeneratorForMethod - { - public ToUpperLowerGenerator() - { - SupportedMethods = new[] + public class ToUpperLowerGenerator : BaseHqlGeneratorForMethod + { + public ToUpperLowerGenerator() + { + SupportedMethods = new[] { ReflectionHelper.GetMethodDefinition<string>(x => x.ToUpper()), ReflectionHelper.GetMethodDefinition<string>(x => x.ToUpperInvariant()), ReflectionHelper.GetMethodDefinition<string>(x => x.ToLower()), ReflectionHelper.GetMethodDefinition<string>(x => x.ToLowerInvariant()) }; - } + } - public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) - { - string methodName; + public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) + { + string methodName; - if (((method.Name == "ToUpper") || (method.Name == "ToUpperInvariant"))) - { - methodName = "upper"; - } - else - { - methodName = "lower"; - } + if (((method.Name == "ToUpper") || (method.Name == "ToUpperInvariant"))) + { + methodName = "upper"; + } + else + { + methodName = "lower"; + } - return treeBuilder.MethodCall(methodName, visitor.Visit(targetObject).AsExpression()); - } - } + return treeBuilder.MethodCall(methodName, visitor.Visit(targetObject).AsExpression()); + } + } - class SubStringGenerator : BaseHqlGeneratorForMethod - { - public SubStringGenerator() - { - SupportedMethods = new[] + public class SubStringGenerator : BaseHqlGeneratorForMethod + { + public SubStringGenerator() + { + SupportedMethods = new[] { ReflectionHelper.GetMethodDefinition<string>(s => s.Substring(0)), ReflectionHelper.GetMethodDefinition<string>(s => s.Substring(0, 0)) }; - } - public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) - { - if (arguments.Count == 1) - { - return treeBuilder.MethodCall("substring", visitor.Visit(targetObject).AsExpression(), - treeBuilder.Constant(0), - visitor.Visit(arguments[0]).AsExpression()); - } - - return treeBuilder.MethodCall("substring", visitor.Visit(targetObject).AsExpression(), - visitor.Visit(arguments[0]).AsExpression(), - visitor.Visit(arguments[1]).AsExpression()); - } - } + } + public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) + { + if (arguments.Count == 1) + { + return treeBuilder.MethodCall("substring", visitor.Visit(targetObject).AsExpression(), + treeBuilder.Constant(0), + visitor.Visit(arguments[0]).AsExpression()); + } - class IndexOfGenerator : BaseHqlGeneratorForMethod - { - public IndexOfGenerator() - { - SupportedMethods = new[] + return treeBuilder.MethodCall("substring", visitor.Visit(targetObject).AsExpression(), + visitor.Visit(arguments[0]).AsExpression(), + visitor.Visit(arguments[1]).AsExpression()); + } + } + + public class IndexOfGenerator : BaseHqlGeneratorForMethod + { + public IndexOfGenerator() + { + SupportedMethods = new[] { ReflectionHelper.GetMethodDefinition<string>(s => s.IndexOf(' ')), ReflectionHelper.GetMethodDefinition<string>(s => s.IndexOf(" ")), ReflectionHelper.GetMethodDefinition<string>(s => s.IndexOf(' ', 0)), ReflectionHelper.GetMethodDefinition<string>(s => s.IndexOf(" ", 0)) }; - } - public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) - { - if (arguments.Count == 1) - { - return treeBuilder.MethodCall("locate", - visitor.Visit(arguments[0]).AsExpression(), - visitor.Visit(targetObject).AsExpression(), - treeBuilder.Constant(0)); - } - return treeBuilder.MethodCall("locate", - visitor.Visit(arguments[0]).AsExpression(), - visitor.Visit(targetObject).AsExpression(), - visitor.Visit(arguments[1]).AsExpression()); - } - } + } + public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) + { + if (arguments.Count == 1) + { + return treeBuilder.MethodCall("locate", + visitor.Visit(arguments[0]).AsExpression(), + visitor.Visit(targetObject).AsExpression(), + treeBuilder.Constant(0)); + } + return treeBuilder.MethodCall("locate", + visitor.Visit(arguments[0]).AsExpression(), + visitor.Visit(targetObject).AsExpression(), + visitor.Visit(arguments[1]).AsExpression()); + } + } - class ReplaceGenerator : BaseHqlGeneratorForMethod - { - public ReplaceGenerator() - { - SupportedMethods = new[] + public class ReplaceGenerator : BaseHqlGeneratorForMethod + { + public ReplaceGenerator() + { + SupportedMethods = new[] { ReflectionHelper.GetMethodDefinition<string>(s => s.Replace(' ', ' ')), ReflectionHelper.GetMethodDefinition<string>(s => s.Replace("", "")) }; - } + } - public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) - { - return treeBuilder.MethodCall("replace", - visitor.Visit(targetObject).AsExpression(), - visitor.Visit(arguments[0]).AsExpression(), - visitor.Visit(arguments[1]).AsExpression()); - } - } - } + public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) + { + return treeBuilder.MethodCall("replace", + visitor.Visit(targetObject).AsExpression(), + visitor.Visit(arguments[0]).AsExpression(), + visitor.Visit(arguments[1]).AsExpression()); + } + } + } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2010-07-31 11:38:05 UTC (rev 5084) +++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2010-07-31 13:59:59 UTC (rev 5085) @@ -655,6 +655,10 @@ <Compile Include="Linq\Expressions\AggregateExpressionNode.cs" /> <Compile Include="Linq\EagerFetchingExtensionMethods.cs" /> <Compile Include="Linq\Functions\ILinqToHqlGeneratorsRegistry.cs" /> + <Compile Include="Linq\Functions\IRuntimeMethodHqlGenerator.cs"> + <SubType>Code</SubType> + </Compile> + <Compile Include="Linq\Functions\LinqToHqlGeneratorsRegistryExtensions.cs" /> <Compile Include="Linq\Functions\LinqToHqlGeneratorsRegistryFactory.cs" /> <Compile Include="Linq\Functions\StandardLinqExtensionMethodGenerator.cs" /> <Compile Include="Linq\LinqExtensionMethodAttribute.cs" /> @@ -683,9 +687,7 @@ <Compile Include="Linq\Functions\IHqlGeneratorForMethod.cs" /> <Compile Include="Linq\Functions\IHqlGeneratorForProperty.cs" /> <Compile Include="Linq\Functions\BaseHqlGeneratorForMethod.cs" /> - <Compile Include="Linq\Functions\BaseHqlGeneratorForType.cs" /> - <Compile Include="Linq\Functions\IHqlGeneratorForType.cs" /> - <Compile Include="Linq\Functions\DateTimeGenerator.cs" /> + <Compile Include="Linq\Functions\DateTimePropertiesHqlGenerator.cs" /> <Compile Include="Linq\Functions\StringGenerator.cs" /> <Compile Include="Linq\Functions\QueryableGenerator.cs" /> <Compile Include="Linq\ReWriters\RemoveUnnecessaryBodyOperators.cs" /> Modified: trunk/nhibernate/src/NHibernate.Test/Linq/LinqToHqlGeneratorsRegistryFactoryTest.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/LinqToHqlGeneratorsRegistryFactoryTest.cs 2010-07-31 11:38:05 UTC (rev 5084) +++ trunk/nhibernate/src/NHibernate.Test/Linq/LinqToHqlGeneratorsRegistryFactoryTest.cs 2010-07-31 13:59:59 UTC (rev 5085) @@ -48,6 +48,11 @@ { throw new NotImplementedException(); } + + public void RegisterGenerator(IRuntimeMethodHqlGenerator generator) + { + throw new NotImplementedException(); + } } } } \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |