From: <dav...@us...> - 2009-01-25 19:31:51
|
Revision: 4000 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4000&view=rev Author: davybrion Date: 2009-01-25 19:31:49 +0000 (Sun, 25 Jan 2009) Log Message: ----------- implementation for FutureValue<T> method on ICriteria (very similar to the Future<T> implementation) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/ICriteria.cs trunk/nhibernate/src/NHibernate/Impl/CriteriaImpl.cs trunk/nhibernate/src/NHibernate/Impl/FutureCriteriaBatch.cs trunk/nhibernate/src/NHibernate/NHibernate.csproj trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/Futures/Fixture.cs Added Paths: ----------- trunk/nhibernate/src/NHibernate/IFutureValue.cs Modified: trunk/nhibernate/src/NHibernate/ICriteria.cs =================================================================== --- trunk/nhibernate/src/NHibernate/ICriteria.cs 2009-01-23 07:13:16 UTC (rev 3999) +++ trunk/nhibernate/src/NHibernate/ICriteria.cs 2009-01-25 19:31:49 UTC (rev 4000) @@ -253,6 +253,16 @@ /// <returns></returns> IEnumerable<T> Future<T>(); + /// <summary> + /// Get an IFutureValue instance, whose value can be retrieved through + /// its Value property. The query is not executed until the Value property + /// is retrieved, which will execute other Future queries as well in a + /// single roundtrip + /// </summary> + /// <typeparam name="T"></typeparam> + /// <returns></returns> + IFutureValue<T> FutureValue<T>(); + #region NHibernate specific /// <summary> Added: trunk/nhibernate/src/NHibernate/IFutureValue.cs =================================================================== --- trunk/nhibernate/src/NHibernate/IFutureValue.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/IFutureValue.cs 2009-01-25 19:31:49 UTC (rev 4000) @@ -0,0 +1,7 @@ +namespace NHibernate +{ + public interface IFutureValue<T> + { + T Value { get; } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Impl/CriteriaImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/CriteriaImpl.cs 2009-01-23 07:13:16 UTC (rev 3999) +++ trunk/nhibernate/src/NHibernate/Impl/CriteriaImpl.cs 2009-01-25 19:31:49 UTC (rev 4000) @@ -371,6 +371,12 @@ return new Subcriteria(this, this, associationPath, alias, joinType); } + public IFutureValue<T> FutureValue<T>() + { + session.FutureCriteriaBatch.Add(this); + return session.FutureCriteriaBatch.GetFutureValue<T>(); + } + public IEnumerable<T> Future<T>() { session.FutureCriteriaBatch.Add(this); @@ -687,6 +693,11 @@ return root.List(); } + public IFutureValue<T> FutureValue<T>() + { + return root.FutureValue<T>(); + } + public IEnumerable<T> Future<T>() { return root.Future<T>(); Modified: trunk/nhibernate/src/NHibernate/Impl/FutureCriteriaBatch.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/FutureCriteriaBatch.cs 2009-01-23 07:13:16 UTC (rev 3999) +++ trunk/nhibernate/src/NHibernate/Impl/FutureCriteriaBatch.cs 2009-01-25 19:31:49 UTC (rev 4000) @@ -3,87 +3,124 @@ namespace NHibernate.Impl { - public class FutureCriteriaBatch - { - private readonly List<ICriteria> criterias = new List<ICriteria>(); - private int index; - private IList results; - private readonly ISession session; + public class FutureCriteriaBatch + { + private readonly List<ICriteria> criterias = new List<ICriteria>(); + private int index; + private IList results; + private readonly ISession session; - public FutureCriteriaBatch(ISession session) - { - this.session = session; - } + public FutureCriteriaBatch(ISession session) + { + this.session = session; + } - public IList Results - { - get - { - if (results == null) - { - var multiCriteria = session.CreateMultiCriteria(); - foreach (var crit in criterias) - { - multiCriteria.Add(crit); - } - results = multiCriteria.List(); - ((SessionImpl)session).FutureCriteriaBatch = null; - } - return results; - } - } + public IList Results + { + get + { + if (results == null) + { + var multiCriteria = session.CreateMultiCriteria(); + foreach (var crit in criterias) + { + multiCriteria.Add(crit); + } + results = multiCriteria.List(); + ((SessionImpl)session).FutureCriteriaBatch = null; + } + return results; + } + } - public void Add(ICriteria criteria) - { - criterias.Add(criteria); - index = criterias.Count - 1; - } + public void Add(ICriteria criteria) + { + criterias.Add(criteria); + index = criterias.Count - 1; + } - public IEnumerable<T> GetEnumerator<T>() - { - int currentIndex = index; - return new DelayedEnumerator<T>(() => (IList)Results[currentIndex]); - } + public IFutureValue<T> GetFutureValue<T>() + { + int currentIndex = index; + return new FutureValue<T>(() => (IList)Results[currentIndex]); + } - #region Nested type: DelayedEnumerator + public IEnumerable<T> GetEnumerator<T>() + { + int currentIndex = index; + return new DelayedEnumerator<T>(() => (IList)Results[currentIndex]); + } - private class DelayedEnumerator<T> : IEnumerable<T> - { - public delegate IList GetResult(); + #region Nested type: FutureValue - private readonly GetResult result; + private class FutureValue<T> : IFutureValue<T> + { + public delegate IList GetResult(); - public DelayedEnumerator(GetResult result) - { - this.result = result; - } + private readonly GetResult getResult; - public IEnumerable<T> Enumerable - { - get - { - foreach (T item in result()) - { - yield return item; - } - } - } + public FutureValue(GetResult result) + { + getResult = result; + } - #region IEnumerable<T> Members + public T Value + { + get + { + var result = getResult(); - IEnumerator IEnumerable.GetEnumerator() - { - return ((IEnumerable) Enumerable).GetEnumerator(); - } + if (result.Count == 0) + { + return default(T); + } - public IEnumerator<T> GetEnumerator() - { - return Enumerable.GetEnumerator(); - } + return (T)result[0]; + } + } + } - #endregion - } + #endregion - #endregion - } + #region Nested type: DelayedEnumerator + + private class DelayedEnumerator<T> : IEnumerable<T> + { + public delegate IList GetResult(); + + private readonly GetResult result; + + public DelayedEnumerator(GetResult result) + { + this.result = result; + } + + public IEnumerable<T> Enumerable + { + get + { + foreach (T item in result()) + { + yield return item; + } + } + } + + #region IEnumerable<T> Members + + IEnumerator IEnumerable.GetEnumerator() + { + return ((IEnumerable)Enumerable).GetEnumerator(); + } + + public IEnumerator<T> GetEnumerator() + { + return Enumerable.GetEnumerator(); + } + + #endregion + } + + #endregion + } } Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-01-23 07:13:16 UTC (rev 3999) +++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-01-25 19:31:49 UTC (rev 4000) @@ -456,6 +456,7 @@ <Compile Include="Exceptions\SqlStateExtracter.cs" /> <Compile Include="Exceptions\TemplatedViolatedConstraintNameExtracter.cs" /> <Compile Include="Id\SelectGenerator.cs" /> + <Compile Include="IFutureValue.cs" /> <Compile Include="Impl\FutureCriteriaBatch.cs" /> <Compile Include="Properties\BackFieldStrategy.cs" /> <Compile Include="Bytecode\CodeDom\BytecodeProviderImpl.cs" /> Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/Futures/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/Futures/Fixture.cs 2009-01-23 07:13:16 UTC (rev 3999) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/Futures/Fixture.cs 2009-01-25 19:31:49 UTC (rev 4000) @@ -1,3 +1,4 @@ +using NHibernate.Criterion; using NHibernate.Impl; using NUnit.Framework; @@ -85,5 +86,39 @@ } } } + + [Test] + public void CanCombineSingleFutureValueWithEnumerableFutures() + { + using (var s = sessions.OpenSession()) + { + if (((SessionFactoryImpl)sessions) + .ConnectionProvider.Driver.SupportsMultipleQueries == false) + { + Assert.Ignore("Not applicable for dialects that do not support multiple queries"); + } + + var persons = s.CreateCriteria(typeof(Person)) + .SetMaxResults(10) + .Future<Person>(); + + var personCount = s.CreateCriteria(typeof(Person)) + .SetProjection(Projections.RowCount()) + .FutureValue<int>(); + + using (var logSpy = new SqlLogSpy()) + { + int count = personCount.Value; + + foreach (var person in persons) + { + + } + + var events = logSpy.Appender.GetEvents(); + Assert.AreEqual(1, events.Length); + } + } + } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |