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 17 commits
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
117 changes: 117 additions & 0 deletions src/NHibernate.Test/Async/QueryTranslator/CustomQueryLoaderFixture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
//------------------------------------------------------------------------------
// <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.Linq;
using NHibernate.Cfg;
using NHibernate.DomainModel.Northwind.Entities;
using NUnit.Framework;
using NHibernate.Linq;

namespace NHibernate.Test.QueryTranslator
{
using System.Threading.Tasks;
[TestFixture(Description = "Tests a custom query translator factory for all query interfaces.")]
internal sealed class CustomQueryLoaderFixtureAsync : TestCase
{
private ISession _session;
private ITransaction _transaction;

protected override string[] Mappings => new[]
{
"Northwind.Mappings.Customer.hbm.xml",
"Northwind.Mappings.Employee.hbm.xml",
"Northwind.Mappings.Order.hbm.xml",
"Northwind.Mappings.OrderLine.hbm.xml",
"Northwind.Mappings.Product.hbm.xml",
"Northwind.Mappings.ProductCategory.hbm.xml",
"Northwind.Mappings.Region.hbm.xml",
"Northwind.Mappings.Shipper.hbm.xml",
"Northwind.Mappings.Supplier.hbm.xml",
"Northwind.Mappings.Territory.hbm.xml",
"Northwind.Mappings.AnotherEntity.hbm.xml",
"Northwind.Mappings.Role.hbm.xml",
"Northwind.Mappings.User.hbm.xml",
"Northwind.Mappings.TimeSheet.hbm.xml",
"Northwind.Mappings.Animal.hbm.xml",
"Northwind.Mappings.Patient.hbm.xml",
"Northwind.Mappings.NumericEntity.hbm.xml"
};

protected override string MappingsAssembly => "NHibernate.DomainModel";

protected override void Configure(Configuration configuration)
{
configuration.SetProperty(Environment.QueryTranslator, typeof(CustomQueryTranslatorFactory).AssemblyQualifiedName);
}

protected override void OnSetUp()
{
base.OnSetUp();

_session = OpenSession();
_transaction = _session.BeginTransaction();

var customer = new Customer
{
CustomerId = "C1",
CompanyName = "Company"
};
_session.Save(customer);
_session.Flush();
_session.Clear();
}

protected override void OnTearDown()
{
base.OnTearDown();

_transaction.Rollback();
_transaction.Dispose();
_session.Close();
_session.Dispose();
}

[Test(Description = "Tests criteria queries.")]
public async Task CriteriaQueryTestAsync()
{
var customers = await (_session.CreateCriteria(typeof(Customer))
.ListAsync<Customer>());

Assert.AreEqual(1, customers.Count);
}

[Test(Description = "Tests HQL queries.")]
public async Task HqlQueryTestAsync()
{
var customers = await (_session.CreateQuery("select c from Customer c")
.ListAsync<Customer>());

Assert.AreEqual(1, customers.Count);
}

[Test(Description = "Tests LINQ queries.")]
public async Task LinqQueryTestAsync()
{
var customers = await (_session.Query<Customer>()
.ToListAsync());

Assert.AreEqual(1, customers.Count);
}

[Test(Description = "Tests query over queries.")]
public async Task QueryOverQueryTestAsync()
{
var customers = await (_session.QueryOver<Customer>()
.ListAsync<Customer>());

Assert.AreEqual(1, customers.Count);
}
}
}
9 changes: 8 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,7 +37,11 @@ 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,
new QueryLoaderFactory());
qt.Compile(null, false);
return qt.SQLString;
}
Expand Down
9 changes: 8 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,7 +42,11 @@ 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,
new QueryLoaderFactory());
qt.Compile(replacements, false);
return qt.SQLString;
}
Expand Down
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,7 +30,11 @@ 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,
new QueryLoaderFactory());
qt.Compile(null, false);
return qt.SQLString;
}
Expand Down
206 changes: 206 additions & 0 deletions src/NHibernate.Test/QueryTranslator/CustomQueryLoader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.Common;
using System.Threading;
using System.Threading.Tasks;
using NHibernate.Cache;
using NHibernate.Engine;
using NHibernate.Event;
using NHibernate.Loader.Hql;
using NHibernate.Persister;
using NHibernate.Persister.Entity;
using NHibernate.SqlCommand;
using NHibernate.Transform;
using NHibernate.Type;

