From: <fab...@us...> - 2011-03-24 18:06:13
|
Revision: 5520 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5520&view=rev Author: fabiomaulo Date: 2011-03-24 18:06:06 +0000 (Thu, 24 Mar 2011) Log Message: ----------- Fix NH-2495 (thanks to Gerke Geurts) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1508/Fixture.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/QueryTest/MultipleMixedQueriesFixture.cs Modified: trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs 2011-03-24 17:28:29 UTC (rev 5519) +++ trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs 2011-03-24 18:06:06 UTC (rev 5520) @@ -8,7 +8,10 @@ using NHibernate.Cache; using NHibernate.Driver; using NHibernate.Engine; +using NHibernate.Engine.Query.Sql; using NHibernate.Hql; +using NHibernate.Loader.Custom; +using NHibernate.Loader.Custom.Sql; using NHibernate.SqlCommand; using NHibernate.SqlTypes; using NHibernate.Transform; @@ -21,9 +24,9 @@ private static readonly IInternalLogger log = LoggerProvider.LoggerFor(typeof(MultiQueryImpl)); private readonly List<IQuery> queries = new List<IQuery>(); - private readonly List<IQueryTranslator> translators = new List<IQueryTranslator>(); - private readonly IList<System.Type> resultCollectionGenericType = new List<System.Type>(); - private readonly List<QueryParameters> parameters = new List<QueryParameters>(); + private readonly List<ITranslator> translators = new List<ITranslator>(); + private readonly IList<System.Type> resultCollectionGenericType = new List<System.Type>(); + private readonly List<QueryParameters> parameters = new List<QueryParameters>(); private IList queryResults; private readonly Dictionary<string, int> queryResultPositions = new Dictionary<string, int>(); private string cacheRegion; @@ -51,6 +54,8 @@ this.session = session; } + #region Parameters setting + public IMultiQuery SetResultTransformer(IResultTransformer transformer) { resultTransformer = transformer; @@ -267,6 +272,9 @@ return this; } + + #endregion + public IMultiQuery AddNamedQuery<T>(string key, string namedQuery) { ThrowIfKeyAlreadyExists(key); @@ -439,8 +447,8 @@ { // TODO : we need a test to check the behavior when the query has a 'new' istead a trasformer // we should take the HolderInstantiator directly from QueryTranslator... taking care with Parameters. - return Parameters[queryPosition].ResultTransformer != null ? - new HolderInstantiator(Parameters[queryPosition].ResultTransformer, translators[queryPosition].ReturnAliases) + return Parameters[queryPosition].ResultTransformer != null ? + new HolderInstantiator(Parameters[queryPosition].ResultTransformer, translators[queryPosition].ReturnAliases) : HolderInstantiator.NoopInstantiator; } @@ -480,10 +488,12 @@ try { if (log.IsDebugEnabled) + { log.DebugFormat("Executing {0} queries", translators.Count); + } for (int i = 0; i < translators.Count; i++) { - IQueryTranslator translator = Translators[i]; + ITranslator translator = Translators[i]; QueryParameters parameter = Parameters[i]; IList tempResults; if (resultCollectionGenericType[i] == typeof(object)) @@ -529,13 +539,13 @@ object result = translator.Loader.GetRowFromResultSet(reader, - session, - parameter, - lockModeArray, - optionalObjectKey, - hydratedObjects[i], - keys, - true); + session, + parameter, + lockModeArray, + optionalObjectKey, + hydratedObjects[i], + keys, + true); tempResults.Add(result); @@ -572,7 +582,7 @@ } for (int i = 0; i < translators.Count; i++) { - IQueryTranslator translator = translators[i]; + ITranslator translator = translators[i]; QueryParameters parameter = parameters[i]; translator.Loader.InitializeEntitiesAndCollections(hydratedObjects[i], reader, session, false); @@ -614,9 +624,7 @@ QueryParameters queryParameters = query.GetQueryParameters(); queryParameters.ValidateParameters(); query.VerifyParameters(); - IQueryTranslator[] queryTranslators = - session.GetQueries(query.ExpandParameterLists(queryParameters.NamedParameters), false); - foreach (IQueryTranslator translator in queryTranslators) + foreach (var translator in GetTranslators(query, queryParameters)) { translators.Add(translator); parameters.Add(queryParameters); @@ -628,12 +636,30 @@ } } - private static QueryParameters GetFilteredQueryParameters(QueryParameters queryParameters, IQueryTranslator translator) + private IEnumerable<ITranslator> GetTranslators(AbstractQueryImpl query, QueryParameters queryParameters) { + // NOTE: updates queryParameters.NamedParameters as (desired) side effect + var queryString = query.ExpandParameterLists(queryParameters.NamedParameters); + + var sqlQuery = query as ISQLQuery; + if (sqlQuery != null) + { + yield return new SqlTranslator(sqlQuery, session.Factory); + yield break; + } + + foreach (var queryTranslator in session.GetQueries(queryString, false)) + { + yield return new HqlTranslatorWrapper(queryTranslator); + } + } + + private static QueryParameters GetFilteredQueryParameters(QueryParameters queryParameters, ITranslator translator) + { QueryParameters filteredQueryParameters = queryParameters; Dictionary<string, TypedValue> namedParameters = new Dictionary<string, TypedValue>(queryParameters.NamedParameters); filteredQueryParameters.NamedParameters.Clear(); - foreach (string paramName in translator.GetParameterTranslations().GetNamedParameterNames()) + foreach (string paramName in translator.GetNamedParameterNames()) { TypedValue v; if (namedParameters.TryGetValue(paramName, out v)) @@ -723,9 +749,9 @@ List<IType[]> resultTypesList = new List<IType[]>(Translators.Count); for (int i = 0; i < Translators.Count; i++) { - IQueryTranslator queryTranslator = Translators[i]; + ITranslator queryTranslator = Translators[i]; querySpaces.AddAll(queryTranslator.QuerySpaces); - resultTypesList.Add(queryTranslator.ActualReturnTypes); + resultTypesList.Add(queryTranslator.ReturnTypes); } int[] firstRows = new int[Parameters.Count]; int[] maxRows = new int[Parameters.Count]; @@ -755,12 +781,14 @@ return GetResultList(result); } - private IList<IQueryTranslator> Translators + private IList<ITranslator> Translators { get { if (sqlString == null) + { AggregateQueriesInformation(); + } return translators; } } @@ -808,18 +836,94 @@ private int AddQueryForLaterExecutionAndReturnIndexOfQuery(System.Type resultGenericListType, IQuery query) { - ThrowNotSupportedIfSqlQuery(query); ((AbstractQueryImpl)query).SetIgnoreUknownNamedParameters(true); queries.Add(query); resultCollectionGenericType.Add(resultGenericListType); return queries.Count - 1; } - protected void ThrowNotSupportedIfSqlQuery(IQuery query) + + #endregion + + private interface ITranslator { - if (query is ISQLQuery) - throw new NotSupportedException("Sql queries in MultiQuery are currently not supported."); + Loader.Loader Loader { get; } + IType[] ReturnTypes { get; } + string[] ReturnAliases { get; } + ICollection<string> QuerySpaces { get; } + IEnumerable<string> GetNamedParameterNames(); } - #endregion + private class HqlTranslatorWrapper : ITranslator + { + private readonly IQueryTranslator innerTranslator; + + public HqlTranslatorWrapper(IQueryTranslator translator) + { + innerTranslator = translator; + } + + public Loader.Loader Loader + { + get { return innerTranslator.Loader; } + } + + public IType[] ReturnTypes + { + get { return innerTranslator.ActualReturnTypes; } + } + + public ICollection<string> QuerySpaces + { + get { return innerTranslator.QuerySpaces; } + } + + public string[] ReturnAliases + { + get { return innerTranslator.ReturnAliases; } + } + + public IEnumerable<string> GetNamedParameterNames() + { + return innerTranslator.GetParameterTranslations().GetNamedParameterNames(); + } + } + + private class SqlTranslator : ITranslator + { + private readonly CustomLoader loader; + + public SqlTranslator(ISQLQuery sqlQuery, ISessionFactoryImplementor sessionFactory) + { + var sqlQueryImpl = (SqlQueryImpl) sqlQuery; + NativeSQLQuerySpecification sqlQuerySpec = sqlQueryImpl.GenerateQuerySpecification(sqlQueryImpl.NamedParams); + var sqlCustomQuery = new SQLCustomQuery(sqlQuerySpec.SqlQueryReturns, sqlQuerySpec.QueryString, sqlQuerySpec.QuerySpaces, sessionFactory); + loader = new CustomLoader(sqlCustomQuery, sessionFactory); + } + + public IType[] ReturnTypes + { + get { return loader.ResultTypes; } + } + + public Loader.Loader Loader + { + get { return loader; } + } + + public ICollection<string> QuerySpaces + { + get { return loader.QuerySpaces; } + } + + public string[] ReturnAliases + { + get { return loader.ReturnAliases; } + } + + public IEnumerable<string> GetNamedParameterNames() + { + return loader.NamedParameters; + } + } } } Modified: trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs 2011-03-24 17:28:29 UTC (rev 5519) +++ trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs 2011-03-24 18:06:06 UTC (rev 5520) @@ -402,6 +402,21 @@ } } + public IType[] ResultTypes + { + get { return resultTypes; } + } + + public string[] ReturnAliases + { + get { return transformerAliases; } + } + + public IEnumerable<string> NamedParameters + { + get { return namedParameterBindPoints.Keys; } + } + public interface IResultColumnProcessor { object Extract(object[] data, IDataReader resultSet, ISessionImplementor session); Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1508/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1508/Fixture.cs 2011-03-24 17:28:29 UTC (rev 5519) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1508/Fixture.cs 2011-03-24 18:06:06 UTC (rev 5520) @@ -1,6 +1,7 @@ using System; using NHibernate.Driver; using NUnit.Framework; +using SharpTestsEx; namespace NHibernate.Test.NHSpecificTest.NH1508 { @@ -66,28 +67,27 @@ } [Test] - public void ThrowsExceptionWhenSqlQueryIsGiven() + public void DoesntThrowsExceptionWhenSqlQueryIsGiven() { using (ISession session = OpenSession()) using (ITransaction tx = session.BeginTransaction()) { ISQLQuery sqlQuery = session.CreateSQLQuery("select * from Document"); - Assert.Throws<NotSupportedException>(() => session.CreateMultiQuery().Add(sqlQuery)); + var multiquery = session.CreateMultiQuery(); + multiquery.Executing(x => x.Add(sqlQuery)).NotThrows(); } } [Test] - public void ThrowsExceptionWhenNamedSqlQueryIsGiven() + public void DoesntThrowsExceptionWhenNamedSqlQueryIsGiven() { using (ISession session = OpenSession()) using (ITransaction tx = session.BeginTransaction()) { - Assert.Throws<NotSupportedException>(() =>session - .CreateMultiQuery() - .AddNamedQuery("SampleSqlQuery")); + var multiquery = session.CreateMultiQuery(); + multiquery.Executing(x => x.AddNamedQuery("SampleSqlQuery")).NotThrows(); } } - } } Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-03-24 17:28:29 UTC (rev 5519) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-03-24 18:06:06 UTC (rev 5520) @@ -667,6 +667,7 @@ <Compile Include="PolymorphicGetAndLoad\PolymorphicGetAndLoadTest.cs" /> <Compile Include="PropertyTest\FieldCamelCaseMUnderscoreFixture.cs" /> <Compile Include="PropertyTest\NoSetterCamelCaseMUnderscoreFixture.cs" /> + <Compile Include="QueryTest\MultipleMixedQueriesFixture.cs" /> <Compile Include="ReadOnly\AbstractReadOnlyTest.cs" /> <Compile Include="ReadOnly\Container.cs" /> <Compile Include="ReadOnly\Course.cs" /> Added: trunk/nhibernate/src/NHibernate.Test/QueryTest/MultipleMixedQueriesFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/QueryTest/MultipleMixedQueriesFixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/QueryTest/MultipleMixedQueriesFixture.cs 2011-03-24 18:06:06 UTC (rev 5520) @@ -0,0 +1,517 @@ +using System.Collections; +using System.Collections.Generic; +using System.Reflection; +using NHibernate.Cache; +using NHibernate.Driver; +using NHibernate.Engine; +using NHibernate.Test.SecondLevelCacheTests; +using NHibernate.Transform; +using NUnit.Framework; +using System; + +namespace NHibernate.Test.QueryTest +{ + public class MultipleMixedQueriesFixture : TestCase + { + protected override string MappingsAssembly + { + get { return "NHibernate.Test"; } + } + + protected override IList Mappings + { + get { return new string[] { "SecondLevelCacheTest.Item.hbm.xml" }; } + } + + [TestFixtureSetUp] + public void CheckMultiQuerySupport() + { + base.TestFixtureSetUp(); + IDriver driver = sessions.ConnectionProvider.Driver; + if (!driver.SupportsMultipleQueries) + { + Assert.Ignore("Driver {0} does not support multi-queries", driver.GetType().FullName); + } + } + + [Test] + public void NH_1085_WillIgnoreParametersIfDoesNotAppearInQuery() + { + using (ISession s = sessions.OpenSession()) + { + IMultiQuery multiQuery = s.CreateMultiQuery() + .Add(s.CreateSQLQuery("select * from ITEM where Id in (:ids)").AddEntity(typeof (Item))) + .Add(s.CreateSQLQuery("select * from ITEM where Id in (:ids2)").AddEntity(typeof (Item))) + .SetParameterList("ids", new int[] {50}) + .SetParameterList("ids2", new int[] {50}); + multiQuery.List(); + } + } + + [Test] + public void NH_1085_WillGiveReasonableErrorIfBadParameterName() + { + using (ISession s = sessions.OpenSession()) + { + IMultiQuery multiQuery = s.CreateMultiQuery() + .Add(s.CreateSQLQuery("select * from ITEM where Id in (:ids)").AddEntity(typeof(Item))) + .Add(s.CreateSQLQuery("select * from ITEM where Id in (:ids2)").AddEntity(typeof(Item))); + var e = Assert.Throws<QueryException>(() => multiQuery.List()); + Assert.That(e.Message, Is.EqualTo("Not all named parameters have been set: ['ids'] [select * from ITEM where Id in (:ids)]")); + } + } + + [Test] + public void CanGetMultiQueryFromSecondLevelCache() + { + CreateItems(); + //set the query in the cache + DoMutiQueryAndAssert(); + + Hashtable cacheHashtable = GetHashTableUsedAsQueryCache(); + IList cachedListEntry = (IList)new ArrayList(cacheHashtable.Values)[0]; + IList cachedQuery = (IList)cachedListEntry[1]; + + IList firstQueryResults = (IList)cachedQuery[0]; + firstQueryResults.Clear(); + firstQueryResults.Add(3); + firstQueryResults.Add(4); + + IList secondQueryResults = (IList)cachedQuery[1]; + secondQueryResults[0] = 2L; + + using (ISession s = sessions.OpenSession()) + { + IMultiQuery multiQuery = s.CreateMultiQuery() + .Add(s.CreateSQLQuery("select * from ITEM where Id > ?").AddEntity(typeof(Item)) + .SetInt32(0, 50) + .SetFirstResult(10)) + .Add(s.CreateQuery("select count(*) from Item i where i.Id > ?") + .SetInt32(0, 50)); + multiQuery.SetCacheable(true); + IList results = multiQuery.List(); + IList items = (IList)results[0]; + Assert.AreEqual(2, items.Count); + long count = (long)((IList)results[1])[0]; + Assert.AreEqual(2L, count); + } + + RemoveAllItems(); + } + + [Test] + public void CanSpecifyParameterOnMultiQueryWhenItIsNotUsedInAllQueries() + { + using (ISession s = OpenSession()) + { + s.CreateMultiQuery() + .Add("from Item") + .Add(s.CreateSQLQuery("select * from ITEM where Id > :id").AddEntity(typeof(Item))) + .SetParameter("id", 5) + .List(); + } + } + + [Test] + public void CanSpecifyParameterOnMultiQueryWhenItIsNotUsedInAllQueries_MoreThanOneParameter() + { + using (ISession s = OpenSession()) + { + s.CreateMultiQuery() + .Add("from Item") + .Add(s.CreateSQLQuery("select * from ITEM where Id = :id or Id = :id2").AddEntity(typeof(Item))) + .Add("from Item i where i.Id = :id2") + .SetParameter("id", 5) + .SetInt32("id2", 5) + .List(); + } + } + + [Test] + public void TwoMultiQueriesWithDifferentPagingGetDifferentResultsWhenUsingCachedQueries() + { + CreateItems(); + using (ISession s = OpenSession()) + { + IMultiQuery multiQuery = s.CreateMultiQuery() + .Add(s.CreateQuery("from Item i where i.Id > ?") + .SetInt32(0, 50) + .SetFirstResult(10)) + .Add(s.CreateSQLQuery("select count(*) as count from ITEM where Id > ?").AddScalar("count", NHibernateUtil.Int64) + .SetInt32(0, 50)); + + multiQuery.SetCacheable(true); + IList results = multiQuery.List(); + IList items = (IList)results[0]; + Assert.AreEqual(89, items.Count); + long count = (long)((IList)results[1])[0]; + Assert.AreEqual(99L, count); + } + + using (ISession s = OpenSession()) + { + IMultiQuery multiQuery = s.CreateMultiQuery() + .Add(s.CreateSQLQuery("select * from ITEM where Id > ?").AddEntity(typeof(Item)) + .SetInt32(0, 50) + .SetFirstResult(20)) + .Add(s.CreateQuery("select count(*) from Item i where i.Id > ?") + .SetInt32(0, 50)); + multiQuery.SetCacheable(true); + IList results = multiQuery.List(); + IList items = (IList)results[0]; + Assert.AreEqual(79, items.Count, + "Should have gotten different result here, because the paging is different"); + long count = (long)((IList)results[1])[0]; + Assert.AreEqual(99L, count); + } + + RemoveAllItems(); + } + + [Test] + public void CanUseSecondLevelCacheWithPositionalParameters() + { + Hashtable cacheHashtable = GetHashTableUsedAsQueryCache(); + cacheHashtable.Clear(); + + CreateItems(); + + DoMutiQueryAndAssert(); + + Assert.AreEqual(1, cacheHashtable.Count); + + RemoveAllItems(); + } + + private void DoMutiQueryAndAssert() + { + using (ISession s = OpenSession()) + { + IMultiQuery multiQuery = s.CreateMultiQuery() + .Add(s.CreateSQLQuery("select * from ITEM where Id > ?").AddEntity(typeof(Item)) + .SetInt32(0, 50) + .SetFirstResult(10)) + .Add(s.CreateQuery("select count(*) from Item i where i.Id > ?") + .SetInt32(0, 50)); + multiQuery.SetCacheable(true); + IList results = multiQuery.List(); + IList items = (IList)results[0]; + Assert.AreEqual(89, items.Count); + long count = (long)((IList)results[1])[0]; + Assert.AreEqual(99L, count); + } + } + + private void CreateItems() + { + using (ISession s = OpenSession()) + using (ITransaction t = s.BeginTransaction()) + { + for (int i = 0; i < 150; i++) + { + Item item = new Item(); + item.Id = i; + s.Save(item); + } + t.Commit(); + } + } + + private Hashtable GetHashTableUsedAsQueryCache() + { + ISessionFactoryImplementor factory = (ISessionFactoryImplementor)sessions; + //need the inner hashtable in the cache + HashtableCache cache = (HashtableCache) + typeof(StandardQueryCache) + .GetField("queryCache", BindingFlags.Instance | BindingFlags.NonPublic) + .GetValue(factory.GetQueryCache(null)); + + return (Hashtable)typeof(HashtableCache) + .GetField("hashtable", BindingFlags.Instance | BindingFlags.NonPublic) + .GetValue(cache); + } + + [Test] + public void CanUseWithParameterizedQueriesAndLimit() + { + using (ISession s = OpenSession()) + { + for (int i = 0; i < 150; i++) + { + Item item = new Item(); + item.Id = i; + s.Save(item); + } + s.Flush(); + } + + using (ISession s = OpenSession()) + { + IQuery getItems = s.CreateSQLQuery("select * from ITEM where Id > :id").AddEntity(typeof(Item)).SetFirstResult(10); + IQuery countItems = s.CreateQuery("select count(*) from Item i where i.Id > :id"); + + IList results = s.CreateMultiQuery() + .Add(getItems) + .Add(countItems) + .SetInt32("id", 50) + .List(); + IList items = (IList)results[0]; + Assert.AreEqual(89, items.Count); + long count = (long)((IList)results[1])[0]; + Assert.AreEqual(99L, count); + } + + RemoveAllItems(); + } + + private void RemoveAllItems() + { + using (ISession s = OpenSession()) + { + s.Delete("from Item"); + s.Flush(); + } + } + + [Test] + public void CanUseSetParameterList() + { + using (ISession s = OpenSession()) + { + Item item = new Item(); + item.Id = 1; + s.Save(item); + s.Flush(); + } + + using (ISession s = OpenSession()) + { + IList results = s.CreateMultiQuery() + .Add(s.CreateSQLQuery("select * from ITEM where Id in (:items)").AddEntity(typeof(Item))) + .Add("select count(*) from Item i where i.id in (:items)") + .SetParameterList("items", new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }) + .List(); + + IList items = (IList)results[0]; + Item fromDb = (Item)items[0]; + Assert.AreEqual(1, fromDb.Id); + + IList counts = (IList)results[1]; + long count = (long)counts[0]; + Assert.AreEqual(1L, count); + } + + using (ISession s = OpenSession()) + { + s.Delete("from Item"); + s.Flush(); + } + } + + [Test] + public void CanExecuteMultiplyQueriesInSingleRoundTrip() + { + using (ISession s = OpenSession()) + { + Item item = new Item(); + item.Id = 1; + s.Save(item); + s.Flush(); + } + + using (ISession s = OpenSession()) + { + IQuery getItems = s.CreateSQLQuery("select * from ITEM").AddEntity(typeof(Item)); + IQuery countItems = s.CreateQuery("select count(*) from Item"); + + IList results = s.CreateMultiQuery() + .Add(getItems) + .Add(countItems) + .List(); + IList items = (IList)results[0]; + Item fromDb = (Item)items[0]; + Assert.AreEqual(1, fromDb.Id); + + IList counts = (IList)results[1]; + long count = (long)counts[0]; + Assert.AreEqual(1L, count); + } + + using (ISession s = OpenSession()) + { + s.Delete("from Item"); + s.Flush(); + } + } + + [Test] + public void CanAddIQueryWithKeyAndRetrieveResultsWithKey() + { + CreateItems(); + + using (ISession session = OpenSession()) + { + IMultiQuery multiQuery = session.CreateMultiQuery(); + + IQuery firstQuery = session.CreateSQLQuery("select * from ITEM where Id < :id").AddEntity(typeof(Item)) + .SetInt32("id", 50); + + IQuery secondQuery = session.CreateQuery("from Item"); + + multiQuery.Add("first", firstQuery).Add("second", secondQuery); + + IList secondResult = (IList)multiQuery.GetResult("second"); + IList firstResult = (IList)multiQuery.GetResult("first"); + + Assert.Greater(secondResult.Count, firstResult.Count); + } + + RemoveAllItems(); + } + + [Test] + public void CanNotAddQueryWithKeyThatAlreadyExists() + { + using (ISession session = OpenSession()) + { + IMultiQuery multiQuery = session.CreateMultiQuery(); + + IQuery firstQuery = session.CreateSQLQuery("select * from ITEM where Id < :id").AddEntity(typeof(Item)) + .SetInt32("id", 50); + + try + { + IQuery secondQuery = session.CreateSQLQuery("select * from ITEM").AddEntity(typeof(Item)); + multiQuery.Add("first", firstQuery).Add("second", secondQuery); + } + catch (InvalidOperationException) + { + } + catch (Exception) + { + Assert.Fail("This should've thrown an InvalidOperationException"); + } + } + } + + [Test] + public void CanNotRetrieveQueryResultWithUnknownKey() + { + using (ISession session = OpenSession()) + { + IMultiQuery multiQuery = session.CreateMultiQuery(); + + multiQuery.Add("firstQuery", session.CreateSQLQuery("select * from ITEM").AddEntity(typeof(Item))); + + try + { + IList firstResult = (IList)multiQuery.GetResult("unknownKey"); + Assert.Fail("This should've thrown an InvalidOperationException"); + } + catch (InvalidOperationException) + { + } + catch (Exception) + { + Assert.Fail("This should've thrown an InvalidOperationException"); + } + + } + } + + [Test] + public void ExecutingQueryThroughMultiQueryTransformsResults() + { + CreateItems(); + + using (ISession session = OpenSession()) + { + ResultTransformerStub transformer = new ResultTransformerStub(); + IQuery query = session.CreateSQLQuery("select * from ITEM").AddEntity(typeof(Item)) + .SetResultTransformer(transformer); + session.CreateMultiQuery() + .Add(query) + .List(); + + Assert.IsTrue(transformer.WasTransformTupleCalled, "Transform Tuple was not called"); + Assert.IsTrue(transformer.WasTransformListCalled, "Transform List was not called"); + } + + RemoveAllItems(); + } + + [Test] + public void ExecutingQueryThroughMultiQueryTransformsResults_When_setting_on_multi_query_directly() + { + CreateItems(); + + using (ISession session = OpenSession()) + { + ResultTransformerStub transformer = new ResultTransformerStub(); + IQuery query = session.CreateSQLQuery("select * from ITEM").AddEntity(typeof(Item)); + session.CreateMultiQuery() + .Add(query) + .SetResultTransformer(transformer) + .List(); + + Assert.IsTrue(transformer.WasTransformTupleCalled, "Transform Tuple was not called"); + Assert.IsTrue(transformer.WasTransformListCalled, "Transform List was not called"); + } + + RemoveAllItems(); + } + + + [Test] + public void CanGetResultsInAGenericList() + { + using (ISession s = OpenSession()) + { + IQuery getItems = s.CreateQuery("from Item"); + IQuery countItems = s.CreateSQLQuery("select count(*) as count from ITEM").AddScalar("count", NHibernateUtil.Int64); + + IList results = s.CreateMultiQuery() + .Add(getItems) + .Add<long>(countItems) + .List(); + + Assert.That(results[0], Is.InstanceOf<ArrayList>()); + Assert.That(results[1], Is.InstanceOf<List<long>>()); + } + } + + public class ResultTransformerStub : IResultTransformer + { + private bool _wasTransformTupleCalled; + private bool _wasTransformListCalled; + + public bool WasTransformTupleCalled + { + get { return _wasTransformTupleCalled; } + } + + public bool WasTransformListCalled + { + get { return _wasTransformListCalled; } + } + + public ResultTransformerStub() + { + _wasTransformTupleCalled = false; + _wasTransformListCalled = false; + } + + public object TransformTuple(object[] tuple, string[] aliases) + { + _wasTransformTupleCalled = true; + return tuple; + } + + public IList TransformList(IList collection) + { + _wasTransformListCalled = true; + return collection; + } + } + } +} \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |