From: <ric...@us...> - 2010-03-06 22:49:28
|
Revision: 4953 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4953&view=rev Author: ricbrown Date: 2010-03-06 22:49:21 +0000 (Sat, 06 Mar 2010) Log Message: ----------- Added QueryOverTransformer. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs trunk/nhibernate/src/NHibernate/IQueryOver.cs trunk/nhibernate/src/NHibernate/Impl/CriteriaImpl.cs trunk/nhibernate/src/NHibernate/NHibernate.csproj trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs Added Paths: ----------- trunk/nhibernate/src/NHibernate/QueryOverTransformer.cs Modified: trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2010-03-03 17:29:11 UTC (rev 4952) +++ trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2010-03-06 22:49:21 UTC (rev 4953) @@ -12,7 +12,7 @@ { [Serializable] - public class QueryOver + public abstract class QueryOver { protected ICriteria criteria; @@ -40,10 +40,12 @@ get { return new DetachedCriteria(impl, impl); } } + public abstract object Clone(); + } [Serializable] - public class QueryOver<TRoot> : QueryOver, IQueryOver<TRoot> + public abstract class QueryOver<TRoot> : QueryOver, IQueryOver<TRoot> { private IList<TRoot> List() @@ -177,6 +179,11 @@ this.criteria = criteria; } + public override object Clone() + { + return new QueryOver<TRoot,TRoot>((CriteriaImpl)criteria.Clone()); + } + public QueryOver<TRoot,TSubType> And(Expression<Func<TSubType, bool>> expression) { return Add(expression); @@ -290,6 +297,12 @@ return new QueryOverOrderBuilder<TRoot,TSubType>(this, path); } + public QueryOver<TRoot,TSubType> ClearOrders() + { + criteria.ClearOrders(); + return this; + } + public QueryOver<TRoot,TSubType> Skip(int firstResult) { criteria.SetFirstResult(firstResult); @@ -620,6 +633,9 @@ IQueryOverOrderBuilder<TRoot,TSubType> IQueryOver<TRoot,TSubType>.ThenBy(Expression<Func<object>> path) { return new IQueryOverOrderBuilder<TRoot,TSubType>(this, path); } + IQueryOver<TRoot,TSubType> IQueryOver<TRoot, TSubType>.ClearOrders() + { return ClearOrders(); } + IQueryOver<TRoot,TSubType> IQueryOver<TRoot,TSubType>.Skip(int firstResult) { return Skip(firstResult); } Modified: trunk/nhibernate/src/NHibernate/IQueryOver.cs =================================================================== --- trunk/nhibernate/src/NHibernate/IQueryOver.cs 2010-03-03 17:29:11 UTC (rev 4952) +++ trunk/nhibernate/src/NHibernate/IQueryOver.cs 2010-03-06 22:49:21 UTC (rev 4953) @@ -22,7 +22,7 @@ /// .List(); /// </code> /// </remarks> - public interface IQueryOver<TRoot> + public interface IQueryOver<TRoot> : ICloneable { /// <summary> /// Access the underlying ICriteria @@ -241,6 +241,11 @@ IQueryOverOrderBuilder<TRoot,TSubType> ThenBy(Expression<Func<object>> path); /// <summary> + /// Clear all orders from the query. + /// </summary> + IQueryOver<TRoot, TSubType> ClearOrders(); + + /// <summary> /// Set the first result to be retrieved /// </summary> /// <param name="firstResult"></param> Modified: trunk/nhibernate/src/NHibernate/Impl/CriteriaImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/CriteriaImpl.cs 2010-03-03 17:29:11 UTC (rev 4952) +++ trunk/nhibernate/src/NHibernate/Impl/CriteriaImpl.cs 2010-03-06 22:49:21 UTC (rev 4953) @@ -460,8 +460,12 @@ projection = projectionList; } - projectionCriteria = this; - SetResultTransformer(CriteriaSpecification.Projection); + if (projection != null) + { + projectionCriteria = this; + SetResultTransformer(CriteriaSpecification.Projection); + } + return this; } Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2010-03-03 17:29:11 UTC (rev 4952) +++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2010-03-06 22:49:21 UTC (rev 4953) @@ -830,6 +830,7 @@ <Compile Include="Hql\Ast\ANTLR\Util\NodeTraverser.cs" /> <Compile Include="Param\VersionTypeSeedParameterSpecification.cs" /> <Compile Include="Proxy\AbstractProxyFactory.cs" /> + <Compile Include="QueryOverTransformer.cs" /> <Compile Include="SqlCommand\InsertSelect.cs" /> <Compile Include="Tool\hbm2ddl\SchemaMetadataUpdater.cs" /> <Compile Include="Tool\hbm2ddl\ScriptSplitter.cs" /> Added: trunk/nhibernate/src/NHibernate/QueryOverTransformer.cs =================================================================== --- trunk/nhibernate/src/NHibernate/QueryOverTransformer.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/QueryOverTransformer.cs 2010-03-06 22:49:21 UTC (rev 4953) @@ -0,0 +1,54 @@ +using NHibernate.Criterion; +using NHibernate.Engine; +using NHibernate.Impl; + +namespace NHibernate +{ + /// <summary> + /// Transforms QueryOver queries + /// </summary> + public static class QueryOverTransformer + { + ///<summary> + /// Returns a clone of the original QueryOver, which will return the count + /// of rows that are returned by the original QueryOver query. + ///</summary> + public static QueryOver<T,T> TransformToRowCount<T>(QueryOver<T> query) + { + QueryOver<T,T> clonedQuery = (QueryOver<T,T>)query.Clone(); + return (QueryOver<T,T>)TransformToRowCount((IQueryOver<T>)clonedQuery); + } + + ///<summary> + /// Returns a clone of the original IQueryOver, which will return the count + /// of rows that are returned by the original IQueryOver query. + ///</summary> + public static IQueryOver<T,T> TransformToRowCount<T>(IQueryOver<T> query) + { + IQueryOver<T,T> clonedQuery = (IQueryOver<T,T>)query.Clone(); + + return + clonedQuery + .ClearOrders() + .Skip(0) + .Take(RowSelection.NoValue) + .Select(Projections.RowCount()); + } + + /// <summary> + /// Creates an exact clone of the IQueryOver + /// </summary> + public static IQueryOver<T,T> Clone<T>(IQueryOver<T> query) + { + return (IQueryOver<T,T>)query.Clone(); + } + + /// <summary> + /// Creates an exact clone of the QueryOver + /// </summary> + public static QueryOver<T,T> Clone<T>(QueryOver<T> query) + { + return (QueryOver<T,T>)query.Clone(); + } + } +} Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs 2010-03-03 17:29:11 UTC (rev 4952) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs 2010-03-06 22:49:21 UTC (rev 4953) @@ -483,6 +483,75 @@ AssertCriteriaAreEqual(expected, actual); } + [Test] + public void CloneIQueryOver() + { + IQueryOver<Person> expected = + CreateTestQueryOver<Person>() + .Where(p => p.Name == "test") + .Select(p => p.Name); + + IQueryOver<Person> actual = QueryOverTransformer.Clone(expected); + + Assert.That(actual, Is.Not.SameAs(expected)); + Assert.That(actual.UnderlyingCriteria, Is.Not.SameAs(expected.UnderlyingCriteria)); + AssertCriteriaAreEqual(expected.UnderlyingCriteria, actual.UnderlyingCriteria); + } + + [Test] + public void CloneIQueryOverWithSubType() + { + IQueryOver<Person,Child> expected = + CreateTestQueryOver<Person>() + .JoinQueryOver(p => p.Children); + + IQueryOver<Person,Person> actual = QueryOverTransformer.Clone(expected); + + ICriteria expectedCriteria = expected.UnderlyingCriteria.GetCriteriaByAlias("this"); + + AssertCriteriaAreEqual(expectedCriteria, actual); + } + + [Test] + public void CloneQueryOver() + { + QueryOver<Person> expected = + QueryOver.Of<Person>() + .Where(p => p.Name == "test") + .Select(p => p.Name); + + QueryOver<Person> actual = QueryOverTransformer.Clone(expected); + + Assert.That(actual, Is.Not.SameAs(expected)); + Assert.That(actual.UnderlyingCriteria, Is.Not.SameAs(expected.UnderlyingCriteria)); + AssertCriteriaAreEqual(expected.UnderlyingCriteria, actual.UnderlyingCriteria); + } + + [Test] + public void TransformQueryOverToRowCount() + { + QueryOver<Person> expected = + QueryOver.Of<Person>() + .Where(p => p.Name == "test") + .JoinQueryOver(p => p.Children) + .Where((Child c) => c.Age == 5) + .Select(Projections.RowCount()); + + QueryOver<Person> actual = + QueryOver.Of<Person>() + .Where(p => p.Name == "test") + .JoinQueryOver(p => p.Children) + .Where((Child c) => c.Age == 5) + .OrderBy(c => c.Age).Asc + .Skip(20) + .Take(10); + + expected = QueryOverTransformer.Clone(expected); + actual = QueryOverTransformer.TransformToRowCount(actual); + + AssertCriteriaAreEqual(expected.UnderlyingCriteria, actual); + } + } } \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |