Skip to content

Allow custom query loader #3209

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build-common/NHibernate.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

<PropertyGroup>
<NhVersion Condition="'$(NhVersion)' == ''" >5.4</NhVersion>
<VersionPatch Condition="'$(VersionPatch)' == ''">0</VersionPatch>
<VersionPatch Condition="'$(VersionPatch)' == ''">1</VersionPatch>
<!-- Clear VersionSuffix for making release and set it to dev for making development builds -->
<VersionSuffix Condition="'$(VersionSuffix)' == ''"></VersionSuffix>
<LangVersion Condition="'$(MSBuildProjectExtension)' != '.vbproj'">9.0</LangVersion>
Expand Down
18 changes: 17 additions & 1 deletion src/NHibernate.Test/BulkManipulation/BaseFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
using System.Collections;
using NHibernate.Hql.Ast.ANTLR;
using System.Collections.Generic;
using NHibernate.Engine;
using NHibernate.Hql.Ast.ANTLR.Tree;
using NHibernate.Loader.Hql;
using NHibernate.Util;

namespace NHibernate.Test.BulkManipulation
Expand Down Expand Up @@ -34,9 +37,22 @@ protected override void Configure(Cfg.Configuration configuration)

public string GetSql(string query)
{
var qt = new QueryTranslatorImpl(null, new HqlParseEngine(query, false, Sfi).Parse(), emptyfilters, Sfi);
var qt = new QueryTranslatorImpl(null,
new HqlParseEngine(query, false, Sfi).Parse(),
emptyfilters,
Sfi,
CreateQueryLoader);
qt.Compile(null, false);
return qt.SQLString;
}

private static IQueryLoader CreateQueryLoader(QueryTranslatorImpl queryTranslatorImpl,
ISessionFactoryImplementor sessionFactoryImplementor,
SelectClause selectClause)
{
return new QueryLoader(queryTranslatorImpl,
sessionFactoryImplementor,
selectClause);
}
}
}
18 changes: 17 additions & 1 deletion src/NHibernate.Test/Hql/Ast/BaseFixture.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
using System;
using System.Collections;
using System.Collections.Generic;
using NHibernate.Engine;
using NHibernate.Hql.Ast.ANTLR;
using NHibernate.Hql.Ast.ANTLR.Tree;
using NHibernate.Loader.Hql;
using NHibernate.Util;

namespace NHibernate.Test.Hql.Ast
Expand Down Expand Up @@ -39,9 +42,22 @@ public string GetSql(string query)

public string GetSql(string query, IDictionary<string, string> replacements)
{
var qt = new QueryTranslatorImpl(null, new HqlParseEngine(query, false, Sfi).Parse(), emptyfilters, Sfi);
var qt = new QueryTranslatorImpl(null,
new HqlParseEngine(query, false, Sfi).Parse(),
emptyfilters,
Sfi,
CreateQueryLoader);
qt.Compile(replacements, false);
return qt.SQLString;
}

private static IQueryLoader CreateQueryLoader(QueryTranslatorImpl queryTranslatorImpl,
ISessionFactoryImplementor sessionFactoryImplementor,
SelectClause selectClause)
{
return new QueryLoader(queryTranslatorImpl,
sessionFactoryImplementor,
selectClause);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using NHibernate.Dialect;
using NHibernate.Engine;
using NHibernate.Hql.Ast.ANTLR;
using NHibernate.Hql.Ast.ANTLR.Tree;
using NHibernate.Loader.Hql;
using NHibernate.Util;
using NUnit.Framework;

Expand Down Expand Up @@ -27,9 +30,22 @@ public void TheModuleOperationShouldAddParenthesisToAvoidWrongSentence()

public string GetSql(string query)
{
var qt = new QueryTranslatorImpl(null, new HqlParseEngine(query, false, Sfi).Parse(), CollectionHelper.EmptyDictionary<string, IFilter>(), Sfi);
var qt = new QueryTranslatorImpl(null,
new HqlParseEngine(query, false, Sfi).Parse(),
CollectionHelper.EmptyDictionary<string, IFilter>(),
Sfi,
CreateQueryLoader);
qt.Compile(null, false);
return qt.SQLString;
}

private static IQueryLoader CreateQueryLoader(QueryTranslatorImpl queryTranslatorImpl,
ISessionFactoryImplementor sessionFactoryImplementor,
SelectClause selectClause)
{
return new QueryLoader(queryTranslatorImpl,
sessionFactoryImplementor,
selectClause);
}
}
}
2 changes: 1 addition & 1 deletion src/NHibernate/Async/Hql/Ast/ANTLR/QueryTranslatorImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@
using System.Linq;
using Antlr.Runtime;
using Antlr.Runtime.Tree;

using NHibernate.Engine;
using NHibernate.Engine.Query;
using NHibernate.Event;
using NHibernate.Hql.Ast.ANTLR.Exec;
using NHibernate.Hql.Ast.ANTLR.Tree;
using NHibernate.Hql.Ast.ANTLR.Util;
using NHibernate.Loader;
using NHibernate.Loader.Hql;
using NHibernate.Param;
using NHibernate.Persister;
Expand Down
1 change: 1 addition & 0 deletions src/NHibernate/Async/Hql/IQueryTranslator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using NHibernate.Engine;
using NHibernate.Engine.Query;
using NHibernate.Event;
using NHibernate.Loader;
using NHibernate.Type;

