|
From: <ste...@us...> - 2009-09-28 17:04:24
|
Revision: 4731
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4731&view=rev
Author: steverstrong
Date: 2009-09-28 17:04:14 +0000 (Mon, 28 Sep 2009)
Log Message:
-----------
Changes to Linq execution to tie in with HQLQueryPlan caching
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Engine/Query/HQLQueryPlan.cs
trunk/nhibernate/src/NHibernate/Engine/Query/QueryPlanCache.cs
trunk/nhibernate/src/NHibernate/IQueryExpression.cs
trunk/nhibernate/src/NHibernate/Impl/AbstractSessionImpl.cs
trunk/nhibernate/src/NHibernate/Impl/QueryImpl.cs
trunk/nhibernate/src/NHibernate/Linq/CommandData.cs
trunk/nhibernate/src/NHibernate/Linq/NhQueryable.cs
trunk/nhibernate/src/NHibernate/NHibernate.csproj
trunk/nhibernate/src/NHibernate.Test/Linq/LinqTestCase.cs
trunk/nhibernate/src/NHibernate.Test/Linq/ReadonlyTestCase.cs
Removed Paths:
-------------
trunk/nhibernate/src/NHibernate/Hql/Ast/HqlExpression.cs
trunk/nhibernate/src/NHibernate/Linq/NhQueryExecutor.cs
Modified: trunk/nhibernate/src/NHibernate/Engine/Query/HQLQueryPlan.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Engine/Query/HQLQueryPlan.cs 2009-09-27 10:06:52 UTC (rev 4730)
+++ trunk/nhibernate/src/NHibernate/Engine/Query/HQLQueryPlan.cs 2009-09-28 17:04:14 UTC (rev 4731)
@@ -28,8 +28,9 @@
private readonly HashedSet<string> enabledFilterNames;
private readonly bool shallow;
+ private IQueryExpression sourceQueryExpression;
- public HQLQueryPlan(string hql, bool shallow,
+ public HQLQueryPlan(string hql, bool shallow,
IDictionary<string, IFilter> enabledFilters, ISessionFactoryImplementor factory)
: this(hql, (string) null, shallow, enabledFilters, factory)
{
@@ -110,6 +111,7 @@
protected internal HQLQueryPlan(string expressionStr, IQueryExpression queryExpression, string collectionRole, bool shallow,
IDictionary<string, IFilter> enabledFilters, ISessionFactoryImplementor factory)
{
+ sourceQueryExpression = queryExpression;
sourceQuery = expressionStr;
this.shallow = shallow;
@@ -192,7 +194,12 @@
}
}
- private static ParameterMetadata BuildParameterMetadata(IParameterTranslations parameterTranslations, string hql)
+ public IQueryExpression QueryExpression
+ {
+ get { return sourceQueryExpression; }
+ }
+
+ private static ParameterMetadata BuildParameterMetadata(IParameterTranslations parameterTranslations, string hql)
{
long start = DateTime.Now.Ticks;
ParamLocationRecognizer recognizer = ParamLocationRecognizer.ParseLocations(hql);
Modified: trunk/nhibernate/src/NHibernate/Engine/Query/QueryPlanCache.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Engine/Query/QueryPlanCache.cs 2009-09-27 10:06:52 UTC (rev 4730)
+++ trunk/nhibernate/src/NHibernate/Engine/Query/QueryPlanCache.cs 2009-09-28 17:04:14 UTC (rev 4731)
@@ -86,6 +86,7 @@
log.Debug("unable to locate HQL query plan in cache; generating (" + expressionStr + ")");
}
plan = new HQLQueryPlan(expressionStr, queryExpression, shallow, enabledFilters, factory);
+ planCache.Put(key, plan);
}
else
{
@@ -95,8 +96,6 @@
}
}
- planCache.Put(key, plan);
-
return plan;
}
Deleted: trunk/nhibernate/src/NHibernate/Hql/Ast/HqlExpression.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Ast/HqlExpression.cs 2009-09-27 10:06:52 UTC (rev 4730)
+++ trunk/nhibernate/src/NHibernate/Hql/Ast/HqlExpression.cs 2009-09-28 17:04:14 UTC (rev 4731)
@@ -1,36 +0,0 @@
-using System.Collections.Generic;
-using System.Reflection;
-using NHibernate.Hql.Ast.ANTLR;
-using NHibernate.Hql.Ast.ANTLR.Tree;
-
-namespace NHibernate.Hql.Ast
-{
- public class HqlExpression : IQueryExpression
- {
- private readonly IASTNode _node;
- private readonly System.Type _type;
- private readonly string _key;
-
- public HqlExpression(HqlQuery node, System.Type type)
- {
- _node = node.AstNode;
- _type = type;
- _key = _node.ToStringTree();
- }
-
- public IASTNode Translate(ISessionFactory sessionFactory)
- {
- return _node;
- }
-
- public string Key
- {
- get { return _key; }
- }
-
- public System.Type Type
- {
- get { return _type; }
- }
- }
-}
Modified: trunk/nhibernate/src/NHibernate/IQueryExpression.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/IQueryExpression.cs 2009-09-27 10:06:52 UTC (rev 4730)
+++ trunk/nhibernate/src/NHibernate/IQueryExpression.cs 2009-09-28 17:04:14 UTC (rev 4731)
@@ -1,4 +1,6 @@
+using NHibernate.Engine;
using NHibernate.Hql.Ast.ANTLR.Tree;
+using NHibernate.Impl;
namespace NHibernate
{
@@ -7,5 +9,6 @@
IASTNode Translate(ISessionFactory sessionFactory);
string Key { get; }
System.Type Type { get; }
+ void SetQueryParametersPriorToExecute(QueryImpl impl);
}
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Impl/AbstractSessionImpl.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Impl/AbstractSessionImpl.cs 2009-09-27 10:06:52 UTC (rev 4730)
+++ trunk/nhibernate/src/NHibernate/Impl/AbstractSessionImpl.cs 2009-09-28 17:04:14 UTC (rev 4731)
@@ -252,8 +252,9 @@
using (new SessionIdLoggingContext(SessionId))
{
CheckAndUpdateSessionStatus();
- QueryImpl query = new QueryImpl(queryExpression, this,
- GetHQLQueryPlan(queryExpression, false).ParameterMetadata);
+ HQLQueryPlan queryPlan = GetHQLQueryPlan(queryExpression, false);
+ QueryImpl query = new QueryImpl(queryPlan.QueryExpression, this,
+ queryPlan.ParameterMetadata);
query.SetComment("[expression]");
return query;
}
Modified: trunk/nhibernate/src/NHibernate/Impl/QueryImpl.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Impl/QueryImpl.cs 2009-09-27 10:06:52 UTC (rev 4730)
+++ trunk/nhibernate/src/NHibernate/Impl/QueryImpl.cs 2009-09-28 17:04:14 UTC (rev 4731)
@@ -74,6 +74,7 @@
}
else
{
+ _queryExpression.SetQueryParametersPriorToExecute(this);
return Session.List(_queryExpression, GetQueryParameters(namedParams));
}
}
Modified: trunk/nhibernate/src/NHibernate/Linq/CommandData.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/CommandData.cs 2009-09-27 10:06:52 UTC (rev 4730)
+++ trunk/nhibernate/src/NHibernate/Linq/CommandData.cs 2009-09-28 17:04:14 UTC (rev 4731)
@@ -8,8 +8,10 @@
{
public class CommandData
{
+ private readonly NamedParameter[] _namedParameters;
private readonly List<LambdaExpression> _itemTransformers;
private readonly List<LambdaExpression> _listTransformers;
+ private readonly List<Action<IQuery>> _additionalCriteria;
public CommandData(HqlQuery statement, NamedParameter[] namedParameters, List<LambdaExpression> itemTransformers, List<LambdaExpression> listTransformers, List<Action<IQuery>> additionalCriteria)
{
@@ -17,47 +19,29 @@
_listTransformers = listTransformers;
Statement = statement;
- NamedParameters = namedParameters;
- AdditionalCriteria = additionalCriteria;
+ _namedParameters = namedParameters;
+ _additionalCriteria = additionalCriteria;
}
public HqlQuery Statement { get; private set; }
- public NamedParameter[] NamedParameters { get; private set; }
- public List<Action<IQuery>> AdditionalCriteria { get; set; }
-
- public System.Type QueryResultType { get; set; }
-
- public IQuery CreateQuery(ISession session, System.Type type)
+ public void SetParameters(IQuery query)
{
- var query = session.CreateQuery(new HqlExpression(Statement, type));
-
- SetParameters(query);
-
- SetResultTransformer(query);
-
- AddAdditionalCriteria(query);
-
- return query;
- }
-
- private void SetParameters(IQuery query)
- {
- foreach (var parameter in NamedParameters)
+ foreach (var parameter in _namedParameters)
{
query.SetParameter(parameter.Name, parameter.Value);
}
}
- private void AddAdditionalCriteria(IQuery query)
+ public void AddAdditionalCriteria(IQuery query)
{
- foreach (var criteria in AdditionalCriteria)
+ foreach (var criteria in _additionalCriteria)
{
criteria(query);
}
}
- private void SetResultTransformer(IQuery query)
+ public void SetResultTransformer(IQuery query)
{
var itemTransformer = MergeLambdas(_itemTransformers);
var listTransformer = MergeLambdas(_listTransformers);
Deleted: trunk/nhibernate/src/NHibernate/Linq/NhQueryExecutor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/NhQueryExecutor.cs 2009-09-27 10:06:52 UTC (rev 4730)
+++ trunk/nhibernate/src/NHibernate/Linq/NhQueryExecutor.cs 2009-09-28 17:04:14 UTC (rev 4731)
@@ -1,39 +0,0 @@
-using System.Collections.Generic;
-using System.Linq;
-using Remotion.Data.Linq;
-
-namespace NHibernate.Linq
-{
- public class NhQueryExecutor : IQueryExecutor
- {
- private readonly ISession _session;
-
- public NhQueryExecutor(ISession session)
- {
- _session = session;
- }
-
- // Executes a query with a scalar result, i.e. a query that ends with a result operator such as Count, Sum, or Average.
- public T ExecuteScalar<T>(QueryModel queryModel)
- {
- return ExecuteCollection<T>(queryModel).Single();
- }
-
- // Executes a query with a single result object, i.e. a query that ends with a result operator such as First, Last, Single, Min, or Max.
- public T ExecuteSingle<T>(QueryModel queryModel, bool returnDefaultWhenEmpty)
- {
- return returnDefaultWhenEmpty ? ExecuteCollection<T>(queryModel).SingleOrDefault() : ExecuteCollection<T>(queryModel).Single();
- }
-
- // Executes a query with a collection result.
- public IEnumerable<T> ExecuteCollection<T>(QueryModel queryModel)
- {
- var commandData = QueryModelVisitor.GenerateHqlQuery(queryModel);
-
- var query = commandData.CreateQuery(_session, typeof(T));
-
- // TODO - check which call on Query makes most sense...
- return (IEnumerable<T>) query.List();
- }
- }
-}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Linq/NhQueryable.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/NhQueryable.cs 2009-09-27 10:06:52 UTC (rev 4730)
+++ trunk/nhibernate/src/NHibernate/Linq/NhQueryable.cs 2009-09-28 17:04:14 UTC (rev 4731)
@@ -1,6 +1,10 @@
+using System;
using System.Linq;
using System.Linq.Expressions;
+using NHibernate.Hql.Ast.ANTLR.Tree;
+using NHibernate.Impl;
using Remotion.Data.Linq;
+using Remotion.Data.Linq.Parsing.Structure;
namespace NHibernate.Linq
{
@@ -9,14 +13,9 @@
/// </summary>
public class NhQueryable<T> : QueryableBase<T>
{
- private static IQueryExecutor CreateExecutor(ISession session)
- {
- return new NhQueryExecutor(session);
- }
-
// This constructor is called by our users, create a new IQueryExecutor.
public NhQueryable(ISession session)
- : base(CreateExecutor(session))
+ : base(new NhQueryProvider(session))
{
}
@@ -26,4 +25,95 @@
{
}
}
+
+ public class NhQueryProvider : IQueryProvider
+ {
+ private readonly ISession _session;
+
+ public NhQueryProvider(ISession session)
+ {
+ _session = session;
+ }
+
+ public object Execute(Expression expression)
+ {
+ var nhLinqExpression = new NhLinqExpression(expression);
+
+ var query = _session.CreateQuery(nhLinqExpression).List();
+
+ if (nhLinqExpression.ReturnType == NhLinqExpressionReturnType.Sequence)
+ {
+ return query.AsQueryable();
+ }
+
+ return query[0];
+ }
+
+ public TResult Execute<TResult>(Expression expression)
+ {
+ return (TResult) Execute(expression);
+ }
+
+ public IQueryable CreateQuery(Expression expression)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IQueryable<T> CreateQuery<T>(Expression expression)
+ {
+ return new NhQueryable<T>(this, expression);
+ }
+ }
+
+ public enum NhLinqExpressionReturnType
+ {
+ Sequence,
+ Scalar
+ }
+
+ public class NhLinqExpression : IQueryExpression
+ {
+ private readonly Expression _expression;
+ private CommandData _commandData;
+
+ public NhLinqExpression(Expression expression)
+ {
+ _expression = expression;
+
+ Key = expression.ToString();
+
+ Type = expression.Type;
+
+ // Note - re-linq handles return types via the GetOutputDataInfo method, and allows for SingleOrDefault here for the ChoiceResultOperator...
+ ReturnType = NhLinqExpressionReturnType.Scalar;
+
+ if (typeof(IQueryable).IsAssignableFrom(Type))
+ {
+ Type = Type.GetGenericArguments()[0];
+ ReturnType = NhLinqExpressionReturnType.Sequence;
+ }
+ }
+
+ public IASTNode Translate(ISessionFactory sessionFactory)
+ {
+ var queryModel = new QueryParser(new ExpressionTreeParser(MethodCallExpressionNodeTypeRegistry.CreateDefault())).GetParsedQuery(_expression);
+
+ _commandData = QueryModelVisitor.GenerateHqlQuery(queryModel);
+
+ return _commandData.Statement.AstNode;
+ }
+
+ public string Key { get; private set; }
+
+ public NhLinqExpressionReturnType ReturnType { get; private set; }
+
+ public System.Type Type { get; private set; }
+
+ public void SetQueryParametersPriorToExecute(QueryImpl impl)
+ {
+ _commandData.SetParameters(impl);
+ _commandData.SetResultTransformer(impl);
+ _commandData.AddAdditionalCriteria(impl);
+ }
+ }
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-09-27 10:06:52 UTC (rev 4730)
+++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-09-28 17:04:14 UTC (rev 4731)
@@ -557,7 +557,6 @@
<Compile Include="Hql\Ast\ANTLR\Tree\ASTErrorNode.cs" />
<Compile Include="Hql\Ast\ANTLR\Tree\InsertStatement.cs" />
<Compile Include="Hql\Ast\ANTLR\Tree\UpdateStatement.cs" />
- <Compile Include="Hql\Ast\HqlExpression.cs" />
<Compile Include="Hql\Ast\HqlTreeBuilder.cs" />
<Compile Include="Hql\Ast\HqlTreeNode.cs" />
<Compile Include="IQueryExpression.cs" />
@@ -581,7 +580,6 @@
<Compile Include="Linq\NhExpressionTreeVisitor.cs" />
<Compile Include="Linq\NhNewExpression.cs" />
<Compile Include="Linq\NhQueryable.cs" />
- <Compile Include="Linq\NhQueryExecutor.cs" />
<Compile Include="Linq\NhThrowingExpressionTreeVisitor.cs" />
<Compile Include="Linq\Nominator.cs" />
<Compile Include="Linq\NonAggregatingGroupBy.cs" />
Modified: trunk/nhibernate/src/NHibernate.Test/Linq/LinqTestCase.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Linq/LinqTestCase.cs 2009-09-27 10:06:52 UTC (rev 4730)
+++ trunk/nhibernate/src/NHibernate.Test/Linq/LinqTestCase.cs 2009-09-28 17:04:14 UTC (rev 4731)
@@ -13,6 +13,16 @@
private Northwind _northwind;
private ISession _session;
+ protected override bool PerformDbDataSetup
+ {
+ get { return true; }
+ }
+
+ protected override bool PerformDbDataTeardown
+ {
+ get { return true; }
+ }
+
protected override string MappingsAssembly
{
get { return "NHibernate.Test"; }
Modified: trunk/nhibernate/src/NHibernate.Test/Linq/ReadonlyTestCase.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Linq/ReadonlyTestCase.cs 2009-09-27 10:06:52 UTC (rev 4730)
+++ trunk/nhibernate/src/NHibernate.Test/Linq/ReadonlyTestCase.cs 2009-09-28 17:04:14 UTC (rev 4731)
@@ -63,6 +63,9 @@
get { return "NHibernate.DomainModel"; }
}
+ protected abstract bool PerformDbDataSetup { get; }
+ protected abstract bool PerformDbDataTeardown { get; }
+
static ReadonlyTestCase()
{
// Configure log4net here since configuration through an attribute doesn't always work.
@@ -84,7 +87,12 @@
}
BuildSessionFactory();
- CreateSchema();
+
+ if (PerformDbDataSetup)
+ {
+ CreateSchema();
+ }
+
if (!AppliesTo(_sessions))
{
DropSchema();
@@ -92,7 +100,10 @@
Assert.Ignore(GetType() + " does not apply with the current session-factory configuration");
}
- OnFixtureSetup();
+ if (PerformDbDataSetup)
+ {
+ OnFixtureSetup();
+ }
}
catch (Exception e)
{
@@ -114,8 +125,12 @@
public void TestFixtureTearDown()
{
OnFixtureTeardown();
-
- DropSchema();
+
+ if (PerformDbDataTeardown)
+ {
+ DropSchema();
+ }
+
Cleanup();
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|