namespace NHibernate.Test.QueryTranslator
{
/// <summary>
/// Custom query loader to test the functionality of custom query translator factory
/// with a custom query loader factory.
/// </summary>
internal sealed class CustomQueryLoader: IQueryLoader
{
private readonly IQueryLoader _queryLoader;

public CustomQueryLoader(IQueryLoader queryLoader)
{
_queryLoader = queryLoader;
}

public 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)
{
return _queryLoader.GetRowFromResultSetAsync(resultSet, session, queryParameters, lockModeArray, optionalObjectKey, hydratedObjects, keys, returnProxies, forcedResultTransformer, queryCacheResultBuilder, cacheBatchingHandler, cancellationToken);
}

public Task InitializeEntitiesAndCollectionsAsync(
IList hydratedObjects,
DbDataReader reader,
ISessionImplementor session,
bool readOnly,
CacheBatcher cacheBatcher,
CancellationToken cancellationToken)
{
return _queryLoader.InitializeEntitiesAndCollectionsAsync(hydratedObjects, reader, session, readOnly, cacheBatcher, cancellationToken);
}

public Task LoadCollectionAsync(ISessionImplementor session, object id, IType type, CancellationToken cancellationToken)
{
return _queryLoader.LoadCollectionAsync(session, id, type, cancellationToken);
}

public Task LoadCollectionBatchAsync(
ISessionImplementor session,
object[] ids,
IType type,
CancellationToken cancellationToken)
{
return _queryLoader.LoadCollectionBatchAsync(session, ids, type, cancellationToken);
}

public bool IsSubselectLoadingEnabled => _queryLoader.IsSubselectLoadingEnabled;

public IType[] ResultTypes => _queryLoader.ResultTypes;

public IType[] CacheTypes => _queryLoader.CacheTypes;

public Loader.Loader.QueryCacheInfo CacheInfo => _queryLoader.CacheInfo;

public ISessionFactoryImplementor Factory => _queryLoader.Factory;

public SqlString SqlString => _queryLoader.SqlString;

public ILoadable[] EntityPersisters => _queryLoader.EntityPersisters;

public string QueryIdentifier => _queryLoader.QueryIdentifier;

public LockMode[] GetLockModes(IDictionary<string, LockMode> lockModes)
{
return _queryLoader.GetLockModes(lockModes);
}

public object GetRowFromResultSet(
DbDataReader resultSet,
ISessionImplementor session,
QueryParameters queryParameters,
LockMode[] lockModeArray,
EntityKey optionalObjectKey,
IList hydratedObjects,
EntityKey[] keys,
bool returnProxies,
IResultTransformer forcedResultTransformer,
QueryCacheResultBuilder queryCacheResultBuilder,
Action<IEntityPersister, CachePutData> cacheBatchingHandler)
{
return _queryLoader.GetRowFromResultSet(resultSet, session, queryParameters, lockModeArray, optionalObjectKey, hydratedObjects, keys, returnProxies, forcedResultTransformer, queryCacheResultBuilder, cacheBatchingHandler);
}

public void CreateSubselects(List<EntityKey[]> keys, QueryParameters queryParameters, ISessionImplementor session)
{
_queryLoader.CreateSubselects(keys, queryParameters, session);
}

public void InitializeEntitiesAndCollections(
IList hydratedObjects,
DbDataReader reader,
ISessionImplementor session,
bool readOnly,
CacheBatcher cacheBatcher)
{
_queryLoader.InitializeEntitiesAndCollections(hydratedObjects, reader, session, readOnly, cacheBatcher);
}

public IList GetResultList(IList results, IResultTransformer resultTransformer)
{
return _queryLoader.GetResultList(results, resultTransformer);
}

public bool UseLimit(RowSelection selection, Dialect.Dialect dialect)
{
return _queryLoader.UseLimit(selection, dialect);
}

public void LoadCollection(ISessionImplementor session, object id, IType type)
{
_queryLoader.LoadCollection(session, id, type);
}

public void LoadCollectionBatch(ISessionImplementor session, object[] ids, IType type)
{
_queryLoader.LoadCollectionBatch(session, ids, type);
}

public bool IsCacheable(QueryParameters queryParameters)
{
return _queryLoader.IsCacheable(queryParameters);
}

public bool IsCacheable(QueryParameters queryParameters, bool supportsQueryCache, IEnumerable<IPersister> persisters)
{
return _queryLoader.IsCacheable(queryParameters, supportsQueryCache, persisters);
}

public ISqlCommand CreateSqlCommand(QueryParameters queryParameters, ISessionImplementor session)
{
return _queryLoader.CreateSqlCommand(queryParameters, session);
}

public void AutoDiscoverTypes(DbDataReader rs, QueryParameters queryParameters, IResultTransformer forcedResultTransformer)
{
_queryLoader.AutoDiscoverTypes(rs, queryParameters, forcedResultTransformer);
}

public IList TransformCacheableResults(QueryParameters queryParameters, CacheableResultTransformer transformer, IList result)
{
return _queryLoader.TransformCacheableResults(queryParameters, transformer, result);
}

public void HandleEmptyCollections(object[] keys, object resultSetId, ISessionImplementor session)
{
_queryLoader.HandleEmptyCollections(keys, resultSetId, session);
}

public void StopLoadingCollections(ISessionImplementor session, DbDataReader reader)
{
_queryLoader.StopLoadingCollections(session, reader);
}

public QueryKey GenerateQueryKey(ISessionImplementor session, QueryParameters queryParameters)
{
return _queryLoader.GenerateQueryKey(session, queryParameters);
}

public IList List(ISessionImplementor session, QueryParameters queryParameters)
{
return _queryLoader.List(session, queryParameters);
}

public IEnumerable GetEnumerable(QueryParameters queryParameters, IEventSource session)
{
return _queryLoader.GetEnumerable(queryParameters, session);
}

public Task<IList> ListAsync(ISessionImplementor session, QueryParameters queryParameters, CancellationToken cancellationToken)
{
return _queryLoader.ListAsync(session, queryParameters, cancellationToken);
}

public Task<IEnumerable> GetEnumerableAsync(QueryParameters queryParameters, IEventSource session, CancellationToken cancellationToken)
{
return _queryLoader.GetEnumerableAsync(queryParameters, session, cancellationToken);
}
}
}
Loading