namespace NHibernate.Hql
Expand Down
1 change: 1 addition & 0 deletions src/NHibernate/Async/Impl/MultiQueryImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
using NHibernate.Engine.Query.Sql;
using NHibernate.Exceptions;
using NHibernate.Hql;
using NHibernate.Loader;
using NHibernate.Loader.Custom;
using NHibernate.Loader.Custom.Sql;
using NHibernate.SqlCommand;
Expand Down
24 changes: 24 additions & 0 deletions src/NHibernate/Async/Loader/Hql/IQueryLoader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by AsyncGenerator.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------


using System.Collections;
using NHibernate.Engine;
using NHibernate.Event;

namespace NHibernate.Loader.Hql
{
using System.Threading.Tasks;
using System.Threading;
public partial interface IQueryLoader: ILoader
{
Task<IList> ListAsync(ISessionImplementor session, QueryParameters queryParameters, CancellationToken cancellationToken);
Task<IEnumerable> GetEnumerableAsync(QueryParameters queryParameters, IEventSource session, CancellationToken cancellationToken);
}
}
5 changes: 2 additions & 3 deletions src/NHibernate/Async/Loader/Hql/QueryLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
using System.Collections.Generic;
using System.Data.Common;
using System.Diagnostics;
using System.Linq;
using NHibernate.Engine;
using NHibernate.Event;
using NHibernate.Hql.Ast.ANTLR;
Expand All @@ -32,7 +31,7 @@ namespace NHibernate.Loader.Hql
{
using System.Threading.Tasks;
using System.Threading;
public partial class QueryLoader : BasicLoader
public partial class QueryLoader : BasicLoader, IQueryLoader
{

public Task<IList> ListAsync(ISessionImplementor session, QueryParameters queryParameters, CancellationToken cancellationToken)
Expand Down Expand Up @@ -89,7 +88,7 @@ protected override async Task<object[]> GetResultRowAsync(object[] row, DbDataRe
return resultRow;
}

internal async Task<IEnumerable> GetEnumerableAsync(QueryParameters queryParameters, IEventSource session, CancellationToken cancellationToken)
public async Task<IEnumerable> GetEnumerableAsync(QueryParameters queryParameters, IEventSource session, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
CheckQuery(queryParameters);
Expand Down
57 changes: 57 additions & 0 deletions src/NHibernate/Async/Loader/ILoader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by AsyncGenerator.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------


using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.Common;
using NHibernate.Cache;
using NHibernate.Engine;
using NHibernate.Persister;
using NHibernate.Persister.Entity;
using NHibernate.SqlCommand;
using NHibernate.Transform;
using NHibernate.Type;

namespace NHibernate.Loader
{
using System.Threading.Tasks;
using System.Threading;
public partial interface ILoader
{

Task<object> GetRowFromResultSetAsync(DbDataReader resultSet, ISessionImplementor session,
QueryParameters queryParameters, LockMode[] lockModeArray,
EntityKey optionalObjectKey, IList hydratedObjects, EntityKey[] keys,
bool returnProxies, IResultTransformer forcedResultTransformer,
QueryCacheResultBuilder queryCacheResultBuilder,
Action<IEntityPersister, CachePutData> cacheBatchingHandler, CancellationToken cancellationToken);

Task InitializeEntitiesAndCollectionsAsync(IList hydratedObjects,
DbDataReader reader,
ISessionImplementor session,
bool readOnly,
CacheBatcher cacheBatcher, CancellationToken cancellationToken);

/// <summary>
/// Called by subclasses that load collections
/// </summary>
Task LoadCollectionAsync(ISessionImplementor session,
object id,
IType type, CancellationToken cancellationToken);

/// <summary>
/// Called by wrappers that batch initialize collections
/// </summary>
Task LoadCollectionBatchAsync(ISessionImplementor session,
object[] ids,
IType type, CancellationToken cancellationToken);
}
}
22 changes: 12 additions & 10 deletions src/NHibernate/Async/Loader/Loader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ namespace NHibernate.Loader
{
using System.Threading.Tasks;
using System.Threading;
public abstract partial class Loader
public abstract partial class Loader : ILoader
{

/// <summary>
Expand Down Expand Up @@ -141,12 +141,12 @@ protected async Task<object> LoadSingleRowAsync(DbDataReader resultSet, ISession
return result;
}

internal async Task<object> GetRowFromResultSetAsync(DbDataReader resultSet, ISessionImplementor session,
QueryParameters queryParameters, LockMode[] lockModeArray,
EntityKey optionalObjectKey, IList hydratedObjects, EntityKey[] keys,
bool returnProxies, IResultTransformer forcedResultTransformer,
QueryCacheResultBuilder queryCacheResultBuilder,
Action<IEntityPersister, CachePutData> cacheBatchingHandler, CancellationToken cancellationToken)
public async Task<object> GetRowFromResultSetAsync(DbDataReader resultSet, ISessionImplementor session,
QueryParameters queryParameters, LockMode[] lockModeArray,
EntityKey optionalObjectKey, IList hydratedObjects, EntityKey[] keys,
bool returnProxies, IResultTransformer forcedResultTransformer,
QueryCacheResultBuilder queryCacheResultBuilder,
Action<IEntityPersister, CachePutData> cacheBatchingHandler, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
ILoadable[] persisters = EntityPersisters;
Expand Down Expand Up @@ -341,9 +341,11 @@ private async Task<IList> DoQueryAsync(ISessionImplementor session, QueryParamet
}
}

internal async Task InitializeEntitiesAndCollectionsAsync(
IList hydratedObjects, DbDataReader reader, ISessionImplementor session, bool readOnly,
CacheBatcher cacheBatcher, CancellationToken cancellationToken)
public async Task InitializeEntitiesAndCollectionsAsync(IList hydratedObjects,
DbDataReader reader,
ISessionImplementor session,
bool readOnly,
CacheBatcher cacheBatcher, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
ICollectionPersister[] collectionPersisters = CollectionPersisters;
Expand Down
1 change: 1 addition & 0 deletions src/NHibernate/Async/Multi/QueryBatchItemBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using System.Linq;
using NHibernate.Cache;
using NHibernate.Engine;
using NHibernate.Loader;
using NHibernate.SqlCommand;
using NHibernate.Type;
using NHibernate.Util;
Expand Down
2 changes: 1 addition & 1 deletion src/NHibernate/Cache/CachePutData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace NHibernate.Cache
/// <summary>
/// The data used to put a value to the 2nd level cache.
/// </summary>
internal class CachePutData
public class CachePutData
{
public CachePutData(CacheKey key, object value, object version, IComparer versionComparer, bool minimalPut)
{
Expand Down
5 changes: 3 additions & 2 deletions src/NHibernate/Cache/QueryCacheResultBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections;
using System.Collections.Generic;
using NHibernate.Collection;
using NHibernate.Loader;
using NHibernate.Type;

namespace NHibernate.Cache
Expand All @@ -14,12 +15,12 @@ public sealed class QueryCacheResultBuilder
private readonly IType[] _resultTypes;
private readonly Loader.Loader.QueryCacheInfo _cacheInfo;

public static bool IsCacheWithFetches(Loader.Loader loader)
public static bool IsCacheWithFetches(ILoader loader)
{
return loader.CacheTypes.Length > loader.ResultTypes.Length;
}

internal QueryCacheResultBuilder(Loader.Loader loader)
internal QueryCacheResultBuilder(ILoader loader)
{
_resultTypes = loader.ResultTypes;

Expand Down
15 changes: 10 additions & 5 deletions src/NHibernate/Engine/Query/QueryPlanCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,14 @@ public IQueryExpressionPlan GetHQLQueryPlan(IQueryExpression queryExpression, bo

plan = new QueryExpressionPlan(queryExpression, shallow, enabledFilters, factory);
// 6.0 TODO: add "CanCachePlan { get; }" to IQueryExpression interface
if (!(queryExpression is ICacheableQueryExpression linqExpression) || linqExpression.CanCachePlan)
if(queryExpression is ICacheableQueryExpression linqExpression && linqExpression.CanCachePlan)
{
planCache.Put(key, PreparePlanToCache(plan));
}
else
{
log.Debug("Query plan not cacheable");
}
}
else
{
Expand All @@ -88,7 +92,7 @@ public IQueryExpressionPlan GetHQLQueryPlan(IQueryExpression queryExpression, bo

private QueryExpressionPlan PreparePlanToCache(QueryExpressionPlan plan)
{
if (plan.QueryExpression is NhLinqExpression planExpression)
if (plan.QueryExpression is ILinqQueryExpression planExpression)
{
return plan.Copy(new NhLinqExpressionCache(planExpression));
}
Expand All @@ -98,7 +102,8 @@ private QueryExpressionPlan PreparePlanToCache(QueryExpressionPlan plan)

private static QueryExpressionPlan CopyIfRequired(QueryExpressionPlan plan, IQueryExpression queryExpression)
{
if (plan.QueryExpression is NhLinqExpressionCache cache && queryExpression is NhLinqExpression expression)
if (plan.QueryExpression is NhLinqExpressionCache cache &&
queryExpression is ILinqQueryExpression linqExpression)
{
//NH-3413
//Here we have to use original expression.
Expand All @@ -109,8 +114,8 @@ private static QueryExpressionPlan CopyIfRequired(QueryExpressionPlan plan, IQue
//NH-3436
// We have to return new instance plan with it's own query expression
// because other treads can override query expression of current plan during execution of query if we will use cached instance of plan
expression.CopyExpressionTranslation(cache);
plan = plan.Copy(expression);
linqExpression.CopyExpressionTranslation(cache);
plan = plan.Copy(linqExpression);
}

return plan;
Expand Down
Loading