|
From: <ste...@us...> - 2009-11-11 13:37:59
|
Revision: 4828
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4828&view=rev
Author: steverstrong
Date: 2009-11-11 13:37:38 +0000 (Wed, 11 Nov 2009)
Log Message:
-----------
More Linq tests and improvement to the Hql tree generation code
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/ASTNode.cs
trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/ConstructorNode.cs
trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/HqlSqlWalkerTreeAdapter.cs
trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs
trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/EqualityHqlGenerator.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/ProjectionEvaluator.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/QueryModelVisitor.cs
trunk/nhibernate/src/NHibernate/NHibernate.csproj
trunk/nhibernate/src/NHibernate.Test/Linq/Entities/Northwind.cs
trunk/nhibernate/src/NHibernate.Test/Linq/LinqTestCase.cs
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate/Linq/Functions/
trunk/nhibernate/src/NHibernate/Linq/Functions/BaseHqlGeneratorForMethod.cs
trunk/nhibernate/src/NHibernate/Linq/Functions/BaseHqlGeneratorForProperty.cs
trunk/nhibernate/src/NHibernate/Linq/Functions/BaseHqlGeneratorForType.cs
trunk/nhibernate/src/NHibernate/Linq/Functions/DateTimeGenerator.cs
trunk/nhibernate/src/NHibernate/Linq/Functions/FunctionRegistry.cs
trunk/nhibernate/src/NHibernate/Linq/Functions/IHqlGeneratorForMethod.cs
trunk/nhibernate/src/NHibernate/Linq/Functions/IHqlGeneratorForProperty.cs
trunk/nhibernate/src/NHibernate/Linq/Functions/IHqlGeneratorForType.cs
trunk/nhibernate/src/NHibernate/Linq/Functions/QueryableGenerator.cs
trunk/nhibernate/src/NHibernate/Linq/Functions/StringGenerator.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/IHqlExpressionVisitor.cs
trunk/nhibernate/src/NHibernate.Test/Linq/BinaryBooleanExpressionTests.cs
trunk/nhibernate/src/NHibernate.Test/Linq/Entities/Animal.cs
trunk/nhibernate/src/NHibernate.Test/Linq/Entities/AnotherEntity.cs
trunk/nhibernate/src/NHibernate.Test/Linq/Entities/Role.cs
trunk/nhibernate/src/NHibernate.Test/Linq/Entities/Timesheet.cs
trunk/nhibernate/src/NHibernate.Test/Linq/Entities/User.cs
trunk/nhibernate/src/NHibernate.Test/Linq/Entities/UserComponent.cs
trunk/nhibernate/src/NHibernate.Test/Linq/Mappings/Animal.hbm.xml
trunk/nhibernate/src/NHibernate.Test/Linq/Mappings/AnotherEntity.hbm.xml
trunk/nhibernate/src/NHibernate.Test/Linq/Mappings/Role.hbm.xml
trunk/nhibernate/src/NHibernate.Test/Linq/Mappings/TimeSheet.hbm.xml
trunk/nhibernate/src/NHibernate.Test/Linq/Mappings/User.hbm.xml
Removed Paths:
-------------
trunk/nhibernate/src/NHibernate/Linq/HqlNodeStack.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/BaseHqlGeneratorForProperty.cs
Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/ASTNode.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/ASTNode.cs 2009-11-10 18:07:01 UTC (rev 4827)
+++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/ASTNode.cs 2009-11-11 13:37:38 UTC (rev 4828)
@@ -17,11 +17,6 @@
private readonly IToken _token;
private List<IASTNode> _children;
- // TODO - currently just used for Constructor stuff in Linq. Should really have a subtype,
- // and a new TreeFactory thingy for the Linq AST generator. But for now...
- private object _hack;
- public object Hack { get { return _hack; } set { _hack = value; } }
-
public ASTNode()
: this((IToken)null) {}
Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/ConstructorNode.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/ConstructorNode.cs 2009-11-10 18:07:01 UTC (rev 4827)
+++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/ConstructorNode.cs 2009-11-11 13:37:38 UTC (rev 4828)
@@ -109,16 +109,7 @@
}
else
{
- if (Hack != null && Hack is ConstructorInfo)
- {
- // The Linq parser has the constructor information available, so it can pass it straight through.
- // Currently using nasty Hack property :) This *will* be improved!
- _constructor = (ConstructorInfo)Hack;
- }
- else
- {
- _constructor = ResolveConstructor(path);
- }
+ _constructor = ResolveConstructor(path);
}
}
Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/HqlSqlWalkerTreeAdapter.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/HqlSqlWalkerTreeAdapter.cs 2009-11-10 18:07:01 UTC (rev 4827)
+++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/HqlSqlWalkerTreeAdapter.cs 2009-11-11 13:37:38 UTC (rev 4828)
@@ -176,15 +176,6 @@
{
var dupped = (IASTNode) Create(node.Token);
- // TODO - nasty hack for Linq. To be removed :). In general, should this just call the copy
- // constructor or something? Then this may work for derived classes... (via a Create overload...)
- ASTNode x = dupped as ASTNode;
- ASTNode y = node as ASTNode;
- if (x != null && y != null)
- {
- x.Hack = y.Hack;
- }
-
dupped.Parent = node.Parent;
return dupped;
Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs 2009-11-10 18:07:01 UTC (rev 4827)
+++ trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs 2009-11-11 13:37:38 UTC (rev 4828)
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Reflection;
using NHibernate.Hql.Ast.ANTLR.Tree;
namespace NHibernate.Hql.Ast
@@ -70,11 +69,6 @@
return new HqlRange(_factory, ident);
}
- public HqlRange Range()
- {
- return new HqlRange(_factory);
- }
-
public HqlRange Range(HqlTreeNode ident, HqlAlias alias)
{
return new HqlRange(_factory, ident, alias);
@@ -95,49 +89,44 @@
return new HqlAlias(_factory, alias);
}
- public HqlEquality Equality()
+ public HqlEquality Equality(HqlExpression lhs, HqlExpression rhs)
{
- return new HqlEquality(_factory);
- }
-
- public HqlEquality Equality(HqlTreeNode lhs, HqlTreeNode rhs)
- {
return new HqlEquality(_factory, lhs, rhs);
}
- public HqlBooleanAnd BooleanAnd()
+ public HqlBooleanAnd BooleanAnd(HqlBooleanExpression lhs, HqlBooleanExpression rhs)
{
- return new HqlBooleanAnd(_factory);
+ return new HqlBooleanAnd(_factory, lhs, rhs);
}
- public HqlBooleanOr BooleanOr()
+ public HqlBooleanOr BooleanOr(HqlBooleanExpression lhs, HqlBooleanExpression rhs)
{
- return new HqlBooleanOr(_factory);
+ return new HqlBooleanOr(_factory, lhs, rhs);
}
- public HqlAdd Add()
+ public HqlAdd Add(HqlExpression lhs, HqlExpression rhs)
{
- return new HqlAdd(_factory);
+ return new HqlAdd(_factory, lhs, rhs);
}
- public HqlSubtract Subtract()
+ public HqlSubtract Subtract(HqlExpression lhs, HqlExpression rhs)
{
- return new HqlSubtract(_factory);
+ return new HqlSubtract(_factory, lhs, rhs);
}
- public HqlMultiplty Multiply()
+ public HqlMultiplty Multiply(HqlExpression lhs, HqlExpression rhs)
{
- return new HqlMultiplty(_factory);
+ return new HqlMultiplty(_factory, lhs, rhs);
}
- public HqlDivide Divide()
+ public HqlDivide Divide(HqlExpression lhs, HqlExpression rhs)
{
- return new HqlDivide(_factory);
+ return new HqlDivide(_factory, lhs, rhs);
}
- public HqlDot Dot()
+ public HqlDot Dot(HqlExpression lhs, HqlExpression rhs)
{
- return new HqlDot(_factory);
+ return new HqlDot(_factory, lhs, rhs);
}
public HqlParameter Parameter(string name)
@@ -145,16 +134,11 @@
return new HqlParameter(_factory, name);
}
- public HqlWhere Where(HqlTreeNode expression)
+ public HqlWhere Where(HqlExpression expression)
{
return new HqlWhere(_factory, expression);
}
- public HqlWhere Where()
- {
- return new HqlWhere(_factory);
- }
-
// TODO - constant will be removed when we have parameter handling done properly. Particularly bad datetime handling here, so it'll be good to delete it :)
public HqlConstant Constant(object value)
{
@@ -194,82 +178,72 @@
return new HqlOrderBy(_factory);
}
- public HqlOrderBy OrderBy(HqlTreeNode expression, HqlDirection hqlDirection)
+ public HqlSelect Select(HqlExpression expression)
{
- return new HqlOrderBy(_factory, expression, hqlDirection);
- }
-
- public HqlSelect Select(HqlTreeNode expression)
- {
return new HqlSelect(_factory, expression);
}
- public HqlSelect Select(params HqlTreeNode[] expression)
+ public HqlSelect Select(params HqlExpression[] expression)
{
return new HqlSelect(_factory, expression);
}
- public HqlSelect Select(IEnumerable<HqlTreeNode> expressions)
+ public HqlSelect Select(IEnumerable<HqlExpression> expressions)
{
return new HqlSelect(_factory, expressions.ToArray());
}
- public HqlConstructor Constructor(ConstructorInfo constructor)
+ public HqlCase Case(HqlWhen[] whenClauses)
{
- return new HqlConstructor(_factory, constructor);
+ return new HqlCase(_factory, whenClauses, null);
}
- public HqlNill Holder()
+ public HqlCase Case(HqlWhen[] whenClauses, HqlExpression ifFalse)
{
- return new HqlNill(_factory);
+ return new HqlCase(_factory, whenClauses, ifFalse);
}
- public HqlCase Case()
+ public HqlWhen When(HqlExpression predicate, HqlExpression ifTrue)
{
- return new HqlCase(_factory);
+ return new HqlWhen(_factory, predicate, ifTrue);
}
- public HqlWhen When()
+ public HqlElse Else(HqlExpression ifFalse)
{
- return new HqlWhen(_factory);
+ return new HqlElse(_factory, ifFalse);
}
- public HqlElse Else()
+ public HqlInequality Inequality(HqlExpression lhs, HqlExpression rhs)
{
- return new HqlElse(_factory);
+ return new HqlInequality(_factory, lhs, rhs);
}
- public HqlInequality Inequality()
+ public HqlLessThan LessThan(HqlExpression lhs, HqlExpression rhs)
{
- return new HqlInequality(_factory);
+ return new HqlLessThan(_factory, lhs, rhs);
}
- public HqlLessThan LessThan()
+ public HqlLessThanOrEqual LessThanOrEqual(HqlExpression lhs, HqlExpression rhs)
{
- return new HqlLessThan(_factory);
+ return new HqlLessThanOrEqual(_factory, lhs, rhs);
}
- public HqlLessThanOrEqual LessThanOrEqual()
+ public HqlGreaterThan GreaterThan(HqlExpression lhs, HqlExpression rhs)
{
- return new HqlLessThanOrEqual(_factory);
+ return new HqlGreaterThan(_factory, lhs, rhs);
}
- public HqlGreaterThan GreaterThan()
+ public HqlGreaterThanOrEqual GreaterThanOrEqual(HqlExpression lhs, HqlExpression rhs)
{
- return new HqlGreaterThan(_factory);
+ return new HqlGreaterThanOrEqual(_factory, lhs, rhs);
}
- public HqlGreaterThanOrEqual GreaterThanOrEqual()
- {
- return new HqlGreaterThanOrEqual(_factory);
- }
-
public HqlCount Count()
{
return new HqlCount(_factory);
}
- public HqlCount Count(HqlTreeNode child)
+ public HqlCount Count(HqlExpression child)
{
return new HqlCount(_factory, child);
}
@@ -279,7 +253,7 @@
return new HqlRowStar(_factory);
}
- public HqlCast Cast(HqlTreeNode expression, System.Type type)
+ public HqlCast Cast(HqlExpression expression, System.Type type)
{
return new HqlCast(_factory, expression, type);
}
@@ -289,58 +263,33 @@
return new HqlBitwiseNot(_factory);
}
- public HqlNot Not()
+ public HqlNot Not(HqlBooleanExpression operand)
{
- return new HqlNot(_factory);
+ return new HqlNot(_factory, operand);
}
- public HqlAverage Average()
+ public HqlAverage Average(HqlExpression expression)
{
- return new HqlAverage(_factory);
- }
-
- public HqlAverage Average(HqlTreeNode expression)
- {
return new HqlAverage(_factory, expression);
}
- public HqlSum Sum()
+ public HqlSum Sum(HqlExpression expression)
{
- return new HqlSum(_factory);
- }
-
- public HqlSum Sum(HqlTreeNode expression)
- {
return new HqlSum(_factory, expression);
}
- public HqlMin Min()
+ public HqlMin Min(HqlExpression expression)
{
- return new HqlMin(_factory);
- }
-
- public HqlMin Min(HqlTreeNode expression)
- {
return new HqlMin(_factory, expression);
}
- public HqlMax Max()
+ public HqlMax Max(HqlExpression expression)
{
- return new HqlMax(_factory);
- }
-
- public HqlMax Max(HqlTreeNode expression)
- {
return new HqlMax(_factory, expression);
}
- public HqlAnd And(HqlTreeNode left, HqlTreeNode right)
+ public HqlJoin Join(HqlExpression expression, HqlAlias @alias)
{
- return new HqlAnd(_factory, left, right);
- }
-
- public HqlJoin Join(HqlTreeNode expression, HqlAlias @alias)
- {
return new HqlJoin(_factory, expression, @alias);
}
@@ -349,9 +298,9 @@
return new HqlAny(_factory);
}
- public HqlExists Exists()
+ public HqlExists Exists(HqlQuery query)
{
- return new HqlExists(_factory);
+ return new HqlExists(_factory, query);
}
public HqlElements Elements()
@@ -374,9 +323,9 @@
return new HqlDirectionDescending(_factory);
}
- public HqlGroupBy GroupBy()
+ public HqlGroupBy GroupBy(HqlExpression expression)
{
- return new HqlGroupBy(_factory);
+ return new HqlGroupBy(_factory, expression);
}
public HqlAll All()
@@ -384,14 +333,14 @@
return new HqlAll(_factory);
}
- public HqlLike Like()
+ public HqlLike Like(HqlExpression lhs, HqlExpression rhs)
{
- return new HqlLike(_factory);
+ return new HqlLike(_factory, lhs, rhs);
}
- public HqlConcat Concat()
+ public HqlConcat Concat(params HqlExpression[] args)
{
- return new HqlConcat(_factory);
+ return new HqlConcat(_factory, args);
}
public HqlExpressionList ExpressionList()
@@ -399,9 +348,14 @@
return new HqlExpressionList(_factory);
}
- public HqlMethodCall MethodCall()
+ public HqlMethodCall MethodCall(string methodName, HqlExpression parameter)
{
- return new HqlMethodCall(_factory);
+ return new HqlMethodCall(_factory, methodName, parameter);
}
+
+ public HqlDistinctHolder DistinctHolder(params HqlTreeNode[] children)
+ {
+ return new HqlDistinctHolder(_factory, children);
+ }
}
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs 2009-11-10 18:07:01 UTC (rev 4827)
+++ trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs 2009-11-11 13:37:38 UTC (rev 4828)
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Reflection;
using NHibernate.Hql.Ast.ANTLR;
using NHibernate.Hql.Ast.ANTLR.Tree;
@@ -8,18 +7,37 @@
{
public class HqlTreeNode
{
- protected readonly IASTNode _node;
- protected readonly List<HqlTreeNode> _children;
+ private readonly IASTNode _node;
+ private readonly List<HqlTreeNode> _children;
- protected HqlTreeNode(int type, string text, IASTFactory factory, params HqlTreeNode[] children)
+ protected HqlTreeNode(int type, string text, IASTFactory factory, IEnumerable<HqlTreeNode> children)
{
_node = factory.CreateNode(type, text);
_children = new List<HqlTreeNode>();
+ AddChildren(children);
+ }
+
+ protected HqlTreeNode(int type, string text, IASTFactory factory, params HqlTreeNode[] children) : this(type, text, factory, (IEnumerable<HqlTreeNode>) children)
+ {
+ }
+
+ private void AddChildren(IEnumerable<HqlTreeNode> children)
+ {
foreach (var child in children)
{
- _children.Add(child);
- _node.AddChild(child.AstNode);
+ if (child != null)
+ {
+ if (child is HqlDistinctHolder)
+ {
+ AddChildren(child.Children);
+ }
+ else
+ {
+ _children.Add(child);
+ _node.AddChild(child.AstNode);
+ }
+ }
}
}
@@ -57,13 +75,7 @@
public IEnumerable<HqlTreeNode> Children
{
- get
- {
- foreach (var child in _children)
- {
- yield return child;
- }
- }
+ get { return _children; }
}
public void ClearChildren()
@@ -72,6 +84,11 @@
_node.ClearChildren();
}
+ protected void SetText(string text)
+ {
+ _node.Text = text;
+ }
+
internal IASTNode AstNode
{
get { return _node; }
@@ -79,28 +96,74 @@
internal void AddChild(HqlTreeNode child)
{
- _children.Add(child);
- _node.AddChild(child.AstNode);
+ if (child is HqlDistinctHolder)
+ {
+ AddChildren(child.Children);
+ }
+ else
+ {
+ _children.Add(child);
+ _node.AddChild(child.AstNode);
+ }
}
- public void AddChild(int index, HqlTreeNode node)
+ public HqlExpression AsExpression()
{
- _children.Insert(index, node);
- _node.InsertChild(index, node.AstNode);
+ // TODO - nice error handling if cast fails
+ return (HqlExpression) this;
}
+ public virtual HqlBooleanExpression AsBooleanExpression()
+ {
+ // TODO - nice error handling if cast fails
+ return (HqlBooleanExpression)this;
+ }
}
- public class HqlQuery : HqlTreeNode
+ public abstract class HqlStatement : HqlTreeNode
{
- internal HqlQuery(IASTFactory factory, params HqlTreeNode[] children)
+ protected HqlStatement(int type, string text, IASTFactory factory, params HqlTreeNode[] children)
+ : base(type, text, factory, children)
+ {
+ }
+ }
+
+ public abstract class HqlExpression : HqlTreeNode
+ {
+ protected HqlExpression(int type, string text, IASTFactory factory, IEnumerable<HqlTreeNode> children)
+ : base(type, text, factory, children)
+ {
+ }
+
+ protected HqlExpression(int type, string text, IASTFactory factory, params HqlTreeNode[] children)
+ : base(type, text, factory, children)
+ {
+ }
+ }
+
+ public abstract class HqlBooleanExpression : HqlExpression
+ {
+ protected HqlBooleanExpression(int type, string text, IASTFactory factory, IEnumerable<HqlTreeNode> children)
+ : base(type, text, factory, children)
+ {
+ }
+
+ protected HqlBooleanExpression(int type, string text, IASTFactory factory, params HqlTreeNode[] children)
+ : base(type, text, factory, children)
+ {
+ }
+ }
+
+ public class HqlQuery : HqlExpression
+ {
+ internal HqlQuery(IASTFactory factory, params HqlStatement[] children)
: base(HqlSqlWalker.QUERY, "query", factory, children)
{
}
}
- public class HqlIdent : HqlTreeNode
+ public class HqlIdent : HqlExpression
{
internal HqlIdent(IASTFactory factory, string ident)
: base(HqlSqlWalker.IDENT, ident, factory)
@@ -118,24 +181,24 @@
switch (System.Type.GetTypeCode(type))
{
case TypeCode.Boolean:
- _node.Text = "bool";
+ SetText("bool");
break;
case TypeCode.Int32:
- _node.Text = "integer";
+ SetText("integer");
break;
case TypeCode.Decimal:
- _node.Text = "decimal";
+ SetText("decimal");
break;
case TypeCode.DateTime:
- _node.Text = "datetime";
+ SetText("datetime");
break;
case TypeCode.String:
- _node.Text = "string";
+ SetText("string");
break;
default:
if (type == typeof(Guid))
{
- _node.Text = "guid";
+ SetText("guid");
break;
}
throw new NotSupportedException(string.Format("Don't currently support idents of type {0}", type.Name));
@@ -155,7 +218,7 @@
}
- public class HqlRange : HqlTreeNode
+ public class HqlRange : HqlStatement
{
internal HqlRange(IASTFactory factory, params HqlTreeNode[] children)
: base(HqlSqlWalker.RANGE, "range", factory, children)
@@ -163,7 +226,7 @@
}
}
- public class HqlFrom : HqlTreeNode
+ public class HqlFrom : HqlStatement
{
internal HqlFrom(IASTFactory factory, params HqlTreeNode[] children)
: base(HqlSqlWalker.FROM, "from", factory, children)
@@ -171,7 +234,7 @@
}
}
- public class HqlSelectFrom : HqlTreeNode
+ public class HqlSelectFrom : HqlStatement
{
internal HqlSelectFrom(IASTFactory factory, params HqlTreeNode[] children)
: base(HqlSqlWalker.SELECT_FROM, "select_from", factory, children)
@@ -179,7 +242,7 @@
}
}
- public class HqlAlias : HqlTreeNode
+ public class HqlAlias : HqlExpression
{
public HqlAlias(IASTFactory factory, string @alias)
: base(HqlSqlWalker.ALIAS, alias, factory)
@@ -187,68 +250,63 @@
}
}
- public class HqlDivide : HqlTreeNode
+ public class HqlDivide : HqlExpression
{
- public HqlDivide(IASTFactory factory)
- : base(HqlSqlWalker.DIV, "/", factory)
+ public HqlDivide(IASTFactory factory, HqlExpression lhs, HqlExpression rhs)
+ : base(HqlSqlWalker.DIV, "/", factory, lhs, rhs)
{
}
}
- public class HqlMultiplty : HqlTreeNode
+ public class HqlMultiplty : HqlExpression
{
- public HqlMultiplty(IASTFactory factory)
- : base(HqlSqlWalker.STAR, "*", factory)
+ public HqlMultiplty(IASTFactory factory, HqlExpression lhs, HqlExpression rhs)
+ : base(HqlSqlWalker.STAR, "*", factory, lhs, rhs)
{
}
}
- public class HqlSubtract : HqlTreeNode
+ public class HqlSubtract : HqlExpression
{
- public HqlSubtract(IASTFactory factory)
- : base(HqlSqlWalker.MINUS, "-", factory)
+ public HqlSubtract(IASTFactory factory, HqlExpression lhs, HqlExpression rhs)
+ : base(HqlSqlWalker.MINUS, "-", factory, lhs, rhs)
{
}
}
- public class HqlAdd : HqlTreeNode
+ public class HqlAdd : HqlExpression
{
- public HqlAdd(IASTFactory factory)
- : base(HqlSqlWalker.PLUS, "+", factory)
+ public HqlAdd(IASTFactory factory, HqlExpression lhs, HqlExpression rhs)
+ : base(HqlSqlWalker.PLUS, "+", factory, lhs, rhs)
{
}
}
- public class HqlBooleanOr : HqlTreeNode
+ public class HqlBooleanOr : HqlBooleanExpression
{
- public HqlBooleanOr(IASTFactory factory)
- : base(HqlSqlWalker.OR, "or", factory)
+ public HqlBooleanOr(IASTFactory factory, HqlBooleanExpression lhs, HqlBooleanExpression rhs)
+ : base(HqlSqlWalker.OR, "or", factory, lhs, rhs)
{
}
}
- public class HqlBooleanAnd : HqlTreeNode
+ public class HqlBooleanAnd : HqlBooleanExpression
{
- public HqlBooleanAnd(IASTFactory factory)
- : base(HqlSqlWalker.AND, "/", factory)
+ public HqlBooleanAnd(IASTFactory factory, HqlBooleanExpression lhs, HqlBooleanExpression rhs)
+ : base(HqlSqlWalker.AND, "/", factory, lhs, rhs)
{
}
}
- public class HqlEquality : HqlTreeNode
+ public class HqlEquality : HqlBooleanExpression
{
- public HqlEquality(IASTFactory factory)
- : base(HqlSqlWalker.EQ, "==", factory)
- {
- }
-
- public HqlEquality(IASTFactory factory, HqlTreeNode lhs, HqlTreeNode rhs)
+ public HqlEquality(IASTFactory factory, HqlExpression lhs, HqlExpression rhs)
: base(HqlSqlWalker.EQ, "==", factory, lhs, rhs)
{
}
}
- public class HqlParameter : HqlTreeNode
+ public class HqlParameter : HqlExpression
{
public HqlParameter(IASTFactory factory, string name)
: base(HqlSqlWalker.COLON, ":", factory)
@@ -257,28 +315,40 @@
}
}
- public class HqlDot : HqlTreeNode
+ public class HqlDot : HqlExpression
{
- public HqlDot(IASTFactory factory)
- : base(HqlSqlWalker.DOT, ".", factory)
+ private readonly IASTFactory _factory;
+
+ public HqlDot(IASTFactory factory, HqlExpression lhs, HqlExpression rhs)
+ : base(HqlSqlWalker.DOT, ".", factory, lhs, rhs)
{
+ _factory = factory;
}
+
+ public override HqlBooleanExpression AsBooleanExpression()
+ {
+ // If we are of boolean type, then we can acts as boolean expression
+ // TODO - implement type check
+ return new HqlBooleanDot(_factory, this);
+ }
}
- public class HqlWhere : HqlTreeNode
+ public class HqlBooleanDot : HqlBooleanExpression
{
- public HqlWhere(IASTFactory factory)
- : base(HqlSqlWalker.WHERE, "where", factory)
+ public HqlBooleanDot(IASTFactory factory, HqlDot dot) : base(dot.AstNode.Type, dot.AstNode.Text, factory, dot.Children)
{
}
+ }
- public HqlWhere(IASTFactory factory, HqlTreeNode expression)
+ public class HqlWhere : HqlStatement
+ {
+ public HqlWhere(IASTFactory factory, HqlExpression expression)
: base(HqlSqlWalker.WHERE, "where", factory, expression)
{
}
}
- public class HqlConstant : HqlTreeNode
+ public class HqlConstant : HqlExpression
{
public HqlConstant(IASTFactory factory, int type, string value)
: base(type, value, factory)
@@ -334,19 +404,12 @@
}
}
- public class HqlOrderBy : HqlTreeNode
+ public class HqlOrderBy : HqlStatement
{
public HqlOrderBy(IASTFactory factory)
: base(HqlSqlWalker.ORDER, "", factory)
{
}
-
- public HqlOrderBy(IASTFactory factory, HqlTreeNode expression, HqlDirection hqlDirection)
- : base(HqlSqlWalker.ORDER, "", factory, expression,
- hqlDirection == HqlDirection.Ascending ?
- (HqlTreeNode)new HqlDirectionAscending(factory) : (HqlTreeNode)new HqlDirectionDescending(factory))
- {
- }
}
public enum HqlDirection
@@ -355,7 +418,7 @@
Descending
}
- public class HqlDirectionAscending : HqlTreeNode
+ public class HqlDirectionAscending : HqlStatement
{
public HqlDirectionAscending(IASTFactory factory)
: base(HqlSqlWalker.ASCENDING, "asc", factory)
@@ -363,7 +426,7 @@
}
}
- public class HqlDirectionDescending : HqlTreeNode
+ public class HqlDirectionDescending : HqlStatement
{
public HqlDirectionDescending(IASTFactory factory)
: base(HqlSqlWalker.DESCENDING, "desc", factory)
@@ -371,120 +434,107 @@
}
}
- public class HqlSelect : HqlTreeNode
+ public class HqlSelect : HqlStatement
{
- public HqlSelect(IASTFactory factory, params HqlTreeNode[] expression)
+ public HqlSelect(IASTFactory factory, params HqlExpression[] expression)
: base(HqlSqlWalker.SELECT, "select", factory, expression)
{
}
}
- public class HqlConstructor : HqlTreeNode
+ public class HqlElse : HqlStatement
{
- public HqlConstructor(IASTFactory factory, ConstructorInfo ctor)
- : base(HqlSqlWalker.CONSTRUCTOR, "ctor", factory)
+ public HqlElse(IASTFactory factory, HqlExpression ifFalse)
+ : base(HqlSqlWalker.ELSE, "else", factory, ifFalse)
{
- ((ASTNode)_node).Hack = ctor;
}
}
- public class HqlNill : HqlTreeNode
+ public class HqlWhen : HqlStatement
{
- public HqlNill(IASTFactory factory)
- : base(0, "nill", factory)
+ public HqlWhen(IASTFactory factory, HqlExpression predicate, HqlExpression ifTrue)
+ : base(HqlSqlWalker.WHEN, "when", factory, predicate, ifTrue)
{
}
}
- public class HqlElse : HqlTreeNode
+ public class HqlCase : HqlExpression
{
- public HqlElse(IASTFactory factory)
- : base(HqlSqlWalker.ELSE, "else", factory)
+ public HqlCase(IASTFactory factory, HqlWhen[] whenClauses, HqlExpression ifFalse)
+ : base(HqlSqlWalker.CASE, "case", factory, whenClauses)
{
+ if (ifFalse != null)
+ {
+ AddChild(new HqlElse(factory, ifFalse));
+ }
}
}
- public class HqlWhen : HqlTreeNode
+ public class HqlGreaterThanOrEqual : HqlBooleanExpression
{
- public HqlWhen(IASTFactory factory)
- : base(HqlSqlWalker.WHEN, "when", factory)
+ public HqlGreaterThanOrEqual(IASTFactory factory, HqlExpression lhs, HqlExpression rhs)
+ : base(HqlSqlWalker.GE, "ge", factory, lhs, rhs)
{
}
}
- public class HqlCase : HqlTreeNode
+ public class HqlGreaterThan : HqlBooleanExpression
{
- public HqlCase(IASTFactory factory)
- : base(HqlSqlWalker.CASE, "case", factory)
+ public HqlGreaterThan(IASTFactory factory, HqlExpression lhs, HqlExpression rhs)
+ : base(HqlSqlWalker.GT, "gt", factory, lhs, rhs)
{
}
}
- public class HqlGreaterThanOrEqual : HqlTreeNode
+ public class HqlLessThanOrEqual : HqlBooleanExpression
{
- public HqlGreaterThanOrEqual(IASTFactory factory)
- : base(HqlSqlWalker.GE, "ge", factory)
+ public HqlLessThanOrEqual(IASTFactory factory, HqlExpression lhs, HqlExpression rhs)
+ : base(HqlSqlWalker.LE, "le", factory, lhs, rhs)
{
}
}
- public class HqlGreaterThan : HqlTreeNode
+ public class HqlLessThan : HqlBooleanExpression
{
- public HqlGreaterThan(IASTFactory factory)
- : base(HqlSqlWalker.GT, "gt", factory)
+ public HqlLessThan(IASTFactory factory, HqlExpression lhs, HqlExpression rhs)
+ : base(HqlSqlWalker.LT, "lt", factory, lhs, rhs)
{
}
}
- public class HqlLessThanOrEqual : HqlTreeNode
+ public class HqlInequality : HqlBooleanExpression
{
- public HqlLessThanOrEqual(IASTFactory factory)
- : base(HqlSqlWalker.LE, "le", factory)
+ public HqlInequality(IASTFactory factory, HqlExpression lhs, HqlExpression rhs)
+ : base(HqlSqlWalker.NE, "ne", factory, lhs, rhs)
{
}
}
- public class HqlLessThan : HqlTreeNode
+ public class HqlRowStar : HqlStatement
{
- public HqlLessThan(IASTFactory factory)
- : base(HqlSqlWalker.LT, "lt", factory)
- {
- }
- }
-
- public class HqlInequality : HqlTreeNode
- {
- public HqlInequality(IASTFactory factory)
- : base(HqlSqlWalker.NE, "ne", factory)
- {
- }
- }
-
- public class HqlRowStar : HqlTreeNode
- {
public HqlRowStar(IASTFactory factory)
: base(HqlSqlWalker.ROW_STAR, "*", factory)
{
}
}
- public class HqlCount : HqlTreeNode
+ public class HqlCount : HqlExpression
{
-
public HqlCount(IASTFactory factory)
: base(HqlSqlWalker.COUNT, "count", factory)
{
}
-
- public HqlCount(IASTFactory factory, HqlTreeNode child)
+
+ public HqlCount(IASTFactory factory, HqlExpression child)
: base(HqlSqlWalker.COUNT, "count", factory, child)
{
}
}
- public class HqlAs : HqlTreeNode
+ public class HqlAs : HqlExpression
{
- public HqlAs(IASTFactory factory, HqlTreeNode expression, System.Type type) : base(HqlSqlWalker.AS, "as", factory, expression)
+ public HqlAs(IASTFactory factory, HqlExpression expression, System.Type type)
+ : base(HqlSqlWalker.AS, "as", factory, expression)
{
switch (System.Type.GetTypeCode(type))
{
@@ -497,136 +547,118 @@
}
}
- public class HqlCast : HqlTreeNode
+ public class HqlCast : HqlExpression
{
- public HqlCast(IASTFactory factory, HqlTreeNode expression, System.Type type) : base(HqlSqlWalker.METHOD_CALL, "method", factory)
+ public HqlCast(IASTFactory factory, HqlExpression expression, System.Type type)
+ : base(HqlSqlWalker.METHOD_CALL, "method", factory)
{
AddChild(new HqlIdent(factory, "cast"));
AddChild(new HqlExpressionList(factory, expression, new HqlIdent(factory, type)));
}
}
- public class HqlExpressionList : HqlTreeNode
+ public class HqlExpressionList : HqlStatement
{
public HqlExpressionList(IASTFactory factory, params HqlTreeNode[] expression) : base(HqlSqlWalker.EXPR_LIST, "expr_list", factory, expression)
{
}
}
- public class HqlNot : HqlTreeNode
+ public class HqlNot : HqlBooleanExpression
{
- public HqlNot(IASTFactory factory) : base(HqlSqlWalker.NOT, "not", factory)
+ public HqlNot(IASTFactory factory, HqlBooleanExpression operand)
+ : base(HqlSqlWalker.NOT, "not", factory, operand)
{
}
}
- public class HqlAverage : HqlTreeNode
+ public class HqlAverage : HqlExpression
{
- public HqlAverage(IASTFactory factory)
- : base(HqlSqlWalker.AGGREGATE, "avg", factory)
+ public HqlAverage(IASTFactory factory, HqlExpression expression)
+ : base(HqlSqlWalker.AGGREGATE, "avg", factory, expression)
{
}
-
- public HqlAverage(IASTFactory factory, HqlTreeNode expression) : base(HqlSqlWalker.AGGREGATE, "avg", factory, expression)
- {
- }
}
- public class HqlBitwiseNot : HqlTreeNode
+ public class HqlBitwiseNot : HqlExpression
{
public HqlBitwiseNot(IASTFactory factory) : base(HqlSqlWalker.BNOT, "not", factory)
{
}
}
- public class HqlSum : HqlTreeNode
+ public class HqlSum : HqlExpression
{
public HqlSum(IASTFactory factory)
: base(HqlSqlWalker.AGGREGATE, "sum", factory)
{
}
- public HqlSum(IASTFactory factory, HqlTreeNode expression)
+ public HqlSum(IASTFactory factory, HqlExpression expression)
: base(HqlSqlWalker.AGGREGATE, "sum", factory, expression)
{
}
}
- public class HqlMax : HqlTreeNode
+ public class HqlMax : HqlExpression
{
- public HqlMax(IASTFactory factory) : base(HqlSqlWalker.AGGREGATE, "max", factory)
- {
- }
-
- public HqlMax(IASTFactory factory, HqlTreeNode expression)
+ public HqlMax(IASTFactory factory, HqlExpression expression)
: base(HqlSqlWalker.AGGREGATE, "max", factory, expression)
{
}
}
- public class HqlMin : HqlTreeNode
+ public class HqlMin : HqlExpression
{
- public HqlMin(IASTFactory factory)
- : base(HqlSqlWalker.AGGREGATE, "min", factory)
- {
- }
-
- public HqlMin(IASTFactory factory, HqlTreeNode expression)
+ public HqlMin(IASTFactory factory, HqlExpression expression)
: base(HqlSqlWalker.AGGREGATE, "min", factory, expression)
{
}
}
- public class HqlAnd : HqlTreeNode
+ public class HqlJoin : HqlStatement
{
- public HqlAnd(IASTFactory factory, HqlTreeNode left, HqlTreeNode right) : base(HqlSqlWalker.AND, "and", factory, left, right)
+ public HqlJoin(IASTFactory factory, HqlExpression expression, HqlAlias @alias) : base(HqlSqlWalker.JOIN, "join", factory, expression, @alias)
{
}
}
- public class HqlJoin : HqlTreeNode
+ public class HqlAny : HqlBooleanExpression
{
- public HqlJoin(IASTFactory factory, HqlTreeNode expression, HqlAlias @alias) : base(HqlSqlWalker.JOIN, "join", factory, expression, @alias)
- {
- }
- }
-
- public class HqlAny : HqlTreeNode
- {
public HqlAny(IASTFactory factory) : base(HqlSqlWalker.ANY, "any", factory)
{
}
}
- public class HqlExists : HqlTreeNode
+ public class HqlExists : HqlBooleanExpression
{
- public HqlExists(IASTFactory factory) : base(HqlSqlWalker.EXISTS, "exists", factory)
+ public HqlExists(IASTFactory factory, HqlQuery query) : base(HqlSqlWalker.EXISTS, "exists", factory, query)
{
}
}
- public class HqlElements : HqlTreeNode
+ public class HqlElements : HqlBooleanExpression
{
public HqlElements(IASTFactory factory) : base(HqlSqlWalker.ELEMENTS, "elements", factory)
{
}
}
- public class HqlDistinct : HqlTreeNode
+ public class HqlDistinct : HqlStatement
{
public HqlDistinct(IASTFactory factory) : base(HqlSqlWalker.DISTINCT, "distinct", factory)
{
}
}
- public class HqlGroupBy : HqlTreeNode
+ public class HqlGroupBy : HqlStatement
{
- public HqlGroupBy(IASTFactory factory) : base(HqlSqlWalker.GROUP, "group by", factory)
+ public HqlGroupBy(IASTFactory factory, HqlExpression expression) : base(HqlSqlWalker.GROUP, "group by", factory, expression)
{
}
}
- public class HqlAll : HqlTreeNode
+ public class HqlAll : HqlBooleanExpression
{
public HqlAll(IASTFactory factory)
: base(HqlSqlWalker.ALL, "all", factory)
@@ -634,24 +666,38 @@
}
}
- public class HqlLike : HqlTreeNode
+ public class HqlLike : HqlBooleanExpression
{
- public HqlLike(IASTFactory factory) : base(HqlSqlWalker.LIKE, "like", factory)
+ public HqlLike(IASTFactory factory, HqlExpression lhs, HqlExpression rhs)
+ : base(HqlSqlWalker.LIKE, "like", factory, lhs, rhs)
{
}
}
- public class HqlConcat : HqlTreeNode
+ public class HqlConcat : HqlExpression
{
- public HqlConcat(IASTFactory factory) : base(HqlSqlWalker.METHOD_CALL, "method", factory)
+ public HqlConcat(IASTFactory factory, params HqlExpression[] args)
+ : base(HqlSqlWalker.METHOD_CALL, "method", factory)
{
+ AddChild(new HqlIdent(factory, "concat"));
+ AddChild(new HqlExpressionList(factory, args));
}
}
- public class HqlMethodCall : HqlTreeNode
+ public class HqlMethodCall : HqlExpression
{
- public HqlMethodCall(IASTFactory factory) : base(HqlSqlWalker.METHOD_CALL, "method", factory)
+ public HqlMethodCall(IASTFactory factory, string methodName, HqlExpression parameter)
+ : base(HqlSqlWalker.METHOD_CALL, "method", factory)
{
+ AddChild(new HqlIdent(factory, methodName));
+ AddChild(new HqlExpressionList(factory, parameter));
}
}
+
+ public class HqlDistinctHolder : HqlExpression
+ {
+ public HqlDistinctHolder(IASTFactory factory, HqlTreeNode[] children) : base(int.MinValue, "distinct holder", factory, children)
+ {
+ }
+ }
}
\ No newline at end of file
Property changes on: trunk/nhibernate/src/NHibernate/Linq/Functions
___________________________________________________________________
Added: bugtraq:url
+ http://jira.nhibernate.org/browse/%BUGID%
Added: bugtraq:logregex
+ NH-\d+
Added: trunk/nhibernate/src/NHibernate/Linq/Functions/BaseHqlGeneratorForMethod.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Functions/BaseHqlGeneratorForMethod.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/Functions/BaseHqlGeneratorForMethod.cs 2009-11-11 13:37:38 UTC (rev 4828)
@@ -0,0 +1,16 @@
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq.Expressions;
+using System.Reflection;
+using NHibernate.Hql.Ast;
+using NHibernate.Linq.Visitors;
+
+namespace NHibernate.Linq.Functions
+{
+ public abstract class BaseHqlGeneratorForMethod : IHqlGeneratorForMethod
+ {
+ public IEnumerable<MethodInfo> SupportedMethods { get; protected set; }
+
+ public abstract HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor);
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Linq/Functions/BaseHqlGeneratorForProperty.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Functions/BaseHqlGeneratorForProperty.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/Functions/BaseHqlGeneratorForProperty.cs 2009-11-11 13:37:38 UTC (rev 4828)
@@ -0,0 +1,14 @@
+using System.Collections.Generic;
+using System.Linq.Expressions;
+using System.Reflection;
+using NHibernate.Hql.Ast;
+using NHibernate.Linq.Visitors;
+
+namespace NHibernate.Linq.Functions
+{
+ public abstract class BaseHqlGeneratorForProperty : IHqlGeneratorForProperty
+ {
+ public IEnumerable<MemberInfo> SupportedProperties { get; protected set; }
+ public abstract HqlTreeNode BuildHql(MemberInfo member, Expression expression, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor);
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Linq/Functions/BaseHqlGeneratorForType.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Functions/BaseHqlGeneratorForType.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/Functions/BaseHqlGeneratorForType.cs 2009-11-11 13:37:38 UTC (rev 4828)
@@ -0,0 +1,30 @@
+using System.Collections.Generic;
+using NHibernate.Linq.Visitors;
+
+namespace NHibernate.Linq.Functions
+{
+ abstract public class BaseHqlGeneratorForType : IHqlGeneratorForType
+ {
+ protected readonly List<IHqlGeneratorForMethod> MethodRegistry = new List<IHqlGeneratorForMethod>();
+ protected readonly List<IHqlGeneratorForProperty> PropertyRegistry = new List<IHqlGeneratorForProperty>();
+
+ public void Register(FunctionRegistry functionRegistry)
+ {
+ foreach (var generator in MethodRegistry)
+ {
+ foreach (var method in generator.SupportedMethods)
+ {
+ functionRegistry.RegisterMethodGenerator(method, generator);
+ }
+ }
+
+ foreach (var generator in PropertyRegistry)
+ {
+ foreach (var property in generator.SupportedProperties)
+ {
+ functionRegistry.RegisterPropertyGenerator(property, generator);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Linq/Functions/DateTimeGenerator.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Functions/DateTimeGenerator.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/Functions/DateTimeGenerator.cs 2009-11-11 13:37:38 UTC (rev 4828)
@@ -0,0 +1,38 @@
+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),
+ };
+ }
+
+ 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
Added: trunk/nhibernate/src/NHibernate/Linq/Functions/FunctionRegistry.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Functions/FunctionRegistry.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/Functions/FunctionRegistry.cs 2009-11-11 13:37:38 UTC (rev 4828)
@@ -0,0 +1,69 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+
+namespace NHibernate.Linq.Functions
+{
+ public class FunctionRegistry
+ {
+ public static FunctionRegistry Initialise()
+ {
+ var registry = new FunctionRegistry();
+
+ // TODO - could use reflection here
+ registry.Register(new QueryableGenerator());
+ registry.Register(new StringGenerator());
+ registry.Register(new DateTimeGenerator());
+
+ return registry;
+ }
+
+ private readonly Dictionary<MethodInfo, IHqlGeneratorForMethod> _registeredMethods = new Dictionary<MethodInfo, IHqlGeneratorForMethod>();
+ private readonly Dictionary<MemberInfo, IHqlGeneratorForProperty> _registeredProperties = new Dictionary<MemberInfo, IHqlGeneratorForProperty>();
+
+ public IHqlGeneratorForMethod GetMethodGenerator(MethodInfo method)
+ {
+ IHqlGeneratorForMethod methodGenerator;
+
+ if (method.IsGenericMethod)
+ {
+ method = method.GetGenericMethodDefinition();
+ }
+
+ if (_registeredMethods.TryGetValue(method, out methodGenerator))
+ {
+ return methodGenerator;
+ }
+
+ throw new NotSupportedException(method.ToString());
+ }
+
+ public IHqlGeneratorForProperty GetPropertyGenerator(MemberInfo member)
+ {
+ IHqlGeneratorForProperty propertyGenerator;
+
+ if (_registeredProperties.TryGetValue(member, out propertyGenerator))
+ {
+ return propertyGenerator;
+ }
+
+ // TODO - different usage pattern to method generator
+ return null;
+ }
+
+ public void RegisterMethodGenerator(MethodInfo method, IHqlGeneratorForMethod generator)
+ {
+ _registeredMethods.Add(method, generator);
+ }
+
+ public void RegisterPropertyGenerator(MemberInfo property, IHqlGeneratorForProperty generator)
+ {
+ _registeredProperties.Add(property, generator);
+ }
+
+ private void Register(IHqlGeneratorForType typeMethodGenerator)
+ {
+ typeMethodGenerator.Register(this);
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Linq/Functions/IHqlGeneratorForMethod.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Functions/IHqlGeneratorForMethod.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/Functions/IHqlGeneratorForMethod.cs 2009-11-11 13:37:38 UTC (rev 4828)
@@ -0,0 +1,15 @@
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq.Expressions;
+using System.Reflection;
+using NHibernate.Hql.Ast;
+using NHibernate.Linq.Visitors;
+
+namespace NHibernate.Linq.Functions
+{
+ public interface IHqlGeneratorForMethod
+ {
+ IEnumerable<MethodInfo> SupportedMethods { get; }
+ HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor);
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Linq/Functions/IHqlGeneratorForProperty.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Functions/IHqlGeneratorForProperty.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/Functions/IHqlGeneratorForProperty.cs 2009-11-11 13:37:38 UTC (rev 4828)
@@ -0,0 +1,14 @@
+using System.Collections.Generic;
+using System.Linq.Expressions;
+using System.Reflection;
+using NHibernate.Hql.Ast;
+using NHibernate.Linq.Visitors;
+
+namespace NHibernate.Linq.Functions
+{
+ public interface IHqlGeneratorForProperty
+ {
+ IEnumerable<MemberInfo> SupportedProperties { get; }
+ HqlTreeNode BuildHql(MemberInfo member, Expression expression, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor);
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Linq/Functions/IHqlGeneratorForType.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Functions/IHqlGeneratorForType.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/Functions/IHqlGeneratorForType.cs 2009-11-11 13:37:38 UTC (rev 4828)
@@ -0,0 +1,7 @@
+namespace NHibernate.Linq.Functions
+{
+ public interface IHqlGeneratorForType
+ {
+ void Register(FunctionRegistry functionRegistry);
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Linq/Functions/QueryableGenerator.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Functions/QueryableGenerator.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/Functions/QueryableGenerator.cs 2009-11-11 13:37:38 UTC (rev 4828)
@@ -0,0 +1,129 @@
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reflection;
+using NHibernate.Hql.Ast;
+using NHibernate.Linq.Visitors;
+
+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());
+ }
+
+ class AnyGenerator : BaseHqlGeneratorForMethod
+ {
+ public AnyGenerator()
+ {
+ SupportedMethods = new[]
+ {
+ ReflectionHelper.GetMethod(() => Queryable.Any<object>(null)),
+ ReflectionHelper.GetMethod(() => Queryable.Any<object>(null, null)),
+ ReflectionHelper.GetMethod(() => Enumerable.Any<object>(null)),
+ ReflectionHelper.GetMethod(() => 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;
+
+ if (arguments.Count > 1)
+ {
+ var expr = (LambdaExpression)arguments[1];
+
+ 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));
+ }
+ }
+
+ class AllGenerator : BaseHqlGeneratorForMethod
+ {
+ public AllGenerator()
+ {
+ SupportedMethods = new[]
+ {
+ ReflectionHelper.GetMethod(() => Queryable.All<object>(null, null)),
+ ReflectionHelper.GetMethod(() => 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];
+
+ return treeBuilder.Not(
+ treeBuilder.Exists(
+ treeBuilder.Query(
+ treeBuilder.SelectFrom(
+ treeBuilder.From(
+ treeBuilder.Range(
+ visitor.Visit(arguments[0]),
+ treeBuilder.Alias(predicate.Parameters[0].Name))
+ )
+ ),
+ treeBuilder.Where(
+ treeBuilder.Not(visitor.Visit(arguments[1]).AsBooleanExpression())
+ )
+ )
+ )
+ );
+ }
+ }
+
+ class MinGenerator : BaseHqlGeneratorForMethod
+ {
+ public MinGenerator()
+ {
+ SupportedMethods = new[]
+ {
+ ReflectionHelper.GetMethod(() => Queryable.Min<object>(null)),
+ ReflectionHelper.GetMethod(() => 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());
+ }
+ }
+
+ class MaxGenerator : BaseHqlGeneratorForMethod
+ {
+ public MaxGenerator()
+ {
+ SupportedMethods = new[]
+ {
+ ReflectionHelper.GetMethod(() => Queryable.Max<object>(null)),
+ ReflectionHelper.GetMethod(() => 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());
+ }
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Linq/Functions/StringGenerator.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Functions/StringGenerator.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/Functions/StringGenerator.cs 2009-11-11 13:37:38 UTC (rev 4828)
@@ -0,0 +1,133 @@
+using System.Collections.ObjectModel;
+using System.Linq.Expressions;
+using System.Reflection;
+using NHibernate.Hql.Ast;
+using NHibernate.Linq.Visitors;
+
+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());
+
+ PropertyRegistry.Add(new LengthGenerator());
+ }
+
+ public class LengthGenerator : BaseHqlGeneratorForProperty
+ {
+ public LengthGenerator()
+ {...
[truncated message content] |