You can subscribe to this list here.
2004 |
Jan
|
Feb
|
Mar
|
Apr
(248) |
May
(82) |
Jun
(90) |
Jul
(177) |
Aug
(253) |
Sep
(157) |
Oct
(151) |
Nov
(143) |
Dec
(278) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2005 |
Jan
(152) |
Feb
(107) |
Mar
(177) |
Apr
(133) |
May
(259) |
Jun
(81) |
Jul
(119) |
Aug
(306) |
Sep
(416) |
Oct
(240) |
Nov
(329) |
Dec
(206) |
2006 |
Jan
(466) |
Feb
(382) |
Mar
(153) |
Apr
(162) |
May
(133) |
Jun
(21) |
Jul
(18) |
Aug
(37) |
Sep
(97) |
Oct
(114) |
Nov
(110) |
Dec
(28) |
2007 |
Jan
(74) |
Feb
(65) |
Mar
(49) |
Apr
(76) |
May
(43) |
Jun
(15) |
Jul
(68) |
Aug
(55) |
Sep
(63) |
Oct
(59) |
Nov
(70) |
Dec
(66) |
2008 |
Jan
(71) |
Feb
(60) |
Mar
(120) |
Apr
(31) |
May
(48) |
Jun
(81) |
Jul
(107) |
Aug
(51) |
Sep
(80) |
Oct
(83) |
Nov
(83) |
Dec
(79) |
2009 |
Jan
(83) |
Feb
(110) |
Mar
(97) |
Apr
(91) |
May
(291) |
Jun
(250) |
Jul
(197) |
Aug
(58) |
Sep
(54) |
Oct
(122) |
Nov
(68) |
Dec
(34) |
2010 |
Jan
(50) |
Feb
(17) |
Mar
(63) |
Apr
(61) |
May
(84) |
Jun
(81) |
Jul
(138) |
Aug
(144) |
Sep
(78) |
Oct
(26) |
Nov
(30) |
Dec
(61) |
2011 |
Jan
(33) |
Feb
(35) |
Mar
(166) |
Apr
(221) |
May
(109) |
Jun
(76) |
Jul
(27) |
Aug
(37) |
Sep
(1) |
Oct
(4) |
Nov
(2) |
Dec
(1) |
2012 |
Jan
|
Feb
|
Mar
(2) |
Apr
(2) |
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
(1) |
Oct
|
Nov
(1) |
Dec
|
2013 |
Jan
|
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
(1) |
Sep
(3) |
Oct
(2) |
Nov
|
Dec
(1) |
2014 |
Jan
(1) |
Feb
(1) |
Mar
(3) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <ric...@us...> - 2011-05-29 18:06:28
|
Revision: 5879 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5879&view=rev Author: ricbrown Date: 2011-05-29 18:06:21 +0000 (Sun, 29 May 2011) Log Message: ----------- NH-2683: Added QueryOver functions to projections and SQL functions Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Criterion/Lambda/LambdaRestrictionBuilder.cs trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverRestrictionBuilder.cs trunk/nhibernate/src/NHibernate/Criterion/Projections.cs trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs trunk/nhibernate/src/NHibernate/Criterion/Restrictions.cs trunk/nhibernate/src/NHibernate/Criterion/RestrictionsExtensions.cs trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs Modified: trunk/nhibernate/src/NHibernate/Criterion/Lambda/LambdaRestrictionBuilder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/Lambda/LambdaRestrictionBuilder.cs 2011-05-29 02:36:57 UTC (rev 5878) +++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/LambdaRestrictionBuilder.cs 2011-05-29 18:06:21 UTC (rev 5879) @@ -14,13 +14,13 @@ { public class LambdaBetweenBuilder { - private string propertyName; + private IProjection projection; private object lo; private bool isNot; - public LambdaBetweenBuilder(string propertyName, object lo, bool isNot) + public LambdaBetweenBuilder(IProjection projection, object lo, bool isNot) { - this.propertyName = propertyName; + this.projection = projection; this.lo = lo; this.isNot = isNot; } @@ -28,13 +28,13 @@ public AbstractCriterion And(object hi) { if (isNot) - return Restrictions.Not(Restrictions.Between(propertyName, lo, hi)); + return Restrictions.Not(Restrictions.Between(projection, lo, hi)); - return Restrictions.Between(propertyName, lo, hi); + return Restrictions.Between(projection, lo, hi); } } - private string propertyName; + private IProjection projection; private bool isNot; private AbstractCriterion Process(AbstractCriterion criterion) @@ -48,9 +48,9 @@ /// <summary> /// Constructed with property name /// </summary> - public LambdaRestrictionBuilder(string propertyName) + public LambdaRestrictionBuilder(IProjection projection) { - this.propertyName = propertyName; + this.projection = projection; } /// <summary> @@ -58,7 +58,7 @@ /// </summary> public LambdaBetweenBuilder IsBetween(object lo) { - return new LambdaBetweenBuilder(propertyName, lo, isNot); + return new LambdaBetweenBuilder(projection, lo, isNot); } public LambdaRestrictionBuilder Not @@ -75,7 +75,7 @@ /// </summary> public AbstractCriterion IsIn(ICollection values) { - return Process(Restrictions.In(propertyName, values)); + return Process(Restrictions.In(projection, values)); } /// <summary> @@ -83,7 +83,7 @@ /// </summary> public AbstractCriterion IsIn(object[] values) { - return Process(Restrictions.In(propertyName, values)); + return Process(Restrictions.In(projection, values)); } /// <summary> @@ -91,7 +91,7 @@ /// </summary> public AbstractCriterion IsInG<T>(ICollection<T> values) { - return Process(Restrictions.InG(propertyName, values)); + return Process(Restrictions.InG(projection, values)); } /// <summary> @@ -99,7 +99,7 @@ /// </summary> public AbstractCriterion IsInsensitiveLike(object value) { - return Process(Restrictions.InsensitiveLike(propertyName, value)); + return Process(Restrictions.InsensitiveLike(projection, value)); } /// <summary> @@ -107,7 +107,7 @@ /// </summary> public AbstractCriterion IsInsensitiveLike(string value, MatchMode matchMode) { - return Process(Restrictions.InsensitiveLike(propertyName, value, matchMode)); + return Process(Restrictions.InsensitiveLike(projection, value, matchMode)); } /// <summary> @@ -115,7 +115,7 @@ /// </summary> public AbstractCriterion IsEmpty { - get { return Process(Restrictions.IsEmpty(propertyName)); } + get { return Process(Restrictions.IsEmpty(ExpressionProcessor.FindProperty(projection))); } } /// <summary> @@ -123,7 +123,7 @@ /// </summary> public AbstractCriterion IsNotEmpty { - get { return Process(Restrictions.IsNotEmpty(propertyName)); } + get { return Process(Restrictions.IsNotEmpty(ExpressionProcessor.FindProperty(projection))); } } /// <summary> @@ -131,7 +131,7 @@ /// </summary> public AbstractCriterion IsNull { - get { return Process(Restrictions.IsNull(propertyName)); } + get { return Process(Restrictions.IsNull(projection)); } } /// <summary> @@ -139,7 +139,7 @@ /// </summary> public AbstractCriterion IsNotNull { - get { return Process(Restrictions.IsNotNull(propertyName)); } + get { return Process(Restrictions.IsNotNull(projection)); } } /// <summary> @@ -147,7 +147,7 @@ /// </summary> public AbstractCriterion IsLike(object value) { - return Process(Restrictions.Like(propertyName, value)); + return Process(Restrictions.Like(projection, value)); } /// <summary> @@ -155,7 +155,7 @@ /// </summary> public AbstractCriterion IsLike(string value, MatchMode matchMode) { - return Process(Restrictions.Like(propertyName, value, matchMode)); + return Process(Restrictions.Like(projection, value, matchMode)); } /// <summary> @@ -163,7 +163,7 @@ /// </summary> public AbstractCriterion IsLike(string value, MatchMode matchMode, char? escapeChar) { - return Process(Restrictions.Like(propertyName, value, matchMode, escapeChar)); + return Process(Restrictions.Like(ExpressionProcessor.FindProperty(projection), value, matchMode, escapeChar)); } } Modified: trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverRestrictionBuilder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverRestrictionBuilder.cs 2011-05-29 02:36:57 UTC (rev 5878) +++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverRestrictionBuilder.cs 2011-05-29 18:06:21 UTC (rev 5879) @@ -13,8 +13,8 @@ public class QueryOverRestrictionBuilder<TRoot,TSubType> : QueryOverRestrictionBuilderBase<QueryOver<TRoot,TSubType>, TRoot, TSubType> { - public QueryOverRestrictionBuilder(QueryOver<TRoot,TSubType> root, string propertyName) - : base(root, propertyName) { } + public QueryOverRestrictionBuilder(QueryOver<TRoot,TSubType> root, IProjection projection) + : base(root, projection) { } public QueryOverRestrictionBuilder<TRoot,TSubType> Not { @@ -30,8 +30,8 @@ public class IQueryOverRestrictionBuilder<TRoot,TSubType> : QueryOverRestrictionBuilderBase<IQueryOver<TRoot,TSubType>, TRoot, TSubType> { - public IQueryOverRestrictionBuilder(IQueryOver<TRoot,TSubType> root, string propertyName) - : base(root, propertyName) { } + public IQueryOverRestrictionBuilder(IQueryOver<TRoot,TSubType> root, IProjection projection) + : base(root, projection) { } public IQueryOverRestrictionBuilder<TRoot,TSubType> Not { @@ -50,14 +50,14 @@ public class LambdaBetweenBuilder { private TReturn root; - private string propertyName; + private IProjection projection; private bool isNot; private object lo; - public LambdaBetweenBuilder(TReturn root, string propertyName, bool isNot, object lo) + public LambdaBetweenBuilder(TReturn root, IProjection projection, bool isNot, object lo) { this.root = root; - this.propertyName = propertyName; + this.projection = projection; this.isNot = isNot; this.lo = lo; } @@ -72,21 +72,21 @@ public TReturn And(object hi) { - return Add(Restrictions.Between(propertyName, lo, hi)); + return Add(Restrictions.Between(projection, lo, hi)); } } private TReturn root; - private string propertyName; + private IProjection projection; protected bool isNot; /// <summary> /// Constructed with property name /// </summary> - public QueryOverRestrictionBuilderBase(TReturn root, string propertyName) + public QueryOverRestrictionBuilderBase(TReturn root, IProjection projection) { this.root = root; - this.propertyName = propertyName; + this.projection = projection; } private TReturn Add(ICriterion criterion) @@ -102,7 +102,7 @@ /// </summary> public LambdaBetweenBuilder IsBetween(object lo) { - return new LambdaBetweenBuilder(root, propertyName, isNot, lo); + return new LambdaBetweenBuilder(root, projection, isNot, lo); } /// <summary> @@ -110,7 +110,7 @@ /// </summary> public TReturn IsIn(ICollection values) { - return Add(Restrictions.In(propertyName, values)); + return Add(Restrictions.In(projection, values)); } /// <summary> @@ -118,7 +118,7 @@ /// </summary> public TReturn IsIn(object[] values) { - return Add(Restrictions.In(propertyName, values)); + return Add(Restrictions.In(projection, values)); } /// <summary> @@ -126,7 +126,7 @@ /// </summary> public TReturn IsInG<T>(ICollection<T> values) { - return Add(Restrictions.InG(propertyName, values)); + return Add(Restrictions.InG(projection, values)); } /// <summary> @@ -134,7 +134,7 @@ /// </summary> public TReturn IsInsensitiveLike(object value) { - return Add(Restrictions.InsensitiveLike(propertyName, value)); + return Add(Restrictions.InsensitiveLike(projection, value)); } /// <summary> @@ -142,7 +142,7 @@ /// </summary> public TReturn IsInsensitiveLike(string value, MatchMode matchMode) { - return Add(Restrictions.InsensitiveLike(propertyName, value, matchMode)); + return Add(Restrictions.InsensitiveLike(projection, value, matchMode)); } /// <summary> @@ -150,7 +150,7 @@ /// </summary> public TReturn IsEmpty { - get { return Add(Restrictions.IsEmpty(propertyName)); } + get { return Add(Restrictions.IsEmpty(ExpressionProcessor.FindProperty(projection))); } } /// <summary> @@ -158,7 +158,7 @@ /// </summary> public TReturn IsNotEmpty { - get { return Add(Restrictions.IsNotEmpty(propertyName)); } + get { return Add(Restrictions.IsNotEmpty(ExpressionProcessor.FindProperty(projection))); } } /// <summary> @@ -166,7 +166,7 @@ /// </summary> public TReturn IsNull { - get { return Add(Restrictions.IsNull(propertyName)); } + get { return Add(Restrictions.IsNull(projection)); } } /// <summary> @@ -174,7 +174,7 @@ /// </summary> public TReturn IsNotNull { - get { return Add(Restrictions.IsNotNull(propertyName)); } + get { return Add(Restrictions.IsNotNull(projection)); } } /// <summary> @@ -182,7 +182,7 @@ /// </summary> public TReturn IsLike(object value) { - return Add(Restrictions.Like(propertyName, value)); + return Add(Restrictions.Like(projection, value)); } /// <summary> @@ -190,7 +190,7 @@ /// </summary> public TReturn IsLike(string value, MatchMode matchMode) { - return Add(Restrictions.Like(propertyName, value, matchMode)); + return Add(Restrictions.Like(projection, value, matchMode)); } /// <summary> @@ -198,7 +198,7 @@ /// </summary> public TReturn IsLike(string value, MatchMode matchMode, char? escapeChar) { - return Add(Restrictions.Like(propertyName, value, matchMode, escapeChar)); + return Add(Restrictions.Like(ExpressionProcessor.FindProperty(projection), value, matchMode, escapeChar)); } } Modified: trunk/nhibernate/src/NHibernate/Criterion/Projections.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/Projections.cs 2011-05-29 02:36:57 UTC (rev 5878) +++ trunk/nhibernate/src/NHibernate/Criterion/Projections.cs 2011-05-29 18:06:21 UTC (rev 5879) @@ -324,7 +324,7 @@ /// </summary> public static AggregateProjection Avg<T>(Expression<Func<T, object>> expression) { - return Projections.Avg(ExpressionProcessor.FindMemberExpression(expression.Body)); + return Projections.Avg(ExpressionProcessor.FindMemberProjection(expression.Body)); } /// <summary> @@ -332,7 +332,7 @@ /// </summary> public static AggregateProjection Avg(Expression<Func<object>> expression) { - return Projections.Avg(ExpressionProcessor.FindMemberExpression(expression.Body)); + return Projections.Avg(ExpressionProcessor.FindMemberProjection(expression.Body)); } /// <summary> @@ -340,7 +340,7 @@ /// </summary> public static CountProjection Count<T>(Expression<Func<T, object>> expression) { - return Projections.Count(ExpressionProcessor.FindMemberExpression(expression.Body)); + return Projections.Count(ExpressionProcessor.FindMemberProjection(expression.Body)); } /// <summary> @@ -348,7 +348,7 @@ /// </summary> public static CountProjection Count(Expression<Func<object>> expression) { - return Projections.Count(ExpressionProcessor.FindMemberExpression(expression.Body)); + return Projections.Count(ExpressionProcessor.FindMemberProjection(expression.Body)); } /// <summary> @@ -388,7 +388,7 @@ /// </summary> public static AggregateProjection Max<T>(Expression<Func<T, object>> expression) { - return Projections.Max(ExpressionProcessor.FindMemberExpression(expression.Body)); + return Projections.Max(ExpressionProcessor.FindMemberProjection(expression.Body)); } /// <summary> @@ -396,7 +396,7 @@ /// </summary> public static AggregateProjection Max(Expression<Func<object>> expression) { - return Projections.Max(ExpressionProcessor.FindMemberExpression(expression.Body)); + return Projections.Max(ExpressionProcessor.FindMemberProjection(expression.Body)); } /// <summary> @@ -404,7 +404,7 @@ /// </summary> public static AggregateProjection Min<T>(Expression<Func<T, object>> expression) { - return Projections.Min(ExpressionProcessor.FindMemberExpression(expression.Body)); + return Projections.Min(ExpressionProcessor.FindMemberProjection(expression.Body)); } /// <summary> @@ -412,7 +412,7 @@ /// </summary> public static AggregateProjection Min(Expression<Func<object>> expression) { - return Projections.Min(ExpressionProcessor.FindMemberExpression(expression.Body)); + return Projections.Min(ExpressionProcessor.FindMemberProjection(expression.Body)); } /// <summary> @@ -441,7 +441,7 @@ /// </summary> public static AggregateProjection Sum<T>(Expression<Func<T, object>> expression) { - return Projections.Sum(ExpressionProcessor.FindMemberExpression(expression.Body)); + return Projections.Sum(ExpressionProcessor.FindMemberProjection(expression.Body)); } /// <summary> @@ -449,7 +449,7 @@ /// </summary> public static AggregateProjection Sum(Expression<Func<object>> expression) { - return Projections.Sum(ExpressionProcessor.FindMemberExpression(expression.Body)); + return Projections.Sum(ExpressionProcessor.FindMemberProjection(expression.Body)); } /// <summary> Modified: trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2011-05-29 02:36:57 UTC (rev 5878) +++ trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2011-05-29 18:06:21 UTC (rev 5879) @@ -344,12 +344,12 @@ public QueryOverRestrictionBuilder<TRoot,TSubType> AndRestrictionOn(Expression<Func<TSubType, object>> expression) { - return new QueryOverRestrictionBuilder<TRoot,TSubType>(this, ExpressionProcessor.FindMemberExpression(expression.Body)); + return new QueryOverRestrictionBuilder<TRoot,TSubType>(this, ExpressionProcessor.FindMemberProjection(expression.Body)); } public QueryOverRestrictionBuilder<TRoot,TSubType> AndRestrictionOn(Expression<Func<object>> expression) { - return new QueryOverRestrictionBuilder<TRoot,TSubType>(this, ExpressionProcessor.FindMemberExpression(expression.Body)); + return new QueryOverRestrictionBuilder<TRoot,TSubType>(this, ExpressionProcessor.FindMemberProjection(expression.Body)); } public QueryOver<TRoot,TSubType> Where(Expression<Func<TSubType, bool>> expression) @@ -379,12 +379,12 @@ public QueryOverRestrictionBuilder<TRoot,TSubType> WhereRestrictionOn(Expression<Func<TSubType, object>> expression) { - return new QueryOverRestrictionBuilder<TRoot,TSubType>(this, ExpressionProcessor.FindMemberExpression(expression.Body)); + return new QueryOverRestrictionBuilder<TRoot,TSubType>(this, ExpressionProcessor.FindMemberProjection(expression.Body)); } public QueryOverRestrictionBuilder<TRoot,TSubType> WhereRestrictionOn(Expression<Func<object>> expression) { - return new QueryOverRestrictionBuilder<TRoot,TSubType>(this, ExpressionProcessor.FindMemberExpression(expression.Body)); + return new QueryOverRestrictionBuilder<TRoot,TSubType>(this, ExpressionProcessor.FindMemberProjection(expression.Body)); } public QueryOver<TRoot,TSubType> Select(params Expression<Func<TRoot, object>>[] projections) @@ -791,10 +791,10 @@ { return AndNot(expression); } IQueryOverRestrictionBuilder<TRoot,TSubType> IQueryOver<TRoot,TSubType>.AndRestrictionOn(Expression<Func<TSubType, object>> expression) - { return new IQueryOverRestrictionBuilder<TRoot,TSubType>(this, ExpressionProcessor.FindMemberExpression(expression.Body)); } + { return new IQueryOverRestrictionBuilder<TRoot,TSubType>(this, ExpressionProcessor.FindMemberProjection(expression.Body)); } IQueryOverRestrictionBuilder<TRoot,TSubType> IQueryOver<TRoot,TSubType>.AndRestrictionOn(Expression<Func<object>> expression) - { return new IQueryOverRestrictionBuilder<TRoot,TSubType>(this, ExpressionProcessor.FindMemberExpression(expression.Body)); } + { return new IQueryOverRestrictionBuilder<TRoot,TSubType>(this, ExpressionProcessor.FindMemberProjection(expression.Body)); } IQueryOver<TRoot,TSubType> IQueryOver<TRoot,TSubType>.Where(Expression<Func<TSubType, bool>> expression) { return Where(expression); } @@ -812,10 +812,10 @@ { return WhereNot(expression); } IQueryOverRestrictionBuilder<TRoot,TSubType> IQueryOver<TRoot,TSubType>.WhereRestrictionOn(Expression<Func<TSubType, object>> expression) - { return new IQueryOverRestrictionBuilder<TRoot,TSubType>(this, ExpressionProcessor.FindMemberExpression(expression.Body)); } + { return new IQueryOverRestrictionBuilder<TRoot,TSubType>(this, ExpressionProcessor.FindMemberProjection(expression.Body)); } IQueryOverRestrictionBuilder<TRoot,TSubType> IQueryOver<TRoot,TSubType>.WhereRestrictionOn(Expression<Func<object>> expression) - { return new IQueryOverRestrictionBuilder<TRoot,TSubType>(this, ExpressionProcessor.FindMemberExpression(expression.Body)); } + { return new IQueryOverRestrictionBuilder<TRoot,TSubType>(this, ExpressionProcessor.FindMemberProjection(expression.Body)); } IQueryOver<TRoot,TSubType> IQueryOver<TRoot,TSubType>.Select(params Expression<Func<TRoot, object>>[] projections) { return Select(projections); } Modified: trunk/nhibernate/src/NHibernate/Criterion/Restrictions.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/Restrictions.cs 2011-05-29 02:36:57 UTC (rev 5878) +++ trunk/nhibernate/src/NHibernate/Criterion/Restrictions.cs 2011-05-29 18:06:21 UTC (rev 5879) @@ -790,8 +790,8 @@ /// <returns>returns LambdaRestrictionBuilder</returns> public static LambdaRestrictionBuilder On<T>(Expression<Func<T, object>> expression) { - string property = ExpressionProcessor.FindMemberExpression(expression.Body); - return new LambdaRestrictionBuilder(property); + IProjection projection = ExpressionProcessor.FindMemberProjection(expression.Body); + return new LambdaRestrictionBuilder(projection); } /// <summary> @@ -801,8 +801,8 @@ /// <returns>returns LambdaRestrictionBuilder</returns> public static LambdaRestrictionBuilder On(Expression<Func<object>> expression) { - string property = ExpressionProcessor.FindMemberExpression(expression.Body); - return new LambdaRestrictionBuilder(property); + IProjection projection = ExpressionProcessor.FindMemberProjection(expression.Body); + return new LambdaRestrictionBuilder(projection); } } Modified: trunk/nhibernate/src/NHibernate/Criterion/RestrictionsExtensions.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/RestrictionsExtensions.cs 2011-05-29 02:36:57 UTC (rev 5878) +++ trunk/nhibernate/src/NHibernate/Criterion/RestrictionsExtensions.cs 2011-05-29 18:06:21 UTC (rev 5879) @@ -89,17 +89,17 @@ public static ICriterion ProcessIsLike(MethodCallExpression methodCallExpression) { - string property = ExpressionProcessor.FindMemberExpression(methodCallExpression.Arguments[0]); + IProjection projection = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); object value = ExpressionProcessor.FindValue(methodCallExpression.Arguments[1]); - return Restrictions.Like(property, value); + return Restrictions.Like(projection, value); } public static ICriterion ProcessIsLikeMatchMode(MethodCallExpression methodCallExpression) { - string property = ExpressionProcessor.FindMemberExpression(methodCallExpression.Arguments[0]); + IProjection projection = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); string value = (string)ExpressionProcessor.FindValue(methodCallExpression.Arguments[1]); MatchMode matchMode = (MatchMode)ExpressionProcessor.FindValue(methodCallExpression.Arguments[2]); - return Restrictions.Like(property, value, matchMode); + return Restrictions.Like(projection, value, matchMode); } public static ICriterion ProcessIsLikeMatchModeEscapeChar(MethodCallExpression methodCallExpression) @@ -113,40 +113,40 @@ public static ICriterion ProcessIsInsensitiveLike(MethodCallExpression methodCallExpression) { - string property = ExpressionProcessor.FindMemberExpression(methodCallExpression.Arguments[0]); + IProjection projection = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); object value = ExpressionProcessor.FindValue(methodCallExpression.Arguments[1]); - return Restrictions.InsensitiveLike(property, value); + return Restrictions.InsensitiveLike(projection, value); } public static ICriterion ProcessIsInsensitiveLikeMatchMode(MethodCallExpression methodCallExpression) { - string property = ExpressionProcessor.FindMemberExpression(methodCallExpression.Arguments[0]); + IProjection projection = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); string value = (string)ExpressionProcessor.FindValue(methodCallExpression.Arguments[1]); MatchMode matchMode = (MatchMode)ExpressionProcessor.FindValue(methodCallExpression.Arguments[2]); - return Restrictions.InsensitiveLike(property, value, matchMode); + return Restrictions.InsensitiveLike(projection, value, matchMode); } public static ICriterion ProcessIsInArray(MethodCallExpression methodCallExpression) { - string property = ExpressionProcessor.FindMemberExpression(methodCallExpression.Arguments[0]); + IProjection projection = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); object[] values = (object[])ExpressionProcessor.FindValue(methodCallExpression.Arguments[1]); - return Restrictions.In(property, values); + return Restrictions.In(projection, values); } public static ICriterion ProcessIsInCollection(MethodCallExpression methodCallExpression) { - string property = ExpressionProcessor.FindMemberExpression(methodCallExpression.Arguments[0]); + IProjection projection = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); ICollection values = (ICollection)ExpressionProcessor.FindValue(methodCallExpression.Arguments[1]); - return Restrictions.In(property, values); + return Restrictions.In(projection, values); } public static ICriterion ProcessIsBetween(MethodCallExpression methodCallExpression) { MethodCallExpression betweenFunction = (MethodCallExpression)methodCallExpression.Object; - string property = ExpressionProcessor.FindMemberExpression(betweenFunction.Arguments[0]); + IProjection projection = ExpressionProcessor.FindMemberProjection(betweenFunction.Arguments[0]); object lo = ExpressionProcessor.FindValue(betweenFunction.Arguments[1]); object hi = ExpressionProcessor.FindValue(methodCallExpression.Arguments[0]); - return Restrictions.Between(property, lo, hi); + return Restrictions.Between(projection, lo, hi); } } } Modified: trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs 2011-05-29 02:36:57 UTC (rev 5878) +++ trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs 2011-05-29 18:06:21 UTC (rev 5879) @@ -741,6 +741,18 @@ _customProjectionProcessors.Add(signature, functionProcessor); } + /// <summary> + /// Retreive the property name from a supplied PropertyProjection + /// Note: throws is the supplied IProjection is not a PropertyProjection + /// </summary> + public static string FindProperty(IProjection projection) + { + if (!(projection is PropertyProjection)) + throw new Exception("Cannot determine property for " + projection.ToString()); + + return ((PropertyProjection)projection).PropertyName; + } + } } Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs 2011-05-29 02:36:57 UTC (rev 5878) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs 2011-05-29 18:06:21 UTC (rev 5879) @@ -593,6 +593,19 @@ using (ISession s = OpenSession()) { + var persons = + s.QueryOver<Person>() + .Where(p => p.BirthDate.YearPart().IsIn(new [] { 2008, 2009 })) + .OrderBy(p => p.Name).Asc + .List(); + + persons.Count.Should().Be(2); + persons[0].Name.Should().Be("p1"); + persons[1].Name.Should().Be("p2"); + } + + using (ISession s = OpenSession()) + { var yearOfBirth = s.QueryOver<Person>() .Where(p => p.Name == "p2") @@ -605,6 +618,17 @@ using (ISession s = OpenSession()) { + var avgYear = + s.QueryOver<Person>() + .SelectList(list => list.SelectAvg(p => p.BirthDate.YearPart())) + .SingleOrDefault<object>(); + + avgYear.GetType().Should().Be(typeof(double)); + string.Format("{0:0}", avgYear).Should().Be("2008"); + } + + using (ISession s = OpenSession()) + { var sqrtOfAge = s.QueryOver<Person>() .Where(p => p.Name == "p1") Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs 2011-05-29 02:36:57 UTC (rev 5878) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs 2011-05-29 18:06:21 UTC (rev 5879) @@ -39,24 +39,24 @@ ICriteria expected = CreateTestCriteria(typeof(Person), "personAlias") .SetProjection(Projections.ProjectionList() - .Add(Projections.Alias(Projections.Avg("Age"), "personAgeProjectionAlias")) - .Add(Projections.Avg("Age"), "personAgeProjectionAlias") - .Add(Projections.Avg("personAlias.Age"), "Age") - .Add(Projections.Count("Age")) - .Add(Projections.Count("personAlias.Age")) + .Add(Projections.Alias(Projections.Avg(Projections.Property("Age")), "personAgeProjectionAlias")) + .Add(Projections.Avg(Projections.Property("Age")), "personAgeProjectionAlias") + .Add(Projections.Avg(Projections.Property("personAlias.Age")), "Age") + .Add(Projections.Count(Projections.Property("Age"))) + .Add(Projections.Count(Projections.Property("personAlias.Age"))) .Add(Projections.CountDistinct("Age")) .Add(Projections.CountDistinct("personAlias.Age")) .Add(Projections.GroupProperty("Age")) .Add(Projections.GroupProperty("personAlias.Age")) - .Add(Projections.Max("Age")) - .Add(Projections.Max("personAlias.Age")) - .Add(Projections.Min("Age")) - .Add(Projections.Min("personAlias.Age")) + .Add(Projections.Max(Projections.Property("Age"))) + .Add(Projections.Max(Projections.Property("personAlias.Age"))) + .Add(Projections.Min(Projections.Property("Age"))) + .Add(Projections.Min(Projections.Property("personAlias.Age"))) .Add(Projections.Property("Age")) .Add(Projections.Property("personAlias.Age")) .Add(Projections.SubQuery(DetachedCriteriaAge)) - .Add(Projections.Sum("Age")) - .Add(Projections.Sum("personAlias.Age"))); + .Add(Projections.Sum(Projections.Property("Age"))) + .Add(Projections.Sum(Projections.Property("personAlias.Age")))); Person personAlias = null; Person personAgeProjectionAlias = null; @@ -91,24 +91,24 @@ ICriteria expected = CreateTestCriteria(typeof(Person), "personAlias") .SetProjection(Projections.ProjectionList() - .Add(Projections.Alias(Projections.Avg("Age"), "personAgeProjectionAlias")) + .Add(Projections.Alias(Projections.Avg(Projections.Property("Age")), "personAgeProjectionAlias")) .Add(Projections.Avg("Age")) - .Add(Projections.Avg("personAlias.Age"), "Age") - .Add(Projections.Count("Age")) - .Add(Projections.Count("personAlias.Age")) + .Add(Projections.Avg(Projections.Property("personAlias.Age")), "Age") + .Add(Projections.Count(Projections.Property("Age"))) + .Add(Projections.Count(Projections.Property("personAlias.Age"))) .Add(Projections.CountDistinct("Age")) .Add(Projections.CountDistinct("personAlias.Age")) .Add(Projections.GroupProperty("Age")) .Add(Projections.GroupProperty("personAlias.Age")) - .Add(Projections.Max("Age")) - .Add(Projections.Max("personAlias.Age")) - .Add(Projections.Min("Age")) - .Add(Projections.Min("personAlias.Age")) + .Add(Projections.Max(Projections.Property("Age"))) + .Add(Projections.Max(Projections.Property("personAlias.Age"))) + .Add(Projections.Min(Projections.Property("Age"))) + .Add(Projections.Min(Projections.Property("personAlias.Age"))) .Add(Projections.Property("Age")) .Add(Projections.Property("personAlias.Age")) .Add(Projections.SubQuery(DetachedCriteriaAge)) - .Add(Projections.Sum("Age")) - .Add(Projections.Sum("personAlias.Age"))); + .Add(Projections.Sum(Projections.Property("Age"))) + .Add(Projections.Sum(Projections.Property("personAlias.Age")))); Person personAlias = null; Person personAgeProjectionAlias = null; Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs 2011-05-29 02:36:57 UTC (rev 5878) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs 2011-05-29 18:06:21 UTC (rev 5879) @@ -151,7 +151,7 @@ CreateTestCriteria(typeof(Person), "personAlias") .Add(Restrictions.Or( Restrictions.Not(Restrictions.Eq(Projections.Property("Name"), "test name")), - Restrictions.Not(Restrictions.Like("personAlias.Name", "%test%")))); + Restrictions.Not(Restrictions.Like(Projections.Property("personAlias.Name"), "%test%")))); Person personAlias = null; IQueryOver<Person> actual = Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs 2011-05-29 02:36:57 UTC (rev 5878) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs 2011-05-29 18:06:21 UTC (rev 5879) @@ -38,22 +38,22 @@ { ICriteria expected = CreateTestCriteria(typeof(Person), "personAlias") - .Add(Restrictions.Between("Age", 18, 65)) - .Add(Restrictions.Between("personAlias.Age", 18, 65)) - .Add(Restrictions.Not(Restrictions.Between("personAlias.Age", 10, 20))) - .Add(!Restrictions.In("Name", new string[] { "name4" })) - .Add(Restrictions.In("Name", new string[] { "name1", "name2", "name3" })) - .Add(Restrictions.In("Name", new ArrayList() { "name1", "name2", "name3" })) - .Add(Restrictions.InG<int>("Age", new int[] { 1, 2, 3 })) - .Add(Restrictions.InsensitiveLike("Name", "test")) - .Add(Restrictions.InsensitiveLike("Name", "tEsT", MatchMode.Anywhere)) + .Add(Restrictions.Between(Projections.Property("Age"), 18, 65)) + .Add(Restrictions.Between(Projections.Property("personAlias.Age"), 18, 65)) + .Add(Restrictions.Not(Restrictions.Between(Projections.Property("personAlias.Age"), 10, 20))) + .Add(!Restrictions.In(Projections.Property("Name"), new string[] { "name4" })) + .Add(Restrictions.In(Projections.Property("Name"), new string[] { "name1", "name2", "name3" })) + .Add(Restrictions.In(Projections.Property("Name"), new ArrayList() { "name1", "name2", "name3" })) + .Add(Restrictions.InG<int>(Projections.Property("Age"), new int[] { 1, 2, 3 })) + .Add(Restrictions.InsensitiveLike(Projections.Property("Name"), "test")) + .Add(Restrictions.InsensitiveLike(Projections.Property("Name"), "tEsT", MatchMode.Anywhere)) .Add(Restrictions.IsEmpty("Children")) .Add(Restrictions.Not(Restrictions.IsEmpty("Children"))) .Add(Restrictions.IsNotEmpty("Children")) - .Add(Restrictions.IsNotNull("Name")) - .Add(Restrictions.IsNull("Name")) - .Add(Restrictions.Like("Name", "%test%")) - .Add(Restrictions.Like("Name", "test", MatchMode.Anywhere)) + .Add(Restrictions.IsNotNull(Projections.Property("Name"))) + .Add(Restrictions.IsNull(Projections.Property("Name"))) + .Add(Restrictions.Like(Projections.Property("Name"), "%test%")) + .Add(Restrictions.Like(Projections.Property("Name"), "test", MatchMode.Anywhere)) .Add(Restrictions.Like("Name", "test", MatchMode.Anywhere, '?')) .Add(Restrictions.NaturalId() .Set("Name", "my name") @@ -116,22 +116,22 @@ { ICriteria expected = CreateTestCriteria(typeof(Person), "personAlias") - .Add(Restrictions.Between("Age", 18, 65)) - .Add(Restrictions.Between("personAlias.Age", 18, 65)) - .Add(Restrictions.Not(Restrictions.Between("Age", 18, 65))) - .Add(Restrictions.In("Name", new string[] { "name1", "name2", "name3" })) - .Add(Restrictions.In("personAlias.Name", new ArrayList() { "name1", "name2", "name3" })) - .Add(Restrictions.InG<int>("Age", new int[] { 1, 2, 3 })) - .Add(Restrictions.InsensitiveLike("Name", "test")) - .Add(Restrictions.InsensitiveLike("Name", "tEsT", MatchMode.Anywhere)) + .Add(Restrictions.Between(Projections.Property("Age"), 18, 65)) + .Add(Restrictions.Between(Projections.Property("personAlias.Age"), 18, 65)) + .Add(Restrictions.Not(Restrictions.Between(Projections.Property("Age"), 18, 65))) + .Add(Restrictions.In(Projections.Property("Name"), new string[] { "name1", "name2", "name3" })) + .Add(Restrictions.In(Projections.Property("personAlias.Name"), new ArrayList() { "name1", "name2", "name3" })) + .Add(Restrictions.InG<int>(Projections.Property("Age"), new int[] { 1, 2, 3 })) + .Add(Restrictions.InsensitiveLike(Projections.Property("Name"), "test")) + .Add(Restrictions.InsensitiveLike(Projections.Property("Name"), "tEsT", MatchMode.Anywhere)) .Add(Restrictions.IsEmpty("Children")) .Add(Restrictions.IsNotEmpty("Children")) - .Add(Restrictions.IsNotNull("Name")) - .Add(Restrictions.IsNull("Name")) - .Add(Restrictions.Like("Name", "%test%")) - .Add(Restrictions.Like("Name", "test", MatchMode.Anywhere)) + .Add(Restrictions.IsNotNull(Projections.Property("Name"))) + .Add(Restrictions.IsNull(Projections.Property("Name"))) + .Add(Restrictions.Like(Projections.Property("Name"), "%test%")) + .Add(Restrictions.Like(Projections.Property("Name"), "test", MatchMode.Anywhere)) .Add(Restrictions.Like("Name", "test", MatchMode.Anywhere, '?')) - .Add(Restrictions.Not(Restrictions.Like("Name", "%test%"))); + .Add(Restrictions.Not(Restrictions.Like(Projections.Property("Name"), "%test%"))); Person personAlias = null; var actual = @@ -161,10 +161,10 @@ { DetachedCriteria expected = DetachedCriteria.For<Person>("personAlias") - .Add(Restrictions.Between("Age", 18, 65)) - .Add(Restrictions.Between("personAlias.Age", 18, 65)) - .Add(Restrictions.In("Name", new string[] { "name1", "name2", "name3" })) - .Add(Restrictions.In("personAlias.Name", new ArrayList() { "name1", "name2", "name3" })); + .Add(Restrictions.Between(Projections.Property("Age"), 18, 65)) + .Add(Restrictions.Between(Projections.Property("personAlias.Age"), 18, 65)) + .Add(Restrictions.In(Projections.Property("Name"), new string[] { "name1", "name2", "name3" })) + .Add(Restrictions.In(Projections.Property("personAlias.Name"), new ArrayList() { "name1", "name2", "name3" })); Person personAlias = null; QueryOver<Person> actual = @@ -232,14 +232,14 @@ { ICriteria expected = CreateTestCriteria(typeof(Person)) - .Add(Restrictions.Like("Name", "%test%")) - .Add(Restrictions.Like("Name", "test", MatchMode.End)) + .Add(Restrictions.Like(Projections.Property("Name"), "%test%")) + .Add(Restrictions.Like(Projections.Property("Name"), "test", MatchMode.End)) .Add(Restrictions.Like("Name", "test", MatchMode.Start, '?')) - .Add(Restrictions.InsensitiveLike("Name", "%test%")) - .Add(Restrictions.InsensitiveLike("Name", "test", MatchMode.Anywhere)) - .Add(Restrictions.In("Name", new string[] { "name1", "name2" })) - .Add(Restrictions.In("Name", new ArrayList() { "name3", "name4" })) - .Add(Restrictions.Between("Age", 10, 20)); + .Add(Restrictions.InsensitiveLike(Projections.Property("Name"), "%test%")) + .Add(Restrictions.InsensitiveLike(Projections.Property("Name"), "test", MatchMode.Anywhere)) + .Add(Restrictions.In(Projections.Property("Name"), new string[] { "name1", "name2" })) + .Add(Restrictions.In(Projections.Property("Name"), new ArrayList() { "name3", "name4" })) + .Add(Restrictions.Between(Projections.Property("Age"), 10, 20)); IQueryOver<Person> actual = CreateTestQueryOver<Person>() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pa...@us...> - 2011-05-29 02:37:04
|
Revision: 5878 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5878&view=rev Author: patearl Date: 2011-05-29 02:36:57 +0000 (Sun, 29 May 2011) Log Message: ----------- Remotion.Linq is no longer internalized when being ILMerged. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/NHibernate.build Modified: trunk/nhibernate/src/NHibernate/NHibernate.build =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.build 2011-05-28 11:13:51 UTC (rev 5877) +++ trunk/nhibernate/src/NHibernate/NHibernate.build 2011-05-29 02:36:57 UTC (rev 5878) @@ -52,7 +52,9 @@ <if test="${not NHibernate.dll.uptodate}"> <mkdir dir="${bin.dir}/merged" /> - <copy file="${bin.dir}/unmerged/NHibernate.dll" tofile="${bin.dir}/NHibernate.dll" /> + + <!-- Merge everything that should be internal --> + <copy file="${bin.dir}/unmerged/NHibernate.dll" tofile="${bin.dir}/NHibernate.dll" /> <copy file="${bin.dir}/unmerged/NHibernate.pdb" tofile="${bin.dir}/NHibernate.pdb" /> <exec program="../../Tools/ILMerge/ILMerge.exe"> @@ -62,14 +64,28 @@ <arg value="/out:${bin.dir}/merged/NHibernate.dll" /> <arg value="${bin.dir}/NHibernate.dll" /> <arg value="${bin.dir}/Antlr3.Runtime.dll" /> - <arg value="${bin.dir}/Remotion.Linq.dll" /> </exec> - - <move file="${bin.dir}/merged/NHibernate.dll" tofile="${bin.dir}/NHibernate.dll" /> + + <delete file="${bin.dir}/Antlr3.Runtime.dll" /> + + <!-- Merge everything that should be accessible --> + <copy file="${bin.dir}/merged/NHibernate.dll" tofile="${bin.dir}/NHibernate.dll" /> + <copy file="${bin.dir}/merged/NHibernate.pdb" tofile="${bin.dir}/NHibernate.pdb" /> + + <exec program="../../Tools/ILMerge/ILMerge.exe"> + <arg value="/t:library" /> + <arg value="/keyfile:../NHibernate.snk" /> + <arg value="/out:${bin.dir}/merged/NHibernate.dll" /> + <arg value="${bin.dir}/NHibernate.dll" /> + <arg value="${bin.dir}/Remotion.Linq.dll" /> + </exec> + + <delete file="${bin.dir}/Remotion.Linq.dll" /> + + <!-- Put merged files in appropriate places --> + <move file="${bin.dir}/merged/NHibernate.dll" tofile="${bin.dir}/NHibernate.dll" /> <move file="${bin.dir}/merged/NHibernate.pdb" tofile="${bin.dir}/NHibernate.pdb" /> <delete dir="${bin.dir}/merged" /> - <delete file="${bin.dir}/Antlr3.Runtime.dll" /> - <delete file="${bin.dir}/Remotion.Linq.dll" /> </if> </target> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2011-05-28 11:13:57
|
Revision: 5877 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5877&view=rev Author: ricbrown Date: 2011-05-28 11:13:51 +0000 (Sat, 28 May 2011) Log Message: ----------- NH-2683: Added QueryOver functions to OrderBy Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverOrderBuilder.cs trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs Modified: trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverOrderBuilder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverOrderBuilder.cs 2011-05-28 07:12:07 UTC (rev 5876) +++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverOrderBuilder.cs 2011-05-28 11:13:51 UTC (rev 5877) @@ -70,7 +70,10 @@ if (projection != null) root.UnderlyingCriteria.AddOrder(orderDelegate(projection)); else - root.UnderlyingCriteria.AddOrder(ExpressionProcessor.ProcessOrder(path, orderStringDelegate, isAlias)); + if (isAlias) + root.UnderlyingCriteria.AddOrder(ExpressionProcessor.ProcessOrder(path, orderStringDelegate)); + else + root.UnderlyingCriteria.AddOrder(ExpressionProcessor.ProcessOrder(path, orderDelegate)); } public TReturn Asc Modified: trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs 2011-05-28 07:12:07 UTC (rev 5876) +++ trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs 2011-05-28 11:13:51 UTC (rev 5877) @@ -650,17 +650,29 @@ /// </summary> /// <param name="expression">The lambda expression to convert</param> /// <param name="orderDelegate">The appropriate order delegate (order direction)</param> - /// <param name="isAlias">Indicates if the path is an aliased projection</param> /// <returns>NHibernate Order</returns> public static Order ProcessOrder( LambdaExpression expression, - Func<string, Order> orderDelegate, - bool isAlias) + Func<string, Order> orderDelegate) { - string property = isAlias ? FindPropertyExpression(expression.Body) : FindMemberExpression(expression.Body); + string property = FindPropertyExpression(expression.Body); Order order = orderDelegate(property); return order; } + /// <summary> + /// Convert a lambda expression to NHibernate Order + /// </summary> + /// <param name="expression">The lambda expression to convert</param> + /// <param name="orderDelegate">The appropriate order delegate (order direction)</param> + /// <returns>NHibernate Order</returns> + public static Order ProcessOrder( LambdaExpression expression, + Func<IProjection, Order> orderDelegate) + { + IProjection projection = FindMemberProjection(expression.Body); + Order order = orderDelegate(projection); + return order; + } + private static AbstractCriterion ProcessSubqueryExpression(LambdaSubqueryType subqueryType, BinaryExpression be) { Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs 2011-05-28 07:12:07 UTC (rev 5876) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs 2011-05-28 11:13:51 UTC (rev 5877) @@ -640,6 +640,34 @@ } [Test] + public void FunctionsOrder() + { + using (ISession s = OpenSession()) + using (ITransaction t = s.BeginTransaction()) + { + s.Save(new Person() { Name = "p2", BirthDate = new DateTime(2008, 07, 06) }); + s.Save(new Person() { Name = "p1", BirthDate = new DateTime(2009, 08, 07) }); + s.Save(new Person() { Name = "p3", BirthDate = new DateTime(2007, 06, 05) }); + + t.Commit(); + } + + using (ISession s = OpenSession()) + using (ITransaction t = s.BeginTransaction()) + { + var persons = + s.QueryOver<Person>() + .OrderBy(p => p.BirthDate.YearPart()).Desc + .List(); + + persons.Count.Should().Be(3); + persons[0].Name.Should().Be("p1"); + persons[1].Name.Should().Be("p2"); + persons[2].Name.Should().Be("p3"); + } + } + + [Test] public void MultiCriteria() { SetupPagingData(); Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs 2011-05-28 07:12:07 UTC (rev 5876) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs 2011-05-28 11:13:51 UTC (rev 5877) @@ -608,10 +608,10 @@ { ICriteria expected = CreateTestCriteria(typeof(Person), "personAlias") - .AddOrder(Order.Asc("Name")) - .AddOrder(Order.Desc("Age")) - .AddOrder(Order.Desc("personAlias.Name")) - .AddOrder(Order.Asc("personAlias.Age")) + .AddOrder(Order.Asc(Projections.Property("Name"))) + .AddOrder(Order.Desc(Projections.Property("Age"))) + .AddOrder(Order.Desc(Projections.Property("personAlias.Name"))) + .AddOrder(Order.Asc(Projections.Property("personAlias.Age"))) .AddOrder(Order.Asc("summary")) .AddOrder(Order.Desc("Count")); @@ -630,11 +630,26 @@ } [Test] + public void OrderByFunction() + { + ICriteria expected = + CreateTestCriteria(typeof(Person), "personAlias") + .AddOrder(Order.Desc(Projections.SqlFunction("year", NHibernateUtil.Int32, Projections.Property("personAlias.BirthDate")))); + + Person personAlias = null; + IQueryOver<Person> actual = + CreateTestQueryOver<Person>(() => personAlias) + .OrderBy(() => personAlias.BirthDate.YearPart()).Desc; + + AssertCriteriaAreEqual(expected, actual); + } + + [Test] public void AllowSingleCallSyntax() { ICriteria expected = CreateTestCriteria(typeof(Person)); expected.Add(Restrictions.IsNotEmpty("Children")); - expected.AddOrder(Order.Asc("Name")); + expected.AddOrder(Order.Asc(Projections.Property("Name"))); expected.SetFetchMode("PersonList", FetchMode.Eager); expected.SetLockMode(LockMode.UpgradeNoWait); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pa...@us...> - 2011-05-28 07:12:13
|
Revision: 5876 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5876&view=rev Author: patearl Date: 2011-05-28 07:12:07 +0000 (Sat, 28 May 2011) Log Message: ----------- Tests: Fixed orphaned objects left by Trim test. Modified Paths: -------------- trunk/nhibernate/src/NHibernate.Test/Linq/FunctionTests.cs Modified: trunk/nhibernate/src/NHibernate.Test/Linq/FunctionTests.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/FunctionTests.cs 2011-05-28 06:54:58 UTC (rev 5875) +++ trunk/nhibernate/src/NHibernate.Test/Linq/FunctionTests.cs 2011-05-28 07:12:07 UTC (rev 5876) @@ -124,9 +124,10 @@ { try { - session.Save(new AnotherEntity { Id = 100, Input = " hi " }); - session.Save(new AnotherEntity { Id = 101, Input = "hi" }); - session.Save(new AnotherEntity { Id = 102, Input = "heh" }); + session.Save(new AnotherEntity { Input = " hi " }); + session.Save(new AnotherEntity { Input = "hi" }); + session.Save(new AnotherEntity { Input = "heh" }); + session.Flush(); Assert.AreEqual(2, session.Query<AnotherEntity>().Where(e => e.Input.Trim() == "hi").Count()); Assert.AreEqual(TestDialect.IgnoresTrailingWhitespace ? 2 : 1, session.Query<AnotherEntity>().Where(e => e.Input.TrimStart() == "hi ").Count()); @@ -139,7 +140,8 @@ } finally { - session.Delete("from AnotherEntity e where e.Id >= 100"); + session.Delete("from AnotherEntity e where e.Id > 5"); + session.Flush(); } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pa...@us...> - 2011-05-28 06:55:04
|
Revision: 5875 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5875&view=rev Author: patearl Date: 2011-05-28 06:54:58 +0000 (Sat, 28 May 2011) Log Message: ----------- Tests: Fixed a typo in a test. Modified Paths: -------------- trunk/nhibernate/src/NHibernate.Test/Linq/FunctionTests.cs Modified: trunk/nhibernate/src/NHibernate.Test/Linq/FunctionTests.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/FunctionTests.cs 2011-05-28 06:39:13 UTC (rev 5874) +++ trunk/nhibernate/src/NHibernate.Test/Linq/FunctionTests.cs 2011-05-28 06:54:58 UTC (rev 5875) @@ -139,7 +139,7 @@ } finally { - session.Delete("from AnotherEntity where Id >= 100"); + session.Delete("from AnotherEntity e where e.Id >= 100"); } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pa...@us...> - 2011-05-28 06:39:20
|
Revision: 5874 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5874&view=rev Author: patearl Date: 2011-05-28 06:39:13 +0000 (Sat, 28 May 2011) Log Message: ----------- Linq: Support Trim function. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Linq/Functions/DefaultLinqToHqlGeneratorsRegistry.cs trunk/nhibernate/src/NHibernate/Linq/Functions/StringGenerator.cs trunk/nhibernate/src/NHibernate.Test/Linq/FunctionTests.cs trunk/nhibernate/src/NHibernate.Test/TestDialect.cs Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/TestDialects/MsSql2008TestDialect.cs Modified: trunk/nhibernate/src/NHibernate/Linq/Functions/DefaultLinqToHqlGeneratorsRegistry.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Functions/DefaultLinqToHqlGeneratorsRegistry.cs 2011-05-28 05:34:42 UTC (rev 5873) +++ trunk/nhibernate/src/NHibernate/Linq/Functions/DefaultLinqToHqlGeneratorsRegistry.cs 2011-05-28 06:39:13 UTC (rev 5874) @@ -30,6 +30,7 @@ this.Merge(new IndexOfGenerator()); this.Merge(new ReplaceGenerator()); this.Merge(new LengthGenerator()); + this.Merge(new TrimGenerator()); this.Merge(new AnyHqlGenerator()); this.Merge(new AllHqlGenerator()); Modified: trunk/nhibernate/src/NHibernate/Linq/Functions/StringGenerator.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Functions/StringGenerator.cs 2011-05-28 05:34:42 UTC (rev 5873) +++ trunk/nhibernate/src/NHibernate/Linq/Functions/StringGenerator.cs 2011-05-28 06:39:13 UTC (rev 5874) @@ -195,6 +195,46 @@ } } + public class TrimGenerator : BaseHqlGeneratorForMethod + { + public TrimGenerator() + { + SupportedMethods = new[] + { + ReflectionHelper.GetMethodDefinition<string>(s => s.Trim()), + ReflectionHelper.GetMethodDefinition<string>(s => s.Trim('a')), + ReflectionHelper.GetMethodDefinition<string>(s => s.TrimStart('a')), + ReflectionHelper.GetMethodDefinition<string>(s => s.TrimEnd('a')) + }; + } + + public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) + { + string trimWhere; + if (method.Name == "TrimStart") + trimWhere = "leading"; + else if (method.Name == "TrimEnd") + trimWhere = "trailing"; + else + trimWhere = "both"; + + string trimChars = ""; + if (method.GetParameters().Length > 0) + foreach (char c in (char[])((ConstantExpression)arguments[0]).Value) + trimChars += c; + + + if (trimChars == "") + { + return treeBuilder.MethodCall("trim", treeBuilder.Ident(trimWhere), treeBuilder.Ident("from"), visitor.Visit(targetObject).AsExpression()); + } + else + { + return treeBuilder.MethodCall("trim", treeBuilder.Ident(trimWhere), treeBuilder.Constant(trimChars), treeBuilder.Ident("from"), visitor.Visit(targetObject).AsExpression()); + } + } + } + public class ToStringRuntimeMethodHqlGenerator : IRuntimeMethodHqlGenerator { private readonly ToStringHqlGeneratorForMethod generator = new ToStringHqlGeneratorForMethod(); Modified: trunk/nhibernate/src/NHibernate.Test/Linq/FunctionTests.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/FunctionTests.cs 2011-05-28 05:34:42 UTC (rev 5873) +++ trunk/nhibernate/src/NHibernate.Test/Linq/FunctionTests.cs 2011-05-28 06:39:13 UTC (rev 5874) @@ -118,5 +118,29 @@ { Assert.AreEqual(2, session.Query<AnotherEntity>().Where(e => (e.Input ?? "hello") == "hello").Count()); } + + [Test] + public void Trim() + { + try + { + session.Save(new AnotherEntity { Id = 100, Input = " hi " }); + session.Save(new AnotherEntity { Id = 101, Input = "hi" }); + session.Save(new AnotherEntity { Id = 102, Input = "heh" }); + + Assert.AreEqual(2, session.Query<AnotherEntity>().Where(e => e.Input.Trim() == "hi").Count()); + Assert.AreEqual(TestDialect.IgnoresTrailingWhitespace ? 2 : 1, session.Query<AnotherEntity>().Where(e => e.Input.TrimStart() == "hi ").Count()); + Assert.AreEqual(1, session.Query<AnotherEntity>().Where(e => e.Input.TrimEnd() == " hi").Count()); + + // Emulated trim does not support multiple trim characters, but for many databases it should work fine anyways. + Assert.AreEqual(1, session.Query<AnotherEntity>().Where(e => e.Input.Trim('h') == "e").Count()); + Assert.AreEqual(1, session.Query<AnotherEntity>().Where(e => e.Input.TrimStart('h') == "eh").Count()); + Assert.AreEqual(1, session.Query<AnotherEntity>().Where(e => e.Input.TrimEnd('h') == "he").Count()); + } + finally + { + session.Delete("from AnotherEntity where Id >= 100"); + } + } } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/TestDialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/TestDialect.cs 2011-05-28 05:34:42 UTC (rev 5873) +++ trunk/nhibernate/src/NHibernate.Test/TestDialect.cs 2011-05-28 06:39:13 UTC (rev 5874) @@ -53,6 +53,8 @@ public virtual bool SupportsHavingWithoutGroupBy { get { return true; } } + public virtual bool IgnoresTrailingWhitespace { get { return false; } } + public bool SupportsSqlType(SqlType sqlType) { try Copied: trunk/nhibernate/src/NHibernate.Test/TestDialects/MsSql2008TestDialect.cs (from rev 5872, trunk/nhibernate/src/NHibernate.Test/TestDialects/SQLiteTestDialect.cs) =================================================================== --- trunk/nhibernate/src/NHibernate.Test/TestDialects/MsSql2008TestDialect.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/TestDialects/MsSql2008TestDialect.cs 2011-05-28 06:39:13 UTC (rev 5874) @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace NHibernate.Test.TestDialects +{ + public class MsSql2008TestDialect : TestDialect + { + public MsSql2008TestDialect(Dialect.Dialect dialect) + : base(dialect) + { + } + + public override bool IgnoresTrailingWhitespace + { + get { return true; } + } + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pa...@us...> - 2011-05-28 05:34:48
|
Revision: 5873 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5873&view=rev Author: patearl Date: 2011-05-28 05:34:42 +0000 (Sat, 28 May 2011) Log Message: ----------- Tests: Linq test for coalesce operator. Modified Paths: -------------- trunk/nhibernate/src/NHibernate.Test/Linq/FunctionTests.cs Modified: trunk/nhibernate/src/NHibernate.Test/Linq/FunctionTests.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/FunctionTests.cs 2011-05-25 22:58:47 UTC (rev 5872) +++ trunk/nhibernate/src/NHibernate.Test/Linq/FunctionTests.cs 2011-05-28 05:34:42 UTC (rev 5873) @@ -1,4 +1,6 @@ using System.Linq; +using NHibernate.DomainModel.Northwind.Entities; +using NHibernate.Linq; using NUnit.Framework; namespace NHibernate.Test.Linq @@ -110,5 +112,11 @@ Assert.AreEqual(498, query.Count()); } + + [Test] + public void Coalesce() + { + Assert.AreEqual(2, session.Query<AnotherEntity>().Where(e => (e.Input ?? "hello") == "hello").Count()); + } } } \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pa...@us...> - 2011-05-25 22:58:54
|
Revision: 5872 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5872&view=rev Author: patearl Date: 2011-05-25 22:58:47 +0000 (Wed, 25 May 2011) Log Message: ----------- NH-2721: Added ignored test. Modified Paths: -------------- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2721/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2721/A.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2721/B.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2721/Fixture.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2721/Mappings.hbm.xml Copied: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2721/A.cs (from rev 5848, trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2279/A.cs) =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2721/A.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2721/A.cs 2011-05-25 22:58:47 UTC (rev 5872) @@ -0,0 +1,29 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace NHibernate.Test.NHSpecificTest.NH2721 +{ + public class A + { + private IList<B> _bs = new List<B>(); + + public A() + { + } + + public A(string name) + { + Name = name; + } + + public int? Id { get; set; } + public string Name { get; set; } + + public IList<B> Bs + { + get { return _bs; } + set { _bs = value; } + } + } +} Copied: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2721/B.cs (from rev 5848, trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2279/B.cs) =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2721/B.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2721/B.cs 2011-05-25 22:58:47 UTC (rev 5872) @@ -0,0 +1,22 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace NHibernate.Test.NHSpecificTest.NH2721 +{ + public class B + { + public B() + { + } + + public B(string name) + { + Name = name; + } + + public int? Id { get; set; } + public string Name { get; set; } + public A A { get; set; } + } +} Copied: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2721/Fixture.cs (from rev 5848, trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2279/Fixture.cs) =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2721/Fixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2721/Fixture.cs 2011-05-25 22:58:47 UTC (rev 5872) @@ -0,0 +1,68 @@ +using System.Collections.Generic; +using System.Linq; +using System.Collections; + +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.NH2721 +{ + [TestFixture] + public class Fixture : BugTestCase + { + protected override void OnTearDown() + { + using( ISession s = sessions.OpenSession() ) + { + s.Delete("from A"); + s.Flush(); + } + } + + [Test] + [Ignore("Does not work because of extraneous update that sets reference to A to null. Can be worked-around by removing not-null on reference to A.")] + public void ListRemoveInsert() + { + A a = new A("a"); + + B b1 = new B("b1"); + a.Bs.Add(b1); + b1.A = a; + + B b2 = new B("b2"); + a.Bs.Add(b2); + b2.A = a; + + B b3 = new B("b3"); + a.Bs.Add(b3); + b3.A = a; + + using (ISession s = OpenSession()) + { + s.SaveOrUpdate(a); + s.Flush(); + } + + using (ISession s = OpenSession()) + { + a = (A) s.Load(typeof (A), a.Id); + CollectionAssert.AreEquivalent(new[] {"b1", "b2", "b3"}, a.Bs.Select(b => b.Name)); + + B removed = a.Bs[2]; + a.Bs.Remove(removed); + a.Bs.Insert(1, removed); + Assert.IsNotNull(a.Bs[0].A); + Assert.IsNotNull(a.Bs[1].A); + Assert.IsNotNull(a.Bs[2].A); + CollectionAssert.AreEquivalent(new[] {"b1", "b3", "b2"}, a.Bs.Select(b => b.Name)); + s.SaveOrUpdate(a); + s.Flush(); + } + + using (ISession s = OpenSession()) + { + a = (A) s.Load(typeof (A), a.Id); + CollectionAssert.AreEquivalent(new[] { "b1", "b3", "b2" }, a.Bs.Select(b => b.Name)); + } + } + } +} \ No newline at end of file Copied: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2721/Mappings.hbm.xml (from rev 5848, trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2279/Mappings.hbm.xml) =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2721/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2721/Mappings.hbm.xml 2011-05-25 22:58:47 UTC (rev 5872) @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping + xmlns="urn:nhibernate-mapping-2.2" + assembly="NHibernate.Test" + namespace="NHibernate.Test.NHSpecificTest.NH2721"> + + <class name="A" table="a" lazy="false"> + <id name="Id" column="id" unsaved-value="null"> + <generator class="native" /> + </id> + <property name="Name" column="name" /> + <list name="Bs" cascade="all-delete-orphan" inverse="false"> + <key column="a_id" /> + <index column="position" /> + <one-to-many class="B" /> + </list> + </class> + + <class name="B" table="b" lazy="false"> + <id name="Id" column="id" unsaved-value="null"> + <generator class="native" /> + </id> + <many-to-one name="A" class="A" column="a_id" not-null="true"/> + <property name="Name" column="name" /> + </class> + +</hibernate-mapping> \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-05-25 21:16:01 UTC (rev 5871) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-05-25 22:58:47 UTC (rev 5872) @@ -854,6 +854,9 @@ <Compile Include="NHSpecificTest\NH2705\SubItemBase.cs" /> <Compile Include="NHSpecificTest\NH2705\SubItemDetails.cs" /> <Compile Include="NHSpecificTest\NH2705\Test.cs" /> + <Compile Include="NHSpecificTest\NH2721\A.cs" /> + <Compile Include="NHSpecificTest\NH2721\B.cs" /> + <Compile Include="NHSpecificTest\NH2721\Fixture.cs" /> <Compile Include="NHSpecificTest\NH2733\Fixture.cs" /> <Compile Include="NHSpecificTest\NH2733\Model.cs" /> <Compile Include="NHSpecificTest\Properties\CompositePropertyRefTest.cs" /> @@ -2698,6 +2701,7 @@ <EmbeddedResource Include="NHSpecificTest\NH1291AnonExample\Mappings.hbm.xml" /> </ItemGroup> <ItemGroup> + <EmbeddedResource Include="NHSpecificTest\NH2721\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2733\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2317\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2366\Mappings.hbm.xml" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2011-05-25 21:16:08
|
Revision: 5871 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5871&view=rev Author: ricbrown Date: 2011-05-25 21:16:01 +0000 (Wed, 25 May 2011) Log Message: ----------- NH-2733 (NH-2683): Using an expression in QueryOver gives: Lambda Parameter not in scope Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFixture.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2733/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2733/Fixture.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2733/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2733/Model.cs Modified: trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs 2011-05-25 12:47:06 UTC (rev 5870) +++ trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs 2011-05-25 21:16:01 UTC (rev 5871) @@ -334,10 +334,14 @@ if (memberExpression.Expression.NodeType == ExpressionType.MemberAccess) { + if (IsMemberExpression(memberExpression.Expression)) + return true; + // if the member has a null value, it was an alias - if (EvaluatesToNull(memberExpression.Expression)) - return true; + return EvaluatesToNull(memberExpression.Expression); } + + return IsMemberExpression(memberExpression.Expression); } if (expression is UnaryExpression) @@ -358,9 +362,16 @@ if (_customProjectionProcessors.ContainsKey(signature)) return true; + if (methodCallExpression.Method.Name == "First") + { + if (IsMemberExpression(methodCallExpression.Arguments[0])) + return true; + + return EvaluatesToNull(methodCallExpression.Arguments[0]); + } + if (methodCallExpression.Method.Name == "GetType" - || methodCallExpression.Method.Name == "get_Item" - || methodCallExpression.Method.Name == "First") + || methodCallExpression.Method.Name == "get_Item") { if (IsMemberExpression(methodCallExpression.Object)) return true; Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFixture.cs 2011-05-25 12:47:06 UTC (rev 5870) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFixture.cs 2011-05-25 21:16:01 UTC (rev 5871) @@ -1,5 +1,6 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; @@ -19,35 +20,165 @@ public void TestFindMemberExpressionReference() { Expression<Func<Person, string>> e = (Person p) => p.Name; - string property = ExpressionProcessor.FindMemberExpression(e.Body); + string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString(); Assert.AreEqual("Name", property); } [Test] + public void TestFindMemberExpressionReferenceAlias() + { + Person personAlias = null; + Expression<Func<string>> e = () => personAlias.Name; + string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString(); + Assert.AreEqual("personAlias.Name", property); + } + + [Test] + public void TestFindMemberExpressionComponent() + { + Expression<Func<Person, string>> e = (Person p) => p.Father.Name; + string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString(); + Assert.AreEqual("Father.Name", property); + } + + [Test] + public void TestFindMemberExpressionComponentAlias() + { + Person personAlias = null; + Expression<Func<string>> e = () => personAlias.Father.Name; + string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString(); + Assert.AreEqual("personAlias.Father.Name", property); + } + + [Test] public void TestFindMemberExpressionValue() { Expression<Func<Person, object>> e = (Person p) => p.Age; - string property = ExpressionProcessor.FindMemberExpression(e.Body); + string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString(); Assert.AreEqual("Age", property); } [Test] + public void TestFindMemberExpressionValueAlias() + { + Person personAlias = null; + Expression<Func<object>> e = () => personAlias.Age; + string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString(); + Assert.AreEqual("personAlias.Age", property); + } + + [Test] public void TestFindMemberExpressionSubCollectionIndex() { Expression<Func<Person, object>> e = (Person p) => p.PersonList[0].Children; - string property = ExpressionProcessor.FindMemberExpression(e.Body); + string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString(); Assert.AreEqual("PersonList.Children", property); } [Test] + public void TestFindMemberExpressionSubCollectionIndexAlias() + { + Person personAlias = null; + Expression<Func<object>> e = () => personAlias.PersonList[0].Children; + string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString(); + Assert.AreEqual("personAlias.PersonList.Children", property); + } + + [Test] + public void TestFindMemberExpressionSubCollectionFirst() + { + Expression<Func<Person, object>> e = (Person p) => p.PersonList.First().Children; + string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString(); + Assert.AreEqual("PersonList.Children", property); + } + + [Test] + public void TestFindMemberExpressionSubCollectionFirstAlias() + { + Person personAlias = null; + Expression<Func<object>> e = () => personAlias.PersonList.First().Children; + string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString(); + Assert.AreEqual("personAlias.PersonList.Children", property); + } + + [Test] public void TestFindMemberExpressionSubCollectionExtensionMethod() { Expression<Func<Person, object>> e = (Person p) => p.PersonList.First().Children; - string property = ExpressionProcessor.FindMemberExpression(e.Body); + string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString(); Assert.AreEqual("PersonList.Children", property); } [Test] + public void TestFindMemberExpressionSubCollectionExtensionMethodAlias() + { + Person personAlias = null; + Expression<Func<object>> e = () => personAlias.PersonList.First().Children; + string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString(); + Assert.AreEqual("personAlias.PersonList.Children", property); + } + + [Test] + public void TestFindMemberExpressionClass() + { + Expression<Func<Person, object>> e = (Person p) => p.GetType(); + string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString(); + Assert.AreEqual("class", property); + } + + [Test] + public void TestFindMemberExpressionClassAlias() + { + Person personAlias = null; + Expression<Func<object>> e = () => personAlias.GetType(); + string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString(); + Assert.AreEqual("personAlias.class", property); + } + + [Test] + public void TestFindMemberExpressionNullableValue() + { + Expression<Func<Person, object>> e = (Person p) => p.NullableGender.Value; + string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString(); + Assert.AreEqual("NullableGender", property); + } + + [Test] + public void TestFindMemberExpressionNullableValueAlias() + { + Person personAlias = null; + Expression<Func<object>> e = () => personAlias.NullableGender.Value; + string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString(); + Assert.AreEqual("personAlias.NullableGender", property); + } + + [Test] + public void TestFindMemberExpressionConstants() + { + var children = new List<Child> { new Child { Nickname = "test nickname" } }; + Person person = + new Person() + { + Name = "test name", + NullableAge = 4, + Children = children, + }; + + Assert.That(Projection(() => person.Name), Is.EqualTo("test name")); + Assert.That(Projection(() => "test name"), Is.EqualTo("test name")); + Assert.That(Projection(() => person.NullableAge.Value), Is.EqualTo(4)); + Assert.That(Projection(() => person.GetType()), Is.EqualTo(typeof(Person))); + Assert.That(Projection(() => person.Children.First().Nickname), Is.EqualTo("test nickname")); + Assert.That(Projection(() => children[0].Nickname), Is.EqualTo("test nickname")); + } + + private T Projection<T>(Expression<Func<T>> e) + { + var constantProjection = ExpressionProcessor.FindMemberProjection(e.Body); + return (T)typeof(ConstantProjection).GetField("value", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(constantProjection); + } + + [Test] public void TestEvaluatePropertyExpression() { string testName = "testName"; Property changes on: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2733 ___________________________________________________________________ Added: bugtraq:url + http://jira.nhibernate.org/browse/%BUGID% Added: bugtraq:logregex + NH-\d+ Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2733/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2733/Fixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2733/Fixture.cs 2011-05-25 21:16:01 UTC (rev 5871) @@ -0,0 +1,81 @@ +using System; +using System.Linq.Expressions; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.NH2733 +{ + public interface ISpecification + { + Expression Expression { get; } + } + + public interface ISpecification<T> : ISpecification + { + Expression<Func<T, bool>> Predicate { get; } + } + + public class Specification<T> + { + public Expression<Func<T, bool>> Predicate { get; protected set; } + + public Expression Expression + { + get + { + return Predicate; + } + } + + public Specification(Expression<Func<T, bool>> predicate) + { + Predicate = predicate; + } + } + + [TestFixture] + public class Fixture : BugTestCase + { + Item Item = null; + + protected override void OnSetUp() + { + using (ISession session = Sfi.OpenSession()) + { + var item = new Item(); + session.Persist(item); + session.Flush(); + } + } + + protected override void OnTearDown() + { + using (ISession session = Sfi.OpenSession()) + { + session.CreateQuery("delete from Item").ExecuteUpdate(); + session.Flush(); + } + base.OnTearDown(); + } + + public static Expression<Func<Item, bool>> GetExpression(DateTime startTime) + { + return item => item.Details.StartTime == startTime; + } + + [Test] + public void CanUseExpressionForWhere() + { + using (ISession session = Sfi.OpenSession()) + { + IQueryOver<Item, Item> query = session.QueryOver(() => Item); + + var start = DateTime.UtcNow; + + query + .Where(GetExpression(start)); + + query.List(); + } + } + } +} Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2733/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2733/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2733/Mappings.hbm.xml 2011-05-25 21:16:01 UTC (rev 5871) @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" + namespace="NHibernate.Test.NHSpecificTest.NH2733" + assembly="NHibernate.Test"> + + <class name="Item" table="`Item_Table`"> + <id name="Id"> + <generator class="native"/> + </id> + <component name="Details"> + <property name="StartTime" /> + </component> + </class> +</hibernate-mapping> Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2733/Model.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2733/Model.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2733/Model.cs 2011-05-25 21:16:01 UTC (rev 5871) @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; + +namespace NHibernate.Test.NHSpecificTest.NH2733 +{ + public class Item + { + public virtual int Id { get; set; } + + public class ItemDetails + { + public virtual DateTime? StartTime { get; set; } + } + + public virtual ItemDetails Details { get; set; } + + public Item() + { + Details = new ItemDetails(); + } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-05-25 12:47:06 UTC (rev 5870) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-05-25 21:16:01 UTC (rev 5871) @@ -854,6 +854,8 @@ <Compile Include="NHSpecificTest\NH2705\SubItemBase.cs" /> <Compile Include="NHSpecificTest\NH2705\SubItemDetails.cs" /> <Compile Include="NHSpecificTest\NH2705\Test.cs" /> + <Compile Include="NHSpecificTest\NH2733\Fixture.cs" /> + <Compile Include="NHSpecificTest\NH2733\Model.cs" /> <Compile Include="NHSpecificTest\Properties\CompositePropertyRefTest.cs" /> <Compile Include="NHSpecificTest\Properties\DynamicEntityTest.cs" /> <Compile Include="NHSpecificTest\Properties\Model.cs" /> @@ -2696,6 +2698,7 @@ <EmbeddedResource Include="NHSpecificTest\NH1291AnonExample\Mappings.hbm.xml" /> </ItemGroup> <ItemGroup> + <EmbeddedResource Include="NHSpecificTest\NH2733\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2317\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2366\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2404\Mappings.hbm.xml" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-05-25 12:47:12
|
Revision: 5870 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5870&view=rev Author: fabiomaulo Date: 2011-05-25 12:47:06 +0000 (Wed, 25 May 2011) Log Message: ----------- Ups... Linq.Dynamic instead Linq Modified Paths: -------------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2477/Fixture.cs Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2477/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2477/Fixture.cs 2011-05-24 12:18:28 UTC (rev 5869) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2477/Fixture.cs 2011-05-25 12:47:06 UTC (rev 5870) @@ -1,5 +1,5 @@ using System; -using System.Linq.Dynamic; +using System.Linq; using NHibernate.Cfg.MappingSchema; using NHibernate.Linq; using NHibernate.Mapping.ByCode; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-05-24 12:18:35
|
Revision: 5869 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5869&view=rev Author: fabiomaulo Date: 2011-05-24 12:18:28 +0000 (Tue, 24 May 2011) Log Message: ----------- Fix NH-2728 Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Mapping/ByCode/ExplicitlyDeclaredModel.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/IModelInspector.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CollectionElementRelation.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/ModelMapper.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/SimpleModelInspector.cs trunk/nhibernate/src/NHibernate/NHibernate.csproj trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ManyToAnyMapper.cs trunk/nhibernate/src/NHibernate.Test/MappingByCode/IntegrationTests/ trunk/nhibernate/src/NHibernate.Test/MappingByCode/IntegrationTests/NH2728/ trunk/nhibernate/src/NHibernate.Test/MappingByCode/IntegrationTests/NH2728/Cat.cs trunk/nhibernate/src/NHibernate.Test/MappingByCode/IntegrationTests/NH2728/Dog.cs trunk/nhibernate/src/NHibernate.Test/MappingByCode/IntegrationTests/NH2728/IAnimal.cs trunk/nhibernate/src/NHibernate.Test/MappingByCode/IntegrationTests/NH2728/SampleTest.cs trunk/nhibernate/src/NHibernate.Test/MappingByCode/IntegrationTests/NH2728/Toy.cs Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/ExplicitlyDeclaredModel.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/ExplicitlyDeclaredModel.cs 2011-05-24 05:29:15 UTC (rev 5868) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/ExplicitlyDeclaredModel.cs 2011-05-24 12:18:28 UTC (rev 5869) @@ -66,6 +66,11 @@ return OneToManyRelations.Contains(member); } + public bool IsManyToAny(MemberInfo member) + { + return ManyToAnyRelations.Contains(member); + } + public virtual bool IsAny(MemberInfo member) { return Any.Contains(member); Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/IModelInspector.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/IModelInspector.cs 2011-05-24 05:29:15 UTC (rev 5868) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/IModelInspector.cs 2011-05-24 12:18:28 UTC (rev 5869) @@ -18,6 +18,8 @@ bool IsManyToOne(MemberInfo member); bool IsManyToMany(MemberInfo member); bool IsOneToMany(MemberInfo member); + bool IsManyToAny(MemberInfo member); + bool IsAny(MemberInfo member); bool IsPersistentId(MemberInfo member); Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CollectionElementRelation.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CollectionElementRelation.cs 2011-05-24 05:29:15 UTC (rev 5868) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CollectionElementRelation.cs 2011-05-24 12:18:28 UTC (rev 5869) @@ -48,7 +48,9 @@ public void ManyToAny(System.Type idTypeOfMetaType, Action<IManyToAnyMapper> mapping) { - throw new NotImplementedException(); + var hbm = new HbmManyToAny(); + mapping(new ManyToAnyMapper(collectionElementType, idTypeOfMetaType, hbm, mapDoc)); + elementRelationshipAssing(hbm); } #endregion Added: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ManyToAnyMapper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ManyToAnyMapper.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ManyToAnyMapper.cs 2011-05-24 12:18:28 UTC (rev 5869) @@ -0,0 +1,156 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NHibernate.Cfg.MappingSchema; +using NHibernate.Type; + +namespace NHibernate.Mapping.ByCode.Impl +{ + public class ManyToAnyMapper: IManyToAnyMapper + { + private const string DefaultIdColumnNameWhenNoProperty = "ReferencedId"; + private const string DefaultMetaColumnNameWhenNoProperty = "ReferencedClass"; + private readonly System.Type elementType; + private readonly System.Type foreignIdType; + private readonly ColumnMapper classColumnMapper; + private readonly ColumnMapper idColumnMapper; + + private readonly HbmManyToAny manyToAny; + private readonly HbmMapping mapDoc; + + public ManyToAnyMapper(System.Type elementType, System.Type foreignIdType, HbmManyToAny manyToAny, HbmMapping mapDoc) + { + if (elementType == null) + { + throw new ArgumentNullException("elementType"); + } + if (foreignIdType == null) + { + throw new ArgumentNullException("foreignIdType"); + } + if (manyToAny == null) + { + throw new ArgumentNullException("manyToAny"); + } + this.elementType = elementType; + this.foreignIdType = foreignIdType; + this.manyToAny = manyToAny; + this.mapDoc = mapDoc; + this.manyToAny.idtype = this.foreignIdType.GetNhTypeName(); + var idHbmColumn = new HbmColumn(); + idColumnMapper = new ColumnMapper(idHbmColumn, DefaultIdColumnNameWhenNoProperty); + var classHbmColumn = new HbmColumn(); + classColumnMapper = new ColumnMapper(classHbmColumn, DefaultMetaColumnNameWhenNoProperty); + manyToAny.column = new[] { classHbmColumn, idHbmColumn }; + } + + public void MetaType(IType metaType) + { + if (metaType != null) + { + CheckMetaTypeImmutability(metaType.Name); + manyToAny.metatype = metaType.Name; + } + } + + public void MetaType<TMetaType>() + { + MetaType(typeof(TMetaType)); + } + + public void MetaType(System.Type metaType) + { + if (metaType != null) + { + string nhTypeName = metaType.GetNhTypeName(); + CheckMetaTypeImmutability(nhTypeName); + manyToAny.metatype = nhTypeName; + } + } + + public void IdType(IType idType) + { + if (idType != null) + { + CheckIdTypeImmutability(idType.Name); + manyToAny.idtype = idType.Name; + } + } + + public void IdType<TIdType>() + { + IdType(typeof(TIdType)); + } + + public void IdType(System.Type idType) + { + if (idType != null) + { + string nhTypeName = idType.GetNhTypeName(); + CheckIdTypeImmutability(nhTypeName); + manyToAny.idtype = nhTypeName; + } + } + + public void Columns(Action<IColumnMapper> idColumnMapping, Action<IColumnMapper> classColumnMapping) + { + idColumnMapping(idColumnMapper); + classColumnMapping(classColumnMapper); + } + + public void MetaValue(object value, System.Type entityType) + { + if (value == null) + { + throw new ArgumentNullException("value"); + } + if (entityType == null) + { + throw new ArgumentNullException("entityType"); + } + if (value is System.Type) + { + throw new ArgumentOutOfRangeException("value", "System.Type is invalid meta-type (you don't need to set meta-values)."); + } + if(!elementType.IsAssignableFrom(entityType)) + { + throw new ArgumentOutOfRangeException("entityType", string.Format("A {0} is not assignable to the collection's elements which type is {1}", entityType, elementType)); + } + System.Type metavalueType = value.GetType(); + if (manyToAny.metavalue == null) + { + manyToAny.metavalue = new HbmMetaValue[0]; + } + Dictionary<string, string> values = manyToAny.metavalue.ToDictionary(mv => mv.value, mv => mv.@class); + MetaType(metavalueType); + string newClassMetavalue = entityType.GetShortClassName(mapDoc); + string metavalueKey = value.ToString(); + string existingClassMetavalue; + if (values.TryGetValue(metavalueKey, out existingClassMetavalue) && existingClassMetavalue != newClassMetavalue) + { + throw new ArgumentException( + string.Format( + "Can't set two different classes for same meta-value (meta-value='{0}' old-class:'{1}' new-class='{2}')", + metavalueKey, existingClassMetavalue, newClassMetavalue)); + } + values[metavalueKey] = newClassMetavalue; + manyToAny.metavalue = values.Select(vd => new HbmMetaValue { value = vd.Key, @class = vd.Value }).ToArray(); + } + + private void CheckMetaTypeImmutability(string nhTypeName) + { + if (manyToAny.metavalue != null && manyToAny.metavalue.Length > 0 && manyToAny.metatype != nhTypeName) + { + throw new ArgumentException(string.Format("Can't change the meta-type (was '{0}' trying to change to '{1}')", manyToAny.metatype, nhTypeName)); + } + } + + private void CheckIdTypeImmutability(string nhTypeName) + { + if (manyToAny.metavalue != null && manyToAny.metavalue.Length > 0 && manyToAny.idtype != nhTypeName) + { + throw new ArgumentException(string.Format("Can't change the id-type after add meta-values (was '{0}' trying to change to '{1}')", manyToAny.idtype, nhTypeName)); + } + } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/ModelMapper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/ModelMapper.cs 2011-05-24 05:29:15 UTC (rev 5868) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/ModelMapper.cs 2011-05-24 12:18:28 UTC (rev 5869) @@ -1264,6 +1264,10 @@ { return new ComponentRelationMapper(property, ownerType, collectionElementType, membersProvider, modelInspector, customizerHolder, this); } + if (modelInspector.IsManyToAny(property)) + { + return new ManyToAnyRelationMapper(propertyPath, customizerHolder, this); + } return new ElementRelationMapper(propertyPath, customizerHolder, this); } @@ -1619,6 +1623,35 @@ #endregion + #region Nested type: ManyToAnyRelationMapper + + private class ManyToAnyRelationMapper : ICollectionElementRelationMapper + { + private readonly ICustomizersHolder customizersHolder; + private readonly ModelMapper modelMapper; + private readonly PropertyPath propertyPath; + + public ManyToAnyRelationMapper(PropertyPath propertyPath, ICustomizersHolder customizersHolder, ModelMapper modelMapper) + { + this.propertyPath = propertyPath; + this.customizersHolder = customizersHolder; + this.modelMapper = modelMapper; + } + + #region Implementation of ICollectionElementRelationMapper + + public void Map(ICollectionElementRelation relation) + { + relation.ManyToAny(typeof(int), x => customizersHolder.InvokeCustomizers(propertyPath, x)); + } + + public void MapCollectionProperties(ICollectionPropertiesMapper mapped) { } + + #endregion + } + + #endregion + #region Nested type: OneToManyRelationMapper private class OneToManyRelationMapper : ICollectionElementRelationMapper Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/SimpleModelInspector.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/SimpleModelInspector.cs 2011-05-24 05:29:15 UTC (rev 5868) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/SimpleModelInspector.cs 2011-05-24 12:18:28 UTC (rev 5869) @@ -78,6 +78,11 @@ return OneToManyRelations.Contains(member); } + public bool IsManyToAny(MemberInfo member) + { + return ManyToAnyRelations.Contains(member); + } + public bool IsAny(MemberInfo member) { return Any.Contains(member); @@ -173,6 +178,7 @@ private Func<MemberInfo, bool, bool> isDynamicComponent = (m, declared) => declared; private Func<MemberInfo, bool, bool> isAny = (m, declared) => declared; private Func<MemberInfo, bool, bool> isManyToMany = (m, declared) => declared; + private Func<MemberInfo, bool, bool> isManyToAny = (m, declared) => declared; private Func<MemberInfo, bool, bool> isManyToOne; private Func<MemberInfo, bool, bool> isMemberOfNaturalId = (m, declared) => declared; private Func<MemberInfo, bool, bool> isOneToMany; @@ -713,6 +719,12 @@ return isOneToMany(member, declaredResult); } + bool IModelInspector.IsManyToAny(MemberInfo member) + { + bool declaredResult = DeclaredPolymorphicMatch(member, m => declaredModel.IsManyToAny(m)); + return isManyToAny(member, declaredResult); + } + bool IModelInspector.IsAny(MemberInfo member) { bool declaredResult = DeclaredPolymorphicMatch(member, m => declaredModel.IsAny(m)); @@ -910,6 +922,15 @@ isOneToMany = match; } + public void IsManyToAny(Func<MemberInfo, bool, bool> match) + { + if (match == null) + { + return; + } + isManyToAny = match; + } + public void IsAny(Func<MemberInfo, bool, bool> match) { if (match == null) Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2011-05-24 05:29:15 UTC (rev 5868) +++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2011-05-24 12:18:28 UTC (rev 5869) @@ -311,6 +311,7 @@ <Compile Include="Mapping\ByCode\Impl\CustomizersImpl\DynamicComponentCustomizer.cs" /> <Compile Include="Mapping\ByCode\Impl\CustomizersImpl\ManyToAnyCustomizer.cs" /> <Compile Include="Mapping\ByCode\Impl\DynamicComponentMapper.cs" /> + <Compile Include="Mapping\ByCode\Impl\ManyToAnyMapper.cs" /> <Compile Include="Mapping\ByCode\PropertyGeneration.cs" /> <Compile Include="Mapping\ByCode\PropertyToField.cs" /> <Compile Include="Mapping\ByCode\SimpleModelInspector.cs" /> Added: trunk/nhibernate/src/NHibernate.Test/MappingByCode/IntegrationTests/NH2728/Cat.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/MappingByCode/IntegrationTests/NH2728/Cat.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/MappingByCode/IntegrationTests/NH2728/Cat.cs 2011-05-24 12:18:28 UTC (rev 5869) @@ -0,0 +1,11 @@ +using System; + +namespace NHibernate.Test.MappingByCode.IntegrationTests.NH2728 +{ + public class Cat : IAnimal + { + public virtual int Id { get; set; } + public virtual string Name { get; set; } + public virtual DateTime Born { get; set; } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/MappingByCode/IntegrationTests/NH2728/Dog.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/MappingByCode/IntegrationTests/NH2728/Dog.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/MappingByCode/IntegrationTests/NH2728/Dog.cs 2011-05-24 12:18:28 UTC (rev 5869) @@ -0,0 +1,10 @@ + +namespace NHibernate.Test.MappingByCode.IntegrationTests.NH2728 +{ + public class Dog : IAnimal + { + public virtual int Id { get; set; } + public virtual string Name { get; set; } + public virtual int Walks { get; set; } + } +} Added: trunk/nhibernate/src/NHibernate.Test/MappingByCode/IntegrationTests/NH2728/IAnimal.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/MappingByCode/IntegrationTests/NH2728/IAnimal.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/MappingByCode/IntegrationTests/NH2728/IAnimal.cs 2011-05-24 12:18:28 UTC (rev 5869) @@ -0,0 +1,9 @@ + +namespace NHibernate.Test.MappingByCode.IntegrationTests.NH2728 +{ + public interface IAnimal + { + int Id { get; set; } + string Name { get; set; } + } +} Added: trunk/nhibernate/src/NHibernate.Test/MappingByCode/IntegrationTests/NH2728/SampleTest.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/MappingByCode/IntegrationTests/NH2728/SampleTest.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/MappingByCode/IntegrationTests/NH2728/SampleTest.cs 2011-05-24 12:18:28 UTC (rev 5869) @@ -0,0 +1,111 @@ +using System; +using NHibernate.Cfg.MappingSchema; +using NHibernate.Mapping.ByCode; +using NUnit.Framework; + +namespace NHibernate.Test.MappingByCode.IntegrationTests.NH2728 +{ + [TestFixture] + public class SampleTest : TestCaseMappingByCode + { + protected override HbmMapping GetMappings() + { + var mapper = new ConventionModelMapper(); + // Working Example + //mapper.Class<Toy>(rc => rc.Set(x => x.Animals, cmap => { }, rel => rel.ManyToAny<int>(meta => + // { + // meta.MetaValue(1, typeof (Cat)); + // meta.MetaValue(2, typeof (Dog)); + // }))); + + // User needs + mapper.Class<Toy>(rc => rc.Set(x => x.Animals, cmap => + { + cmap.Table("Animals_Toys"); + cmap.Key(km => km.Column("Cat_Id")); + }, rel => rel.ManyToAny<int>(meta => + { + meta.MetaValue(1, typeof(Cat)); + meta.MetaValue(2, typeof(Dog)); + meta.Columns(cid => + { + cid.Name("Animal_Id"); + cid.NotNullable(true); + }, ctype => + { + ctype.Name("Animal_Type"); + ctype.NotNullable(true); + }); + }))); + var mappings = mapper.CompileMappingFor(new[] { typeof(Cat), typeof(Dog), typeof(Toy) }); + //Console.WriteLine(mappings.AsString()); // <=== uncomment this line to see the XML mapping + return mappings; + } + + protected override void OnSetUp() + { + base.OnSetUp(); + using (ISession session = this.OpenSession()) + { + var cat1 = new Cat() + { + Id = 1, + Name = "Cat 1", + Born = DateTime.Now, + }; + session.Save(cat1); + + var cat2 = new Cat() + { + Id = 2, + Name = "Cat 2", + Born = DateTime.Now, + }; + session.Save(cat2); + + var dog1 = new Dog() + { + Id = 1, + Name = "Dog 1", + Walks = 11, + }; + session.Save(dog1); + + var toy1 = new Toy() + { + Id = 1, + Name = "Toy 1", + }; + toy1.Animals.Add(cat1); + toy1.Animals.Add(cat2); + toy1.Animals.Add(dog1); + session.Save(toy1); + + session.Flush(); + } + } + + protected override void OnTearDown() + { + base.OnTearDown(); + using (ISession session = this.OpenSession()) + { + string hql = "from System.Object"; + session.Delete(hql); + session.Flush(); + } + } + + [Test] + public void ShouldBeAbleToGetFromToyToAnimals() + { + using (ISession session = this.OpenSession()) + { + var toy1 = session.Get<Toy>(1); + + Assert.AreEqual(1, toy1.Id); + Assert.AreEqual(3, toy1.Animals.Count); + } + } + } +} Added: trunk/nhibernate/src/NHibernate.Test/MappingByCode/IntegrationTests/NH2728/Toy.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/MappingByCode/IntegrationTests/NH2728/Toy.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/MappingByCode/IntegrationTests/NH2728/Toy.cs 2011-05-24 12:18:28 UTC (rev 5869) @@ -0,0 +1,17 @@ +using System.Collections.Generic; + +namespace NHibernate.Test.MappingByCode.IntegrationTests.NH2728 +{ + public class Toy + { + public Toy() + { + Animals = new HashSet<IAnimal>(); + } + + public virtual int Id { get; set; } + public virtual string Name { get; set; } + + public virtual ICollection<IAnimal> Animals { get; protected set; } + } +} Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-05-24 05:29:15 UTC (rev 5868) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-05-24 12:18:28 UTC (rev 5869) @@ -552,6 +552,11 @@ <Compile Include="MappingByCode\ExpliticMappingTests\SubclassPropertiesSplitsTests.cs" /> <Compile Include="MappingByCode\ExpliticMappingTests\VersionTests.cs" /> <Compile Include="MappingByCode\For.cs" /> + <Compile Include="MappingByCode\IntegrationTests\NH2728\Cat.cs" /> + <Compile Include="MappingByCode\IntegrationTests\NH2728\Dog.cs" /> + <Compile Include="MappingByCode\IntegrationTests\NH2728\IAnimal.cs" /> + <Compile Include="MappingByCode\IntegrationTests\NH2728\SampleTest.cs" /> + <Compile Include="MappingByCode\IntegrationTests\NH2728\Toy.cs" /> <Compile Include="MappingByCode\MappersTests\AnyMapperTest.cs" /> <Compile Include="MappingByCode\MappersTests\IdMapperTest.cs" /> <Compile Include="MappingByCode\MappersTests\ManyToOneMapperTest.cs" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pa...@us...> - 2011-05-24 05:29:21
|
Revision: 5868 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5868&view=rev Author: patearl Date: 2011-05-24 05:29:15 +0000 (Tue, 24 May 2011) Log Message: ----------- Noted GetLimitString breaking change in release notes. Modified Paths: -------------- trunk/nhibernate/releasenotes.txt Modified: trunk/nhibernate/releasenotes.txt =================================================================== --- trunk/nhibernate/releasenotes.txt 2011-05-24 05:23:00 UTC (rev 5867) +++ trunk/nhibernate/releasenotes.txt 2011-05-24 05:29:15 UTC (rev 5868) @@ -3,6 +3,7 @@ * removed obsolete "use_outer_join" property from nhibernate-configuration.xsd (simply remove it from your xml configuration) ##### Possible Breaking Changes ##### + * All Dialect.GetLimitString() methods replaced with a single GetLimitString method with a new signature. * [NH-2550] - Allow public access to FieldInterceptor Session (IFieldInterceptor changed) * [NH-2593] - For Microsoft SQL Server the default batch-size (adonet.batch_size) is set to 20 where not explicit defined in the session-factory configuration * - ICollectionPersister added property to fix [NH-2489] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pa...@us...> - 2011-05-24 05:23:09
|
Revision: 5867 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5867&view=rev Author: patearl Date: 2011-05-24 05:23:00 +0000 (Tue, 24 May 2011) Log Message: ----------- Removed all but one Dialect GetLimitString method. (Breaking Change) Various limit-related simplifications, bug fixes, and improvements. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Criterion/SubqueryExpression.cs trunk/nhibernate/src/NHibernate/Dialect/DB2400Dialect.cs trunk/nhibernate/src/NHibernate/Dialect/DB2Dialect.cs trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs trunk/nhibernate/src/NHibernate/Dialect/FirebirdDialect.cs trunk/nhibernate/src/NHibernate/Dialect/InformixDialect.cs trunk/nhibernate/src/NHibernate/Dialect/MsSql2000Dialect.cs trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs trunk/nhibernate/src/NHibernate/Dialect/MsSqlCe40Dialect.cs trunk/nhibernate/src/NHibernate/Dialect/MySQL5Dialect.cs trunk/nhibernate/src/NHibernate/Dialect/MySQLDialect.cs trunk/nhibernate/src/NHibernate/Dialect/Oracle8iDialect.cs trunk/nhibernate/src/NHibernate/Dialect/PostgreSQLDialect.cs trunk/nhibernate/src/NHibernate/Dialect/SQLiteDialect.cs trunk/nhibernate/src/NHibernate/Dialect/SybaseASA9Dialect.cs trunk/nhibernate/src/NHibernate/Dialect/SybaseSQLAnywhere10Dialect.cs trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/SqlGenerator.cs trunk/nhibernate/src/NHibernate/Loader/Loader.cs trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs trunk/nhibernate/src/NHibernate.Test/DialectTest/DB2DialectFixture.cs trunk/nhibernate/src/NHibernate.Test/DialectTest/FirebirdDialectFixture.cs trunk/nhibernate/src/NHibernate.Test/DialectTest/MsSql2005DialectFixture.cs trunk/nhibernate/src/NHibernate.Test/DialectTest/MsSqlCe40DialectFixture.cs trunk/nhibernate/src/NHibernate.Test/DialectTest/MsSqlDialectFixture.cs trunk/nhibernate/src/NHibernate.Test/DialectTest/SQLiteDialectFixture.cs Modified: trunk/nhibernate/src/NHibernate/Criterion/SubqueryExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/SubqueryExpression.cs 2011-05-23 22:25:56 UTC (rev 5866) +++ trunk/nhibernate/src/NHibernate/Criterion/SubqueryExpression.cs 2011-05-24 05:23:00 UTC (rev 5867) @@ -66,7 +66,7 @@ if (criteriaImpl.FirstResult != 0 || criteriaImpl.MaxResults != RowSelection.NoValue) { - int firstResults = Loader.Loader.GetFirstRow(parameters.RowSelection); + int firstResults = factory.Dialect.GetOffsetValue(Loader.Loader.GetFirstRow(parameters.RowSelection)); int maxResults = Loader.Loader.GetMaxOrLimit(factory.Dialect, parameters.RowSelection); int? offsetParameterIndex = criteriaQuery.CreatePagingParameter(firstResults); int? limitParameterIndex = criteriaQuery.CreatePagingParameter(maxResults); Modified: trunk/nhibernate/src/NHibernate/Dialect/DB2400Dialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/DB2400Dialect.cs 2011-05-23 22:25:56 UTC (rev 5866) +++ trunk/nhibernate/src/NHibernate/Dialect/DB2400Dialect.cs 2011-05-24 05:23:00 UTC (rev 5867) @@ -46,17 +46,11 @@ get { return false; } } - public override SqlString GetLimitString(SqlString querySqlString, int offset, int limit, int? offsetParameterIndex, int? limitParameterIndex) - { - // override the base-class's implementation that uses limit parameters - return GetLimitString(querySqlString, offset, limit); - } - - public override SqlString GetLimitString(SqlString querySqlString, int offset, int limit) + public override SqlString GetLimitString(SqlString queryString, SqlString offset, SqlString limit) { - return new SqlStringBuilder(querySqlString) + return new SqlStringBuilder(queryString) .Add(" fetch first ") - .Add(limit.ToString()) + .Add(limit) .Add(" rows only ") .ToSqlString(); } Modified: trunk/nhibernate/src/NHibernate/Dialect/DB2Dialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/DB2Dialect.cs 2011-05-23 22:25:56 UTC (rev 5866) +++ trunk/nhibernate/src/NHibernate/Dialect/DB2Dialect.cs 2011-05-24 05:23:00 UTC (rev 5867) @@ -205,16 +205,7 @@ get { return true; } } - /// <summary> - /// Add a <c>LIMIT</c> clause to the given SQL <c>SELECT</c> - /// </summary> - /// <param name="querySqlString">A Query in the form of a SqlString.</param> - /// <param name="offset">Offset of the first row to be returned by the query (zero-based)</param> - /// <param name="limit">Maximum number of rows to be returned by the query</param> - /// <param name="offsetParameterIndex">Optionally, the Offset parameter index</param> - /// <param name="limitParameterIndex">Optionally, the Limit parameter index</param> - /// <returns>A new <see cref="SqlString"/> that contains the <c>LIMIT</c> clause.</returns> - public override SqlString GetLimitString(SqlString querySqlString, int offset, int limit, int? offsetParameterIndex, int? limitParameterIndex) + public override SqlString GetLimitString(SqlString querySqlString, SqlString offset, SqlString limit) { /* * "select * from (select row_number() over(orderby_clause) as rownum, " @@ -230,20 +221,27 @@ .Add(querySqlString.Substring(7)) .Add(") as tempresult where rownum "); - if (offset > 0) + if (offset != null && limit != null) { pagingBuilder .Add("between ") - .Add(Parameter.WithIndex(offsetParameterIndex.Value)) + .Add(offset) .Add("+1 and ") - .Add(Parameter.WithIndex(limitParameterIndex.Value)); + .Add(limit); } - else + else if (limit != null) { pagingBuilder .Add("<= ") - .Add(Parameter.WithIndex(limitParameterIndex.Value)); + .Add(limit); } + else + { + // We just have an offset. + pagingBuilder + .Add("> ") + .Add(offset); + } return pagingBuilder.ToSqlString(); } Modified: trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs 2011-05-23 22:25:56 UTC (rev 5866) +++ trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs 2011-05-24 05:23:00 UTC (rev 5867) @@ -1680,70 +1680,82 @@ get { return false; } } - public virtual SqlString GetLimitString(SqlString querySqlString, int offset, int limit, Parameter offsetParameter, Parameter limitParameter) - { - if (!SupportsVariableLimit) - return GetLimitString(querySqlString, offset, limit); + /// <summary> + /// For limit clauses, indicates whether to use 0 or 1 as the offset that returns the first row. Should be true if the first row is at offset 1. + /// </summary> + public virtual bool OffsetStartsAtOne + { + get { return false; } + } - if ((offsetParameter == null) && (limitParameter == null)) - return GetLimitString(querySqlString, offset, limit); + /// <summary> + /// Add a <c>LIMIT</c> clause to the given SQL <c>SELECT</c>. + /// Expects any database-specific offset and limit adjustments to have already been performed (ex. UseMaxForLimit, OffsetStartsAtOne). + /// </summary> + /// <param name="queryString">The <see cref="SqlString"/> to base the limit query off.</param> + /// <param name="offset">Offset of the first row to be returned by the query. This may be represented as a parameter, a string literal, or a null value if no limit is requested. This should have already been adjusted to account for OffsetStartsAtOne.</param> + /// <param name="limit">Maximum number of rows to be returned by the query. This may be represented as a parameter, a string literal, or a null value if no offset is requested. This should have already been adjusted to account for UseMaxForLimit.</param> + /// <returns>A new <see cref="SqlString"/> that contains the <c>LIMIT</c> clause.</returns> + public virtual SqlString GetLimitString(SqlString queryString, SqlString offset, SqlString limit) + { + throw new NotSupportedException("Dialect does not have support for limit strings."); + } - throw new NotSupportedException("Override to support limits passed as parameters"); - } + /// <summary> + /// Expects any database-specific offset and limit adjustments to have already been performed (ex. UseMaxForLimit, OffsetStartsAtOne). + /// </summary> + internal SqlString GetLimitString(SqlString queryString, int? offset, int? limit, int? offsetParameterIndex, int? limitParameterIndex) + { + SqlString offsetParameter = + SupportsVariableLimit && offsetParameterIndex.HasValue ? new SqlString(Parameter.WithIndex(offsetParameterIndex.Value)) : + offset.HasValue ? new SqlString(offset.ToString()) : + null; - /// <summary> - /// Add a <c>LIMIT</c> clause to the given SQL <c>SELECT</c> - /// when the dialect supports variable limits (i.e. parameters for the limit constraints) - /// </summary> - /// <param name="querySqlString">The <see cref="SqlString"/> to base the limit query off.</param> - /// <param name="offset">Offset of the first row to be returned by the query (zero-based)</param> - /// <param name="limit">Maximum number of rows to be returned by the query</param> - /// <param name="offsetParameterIndex">Optionally, the Offset parameter index in the sql</param> - /// <param name="limitParameterIndex">Optionally, the Limit parameter index in the sql</param> - /// <returns>A new <see cref="SqlString"/> that contains the <c>LIMIT</c> clause.</returns> - public virtual SqlString GetLimitString(SqlString querySqlString, int offset, int limit, int? offsetParameterIndex, int? limitParameterIndex) - { - if (!SupportsVariableLimit) - return GetLimitString(querySqlString, offset, limit); + SqlString limitParameter = + SupportsVariableLimit && limitParameterIndex.HasValue ? new SqlString(Parameter.WithIndex(limitParameterIndex.Value)) : + limit.HasValue ? new SqlString(limit.ToString()) : + null; - if ((offsetParameterIndex == null) && (limitParameterIndex == null)) - return GetLimitString(querySqlString, offset, limit); + return GetLimitString(queryString, offsetParameter, limitParameter); + } - throw new NotSupportedException("Override to support limits passed as parameters"); - } + /// <summary> + /// Expects any database-specific offset and limit adjustments to have already been performed (ex. UseMaxForLimit, OffsetStartsAtOne). + /// </summary> + internal SqlString GetLimitString(SqlString queryString, int? offset, int? limit, Parameter offsetParameter, Parameter limitParameter) + { + SqlString o = + SupportsVariableLimit && offsetParameter != null ? new SqlString(offsetParameter) : + offset.HasValue ? new SqlString(offset.ToString()) : + null; - /// <summary> - /// Add a <c>LIMIT</c> clause to the given SQL <c>SELECT</c> - /// </summary> - /// <param name="querySqlString">A Query in the form of a SqlString.</param> - /// <param name="offset">Offset of the first row to be returned by the query (zero-based)</param> - /// <param name="limit">Maximum number of rows to be returned by the query</param> - /// <returns>A new SqlString that contains the <c>LIMIT</c> clause.</returns> - public virtual SqlString GetLimitString(SqlString querySqlString, int offset, int limit) - { - return GetLimitString(querySqlString, offset > 0); - } + SqlString l = + SupportsVariableLimit && limitParameter != null ? new SqlString(limitParameter) : + limit.HasValue ? new SqlString(limit.ToString()) : + null; - /// <summary> Apply s limit clause to the query. </summary> - /// <param name="querySqlString">The query to which to apply the limit. </param> - /// <param name="hasOffset">Is the query requesting an offset? </param> - /// <returns> the modified SQL </returns> - /// <remarks> - /// Typically dialects utilize <see cref="SupportsVariableLimit"/> - /// limit caluses when they support limits. Thus, when building the - /// select command we do not actually need to know the limit or the offest - /// since we will just be using placeholders. - /// <p/> - /// Here we do still pass along whether or not an offset was specified - /// so that dialects not supporting offsets can generate proper exceptions. - /// In general, dialects will override one or the other of this method and - /// <see cref="GetLimitString(SqlString,int,int)"/>. - /// </remarks> - public virtual SqlString GetLimitString(SqlString querySqlString, bool hasOffset) - { - throw new NotSupportedException("Paged Queries not supported"); - } + return GetLimitString(queryString, o, l); + } + internal int GetLimitValue(int offset, int limit) + { + if (limit == int.MaxValue) + return int.MaxValue; + + if (UseMaxForLimit) + return GetOffsetValue(offset) + limit; + + return limit; + } + + internal int GetOffsetValue(int offset) + { + if (OffsetStartsAtOne) + return offset + 1; + + return offset; + } + #endregion #region identifier quoting support Modified: trunk/nhibernate/src/NHibernate/Dialect/FirebirdDialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/FirebirdDialect.cs 2011-05-23 22:25:56 UTC (rev 5866) +++ trunk/nhibernate/src/NHibernate/Dialect/FirebirdDialect.cs 2011-05-24 05:23:00 UTC (rev 5867) @@ -177,28 +177,32 @@ get { return true; } } - /// <summary> - /// Add a <c>FIRST x [SKIP] y</c> clause to the given SQL <c>SELECT</c> - /// </summary> - /// <param name="querySqlString">A Query in the form of a SqlString.</param> - /// <param name="limit">Maximum number of rows to be returned by the query</param> - /// <param name="offset">Offset of the first row to process in the result set</param> - /// <returns>A new SqlString that contains the <c>FIRST</c> clause.</returns> - public override SqlString GetLimitString(SqlString querySqlString, int offset, int limit) + public override SqlString GetLimitString(SqlString queryString, SqlString offset, SqlString limit) { - /* + // FIXME - This should use the ROWS syntax in Firebird to avoid problems with subqueries metioned here: + // http://www.firebirdsql.org/refdocs/langrefupd20-select.html#langrefupd20-first-skip + + /* * "SELECT FIRST x [SKIP y] rest-of-sql-statement" */ - int insertIndex = GetAfterSelectInsertPoint(querySqlString); - if (offset > 0) - { - return querySqlString.Insert(insertIndex, " first " + limit.ToString() + " skip " + offset.ToString()); + int insertIndex = GetAfterSelectInsertPoint(queryString); + + SqlStringBuilder limitFragment = new SqlStringBuilder(); + + if (limit != null) + { + limitFragment.Add(" first "); + limitFragment.Add(limit); + } + + if (offset != null) + { + limitFragment.Add(" skip "); + limitFragment.Add(offset); } - else - { - return querySqlString.Insert(insertIndex, " first " + limit.ToString()); - } + + return queryString.Insert(insertIndex, limitFragment.ToSqlString()); } public override bool SupportsVariableLimit Modified: trunk/nhibernate/src/NHibernate/Dialect/InformixDialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/InformixDialect.cs 2011-05-23 22:25:56 UTC (rev 5866) +++ trunk/nhibernate/src/NHibernate/Dialect/InformixDialect.cs 2011-05-24 05:23:00 UTC (rev 5867) @@ -376,36 +376,29 @@ get { return true; } } - /// <summary> Apply s limit clause to the query. </summary> - /// <param name="querySqlString">The query to which to apply the limit. </param> - /// <param name="offset">Offset of the first row to be returned by the query (zero-based)</param> - /// <param name="limit">Maximum number of rows to be returned by the query</param> - /// <returns> the modified SQL </returns> - /// <remarks> - /// Typically dialects utilize <see cref="SupportsVariableLimit"/> - /// limit caluses when they support limits. Thus, when building the - /// select command we do not actually need to know the limit or the offest - /// since we will just be using placeholders. - /// <p/> - /// Here we do still pass along whether or not an offset was specified - /// so that dialects not supporting offsets can generate proper exceptions. - /// In general, dialects will override one or the other of this method and - /// <see cref="GetLimitString(SqlString,int,int)"/>. - /// </remarks> - public override SqlString GetLimitString(SqlString querySqlString, int offset, int limit) + public override SqlString GetLimitString(SqlString queryString, SqlString offset, SqlString limit) { /* * "SELECT [SKIP x] FIRST y rest-of-sql-statement" */ - int insertIndex = GetAfterSelectInsertPoint(querySqlString); + // TODO - Check support for cases where only the offset is specified, but the limit is not. Might need to use int.MaxValue. - if (offset > 0) + int insertIndex = GetAfterSelectInsertPoint(queryString); + + SqlStringBuilder limitFragment = new SqlStringBuilder(); + if (offset != null) + { + limitFragment.Add(" skip "); + limitFragment.Add(offset); + } + if (limit != null) { - return querySqlString.Insert(insertIndex, " skip " + offset + " first " + limit); + limitFragment.Add(" first "); + limitFragment.Add(limit); } - return querySqlString.Insert(insertIndex, " first " + limit); + return queryString.Insert(insertIndex, limitFragment.ToSqlString()); } /// <summary> Modified: trunk/nhibernate/src/NHibernate/Dialect/MsSql2000Dialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/MsSql2000Dialect.cs 2011-05-23 22:25:56 UTC (rev 5866) +++ trunk/nhibernate/src/NHibernate/Dialect/MsSql2000Dialect.cs 2011-05-24 05:23:00 UTC (rev 5867) @@ -329,25 +329,17 @@ get { return false; } } - /// <summary> - /// Add a <c>LIMIT (TOP)</c> clause to the given SQL <c>SELECT</c> - /// </summary> - /// <param name="querySqlString">A Query in the form of a SqlString.</param> - /// <param name="limit">Maximum number of rows to be returned by the query</param> - /// <param name="offset">Offset of the first row to process in the result set</param> - /// <returns>A new SqlString that contains the <c>LIMIT</c> clause.</returns> - public override SqlString GetLimitString(SqlString querySqlString, int offset, int limit) + public override SqlString GetLimitString(SqlString querySqlString, SqlString offset, SqlString limit) { - if (offset > 0) - { - throw new NotSupportedException("SQL Server does not support an offset"); - } - /* * "SELECT TOP limit rest-of-sql-statement" */ - return querySqlString.Insert(GetAfterSelectInsertPoint(querySqlString), " top " + limit); + SqlStringBuilder topFragment = new SqlStringBuilder(); + topFragment.Add(" top "); + topFragment.Add(limit); + + return querySqlString.Insert(GetAfterSelectInsertPoint(querySqlString), topFragment.ToSqlString()); } /// <summary> Modified: trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs 2011-05-23 22:25:56 UTC (rev 5866) +++ trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs 2011-05-24 05:23:00 UTC (rev 5867) @@ -29,89 +29,45 @@ RegisterKeyword("xml"); } - public override SqlString GetLimitString(SqlString querySqlString, int offset, int limit) - { - return GetLimitString(querySqlString, - offset == 0 ? null : new SqlString(offset.ToString()), - limit == int.MaxValue ? null : new SqlString(limit.ToString())); - } - - /// <summary> - /// Add a <c>LIMIT</c> clause to the given SQL <c>SELECT</c> - /// </summary> - /// <param name="querySqlString">The <see cref="SqlString"/> to base the limit query off.</param> - /// <param name="offset">Offset of the first row to be returned by the query (zero-based)</param> - /// <param name="limit">Maximum number of rows to be returned by the query</param> - /// <param name="offsetParameterIndex">Optionally, the Offset parameter index in the sql</param> - /// <param name="limitParameterIndex">Optionally, the Limit parameter index in the sql</param> - /// <returns>A new <see cref="SqlString"/> with the <c>LIMIT</c> clause applied.</returns> - /// <remarks> - /// Note that we need to explicitly specify the columns, because we need to be able to use them in a paged subselect [NH-1155] - /// </remarks> - public override SqlString GetLimitString(SqlString querySqlString, int offset, int limit, int? offsetParameterIndex, int? limitParameterIndex) + public override SqlString GetLimitString(SqlString queryString, SqlString offset, SqlString limit) { - object limitObject = limitParameterIndex == null ? (object) new SqlString(limit.ToString()) : Parameter.WithIndex(limitParameterIndex.Value); - object offsetObject = null; - if (offset != 0) - { - offsetObject = offsetParameterIndex == null ? (object) new SqlString(offset.ToString()) : Parameter.WithIndex(offsetParameterIndex.Value); - } - return GetLimitString(querySqlString, offsetObject, limitObject); - } - - public override SqlString GetLimitString(SqlString querySqlString, int offset, int limit, Parameter offsetParameter, Parameter limitParameter) - { - object limitObject = limitParameter ?? (object) new SqlString(limit.ToString()); - object offsetObject = null; - if (offset != 0) - { - offsetObject = offsetParameter ?? (object) new SqlString(offset.ToString()); - } - return GetLimitString(querySqlString, offsetObject, limitObject); - } - - private SqlString GetLimitString(SqlString querySqlString, object offset, object limit) - { - if (offset == null && limit == null) - return querySqlString; - SqlStringBuilder result = new SqlStringBuilder(); if (offset == null) { - int insertPoint = this.GetAfterSelectInsertPoint(querySqlString); + int insertPoint = GetAfterSelectInsertPoint(queryString); return result - .Add(querySqlString.Substring(0, insertPoint)) + .Add(queryString.Substring(0, insertPoint)) .Add(" TOP (") - .AddObject(limit) + .Add(limit) .Add(") ") - .Add(querySqlString.Substring(insertPoint)) + .Add(queryString.Substring(insertPoint)) .ToSqlString(); } - int fromIndex = GetFromIndex(querySqlString); - SqlString select = querySqlString.Substring(0, fromIndex); + int fromIndex = GetFromIndex(queryString); + SqlString select = queryString.Substring(0, fromIndex); List<SqlString> columnsOrAliases; Dictionary<SqlString, SqlString> aliasToColumn; ExtractColumnOrAliasNames(select, out columnsOrAliases, out aliasToColumn); - - int orderIndex = querySqlString.LastIndexOfCaseInsensitive(" order by "); + + int orderIndex = queryString.LastIndexOfCaseInsensitive(" order by "); SqlString fromAndWhere; SqlString[] sortExpressions; //don't use the order index if it is contained within a larger statement(assuming //a statement with non matching parenthesis is part of a larger block) - if (orderIndex > 0 && HasMatchingParens(querySqlString.Substring(orderIndex).ToString())) + if (orderIndex > 0 && HasMatchingParens(queryString.Substring(orderIndex).ToString())) { - fromAndWhere = querySqlString.Substring(fromIndex, orderIndex - fromIndex).Trim(); - SqlString orderBy = querySqlString.Substring(orderIndex).Trim(); + fromAndWhere = queryString.Substring(fromIndex, orderIndex - fromIndex).Trim(); + SqlString orderBy = queryString.Substring(orderIndex).Trim(); sortExpressions = orderBy.Substring(9).Split(","); } else { - fromAndWhere = querySqlString.Substring(fromIndex).Trim(); + fromAndWhere = queryString.Substring(fromIndex).Trim(); // Use dummy sort to avoid errors sortExpressions = new[] {new SqlString("CURRENT_TIMESTAMP"),}; } @@ -119,7 +75,7 @@ result.Add("SELECT "); if (limit != null) - result.Add("TOP (").AddObject(limit).Add(") "); + result.Add("TOP (").Add(limit).Add(") "); result .Add(StringHelper.Join(", ", columnsOrAliases)) @@ -133,7 +89,7 @@ .Add(") as __hibernate_sort_row ") .Add(fromAndWhere) .Add(") as query WHERE query.__hibernate_sort_row > ") - .AddObject(offset) + .Add(offset) .Add(" ORDER BY query.__hibernate_sort_row"); return result.ToSqlString(); Modified: trunk/nhibernate/src/NHibernate/Dialect/MsSqlCe40Dialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/MsSqlCe40Dialect.cs 2011-05-23 22:25:56 UTC (rev 5866) +++ trunk/nhibernate/src/NHibernate/Dialect/MsSqlCe40Dialect.cs 2011-05-24 05:23:00 UTC (rev 5867) @@ -20,13 +20,27 @@ get { return true; } } - public override SqlString GetLimitString(SqlString querySqlString, int offset, int limit) + public override SqlString GetLimitString(SqlString queryString, SqlString offset, SqlString limit) { - if (querySqlString.IndexOfCaseInsensitive(" ORDER BY ") < 0) - { - querySqlString = querySqlString.Append(" ORDER BY GETDATE()"); - } - return querySqlString.Append(string.Format(" OFFSET {0} ROWS FETCH NEXT {1} ROWS ONLY", offset, limit)); + SqlStringBuilder builder = new SqlStringBuilder(queryString); + if (queryString.IndexOfCaseInsensitive(" ORDER BY ") < 0) + builder.Add(" ORDER BY GETDATE()"); + + builder.Add(" OFFSET "); + if (offset == null) + builder.Add("0"); + else + builder.Add(offset); + builder.Add(" ROWS"); + + if (limit != null) + { + builder.Add(" FETCH NEXT "); + builder.Add(limit); + builder.Add(" ROWS ONLY"); + } + + return builder.ToSqlString(); } } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Dialect/MySQL5Dialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/MySQL5Dialect.cs 2011-05-23 22:25:56 UTC (rev 5866) +++ trunk/nhibernate/src/NHibernate/Dialect/MySQL5Dialect.cs 2011-05-24 05:23:00 UTC (rev 5867) @@ -41,23 +41,6 @@ } } - public override SqlString GetLimitString(SqlString querySqlString, int offset, int limit) - { - var pagingBuilder = new SqlStringBuilder(); - - pagingBuilder.Add(querySqlString); - pagingBuilder.Add(" limit "); - if (offset > 0) - { - pagingBuilder.Add(offset.ToString()); - pagingBuilder.Add(", "); - } - - pagingBuilder.Add(limit.ToString()); - - return pagingBuilder.ToSqlString(); - } - public override string SelectGUIDString { get Modified: trunk/nhibernate/src/NHibernate/Dialect/MySQLDialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/MySQLDialect.cs 2011-05-23 22:25:56 UTC (rev 5866) +++ trunk/nhibernate/src/NHibernate/Dialect/MySQLDialect.cs 2011-05-24 05:23:00 UTC (rev 5867) @@ -176,31 +176,24 @@ get { return false; } } - /// <summary> - /// Add a <c>LIMIT</c> clause to the given SQL <c>SELECT</c> - /// </summary> - /// <param name="querySqlString">The <see cref="SqlString"/> to base the limit query off.</param> - /// <param name="offset">Offset of the first row to be returned by the query (zero-based)</param> - /// <param name="limit">Maximum number of rows to be returned by the query</param> - /// <param name="offsetParameterIndex">Optionally, the Offset parameter index</param> - /// <param name="limitParameterIndex">Optionally, the Limit parameter index</param> - /// <returns>A new <see cref="SqlString"/> that contains the <c>LIMIT</c> clause.</returns> - public override SqlString GetLimitString(SqlString querySqlString, int offset, int limit, int? offsetParameterIndex, int? limitParameterIndex) - { - var pagingBuilder = new SqlStringBuilder(); - pagingBuilder.Add(querySqlString); - pagingBuilder.Add(" limit "); + public override SqlString GetLimitString(SqlString queryString, SqlString offset, SqlString limit) + { + var pagingBuilder = new SqlStringBuilder(queryString); + pagingBuilder.Add(" limit "); - if (offset > 0) - { - pagingBuilder.Add(Parameter.WithIndex(offsetParameterIndex.Value)); - pagingBuilder.Add(", "); - } + if (offset != null) + { + pagingBuilder.Add(offset); + pagingBuilder.Add(", "); + } - pagingBuilder.Add(Parameter.WithIndex(limitParameterIndex.Value)); + if (limit != null) + pagingBuilder.Add(limit); + else + pagingBuilder.Add(int.MaxValue.ToString()); - return pagingBuilder.ToSqlString(); - } + return pagingBuilder.ToSqlString(); + } public override string GetAddForeignKeyConstraintString(string constraintName, string[] foreignKey, string referencedTable, string[] primaryKey, Modified: trunk/nhibernate/src/NHibernate/Dialect/Oracle8iDialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/Oracle8iDialect.cs 2011-05-23 22:25:56 UTC (rev 5866) +++ trunk/nhibernate/src/NHibernate/Dialect/Oracle8iDialect.cs 2011-05-24 05:23:00 UTC (rev 5867) @@ -250,10 +250,9 @@ return new DecodeCaseFragment(this); } - public override SqlString GetLimitString(SqlString sql, int offset, int limit, int? offsetParameterIndex, int? limitParameterIndex) + public override SqlString GetLimitString(SqlString sql, SqlString offset, SqlString limit) { sql = sql.Trim(); - bool hasOffset = offset > 0; bool isForUpdate = false; if (sql.EndsWithCaseInsensitive(" for update")) { @@ -264,7 +263,7 @@ string selectColumns = ExtractColumnOrAliasNames(sql); var pagingSelect = new SqlStringBuilder(sql.Parts.Count + 10); - if (hasOffset) + if (offset != null && limit != null) { pagingSelect.Add("select " + selectColumns + " from ( select row_.*, rownum rownum_ from ( "); } @@ -273,14 +272,19 @@ pagingSelect.Add("select " + selectColumns + " from ( "); } pagingSelect.Add(sql); - if (hasOffset) + if (offset != null && limit != null) { - pagingSelect.Add(" ) row_ where rownum <=").AddParameter(limitParameterIndex.Value).Add(") where rownum_ >").AddParameter(offsetParameterIndex.Value); + pagingSelect.Add(" ) row_ where rownum <=").Add(limit).Add(") where rownum_ >").Add(offset); } - else + else if (limit != null) { - pagingSelect.Add(" ) where rownum <=").AddParameter(limitParameterIndex.Value); + pagingSelect.Add(" ) where rownum <=").Add(limit); } + else + { + // offset is specified, but limit is not. + pagingSelect.Add(" ) where rownum >").Add(offset); + } if (isForUpdate) { Modified: trunk/nhibernate/src/NHibernate/Dialect/PostgreSQLDialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/PostgreSQLDialect.cs 2011-05-23 22:25:56 UTC (rev 5866) +++ trunk/nhibernate/src/NHibernate/Dialect/PostgreSQLDialect.cs 2011-05-24 05:23:00 UTC (rev 5867) @@ -133,42 +133,21 @@ get { return true; } } - /// <summary> - /// Add a <c>LIMIT</c> clause to the given SQL <c>SELECT</c> - /// </summary> - /// <param name="querySqlString">The <see cref="SqlString"/> to base the limit query off.</param> - /// <param name="offset">Offset of the first row to be returned by the query (zero-based)</param> - /// <param name="limit">Maximum number of rows to be returned by the query</param> - /// <param name="offsetParameterIndex">Optionally, the Offset parameter index</param> - /// <param name="limitParameterIndex">Optionally, the Limit parameter index</param> - /// <returns>A new <see cref="SqlString"/> that contains the <c>LIMIT</c> clause.</returns> - public override SqlString GetLimitString(SqlString querySqlString, int offset, int limit, int? offsetParameterIndex, int? limitParameterIndex) - { - object limitObject = Parameter.WithIndex(limitParameterIndex.Value); - object offsetObject = offset > 0 ? Parameter.WithIndex(offsetParameterIndex.Value) : null; - return GetLimitString(querySqlString, offsetObject, limitObject); - } - - public override SqlString GetLimitString(SqlString querySqlString, int offset, int limit) + public override SqlString GetLimitString(SqlString queryString, SqlString offset, SqlString limit) { - return GetLimitString(querySqlString, new SqlString(offset.ToString()), new SqlString(limit.ToString())); - } - - private SqlString GetLimitString(SqlString querySqlString, object offset, object limit) - { SqlStringBuilder pagingBuilder = new SqlStringBuilder(); - pagingBuilder.Add(querySqlString); + pagingBuilder.Add(queryString); if (limit != null) { pagingBuilder.Add(" limit "); - pagingBuilder.AddObject(limit); + pagingBuilder.Add(limit); } if (offset != null) { pagingBuilder.Add(" offset "); - pagingBuilder.AddObject(offset); + pagingBuilder.Add(offset); } return pagingBuilder.ToSqlString(); Modified: trunk/nhibernate/src/NHibernate/Dialect/SQLiteDialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/SQLiteDialect.cs 2011-05-23 22:25:56 UTC (rev 5866) +++ trunk/nhibernate/src/NHibernate/Dialect/SQLiteDialect.cs 2011-05-24 05:23:00 UTC (rev 5867) @@ -149,11 +149,6 @@ get { return false; } } - public override bool SupportsVariableLimit - { - get { return false; } - } - public override bool SupportsIdentityColumns { get { return true; } @@ -244,29 +239,27 @@ get { return "DEFAULT VALUES"; } } - /// <summary> - /// Add a LIMIT N clause to the given SQL <c>SELECT</c> - /// </summary> - /// <param name="querySqlString">A Query in the form of a SqlString.</param> - /// <param name="limit">Maximum number of rows to be returned by the query</param> - /// <param name="offset">Offset of the first row to process in the result set</param> - /// <returns>A new SqlString that contains the <c>LIMIT</c> clause.</returns> - public override SqlString GetLimitString(SqlString querySqlString, int offset, int limit) - { - SqlStringBuilder pagingBuilder = new SqlStringBuilder(); - pagingBuilder.Add(querySqlString); - pagingBuilder.Add(" limit "); - pagingBuilder.Add(limit.ToString()); + public override SqlString GetLimitString(SqlString queryString, SqlString offset, SqlString limit) + { + SqlStringBuilder pagingBuilder = new SqlStringBuilder(); + pagingBuilder.Add(queryString); - if (offset > 0) - { - pagingBuilder.Add(" offset "); - pagingBuilder.Add(offset.ToString()); - } + pagingBuilder.Add(" limit "); + if (limit != null) + pagingBuilder.Add(limit); + else + // We must have a limit present if we have an offset. + pagingBuilder.Add(int.MaxValue.ToString()); - return pagingBuilder.ToSqlString(); - } + if (offset != null) + { + pagingBuilder.Add(" offset "); + pagingBuilder.Add(offset); + } + return pagingBuilder.ToSqlString(); + } + public override bool SupportsTemporaryTables { get { return true; } Modified: trunk/nhibernate/src/NHibernate/Dialect/SybaseASA9Dialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/SybaseASA9Dialect.cs 2011-05-23 22:25:56 UTC (rev 5866) +++ trunk/nhibernate/src/NHibernate/Dialect/SybaseASA9Dialect.cs 2011-05-24 05:23:00 UTC (rev 5867) @@ -92,11 +92,29 @@ get { return false; } } - public override SqlString GetLimitString(SqlString querySqlString, int offset, int limit) + public override bool OffsetStartsAtOne + { + get { return true; } + } + + public override SqlString GetLimitString(SqlString queryString, SqlString offset, SqlString limit) { - int intSelectInsertPoint = GetAfterSelectInsertPoint(querySqlString); - string strLimit = string.Format(" top {0} start at {1}", limit, offset + 1); - return querySqlString.Insert(intSelectInsertPoint, strLimit); + int intSelectInsertPoint = GetAfterSelectInsertPoint(queryString); + + SqlStringBuilder limitFragment = new SqlStringBuilder(); + limitFragment.Add(" top "); + if (limit != null) + limitFragment.Add(limit); + else + limitFragment.Add(int.MaxValue.ToString()); + + if (offset != null) + { + limitFragment.Add(" start at "); + limitFragment.Add(offset); + } + + return queryString.Insert(intSelectInsertPoint, limitFragment.ToSqlString()); } public override IDataBaseSchema GetDataBaseSchema(DbConnection connection) Modified: trunk/nhibernate/src/NHibernate/Dialect/SybaseSQLAnywhere10Dialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/SybaseSQLAnywhere10Dialect.cs 2011-05-23 22:25:56 UTC (rev 5866) +++ trunk/nhibernate/src/NHibernate/Dialect/SybaseSQLAnywhere10Dialect.cs 2011-05-24 05:23:00 UTC (rev 5867) @@ -446,59 +446,37 @@ return 0; } - /// <summary> - /// SQL Anywhere 11 uses SELECT TOP n START AT m [ select list items ] - /// for LIMIT/OFFSET support. - /// - /// Produce a parametertized SQL query using positional parameters for - /// TOP and START AT (if specified). - /// </summary> - public override SqlString GetLimitString(SqlString sql, bool hasOffset) + public override SqlString GetLimitString(SqlString sql, SqlString offset, SqlString limit) { - int insertionPoint = GetAfterSelectInsertPoint(sql); - - if (insertionPoint > 0) - { - SqlStringBuilder limitBuilder = new SqlStringBuilder(); - limitBuilder.Add("select"); - if (insertionPoint > 6) - { - limitBuilder.Add(" distinct "); - } - limitBuilder.Add(" top "); - limitBuilder.Add(Parameter.Placeholder); - if (hasOffset) - { - limitBuilder.Add(" start at "); - limitBuilder.Add(Parameter.Placeholder); - } - limitBuilder.Add(sql.Substring(insertionPoint)); - return limitBuilder.ToSqlString(); - } - else - { - return sql; // unchanged - } - } + // SQL Anywhere 11 uses SELECT TOP n START AT m [ select list items ] + // for LIMIT/OFFSET support. Does not support a limit of zero. - /// <summary> - /// SQL Anywhere 11 uses SELECT TOP n START AT m [ select list items ] - /// for LIMIT/OFFSET support. - /// - /// Generate SELECT TOP n START AT m syntax using bound parameters - /// SQL Anywhere constraints: n > 0, m >= 0 - /// </summary> - public override SqlString GetLimitString(SqlString sql, int offset, int limit) - { - if (offset < 0) - { - throw new NotSupportedException("SQL Anywhere does not support negative offsets"); - } - if (limit <= 0) - { - throw new NotSupportedException("negative or zero TOP n (SQL limit) is not supported"); - } - return GetLimitString(sql, offset > 0); + // FIXME - Add support for where offset is set, but limit is not. + + int insertionPoint = GetAfterSelectInsertPoint(sql); + + if (insertionPoint > 0) + { + SqlStringBuilder limitBuilder = new SqlStringBuilder(); + limitBuilder.Add("select"); + if (insertionPoint > 6) + { + limitBuilder.Add(" distinct "); + } + limitBuilder.Add(" top "); + limitBuilder.Add(limit); + if (offset != null) + { + limitBuilder.Add(" start at "); + limitBuilder.Add(offset); + } + limitBuilder.Add(sql.Substring(insertionPoint)); + return limitBuilder.ToSqlString(); + } + else + { + return sql; // unchanged + } } #endregion Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/SqlGenerator.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/SqlGenerator.cs 2011-05-23 22:25:56 UTC (rev 5866) +++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/SqlGenerator.cs 2011-05-24 05:23:00 UTC (rev 5867) @@ -341,17 +341,15 @@ var dialect = sessionFactory.Dialect; - var hqlQueryHasFixedLimits = (queryWriter.Take.HasValue || queryWriter.Skip.HasValue) && !skipIsParameter && !takeIsParameter; - if(hqlQueryHasFixedLimits) - { - return dialect.GetLimitString(sqlString, queryWriter.Skip ?? 0, queryWriter.Take ?? int.MaxValue); - } + // FIXME - We need to adjust the parameters from the user according to dialect settings like UseMaxForLimit, OffsetStartsAtOne. This will need to happen every time we query. + // Skip-Take in HQL should be supported just for Dialect supporting variable limits at least when users use parameters for skip-take. if (!dialect.SupportsVariableLimit && (skipIsParameter || takeIsParameter)) { throw new NotSupportedException("The dialect " + dialect.GetType().FullName + " does not supports variable limits"); } - // At this point at least one of the two limits is a parameter and that parameter should be of IExplicitValueParameterSpecification + + // If a limit is a parameter, it should be of type IExplicitValueParameterSpecification. Parameter skipParameter = null; Parameter takeParameter = null; if(queryWriter.SkipParameter != null) @@ -365,8 +363,12 @@ takeParameter.BackTrack = queryWriter.TakeParameter.IdForBackTrack; } - sqlString = dialect.GetLimitString(sqlString, skipIsParameter ? 1 : queryWriter.Skip ?? 0, queryWriter.Take ?? int.MaxValue, skipParameter, takeParameter); - return sqlString; + // We allow the user to specify either constants or parameters for their limits. + return dialect.GetLimitString(sqlString, + queryWriter.Skip.HasValue ? (int?)dialect.GetOffsetValue(queryWriter.Skip.Value) : null, + queryWriter.Take.HasValue ? (int?)dialect.GetLimitValue(queryWriter.Skip ?? 0, queryWriter.Take.Value) : null, + skipParameter, + takeParameter); } private void Skip(IASTNode node) Modified: trunk/nhibernate/src/NHibernate/Loader/Loader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Loader.cs 2011-05-23 22:25:56 UTC (rev 5866) +++ trunk/nhibernate/src/NHibernate/Loader/Loader.cs 2011-05-24 05:23:00 UTC (rev 5867) @@ -1127,11 +1127,12 @@ if (useLimit) { + int max = GetMaxOrLimit(dialect, selection); sqlString = dialect.GetLimitString( sqlString.Trim(), - useOffset ? GetFirstRow(selection) : 0, - GetMaxOrLimit(dialect, selection), + useOffset ? (int?)dialect.GetOffsetValue(GetFirstRow(selection)) : null, + max != int.MaxValue ? (int?)max : null, queryParameters.OffsetParameterIndex, queryParameters.LimitParameterIndex); } @@ -1216,19 +1217,12 @@ internal static int GetMaxOrLimit(Dialect.Dialect dialect, RowSelection selection) { int firstRow = GetFirstRow(selection); - int lastRow = selection.MaxRows; + int rowCount = selection.MaxRows; - if (lastRow == RowSelection.NoValue) + if (rowCount == RowSelection.NoValue) return int.MaxValue; - if (dialect.UseMaxForLimit) - { - return lastRow + firstRow; - } - else - { - return lastRow; - } + return dialect.GetLimitValue(firstRow, rowCount); } private int GetFirstLimitParameterCount(Dialect.Dialect dialect, bool useLimit, bool hasFirstRow, bool useOffset) @@ -1748,11 +1742,12 @@ if (useLimit) { + int max = GetMaxOrLimit(dialect, selection); sqlString = dialect.GetLimitString( sqlString.Trim(), - useOffset ? GetFirstRow(selection) : 0, - GetMaxOrLimit(dialect, selection), + useOffset ? (int?)dialect.GetOffsetValue(GetFirstRow(selection)) : null, + max != int.MaxValue ? (int?)max : null, parameters.OffsetParameterIndex, parameters.LimitParameterIndex); } Modified: trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs =================================================================== --- trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs 2011-05-23 22:25:56 UTC (rev 5866) +++ trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs 2011-05-24 05:23:00 UTC (rev 5867) @@ -614,8 +614,13 @@ return lastIndex >= 0 ? Substring(lastIndex) : Empty; } - public SqlString Insert(int index, string text) - { + public SqlString Insert(int index, string text) + { + return Insert(index, new SqlString(text)); + } + + public SqlString Insert(int index, SqlString sqlString) + { if (index < 0) { throw new ArgumentException("index should be greater than or equal to 0", "index"); @@ -642,20 +647,22 @@ else if (nextOffset == index) { result.AddObject(part); - result.Add(text); + result.Add(sqlString); inserted = true; } else if (offset == index) { - result.Add(text); + result.Add(sqlString); result.AddObject(part); inserted = true; } else if (index > offset && index < nextOffset) { string partString = (string) part; - result.Add(partString.Insert(index - offset, text)); - inserted = true; + result.Add(partString.Substring(0, index - offset)); + result.Add(sqlString); + result.Add(partString.Substring(index - offset, partString.Length - (index - offset))); + inserted = true; } else { Modified: trunk/nhibernate/src/NHibernate.Test/DialectTest/DB2DialectFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/DialectTest/DB2DialectFixture.cs 2011-05-23 22:25:56 UTC (rev 5866) +++ trunk/nhibernate/src/NHibernate.Test/DialectTest/DB2DialectFixture.cs 2011-05-24 05:23:00 UTC (rev 5867) @@ -24,11 +24,11 @@ " order by a, x" }); - SqlString limited = dialect.GetLimitString(sql, 1, 2, -1, -2); + SqlString limited = dialect.GetLimitString(sql, new SqlString("111"), new SqlString("222")); Assert.AreEqual( - "select * from (select rownumber() over(order by a, x) as rownum, a, b, c from d where X = ? and Z = ? order by a, x) as tempresult where rownum between ?+1 and ?", + "select * from (select rownumber() over(order by a, x) as rownum, a, b, c from d where X = ? and Z = ? order by a, x) as tempresult where rownum between 111+1 and 222", limited.ToString()); - Assert.AreEqual(4, limited.GetParameterCount()); + Assert.AreEqual(2, limited.GetParameterCount()); } } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/DialectTest/FirebirdDialectFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/DialectTest/FirebirdDialectFixture.cs 2011-05-23 22:25:56 UTC (rev 5866) +++ trunk/nhibernate/src/NHibernate.Test/DialectTest/FirebirdDialectFixture.cs 2011-05-24 05:23:00 UTC (rev 5867) @@ -12,19 +12,19 @@ { FirebirdDialect d = new FirebirdDialect(); - SqlString str = d.GetLimitString(new SqlString("SELECT * FROM fish"), 0, 10); + SqlString str = d.GetLimitString(new SqlString("SELECT * FROM fish"), null, new SqlString("10")); Assert.AreEqual("SELECT first 10 * FROM fish", str.ToString()); - str = d.GetLimitString(new SqlString("SELECT * FROM fish ORDER BY name"), 5, 15); + str = d.GetLimitString(new SqlString("SELECT * FROM fish ORDER BY name"), new SqlString("5"), new SqlString("15")); Assert.AreEqual("SELECT first 15 skip 5 * FROM fish ORDER BY name", str.ToString()); - str = d.GetLimitString(new SqlString("SELECT * FROM fish ORDER BY name DESC"), 7, 28); + str = d.GetLimitString(new SqlString("SELECT * FROM fish ORDER BY name DESC"), new SqlString("7"), new SqlString("28")); Assert.AreEqual("SELECT first 28 skip 7 * FROM fish ORDER BY name DESC", str.ToString()); - str = d.GetLimitString(new SqlString("SELECT DISTINCT fish.family FROM fish ORDER BY name DESC"), 0, 28); + str = d.GetLimitString(new SqlString("SELECT DISTINCT fish.family FROM fish ORDER BY name DESC"), null, new SqlString("28")); Assert.AreEqual("SELECT first 28 DISTINCT fish.family FROM fish ORDER BY name DESC", str.ToString()); - str = d.GetLimitString(new SqlString("SELECT DISTINCT fish.family FROM fish ORDER BY name DESC"), 7, 28); + str = d.GetLimitString(new SqlString("SELECT DISTINCT fish.family FROM fish ORDER BY name DESC"), new SqlString("7"), new SqlString("28")); Assert.AreEqual("SELECT first 28 skip 7 DISTINCT fish.family FROM fish ORDER BY name DESC", str.ToString()); } } Modified: trunk/nhibernate/src/NHibernate.Test/DialectTest/MsSql2005DialectFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/DialectTest/MsSql2005DialectFixture.cs 2011-05-23 22:25:56 UTC (rev 5866) +++ trunk/nhibernate/src/NHibernate.Test/DialectTest/MsSql2005DialectFixture.cs 2011-05-24 05:23:00 UTC (rev 5867) @@ -16,66 +16,54 @@ { MsSql2005Dialect d = new MsSql2005Dialect(); - SqlString str = d.GetLimitString(new SqlString("select distinct c.Contact_Id as Contact1_19_0_, c._Rating as Rating2_19_0_ from dbo.Contact c where COALESCE(c.Rating, 0) > 0 order by c.Rating desc , c.Last_Name , c.First_Name"), 1, 10, -1, -2); - System.Console.WriteLine(str); + SqlString str = d.GetLimitString(new SqlString("select distinct c.Contact_Id as Contact1_19_0_, c._Rating as Rating2_19_0_ from dbo.Contact c where COALESCE(c.Rating, 0) > 0 order by c.Rating desc , c.Last_Name , c.First_Name"), new SqlString("111"), new SqlString("222")); Assert.AreEqual( - "SELECT TOP (?) Contact1_19_0_, Rating2_19_0_ FROM (select distinct c.Contact_Id as Contact1_19_0_, c._Rating as Rating2_19_0_, ROW_NUMBER() OVER(ORDER BY c.Rating DESC, c.Last_Name, c.First_Name) as __hibernate_sort_row from dbo.Contact c where COALESCE(c.Rating, 0) > 0) as query WHERE query.__hibernate_sort_row > ? ORDER BY query.__hibernate_sort_row", + "SELECT TOP (222) Contact1_19_0_, Rating2_19_0_ FROM (select distinct c.Contact_Id as Contact1_19_0_, c._Rating as Rating2_19_0_, ROW_NUMBER() OVER(ORDER BY c.Rating DESC, c.Last_Name, c.First_Name) as __hibernate_sort_row from dbo.Contact c where COALESCE(c.Rating, 0) > 0) as query WHERE query.__hibernate_sort_row > 111 ORDER BY query.__hibernate_sort_row", str.ToString()); - str = d.GetLimitString(new SqlString("SELECT fish.id FROM fish"), 1, 10, -1, -2); - System.Console.WriteLine(str); + str = d.GetLimitString(new SqlString("SELECT fish.id FROM fish"), new SqlString("111"), new SqlString("222")); Assert.AreEqual( - "SELECT TOP (?) id FROM (SELECT fish.id, ROW_NUMBER() OVER(ORDER BY CURRENT_TIMESTAMP) as __hibernate_sort_row FROM fish) as query WHERE query.__hibernate_sort_row > ? ORDER BY query.__hibernate_sort_row", + "SELECT TOP (222) id FROM (SELECT fish.id, ROW_NUMBER() OVER(ORDER BY CURRENT_TIMESTAMP) as __hibernate_sort_row FROM fish) as query WHERE query.__hibernate_sort_row > 111 ORDER BY query.__hibernate_sort_row", str.ToString()); - str = d.GetLimitString(new SqlString("SELECT DISTINCT fish_.id FROM fish fish_"), 1, 10, -1, -2); - System.Console.WriteLine(str); + str = d.GetLimitString(new SqlString("SELECT DISTINCT fish_.id FROM fish fish_"), new SqlString("111"), new SqlString("222")); Assert.AreEqual( - "SELECT TOP (?) id FROM (SELECT DISTINCT fish_.id, ROW_NUMBER() OVER(ORDER BY CURRENT_TIMESTAMP) as __hibernate_sort_row FROM fish fish_) as query WHERE query.__hibernate_sort_row > ? ORDER BY query.__hibernate_sort_row", + "SELECT TOP (222) id FROM (SELECT DISTINCT fish_.id, ROW_NUMBER() OVER(ORDER BY CURRENT_TIMESTAMP) as __hibernate_sort_row FROM fish fish_) as query WHERE query.__hibernate_sort_row > 111 ORDER BY query.__hibernate_sort_row", str.ToString()); - str = d.GetLimitString(new SqlString("SELECT DISTINCT fish_.id as ixx9_ FROM fish fish_"), 1, 10, -1, -2); - System.Console.WriteLine(str); + str = d.GetLimitString(new SqlString("SELECT DISTINCT fish_.id as ixx9_ FROM fish fish_"), new SqlString("111"), new SqlString("222")); Assert.AreEqual( - "SELECT TOP (?) ixx9_ FROM (SELECT DISTINCT fish_.id as ixx9_, ROW_NUMBER() OVER(ORDER BY CURRENT_TIMESTAMP) as __hibernate_sort_row FROM fish fish_) as query WHERE query.__hibernate_sort_row > ? ORDER BY query.__hibernate_sort_row", + "SELECT TOP (222) ixx9_ FROM (SELECT DISTINCT fish_.id as ixx9_, ROW_NUMBER() OVER(ORDER BY CURRENT_TIMESTAMP) as __hibernate_sort_row FROM fish fish_) as query WHERE query.__hibernate_sort_row > 111 ORDER BY query.__hibernate_sort_row", str.ToString()); - str = d.GetLimitString(new SqlString("SELECT * FROM fish ORDER BY name"), 5, 15, -1, -2); - System.Console.WriteLine(str); + str = d.GetLimitString(new SqlString("SELECT * FROM fish ORDER BY name"), new SqlString("111"), new SqlString("222")); Assert.AreEqual( - "SELECT TOP (?) * FROM (SELECT *, ROW_NUMBER() OVER(ORDER BY name) as __hibernate_sort_row FROM fish) as query WHERE query.__hibernate_sort_row > ? ORDER BY query.__hibernate_sort_row", + "SELECT TOP (222) * FROM (SELECT *, ROW_NUMBER() OVER(ORDER BY name) as __hibernate_sort_row FROM fish) as query WHERE query.__hibernate_sort_row > 111 ORDER BY query.__hibernate_sort_row", str.ToString()); - str = d.GetLimitString(new SqlString("SELECT fish.id, fish.name FROM fish ORDER BY name DESC"), 7, 28, -1, -2); - System.Console.WriteLine(str); + str = d.GetLimitString(new SqlString("SELECT fish.id, fish.name FROM fish ORDER BY name DESC"), new SqlString("111"), new SqlString("222")); Assert.AreEqual( - "SELECT TOP (?) id, name FROM (SELECT fish.id, fish.name, ROW_NUMBER() OVER(ORDER BY fish.name DESC) as __hibernate_sort_row FROM fish) as query WHERE query.__hibernate_sort_row > ? ORDER BY query.__hibernate_sort_row", + "SELECT TOP (222) id, name FROM (SELECT fish.id, fish.name, ROW_NUMBER() OVER(ORDER BY fish.name DESC) as __hibernate_sort_row FROM fish) as query WHERE query.__hibernate_sort_row > 111 ORDER BY query.__hibernate_sort_row", str.ToString()); - str = - d.GetLimitString( - new SqlString("SELECT * FROM fish LEFT JOIN (SELECT * FROM meat ORDER BY weight) AS t ORDER BY name DESC"), 10, 20, -1, -2); - System.Console.WriteLine(str); + str = d.GetLimitString(new SqlString("SELECT * FROM fish LEFT JOIN (SELECT * FROM meat ORDER BY weight) AS t ORDER BY name DESC"), new SqlString("111"), new SqlString("222")); Assert.AreEqual( - "SELECT TOP (?) * FROM (SELECT *, ROW_NUMBER() OVER(ORDER BY name DESC) as __hibernate_sort_row FROM fish LEFT JOIN (SELECT * FROM meat ORDER BY weight) AS t) as query WHERE query.__hibernate_sort_row > ? ORDER BY query.__hibernate_sort_row", + "SELECT TOP (222) * FROM (SELECT *, ROW_NUMBER() OVER(ORDER BY name DESC) as __hibernate_sort_row FROM fish LEFT JOIN (SELECT * FROM meat ORDER BY weight) AS t) as query WHERE query.__hibernate_sort_row > 111 ORDER BY query.__hibernate_sort_row", str.ToString()); - str = d.GetLimitString(new SqlString("SELECT *, (SELECT COUNT(1) FROM fowl WHERE fish_id = fish.id) AS some_count FROM fish"), 1, 10, -1, -2); - System.Console.WriteLine(str); + str = d.GetLimitString(new SqlString("SELECT *, (SELECT COUNT(1) FROM fowl WHERE fish_id = fish.id) AS some_count FROM fish"), new SqlString("111"), new SqlString("222")); Assert.AreEqual( - "SELECT TOP (?) *, some_count FROM (SELECT *, (SELECT COUNT(1) FROM fowl WHERE fish_id = fish.id) AS some_count, ROW_NUMBER() OVER(ORDER BY CURRENT_TIMESTAMP) as __hibernate_sort_row FROM fish) as query WHERE query.__hibernate_sort_row > ? ORDER BY query.__hibernate_sort_row", + "SELECT TOP (222) *, some_count FROM (SELECT *, (SELECT COUNT(1) FROM fowl WHERE fish_id = fish.id) AS some_count, ROW_NUMBER() OVER(ORDER BY CURRENT_TIMESTAMP) as __hibernate_sort_row FROM fish) as query WHERE query.__hibernate_sort_row > 111 ORDER BY query.__hibernate_sort_row", str.ToString()); - str = d.GetLimitString(new SqlString("SELECT * FROM fish WHERE scales = ", Parameter.Placeholder), 1, 10, -1, -2); - System.Console.WriteLine(str); + str = d.GetLimitString(new SqlString("SELECT * FROM fish WHERE scales = ", Parameter.Placeholder), new SqlString("111"), new SqlString("222")); Assert.AreEqual( - "SELECT TOP (?) * FROM (SELECT *, ROW_NUMBER() OVER(ORDER BY CURRENT_TIMESTAMP) as __hibernate_sort_row FROM fish WHERE scales = ?) as query WHERE query.__hibernate_sort_row > ? ORDER BY query.__hibernate_sort_row", + "SELECT TOP (222) * FROM (SELECT *, ROW_NUMBER() OVER(ORDER BY CURRENT_TIMESTAMP) as __hibernate_sort_row FROM fish WHERE scales = ?) as query WHERE query.__hibernate_sort_row > 111 ORDER BY query.__hibernate_sort_row", str.ToString()); - str = d.GetLimitString(new SqlString("SELECT f.Type, COUNT(DISTINCT f.Name) AS Name FROM Fish f GROUP BY f.Type ORDER BY COUNT(DISTINCT f.Name)"), 1, 10, -1, -2); - System.Console.WriteLine(str); + str = d.GetLimitString(new SqlString("SELECT f.Type, COUNT(DISTINCT f.Name) AS Name FROM Fish f GROUP BY f.Type ORDER BY COUNT(DISTINCT f.Name)"), new SqlString("111"), new SqlString("222")); Assert.AreEqual( - "SELECT TOP (?) Type, Name FROM (SELECT f.Type, COUNT(DISTINCT f.Name) AS Name, ROW_NUMBER() OVER(ORDER BY COUNT(DISTINCT f.Name)) as __hibernate_sort_row FROM Fish f GROUP BY f.Type) as query WHERE query.__hibernate_sort_row > ? ORDER BY query.__hibernate_sort_row", + "SELECT TOP (222) Type, Name FROM (SELECT f.Type, COUNT(DISTINCT f.Name) AS Name, ROW_NUMBER() OVER(ORDER BY COUNT(DISTINCT f.Name)) as __hibernate_sort_row FROM Fish f GROUP BY f.Type) as query WHERE query.__hibernate_sort_row > 111 ORDER BY query.__hibernate_sort_row", str.ToString()); } @@ -85,8 +73,7 @@ { var d = new MsSql2005Dialect(); - SqlString str = d.GetLimitString(new SqlString("select distinct c.Contact_Id as Contact1_19_0_, c._Rating as ... [truncated message content] |
From: <fab...@us...> - 2011-05-23 22:26:03
|
Revision: 5866 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5866&view=rev Author: fabiomaulo Date: 2011-05-23 22:25:56 +0000 (Mon, 23 May 2011) Log Message: ----------- First approximation to fix NH-2728 (many-to-any by code) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Mapping/ByCode/AbstractExplicitlyDeclaredModel.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/FakeModelExplicitDeclarationsHolder.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/ICollectionElementRelation.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/IModelExplicitDeclarationsHolder.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CollectionElementRelation.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersHolder.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/CollectionElementRelationCustomizer.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/PropertyContainerCustomizer.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ExplicitDeclarationsHolder.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ICustomizersHolder.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/ModelExplicitDeclarationsHolderExtensions.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/SimpleModelInspector.cs trunk/nhibernate/src/NHibernate/NHibernate.csproj trunk/nhibernate/src/NHibernate.Test/MappingByCode/ModelExplicitDeclarationsHolderMergeTest.cs Added Paths: ----------- trunk/nhibernate/src/NHibernate/Mapping/ByCode/IManyToAnyMapper.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/ManyToAnyCustomizer.cs Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/AbstractExplicitlyDeclaredModel.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/AbstractExplicitlyDeclaredModel.cs 2011-05-23 20:10:41 UTC (rev 5865) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/AbstractExplicitlyDeclaredModel.cs 2011-05-23 22:25:56 UTC (rev 5866) @@ -16,6 +16,7 @@ private readonly HashSet<MemberInfo> idBags = new HashSet<MemberInfo>(); private readonly HashSet<MemberInfo> lists = new HashSet<MemberInfo>(); private readonly HashSet<MemberInfo> manyToManyRelations = new HashSet<MemberInfo>(); + private readonly HashSet<MemberInfo> manyToAnyRelations = new HashSet<MemberInfo>(); private readonly HashSet<MemberInfo> manyToOneRelations = new HashSet<MemberInfo>(); private readonly HashSet<MemberInfo> naturalIds = new HashSet<MemberInfo>(); private readonly HashSet<MemberInfo> composedIds = new HashSet<MemberInfo>(); @@ -90,6 +91,11 @@ get { return oneToManyRelations; } } + public IEnumerable<MemberInfo> ManyToAnyRelations + { + get { return manyToAnyRelations; } + } + public IEnumerable<MemberInfo> Any { get { return any; } @@ -338,6 +344,12 @@ oneToManyRelations.Add(member); } + public void AddAsManyToAnyRelation(MemberInfo member) + { + persistentMembers.Add(member); + manyToAnyRelations.Add(member); + } + public void AddAsAny(MemberInfo member) { persistentMembers.Add(member); Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/FakeModelExplicitDeclarationsHolder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/FakeModelExplicitDeclarationsHolder.cs 2011-05-23 20:10:41 UTC (rev 5865) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/FakeModelExplicitDeclarationsHolder.cs 2011-05-23 22:25:56 UTC (rev 5866) @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -15,6 +16,7 @@ private readonly IEnumerable<MemberInfo> lists = Enumerable.Empty<MemberInfo>(); private readonly IEnumerable<MemberInfo> manyToManyRelations = Enumerable.Empty<MemberInfo>(); private readonly IEnumerable<MemberInfo> manyToOneRelations = Enumerable.Empty<MemberInfo>(); + private readonly IEnumerable<MemberInfo> manyToAnyRelations = Enumerable.Empty<MemberInfo>(); private readonly IEnumerable<MemberInfo> naturalIds = Enumerable.Empty<MemberInfo>(); private readonly IEnumerable<MemberInfo> oneToManyRelations = Enumerable.Empty<MemberInfo>(); private readonly IEnumerable<MemberInfo> oneToOneRelations = Enumerable.Empty<MemberInfo>(); @@ -84,6 +86,11 @@ get { return oneToManyRelations; } } + public IEnumerable<MemberInfo> ManyToAnyRelations + { + get { return manyToAnyRelations; } + } + public IEnumerable<MemberInfo> Any { get { return any; } @@ -191,6 +198,7 @@ public void AddAsManyToManyRelation(MemberInfo member) {} public void AddAsOneToManyRelation(MemberInfo member) {} + public void AddAsManyToAnyRelation(MemberInfo member) {} public void AddAsAny(MemberInfo member) {} Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/ICollectionElementRelation.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/ICollectionElementRelation.cs 2011-05-23 20:10:41 UTC (rev 5865) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/ICollectionElementRelation.cs 2011-05-23 22:25:56 UTC (rev 5866) @@ -8,6 +8,7 @@ void OneToMany(Action<IOneToManyMapper> mapping); void ManyToMany(Action<IManyToManyMapper> mapping); void Component(Action<IComponentElementMapper> mapping); + void ManyToAny(System.Type idTypeOfMetaType, Action<IManyToAnyMapper> mapping); } public interface ICollectionElementRelation<TElement> @@ -19,5 +20,7 @@ void ManyToMany(); void ManyToMany(Action<IManyToManyMapper> mapping); void Component(Action<IComponentElementMapper<TElement>> mapping); + void ManyToAny(System.Type idTypeOfMetaType, Action<IManyToAnyMapper> mapping); + void ManyToAny<TIdTypeOfMetaType>(Action<IManyToAnyMapper> mapping); } } \ No newline at end of file Added: trunk/nhibernate/src/NHibernate/Mapping/ByCode/IManyToAnyMapper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/IManyToAnyMapper.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/IManyToAnyMapper.cs 2011-05-23 22:25:56 UTC (rev 5866) @@ -0,0 +1,25 @@ +using System; +using NHibernate.Type; + +namespace NHibernate.Mapping.ByCode +{ + public interface IManyToAnyMapper + { + void MetaType(IType metaType); + void MetaType<TMetaType>(); + void MetaType(System.Type metaType); + + void IdType(IType idType); + void IdType<TIdType>(); + void IdType(System.Type idType); + + void Columns(Action<IColumnMapper> idColumnMapping, Action<IColumnMapper> classColumnMapping); + + /// <summary> + /// Add or modify a value-class pair. + /// </summary> + /// <param name="value">The value of the DB-field dor a given association instance (should override <see cref="object.ToString"/>)</param> + /// <param name="entityType">The class associated to the specific <paramref name="value"/>. </param> + void MetaValue(object value, System.Type entityType); + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/IModelExplicitDeclarationsHolder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/IModelExplicitDeclarationsHolder.cs 2011-05-23 20:10:41 UTC (rev 5865) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/IModelExplicitDeclarationsHolder.cs 2011-05-23 22:25:56 UTC (rev 5866) @@ -29,6 +29,8 @@ IEnumerable<MemberInfo> ManyToOneRelations { get; } IEnumerable<MemberInfo> ManyToManyRelations { get; } IEnumerable<MemberInfo> OneToManyRelations { get; } + IEnumerable<MemberInfo> ManyToAnyRelations { get; } + IEnumerable<MemberInfo> Any { get; } IEnumerable<MemberInfo> Poids { get; } @@ -61,6 +63,8 @@ void AddAsManyToOneRelation(MemberInfo member); void AddAsManyToManyRelation(MemberInfo member); void AddAsOneToManyRelation(MemberInfo member); + void AddAsManyToAnyRelation(MemberInfo member); + void AddAsAny(MemberInfo member); void AddAsPoid(MemberInfo member); Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CollectionElementRelation.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CollectionElementRelation.cs 2011-05-23 20:10:41 UTC (rev 5865) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CollectionElementRelation.cs 2011-05-23 22:25:56 UTC (rev 5866) @@ -46,6 +46,11 @@ elementRelationshipAssing(hbm); } + public void ManyToAny(System.Type idTypeOfMetaType, Action<IManyToAnyMapper> mapping) + { + throw new NotImplementedException(); + } + #endregion } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersHolder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersHolder.cs 2011-05-23 20:10:41 UTC (rev 5865) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersHolder.cs 2011-05-23 22:25:56 UTC (rev 5866) @@ -24,6 +24,9 @@ private readonly Dictionary<PropertyPath, List<Action<IManyToManyMapper>>> collectionRelationManyToManyCustomizers = new Dictionary<PropertyPath, List<Action<IManyToManyMapper>>>(); + private readonly Dictionary<PropertyPath, List<Action<IManyToAnyMapper>>> collectionRelationManyToAnyCustomizers = + new Dictionary<PropertyPath, List<Action<IManyToAnyMapper>>>(); + private readonly Dictionary<PropertyPath, List<Action<IOneToManyMapper>>> collectionRelationOneToManyCustomizers = new Dictionary<PropertyPath, List<Action<IOneToManyMapper>>>(); @@ -190,6 +193,11 @@ AddCustomizer(collectionRelationOneToManyCustomizers, member, collectionRelationOneToManyCustomizer); } + public void AddCustomizer(PropertyPath member, Action<IManyToAnyMapper> collectionRelationManyToAnyCustomizer) + { + AddCustomizer(collectionRelationManyToAnyCustomizers, member, collectionRelationManyToAnyCustomizer); + } + public void AddCustomizer(PropertyPath member, Action<IMapKeyManyToManyMapper> mapKeyManyToManyCustomizer) { AddCustomizer(mapKeyManyToManyCustomizers, member, mapKeyManyToManyCustomizer); @@ -200,6 +208,11 @@ AddCustomizer(mapKeyElementCustomizers, member, mapKeyElementCustomizer); } + public void InvokeCustomizers(PropertyPath member, IManyToAnyMapper mapper) + { + InvokeCustomizers(collectionRelationManyToAnyCustomizers, member, mapper); + } + public IEnumerable<System.Type> GetAllCustomizedEntities() { return rootClassCustomizers.Keys.Concat(subclassCustomizers.Keys).Concat(joinedClassCustomizers.Keys).Concat(unionClassCustomizers.Keys); Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/CollectionElementRelationCustomizer.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/CollectionElementRelationCustomizer.cs 2011-05-23 20:10:41 UTC (rev 5865) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/CollectionElementRelationCustomizer.cs 2011-05-23 22:25:56 UTC (rev 5866) @@ -61,6 +61,21 @@ mapping(componetElementCustomizer); } + public void ManyToAny(System.Type idTypeOfMetaType, Action<IManyToAnyMapper> mapping) + { + if (mapping == null) + { + throw new ArgumentNullException("mapping"); + } + var manyToAnyCustomizer = new ManyToAnyCustomizer(explicitDeclarationsHolder, propertyPath, customizersHolder); + mapping(manyToAnyCustomizer); + } + + public void ManyToAny<TIdTypeOfMetaType>(Action<IManyToAnyMapper> mapping) + { + ManyToAny(typeof(TIdTypeOfMetaType), mapping); + } + #endregion } } \ No newline at end of file Added: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/ManyToAnyCustomizer.cs =================================================================== (Binary files differ) Property changes on: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/ManyToAnyCustomizer.cs ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/PropertyContainerCustomizer.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/PropertyContainerCustomizer.cs 2011-05-23 20:10:41 UTC (rev 5865) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/PropertyContainerCustomizer.cs 2011-05-23 22:25:56 UTC (rev 5866) @@ -185,7 +185,7 @@ { foreach (var member in members) { - CustomizersHolder.AddCustomizer(new PropertyPath(PropertyPath, member), am => am.IdType(idTypeOfMetaType)); + CustomizersHolder.AddCustomizer(new PropertyPath(PropertyPath, member), (IAnyMapper am) => am.IdType(idTypeOfMetaType)); CustomizersHolder.AddCustomizer(new PropertyPath(PropertyPath, member), mapping); explicitDeclarationsHolder.AddAsAny(member); Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ExplicitDeclarationsHolder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ExplicitDeclarationsHolder.cs 2011-05-23 20:10:41 UTC (rev 5865) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ExplicitDeclarationsHolder.cs 2011-05-23 22:25:56 UTC (rev 5866) @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -15,6 +16,7 @@ private readonly HashSet<MemberInfo> lists = new HashSet<MemberInfo>(); private readonly HashSet<MemberInfo> manyToManyRelations = new HashSet<MemberInfo>(); private readonly HashSet<MemberInfo> manyToOneRelations = new HashSet<MemberInfo>(); + private readonly HashSet<MemberInfo> manyToAnyRelations = new HashSet<MemberInfo>(); private readonly HashSet<MemberInfo> naturalIds = new HashSet<MemberInfo>(); private readonly HashSet<MemberInfo> oneToManyRelations = new HashSet<MemberInfo>(); private readonly HashSet<MemberInfo> oneToOneRelations = new HashSet<MemberInfo>(); @@ -79,6 +81,11 @@ get { return oneToManyRelations; } } + public IEnumerable<MemberInfo> ManyToAnyRelations + { + get { return manyToAnyRelations; } + } + public IEnumerable<MemberInfo> Any { get { return any; } @@ -216,6 +223,11 @@ oneToManyRelations.Add(member); } + public void AddAsManyToAnyRelation(MemberInfo member) + { + manyToAnyRelations.Add(member); + } + public void AddAsAny(MemberInfo member) { any.Add(member); Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ICustomizersHolder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ICustomizersHolder.cs 2011-05-23 20:10:41 UTC (rev 5865) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ICustomizersHolder.cs 2011-05-23 22:25:56 UTC (rev 5866) @@ -48,16 +48,10 @@ void InvokeCustomizers(PropertyPath member, IComponentAsIdAttributesMapper mapper); void InvokeCustomizers(PropertyPath member, IDynamicComponentAttributesMapper mapper); - #region Collection Element relations invokers - - void InvokeCustomizers(PropertyPath member, IManyToManyMapper mapper); - void InvokeCustomizers(PropertyPath member, IElementMapper mapper); - void InvokeCustomizers(PropertyPath member, IOneToManyMapper mapper); - - #endregion - #region Dictionary key relations + void AddCustomizer(PropertyPath member, Action<IMapKeyManyToManyMapper> mapKeyManyToManyCustomizer); + void AddCustomizer(PropertyPath member, Action<IMapKeyMapper> mapKeyElementCustomizer); void InvokeCustomizers(PropertyPath member, IMapKeyManyToManyMapper mapper); void InvokeCustomizers(PropertyPath member, IMapKeyMapper mapper); @@ -68,16 +62,14 @@ void AddCustomizer(PropertyPath member, Action<IManyToManyMapper> collectionRelationManyToManyCustomizer); void AddCustomizer(PropertyPath member, Action<IElementMapper> collectionRelationElementCustomizer); void AddCustomizer(PropertyPath member, Action<IOneToManyMapper> collectionRelationOneToManyCustomizer); + void AddCustomizer(PropertyPath member, Action<IManyToAnyMapper> collectionRelationManyToAnyCustomizer); + void InvokeCustomizers(PropertyPath member, IManyToManyMapper mapper); + void InvokeCustomizers(PropertyPath member, IElementMapper mapper); + void InvokeCustomizers(PropertyPath member, IOneToManyMapper mapper); + void InvokeCustomizers(PropertyPath member, IManyToAnyMapper mapper); #endregion - #region Dictionary key relations - - void AddCustomizer(PropertyPath member, Action<IMapKeyManyToManyMapper> mapKeyManyToManyCustomizer); - void AddCustomizer(PropertyPath member, Action<IMapKeyMapper> mapKeyElementCustomizer); - - #endregion - IEnumerable<System.Type> GetAllCustomizedEntities(); } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/ModelExplicitDeclarationsHolderExtensions.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/ModelExplicitDeclarationsHolderExtensions.cs 2011-05-23 20:10:41 UTC (rev 5865) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/ModelExplicitDeclarationsHolderExtensions.cs 2011-05-23 22:25:56 UTC (rev 5866) @@ -20,6 +20,7 @@ System.Array.ForEach(source.OneToOneRelations.ToArray(), destination.AddAsOneToOneRelation); System.Array.ForEach(source.ManyToOneRelations.ToArray(), destination.AddAsManyToOneRelation); System.Array.ForEach(source.ManyToManyRelations.ToArray(), destination.AddAsManyToManyRelation); + System.Array.ForEach(source.ManyToAnyRelations.ToArray(), destination.AddAsManyToAnyRelation); System.Array.ForEach(source.OneToManyRelations.ToArray(), destination.AddAsOneToManyRelation); System.Array.ForEach(source.Any.ToArray(), destination.AddAsAny); Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/SimpleModelInspector.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/SimpleModelInspector.cs 2011-05-23 20:10:41 UTC (rev 5865) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/SimpleModelInspector.cs 2011-05-23 22:25:56 UTC (rev 5866) @@ -428,6 +428,11 @@ get { return declaredModel.OneToManyRelations; } } + IEnumerable<MemberInfo> IModelExplicitDeclarationsHolder.ManyToAnyRelations + { + get { return declaredModel.ManyToAnyRelations; } + } + IEnumerable<MemberInfo> IModelExplicitDeclarationsHolder.Any { get { return declaredModel.Any; } @@ -553,6 +558,11 @@ declaredModel.AddAsOneToManyRelation(member); } + void IModelExplicitDeclarationsHolder.AddAsManyToAnyRelation(MemberInfo member) + { + declaredModel.AddAsManyToAnyRelation(member); + } + void IModelExplicitDeclarationsHolder.AddAsAny(MemberInfo member) { declaredModel.AddAsAny(member); Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2011-05-23 20:10:41 UTC (rev 5865) +++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2011-05-23 22:25:56 UTC (rev 5866) @@ -302,12 +302,14 @@ <Compile Include="Mapping\ByCode\Conformist\UnionSubclassMapping.cs" /> <Compile Include="Mapping\ByCode\ICompositeIdMapper.cs" /> <Compile Include="Mapping\ByCode\IDynamicComponentAttributesMapper.cs" /> + <Compile Include="Mapping\ByCode\IManyToAnyMapper.cs" /> <Compile Include="Mapping\ByCode\Impl\ComponentAsIdLikeComponetAttributesMapper.cs" /> <Compile Include="Mapping\ByCode\Impl\ComponentAsIdMapper.cs" /> <Compile Include="Mapping\ByCode\Impl\ComposedIdMapper.cs" /> <Compile Include="Mapping\ByCode\Impl\CustomizersImpl\ComponentAsIdCustomizer.cs" /> <Compile Include="Mapping\ByCode\Impl\CustomizersImpl\ComposedIdCustomizer.cs" /> <Compile Include="Mapping\ByCode\Impl\CustomizersImpl\DynamicComponentCustomizer.cs" /> + <Compile Include="Mapping\ByCode\Impl\CustomizersImpl\ManyToAnyCustomizer.cs" /> <Compile Include="Mapping\ByCode\Impl\DynamicComponentMapper.cs" /> <Compile Include="Mapping\ByCode\PropertyGeneration.cs" /> <Compile Include="Mapping\ByCode\PropertyToField.cs" /> Modified: trunk/nhibernate/src/NHibernate.Test/MappingByCode/ModelExplicitDeclarationsHolderMergeTest.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/MappingByCode/ModelExplicitDeclarationsHolderMergeTest.cs 2011-05-23 20:10:41 UTC (rev 5865) +++ trunk/nhibernate/src/NHibernate.Test/MappingByCode/ModelExplicitDeclarationsHolderMergeTest.cs 2011-05-23 22:25:56 UTC (rev 5866) @@ -24,6 +24,7 @@ private readonly HashSet<MemberInfo> idBags = new HashSet<MemberInfo>(); private readonly HashSet<MemberInfo> lists = new HashSet<MemberInfo>(); private readonly HashSet<MemberInfo> manyToManyRelations = new HashSet<MemberInfo>(); + private readonly HashSet<MemberInfo> manyToAnyRelations = new HashSet<MemberInfo>(); private readonly HashSet<MemberInfo> manyToOneRelations = new HashSet<MemberInfo>(); private readonly HashSet<MemberInfo> naturalIds = new HashSet<MemberInfo>(); private readonly HashSet<MemberInfo> oneToManyRelations = new HashSet<MemberInfo>(); @@ -126,6 +127,15 @@ } } + public IEnumerable<MemberInfo> ManyToAnyRelations + { + get + { + PropertiesGettersUsed.Add("ManyToAnyRelations"); + return manyToAnyRelations; + } + } + public IEnumerable<MemberInfo> Any { get @@ -285,6 +295,8 @@ public void AddAsManyToOneRelation(MemberInfo member) { } public void AddAsManyToManyRelation(MemberInfo member) { } public void AddAsOneToManyRelation(MemberInfo member) { } + public void AddAsManyToAnyRelation(MemberInfo member) {} + public void AddAsAny(MemberInfo member) { } public void AddAsPoid(MemberInfo member) { } public void AddAsPartOfComposedId(MemberInfo member) { } @@ -467,6 +479,17 @@ } [Test] + public void MergeManyToAnyRelations() + { + var destination = new ExplicitDeclarationsHolder(); + var source = new ExplicitDeclarationsHolder(); + source.AddAsManyToAnyRelation(property); + + destination.Merge(source); + destination.ManyToAnyRelations.Should().Have.Count.EqualTo(1); + } + + [Test] public void MergeManyToManyRelations() { var destination = new ExplicitDeclarationsHolder(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-05-23 20:10:48
|
Revision: 5865 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5865&view=rev Author: fabiomaulo Date: 2011-05-23 20:10:41 +0000 (Mon, 23 May 2011) Log Message: ----------- Not fixed test fro NH-2477 Modified Paths: -------------- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2477/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2477/Fixture.cs Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2477/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2477/Fixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2477/Fixture.cs 2011-05-23 20:10:41 UTC (rev 5865) @@ -0,0 +1,72 @@ +using System; +using System.Linq.Dynamic; +using NHibernate.Cfg.MappingSchema; +using NHibernate.Linq; +using NHibernate.Mapping.ByCode; +using NUnit.Framework; +using SharpTestsEx; + +namespace NHibernate.Test.NHSpecificTest.NH2477 +{ + public class Something + { + public virtual int Id { get; set; } + public virtual string Name { get; set; } + } + + [TestFixture, Ignore("Not fixed yet.")] + public class Fixture: TestCaseMappingByCode + { + protected override HbmMapping GetMappings() + { + var mapper = new ConventionModelMapper(); + mapper.BeforeMapClass += (t, mi, map)=> map.Id(idm=> idm.Generator(Generators.Native)); + return mapper.CompileMappingFor(new[] { typeof(Something) }); + } + + private class Scenario : IDisposable + { + private readonly ISessionFactory factory; + + public Scenario(ISessionFactory factory) + { + this.factory = factory; + using (var session = factory.OpenSession()) + using (session.BeginTransaction()) + { + for (int i = 0; i < 5; i++) + { + session.Persist(new Something { Name = i.ToString() }); + } + session.Transaction.Commit(); + } + } + + public void Dispose() + { + using (var session = factory.OpenSession()) + using (session.BeginTransaction()) + { + session.CreateQuery("delete from Something").ExecuteUpdate(); + session.Transaction.Commit(); + } + } + } + + [Test] + public void WhenTakeBeforeCountShouldApplyTake() + { + using (new Scenario(Sfi)) + { + using (var session = sessions.OpenSession()) + using (session.BeginTransaction()) + { + // This is another case where we have to work with subqueries and we have to write a specific query rewriter for Skip/Take instead flat the query in QueryReferenceExpressionFlattener + //var actual = session.CreateQuery("select count(s) from Something s where s in (from Something take 3)").UniqueResult<long>(); + var actual = session.Query<Something>().Take(3).Count(); + actual.Should().Be(3); + } + } + } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-05-23 19:10:23 UTC (rev 5864) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-05-23 20:10:41 UTC (rev 5865) @@ -793,6 +793,7 @@ <Compile Include="NHSpecificTest\NH2470\Class1Class2Tests.cs" /> <Compile Include="NHSpecificTest\NH2470\DomainObject.cs" /> <Compile Include="NHSpecificTest\NH2470\DTO.cs" /> + <Compile Include="NHSpecificTest\NH2477\Fixture.cs" /> <Compile Include="NHSpecificTest\NH2484\Fixture.cs" /> <Compile Include="NHSpecificTest\NH2484\Model.cs" /> <Compile Include="NHSpecificTest\NH2488\Fixture.cs" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-05-23 19:10:29
|
Revision: 5864 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5864&view=rev Author: fabiomaulo Date: 2011-05-23 19:10:23 +0000 (Mon, 23 May 2011) Log Message: ----------- Fix NH-2317 Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Linq/ReWriters/QueryReferenceExpressionFlattener.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2317/Fixture.cs Modified: trunk/nhibernate/src/NHibernate/Linq/ReWriters/QueryReferenceExpressionFlattener.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/ReWriters/QueryReferenceExpressionFlattener.cs 2011-05-23 19:07:03 UTC (rev 5863) +++ trunk/nhibernate/src/NHibernate/Linq/ReWriters/QueryReferenceExpressionFlattener.cs 2011-05-23 19:10:23 UTC (rev 5864) @@ -1,61 +1,82 @@ -using System.Linq.Expressions; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; using NHibernate.Linq.Visitors; using Remotion.Linq; using Remotion.Linq.Clauses; using Remotion.Linq.Clauses.Expressions; +using Remotion.Linq.Clauses.ResultOperators; namespace NHibernate.Linq.ReWriters { + /// <summary> + /// This re-writer is responsible to re-write a query without a body (no where-clause and so on). + /// </summary> public class QueryReferenceExpressionFlattener : NhExpressionTreeVisitor { - private readonly QueryModel _model; + private readonly QueryModel _model; + // NOTE: Skip/Take are not completelly flattenable since Take(10).Skip(5).Take(2) should result in a subqueries-tsunami (so far not common understanding from our users) + private static readonly List<System.Type> FlattenableResultOperactors = new List<System.Type> + { + typeof(CacheableResultOperator), + typeof(SkipResultOperator), + typeof(TakeResultOperator), + }; - private QueryReferenceExpressionFlattener(QueryModel model) + private QueryReferenceExpressionFlattener(QueryModel model) { - _model = model; + _model = model; } - public static void ReWrite(QueryModel model) + public static void ReWrite(QueryModel model) { var visitor = new QueryReferenceExpressionFlattener(model); model.TransformExpressions(visitor.VisitExpression); } - protected override Expression VisitSubQueryExpression(SubQueryExpression subQuery) - { - if ((subQuery.QueryModel.BodyClauses.Count == 0) && - ((subQuery.QueryModel.ResultOperators.Count == 0) || (subQuery.QueryModel.ResultOperators.Count == 1 && subQuery.QueryModel.ResultOperators[0] is CacheableResultOperator)) - ) - { - var selectQuerySource = - subQuery.QueryModel.SelectClause.Selector as QuerySourceReferenceExpression; + protected override Expression VisitSubQueryExpression(SubQueryExpression subQuery) + { + var hasBodyClauses = subQuery.QueryModel.BodyClauses.Count > 0; + if(hasBodyClauses) + { + return base.VisitSubQueryExpression(subQuery); + } + var resultOperators = subQuery.QueryModel.ResultOperators; + if (resultOperators.Count == 0 || HasJustAllFlattenableOperator(resultOperators)) + { + var selectQuerySource = subQuery.QueryModel.SelectClause.Selector as QuerySourceReferenceExpression; - if (selectQuerySource != null && selectQuerySource.ReferencedQuerySource == subQuery.QueryModel.MainFromClause) - { - if (subQuery.QueryModel.ResultOperators.Count == 1) - { - _model.ResultOperators.Add(subQuery.QueryModel.ResultOperators[0]); - } + if (selectQuerySource != null && selectQuerySource.ReferencedQuerySource == subQuery.QueryModel.MainFromClause) + { + foreach (var resultOperator in resultOperators) + { + _model.ResultOperators.Add(resultOperator); + } - return subQuery.QueryModel.MainFromClause.FromExpression; - } - } + return subQuery.QueryModel.MainFromClause.FromExpression; + } + } - return base.VisitSubQueryExpression(subQuery); - } + return base.VisitSubQueryExpression(subQuery); + } - protected override Expression VisitQuerySourceReferenceExpression(QuerySourceReferenceExpression expression) + private bool HasJustAllFlattenableOperator(IEnumerable<ResultOperatorBase> resultOperators) { + return resultOperators.All(x => FlattenableResultOperactors.Contains(x.GetType())); + } + + protected override Expression VisitQuerySourceReferenceExpression(QuerySourceReferenceExpression expression) + { var fromClauseBase = expression.ReferencedQuerySource as FromClauseBase; - if (fromClauseBase != null && + if (fromClauseBase != null && fromClauseBase.FromExpression is QuerySourceReferenceExpression && expression.Type == fromClauseBase.FromExpression.Type) { return fromClauseBase.FromExpression; } - return base.VisitQuerySourceReferenceExpression(expression); + return base.VisitQuerySourceReferenceExpression(expression); } } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2317/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2317/Fixture.cs 2011-05-23 19:07:03 UTC (rev 5863) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2317/Fixture.cs 2011-05-23 19:10:23 UTC (rev 5864) @@ -5,7 +5,7 @@ namespace NHibernate.Test.NHSpecificTest.NH2317 { - [TestFixture, Ignore("Not fixed yet.")] + [TestFixture] public class Fixture : BugTestCase { protected override void OnSetUp() @@ -28,8 +28,12 @@ using (var session = sessions.OpenSession()) using(session.BeginTransaction()) { - // HQL show how should look the HQL tree in this case and in all others casses where Skip/Take are not the last sentences - var expected = session.CreateQuery("select a.id from Artist a where a in (from Artist take 3)").List<int>(); + // The HQL : "select a.id from Artist a where a in (from Artist take 3)" + // shows how should look the HQL tree in the case where Skip/Take are not the last sentences. + + // When the query has no where-clauses the the HQL can be reduced to: "select a.id from Artist a take 3)" + + var expected = session.CreateQuery("select a.id from Artist a take 3").List<int>(); var actual = session.Query<Artist>().Take(3).Select(a => a.Id).ToArray(); actual.Should().Have.SameValuesAs(expected); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-05-23 19:07:10
|
Revision: 5863 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5863&view=rev Author: fabiomaulo Date: 2011-05-23 19:07:03 +0000 (Mon, 23 May 2011) Log Message: ----------- Just an adjustment, to avoid an cyclopean ProxyFactory instance Modified Paths: -------------- trunk/nhibernate/src/NHibernate/NHibernate.csproj trunk/nhibernate/src/NHibernate/Proxy/DefaultProxyFactory.cs Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2011-05-23 15:23:00 UTC (rev 5862) +++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2011-05-23 19:07:03 UTC (rev 5863) @@ -39,7 +39,8 @@ <OutputPath>bin\Debug-2.0\</OutputPath> <BaseIntermediateOutputPath>obj\</BaseIntermediateOutputPath> <IntermediateOutputPath>obj\Debug-2.0\</IntermediateOutputPath> - <DefineConstants>TRACE;DEBUG</DefineConstants> + <DefineConstants> + </DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> <DocumentationFile>bin\Debug-2.0\NHibernate.XML</DocumentationFile> Modified: trunk/nhibernate/src/NHibernate/Proxy/DefaultProxyFactory.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Proxy/DefaultProxyFactory.cs 2011-05-23 15:23:00 UTC (rev 5862) +++ trunk/nhibernate/src/NHibernate/Proxy/DefaultProxyFactory.cs 2011-05-23 19:07:03 UTC (rev 5863) @@ -7,7 +7,7 @@ { public class DefaultProxyFactory : AbstractProxyFactory { - private static readonly ProxyFactory factory = new ProxyFactory(); + private readonly ProxyFactory factory = new ProxyFactory(); protected static readonly IInternalLogger log = LoggerProvider.LoggerFor(typeof (DefaultProxyFactory)); public override INHibernateProxy GetProxy(object id, ISessionImplementor session) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-05-23 15:23:07
|
Revision: 5862 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5862&view=rev Author: fabiomaulo Date: 2011-05-23 15:23:00 +0000 (Mon, 23 May 2011) Log Message: ----------- Added comment Modified Paths: -------------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2317/Fixture.cs Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2317/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2317/Fixture.cs 2011-05-23 14:03:12 UTC (rev 5861) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2317/Fixture.cs 2011-05-23 15:23:00 UTC (rev 5862) @@ -28,7 +28,8 @@ using (var session = sessions.OpenSession()) using(session.BeginTransaction()) { - var expected = session.CreateQuery("select a.id from Artist a").SetMaxResults(3).List<int>(); + // HQL show how should look the HQL tree in this case and in all others casses where Skip/Take are not the last sentences + var expected = session.CreateQuery("select a.id from Artist a where a in (from Artist take 3)").List<int>(); var actual = session.Query<Artist>().Take(3).Select(a => a.Id).ToArray(); actual.Should().Have.SameValuesAs(expected); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-05-23 14:03:20
|
Revision: 5861 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5861&view=rev Author: fabiomaulo Date: 2011-05-23 14:03:12 +0000 (Mon, 23 May 2011) Log Message: ----------- Test for NH-2317 Not fixed Modified Paths: -------------- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2317/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2317/Domain.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2317/Fixture.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2317/Mappings.hbm.xml Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2317/Domain.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2317/Domain.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2317/Domain.cs 2011-05-23 14:03:12 UTC (rev 5861) @@ -0,0 +1,8 @@ +namespace NHibernate.Test.NHSpecificTest.NH2317 +{ + public class Artist + { + public virtual int Id { get; set; } + public virtual string Name { get; set; } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2317/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2317/Fixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2317/Fixture.cs 2011-05-23 14:03:12 UTC (rev 5861) @@ -0,0 +1,48 @@ +using System.Linq; +using NHibernate.Linq; +using NUnit.Framework; +using SharpTestsEx; + +namespace NHibernate.Test.NHSpecificTest.NH2317 +{ + [TestFixture, Ignore("Not fixed yet.")] + public class Fixture : BugTestCase + { + protected override void OnSetUp() + { + base.OnSetUp(); + using (var session = sessions.OpenStatelessSession()) + using (var tx = session.BeginTransaction()) + { + foreach (var artistName in new[] { "Foo", "Bar", "Baz", "Soz", "Tiz", "Fez" }) + { + session.Insert(new Artist { Name = artistName }); + } + tx.Commit(); + } + } + + [Test] + public void QueryShouldWork() + { + using (var session = sessions.OpenSession()) + using(session.BeginTransaction()) + { + var expected = session.CreateQuery("select a.id from Artist a").SetMaxResults(3).List<int>(); + var actual = session.Query<Artist>().Take(3).Select(a => a.Id).ToArray(); + actual.Should().Have.SameValuesAs(expected); + } + } + + protected override void OnTearDown() + { + using(var session = sessions.OpenStatelessSession()) + using (var tx = session.BeginTransaction()) + { + session.CreateQuery("delete Artist").ExecuteUpdate(); + tx.Commit(); + } + base.OnTearDown(); + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2317/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2317/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2317/Mappings.hbm.xml 2011-05-23 14:03:12 UTC (rev 5861) @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" + assembly="NHibernate.Test" + namespace="NHibernate.Test.NHSpecificTest.NH2317"> + + <class name="Artist"> + <id name="Id" type="int"> + <generator class="hilo"/> + </id> + <property name="Name" /> + </class> + </hibernate-mapping> \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-05-23 12:59:32 UTC (rev 5860) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-05-23 14:03:12 UTC (rev 5861) @@ -723,6 +723,8 @@ <Compile Include="NHSpecificTest\NH2303\Model.cs" /> <Compile Include="NHSpecificTest\NH2313\Domain.cs" /> <Compile Include="NHSpecificTest\NH2313\Fixture.cs" /> + <Compile Include="NHSpecificTest\NH2317\Domain.cs" /> + <Compile Include="NHSpecificTest\NH2317\Fixture.cs" /> <Compile Include="NHSpecificTest\NH2322\Fixture.cs" /> <Compile Include="NHSpecificTest\NH2322\Model.cs" /> <Compile Include="NHSpecificTest\NH2322\PostUpdateEventListener.cs" /> @@ -2688,6 +2690,7 @@ <EmbeddedResource Include="NHSpecificTest\NH1291AnonExample\Mappings.hbm.xml" /> </ItemGroup> <ItemGroup> + <EmbeddedResource Include="NHSpecificTest\NH2317\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2366\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2404\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2705\Mappings.hbm.xml" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-05-23 12:59:39
|
Revision: 5860 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5860&view=rev Author: fabiomaulo Date: 2011-05-23 12:59:32 +0000 (Mon, 23 May 2011) Log Message: ----------- LINQ provider using HQL skip/take Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs trunk/nhibernate/src/NHibernate/Linq/IntermediateHqlTree.cs trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessFirst.cs trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessSkip.cs trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessTake.cs Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs 2011-05-23 12:28:49 UTC (rev 5859) +++ trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs 2011-05-23 12:59:32 UTC (rev 5860) @@ -176,6 +176,16 @@ return new HqlOrderBy(_factory); } + public HqlSkip Skip(HqlExpression parameter) + { + return new HqlSkip(_factory, parameter); + } + + public HqlTake Take(HqlExpression parameter) + { + return new HqlTake(_factory, parameter); + } + public HqlSelect Select(HqlExpression expression) { return new HqlSelect(_factory, expression); Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs 2011-05-23 12:28:49 UTC (rev 5859) +++ trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs 2011-05-23 12:59:32 UTC (rev 5860) @@ -363,6 +363,18 @@ } } + public class HqlSkip : HqlStatement + { + public HqlSkip(IASTFactory factory, HqlExpression parameter) + : base(HqlSqlWalker.SKIP, "skip", factory, parameter) { } + } + + public class HqlTake : HqlStatement + { + public HqlTake(IASTFactory factory, HqlExpression parameter) + : base(HqlSqlWalker.TAKE, "take", factory, parameter) {} + } + public class HqlConstant : HqlExpression { public HqlConstant(IASTFactory factory, int type, string value) Modified: trunk/nhibernate/src/NHibernate/Linq/IntermediateHqlTree.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/IntermediateHqlTree.cs 2011-05-23 12:28:49 UTC (rev 5859) +++ trunk/nhibernate/src/NHibernate/Linq/IntermediateHqlTree.cs 2011-05-23 12:59:32 UTC (rev 5860) @@ -11,26 +11,45 @@ { public class IntermediateHqlTree { - private readonly bool _root; + /* NOTE: + * Because common understanding of our users, we are flatting the behavior of Skip and Take methods. + * In RAM a query like primeNumbers.Skip(2).Take(6).Where(x=> x > 10) has a completely different results than primeNumbers.Where(x=> x > 10).Skip(2).Take(6) that has + * different results than primeNumbers.Take(6).Where(x=> x > 10).Skip(2) and so on. + * We are flatting/override even the double-usage of Skip and Take in the same query as: primeNumbers.Skip(2).Where(x=> x > 10).Take(6).Skip(3) + * We ***shouldn't*** change the behavior of the query just because we are translating it in SQL. + */ + private readonly bool isRoot; private readonly List<Action<IQuery, IDictionary<string, Tuple<object, IType>>>> _additionalCriteria = new List<Action<IQuery, IDictionary<string, Tuple<object, IType>>>>(); private readonly List<LambdaExpression> _listTransformers = new List<LambdaExpression>(); private readonly List<LambdaExpression> _itemTransformers = new List<LambdaExpression>(); private readonly List<LambdaExpression> _postExecuteTransformers = new List<LambdaExpression>(); private bool _hasDistinctRootOperator; + private HqlExpression skipCount; + private HqlExpression takeCount; - public HqlTreeNode Root { get; private set; } - public HqlTreeBuilder TreeBuilder { get; private set; } + private HqlTreeNode root; + public HqlTreeNode Root + { + get + { + ExecuteAddSkipClause(skipCount); + ExecuteAddTakeClause(takeCount); + return root; + } + } + public HqlTreeBuilder TreeBuilder { get; private set; } + public IntermediateHqlTree(bool root) { - _root = root; + isRoot = root; TreeBuilder = new HqlTreeBuilder(); - Root = TreeBuilder.Query(TreeBuilder.SelectFrom(TreeBuilder.From())); + this.root = TreeBuilder.Query(TreeBuilder.SelectFrom(TreeBuilder.From())); } public ExpressionToHqlTranslationResults GetTranslation() { - if (_root) + if (isRoot) { DetectOuterExists(); } @@ -62,41 +81,86 @@ public void AddFromClause(HqlTreeNode from) { - Root.NodesPreOrder.Where(n => n is HqlFrom).First().AddChild(from); + root.NodesPreOrder.Where(n => n is HqlFrom).First().AddChild(from); } public void AddSelectClause(HqlTreeNode select) { - Root.NodesPreOrder.Where(n => n is HqlSelectFrom).First().AddChild(select); + root.NodesPreOrder.Where(n => n is HqlSelectFrom).First().AddChild(select); } public void AddGroupByClause(HqlGroupBy groupBy) { - Root.As<HqlQuery>().AddChild(groupBy); + root.As<HqlQuery>().AddChild(groupBy); } public void AddOrderByClause(HqlExpression orderBy, HqlDirectionStatement direction) { - var orderByRoot = Root.NodesPreOrder.Where(n => n is HqlOrderBy).FirstOrDefault(); + var orderByRoot = root.NodesPreOrder.Where(n => n is HqlOrderBy).FirstOrDefault(); if (orderByRoot == null) { orderByRoot = TreeBuilder.OrderBy(); - Root.As<HqlQuery>().AddChild(orderByRoot); + root.As<HqlQuery>().AddChild(orderByRoot); } orderByRoot.AddChild(orderBy); orderByRoot.AddChild(direction); } - public void AddWhereClause(HqlBooleanExpression where) + public void AddSkipClause(HqlExpression toSkip) + { + skipCount = toSkip; + } + + public void AddTakeClause(HqlExpression toTake) + { + takeCount = toTake; + } + + private void ExecuteAddTakeClause(HqlExpression toTake) + { + if(toTake == null) + { + return; + } + + HqlQuery hqlQuery = root.NodesPreOrder.OfType<HqlQuery>().First(); + HqlTreeNode takeRoot = hqlQuery.Children.FirstOrDefault(n => n is HqlTake); + + // were present we ignore the new value + if (takeRoot == null) + { + //We should check the value instead delegate the behavior to the result SQL-> MSDN: If count is less than or equal to zero, source is not enumerated and an empty IEnumerable<T> is returned. + takeRoot = TreeBuilder.Take(toTake); + hqlQuery.AddChild(takeRoot); + } + } + + private void ExecuteAddSkipClause(HqlExpression toSkip) + { + if (toSkip == null) + { + return; + } + // We should check the value instead delegate the behavior to the result SQL-> MSDN: If count is less than or equal to zero, all elements of source are yielded. + HqlQuery hqlQuery = root.NodesPreOrder.OfType<HqlQuery>().First(); + HqlTreeNode skipRoot = hqlQuery.Children.FirstOrDefault(n => n is HqlSkip); + if (skipRoot == null) + { + skipRoot = TreeBuilder.Skip(toSkip); + hqlQuery.AddChild(skipRoot); + } + } + + public void AddWhereClause(HqlBooleanExpression where) { - var currentWhere = Root.NodesPreOrder.Where(n => n is HqlWhere).FirstOrDefault(); + var currentWhere = root.NodesPreOrder.Where(n => n is HqlWhere).FirstOrDefault(); if (currentWhere == null) { currentWhere = TreeBuilder.Where(where); - Root.As<HqlQuery>().AddChild(currentWhere); + root.As<HqlQuery>().AddChild(currentWhere); } else { @@ -109,16 +173,15 @@ private void DetectOuterExists() { - if (Root is HqlExists) - { - Root = Root.Children.First(); + if (root is HqlExists) + { + AddTakeClause(TreeBuilder.Constant(1)); + root = Root.Children.First(); - _additionalCriteria.Add((q, p) => q.SetMaxResults(1)); + Expression<Func<IEnumerable<object>, bool>> x = l => l.Any(); - Expression<Func<IEnumerable<object>, bool>> x = l => l.Any(); - - _listTransformers.Add(x); - } + _listTransformers.Add(x); + } } @@ -139,7 +202,7 @@ public void SetRoot(HqlTreeNode newRoot) { - Root = newRoot; + root = newRoot; } } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessFirst.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessFirst.cs 2011-05-23 12:28:49 UTC (rev 5859) +++ trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessFirst.cs 2011-05-23 12:59:32 UTC (rev 5860) @@ -13,7 +13,7 @@ AddClientSideEval(firstMethod, queryModelVisitor, tree); - tree.AddAdditionalCriteria((q, p) => q.SetMaxResults(1)); + tree.AddTakeClause(tree.TreeBuilder.Constant(1)); } } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessSkip.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessSkip.cs 2011-05-23 12:28:49 UTC (rev 5859) +++ trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessSkip.cs 2011-05-23 12:59:32 UTC (rev 5860) @@ -1,22 +1,29 @@ using System.Linq.Expressions; +using NHibernate.Engine.Query; using Remotion.Linq.Clauses.ResultOperators; namespace NHibernate.Linq.Visitors.ResultOperatorProcessors { - public class ProcessSkip : IResultOperatorProcessor<SkipResultOperator> - { - public void Process(SkipResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) - { - NamedParameter parameterName; + public class ProcessSkip : IResultOperatorProcessor<SkipResultOperator> + { + #region IResultOperatorProcessor<SkipResultOperator> Members - if (queryModelVisitor.VisitorParameters.ConstantToParameterMap.TryGetValue(resultOperator.Count as ConstantExpression, out parameterName)) - { - tree.AddAdditionalCriteria((q, p) => q.SetFirstResult((int)p[parameterName.Name].First)); - } - else - { - tree.AddAdditionalCriteria((q, p) => q.SetFirstResult(resultOperator.GetConstantCount())); - } - } - } + public void Process(SkipResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) + { + VisitorParameters parameters = queryModelVisitor.VisitorParameters; + NamedParameter namedParameter; + + if (parameters.ConstantToParameterMap.TryGetValue(resultOperator.Count as ConstantExpression, out namedParameter)) + { + parameters.RequiredHqlParameters.Add(new NamedParameterDescriptor(namedParameter.Name, null, new[] {parameters.RequiredHqlParameters.Count + 1}, false)); + tree.AddSkipClause(tree.TreeBuilder.Parameter(namedParameter.Name)); + } + else + { + tree.AddSkipClause(tree.TreeBuilder.Constant(resultOperator.GetConstantCount())); + } + } + + #endregion + } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessTake.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessTake.cs 2011-05-23 12:28:49 UTC (rev 5859) +++ trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessTake.cs 2011-05-23 12:59:32 UTC (rev 5860) @@ -1,24 +1,29 @@ using System.Linq.Expressions; +using NHibernate.Engine.Query; using Remotion.Linq.Clauses.ResultOperators; namespace NHibernate.Linq.Visitors.ResultOperatorProcessors { - public class ProcessTake : IResultOperatorProcessor<TakeResultOperator> - { - public void Process(TakeResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) - { - NamedParameter parameterName; + public class ProcessTake : IResultOperatorProcessor<TakeResultOperator> + { + #region IResultOperatorProcessor<TakeResultOperator> Members - // TODO - very similar to ProcessSkip, plus want to investigate the scenario in the "else" - // clause to see if it is valid - if (queryModelVisitor.VisitorParameters.ConstantToParameterMap.TryGetValue(resultOperator.Count as ConstantExpression, out parameterName)) - { - tree.AddAdditionalCriteria((q, p) => q.SetMaxResults((int)p[parameterName.Name].First)); - } - else - { - tree.AddAdditionalCriteria((q, p) => q.SetMaxResults(resultOperator.GetConstantCount())); - } - } - } + public void Process(TakeResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) + { + VisitorParameters parameters = queryModelVisitor.VisitorParameters; + NamedParameter namedParameter; + + if (parameters.ConstantToParameterMap.TryGetValue(resultOperator.Count as ConstantExpression, out namedParameter)) + { + parameters.RequiredHqlParameters.Add(new NamedParameterDescriptor(namedParameter.Name, null, new[] {parameters.RequiredHqlParameters.Count + 1}, false)); + tree.AddTakeClause(tree.TreeBuilder.Parameter(namedParameter.Name)); + } + else + { + tree.AddTakeClause(tree.TreeBuilder.Constant(resultOperator.GetConstantCount())); + } + } + + #endregion + } } \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-05-23 12:28:55
|
Revision: 5859 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5859&view=rev Author: fabiomaulo Date: 2011-05-23 12:28:49 +0000 (Mon, 23 May 2011) Log Message: ----------- First approx to use BackTrack for all parameters kind (at least for HQL) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/SqlGenerator.cs trunk/nhibernate/src/NHibernate/Param/AbstractExplicitParameterSpecification.cs trunk/nhibernate/src/NHibernate/Param/AggregatedIndexCollectionSelectorParameterSpecifications.cs trunk/nhibernate/src/NHibernate/Param/CollectionFilterKeyParameterSpecification.cs trunk/nhibernate/src/NHibernate/Param/DynamicFilterParameterSpecification.cs trunk/nhibernate/src/NHibernate/Param/IParameterSpecification.cs trunk/nhibernate/src/NHibernate/Param/NamedParameterSpecification.cs trunk/nhibernate/src/NHibernate/Param/ParameterTranslationsImpl.cs trunk/nhibernate/src/NHibernate/Param/PositionalParameterSpecification.cs trunk/nhibernate/src/NHibernate/Param/VersionTypeSeedParameterSpecification.cs Modified: trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs 2011-05-23 11:30:57 UTC (rev 5858) +++ trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs 2011-05-23 12:28:49 UTC (rev 5859) @@ -567,12 +567,12 @@ return ConvertITypesToSqlTypes(paramTypeList, factory, totalSpan); } - private int[] GetEffectiveNamedParameterLocations(IList<Parameter> sqlParameters, string name) + private int[] GetEffectiveNamedParameterLocations(IList<Parameter> sqlParameters, object backTrackId) { var locations = new List<int>(5); for (int i = 0; i < sqlParameters.Count; i++) { - if(name.Equals(sqlParameters[i].BackTrack)) + if (backTrackId.Equals(sqlParameters[i].BackTrack)) { locations.Add(i); } Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/SqlGenerator.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/SqlGenerator.cs 2011-05-23 11:30:57 UTC (rev 5858) +++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/SqlGenerator.cs 2011-05-23 12:28:49 UTC (rev 5859) @@ -132,17 +132,9 @@ var parameterNode= n as ParameterNode; if (parameterNode != null) { - var namedParameterSpecification = parameterNode.HqlParameterSpecification as NamedParameterSpecification; - if(namedParameterSpecification != null) - { - var parameter = Parameter.Placeholder; - parameter.BackTrack = namedParameterSpecification.Name; - writer.PushParameter(parameter); - } - else - { - ParameterOut(); - } + var parameter = Parameter.Placeholder; + parameter.BackTrack = parameterNode.HqlParameterSpecification.IdForBackTrack; + writer.PushParameter(parameter); } else if (n is SqlNode) { @@ -365,12 +357,12 @@ if(queryWriter.SkipParameter != null) { skipParameter = Parameter.Placeholder; - skipParameter.BackTrack = queryWriter.SkipParameter.Name; + skipParameter.BackTrack = queryWriter.SkipParameter.IdForBackTrack; } if (queryWriter.TakeParameter != null) { takeParameter = Parameter.Placeholder; - takeParameter.BackTrack = queryWriter.TakeParameter.Name; + takeParameter.BackTrack = queryWriter.TakeParameter.IdForBackTrack; } sqlString = dialect.GetLimitString(sqlString, skipIsParameter ? 1 : queryWriter.Skip ?? 0, queryWriter.Take ?? int.MaxValue, skipParameter, takeParameter); @@ -383,7 +375,7 @@ var pnode = node as ParameterNode; if (pnode != null) { - queryWriter.SkipParameter = (NamedParameterSpecification) pnode.HqlParameterSpecification; + queryWriter.SkipParameter = pnode.HqlParameterSpecification; collectedParameters.Add(pnode.HqlParameterSpecification); return; } @@ -396,7 +388,7 @@ var pnode = node as ParameterNode; if (pnode != null) { - queryWriter.TakeParameter = (NamedParameterSpecification)pnode.HqlParameterSpecification; + queryWriter.TakeParameter = pnode.HqlParameterSpecification; collectedParameters.Add(pnode.HqlParameterSpecification); return; } @@ -458,8 +450,8 @@ { private readonly SqlStringBuilder builder = new SqlStringBuilder(); - public NamedParameterSpecification TakeParameter { get; set; } - public NamedParameterSpecification SkipParameter { get; set; } + public IParameterSpecification TakeParameter { get; set; } + public IParameterSpecification SkipParameter { get; set; } public int? Skip { get; set; } public int? Take { get; set; } Modified: trunk/nhibernate/src/NHibernate/Param/AbstractExplicitParameterSpecification.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Param/AbstractExplicitParameterSpecification.cs 2011-05-23 11:30:57 UTC (rev 5858) +++ trunk/nhibernate/src/NHibernate/Param/AbstractExplicitParameterSpecification.cs 2011-05-23 12:28:49 UTC (rev 5859) @@ -37,6 +37,7 @@ } public abstract string RenderDisplayInfo(); + public abstract object IdForBackTrack { get; } public abstract int Bind(IDbCommand statement, QueryParameters qp, ISessionImplementor session, int position); } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Param/AggregatedIndexCollectionSelectorParameterSpecifications.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Param/AggregatedIndexCollectionSelectorParameterSpecifications.cs 2011-05-23 11:30:57 UTC (rev 5858) +++ trunk/nhibernate/src/NHibernate/Param/AggregatedIndexCollectionSelectorParameterSpecifications.cs 2011-05-23 12:28:49 UTC (rev 5859) @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Data; using System.Text; using NHibernate.Engine; @@ -9,7 +10,7 @@ public class AggregatedIndexCollectionSelectorParameterSpecifications : IParameterSpecification { private readonly IList<IParameterSpecification> _paramSpecs; - + private readonly Guid idForBackTrack = Guid.NewGuid(); public AggregatedIndexCollectionSelectorParameterSpecifications(IList<IParameterSpecification> paramSpecs) { _paramSpecs = paramSpecs; } @@ -37,6 +38,11 @@ return "index-selector [" + CollectDisplayInfo() + "]" ; } + public object IdForBackTrack + { + get { return idForBackTrack; } + } + private string CollectDisplayInfo() { StringBuilder buffer = new StringBuilder(); Modified: trunk/nhibernate/src/NHibernate/Param/CollectionFilterKeyParameterSpecification.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Param/CollectionFilterKeyParameterSpecification.cs 2011-05-23 11:30:57 UTC (rev 5858) +++ trunk/nhibernate/src/NHibernate/Param/CollectionFilterKeyParameterSpecification.cs 2011-05-23 12:28:49 UTC (rev 5859) @@ -9,7 +9,8 @@ { private readonly string _collectionRole; private readonly IType _keyType; - private int _queryParameterPosition; + private readonly int _queryParameterPosition; + private readonly string idForBackTrack; /// <summary> /// Creates a specialized collection-filter collection-key parameter spec. @@ -22,6 +23,7 @@ _collectionRole = collectionRole; _keyType = keyType; _queryParameterPosition = queryParameterPosition; + idForBackTrack = "nhcollkey_" + _collectionRole + "nh"; } public int Bind( @@ -45,5 +47,10 @@ { return "collection-filter-key=" + _collectionRole; } + + public object IdForBackTrack + { + get { return idForBackTrack; } + } } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Param/DynamicFilterParameterSpecification.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Param/DynamicFilterParameterSpecification.cs 2011-05-23 11:30:57 UTC (rev 5858) +++ trunk/nhibernate/src/NHibernate/Param/DynamicFilterParameterSpecification.cs 2011-05-23 12:28:49 UTC (rev 5859) @@ -11,7 +11,7 @@ private readonly string _filterName; private readonly string _parameterName; private readonly IType _definedParameterType; - + private readonly string idForBackTrack; /// <summary> /// Constructs a parameter specification for a particular filter parameter. /// </summary> @@ -26,6 +26,7 @@ _filterName = filterName; _parameterName = parameterName; _definedParameterType = definedParameterType; + idForBackTrack = "nhdf_" + _filterName + "_" + _parameterName + "_nhdf"; } public int Bind(IDbCommand statement, QueryParameters qp, ISessionImplementor session, int start) @@ -63,5 +64,10 @@ { return "dynamic-filter={filterName=" + _filterName + ",paramName=" + _parameterName + "}"; } + + public object IdForBackTrack + { + get { return idForBackTrack; } + } } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Param/IParameterSpecification.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Param/IParameterSpecification.cs 2011-05-23 11:30:57 UTC (rev 5858) +++ trunk/nhibernate/src/NHibernate/Param/IParameterSpecification.cs 2011-05-23 12:28:49 UTC (rev 5859) @@ -33,5 +33,13 @@ /// </summary> /// <returns>The displayable info</returns> string RenderDisplayInfo(); + + /// <summary> + /// An object to unique identify this parameter inside an <see cref="NHibernate.SqlCommand.SqlString"/>. + /// </summary> + /// <remarks> + /// The <see cref="IdForBackTrack"/> is supposed to be unique in the context of a query. + /// </remarks> + object IdForBackTrack { get; } } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Param/NamedParameterSpecification.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Param/NamedParameterSpecification.cs 2011-05-23 11:30:57 UTC (rev 5858) +++ trunk/nhibernate/src/NHibernate/Param/NamedParameterSpecification.cs 2011-05-23 12:28:49 UTC (rev 5859) @@ -45,6 +45,11 @@ return ExpectedType != null ? string.Format(format, _name, ExpectedType) : string.Format(format, _name, "Unknow"); } + public override object IdForBackTrack + { + get { return _name; } + } + /// <summary> /// Getter for property 'name'. /// </summary> Modified: trunk/nhibernate/src/NHibernate/Param/ParameterTranslationsImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Param/ParameterTranslationsImpl.cs 2011-05-23 11:30:57 UTC (rev 5858) +++ trunk/nhibernate/src/NHibernate/Param/ParameterTranslationsImpl.cs 2011-05-23 12:28:49 UTC (rev 5859) @@ -124,19 +124,16 @@ [Serializable] public class ParameterInfo { - private readonly int[] originalLocation; private readonly int[] sqlLocations; public ParameterInfo(int[] sqlPositions, IType expectedType) { - originalLocation = (int[])sqlPositions.Clone(); sqlLocations = sqlPositions; ExpectedType = expectedType; } public ParameterInfo(int sqlPosition, IType expectedType) { - originalLocation = new[] { sqlPosition }; sqlLocations = new[] { sqlPosition }; ExpectedType = expectedType; } Modified: trunk/nhibernate/src/NHibernate/Param/PositionalParameterSpecification.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Param/PositionalParameterSpecification.cs 2011-05-23 11:30:57 UTC (rev 5858) +++ trunk/nhibernate/src/NHibernate/Param/PositionalParameterSpecification.cs 2011-05-23 12:28:49 UTC (rev 5859) @@ -12,7 +12,7 @@ public class PositionalParameterSpecification : AbstractExplicitParameterSpecification { private readonly int _hqlPosition; - + private readonly string idForBackTrack; /// <summary> /// Constructs a position/ordinal parameter bind specification. /// </summary> @@ -22,6 +22,7 @@ public PositionalParameterSpecification(int sourceLine, int sourceColumn, int hqlPosition) : base(sourceLine, sourceColumn) { _hqlPosition = hqlPosition; + idForBackTrack = "nh" + hqlPosition + "nh"; //<= I don't think the user have the insane idea to use this name a named-parameter name } /// <summary> @@ -46,6 +47,11 @@ return "ordinal=" + _hqlPosition + ", expectedType=" + ExpectedType; } + public override object IdForBackTrack + { + get { return idForBackTrack; } + } + /// <summary> /// Getter for property 'hqlPosition'. /// </summary> Modified: trunk/nhibernate/src/NHibernate/Param/VersionTypeSeedParameterSpecification.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Param/VersionTypeSeedParameterSpecification.cs 2011-05-23 11:30:57 UTC (rev 5858) +++ trunk/nhibernate/src/NHibernate/Param/VersionTypeSeedParameterSpecification.cs 2011-05-23 12:28:49 UTC (rev 5859) @@ -1,3 +1,4 @@ +using System; using System.Data; using NHibernate.Engine; using NHibernate.Type; @@ -32,5 +33,10 @@ { return "version-seed, type=" + type; } + + public object IdForBackTrack + { + get { return "nhv_seed_nh"; } + } } } \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-05-23 11:31:03
|
Revision: 5858 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5858&view=rev Author: fabiomaulo Date: 2011-05-23 11:30:57 +0000 (Mon, 23 May 2011) Log Message: ----------- Minor (commented, reformatted) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/SqlCommand/Parameter.cs Modified: trunk/nhibernate/src/NHibernate/SqlCommand/Parameter.cs =================================================================== --- trunk/nhibernate/src/NHibernate/SqlCommand/Parameter.cs 2011-05-22 22:44:45 UTC (rev 5857) +++ trunk/nhibernate/src/NHibernate/SqlCommand/Parameter.cs 2011-05-23 11:30:57 UTC (rev 5858) @@ -10,40 +10,48 @@ [Serializable] public class Parameter { + private Parameter() {} + /// <summary> - /// We need to know what the position of the parameter was in a query - /// before we rearranged the query. + /// We need to know what the position of the parameter was in a query + /// before we rearranged the query. /// This is the ADO parameter position that this SqlString parameter is /// bound to. The SqlString can be safely rearranged once this is set. /// </summary> - public int? ParameterPosition; + public int? ParameterPosition; // NH TODO: remove this that is basically used by Criteria and use the more generic BackTrack + /// <summary> + /// Unique identifier of a parameter to be tracked back by its generator. + /// </summary> + /// <remarks> + /// We have various query-systems. Each one, at the end, give us a <see cref="SqlString"/>. + /// At the same time we have various bad-guys playing the game (hql function implementations, the dialect...). + /// A bad guy can rearrange a <see cref="SqlString"/> and the query-system can easly lost organization/sequence of parameters. + /// Using the <see cref="BackTrack"/> the query-system can easily find where are its parameters. + /// </remarks> public object BackTrack { get; set; } - /// <summary> - /// Used as a placeholder when parsing HQL or SQL queries. - /// </summary> - public static Parameter Placeholder - { - get { return new Parameter(); } - } /// <summary> + /// Used as a placeholder when parsing HQL or SQL queries. + /// </summary> + public static Parameter Placeholder + { + get { return new Parameter(); } + } + + /// <summary> /// Create a parameter with the specified position /// </summary> public static Parameter WithIndex(int position) { - return new Parameter() { ParameterPosition = position }; + return new Parameter {ParameterPosition = position}; } public Parameter Clone() { - return new Parameter { BackTrack = this.BackTrack }; + return new Parameter {BackTrack = BackTrack}; } - private Parameter() - { - } - /// <summary> /// Generates an array of parameters for the given <see cref="SqlType">SqlTypes</see>. /// </summary> @@ -51,7 +59,7 @@ /// <returns>An array of <see cref="Parameter"/> objects</returns> public static Parameter[] GenerateParameters(int count) { - Parameter[] result = new Parameter[count]; + var result = new Parameter[count]; for (int i = 0; i < count; i++) { result[i] = Placeholder; @@ -70,7 +78,7 @@ public override bool Equals(object obj) { // All parameters are equal, this check that - // the other one is not null and a parameter + // the other one is not null and a parameter return obj is Parameter; } @@ -78,7 +86,7 @@ /// Gets a hash code for the parameter. /// </summary> /// <returns> - /// An <see cref="Int32"/> value for the hash code. + /// An <see cref="int"/> value for the hash code. /// </returns> public override int GetHashCode() { @@ -91,34 +99,34 @@ return StringHelper.SqlParameter; } - public static bool operator ==(Parameter a, Parameter b) - { - return Equals(a, b); - } + public static bool operator ==(Parameter a, Parameter b) + { + return Equals(a, b); + } - public static bool operator ==(object a, Parameter b) - { - return Equals(a, b); - } + public static bool operator ==(object a, Parameter b) + { + return Equals(a, b); + } - public static bool operator ==(Parameter a, object b) - { - return Equals(a, b); - } + public static bool operator ==(Parameter a, object b) + { + return Equals(a, b); + } - public static bool operator !=(Parameter a, object b) - { - return !(a == b); - } + public static bool operator !=(Parameter a, object b) + { + return !(a == b); + } - public static bool operator !=(object a, Parameter b) - { - return !(a == b); - } + public static bool operator !=(object a, Parameter b) + { + return !(a == b); + } - public static bool operator !=(Parameter a, Parameter b) - { - return !(a == b); - } + public static bool operator !=(Parameter a, Parameter b) + { + return !(a == b); + } } -} +} \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-05-22 22:44:52
|
Revision: 5857 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5857&view=rev Author: fabiomaulo Date: 2011-05-22 22:44:45 +0000 (Sun, 22 May 2011) Log Message: ----------- Fix NH-2702 (ready for refactoring but after fix all others related issues) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/SqlGenerator.cs trunk/nhibernate/src/NHibernate/SqlCommand/Parameter.cs trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs trunk/nhibernate/src/NHibernate.Test/Hql/Ast/LimitClauseFixture.cs Modified: trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs 2011-05-22 22:43:01 UTC (rev 5856) +++ trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs 2011-05-22 22:44:45 UTC (rev 5857) @@ -1680,6 +1680,17 @@ get { return false; } } + public virtual SqlString GetLimitString(SqlString querySqlString, int offset, int limit, Parameter offsetParameter, Parameter limitParameter) + { + if (!SupportsVariableLimit) + return GetLimitString(querySqlString, offset, limit); + + if ((offsetParameter == null) && (limitParameter == null)) + return GetLimitString(querySqlString, offset, limit); + + throw new NotSupportedException("Override to support limits passed as parameters"); + } + /// <summary> /// Add a <c>LIMIT</c> clause to the given SQL <c>SELECT</c> /// when the dialect supports variable limits (i.e. parameters for the limit constraints) @@ -1687,8 +1698,8 @@ /// <param name="querySqlString">The <see cref="SqlString"/> to base the limit query off.</param> /// <param name="offset">Offset of the first row to be returned by the query (zero-based)</param> /// <param name="limit">Maximum number of rows to be returned by the query</param> - /// <param name="offsetParameterIndex">Optionally, the Offset parameter index</param> - /// <param name="limitParameterIndex">Optionally, the Limit parameter index</param> + /// <param name="offsetParameterIndex">Optionally, the Offset parameter index in the sql</param> + /// <param name="limitParameterIndex">Optionally, the Limit parameter index in the sql</param> /// <returns>A new <see cref="SqlString"/> that contains the <c>LIMIT</c> clause.</returns> public virtual SqlString GetLimitString(SqlString querySqlString, int offset, int limit, int? offsetParameterIndex, int? limitParameterIndex) { Modified: trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs 2011-05-22 22:43:01 UTC (rev 5856) +++ trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs 2011-05-22 22:44:45 UTC (rev 5857) @@ -42,23 +42,36 @@ /// <param name="querySqlString">The <see cref="SqlString"/> to base the limit query off.</param> /// <param name="offset">Offset of the first row to be returned by the query (zero-based)</param> /// <param name="limit">Maximum number of rows to be returned by the query</param> - /// <param name="offsetParameterIndex">Optionally, the Offset parameter index</param> - /// <param name="limitParameterIndex">Optionally, the Limit parameter index</param> + /// <param name="offsetParameterIndex">Optionally, the Offset parameter index in the sql</param> + /// <param name="limitParameterIndex">Optionally, the Limit parameter index in the sql</param> /// <returns>A new <see cref="SqlString"/> with the <c>LIMIT</c> clause applied.</returns> /// <remarks> /// Note that we need to explicitly specify the columns, because we need to be able to use them in a paged subselect [NH-1155] /// </remarks> public override SqlString GetLimitString(SqlString querySqlString, int offset, int limit, int? offsetParameterIndex, int? limitParameterIndex) { - object limitObject = limitParameterIndex == null ? Parameter.Placeholder : Parameter.WithIndex(limitParameterIndex.Value); - object offsetObject = null; - if (offset != 0) - offsetObject = offsetParameterIndex == null ? Parameter.Placeholder : Parameter.WithIndex(offsetParameterIndex.Value); - return GetLimitString(querySqlString, offsetObject, limitObject); + object limitObject = limitParameterIndex == null ? (object) new SqlString(limit.ToString()) : Parameter.WithIndex(limitParameterIndex.Value); + object offsetObject = null; + if (offset != 0) + { + offsetObject = offsetParameterIndex == null ? (object) new SqlString(offset.ToString()) : Parameter.WithIndex(offsetParameterIndex.Value); + } + return GetLimitString(querySqlString, offsetObject, limitObject); } - private SqlString GetLimitString(SqlString querySqlString, object offset, object limit) + public override SqlString GetLimitString(SqlString querySqlString, int offset, int limit, Parameter offsetParameter, Parameter limitParameter) { + object limitObject = limitParameter ?? (object) new SqlString(limit.ToString()); + object offsetObject = null; + if (offset != 0) + { + offsetObject = offsetParameter ?? (object) new SqlString(offset.ToString()); + } + return GetLimitString(querySqlString, offsetObject, limitObject); + } + + private SqlString GetLimitString(SqlString querySqlString, object offset, object limit) + { if (offset == null && limit == null) return querySqlString; Modified: trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs 2011-05-22 22:43:01 UTC (rev 5856) +++ trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs 2011-05-22 22:44:45 UTC (rev 5857) @@ -487,7 +487,7 @@ int span = typedval.Type.GetColumnSpan(factory); string name = namedParameter.Key; - int[] locs = getNamedParameterLocations(name); + int[] locs = GetEffectiveNamedParameterLocations(sqlParameters, name) ?? getNamedParameterLocations(name); for (int i = 0; i < locs.Length; i++) { int location = locs[i]; @@ -567,6 +567,23 @@ return ConvertITypesToSqlTypes(paramTypeList, factory, totalSpan); } + private int[] GetEffectiveNamedParameterLocations(IList<Parameter> sqlParameters, string name) + { + var locations = new List<int>(5); + for (int i = 0; i < sqlParameters.Count; i++) + { + if(name.Equals(sqlParameters[i].BackTrack)) + { + locations.Add(i); + } + } + if(locations.Count == 0) + { + return null; + } + return locations.ToArray(); + } + public int BindParameters(IDbCommand command, int start, ISessionImplementor session) { int location = start; Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/SqlGenerator.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/SqlGenerator.cs 2011-05-22 22:43:01 UTC (rev 5856) +++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/SqlGenerator.cs 2011-05-22 22:44:45 UTC (rev 5857) @@ -129,9 +129,20 @@ private void Out(IASTNode n) { - if (n is ParameterNode) + var parameterNode= n as ParameterNode; + if (parameterNode != null) { - ParameterOut(); + var namedParameterSpecification = parameterNode.HqlParameterSpecification as NamedParameterSpecification; + if(namedParameterSpecification != null) + { + var parameter = Parameter.Placeholder; + parameter.BackTrack = namedParameterSpecification.Name; + writer.PushParameter(parameter); + } + else + { + ParameterOut(); + } } else if (n is SqlNode) { @@ -142,9 +153,9 @@ Out(n.Text); } - if (n is ParameterNode) + if (parameterNode != null) { - collectedParameters.Add(((ParameterNode) n).HqlParameterSpecification); + collectedParameters.Add(parameterNode.HqlParameterSpecification); } else if (n is IParameterContainer) { @@ -318,35 +329,78 @@ private void EndQuery() { - var queryWriter = ((QueryWriter) writer); - SqlString sqlString = queryWriter.ToSqlString(); + SqlString sqlString = GetSqlStringWithLimitsIfNeeded((QueryWriter) writer); - if (queryWriter.Take.HasValue || queryWriter.Skip.HasValue) - { - sqlString = sessionFactory.Dialect.GetLimitString(sqlString, queryWriter.Skip ?? 0, queryWriter.Take ?? int.MaxValue); - } - writer = outputStack[0]; outputStack.RemoveAt(0); Out(sqlString); } + private SqlString GetSqlStringWithLimitsIfNeeded(QueryWriter queryWriter) + { + SqlString sqlString = queryWriter.ToSqlString(); + var skipIsParameter = queryWriter.SkipParameter != null; + var takeIsParameter = queryWriter.TakeParameter != null; + var hqlQueryHasLimits = queryWriter.Take.HasValue || queryWriter.Skip.HasValue || skipIsParameter || takeIsParameter; + if (!hqlQueryHasLimits) + { + return sqlString; + } + + var dialect = sessionFactory.Dialect; + + var hqlQueryHasFixedLimits = (queryWriter.Take.HasValue || queryWriter.Skip.HasValue) && !skipIsParameter && !takeIsParameter; + if(hqlQueryHasFixedLimits) + { + return dialect.GetLimitString(sqlString, queryWriter.Skip ?? 0, queryWriter.Take ?? int.MaxValue); + } + // Skip-Take in HQL should be supported just for Dialect supporting variable limits at least when users use parameters for skip-take. + if (!dialect.SupportsVariableLimit && (skipIsParameter || takeIsParameter)) + { + throw new NotSupportedException("The dialect " + dialect.GetType().FullName + " does not supports variable limits"); + } + // At this point at least one of the two limits is a parameter and that parameter should be of IExplicitValueParameterSpecification + Parameter skipParameter = null; + Parameter takeParameter = null; + if(queryWriter.SkipParameter != null) + { + skipParameter = Parameter.Placeholder; + skipParameter.BackTrack = queryWriter.SkipParameter.Name; + } + if (queryWriter.TakeParameter != null) + { + takeParameter = Parameter.Placeholder; + takeParameter.BackTrack = queryWriter.TakeParameter.Name; + } + + sqlString = dialect.GetLimitString(sqlString, skipIsParameter ? 1 : queryWriter.Skip ?? 0, queryWriter.Take ?? int.MaxValue, skipParameter, takeParameter); + return sqlString; + } + private void Skip(IASTNode node) { - if (node is ParameterNode) + var queryWriter = (QueryWriter)writer; + var pnode = node as ParameterNode; + if (pnode != null) { - throw new NotSupportedException("Parameter limits is not supported yet."); + queryWriter.SkipParameter = (NamedParameterSpecification) pnode.HqlParameterSpecification; + collectedParameters.Add(pnode.HqlParameterSpecification); + return; } - ((QueryWriter) writer).Skip = Convert.ToInt32(node.Text); + queryWriter.Skip = Convert.ToInt32(node.Text); } private void Take(IASTNode node) { - if (node is ParameterNode) + var queryWriter = (QueryWriter)writer; + var pnode = node as ParameterNode; + if (pnode != null) { - throw new NotSupportedException("Parameter limits is not supported yet."); + queryWriter.TakeParameter = (NamedParameterSpecification)pnode.HqlParameterSpecification; + collectedParameters.Add(pnode.HqlParameterSpecification); + return; } - ((QueryWriter) writer).Take = Convert.ToInt32(node.Text); + queryWriter.Take = Convert.ToInt32(node.Text); } #region Nested type: DefaultWriter @@ -380,6 +434,11 @@ generator.GetStringBuilder().AddParameter(); } + public void PushParameter(Parameter parameter) + { + generator.GetStringBuilder().Add(parameter); + } + public void CommaBetweenParameters(String comma) { generator.GetStringBuilder().Add(comma); @@ -399,8 +458,13 @@ { private readonly SqlStringBuilder builder = new SqlStringBuilder(); - #region ISqlWriter Members + public NamedParameterSpecification TakeParameter { get; set; } + public NamedParameterSpecification SkipParameter { get; set; } + public int? Skip { get; set; } + public int? Take { get; set; } + #region ISqlWriter Members + public void Clause(String clause) { builder.Add(clause); @@ -416,7 +480,12 @@ builder.AddParameter(); } - public void CommaBetweenParameters(String comma) + public void PushParameter(Parameter parameter) + { + builder.Add(parameter); + } + + public void CommaBetweenParameters(String comma) { builder.Add(comma); } @@ -426,8 +495,6 @@ return builder.ToSqlString(); } - public int? Skip { get; set; } - public int? Take { get; set; } #endregion } @@ -489,6 +556,18 @@ } } + public void PushParameter(Parameter parameter) + { + if (argInd == args.Count) + { + args.Add(new SqlString(parameter)); + } + else + { + args[argInd] = args[argInd].Append(new SqlString(parameter)); + } + } + public void CommaBetweenParameters(string comma) { ++argInd; @@ -509,6 +588,7 @@ void Clause(string clause); void Clause(SqlString clause); void Parameter(); + void PushParameter(Parameter parameter); /** * todo remove this hack * The parameter is either ", " or " , ". This is needed to pass sql generating tests as the old Modified: trunk/nhibernate/src/NHibernate/SqlCommand/Parameter.cs =================================================================== --- trunk/nhibernate/src/NHibernate/SqlCommand/Parameter.cs 2011-05-22 22:43:01 UTC (rev 5856) +++ trunk/nhibernate/src/NHibernate/SqlCommand/Parameter.cs 2011-05-22 22:44:45 UTC (rev 5857) @@ -18,6 +18,7 @@ /// </summary> public int? ParameterPosition; + public object BackTrack { get; set; } /// <summary> /// Used as a placeholder when parsing HQL or SQL queries. /// </summary> @@ -34,6 +35,11 @@ return new Parameter() { ParameterPosition = position }; } + public Parameter Clone() + { + return new Parameter { BackTrack = this.BackTrack }; + } + private Parameter() { } Modified: trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs =================================================================== --- trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs 2011-05-22 22:43:01 UTC (rev 5856) +++ trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs 2011-05-22 22:44:45 UTC (rev 5857) @@ -580,10 +580,11 @@ for (int i=0; i<clone.sqlParts.Length; i++) { - if (clone.sqlParts[i] is Parameter) + var parameter = clone.sqlParts[i] as Parameter; + if (parameter != null) { - var originalParameter = (Parameter)clone.sqlParts[i]; - var copyParameter = SqlCommand.Parameter.Placeholder; + var originalParameter = parameter; + var copyParameter = originalParameter.Clone(); if (originalParameter.ParameterPosition < 0) { Modified: trunk/nhibernate/src/NHibernate.Test/Hql/Ast/LimitClauseFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Hql/Ast/LimitClauseFixture.cs 2011-05-22 22:43:01 UTC (rev 5856) +++ trunk/nhibernate/src/NHibernate.Test/Hql/Ast/LimitClauseFixture.cs 2011-05-22 22:44:45 UTC (rev 5857) @@ -1,155 +1,177 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using System.Linq; using NHibernate.Hql.Ast.ANTLR; using NUnit.Framework; +using SharpTestsEx; namespace NHibernate.Test.Hql.Ast { - [TestFixture] - public class LimitClauseFixture : BaseFixture - { - protected override void OnSetUp() - { - ISession session = OpenSession(); - ITransaction txn = session.BeginTransaction(); + [TestFixture] + public class LimitClauseFixture : BaseFixture + { + protected override bool AppliesTo(Dialect.Dialect dialect) + { + return dialect.SupportsVariableLimit; + } - var mother = new Human { BodyWeight = 10, Description = "mother" }; - var father = new Human { BodyWeight = 15, Description = "father" }; - var child1 = new Human { BodyWeight = 5, Description = "child1" }; - var child2 = new Human { BodyWeight = 6, Description = "child2" }; - var friend = new Human { BodyWeight = 20, Description = "friend" }; + protected override void OnSetUp() + { + ISession session = OpenSession(); + ITransaction txn = session.BeginTransaction(); - session.Save(mother); - session.Save(father); - session.Save(child1); - session.Save(child2); - session.Save(friend); + var mother = new Human {BodyWeight = 10, Description = "mother"}; + var father = new Human {BodyWeight = 15, Description = "father"}; + var child1 = new Human {BodyWeight = 5, Description = "child1"}; + var child2 = new Human {BodyWeight = 6, Description = "child2"}; + var friend = new Human {BodyWeight = 20, Description = "friend"}; - txn.Commit(); - session.Close(); - } + session.Save(mother); + session.Save(father); + session.Save(child1); + session.Save(child2); + session.Save(friend); - protected override void OnTearDown() - { - ISession session = OpenSession(); - ITransaction txn = session.BeginTransaction(); + txn.Commit(); + session.Close(); + } + + protected override void OnTearDown() + { + ISession session = OpenSession(); + ITransaction txn = session.BeginTransaction(); session.Delete("from Animal"); - txn.Commit(); - session.Close(); - } + txn.Commit(); + session.Close(); + } - [Test] - public void None() - { - ISession s = OpenSession(); - ITransaction txn = s.BeginTransaction(); + [Test] + public void None() + { + ISession s = OpenSession(); + ITransaction txn = s.BeginTransaction(); - var actual = s.CreateQuery("from Human h order by h.bodyWeight").List<Human>().Select(h => h.BodyWeight).ToArray(); - var expected = new[] { 5, 6, 10, 15, 20 }; - CollectionAssert.AreEqual(expected, actual); + float[] actual = s.CreateQuery("from Human h order by h.bodyWeight").List<Human>().Select(h => h.BodyWeight).ToArray(); + var expected = new[] {5, 6, 10, 15, 20}; + CollectionAssert.AreEqual(expected, actual); - txn.Commit(); - s.Close(); - } + txn.Commit(); + s.Close(); + } - [Test] - public void Skip() - { - ISession s = OpenSession(); - ITransaction txn = s.BeginTransaction(); + [Test] + public void Skip() + { + ISession s = OpenSession(); + ITransaction txn = s.BeginTransaction(); - var actual = s.CreateQuery("from Human h where h.bodyWeight > :minW order by h.bodyWeight skip 2").SetDouble("minW", 0d).List<Human>().Select(h => h.BodyWeight).ToArray(); - var expected = new[] { 10, 15, 20 }; - CollectionAssert.AreEqual(expected, actual); + float[] actual = s.CreateQuery("from Human h where h.bodyWeight > :minW order by h.bodyWeight skip 2").SetDouble("minW", 0d).List<Human>().Select(h => h.BodyWeight).ToArray(); + var expected = new[] {10, 15, 20}; + CollectionAssert.AreEqual(expected, actual); - txn.Commit(); - s.Close(); - } + txn.Commit(); + s.Close(); + } - [Test, Ignore("Not supported yet.")] - public void SkipWithParameter() - { - ISession s = OpenSession(); - ITransaction txn = s.BeginTransaction(); + [Test] + public void SkipTake() + { + ISession s = OpenSession(); + ITransaction txn = s.BeginTransaction(); - var actual = s.CreateQuery("from Human h order by h.bodyWeight skip :jump").SetInt32("jump", 2).List<Human>().Select(h => h.BodyWeight).ToArray(); - var expected = new[] { 10, 15, 20 }; - CollectionAssert.AreEqual(expected, actual); + float[] actual = s.CreateQuery("from Human h order by h.bodyWeight skip 1 take 3").List<Human>().Select(h => h.BodyWeight).ToArray(); + var expected = new[] {6, 10, 15}; + CollectionAssert.AreEqual(expected, actual); - txn.Commit(); - s.Close(); - } + txn.Commit(); + s.Close(); + } - [Test] - public void Take() - { - ISession s = OpenSession(); - ITransaction txn = s.BeginTransaction(); + [Test] + public void SkipTakeWithParameter() + { + ISession s = OpenSession(); + ITransaction txn = s.BeginTransaction(); - var actual = s.CreateQuery("from Human h order by h.bodyWeight take 2").List<Human>().Select(h => h.BodyWeight).ToArray(); - var expected = new[] { 5, 6 }; - CollectionAssert.AreEqual(expected, actual); + float[] actual = s.CreateQuery("from Human h order by h.bodyWeight skip :pSkip take :pTake") + .SetInt32("pSkip", 1) + .SetInt32("pTake", 3).List<Human>().Select(h => h.BodyWeight).ToArray(); + var expected = new[] {6f, 10f, 15f}; + actual.Should().Have.SameSequenceAs(expected); - txn.Commit(); - s.Close(); - } + txn.Commit(); + s.Close(); + } - [Test, Ignore("Not supported yet.")] - public void TakeWithParameter() - { - ISession s = OpenSession(); - ITransaction txn = s.BeginTransaction(); + [Test] + public void SkipTakeWithParameterList() + { + ISession s = OpenSession(); + ITransaction txn = s.BeginTransaction(); - var actual = s.CreateQuery("from Human h order by h.bodyWeight take :jump").SetInt32("jump", 2).List<Human>().Select(h => h.BodyWeight).ToArray(); - var expected = new[] { 5, 6 }; - CollectionAssert.AreEqual(expected, actual); + float[] actual = s.CreateQuery("from Human h where h.bodyWeight in (:list) order by h.bodyWeight skip :pSkip take :pTake") + .SetParameterList("list", new[] {10f, 15f, 5f}) + .SetInt32("pSkip", 1) + .SetInt32("pTake", 4).List<Human>().Select(h => h.BodyWeight).ToArray(); + var expected = new[] {10f, 15f}; + actual.Should().Have.SameSequenceAs(expected); - txn.Commit(); - s.Close(); - } + txn.Commit(); + s.Close(); + } - [Test] - public void SkipTake() - { - ISession s = OpenSession(); - ITransaction txn = s.BeginTransaction(); + [Test] + public void SkipWithParameter() + { + ISession s = OpenSession(); + ITransaction txn = s.BeginTransaction(); - var actual = s.CreateQuery("from Human h order by h.bodyWeight skip 1 take 3").List<Human>().Select(h => h.BodyWeight).ToArray(); - var expected = new[] { 6, 10, 15 }; - CollectionAssert.AreEqual(expected, actual); + float[] actual = s.CreateQuery("from Human h order by h.bodyWeight skip :jump").SetInt32("jump", 2).List<Human>().Select(h => h.BodyWeight).ToArray(); + var expected = new[] {10f, 15f, 20f}; + actual.Should().Have.SameSequenceAs(expected); - txn.Commit(); - s.Close(); - } + txn.Commit(); + s.Close(); + } - [Test, Ignore("Not supported yet.")] - public void SkipTakeWithParameter() - { - ISession s = OpenSession(); - ITransaction txn = s.BeginTransaction(); + [Test] + public void Take() + { + ISession s = OpenSession(); + ITransaction txn = s.BeginTransaction(); - var actual = s.CreateQuery("from Human h order by h.bodyWeight skip :pSkip take :pTake") - .SetInt32("pSkip", 1) - .SetInt32("pTake", 3).List<Human>().Select(h => h.BodyWeight).ToArray(); - var expected = new[] { 6, 10, 15 }; - CollectionAssert.AreEqual(expected, actual); + float[] actual = s.CreateQuery("from Human h order by h.bodyWeight take 2").List<Human>().Select(h => h.BodyWeight).ToArray(); + var expected = new[] {5, 6}; + CollectionAssert.AreEqual(expected, actual); - txn.Commit(); - s.Close(); - } + txn.Commit(); + s.Close(); + } - [Test] - public void TakeSkip() - { - ISession s = OpenSession(); - ITransaction txn = s.BeginTransaction(); + [Test] + public void TakeSkip() + { + ISession s = OpenSession(); + ITransaction txn = s.BeginTransaction(); - Assert.Throws<QuerySyntaxException>(() => s.CreateQuery("from Human h order by h.bodyWeight take 1 skip 2").List<Human>(), "take should not be allowed before skip"); + Assert.Throws<QuerySyntaxException>(() => s.CreateQuery("from Human h order by h.bodyWeight take 1 skip 2").List<Human>(), "take should not be allowed before skip"); - txn.Commit(); - s.Close(); - } - } -} + txn.Commit(); + s.Close(); + } + + [Test] + public void TakeWithParameter() + { + ISession s = OpenSession(); + ITransaction txn = s.BeginTransaction(); + + float[] actual = s.CreateQuery("from Human h where h.bodyWeight > :minW order by h.bodyWeight take :jump") + .SetDouble("minW", 1d) + .SetInt32("jump", 2).List<Human>().Select(h => h.BodyWeight).ToArray(); + var expected = new[] {5, 6}; + CollectionAssert.AreEqual(expected, actual); + + txn.Commit(); + s.Close(); + } + } +} \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-05-22 22:43:07
|
Revision: 5856 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5856&view=rev Author: fabiomaulo Date: 2011-05-22 22:43:01 +0000 (Sun, 22 May 2011) Log Message: ----------- Fixed test (different local numbers format configuration) Modified Paths: -------------- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs 2011-05-22 16:34:11 UTC (rev 5855) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs 2011-05-22 22:43:01 UTC (rev 5856) @@ -611,8 +611,8 @@ .Select(p => p.Age.Sqrt()) .SingleOrDefault<object>(); - sqrtOfAge.GetType().Should().Be(typeof(double)); - string.Format("{0:0.00}", sqrtOfAge).Should().Be("9.49"); + sqrtOfAge.Should().Be.InstanceOf<double>(); + string.Format("{0:0.00}", sqrtOfAge).Should().Be((9.49).ToString()); } using (ISession s = OpenSession()) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2011-05-22 16:34:18
|
Revision: 5855 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5855&view=rev Author: ricbrown Date: 2011-05-22 16:34:11 +0000 (Sun, 22 May 2011) Log Message: ----------- NH-2683: Updated QueryOver Concat() extension to allow arbitrary parameters Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Criterion/Projections.cs trunk/nhibernate/src/NHibernate/Criterion/ProjectionsExtensions.cs trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs Modified: trunk/nhibernate/src/NHibernate/Criterion/Projections.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/Projections.cs 2011-05-22 14:58:58 UTC (rev 5854) +++ trunk/nhibernate/src/NHibernate/Criterion/Projections.cs 2011-05-22 16:34:11 UTC (rev 5855) @@ -451,5 +451,25 @@ { return Projections.Sum(ExpressionProcessor.FindMemberExpression(expression.Body)); } + + /// <summary> + /// Project SQL function concat() + /// Note: throws an exception outside of a QueryOver expression + /// </summary> + public static string Concat(params string[] strings) + { + throw new Exception("Not to be used directly - use inside QueryOver expression"); + } + + internal static IProjection ProcessConcat(MethodCallExpression methodCallExpression) + { + NewArrayExpression args = (NewArrayExpression)methodCallExpression.Arguments[0]; + IProjection[] projections = new IProjection[args.Expressions.Count]; + + for (var i=0; i<args.Expressions.Count; i++) + projections[i] = ExpressionProcessor.FindMemberProjection(args.Expressions[i]); + + return Projections.SqlFunction("concat", NHibernateUtil.String, projections); + } } } Modified: trunk/nhibernate/src/NHibernate/Criterion/ProjectionsExtensions.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/ProjectionsExtensions.cs 2011-05-22 14:58:58 UTC (rev 5854) +++ trunk/nhibernate/src/NHibernate/Criterion/ProjectionsExtensions.cs 2011-05-22 16:34:11 UTC (rev 5855) @@ -341,22 +341,6 @@ } /// <summary> - /// Project SQL function concat() - /// Note: throws an exception outside of a QueryOver expression - /// </summary> - public static string ConcatStr(this string stringProperty, string value) - { - throw new Exception("Not to be used directly - use inside QueryOver expression"); - } - - internal static IProjection ProcessConcatStr(MethodCallExpression methodCallExpression) - { - IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); - object concatWithValue = ExpressionProcessor.FindValue(methodCallExpression.Arguments[1]); - return Projections.SqlFunction("concat", NHibernateUtil.String, property, Projections.Constant(string.Empty), Projections.Constant(concatWithValue)); - } - - /// <summary> /// Project SQL function mod() /// Note: throws an exception outside of a QueryOver expression /// </summary> Modified: trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs 2011-05-22 14:58:58 UTC (rev 5854) +++ trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs 2011-05-22 16:34:11 UTC (rev 5855) @@ -109,7 +109,7 @@ RegisterCustomProjection(() => ProjectionsExtensions.CharIndex(string.Empty, string.Empty, 0), ProjectionsExtensions.ProcessCharIndex); RegisterCustomProjection(() => ProjectionsExtensions.Coalesce<DBNull>(null, null), ProjectionsExtensions.ProcessCoalesce); RegisterCustomProjection(() => ProjectionsExtensions.Coalesce<int>(null, 0), ProjectionsExtensions.ProcessCoalesce); - RegisterCustomProjection(() => ProjectionsExtensions.ConcatStr(string.Empty, string.Empty), ProjectionsExtensions.ProcessConcatStr); + RegisterCustomProjection(() => Projections.Concat(null), Projections.ProcessConcat); RegisterCustomProjection(() => ProjectionsExtensions.Mod(0, 0), ProjectionsExtensions.ProcessMod); RegisterCustomProjection(() => ProjectionsExtensions.Abs(default(int)), ProjectionsExtensions.ProcessIntAbs); RegisterCustomProjection(() => ProjectionsExtensions.Abs(default(double)), ProjectionsExtensions.ProcessDoubleAbs); @@ -163,6 +163,9 @@ /// </summary> public static IProjection FindMemberProjection(Expression expression) { + if (!IsMemberExpression(expression)) + return Projections.Constant(FindValue(expression)); + if (expression is UnaryExpression) { UnaryExpression unaryExpression = (UnaryExpression)expression; @@ -309,6 +312,9 @@ private static bool IsMemberExpression(Expression expression) { + if (expression is ParameterExpression) + return true; + if (expression is MemberExpression) { MemberExpression memberExpression = (MemberExpression)expression; @@ -319,6 +325,13 @@ if (memberExpression.Expression.NodeType == ExpressionType.Parameter) return true; + if (IsNullableOfT(memberExpression.Member.DeclaringType)) + { + // it's a Nullable<T>, so ignore any .Value + if (memberExpression.Member.Name == "Value") + return IsMemberExpression(memberExpression.Expression); + } + if (memberExpression.Expression.NodeType == ExpressionType.MemberAccess) { // if the member has a null value, it was an alias @@ -337,6 +350,25 @@ return IsMemberExpression(unaryExpression.Operand); } + if (expression is MethodCallExpression) + { + MethodCallExpression methodCallExpression = (MethodCallExpression)expression; + + string signature = Signature(methodCallExpression.Method); + if (_customProjectionProcessors.ContainsKey(signature)) + return true; + + if (methodCallExpression.Method.Name == "GetType" + || methodCallExpression.Method.Name == "get_Item" + || methodCallExpression.Method.Name == "First") + { + if (IsMemberExpression(methodCallExpression.Object)) + return true; + + return EvaluatesToNull(methodCallExpression.Object); + } + } + return false; } Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs 2011-05-22 14:58:58 UTC (rev 5854) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs 2011-05-22 16:34:11 UTC (rev 5855) @@ -575,7 +575,7 @@ { s.Save(new Person() { Name = "p1", BirthDate = new DateTime(2009, 08, 07), Age = 90 }); s.Save(new Person() { Name = "p2", BirthDate = new DateTime(2008, 07, 06) }); - s.Save(new Person() { Name = "p3", BirthDate = new DateTime(2007, 06, 05) }); + s.Save(new Person() { Name = "pP3", BirthDate = new DateTime(2007, 06, 05) }); t.Commit(); } @@ -614,6 +614,29 @@ sqrtOfAge.GetType().Should().Be(typeof(double)); string.Format("{0:0.00}", sqrtOfAge).Should().Be("9.49"); } + + using (ISession s = OpenSession()) + { + var names = + s.QueryOver<Person>() + .Where(p => p.Name == "pP3") + .Select(p => p.Name.Lower(), p => p.Name.Upper()) + .SingleOrDefault<object[]>(); + + names[0].Should().Be("pp3"); + names[1].Should().Be("PP3"); + } + + using (ISession s = OpenSession()) + { + var name = + s.QueryOver<Person>() + .Where(p => p.Name == "p1") + .Select(p => Projections.Concat(p.Name, ", ", p.Name)) + .SingleOrDefault<string>(); + + name.Should().Be("p1, p1"); + } } [Test] Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs 2011-05-22 14:58:58 UTC (rev 5854) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs 2011-05-22 16:34:11 UTC (rev 5855) @@ -277,7 +277,7 @@ .Add(Restrictions.Eq(Projections.SqlFunction("locate", NHibernateUtil.String, Projections.Constant("e"), Projections.Property("Name"), Projections.Constant(1)), 2)) .Add(Restrictions.Eq(Projections.SqlFunction("coalesce", NHibernateUtil.Object, Projections.Property("Name"), Projections.Constant("not-null-val")), "test")) .Add(Restrictions.Eq(Projections.SqlFunction("coalesce", NHibernateUtil.Object, Projections.Property("NullableIsParent"), Projections.Constant(true)), true)) - .Add(Restrictions.Eq(Projections.SqlFunction("concat", NHibernateUtil.String, Projections.Property("Name"), Projections.Constant(string.Empty), Projections.Constant("A")), "testA")) + .Add(Restrictions.Eq(Projections.SqlFunction("concat", NHibernateUtil.String, Projections.Property("Name"), Projections.Constant(", "), Projections.Property("Name")), "test, test")) .Add(Restrictions.Eq(Projections.SqlFunction("mod", NHibernateUtil.Int32, Projections.Property("Height"), Projections.Constant(10)), 0)); IQueryOver<Person> actual = @@ -299,7 +299,7 @@ .And(p => p.Name.CharIndex("e", 1) == 2) .And(p => p.Name.Coalesce("not-null-val") == "test") .And(p => p.NullableIsParent.Coalesce(true) == true) - .And(p => p.Name.ConcatStr("A") == "testA") + .And(p => Projections.Concat(p.Name, ", ", p.Name) == "test, test") .And(p => p.Height.Mod(10) == 0); AssertCriteriaAreEqual(expected, actual); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |