From: <fab...@us...> - 2011-05-12 16:42:34
|
Revision: 5812 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5812&view=rev Author: fabiomaulo Date: 2011-05-12 16:42:27 +0000 (Thu, 12 May 2011) Log Message: ----------- Fix NH-2699 Modified Paths: -------------- trunk/nhibernate/src/NHibernate/NHibernate.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate/Dialect/MsSqlAzure2008Dialect.cs Added: trunk/nhibernate/src/NHibernate/Dialect/MsSqlAzure2008Dialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/MsSqlAzure2008Dialect.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Dialect/MsSqlAzure2008Dialect.cs 2011-05-12 16:42:27 UTC (rev 5812) @@ -0,0 +1,10 @@ +namespace NHibernate.Dialect +{ + public class MsSqlAzure2008Dialect : MsSql2008Dialect + { + public override string PrimaryKeyString + { + get { return "primary key CLUSTERED"; } + } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2011-05-12 16:27:11 UTC (rev 5811) +++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2011-05-12 16:42:27 UTC (rev 5812) @@ -137,6 +137,7 @@ <Compile Include="Dialect\GenericDialect.cs" /> <Compile Include="Dialect\MsSql2000Dialect.cs" /> <Compile Include="Dialect\MsSql7Dialect.cs" /> + <Compile Include="Dialect\MsSqlAzure2008Dialect.cs" /> <Compile Include="Dialect\MySQLDialect.cs" /> <Compile Include="Dialect\PostgreSQLDialect.cs" /> <Compile Include="Dialect\Schema\PostgreSQLMetadata.cs" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-05-12 18:32:59
|
Revision: 5813 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5813&view=rev Author: fabiomaulo Date: 2011-05-12 18:32:53 +0000 (Thu, 12 May 2011) Log Message: ----------- Fix NH-2691 (with some other possible cases) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Linq/Expressions/NhCountExpression.cs trunk/nhibernate/src/NHibernate/Linq/ReWriters/MergeAggregatingResultsRewriter.cs trunk/nhibernate/src/NHibernate/Linq/ReWriters/RemoveUnnecessaryBodyOperators.cs trunk/nhibernate/src/NHibernate/Linq/Visitors/NhExpressionTreeVisitor.cs trunk/nhibernate/src/NHibernate/Linq/Visitors/NhThrowingExpressionTreeVisitor.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2691/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2691/Domain.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2691/Fixture.cs Modified: trunk/nhibernate/src/NHibernate/Linq/Expressions/NhCountExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Expressions/NhCountExpression.cs 2011-05-12 16:42:27 UTC (rev 5812) +++ trunk/nhibernate/src/NHibernate/Linq/Expressions/NhCountExpression.cs 2011-05-12 18:32:53 UTC (rev 5813) @@ -2,27 +2,33 @@ namespace NHibernate.Linq.Expressions { - public class NhCountExpression : NhAggregatedExpression + public abstract class NhCountExpression : NhAggregatedExpression { - public NhCountExpression(Expression expression, System.Type type) - : base(expression, type, NhExpressionType.Count) + protected NhCountExpression(Expression expression, System.Type type) + : base(expression, type, NhExpressionType.Count) {} + + public abstract NhCountExpression CreateNew(Expression expression); + } + + public class NhShortCountExpression : NhCountExpression + { + public NhShortCountExpression(Expression expression) + : base(expression, typeof (int)) {} + + public override NhCountExpression CreateNew(Expression expression) { + return new NhShortCountExpression(expression); } } - public class NhShortCountExpression : NhCountExpression - { - public NhShortCountExpression(Expression expression) - : base(expression, typeof(int)) - { - } - } + public class NhLongCountExpression : NhCountExpression + { + public NhLongCountExpression(Expression expression) + : base(expression, typeof (long)) {} - public class NhLongCountExpression : NhCountExpression - { - public NhLongCountExpression(Expression expression) - : base(expression, typeof(long)) - { - } - } -} + public override NhCountExpression CreateNew(Expression expression) + { + return new NhLongCountExpression(expression); + } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Linq/ReWriters/MergeAggregatingResultsRewriter.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/ReWriters/MergeAggregatingResultsRewriter.cs 2011-05-12 16:42:27 UTC (rev 5812) +++ trunk/nhibernate/src/NHibernate/Linq/ReWriters/MergeAggregatingResultsRewriter.cs 2011-05-12 18:32:53 UTC (rev 5813) @@ -110,6 +110,10 @@ return CreateAggregate(m.Arguments[0], (LambdaExpression)m.Arguments[1], e => new NhShortCountExpression(e), () => new CountResultOperator()); + case "LongCount": + return CreateAggregate(m.Arguments[0], (LambdaExpression) m.Arguments[1], + e => new NhLongCountExpression(e), + () => new LongCountResultOperator()); case "Min": return CreateAggregate(m.Arguments[0], (LambdaExpression) m.Arguments[1], e => new NhMinExpression(e), Modified: trunk/nhibernate/src/NHibernate/Linq/ReWriters/RemoveUnnecessaryBodyOperators.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/ReWriters/RemoveUnnecessaryBodyOperators.cs 2011-05-12 16:42:27 UTC (rev 5812) +++ trunk/nhibernate/src/NHibernate/Linq/ReWriters/RemoveUnnecessaryBodyOperators.cs 2011-05-12 18:32:53 UTC (rev 5813) @@ -1,39 +1,33 @@ -using System; -using System.Linq; -using System.Linq.Expressions; -using NHibernate.Linq.Expressions; +using System.Linq; using Remotion.Linq; using Remotion.Linq.Clauses; using Remotion.Linq.Clauses.ResultOperators; -using Remotion.Linq.Parsing; namespace NHibernate.Linq.ReWriters { - public class RemoveUnnecessaryBodyOperators : QueryModelVisitorBase - { - private RemoveUnnecessaryBodyOperators() - { - } + public class RemoveUnnecessaryBodyOperators : QueryModelVisitorBase + { + private RemoveUnnecessaryBodyOperators() {} - public static void ReWrite(QueryModel queryModel) - { - var rewriter = new RemoveUnnecessaryBodyOperators(); + public static void ReWrite(QueryModel queryModel) + { + var rewriter = new RemoveUnnecessaryBodyOperators(); - rewriter.VisitQueryModel(queryModel); - } + rewriter.VisitQueryModel(queryModel); + } - public override void VisitResultOperator(ResultOperatorBase resultOperator, QueryModel queryModel, int index) - { - if (resultOperator is CountResultOperator) - { - // For count operators, we can remove any order-by result operators - foreach (var orderby in queryModel.BodyClauses.Where(bc => bc is OrderByClause).ToList()) - { - queryModel.BodyClauses.Remove(orderby); - } - } + public override void VisitResultOperator(ResultOperatorBase resultOperator, QueryModel queryModel, int index) + { + if (resultOperator is CountResultOperator || resultOperator is LongCountResultOperator) + { + // For count operators, we can remove any order-by result operators + foreach (IBodyClause orderby in queryModel.BodyClauses.Where(bc => bc is OrderByClause).ToList()) + { + queryModel.BodyClauses.Remove(orderby); + } + } - base.VisitResultOperator(resultOperator, queryModel, index); - } - } + base.VisitResultOperator(resultOperator, queryModel, index); + } + } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/NhExpressionTreeVisitor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Visitors/NhExpressionTreeVisitor.cs 2011-05-12 16:42:27 UTC (rev 5812) +++ trunk/nhibernate/src/NHibernate/Linq/Visitors/NhExpressionTreeVisitor.cs 2011-05-12 18:32:53 UTC (rev 5813) @@ -78,7 +78,7 @@ { Expression nx = VisitExpression(expression.Expression); - return nx != expression.Expression ? new NhShortCountExpression(nx) : expression; + return nx != expression.Expression ? expression.CreateNew(nx) : expression; } protected virtual Expression VisitNhSum(NhSumExpression expression) Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/NhThrowingExpressionTreeVisitor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Visitors/NhThrowingExpressionTreeVisitor.cs 2011-05-12 16:42:27 UTC (rev 5812) +++ trunk/nhibernate/src/NHibernate/Linq/Visitors/NhThrowingExpressionTreeVisitor.cs 2011-05-12 18:32:53 UTC (rev 5813) @@ -85,7 +85,7 @@ { Expression nx = base.VisitExpression(expression.Expression); - return nx != expression.Expression ? new NhCountExpression(nx, expression.Type) : expression; + return nx != expression.Expression ? expression.CreateNew(nx) : expression; } protected virtual Expression BaseVisitNhSum(NhSumExpression expression) Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2691/Domain.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2691/Domain.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2691/Domain.cs 2011-05-12 18:32:53 UTC (rev 5813) @@ -0,0 +1,28 @@ +using System; + +namespace NHibernate.Test.NHSpecificTest.NH2691 +{ + public abstract class Animal + { + public virtual int Id { get; set; } + public virtual string Description { get; set; } + public virtual int Sequence { get; set; } + } + + public abstract class Reptile : Animal + { + public virtual double BodyTemperature { get; set; } + } + + public class Lizard : Reptile { } + + public abstract class Mammal : Animal + { + public virtual bool Pregnant { get; set; } + public virtual DateTime? BirthDate { get; set; } + } + + public class Dog : Mammal { } + + public class Cat : Mammal { } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2691/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2691/Fixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2691/Fixture.cs 2011-05-12 18:32:53 UTC (rev 5813) @@ -0,0 +1,45 @@ +using System.Linq; +using NHibernate.Cfg.MappingSchema; +using NHibernate.Linq; +using NHibernate.Mapping.ByCode; +using NUnit.Framework; +using SharpTestsEx; + +namespace NHibernate.Test.NHSpecificTest.NH2691 +{ + public class Fixture: TestCaseMappingByCode + { + protected override HbmMapping GetMappings() + { + var mapper = new ConventionModelMapper(); + mapper.IsTablePerClass((type, declared) => false); + mapper.IsTablePerClassHierarchy((type, declared) => true); + var mappings = mapper.CompileMappingFor(new[] {typeof (Animal), typeof (Reptile), typeof (Mammal), typeof (Lizard), typeof (Dog), typeof (Cat)}); + return mappings; + } + + [Test] + public void WhenUseCountWithOrderThenCutTheOrder() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var baseQuery = from cat in session.Query<Cat>() orderby cat.BirthDate select cat; + Executing.This(() => baseQuery.Count()).Should().NotThrow(); + session.Transaction.Commit(); + } + } + + [Test] + public void WhenUseLongCountWithOrderThenCutTheOrder() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var baseQuery = from cat in session.Query<Cat>() orderby cat.BirthDate select cat; + Executing.This(() => baseQuery.LongCount()).Should().NotThrow(); + session.Transaction.Commit(); + } + } + } +} \ 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-12 16:42:27 UTC (rev 5812) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-05-12 18:32:53 UTC (rev 5813) @@ -820,6 +820,8 @@ <Compile Include="NHSpecificTest\NH2660And2661\Test.cs" /> <Compile Include="NHSpecificTest\NH2673\Blog.cs" /> <Compile Include="NHSpecificTest\NH2673\CachingWithTrasformerTests.cs" /> + <Compile Include="NHSpecificTest\NH2691\Domain.cs" /> + <Compile Include="NHSpecificTest\NH2691\Fixture.cs" /> <Compile Include="NHSpecificTest\NH2697\ArticleGroupItem.cs" /> <Compile Include="NHSpecificTest\NH2697\ArticleItem.cs" /> <Compile Include="NHSpecificTest\NH2697\SampleTest.cs" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2011-05-15 13:04:09
|
Revision: 5817 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5817&view=rev Author: ricbrown Date: 2011-05-15 13:04:02 +0000 (Sun, 15 May 2011) Log Message: ----------- NH-2683: Started with single extension function .Year() Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Criterion/ProjectionsExtensions.cs trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/Model.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/ProjectionsExtensions.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/ProjectionsExtensions.cs 2011-05-15 13:00:22 UTC (rev 5816) +++ trunk/nhibernate/src/NHibernate/Criterion/ProjectionsExtensions.cs 2011-05-15 13:04:02 UTC (rev 5817) @@ -19,5 +19,20 @@ string aliasContainer = ExpressionProcessor.FindPropertyExpression(alias.Body); return Projections.Alias(projection, aliasContainer); } + + /// <summary> + /// Project SQL function year() + /// Note: throws an exception outside of a QueryOver expression + /// </summary> + public static int Year(this DateTime dateTimeProperty) + { + throw new Exception("Not to be used directly - use inside QueryOver expression"); + } + + internal static IProjection ProcessYear(MethodCallExpression methodCallExpression) + { + IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); + return Projections.SqlFunction("year", NHibernateUtil.DateTime, property); + } } } Modified: trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs 2011-05-15 13:00:22 UTC (rev 5816) +++ trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs 2011-05-15 13:04:02 UTC (rev 5817) @@ -31,14 +31,15 @@ public static class ExpressionProcessor { - private readonly static IDictionary<ExpressionType, Func<string, object, ICriterion>> _simpleExpressionCreators = null; + private readonly static IDictionary<ExpressionType, Func<IProjection, object, ICriterion>> _simpleExpressionCreators = null; private readonly static IDictionary<ExpressionType, Func<string, string, ICriterion>> _propertyExpressionCreators = null; private readonly static IDictionary<LambdaSubqueryType, IDictionary<ExpressionType, Func<string, DetachedCriteria, AbstractCriterion>>> _subqueryExpressionCreatorTypes = null; private readonly static IDictionary<string, Func<MethodCallExpression, ICriterion>> _customMethodCallProcessors = null; + private readonly static IDictionary<string, Func<MethodCallExpression, IProjection>> _customProjectionProcessors = null; static ExpressionProcessor() { - _simpleExpressionCreators = new Dictionary<ExpressionType, Func<string, object, ICriterion>>(); + _simpleExpressionCreators = new Dictionary<ExpressionType, Func<IProjection, object, ICriterion>>(); _simpleExpressionCreators[ExpressionType.Equal] = Eq; _simpleExpressionCreators[ExpressionType.NotEqual] = Ne; _simpleExpressionCreators[ExpressionType.GreaterThan] = Gt; @@ -86,36 +87,39 @@ RegisterCustomMethodCall(() => RestrictionExtensions.IsIn(null, new object[0]), RestrictionExtensions.ProcessIsInArray); RegisterCustomMethodCall(() => RestrictionExtensions.IsIn(null, new List<object>()), RestrictionExtensions.ProcessIsInCollection); RegisterCustomMethodCall(() => RestrictionExtensions.IsBetween(null, null).And(null), RestrictionExtensions.ProcessIsBetween); + + _customProjectionProcessors = new Dictionary<string, Func<MethodCallExpression, IProjection>>(); + RegisterCustomProjection(() => ProjectionsExtensions.Year(default(DateTime)), ProjectionsExtensions.ProcessYear); } - private static ICriterion Eq(string propertyName, object value) + private static ICriterion Eq(IProjection propertyName, object value) { return Restrictions.Eq(propertyName, value); } - private static ICriterion Ne(string propertyName, object value) + private static ICriterion Ne(IProjection propertyName, object value) { return NHibernate.Criterion.Restrictions.Not( NHibernate.Criterion.Restrictions.Eq(propertyName, value)); } - private static ICriterion Gt(string propertyName, object value) + private static ICriterion Gt(IProjection propertyName, object value) { return NHibernate.Criterion.Restrictions.Gt(propertyName, value); } - private static ICriterion Ge(string propertyName, object value) + private static ICriterion Ge(IProjection propertyName, object value) { return NHibernate.Criterion.Restrictions.Ge(propertyName, value); } - private static ICriterion Lt(string propertyName, object value) + private static ICriterion Lt(IProjection propertyName, object value) { return NHibernate.Criterion.Restrictions.Lt(propertyName, value); } - private static ICriterion Le(string propertyName, object value) + private static ICriterion Le(IProjection propertyName, object value) { return NHibernate.Criterion.Restrictions.Le(propertyName, value); } @@ -131,6 +135,23 @@ } /// <summary> + /// Retrieves the projection for the expression + /// </summary> + public static IProjection FindMemberProjection(Expression expression) + { + if (expression is MethodCallExpression) + { + MethodCallExpression methodCallExpression = (MethodCallExpression)expression; + + string signature = Signature(methodCallExpression.Method); + if (_customProjectionProcessors.ContainsKey(signature)) + return _customProjectionProcessors[signature](methodCallExpression); + } + + return Projections.Property(FindMemberExpression(expression)); + } + + /// <summary> /// Retrieves the name of the property from a member expression /// </summary> /// <param name="expression">An expression tree that can contain either a member, or a conversion from a member. @@ -245,7 +266,8 @@ if (expression is MethodCallExpression) { - return typeof(System.Type); + var methodCallExpression = (MethodCallExpression)expression; + return methodCallExpression.Method.ReturnType; } throw new Exception("Could not determine member type from " + expression.ToString()); @@ -320,7 +342,7 @@ private static ICriterion ProcessSimpleExpression(Expression left, Expression right, ExpressionType nodeType) { - string property = FindMemberExpression(left); + IProjection property = FindMemberProjection(left); System.Type propertyType = FindMemberType(left); object value = FindValue(right); @@ -332,7 +354,7 @@ if (!_simpleExpressionCreators.ContainsKey(nodeType)) throw new Exception("Unhandled simple expression type: " + nodeType); - Func<string, object, ICriterion> simpleExpressionCreator = _simpleExpressionCreators[nodeType]; + Func<IProjection, object, ICriterion> simpleExpressionCreator = _simpleExpressionCreators[nodeType]; ICriterion criterion = simpleExpressionCreator(property, value); return criterion; } @@ -347,7 +369,7 @@ return ProcessSimpleExpression(methodCall.Arguments[0], methodCall.Arguments[1], be.NodeType); } - private static ICriterion ProcessSimpleNullExpression(string property, ExpressionType expressionType) + private static ICriterion ProcessSimpleNullExpression(IProjection property, ExpressionType expressionType) { if (expressionType == ExpressionType.Equal) return Restrictions.IsNull(property); @@ -615,6 +637,18 @@ _customMethodCallProcessors.Add(signature, functionProcessor); } + /// <summary> + /// Register a custom projection for use in a QueryOver expression + /// </summary> + /// <param name="function">Lambda expression demonstrating call of custom method</param> + /// <param name="functionProcessor">function to convert MethodCallExpression to IProjection</param> + public static void RegisterCustomProjection<T>(Expression<Func<T>> function, Func<MethodCallExpression, IProjection> functionProcessor) + { + MethodCallExpression functionExpression = (MethodCallExpression)function.Body; + string signature = Signature(functionExpression.Method); + _customProjectionProcessors.Add(signature, functionProcessor); + } + } } Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/Model.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/Model.cs 2011-05-15 13:00:22 UTC (rev 5816) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/Model.cs 2011-05-15 13:04:02 UTC (rev 5817) @@ -31,6 +31,7 @@ public virtual Person Father { get; set; } public virtual bool IsParent { get; set; } public virtual char Blood { get; set; } + public virtual DateTime BirthDate { get; set; } public virtual int? NullableAge { get; set; } public virtual PersonGender? NullableGender { get; set; } Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs 2011-05-15 13:00:22 UTC (rev 5816) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs 2011-05-15 13:04:02 UTC (rev 5817) @@ -21,13 +21,13 @@ { ICriteria expected = CreateTestCriteria(typeof(Person)) - .Add(Restrictions.Eq("Name", "test name")) - .Add(Restrictions.Not(Restrictions.Eq("Name", "not test name"))) - .Add(Restrictions.Gt("Age", 10)) - .Add(Restrictions.Ge("Age", 11)) - .Add(Restrictions.Lt("Age", 50)) - .Add(Restrictions.Le("Age", 49)) - .Add(Restrictions.Eq("class", typeof(Person))) + .Add(Restrictions.Eq(Projections.Property("Name"), "test name")) + .Add(Restrictions.Not(Restrictions.Eq(Projections.Property("Name"), "not test name"))) + .Add(Restrictions.Gt(Projections.Property("Age"), 10)) + .Add(Restrictions.Ge(Projections.Property("Age"), 11)) + .Add(Restrictions.Lt(Projections.Property("Age"), 50)) + .Add(Restrictions.Le(Projections.Property("Age"), 49)) + .Add(Restrictions.Eq(Projections.Property("class"), typeof(Person))) .Add(Restrictions.Eq("class", typeof(Person).FullName)); IQueryOver<Person> actual = @@ -55,12 +55,12 @@ { ICriteria expected = CreateTestCriteria(typeof(Person)) - .Add(Restrictions.Eq("Name", "test name")) - .Add(Restrictions.Not(Restrictions.Eq("Name", "test name"))) - .Add(Restrictions.Gt("Name", "test name")) - .Add(Restrictions.Ge("Name", "test name")) - .Add(Restrictions.Lt("Name", "test name")) - .Add(Restrictions.Le("Name", "test name")) + .Add(Restrictions.Eq(Projections.Property("Name"), "test name")) + .Add(Restrictions.Not(Restrictions.Eq(Projections.Property("Name"), "test name"))) + .Add(Restrictions.Gt(Projections.Property("Name"), "test name")) + .Add(Restrictions.Ge(Projections.Property("Name"), "test name")) + .Add(Restrictions.Lt(Projections.Property("Name"), "test name")) + .Add(Restrictions.Le(Projections.Property("Name"), "test name")) .Add(Restrictions.EqProperty("Name", "Name")) .Add(Restrictions.Not(Restrictions.EqProperty("Name", "Name"))) .Add(Restrictions.GtProperty("Name", "Name")) @@ -115,8 +115,8 @@ { ICriteria expected = CreateTestCriteria(typeof(Person)) - .Add(Restrictions.Eq("Blood", 'A')) - .Add(Restrictions.Not(Restrictions.Eq("Blood", 'B'))); + .Add(Restrictions.Eq(Projections.Property("Blood"), 'A')) + .Add(Restrictions.Not(Restrictions.Eq(Projections.Property("Blood"), 'B'))); IQueryOver<Person> actual = CreateTestQueryOver<Person>() @@ -132,9 +132,9 @@ ICriteria expected = CreateTestCriteria(typeof(Person)) .Add(Restrictions.And( - Restrictions.Eq("Name", "test name"), + Restrictions.Eq(Projections.Property("Name"), "test name"), Restrictions.Or( - Restrictions.Gt("Age", 21), + Restrictions.Gt(Projections.Property("Age"), 21), Restrictions.Eq("HasCar", true)))); IQueryOver<Person> actual = @@ -150,7 +150,7 @@ ICriteria expected = CreateTestCriteria(typeof(Person), "personAlias") .Add(Restrictions.Or( - Restrictions.Not(Restrictions.Eq("Name", "test name")), + Restrictions.Not(Restrictions.Eq(Projections.Property("Name"), "test name")), Restrictions.Not(Restrictions.Like("personAlias.Name", "%test%")))); Person personAlias = null; @@ -166,8 +166,8 @@ { ICriteria expected = CreateTestCriteria(typeof(Person), "personAlias") - .Add(Restrictions.Not(Restrictions.Eq("Name", "test name"))) - .Add(Restrictions.Not(Restrictions.Eq("personAlias.Name", "test name"))); + .Add(Restrictions.Not(Restrictions.Eq(Projections.Property("Name"), "test name"))) + .Add(Restrictions.Not(Restrictions.Eq(Projections.Property("personAlias.Name"), "test name"))); Person personAlias = null; IQueryOver<Person> actual = @@ -224,13 +224,13 @@ { ICriteria expected = CreateTestCriteria(typeof(Person), "personAlias") - .Add(Restrictions.Eq("personAlias.Name", "test name")) - .Add(Restrictions.Not(Restrictions.Eq("personAlias.Name", "not test name"))) - .Add(Restrictions.Gt("personAlias.Age", 10)) - .Add(Restrictions.Ge("personAlias.Age", 11)) - .Add(Restrictions.Lt("personAlias.Age", 50)) - .Add(Restrictions.Le("personAlias.Age", 49)) - .Add(Restrictions.Eq("personAlias.class", typeof(Person))) + .Add(Restrictions.Eq(Projections.Property("personAlias.Name"), "test name")) + .Add(Restrictions.Not(Restrictions.Eq(Projections.Property("personAlias.Name"), "not test name"))) + .Add(Restrictions.Gt(Projections.Property("personAlias.Age"), 10)) + .Add(Restrictions.Ge(Projections.Property("personAlias.Age"), 11)) + .Add(Restrictions.Lt(Projections.Property("personAlias.Age"), 50)) + .Add(Restrictions.Le(Projections.Property("personAlias.Age"), 49)) + .Add(Restrictions.Eq(Projections.Property("personAlias.class"), typeof(Person))) .Add(Restrictions.Eq("personAlias.class", typeof(Person).FullName)); Person personAlias = null; @@ -254,7 +254,7 @@ ICriteria expected = CreateTestCriteria(typeof(Person)) .CreateCriteria("Father") - .Add(Expression.Eq("Name", "test name")); + .Add(Expression.Eq(Projections.Property("Name"), "test name")); IQueryOver<Person> actual = CreateTestQueryOver<Person>() @@ -270,7 +270,7 @@ ICriteria expected = CreateTestCriteria(typeof(Person), "personAlias") .CreateCriteria("personAlias.Father") - .Add(Expression.Eq("Name", "test name")); + .Add(Expression.Eq(Projections.Property("Name"), "test name")); Person personAlias = null; IQueryOver<Person> actual = @@ -287,7 +287,7 @@ ICriteria expected = CreateTestCriteria(typeof(Person)) .CreateCriteria("Children") - .Add(Expression.Eq("Nickname", "test name")); + .Add(Expression.Eq(Projections.Property("Nickname"), "test name")); IQueryOver<Person> actual = CreateTestQueryOver<Person>() @@ -303,7 +303,7 @@ ICriteria expected = CreateTestCriteria(typeof(Person), "personAlias") .CreateCriteria("personAlias.Children", JoinType.InnerJoin) - .Add(Expression.Eq("Nickname", "test name")); + .Add(Expression.Eq(Projections.Property("Nickname"), "test name")); Person personAlias = null; IQueryOver<Person> actual = @@ -416,17 +416,17 @@ { ICriteria expected = CreateTestCriteria(typeof(Person)) - .CreateCriteria("PersonList", "alias1", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "many func t,bool")) - .CreateCriteria("PersonList", "alias2", JoinType.LeftOuterJoin, Restrictions.Eq("alias1.Name", "many func bool")) + .CreateCriteria("PersonList", "alias1", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("Name"), "many func t,bool")) + .CreateCriteria("PersonList", "alias2", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("alias1.Name"), "many func bool")) .CreateCriteria("PersonList", "alias3", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "many private")) - .CreateCriteria("Father", "alias4", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "one func t,bool")) - .CreateCriteria("Father", "alias5", JoinType.LeftOuterJoin, Restrictions.Eq("alias4.Name", "one func bool")) + .CreateCriteria("Father", "alias4", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("Name"), "one func t,bool")) + .CreateCriteria("Father", "alias5", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("alias4.Name"), "one func bool")) .CreateCriteria("Father", "alias6", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "one private")) - .CreateCriteria("alias1.PersonList", "alias7", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "a many func t,bool")) - .CreateCriteria("alias2.PersonList", "alias8", JoinType.LeftOuterJoin, Restrictions.Eq("alias1.Name", "a many func bool")) + .CreateCriteria("alias1.PersonList", "alias7", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("Name"), "a many func t,bool")) + .CreateCriteria("alias2.PersonList", "alias8", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("alias1.Name"), "a many func bool")) .CreateCriteria("alias3.PersonList", "alias9", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "a many private")) - .CreateCriteria("alias4.Father", "alias10", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "a one func t,bool")) - .CreateCriteria("alias5.Father", "alias11", JoinType.LeftOuterJoin, Restrictions.Eq("alias4.Name", "a one func bool")) + .CreateCriteria("alias4.Father", "alias10", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("Name"), "a one func t,bool")) + .CreateCriteria("alias5.Father", "alias11", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("alias4.Name"), "a one func bool")) .CreateCriteria("alias6.Father", "alias12", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "a one private")); Person alias1 = null; @@ -448,13 +448,13 @@ .Left.JoinQueryOver(p => p.PersonList, () => alias3, Restrictions.Eq("Name", "many private")) .Left.JoinQueryOver(p => p.Father, () => alias4, p => p.Name == "one func t,bool") .Left.JoinQueryOver(p => p.Father, () => alias5, () => alias4.Name == "one func bool") - .Left.JoinQueryOver(p => p.Father, () => alias6, p => p.Name == "one private") + .Left.JoinQueryOver(p => p.Father, () => alias6, Restrictions.Eq("Name", "one private")) .Left.JoinQueryOver(() => alias1.PersonList, () => alias7, p => p.Name == "a many func t,bool") .Left.JoinQueryOver(() => alias2.PersonList, () => alias8, () => alias1.Name == "a many func bool") .Left.JoinQueryOver(() => alias3.PersonList, () => alias9, Restrictions.Eq("Name", "a many private")) .Left.JoinQueryOver(() => alias4.Father, () => alias10, p => p.Name == "a one func t,bool") .Left.JoinQueryOver(() => alias5.Father, () => alias11, () => alias4.Name == "a one func bool") - .Left.JoinQueryOver(() => alias6.Father, () => alias12, p => p.Name == "a one private"); + .Left.JoinQueryOver(() => alias6.Father, () => alias12, Restrictions.Eq("Name", "a one private")); AssertCriteriaAreEqual(expected, actual); } @@ -464,17 +464,17 @@ { DetachedCriteria expected = DetachedCriteria.For<Person>() - .CreateCriteria("PersonList", "alias1", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "many func t,bool")) - .CreateCriteria("PersonList", "alias2", JoinType.LeftOuterJoin, Restrictions.Eq("alias1.Name", "many func bool")) + .CreateCriteria("PersonList", "alias1", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("Name"), "many func t,bool")) + .CreateCriteria("PersonList", "alias2", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("alias1.Name"), "many func bool")) .CreateCriteria("PersonList", "alias3", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "many private")) - .CreateCriteria("Father", "alias4", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "one func t,bool")) - .CreateCriteria("Father", "alias5", JoinType.LeftOuterJoin, Restrictions.Eq("alias4.Name", "one func bool")) + .CreateCriteria("Father", "alias4", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("Name"), "one func t,bool")) + .CreateCriteria("Father", "alias5", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("alias4.Name"), "one func bool")) .CreateCriteria("Father", "alias6", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "one private")) - .CreateCriteria("alias1.PersonList", "alias7", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "a many func t,bool")) - .CreateCriteria("alias2.PersonList", "alias8", JoinType.LeftOuterJoin, Restrictions.Eq("alias1.Name", "a many func bool")) + .CreateCriteria("alias1.PersonList", "alias7", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("Name"), "a many func t,bool")) + .CreateCriteria("alias2.PersonList", "alias8", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("alias1.Name"), "a many func bool")) .CreateCriteria("alias3.PersonList", "alias9", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "a many private")) - .CreateCriteria("alias4.Father", "alias10", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "a one func t,bool")) - .CreateCriteria("alias5.Father", "alias11", JoinType.LeftOuterJoin, Restrictions.Eq("alias4.Name", "a one func bool")) + .CreateCriteria("alias4.Father", "alias10", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("Name"), "a one func t,bool")) + .CreateCriteria("alias5.Father", "alias11", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("alias4.Name"), "a one func bool")) .CreateCriteria("alias6.Father", "alias12", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "a one private")); Person alias1 = null; @@ -496,13 +496,13 @@ .Left.JoinQueryOver(p => p.PersonList, () => alias3, Restrictions.Eq("Name", "many private")) .Left.JoinQueryOver(p => p.Father, () => alias4, p => p.Name == "one func t,bool") .Left.JoinQueryOver(p => p.Father, () => alias5, () => alias4.Name == "one func bool") - .Left.JoinQueryOver(p => p.Father, () => alias6, p => p.Name == "one private") + .Left.JoinQueryOver(p => p.Father, () => alias6, Restrictions.Eq("Name", "one private")) .Left.JoinQueryOver(() => alias1.PersonList, () => alias7, p => p.Name == "a many func t,bool") .Left.JoinQueryOver(() => alias2.PersonList, () => alias8, () => alias1.Name == "a many func bool") .Left.JoinQueryOver(() => alias3.PersonList, () => alias9, Restrictions.Eq("Name", "a many private")) .Left.JoinQueryOver(() => alias4.Father, () => alias10, p => p.Name == "a one func t,bool") .Left.JoinQueryOver(() => alias5.Father, () => alias11, () => alias4.Name == "a one func bool") - .Left.JoinQueryOver(() => alias6.Father, () => alias12, p => p.Name == "a one private"); + .Left.JoinQueryOver(() => alias6.Father, () => alias12, Restrictions.Eq("Name", "a one private")); AssertCriteriaAreEqual(expected, actual); } @@ -512,17 +512,17 @@ { ICriteria expected = CreateTestCriteria(typeof(Person)) - .CreateAlias("PersonList", "alias1", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "many func t,bool")) - .CreateAlias("PersonList", "alias2", JoinType.LeftOuterJoin, Restrictions.Eq("alias1.Name", "many func bool")) + .CreateAlias("PersonList", "alias1", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("Name"), "many func t,bool")) + .CreateAlias("PersonList", "alias2", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("alias1.Name"), "many func bool")) .CreateAlias("PersonList", "alias3", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "many private")) - .CreateAlias("Father", "alias4", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "one func t,bool")) - .CreateAlias("Father", "alias5", JoinType.LeftOuterJoin, Restrictions.Eq("alias4.Name", "one func bool")) + .CreateAlias("Father", "alias4", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("Name"), "one func t,bool")) + .CreateAlias("Father", "alias5", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("alias4.Name"), "one func bool")) .CreateAlias("Father", "alias6", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "one private")) - .CreateAlias("alias1.PersonList", "alias7", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "a many func t,bool")) - .CreateAlias("alias2.PersonList", "alias8", JoinType.LeftOuterJoin, Restrictions.Eq("alias1.Name", "a many func bool")) + .CreateAlias("alias1.PersonList", "alias7", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("Name"), "a many func t,bool")) + .CreateAlias("alias2.PersonList", "alias8", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("alias1.Name"), "a many func bool")) .CreateAlias("alias3.PersonList", "alias9", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "a many private")) - .CreateAlias("alias4.Father", "alias10", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "a one func t,bool")) - .CreateAlias("alias5.Father", "alias11", JoinType.LeftOuterJoin, Restrictions.Eq("alias4.Name", "a one func bool")) + .CreateAlias("alias4.Father", "alias10", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("Name"), "a one func t,bool")) + .CreateAlias("alias5.Father", "alias11", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("alias4.Name"), "a one func bool")) .CreateAlias("alias6.Father", "alias12", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "a one private")); Person alias1 = null; @@ -544,13 +544,13 @@ .Left.JoinAlias(p => p.PersonList, () => alias3, Restrictions.Eq("Name", "many private")) .Left.JoinAlias(p => p.Father, () => alias4, p => p.Name == "one func t,bool") .Left.JoinAlias(p => p.Father, () => alias5, () => alias4.Name == "one func bool") - .Left.JoinAlias(p => p.Father, () => alias6, p => p.Name == "one private") + .Left.JoinAlias(p => p.Father, () => alias6, Restrictions.Eq("Name", "one private")) .Left.JoinAlias(() => alias1.PersonList, () => alias7, p => p.Name == "a many func t,bool") .Left.JoinAlias(() => alias2.PersonList, () => alias8, () => alias1.Name == "a many func bool") .Left.JoinAlias(() => alias3.PersonList, () => alias9, Restrictions.Eq("Name", "a many private")) .Left.JoinAlias(() => alias4.Father, () => alias10, p => p.Name == "a one func t,bool") .Left.JoinAlias(() => alias5.Father, () => alias11, () => alias4.Name == "a one func bool") - .Left.JoinAlias(() => alias6.Father, () => alias12, p => p.Name == "a one private"); + .Left.JoinAlias(() => alias6.Father, () => alias12, Restrictions.Eq("Name", "a one private")); AssertCriteriaAreEqual(expected, actual); } @@ -560,17 +560,17 @@ { DetachedCriteria expected = DetachedCriteria.For<Person>() - .CreateAlias("PersonList", "alias1", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "many func t,bool")) - .CreateAlias("PersonList", "alias2", JoinType.LeftOuterJoin, Restrictions.Eq("alias1.Name", "many func bool")) + .CreateAlias("PersonList", "alias1", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("Name"), "many func t,bool")) + .CreateAlias("PersonList", "alias2", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("alias1.Name"), "many func bool")) .CreateAlias("PersonList", "alias3", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "many private")) - .CreateAlias("Father", "alias4", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "one func t,bool")) - .CreateAlias("Father", "alias5", JoinType.LeftOuterJoin, Restrictions.Eq("alias4.Name", "one func bool")) + .CreateAlias("Father", "alias4", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("Name"), "one func t,bool")) + .CreateAlias("Father", "alias5", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("alias4.Name"), "one func bool")) .CreateAlias("Father", "alias6", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "one private")) - .CreateAlias("alias1.PersonList", "alias7", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "a many func t,bool")) - .CreateAlias("alias2.PersonList", "alias8", JoinType.LeftOuterJoin, Restrictions.Eq("alias1.Name", "a many func bool")) + .CreateAlias("alias1.PersonList", "alias7", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("Name"), "a many func t,bool")) + .CreateAlias("alias2.PersonList", "alias8", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("alias1.Name"), "a many func bool")) .CreateAlias("alias3.PersonList", "alias9", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "a many private")) - .CreateAlias("alias4.Father", "alias10", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "a one func t,bool")) - .CreateAlias("alias5.Father", "alias11", JoinType.LeftOuterJoin, Restrictions.Eq("alias4.Name", "a one func bool")) + .CreateAlias("alias4.Father", "alias10", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("Name"), "a one func t,bool")) + .CreateAlias("alias5.Father", "alias11", JoinType.LeftOuterJoin, Restrictions.Eq(Projections.Property("alias4.Name"), "a one func bool")) .CreateAlias("alias6.Father", "alias12", JoinType.LeftOuterJoin, Restrictions.Eq("Name", "a one private")); Person alias1 = null; @@ -592,13 +592,13 @@ .Left.JoinAlias(p => p.PersonList, () => alias3, Restrictions.Eq("Name", "many private")) .Left.JoinAlias(p => p.Father, () => alias4, p => p.Name == "one func t,bool") .Left.JoinAlias(p => p.Father, () => alias5, () => alias4.Name == "one func bool") - .Left.JoinAlias(p => p.Father, () => alias6, p => p.Name == "one private") + .Left.JoinAlias(p => p.Father, () => alias6, Restrictions.Eq("Name", "one private")) .Left.JoinAlias(() => alias1.PersonList, () => alias7, p => p.Name == "a many func t,bool") .Left.JoinAlias(() => alias2.PersonList, () => alias8, () => alias1.Name == "a many func bool") .Left.JoinAlias(() => alias3.PersonList, () => alias9, Restrictions.Eq("Name", "a many private")) .Left.JoinAlias(() => alias4.Father, () => alias10, p => p.Name == "a one func t,bool") .Left.JoinAlias(() => alias5.Father, () => alias11, () => alias4.Name == "a one func bool") - .Left.JoinAlias(() => alias6.Father, () => alias12, p => p.Name == "a one private"); + .Left.JoinAlias(() => alias6.Father, () => alias12, Restrictions.Eq("Name", "a one private")); AssertCriteriaAreEqual(expected, actual); } @@ -781,7 +781,7 @@ { DetachedCriteria expected = DetachedCriteria.For<Person>("personAlias") - .Add(Restrictions.Eq("personAlias.Name", "test name")); + .Add(Restrictions.Eq(Projections.Property("personAlias.Name"), "test name")); Person personAlias = null; QueryOver<Person> actual = Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs 2011-05-15 13:00:22 UTC (rev 5816) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs 2011-05-15 13:04:02 UTC (rev 5817) @@ -17,10 +17,10 @@ { ICriteria expected = CreateTestCriteria(typeof(Person), "personAlias") - .Add(Restrictions.Lt("Age", 65)) - .Add(Restrictions.Ge("personAlias.Age", 18)) - .Add(Restrictions.Not(Restrictions.Ge("Age", 65))) - .Add(Restrictions.Not(Restrictions.Lt("personAlias.Age", 18))); + .Add(Restrictions.Lt(Projections.Property("Age"), 65)) + .Add(Restrictions.Ge(Projections.Property("personAlias.Age"), 18)) + .Add(Restrictions.Not(Restrictions.Ge(Projections.Property("Age"), 65))) + .Add(Restrictions.Not(Restrictions.Lt(Projections.Property("personAlias.Age"), 18))); Person personAlias = null; var actual = @@ -92,11 +92,11 @@ ICriteria expected = CreateTestCriteria(typeof(Person), "personAlias") .Add(Restrictions.Conjunction() - .Add(Restrictions.Eq("Name", "test")) - .Add(Restrictions.Eq("personAlias.Name", "test"))) + .Add(Restrictions.Eq(Projections.Property("Name"), "test")) + .Add(Restrictions.Eq(Projections.Property("personAlias.Name"), "test"))) .Add(Restrictions.Disjunction() - .Add(Restrictions.Eq("Name", "test")) - .Add(Restrictions.Eq("personAlias.Name", "test"))); + .Add(Restrictions.Eq(Projections.Property("Name"), "test")) + .Add(Restrictions.Eq(Projections.Property("personAlias.Name"), "test"))); Person personAlias = null; var actual = @@ -182,23 +182,23 @@ { ICriteria expected = CreateTestCriteria(typeof(Person), "personAlias") - .Add(Restrictions.IsNull("Name")) - .Add(Restrictions.IsNull("Name")) - .Add(Restrictions.IsNull("Name")) - .Add(Restrictions.IsNull("Father")) - .Add(Restrictions.IsNull("Father")) - .Add(Restrictions.IsNull("NullableGender")) - .Add(Restrictions.IsNull("NullableAge")) - .Add(Restrictions.IsNull("NullableIsParent")) - .Add(Restrictions.Not(Restrictions.IsNull("Name"))) - .Add(Restrictions.Not(Restrictions.IsNull("Name"))) - .Add(Restrictions.Not(Restrictions.IsNull("Name"))) - .Add(Restrictions.Not(Restrictions.IsNull("Father"))) - .Add(Restrictions.Not(Restrictions.IsNull("Father"))) - .Add(Restrictions.Not(Restrictions.IsNull("NullableGender"))) - .Add(Restrictions.Not(Restrictions.IsNull("NullableAge"))) - .Add(Restrictions.Not(Restrictions.IsNull("NullableIsParent"))) - .Add(Restrictions.IsNull("personAlias.Name")); + .Add(Restrictions.IsNull(Projections.Property("Name"))) + .Add(Restrictions.IsNull(Projections.Property("Name"))) + .Add(Restrictions.IsNull(Projections.Property("Name"))) + .Add(Restrictions.IsNull(Projections.Property("Father"))) + .Add(Restrictions.IsNull(Projections.Property("Father"))) + .Add(Restrictions.IsNull(Projections.Property("NullableGender"))) + .Add(Restrictions.IsNull(Projections.Property("NullableAge"))) + .Add(Restrictions.IsNull(Projections.Property("NullableIsParent"))) + .Add(Restrictions.Not(Restrictions.IsNull(Projections.Property("Name")))) + .Add(Restrictions.Not(Restrictions.IsNull(Projections.Property("Name")))) + .Add(Restrictions.Not(Restrictions.IsNull(Projections.Property("Name")))) + .Add(Restrictions.Not(Restrictions.IsNull(Projections.Property("Father")))) + .Add(Restrictions.Not(Restrictions.IsNull(Projections.Property("Father")))) + .Add(Restrictions.Not(Restrictions.IsNull(Projections.Property("NullableGender")))) + .Add(Restrictions.Not(Restrictions.IsNull(Projections.Property("NullableAge")))) + .Add(Restrictions.Not(Restrictions.IsNull(Projections.Property("NullableIsParent")))) + .Add(Restrictions.IsNull(Projections.Property("personAlias.Name"))); Person personAlias = null; CustomPerson nullPerson = null; @@ -255,6 +255,20 @@ AssertCriteriaAreEqual(expected, actual); } + [Test] + public void FunctionExtensions() + { + ICriteria expected = + CreateTestCriteria(typeof(Person)) + .Add(Restrictions.Eq(Projections.SqlFunction("year", NHibernateUtil.DateTime, Projections.Property("BirthDate")), 1970)); + + IQueryOver<Person> actual = + CreateTestQueryOver<Person>() + .Where(p => p.BirthDate.Year() == 1970); + + AssertCriteriaAreEqual(expected, actual); + } + } } \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-05-15 19:22:20
|
Revision: 5821 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5821&view=rev Author: fabiomaulo Date: 2011-05-15 19:22:14 +0000 (Sun, 15 May 2011) Log Message: ----------- Test ported with bug fix Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/OneToOneMapper.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/MappingByCode/MappersTests/OneToOneMapperTest.cs Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/OneToOneMapper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/OneToOneMapper.cs 2011-05-15 19:15:09 UTC (rev 5820) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/OneToOneMapper.cs 2011-05-15 19:22:14 UTC (rev 5821) @@ -11,7 +11,7 @@ private readonly HbmOneToOne oneToOne; public OneToOneMapper(MemberInfo member, HbmOneToOne oneToOne) - : this(member, new AccessorPropertyMapper(member.DeclaringType, member.Name, x => oneToOne.access = x), oneToOne) {} + : this(member, member == null ? (IAccessorPropertyMapper)new NoMemberPropertyMapper() : new AccessorPropertyMapper(member.DeclaringType, member.Name, x => oneToOne.access = x), oneToOne) { } public OneToOneMapper(MemberInfo member, IAccessorPropertyMapper accessorMapper, HbmOneToOne oneToOne) { Added: trunk/nhibernate/src/NHibernate.Test/MappingByCode/MappersTests/OneToOneMapperTest.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/MappingByCode/MappersTests/OneToOneMapperTest.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/MappingByCode/MappersTests/OneToOneMapperTest.cs 2011-05-15 19:22:14 UTC (rev 5821) @@ -0,0 +1,143 @@ +using System; +using System.Linq; +using NHibernate.Mapping.ByCode; +using NHibernate.Cfg.MappingSchema; +using NHibernate.Mapping.ByCode.Impl; +using NUnit.Framework; +using SharpTestsEx; + +namespace NHibernate.Test.MappingByCode.MappersTests +{ + public class OneToOneMapperTest + { + private class MyClass + { + public Relation Relation { get; set; } + } + + private class Relation + { + public string Whatever { get; set; } + } + + [Test] + public void AssignCascadeStyle() + { + var hbm = new HbmOneToOne(); + var mapper = new OneToOneMapper(null, hbm); + mapper.Cascade(Mapping.ByCode.Cascade.Persist | Mapping.ByCode.Cascade.Remove); + hbm.cascade.Split(',').Select(w => w.Trim()).Should().Contain("persist").And.Contain("delete"); + } + + [Test] + public void AutoCleanUnsupportedCascadeStyle() + { + var hbm = new HbmOneToOne(); + var mapper = new OneToOneMapper(null, hbm); + mapper.Cascade(Mapping.ByCode.Cascade.Persist | Mapping.ByCode.Cascade.DeleteOrphans | Mapping.ByCode.Cascade.Remove); + hbm.cascade.Split(',').Select(w => w.Trim()).All(w => w.Satisfy(cascade => !cascade.Contains("orphan"))); + } + + [Test] + public void CanSetAccessor() + { + var member = typeof(MyClass).GetProperty("Relation"); + var hbm = new HbmOneToOne(); + var mapper = new OneToOneMapper(member, hbm); + + mapper.Access(Accessor.ReadOnly); + hbm.Access.Should().Be("readonly"); + } + + [Test] + public void CanSetLazyness() + { + var hbm = new HbmOneToOne(); + var mapper = new OneToOneMapper(null, hbm); + mapper.Lazy(LazyRelation.NoProxy); + hbm.Lazy.Should().Have.Value(); + hbm.Lazy.Should().Be(HbmLaziness.NoProxy); + } + + [Test] + public void CanSetConstrained() + { + var hbm = new HbmOneToOne(); + var mapper = new OneToOneMapper(null, hbm); + mapper.Constrained(true); + hbm.constrained.Should().Be.True(); + } + + [Test] + public void WhenNoMemberPropertyRefAcceptAnything() + { + var hbm = new HbmOneToOne(); + var mapper = new OneToOneMapper(null, hbm); + mapper.PropertyReference(typeof(Array).GetProperty("Length")); + + hbm.propertyref.Should().Be("Length"); + } + + [Test] + public void WhenNullMemberPropertyRefNull() + { + var hbm = new HbmOneToOne(); + var mapper = new OneToOneMapper(null, hbm); + mapper.PropertyReference(null); + + hbm.propertyref.Should().Be.Null(); + } + + [Test] + public void WhenMemberPropertyRefAcceptOnlyMemberOfExpectedType() + { + var hbm = new HbmOneToOne(); + var mapper = new OneToOneMapper(typeof(MyClass).GetProperty("Relation"), hbm); + mapper.PropertyReference(typeof(Relation).GetProperty("Whatever")); + + hbm.propertyref.Should().Be("Whatever"); + + Executing.This(() => mapper.PropertyReference(typeof(Array).GetProperty("Length"))).Should().Throw<ArgumentOutOfRangeException>(); + } + + + [Test] + public void CanSetFormula() + { + var member = For<MyClass>.Property(c => c.Relation); + var mapping = new HbmOneToOne(); + var mapper = new OneToOneMapper(member, mapping); + + mapper.Formula("SomeFormula"); + mapping.formula1.Should().Be("SomeFormula"); + } + + [Test] + public void WhenSetFormulaWithNullThenSetFormulaWithNull() + { + var member = For<MyClass>.Property(c => c.Relation); + var mapping = new HbmOneToOne(); + var mapper = new OneToOneMapper(member, mapping); + mapper.Formula(null); + mapping.formula.Should().Be.Null(); + mapping.formula1.Should().Be.Null(); + } + + [Test] + public void WhenSetFormulaWithMultipleLinesThenSetFormulaNode() + { + var member = For<MyClass>.Property(c => c.Relation); + var mapping = new HbmOneToOne(); + var mapper = new OneToOneMapper(member, mapping); + var formula = @"Line1 +Line2"; + mapper.Formula(formula); + mapping.formula1.Should().Be.Null(); + var hbmFormula = mapping.formula.First(); + hbmFormula.Text.Length.Should().Be(2); + hbmFormula.Text[0].Should().Be("Line1"); + hbmFormula.Text[1].Should().Be("Line2"); + mapping.formula1.Should().Be.Null(); + } + } +} \ 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-15 19:15:09 UTC (rev 5820) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-05-15 19:22:14 UTC (rev 5821) @@ -580,6 +580,7 @@ <Compile Include="MappingByCode\MappersTests\JoinedSubclassMapperTests\TablesSincronizationTests.cs" /> <Compile Include="MappingByCode\MappersTests\JoinMapperTests.cs" /> <Compile Include="MappingByCode\MappersTests\NaturalIdMapperTest.cs" /> + <Compile Include="MappingByCode\MappersTests\OneToOneMapperTest.cs" /> <Compile Include="MappingByCode\MappersTests\PropertyMapperTest.cs" /> <Compile Include="MappingByCode\MappersTests\SubclassMapperTests\SetPersisterTests.cs" /> <Compile Include="MappingByCode\MappersTests\SubclassMapperTests\TablesSincronizationTests.cs" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-05-15 19:27:49
|
Revision: 5822 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5822&view=rev Author: fabiomaulo Date: 2011-05-15 19:27:43 +0000 (Sun, 15 May 2011) Log Message: ----------- Test ported with bug fix Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ManyToOneMapper.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/MappingByCode/ManyToOneMapperTest.cs Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ManyToOneMapper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ManyToOneMapper.cs 2011-05-15 19:22:14 UTC (rev 5821) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ManyToOneMapper.cs 2011-05-15 19:27:43 UTC (rev 5822) @@ -14,7 +14,7 @@ private readonly MemberInfo member; public ManyToOneMapper(MemberInfo member, HbmManyToOne manyToOne, HbmMapping mapDoc) - : this(member, new AccessorPropertyMapper(member.DeclaringType, member.Name, x => manyToOne.access = x), manyToOne, mapDoc) {} + : this(member, member == null ? (IAccessorPropertyMapper)new NoMemberPropertyMapper() : new AccessorPropertyMapper(member.DeclaringType, member.Name, x => manyToOne.access = x), manyToOne, mapDoc) { } public ManyToOneMapper(MemberInfo member, IAccessorPropertyMapper accessorPropertyMapper, HbmManyToOne manyToOne, HbmMapping mapDoc) { Added: trunk/nhibernate/src/NHibernate.Test/MappingByCode/ManyToOneMapperTest.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/MappingByCode/ManyToOneMapperTest.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/MappingByCode/ManyToOneMapperTest.cs 2011-05-15 19:27:43 UTC (rev 5822) @@ -0,0 +1,305 @@ +using System; +using System.Linq; +using NHibernate.Mapping.ByCode; +using NHibernate.Cfg.MappingSchema; +using NHibernate.Mapping.ByCode.Impl; +using NUnit.Framework; +using SharpTestsEx; + +namespace NHibernate.Test.MappingByCode +{ + public class ManyToOneMapperTest + { + private class MyClass + { + public Relation Relation { get; set; } + public IRelation TheOtherRelation { get; set; } + } + + private interface IRelation + { + + } + + private class Relation : IRelation + { + + } + + private class Whatever + { + + } + + [Test] + public void AssignCascadeStyle() + { + var hbmMapping = new HbmMapping(); + var hbm = new HbmManyToOne(); + var mapper = new ManyToOneMapper(null, hbm, hbmMapping); + mapper.Cascade(Mapping.ByCode.Cascade.Persist | Mapping.ByCode.Cascade.Remove); + hbm.cascade.Split(',').Select(w => w.Trim()).Should().Contain("persist").And.Contain("delete"); + } + + [Test] + public void AutoCleanUnsupportedCascadeStyle() + { + var hbmMapping = new HbmMapping(); + var hbm = new HbmManyToOne(); + var mapper = new ManyToOneMapper(null, hbm, hbmMapping); + mapper.Cascade(Mapping.ByCode.Cascade.Persist | Mapping.ByCode.Cascade.DeleteOrphans | Mapping.ByCode.Cascade.Remove); + hbm.cascade.Split(',').Select(w => w.Trim()).All(w => w.Satisfy(cascade => !cascade.Contains("orphan"))); + } + + [Test] + public void CanSetAccessor() + { + var hbmMapping = new HbmMapping(); + var member = typeof(MyClass).GetProperty("Relation"); + var hbm = new HbmManyToOne(); + var mapper = new ManyToOneMapper(member, hbm, hbmMapping); + + mapper.Access(Accessor.ReadOnly); + hbm.Access.Should().Be("readonly"); + } + + [Test] + public void WhenSetDifferentColumnNameThenSetTheName() + { + var hbmMapping = new HbmMapping(); + var member = typeof(MyClass).GetProperty("Relation"); + var hbm = new HbmManyToOne(); + var mapper = new ManyToOneMapper(member, hbm, hbmMapping); + mapper.Column(cm => cm.Name("RelationId")); + + hbm.Columns.Should().Have.Count.EqualTo(1); + hbm.Columns.Single().name.Should().Be("RelationId"); + } + + [Test] + public void WhenSetDefaultColumnNameThenDoesNotSetTheName() + { + var hbmMapping = new HbmMapping(); + var member = typeof(MyClass).GetProperty("Relation"); + var mapping = new HbmManyToOne(); + var mapper = new ManyToOneMapper(member, mapping, hbmMapping); + mapper.Column(cm => cm.Name("Relation")); + mapping.column.Should().Be.Null(); + mapping.Columns.Should().Be.Empty(); + } + + [Test] + public void WhenSetBasicColumnValuesThenSetPlainValues() + { + var hbmMapping = new HbmMapping(); + var member = typeof(MyClass).GetProperty("Relation"); + var mapping = new HbmManyToOne(); + var mapper = new ManyToOneMapper(member, mapping, hbmMapping); + mapper.Column(cm => + { + cm.UniqueKey("theUnique"); + cm.NotNullable(true); + }); + mapping.Items.Should().Be.Null(); + mapping.uniquekey.Should().Be("theUnique"); + mapping.notnull.Should().Be(true); + mapping.notnullSpecified.Should().Be(true); + } + + [Test] + public void WhenSetColumnValuesThenAddColumnTag() + { + var hbmMapping = new HbmMapping(); + var member = typeof(MyClass).GetProperty("Relation"); + var mapping = new HbmManyToOne(); + var mapper = new ManyToOneMapper(member, mapping, hbmMapping); + mapper.Column(cm => + { + cm.SqlType("BIGINT"); + cm.NotNullable(true); + }); + mapping.Items.Should().Not.Be.Null(); + mapping.Columns.Should().Have.Count.EqualTo(1); + } + + [Test] + public void WhenSetBasicColumnValuesMoreThanOnesThenMergeColumn() + { + var hbmMapping = new HbmMapping(); + var member = typeof(MyClass).GetProperty("Relation"); + var mapping = new HbmManyToOne(); + var mapper = new ManyToOneMapper(member, mapping, hbmMapping); + mapper.Column(cm => cm.UniqueKey("theUnique")); + mapper.Column(cm => cm.NotNullable(true)); + + mapping.Items.Should().Be.Null(); + mapping.uniquekey.Should().Be("theUnique"); + mapping.notnull.Should().Be(true); + mapping.notnullSpecified.Should().Be(true); + } + + [Test] + public void WhenSetMultiColumnsValuesThenAddColumns() + { + var hbmMapping = new HbmMapping(); + var member = typeof(MyClass).GetProperty("Relation"); + var mapping = new HbmManyToOne(); + var mapper = new ManyToOneMapper(member, mapping, hbmMapping); + mapper.Columns(cm => + { + cm.Name("column1"); + cm.Length(50); + }, cm => + { + cm.Name("column2"); + cm.SqlType("VARCHAR(10)"); + }); + mapping.Columns.Should().Have.Count.EqualTo(2); + } + + [Test] + public void WhenSetMultiColumnsValuesThenAutoassignColumnNames() + { + var hbmMapping = new HbmMapping(); + var member = typeof(MyClass).GetProperty("Relation"); + var mapping = new HbmManyToOne(); + var mapper = new ManyToOneMapper(member, mapping, hbmMapping); + mapper.Columns(cm => cm.Length(50), cm => cm.SqlType("VARCHAR(10)")); + mapping.Columns.Should().Have.Count.EqualTo(2); + mapping.Columns.All(cm => cm.name.Satisfy(n => !string.IsNullOrEmpty(n))); + } + + [Test] + public void AfterSetMultiColumnsCantSetSimpleColumn() + { + var hbmMapping = new HbmMapping(); + var member = typeof(MyClass).GetProperty("Relation"); + var mapping = new HbmManyToOne(); + var mapper = new ManyToOneMapper(member, mapping, hbmMapping); + mapper.Columns(cm => cm.Length(50), cm => cm.SqlType("VARCHAR(10)")); + Executing.This(() => mapper.Column(cm => cm.Length(50))).Should().Throw<MappingException>(); + } + + [Test] + public void WhenSetBasicColumnValuesThroughShortCutThenMergeColumn() + { + var hbmMapping = new HbmMapping(); + var member = typeof(MyClass).GetProperty("Relation"); + var mapping = new HbmManyToOne(); + var mapper = new ManyToOneMapper(member, mapping, hbmMapping); + mapper.Column("pizza"); + mapper.NotNullable(true); + mapper.Unique(true); + mapper.UniqueKey("AA"); + mapper.Index("II"); + + mapping.Items.Should().Be.Null(); + mapping.column.Should().Be("pizza"); + mapping.notnull.Should().Be(true); + mapping.unique.Should().Be(true); + mapping.uniquekey.Should().Be("AA"); + mapping.index.Should().Be("II"); + } + + [Test] + public void WhenSetFetchModeToJoinThenSetFetch() + { + var hbmMapping = new HbmMapping(); + var member = typeof(MyClass).GetProperty("Relation"); + var mapping = new HbmManyToOne(); + var mapper = new ManyToOneMapper(member, mapping, hbmMapping); + + mapper.Fetch(FetchKind.Join); + + mapping.fetch.Should().Be(HbmFetchMode.Join); + mapping.fetchSpecified.Should().Be.True(); + } + + [Test] + public void WhenSetFetchModeToSelectThenResetFetch() + { + var hbmMapping = new HbmMapping(); + var member = typeof(MyClass).GetProperty("Relation"); + var mapping = new HbmManyToOne(); + var mapper = new ManyToOneMapper(member, mapping, hbmMapping); + + mapper.Fetch(FetchKind.Select); + + mapping.fetch.Should().Be(HbmFetchMode.Select); + mapping.fetchSpecified.Should().Be.False(); + } + + [Test] + public void CanForceClassRelation() + { + var hbmMapping = new HbmMapping(); + var member = typeof(MyClass).GetProperty("TheOtherRelation"); + var mapping = new HbmManyToOne(); + var mapper = new ManyToOneMapper(member, mapping, hbmMapping); + + mapper.Class(typeof(Relation)); + + mapping.Class.Should().Contain("Relation").And.Not.Contain("IRelation"); + } + + [Test] + public void WhenForceClassRelationToIncompatibleTypeThenThrows() + { + var hbmMapping = new HbmMapping(); + var member = typeof(MyClass).GetProperty("TheOtherRelation"); + var mapping = new HbmManyToOne(); + var mapper = new ManyToOneMapper(member, mapping, hbmMapping); + + Executing.This(() => mapper.Class(typeof(Whatever))).Should().Throw<ArgumentOutOfRangeException>(); + } + + [Test] + public void CanSetLazyness() + { + var hbmMapping = new HbmMapping(); + var member = typeof(MyClass).GetProperty("TheOtherRelation"); + var mapping = new HbmManyToOne(); + var mapper = new ManyToOneMapper(member, mapping, hbmMapping); + mapper.Lazy(LazyRelation.NoProxy); + mapping.Lazy.Should().Have.Value(); + mapping.Lazy.Should().Be(HbmLaziness.NoProxy); + } + + [Test] + public void CanSetUpdate() + { + var hbmMapping = new HbmMapping(); + var member = typeof(MyClass).GetProperty("Relation"); + var hbm = new HbmManyToOne(); + var mapper = new ManyToOneMapper(member, hbm, hbmMapping); + + mapper.Update(false); + hbm.update.Should().Be.False(); + } + + [Test] + public void CanSetInsert() + { + var hbmMapping = new HbmMapping(); + var member = typeof(MyClass).GetProperty("Relation"); + var hbm = new HbmManyToOne(); + var mapper = new ManyToOneMapper(member, hbm, hbmMapping); + + mapper.Insert(false); + hbm.insert.Should().Be.False(); + } + + [Test] + public void CanSetFk() + { + var hbmMapping = new HbmMapping(); + var member = typeof(MyClass).GetProperty("Relation"); + var hbm = new HbmManyToOne(); + var mapper = new ManyToOneMapper(member, hbm, hbmMapping); + + mapper.ForeignKey("MyFkName"); + + hbm.foreignkey.Should().Be("MyFkName"); + } + } +} \ 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-15 19:22:14 UTC (rev 5821) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-05-15 19:27:43 UTC (rev 5822) @@ -552,6 +552,7 @@ <Compile Include="MappingByCode\ExpliticMappingTests\SubclassPropertiesSplitsTests.cs" /> <Compile Include="MappingByCode\ExpliticMappingTests\VersionTests.cs" /> <Compile Include="MappingByCode\For.cs" /> + <Compile Include="MappingByCode\ManyToOneMapperTest.cs" /> <Compile Include="MappingByCode\MappersTests\AbstractPropertyContainerMapperTest.cs" /> <Compile Include="MappingByCode\MappersTests\ClassMapperTests\CheckMixingPOIDStrategiesTests.cs" /> <Compile Include="MappingByCode\MappersTests\ClassMapperTests\ClassMapperWithJoinPropertiesTest.cs" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-05-15 19:33:20
|
Revision: 5824 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5824&view=rev Author: fabiomaulo Date: 2011-05-15 19:33:14 +0000 (Sun, 15 May 2011) Log Message: ----------- Test ported with bug fix Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/AnyMapper.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/MappingByCode/MappersTests/AnyMapperTest.cs Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/AnyMapper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/AnyMapper.cs 2011-05-15 19:29:27 UTC (rev 5823) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/AnyMapper.cs 2011-05-15 19:33:14 UTC (rev 5824) @@ -20,7 +20,7 @@ private readonly MemberInfo member; public AnyMapper(MemberInfo member, System.Type foreignIdType, HbmAny any, HbmMapping mapDoc) - : this(member, foreignIdType, new AccessorPropertyMapper(member.DeclaringType, member.Name, x => any.access = x), any, mapDoc) {} + : this(member, foreignIdType, member == null ? (IAccessorPropertyMapper)new NoMemberPropertyMapper() : new AccessorPropertyMapper(member.DeclaringType, member.Name, x => any.access = x), any, mapDoc) { } public AnyMapper(MemberInfo member, System.Type foreignIdType, IAccessorPropertyMapper accessorMapper, HbmAny any, HbmMapping mapDoc) { Added: trunk/nhibernate/src/NHibernate.Test/MappingByCode/MappersTests/AnyMapperTest.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/MappingByCode/MappersTests/AnyMapperTest.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/MappingByCode/MappersTests/AnyMapperTest.cs 2011-05-15 19:33:14 UTC (rev 5824) @@ -0,0 +1,302 @@ +using System; +using System.Linq; +using NHibernate.Cfg.MappingSchema; +using NHibernate.Mapping.ByCode.Impl; +using NUnit.Framework; +using SharpTestsEx; + +namespace NHibernate.Test.MappingByCode.MappersTests +{ + public class AnyMapperTest + { + private class MyClass + { + public int Id { get; set; } + public MyReferenceClass MyReferenceClass { get; set; } + } + + private class MyReferenceClass + { + public int Id { get; set; } + } + + [Test] + public void AtCreationSetIdType() + { + var hbmMapping = new HbmMapping(); + var hbmAny = new HbmAny(); + new AnyMapper(null, typeof(int), hbmAny, hbmMapping); + hbmAny.idtype.Should().Be("Int32"); + } + + [Test] + public void AtCreationSetTheTwoRequiredColumnsNodes() + { + var hbmMapping = new HbmMapping(); + var hbmAny = new HbmAny(); + new AnyMapper(null, typeof(int), hbmAny, hbmMapping); + hbmAny.Columns.Should().Have.Count.EqualTo(2); + hbmAny.Columns.Select(c => c.name).All(n => n.Satisfy(name => !string.IsNullOrEmpty(name))); + } + + [Test] + public void CanSetIdTypeThroughIType() + { + var hbmMapping = new HbmMapping(); + var hbmAny = new HbmAny(); + var mapper = new AnyMapper(null, typeof(int), hbmAny, hbmMapping); + mapper.IdType(NHibernateUtil.Int64); + hbmAny.idtype.Should().Be("Int64"); + } + + [Test] + public void CanSetIdTypeThroughGenericMethod() + { + var hbmMapping = new HbmMapping(); + var hbmAny = new HbmAny(); + var mapper = new AnyMapper(null, typeof(int), hbmAny, hbmMapping); + mapper.IdType<long>(); + hbmAny.idtype.Should().Be("Int64"); + } + + [Test] + public void CanSetIdTypeThroughType() + { + var hbmMapping = new HbmMapping(); + var hbmAny = new HbmAny(); + var mapper = new AnyMapper(null, typeof(int), hbmAny, hbmMapping); + mapper.IdType(typeof(long)); + hbmAny.idtype.Should().Be("Int64"); + } + + [Test] + public void CanSetMetaTypeThroughIType() + { + var hbmMapping = new HbmMapping(); + var hbmAny = new HbmAny(); + var mapper = new AnyMapper(null, typeof(int), hbmAny, hbmMapping); + mapper.MetaType(NHibernateUtil.Character); + hbmAny.MetaType.Should().Be("Char"); + } + + [Test] + public void CanSetMetaTypeThroughGenericMethod() + { + var hbmMapping = new HbmMapping(); + var hbmAny = new HbmAny(); + var mapper = new AnyMapper(null, typeof(int), hbmAny, hbmMapping); + mapper.MetaType<char>(); + hbmAny.MetaType.Should().Be("Char"); + } + + [Test] + public void CanSetMetaTypeThroughType() + { + var hbmMapping = new HbmMapping(); + var hbmAny = new HbmAny(); + var mapper = new AnyMapper(null, typeof(int), hbmAny, hbmMapping); + mapper.MetaType(typeof(char)); + hbmAny.MetaType.Should().Be("Char"); + } + + [Test] + public void CanSetCascade() + { + var hbmMapping = new HbmMapping(); + var hbmAny = new HbmAny(); + var mapper = new AnyMapper(null, typeof(int), hbmAny, hbmMapping); + mapper.Cascade(Mapping.ByCode.Cascade.All); + hbmAny.cascade.Should().Be("all"); + } + + [Test] + public void AutoCleanInvalidCascade() + { + var hbmMapping = new HbmMapping(); + var hbmAny = new HbmAny(); + var mapper = new AnyMapper(null, typeof(int), hbmAny, hbmMapping); + mapper.Cascade(Mapping.ByCode.Cascade.All | Mapping.ByCode.Cascade.DeleteOrphans); + hbmAny.cascade.Should().Be("all"); + } + + [Test] + public void CanSetIndex() + { + var hbmMapping = new HbmMapping(); + var hbmAny = new HbmAny(); + var mapper = new AnyMapper(null, typeof(int), hbmAny, hbmMapping); + mapper.Index("pizza"); + hbmAny.index.Should().Be("pizza"); + } + + [Test] + public void CanSetLazy() + { + var hbmMapping = new HbmMapping(); + var hbmAny = new HbmAny(); + var mapper = new AnyMapper(null, typeof(int), hbmAny, hbmMapping); + mapper.Lazy(true); + hbmAny.lazy.Should().Be(true); + } + + [Test] + public void WhenSetIdColumnPropertiesThenWorkOnSameHbmColumnCreatedAtCtor() + { + const int idColumnIndex = 1; + var hbmMapping = new HbmMapping(); + var hbmAny = new HbmAny(); + var mapper = new AnyMapper(null, typeof(int), hbmAny, hbmMapping); + var columnsBefore = hbmAny.Columns.ToArray(); + mapper.Columns(idcm => idcm.Length(10), metacm => { }); + var columnsAfter = hbmAny.Columns.ToArray(); + columnsBefore[idColumnIndex].Should().Be.SameInstanceAs(columnsAfter[idColumnIndex]); + columnsBefore[idColumnIndex].length.Should().Be("10"); + } + + [Test] + public void WhenSetMetaColumnPropertiesThenWorkOnSameHbmColumnCreatedAtCtor() + { + // The first column in the mapping is the MetaValue + const int metaValueColumnIndex = 0; + var hbmMapping = new HbmMapping(); + var hbmAny = new HbmAny(); + var mapper = new AnyMapper(null, typeof(int), hbmAny, hbmMapping); + var columnsBefore = hbmAny.Columns.ToArray(); + mapper.Columns(idcm => { }, metacm => metacm.Length(500)); + var columnsAfter = hbmAny.Columns.ToArray(); + columnsBefore[metaValueColumnIndex].Should().Be.SameInstanceAs(columnsAfter[metaValueColumnIndex]); + columnsBefore[metaValueColumnIndex].length.Should().Be("500"); + } + + [Test] + public void MetaTypeShouldBeImmutable() + { + var hbmMapping = new HbmMapping(); + var hbmAny = new HbmAny(); + var mapper = new AnyMapper(null, typeof(int), hbmAny, hbmMapping); + mapper.MetaValue('A', typeof(MyReferenceClass)); + Executing.This(() => mapper.MetaType(NHibernateUtil.Int32)).Should().Throw<ArgumentException>(); + Executing.This(mapper.MetaType<int>).Should().Throw<ArgumentException>(); + } + + [Test] + public void WhenNullParameterThenThrow() + { + var hbmMapping = new HbmMapping(); + var hbmAny = new HbmAny(); + var mapper = new AnyMapper(null, typeof(int), hbmAny, hbmMapping); + Executing.This(() => mapper.MetaValue(null, typeof(MyReferenceClass))).Should().Throw<ArgumentNullException>(); + Executing.This(() => mapper.MetaValue('A', null)).Should().Throw<ArgumentNullException>(); + } + + [Test] + public void WhenSetFirstMetaValueThenSetMetaTypeIfNotClass() + { + var hbmMapping = new HbmMapping(); + var hbmAny = new HbmAny(); + var mapper = new AnyMapper(null, typeof(int), hbmAny, hbmMapping); + mapper.MetaValue('A', typeof(MyReferenceClass)); + hbmAny.MetaType.Should().Be("Char"); + } + + [Test] + public void WhenSetMetaValueWithClassThenThrow() + { + var hbmMapping = new HbmMapping(); + var hbmAny = new HbmAny(); + var mapper = new AnyMapper(null, typeof(int), hbmAny, hbmMapping); + Executing.This(() => mapper.MetaValue(typeof(MyReferenceClass), typeof(MyReferenceClass))).Should().Throw<ArgumentOutOfRangeException>(); + } + + [Test] + public void WhenSetSecondMetaValueThenCheckCompatibility() + { + var hbmMapping = new HbmMapping(); + var hbmAny = new HbmAny(); + var mapper = new AnyMapper(null, typeof(int), hbmAny, hbmMapping); + mapper.MetaValue('A', typeof(MyReferenceClass)); + Executing.This(() => mapper.MetaValue(5, typeof(MyClass))).Should().Throw<ArgumentException>(); + } + + [Test] + public void WhenDuplicatedMetaValueThenRegisterOne() + { + var hbmMapping = new HbmMapping(); + var hbmAny = new HbmAny(); + var mapper = new AnyMapper(null, typeof(int), hbmAny, hbmMapping); + mapper.MetaValue('A', typeof(MyReferenceClass)); + mapper.MetaValue('A', typeof(MyReferenceClass)); + hbmAny.metavalue.Should().Have.Count.EqualTo(1); + } + + [Test] + public void WhenDuplicatedMetaValueWithDifferentTypeThenThrow() + { + var hbmMapping = new HbmMapping(); + var hbmAny = new HbmAny(); + var mapper = new AnyMapper(null, typeof(int), hbmAny, hbmMapping); + mapper.MetaValue('A', typeof(MyReferenceClass)); + Executing.This(() => mapper.MetaValue('A', typeof(MyClass))).Should().Throw<ArgumentException>(); + } + + [Test] + public void WhenSetTwoMetaValueThenHasTwoMetaValues() + { + var hbmMapping = new HbmMapping(); + var hbmAny = new HbmAny(); + var mapper = new AnyMapper(null, typeof(int), hbmAny, hbmMapping); + mapper.MetaValue('A', typeof(MyReferenceClass)); + mapper.MetaValue('B', typeof(MyClass)); + hbmAny.metavalue.Should().Have.Count.EqualTo(2); + hbmAny.metavalue.Select(mv => mv.value).Should().Have.SameValuesAs("A", "B"); + hbmAny.metavalue.Select(mv => mv.@class).Satisfy(c => c.Any(clazz => clazz.Contains("MyReferenceClass"))); + hbmAny.metavalue.Select(mv => mv.@class).Satisfy(c => c.Any(clazz => clazz.Contains("MyClass"))); + } + + [Test] + public void AtCreationSetColumnsUsingMemberName() + { + var member = typeof(MyClass).GetProperty("MyReferenceClass"); + var hbmMapping = new HbmMapping(); + var hbmAny = new HbmAny(); + new AnyMapper(member, typeof(int), hbmAny, hbmMapping); + hbmAny.Columns.ElementAt(0).name.Should().Contain("MyReferenceClass"); + hbmAny.Columns.ElementAt(1).name.Should().Contain("MyReferenceClass"); + } + + [Test] + public void IdMetaTypeShouldBeImmutableAfterAddMetaValues() + { + var hbmMapping = new HbmMapping(); + var hbmAny = new HbmAny(); + var mapper = new AnyMapper(null, typeof(int), hbmAny, hbmMapping); + mapper.MetaValue('A', typeof(MyReferenceClass)); + Executing.This(() => mapper.IdType(NHibernateUtil.Int32)).Should().NotThrow(); + Executing.This(mapper.IdType<int>).Should().NotThrow(); + Executing.This(mapper.IdType<string>).Should().Throw<ArgumentException>(); + Executing.This(() => mapper.IdType(NHibernateUtil.String)).Should().Throw<ArgumentException>(); + } + + [Test] + public void CanSetUpdate() + { + var hbmMapping = new HbmMapping(); + var hbmAny = new HbmAny(); + var mapper = new AnyMapper(null, typeof(int), hbmAny, hbmMapping); + + mapper.Update(false); + hbmAny.update.Should().Be.False(); + } + + [Test] + public void CanSetInsert() + { + var hbmMapping = new HbmMapping(); + var hbmAny = new HbmAny(); + var mapper = new AnyMapper(null, typeof(int), hbmAny, hbmMapping); + + mapper.Insert(false); + hbmAny.insert.Should().Be.False(); + } + } +} \ 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-15 19:29:27 UTC (rev 5823) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-05-15 19:33:14 UTC (rev 5824) @@ -552,6 +552,7 @@ <Compile Include="MappingByCode\ExpliticMappingTests\SubclassPropertiesSplitsTests.cs" /> <Compile Include="MappingByCode\ExpliticMappingTests\VersionTests.cs" /> <Compile Include="MappingByCode\For.cs" /> + <Compile Include="MappingByCode\MappersTests\AnyMapperTest.cs" /> <Compile Include="MappingByCode\MappersTests\ManyToOneMapperTest.cs" /> <Compile Include="MappingByCode\MappersTests\AbstractPropertyContainerMapperTest.cs" /> <Compile Include="MappingByCode\MappersTests\ClassMapperTests\CheckMixingPOIDStrategiesTests.cs" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-05-15 19:39:17
|
Revision: 5825 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5825&view=rev Author: fabiomaulo Date: 2011-05-15 19:39:11 +0000 (Sun, 15 May 2011) Log Message: ----------- Test ported with bug fix Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/IdMapper.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/MappingByCode/MappersTests/IdMapperTest.cs Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/IdMapper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/IdMapper.cs 2011-05-15 19:33:14 UTC (rev 5824) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/IdMapper.cs 2011-05-15 19:39:11 UTC (rev 5825) @@ -79,7 +79,12 @@ if(hbmId.name == null) { // no member for the id - hbmId.type1 = generator.DefaultReturnType.GetNhTypeName(); + var defaultReturnType = generator.DefaultReturnType; + // where a DefaultReturnType is not available, let NH discover it during the mapping-binding process + if (defaultReturnType != null) + { + hbmId.type1 = defaultReturnType.GetNhTypeName(); + } } object generatorParameters = generator.Params; if (generatorParameters != null) Added: trunk/nhibernate/src/NHibernate.Test/MappingByCode/MappersTests/IdMapperTest.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/MappingByCode/MappersTests/IdMapperTest.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/MappingByCode/MappersTests/IdMapperTest.cs 2011-05-15 19:39:11 UTC (rev 5825) @@ -0,0 +1,146 @@ +using System.Linq; +using System.Reflection; +using NHibernate.Mapping.ByCode; +using NHibernate.Cfg.MappingSchema; +using NHibernate.Mapping.ByCode.Impl; +using NUnit.Framework; +using SharpTestsEx; + +namespace NHibernate.Test.MappingByCode.MappersTests +{ + public class IdMapperTest + { + // The strategy Assigned is the default and does not need the "generator" + //public void SetGeneratorAtCtor() + //{ + // var hbmId = new HbmId(); + // new IdMapper(hbmId); + // hbmId.generator.Should().Not.Be.Null(); + //} + + [Test] + public void CanSetGenerator() + { + var hbmId = new HbmId(); + new IdMapper(hbmId).Generator(Generators.HighLow); + hbmId.generator.@class.Should().Be.EqualTo("hilo"); + } + + [Test] + public void CanSetGeneratorWithParameters() + { + var hbmId = new HbmId(); + new IdMapper(hbmId).Generator(Generators.HighLow, p => p.Params(new { max_low = 99, where = "TableName" })); + hbmId.generator.@class.Should().Be.EqualTo("hilo"); + hbmId.generator.param.Should().Have.Count.EqualTo(2); + hbmId.generator.param.Select(p => p.name).Should().Have.SameValuesAs("max_low", "where"); + hbmId.generator.param.Select(p => p.GetText()).Should().Have.SameValuesAs("99", "TableName"); + } + + [Test] + public void CanSetGeneratorGuid() + { + var hbmId = new HbmId(); + new IdMapper(hbmId).Generator(Generators.Guid); + hbmId.generator.@class.Should().Be.EqualTo("guid"); + } + + [Test] + public void CanSetGeneratorGuidComb() + { + var hbmId = new HbmId(); + new IdMapper(hbmId).Generator(Generators.GuidComb); + hbmId.generator.@class.Should().Be.EqualTo("guid.comb"); + } + + [Test] + public void CanSetGeneratorSequence() + { + var hbmId = new HbmId(); + new IdMapper(hbmId).Generator(Generators.Sequence); + hbmId.generator.@class.Should().Be.EqualTo("sequence"); + } + + [Test] + public void CanSetGeneratorIdentity() + { + var hbmId = new HbmId(); + new IdMapper(hbmId).Generator(Generators.Identity); + hbmId.generator.@class.Should().Be.EqualTo("identity"); + } + + private class MyClass + { + public int Id { get; set; } + public Related OneToOne { get; set; } + } + + private class Related + { + public int Id { get; set; } + } + + [Test] + public void CanSetGeneratorForeign() + { + var hbmId = new HbmId(); + new IdMapper(hbmId).Generator(Generators.Foreign<MyClass>(mc => mc.OneToOne)); + hbmId.generator.@class.Should().Be.EqualTo("foreign"); + hbmId.generator.param.Should().Not.Be.Null().And.Have.Count.EqualTo(1); + hbmId.generator.param.Single().Satisfy(p => p.name == "property" && p.GetText() == "OneToOne"); + } + + [Test] + public void CanSetGeneratorAssigned() + { + var hbmId = new HbmId(); + new IdMapper(hbmId).Generator(Generators.Assigned); + hbmId.generator.@class.Should().Be.EqualTo("assigned"); + } + + private class BaseEntity + { + private int id; + + public int Id + { + get { return id; } + } + } + + private class Entity : BaseEntity + { + + } + + [Test] + public void WhenHasMemberCanSetAccessor() + { + var member = typeof(Entity).GetProperty("Id", + BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic + | BindingFlags.FlattenHierarchy); + var hbmId = new HbmId(); + var mapper = new IdMapper(member, hbmId); + mapper.Access(Accessor.NoSetter); + hbmId.access.Should().Be("nosetter.camelcase"); + } + + [Test] + public void CanSetColumnName() + { + var hbmId = new HbmId(); + var mapper = new IdMapper(null, hbmId); + mapper.Column("MyName"); + hbmId.Columns.Single().name.Should().Be("MyName"); + } + + [Test] + public void CanSetLength() + { + var hbmId = new HbmId(); + var mapper = new IdMapper(null, hbmId); + mapper.Length(10); + hbmId.length.Should().Be("10"); + } + } +} \ 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-15 19:33:14 UTC (rev 5824) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-05-15 19:39:11 UTC (rev 5825) @@ -553,6 +553,7 @@ <Compile Include="MappingByCode\ExpliticMappingTests\VersionTests.cs" /> <Compile Include="MappingByCode\For.cs" /> <Compile Include="MappingByCode\MappersTests\AnyMapperTest.cs" /> + <Compile Include="MappingByCode\MappersTests\IdMapperTest.cs" /> <Compile Include="MappingByCode\MappersTests\ManyToOneMapperTest.cs" /> <Compile Include="MappingByCode\MappersTests\AbstractPropertyContainerMapperTest.cs" /> <Compile Include="MappingByCode\MappersTests\ClassMapperTests\CheckMixingPOIDStrategiesTests.cs" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-05-17 17:45:16
|
Revision: 5830 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5830&view=rev Author: fabiomaulo Date: 2011-05-17 17:45:09 +0000 (Tue, 17 May 2011) Log Message: ----------- Fix NH-2705 and NH-2615 Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/HqlSqlWalker.cs trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/FromClause.cs trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/FromElement.cs trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/FromElementFactory.cs trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/FromElementType.cs trunk/nhibernate/src/NHibernate/NHibernate.csproj trunk/nhibernate/src/NHibernate/PropertyNotFoundException.cs trunk/nhibernate/src/NHibernate/Type/ComponentType.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2705/ItemBase.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2705/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2705/SubItemBase.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2705/Test.cs Added Paths: ----------- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/ComponentJoin.cs Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/HqlSqlWalker.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/HqlSqlWalker.cs 2011-05-16 14:37:27 UTC (rev 5829) +++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/HqlSqlWalker.cs 2011-05-17 17:45:09 UTC (rev 5830) @@ -678,23 +678,30 @@ // to the root dot node. dot.Resolve( true, false, alias == null ? null : alias.Text ); - FromElement fromElement = dot.GetImpliedJoin(); - - if (fromElement == null) + FromElement fromElement; + if (dot.DataType != null && dot.DataType.IsComponentType) { - throw new InvalidPathException("Invalid join: " + dot.Path); + var factory = new FromElementFactory(CurrentFromClause, dot.GetLhs().FromElement, dot.PropertyPath, alias == null ? null : alias.Text, null, false); + fromElement = factory.CreateComponentJoin((ComponentType) dot.DataType); } - - fromElement.SetAllPropertyFetch(propertyFetch!=null); - - if ( with != null ) + else { - if ( fetch ) + fromElement = dot.GetImpliedJoin(); + if (fromElement == null) { - throw new SemanticException( "with-clause not allowed on fetched associations; use filters" ); + throw new InvalidPathException("Invalid join: " + dot.Path); } + fromElement.SetAllPropertyFetch(propertyFetch != null); - HandleWithFragment( fromElement, with ); + if (with != null) + { + if (fetch) + { + throw new SemanticException("with-clause not allowed on fetched associations; use filters"); + } + + HandleWithFragment(fromElement, with); + } } if ( log.IsDebugEnabled ) Added: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/ComponentJoin.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/ComponentJoin.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/ComponentJoin.cs 2011-05-17 17:45:09 UTC (rev 5830) @@ -0,0 +1,175 @@ +using System; +using System.Text; +using NHibernate.Persister.Collection; +using NHibernate.Persister.Entity; +using NHibernate.Type; +using NHibernate.Util; + +namespace NHibernate.Hql.Ast.ANTLR.Tree +{ + public class ComponentJoin : FromElement + { + private readonly string columns; + private readonly string componentPath; + private readonly string componentProperty; + private readonly ComponentType componentType; + + public ComponentJoin(FromClause fromClause, FromElement origin, string alias, string componentPath, ComponentType componentType) + : base(fromClause, origin, alias) + { + this.componentPath = componentPath; + this.componentType = componentType; + componentProperty = StringHelper.Unqualify(componentPath); + fromClause.AddJoinByPathMap(componentPath, this); + InitializeComponentJoin(new ComponentFromElementType(this)); + + string[] cols = origin.GetPropertyMapping("").ToColumns(TableAlias, componentProperty); + columns = string.Join(", ", cols); + } + + public string ComponentPath + { + get { return componentPath; } + } + + public ComponentType ComponentType + { + get { return componentType; } + } + + public string ComponentProperty + { + get { return componentProperty; } + } + + public override IType DataType + { + get { return ComponentType; } + set { base.DataType = value; } + } + + public override string GetIdentityColumn() + { + return columns; + } + + public override string GetDisplayText() + { + return "ComponentJoin{path=" + ComponentPath + ", type=" + componentType.ReturnedClass + "}"; + } + + #region Nested type: ComponentFromElementType + + public class ComponentFromElementType : FromElementType + { + private readonly ComponentJoin fromElement; + private readonly IPropertyMapping propertyMapping; + + public ComponentFromElementType(ComponentJoin fromElement) + : base(fromElement) + { + this.fromElement = fromElement; + propertyMapping = new ComponentPropertyMapping(this); + } + + public ComponentJoin FromElement + { + get { return fromElement; } + } + + public override IType DataType + { + get { return fromElement.ComponentType; } + } + + public override IQueryableCollection QueryableCollection + { + get { return null; } + set { base.QueryableCollection = value; } + } + + public override IPropertyMapping GetPropertyMapping(string propertyName) + { + return propertyMapping; + } + + public override IType GetPropertyType(string propertyName, string propertyPath) + { + int index = fromElement.ComponentType.GetPropertyIndex(propertyName); + return fromElement.ComponentType.Subtypes[index]; + } + + public override string RenderScalarIdentifierSelect(int i) + { + String[] cols = GetBasePropertyMapping().ToColumns(fromElement.TableAlias, fromElement.ComponentProperty); + var buf = new StringBuilder(); + // For property references generate <tablealias>.<columnname> as <projectionalias> + for (int j = 0; j < cols.Length; j++) + { + string column = cols[j]; + if (j > 0) + { + buf.Append(", "); + } + buf.Append(column).Append(" as ").Append(NameGenerator.ScalarName(i, j)); + } + return buf.ToString(); + } + + protected IPropertyMapping GetBasePropertyMapping() + { + return fromElement.Origin.GetPropertyMapping(""); + } + + #region Nested type: ComponentPropertyMapping + + private class ComponentPropertyMapping : IPropertyMapping + { + private readonly ComponentFromElementType fromElementType; + + public ComponentPropertyMapping(ComponentFromElementType fromElementType) + { + this.fromElementType = fromElementType; + } + + #region IPropertyMapping Members + + public IType Type + { + get { return fromElementType.FromElement.ComponentType; } + } + + public IType ToType(string propertyName) + { + return fromElementType.GetBasePropertyMapping().ToType(GetPropertyPath(propertyName)); + } + + public bool TryToType(string propertyName, out IType type) + { + return fromElementType.GetBasePropertyMapping().TryToType(GetPropertyPath(propertyName), out type); + } + + public string[] ToColumns(string alias, string propertyName) + { + return fromElementType.GetBasePropertyMapping().ToColumns(alias, GetPropertyPath(propertyName)); + } + + public string[] ToColumns(string propertyName) + { + return fromElementType.GetBasePropertyMapping().ToColumns(GetPropertyPath(propertyName)); + } + + #endregion + + private string GetPropertyPath(string propertyName) + { + return fromElementType.FromElement.ComponentPath + '.' + propertyName; + } + } + + #endregion + } + + #endregion + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/FromClause.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/FromClause.cs 2011-05-16 14:37:27 UTC (rev 5829) +++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/FromClause.cs 2011-05-17 17:45:09 UTC (rev 5830) @@ -342,7 +342,7 @@ string tableAlias = element.TableAlias; if (tableAlias != null) { - _fromElementByTableAlias.Add(tableAlias, element); + _fromElementByTableAlias[tableAlias] = element; } } Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/FromElement.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/FromElement.cs 2011-05-16 14:37:27 UTC (rev 5829) +++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/FromElement.cs 2011-05-17 17:45:09 UTC (rev 5830) @@ -39,12 +39,35 @@ private string _withClauseFragment; private string _withClauseJoinAlias; private bool _filter; + private IToken _token; - public FromElement(IToken token) : base(token) { + _token= token; } + /// <summary> + /// Constructor form used to initialize <see cref="ComponentJoin"/>. + /// </summary> + /// <param name="fromClause">The FROM clause to which this element belongs.</param> + /// <param name="origin">The origin (LHS) of this element.</param> + /// <param name="alias">The alias applied to this element.</param> + protected FromElement(FromClause fromClause,FromElement origin,string alias):this(origin._token) + { + _fromClause = fromClause; + _origin = origin; + _classAlias = alias; + _tableAlias = origin.TableAlias; + base.Initialize(fromClause.Walker); + } + + protected void InitializeComponentJoin(FromElementType elementType) + { + _elementType = elementType; + _fromClause.RegisterFromElement(this); + _initialized = true; + } + public void SetAllPropertyFetch(bool fetch) { _isAllPropertyFetch = fetch; @@ -429,7 +452,7 @@ return _elementType.GetPropertyType(propertyName, propertyPath); } - public string GetIdentityColumn() + public virtual string GetIdentityColumn() { CheckInitialized(); string table = TableAlias; Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/FromElementFactory.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/FromElementFactory.cs 2011-05-16 14:37:27 UTC (rev 5829) +++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/FromElementFactory.cs 2011-05-17 17:45:09 UTC (rev 5830) @@ -562,5 +562,10 @@ } } + public FromElement CreateComponentJoin(ComponentType type) + { + // need to create a "place holder" from-element that can store the component/alias for this component join + return new ComponentJoin(_fromClause, _origin, _classAlias, _path, type); + } } } Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/FromElementType.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/FromElementType.cs 2011-05-16 14:37:27 UTC (rev 5829) +++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/FromElementType.cs 2011-05-17 17:45:09 UTC (rev 5830) @@ -42,6 +42,11 @@ } } + protected FromElementType(FromElement fromElement) + { + _fromElement = fromElement; + } + public IEntityPersister EntityPersister { get { return _persister; } @@ -57,7 +62,7 @@ get { return _fromElement.CollectionTableAlias; } } - public IType DataType + public virtual IType DataType { get { @@ -167,7 +172,7 @@ /// </summary> /// <param name="i">the sequence of the returned type</param> /// <returns>the identifier select with the column alias.</returns> - public string RenderScalarIdentifierSelect(int i) + public virtual string RenderScalarIdentifierSelect(int i) { CheckInitialized(); string[] cols = GetPropertyMapping(Persister.Entity.EntityPersister.EntityID).ToColumns(TableAlias, Persister.Entity.EntityPersister.EntityID); @@ -273,7 +278,7 @@ } } - public IPropertyMapping GetPropertyMapping(string propertyName) + public virtual IPropertyMapping GetPropertyMapping(string propertyName) { CheckInitialized(); @@ -317,7 +322,7 @@ /// <param name="propertyName">The last part of the full path to the property.</param> /// <param name="propertyPath">The full property path.</param> /// <returns>The type</returns> - public IType GetPropertyType(string propertyName, string propertyPath) + public virtual IType GetPropertyType(string propertyName, string propertyPath) { CheckInitialized(); @@ -359,7 +364,7 @@ get { return (_persister is IQueryable) ? (IQueryable) _persister : null; } } - public IQueryableCollection QueryableCollection + public virtual IQueryableCollection QueryableCollection { get { return _queryableCollection; } set Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2011-05-16 14:37:27 UTC (rev 5829) +++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2011-05-17 17:45:09 UTC (rev 5830) @@ -206,6 +206,7 @@ <Compile Include="FetchMode.cs" /> <Compile Include="FlushMode.cs" /> <Compile Include="HibernateException.cs" /> + <Compile Include="Hql\Ast\ANTLR\Tree\ComponentJoin.cs" /> <Compile Include="Hql\Classic\ClauseParser.cs" /> <Compile Include="Hql\Classic\FromParser.cs" /> <Compile Include="Hql\Classic\FromPathExpressionParser.cs" /> Modified: trunk/nhibernate/src/NHibernate/PropertyNotFoundException.cs =================================================================== --- trunk/nhibernate/src/NHibernate/PropertyNotFoundException.cs 2011-05-16 14:37:27 UTC (rev 5829) +++ trunk/nhibernate/src/NHibernate/PropertyNotFoundException.cs 2011-05-17 17:45:09 UTC (rev 5830) @@ -38,7 +38,7 @@ /// <param name="targetType">The <see cref="System.Type" /> that is missing the field</param> /// <param name="propertyName">The name of the missing property</param> public PropertyNotFoundException(System.Type targetType, string propertyName) - : base(String.Format("Could not find field '{0}' in class '{1}'", + : base(String.Format("Could not find property nor field '{0}' in class '{1}'", propertyName, targetType)) { this.targetType = targetType; Modified: trunk/nhibernate/src/NHibernate/Type/ComponentType.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Type/ComponentType.cs 2011-05-16 14:37:27 UTC (rev 5829) +++ trunk/nhibernate/src/NHibernate/Type/ComponentType.cs 2011-05-17 17:45:09 UTC (rev 5830) @@ -688,5 +688,18 @@ { get { return true; } } + + public int GetPropertyIndex(string name) + { + string[] names = PropertyNames; + for (int i = 0; i < names.Length; i++) + { + if (names[i].Equals(name)) + { + return i; + } + } + throw new PropertyNotFoundException(ReturnedClass, name); + } } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2705/ItemBase.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2705/ItemBase.cs 2011-05-16 14:37:27 UTC (rev 5829) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2705/ItemBase.cs 2011-05-17 17:45:09 UTC (rev 5830) @@ -7,6 +7,4 @@ } public class ItemWithComponentSubItem : ItemBase {} - - public class ItemWithManyToOneSubItem : ItemBase {} } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2705/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2705/Mappings.hbm.xml 2011-05-16 14:37:27 UTC (rev 5829) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2705/Mappings.hbm.xml 2011-05-17 17:45:09 UTC (rev 5830) @@ -14,20 +14,8 @@ <many-to-one class="SubItemDetails" name="Details" column="SubItemDetails_id"/> </component> </joined-subclass> - <joined-subclass name="ItemWithManyToOneSubItem"> - <key column="ItemBase_id"/> - <many-to-one class="SubItemEntity" name="SubItem" column="SubItem_id"/> - </joined-subclass> </class> - <class name="SubItemEntity"> - <id name="Id" type="int"> - <generator class="native" /> - </id> - <property name="Name" /> - <many-to-one class="SubItemDetails" name="Details" column="SubItemDetails_id" /> - </class> - <class name="SubItemDetails"> <id name="Id" type="int"> <generator class="native" /> Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2705/SubItemBase.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2705/SubItemBase.cs 2011-05-16 14:37:27 UTC (rev 5829) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2705/SubItemBase.cs 2011-05-17 17:45:09 UTC (rev 5830) @@ -1,5 +1,7 @@ namespace NHibernate.Test.NHSpecificTest.NH2705 { + // NOTE: an Entity and a Component in the same hierarchy is not supported + // we are using this trick just to ""simplify"" the test. public class SubItemBase { public virtual string Name { get; set; } @@ -7,9 +9,4 @@ } public class SubItemComponent : SubItemBase {} - - public class SubItemEntity : SubItemBase - { - public virtual int Id { get; set; } - } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2705/Test.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2705/Test.cs 2011-05-16 14:37:27 UTC (rev 5829) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2705/Test.cs 2011-05-17 17:45:09 UTC (rev 5830) @@ -8,7 +8,7 @@ namespace NHibernate.Test.NHSpecificTest.NH2705 { - [TestFixture, Ignore("Not fixed yet")] + [TestFixture] public class Test : BugTestCase { private static IEnumerable<T> GetAndFetch<T>(string name, ISession session) where T : ItemBase @@ -30,22 +30,26 @@ } [Test] - public void Fetch_OnManyToOne_ShouldNotThrow() + public void HqlQueryWithFetch_WhenDerivedClassesUseComponentAndManyToOne_DoesNotGenerateInvalidSql() { using (ISession s = OpenSession()) { - Executing.This(() => GetAndFetch<ItemWithManyToOneSubItem>("hello", s)).Should().NotThrow(); + using (var log = new SqlLogSpy()) + { + Executing.This(() => s.CreateQuery("from ItemWithComponentSubItem i left join fetch i.SubItem").List() + ).Should().NotThrow(); + } } } [Test] - public void HqlQueryWithFetch_WhenDerivedClassesUseComponentAndManyToOne_DoesNotGenerateInvalidSql() + public void HqlQueryWithFetch_WhenDerivedClassesUseComponentAndEagerFetchManyToOne_DoesNotGenerateInvalidSql() { using (ISession s = OpenSession()) { using (var log = new SqlLogSpy()) { - Executing.This(() => s.CreateQuery("from ItemBase i left join fetch i.SubItem").List() + Executing.This(() => s.CreateQuery("from ItemWithComponentSubItem i left join fetch i.SubItem.Details").List() ).Should().NotThrow(); } } @@ -64,11 +68,23 @@ // fetching second level properties should work too - Executing.This(() => s.Query<ItemBase>() + Executing.This(() => s.Query<ItemWithComponentSubItem>() .Fetch(p => p.SubItem).ThenFetch(p => p.Details).ToList() ).Should().NotThrow(); } } } + + [Test, Ignore("Locked by re-linq")] + public void LinqQueryWithFetch_WhenDerivedClassesUseComponentAndEagerFetchManyToOne_DoesNotGenerateInvalidSql() + { + using (ISession s = OpenSession()) + { + using (var log = new SqlLogSpy()) + { + Executing.This(() => s.Query<ItemWithComponentSubItem>().Fetch(p => p.SubItem.Details).ToList()).Should().NotThrow(); + } + } + } } } \ 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-17 21:23:56
|
Revision: 5834 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5834&view=rev Author: fabiomaulo Date: 2011-05-17 21:23:50 +0000 (Tue, 17 May 2011) Log Message: ----------- - Fix NH-2568 - added persister conf. support to mapping-by-code Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Cfg/Configuration.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/ICollectionPropertiesMapper.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/BagMapper.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/CollectionPropertiesCustomizer.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/IdBagMapper.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ListMapper.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/MapMapper.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/SetMapper.cs trunk/nhibernate/src/NHibernate/Persister/PersisterFactory.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2568/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2568/UsageOfCustomCollectionPersisterTests.cs Modified: trunk/nhibernate/src/NHibernate/Cfg/Configuration.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Cfg/Configuration.cs 2011-05-17 20:45:36 UTC (rev 5833) +++ trunk/nhibernate/src/NHibernate/Cfg/Configuration.cs 2011-05-17 21:23:50 UTC (rev 5834) @@ -531,6 +531,11 @@ } } + public void AddMapping(HbmMapping mappingDocument) + { + AddDeserializedMapping(mappingDocument, "mapping_by_code"); + } + private void OnAfterBindMapping(BindMappingEventArgs bindMappingEventArgs) { var handler = AfterBindMapping; Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/ICollectionPropertiesMapper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/ICollectionPropertiesMapper.cs 2011-05-17 20:45:36 UTC (rev 5833) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/ICollectionPropertiesMapper.cs 2011-05-17 21:23:50 UTC (rev 5834) @@ -1,6 +1,7 @@ using System; using System.Linq.Expressions; using System.Reflection; +using NHibernate.Persister.Collection; using NHibernate.UserTypes; namespace NHibernate.Mapping.ByCode @@ -27,6 +28,7 @@ void Cache(Action<ICacheMapper> cacheMapping); void Filter(string filterName, Action<IFilterMapper> filterMapping); void Fetch(CollectionFetchMode fetchMode); + void Persister(System.Type persister); } public interface ICollectionPropertiesMapper<TEntity, TElement> : IEntityPropertyMapper, ICollectionSqlsMapper where TEntity : class @@ -50,5 +52,6 @@ void Cache(Action<ICacheMapper> cacheMapping); void Filter(string filterName, Action<IFilterMapper> filterMapping); void Fetch(CollectionFetchMode fetchMode); + void Persister<TPersister>() where TPersister : ICollectionPersister; } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/BagMapper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/BagMapper.cs 2011-05-17 20:45:36 UTC (rev 5833) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/BagMapper.cs 2011-05-17 21:23:50 UTC (rev 5834) @@ -3,6 +3,7 @@ using System.Linq; using System.Reflection; using NHibernate.Cfg.MappingSchema; +using NHibernate.Persister.Collection; using NHibernate.UserTypes; namespace NHibernate.Mapping.ByCode.Impl @@ -188,6 +189,19 @@ mapping.fetchSpecified = mapping.fetch != HbmCollectionFetchMode.Select; } + public void Persister(System.Type persister) + { + if (persister == null) + { + throw new ArgumentNullException("persister"); + } + if (!typeof(ICollectionPersister).IsAssignableFrom(persister)) + { + throw new ArgumentOutOfRangeException("persister", "Expected type implementing ICollectionPersister."); + } + mapping.persister = persister.AssemblyQualifiedName; + } + #endregion #region Implementation of IEntityPropertyMapper Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/CollectionPropertiesCustomizer.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/CollectionPropertiesCustomizer.cs 2011-05-17 20:45:36 UTC (rev 5833) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/CollectionPropertiesCustomizer.cs 2011-05-17 21:23:50 UTC (rev 5834) @@ -1,6 +1,7 @@ using System; using System.Linq.Expressions; using System.Reflection; +using NHibernate.Persister.Collection; using NHibernate.UserTypes; namespace NHibernate.Mapping.ByCode.Impl.CustomizersImpl @@ -118,6 +119,11 @@ CustomizersHolder.AddCustomizer(PropertyPath, (ICollectionPropertiesMapper x) => x.Fetch(fetchMode)); } + public void Persister<TPersister>() where TPersister : ICollectionPersister + { + CustomizersHolder.AddCustomizer(PropertyPath, (ICollectionPropertiesMapper x) => x.Persister(typeof(TPersister))); + } + #endregion #region ICollectionPropertiesMapper<TEntity,TElement> Members Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/IdBagMapper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/IdBagMapper.cs 2011-05-17 20:45:36 UTC (rev 5833) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/IdBagMapper.cs 2011-05-17 21:23:50 UTC (rev 5834) @@ -3,6 +3,7 @@ using System.Linq; using System.Reflection; using NHibernate.Cfg.MappingSchema; +using NHibernate.Persister.Collection; using NHibernate.UserTypes; namespace NHibernate.Mapping.ByCode.Impl @@ -194,6 +195,19 @@ mapping.fetchSpecified = mapping.fetch != HbmCollectionFetchMode.Select; } + public void Persister(System.Type persister) + { + if (persister == null) + { + throw new ArgumentNullException("persister"); + } + if (!typeof(ICollectionPersister).IsAssignableFrom(persister)) + { + throw new ArgumentOutOfRangeException("persister", "Expected type implementing ICollectionPersister."); + } + mapping.persister = persister.AssemblyQualifiedName; + } + public void Id(Action<ICollectionIdMapper> idMapping) { idMapping(idMapper); Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ListMapper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ListMapper.cs 2011-05-17 20:45:36 UTC (rev 5833) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ListMapper.cs 2011-05-17 21:23:50 UTC (rev 5834) @@ -3,6 +3,7 @@ using System.Linq; using System.Reflection; using NHibernate.Cfg.MappingSchema; +using NHibernate.Persister.Collection; using NHibernate.UserTypes; namespace NHibernate.Mapping.ByCode.Impl @@ -192,6 +193,19 @@ mapping.fetchSpecified = mapping.fetch != HbmCollectionFetchMode.Select; } + public void Persister(System.Type persister) + { + if (persister == null) + { + throw new ArgumentNullException("persister"); + } + if (!typeof(ICollectionPersister).IsAssignableFrom(persister)) + { + throw new ArgumentOutOfRangeException("persister", "Expected type implementing ICollectionPersister."); + } + mapping.persister = persister.AssemblyQualifiedName; + } + public void Index(Action<IListIndexMapper> listIndexMapping) { listIndexMapping(listIndexMapper); Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/MapMapper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/MapMapper.cs 2011-05-17 20:45:36 UTC (rev 5833) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/MapMapper.cs 2011-05-17 21:23:50 UTC (rev 5834) @@ -3,6 +3,7 @@ using System.Linq; using System.Reflection; using NHibernate.Cfg.MappingSchema; +using NHibernate.Persister.Collection; using NHibernate.UserTypes; namespace NHibernate.Mapping.ByCode.Impl @@ -209,6 +210,19 @@ mapping.fetchSpecified = mapping.fetch != HbmCollectionFetchMode.Select; } + public void Persister(System.Type persister) + { + if (persister == null) + { + throw new ArgumentNullException("persister"); + } + if (!typeof(ICollectionPersister).IsAssignableFrom(persister)) + { + throw new ArgumentOutOfRangeException("persister", "Expected type implementing ICollectionPersister."); + } + mapping.persister = persister.AssemblyQualifiedName; + } + #endregion #region Implementation of IEntityPropertyMapper Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/SetMapper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/SetMapper.cs 2011-05-17 20:45:36 UTC (rev 5833) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/SetMapper.cs 2011-05-17 21:23:50 UTC (rev 5834) @@ -3,6 +3,7 @@ using System.Linq; using System.Reflection; using NHibernate.Cfg.MappingSchema; +using NHibernate.Persister.Collection; using NHibernate.UserTypes; namespace NHibernate.Mapping.ByCode.Impl @@ -194,6 +195,19 @@ mapping.fetchSpecified = mapping.fetch != HbmCollectionFetchMode.Select; } + public void Persister(System.Type persister) + { + if (persister == null) + { + throw new ArgumentNullException("persister"); + } + if (!typeof(ICollectionPersister).IsAssignableFrom(persister)) + { + throw new ArgumentOutOfRangeException("persister", "Expected type implementing ICollectionPersister."); + } + mapping.persister = persister.AssemblyQualifiedName; + } + #endregion #region Implementation of IEntityPropertyMapper Modified: trunk/nhibernate/src/NHibernate/Persister/PersisterFactory.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Persister/PersisterFactory.cs 2011-05-17 20:45:36 UTC (rev 5833) +++ trunk/nhibernate/src/NHibernate/Persister/PersisterFactory.cs 2011-05-17 21:23:50 UTC (rev 5834) @@ -1,5 +1,6 @@ using System; using System.Reflection; +using System.Text; using NHibernate.Cache; using NHibernate.Cfg; using NHibernate.Engine; @@ -38,6 +39,14 @@ typeof(ISessionFactoryImplementor) }; + private static readonly System.Type[] CollectionPersisterConstructor2Args = new System.Type[] + { + typeof(Mapping.Collection), + typeof(ICacheConcurrencyStrategy), + typeof(Configuration), + typeof(ISessionFactoryImplementor) + }; + /// <summary> /// Creates a built in Entity Persister or a custom Persister. /// </summary> @@ -78,7 +87,7 @@ } else { - return Create(persisterClass, model, cache, factory); + return Create(persisterClass, model, cache, factory, cfg); } } @@ -122,21 +131,41 @@ } public static ICollectionPersister Create(System.Type persisterClass, Mapping.Collection model, - ICacheConcurrencyStrategy cache, ISessionFactoryImplementor factory) + ICacheConcurrencyStrategy cache, ISessionFactoryImplementor factory, Configuration cfg) { ConstructorInfo pc; + var use4Parameters = false; try { pc = persisterClass.GetConstructor(CollectionPersisterConstructorArgs); + if (pc == null) + { + use4Parameters = true; + pc = persisterClass.GetConstructor(CollectionPersisterConstructor2Args); + } } catch (Exception e) { throw new MappingException("Could not get constructor for " + persisterClass.Name, e); } - + if(pc == null) + { + var messageBuilder = new StringBuilder(); + messageBuilder.AppendLine("Could not find a public constructor for " + persisterClass.Name +";"); + messageBuilder.AppendLine("- The ctor may have " + CollectionPersisterConstructorArgs.Length + " parameters of types (in order):"); + System.Array.ForEach(CollectionPersisterConstructorArgs, t=> messageBuilder.AppendLine(t.FullName)); + messageBuilder.AppendLine(); + messageBuilder.AppendLine("- The ctor may have " + CollectionPersisterConstructor2Args.Length + " parameters of types (in order):"); + System.Array.ForEach(CollectionPersisterConstructor2Args, t => messageBuilder.AppendLine(t.FullName)); + throw new MappingException(messageBuilder.ToString()); + } try { - return (ICollectionPersister) pc.Invoke(new object[] {model, cache, factory}); + if (!use4Parameters) + { + return (ICollectionPersister) pc.Invoke(new object[] {model, cache, factory}); + } + return (ICollectionPersister)pc.Invoke(new object[] { model, cache, cfg, factory }); } catch (TargetInvocationException tie) { Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2568/UsageOfCustomCollectionPersisterTests.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2568/UsageOfCustomCollectionPersisterTests.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2568/UsageOfCustomCollectionPersisterTests.cs 2011-05-17 21:23:50 UTC (rev 5834) @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using NHibernate.Cache; +using NHibernate.Cfg; +using NHibernate.Cfg.MappingSchema; +using NHibernate.Engine; +using NHibernate.Mapping.ByCode; +using NHibernate.Persister.Collection; +using NUnit.Framework; +using SharpTestsEx; + +namespace NHibernate.Test.NHSpecificTest.NH2568 +{ + public class MyEntity + { + public virtual int Id { get; set; } + public virtual ICollection<MyRelated> Relateds { get; set; } + } + public class MyRelated + { + public virtual int Id { get; set; } + } + + public class UsageOfCustomCollectionPersisterTests + { + private HbmMapping GetMappings() + { + var mapper = new ModelMapper(); + mapper.Class<MyRelated>(rm=> rm.Id(x=> x.Id)); + mapper.Class<MyEntity>(rm => + { + rm.Id(x => x.Id); + rm.Bag(x => x.Relateds, am => am.Persister<MyCollectionPersister>(), rel=> rel.OneToMany()); + }); + var mappings = mapper.CompileMappingForAllExplicitAddedEntities(); + return mappings; + } + + [Test] + public void BuildingSessionFactoryShouldNotThrows() + { + Configuration cfg = TestConfigurationHelper.GetDefaultConfiguration(); + cfg.AddMapping(GetMappings()); + cfg.Executing(c=>c.BuildSessionFactory()).NotThrows(); + } + } + + public class MyCollectionPersister: OneToManyPersister + { + public MyCollectionPersister(Mapping.Collection collection, ICacheConcurrencyStrategy cache, Configuration cfg, ISessionFactoryImplementor factory) : base(collection, cache, cfg, factory) {} + } +} \ 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-17 20:45:36 UTC (rev 5833) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-05-17 21:23:50 UTC (rev 5834) @@ -804,6 +804,7 @@ <Compile Include="NHSpecificTest\NH2554\Model.cs" /> <Compile Include="NHSpecificTest\NH2565\Domain.cs" /> <Compile Include="NHSpecificTest\NH2565\Fixture.cs" /> + <Compile Include="NHSpecificTest\NH2568\UsageOfCustomCollectionPersisterTests.cs" /> <Compile Include="NHSpecificTest\NH2569\Fixture.cs" /> <Compile Include="NHSpecificTest\NH2580\Fixture.cs" /> <Compile Include="NHSpecificTest\NH2583\AbstractMassTestingFixture.cs" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-05-18 17:51:16
|
Revision: 5838 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5838&view=rev Author: fabiomaulo Date: 2011-05-18 17:51:09 +0000 (Wed, 18 May 2011) Log Message: ----------- Fixed issue reported in dev-list regarding r5793 Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2673/CachingWithTrasformerTests.cs Modified: trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs 2011-05-17 23:07:11 UTC (rev 5837) +++ trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs 2011-05-18 17:51:09 UTC (rev 5838) @@ -75,7 +75,7 @@ return List(session, translator.GetQueryParameters(), querySpaces, resultTypes); } - protected override object GetResultColumnOrRow(object[] row, IResultTransformer resultTransformer, IDataReader rs, + protected override object GetResultColumnOrRow(object[] row, IResultTransformer customResultTransformer, IDataReader rs, ISessionImplementor session) { object[] result; @@ -107,9 +107,10 @@ result = row; } - if (resultTransformer == null && result.Length == 1) + if (customResultTransformer == null) { - return result[0]; + // apply the defaut transformer of criteria aka RootEntityResultTransformer + return result[result.Length - 1]; } return result; } @@ -164,20 +165,20 @@ return lockModesArray; } - public override IList GetResultList(IList results, IResultTransformer resultTransformer) + public override IList GetResultList(IList results, IResultTransformer customResultTransformer) { - var transformer = resultTransformer ?? CriteriaSpecification.RootEntity; + if (customResultTransformer == null) + { + // apply the defaut transformer of criteria aka RootEntityResultTransformer + return results; + } for (int i = 0; i < results.Count; i++) { - var row = results[i] as object[]; - if(row == null) - { - row = new object[] { results[i] }; - } - object result = transformer.TransformTuple(row, translator.HasProjection ? translator.ProjectedAliases : userAliases); + var row = results[i] as object[] ?? new object[] { results[i] }; + object result = customResultTransformer.TransformTuple(row, translator.HasProjection ? translator.ProjectedAliases : userAliases); results[i] = result; } - return transformer.TransformList(results); + return customResultTransformer.TransformList(results); } } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2673/CachingWithTrasformerTests.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2673/CachingWithTrasformerTests.cs 2011-05-17 23:07:11 UTC (rev 5837) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2673/CachingWithTrasformerTests.cs 2011-05-18 17:51:09 UTC (rev 5838) @@ -1,5 +1,6 @@ using System; using System.Collections; +using System.Linq; using NHibernate.Cache; using NHibernate.Cfg; using NHibernate.Cfg.MappingSchema; @@ -153,5 +154,57 @@ } } } + + [Test] + public void WhenEagerLoadingWithCriteriaThenNotThrows() + { + // reported in dev-list instead on JIRA + using (new Scenario(Sfi)) + { + using (var session = OpenSession()) + using (var tx = session.BeginTransaction()) + { + var query = session.CreateCriteria<Blog>() + .SetFetchMode("Posts", FetchMode.Eager) + .SetCacheable(true); + query.Executing(q => q.List<Blog>()).NotThrows(); + tx.Commit(); + } + } + } + + [Test] + public void WhenEagerLoadingWithMultiCriteriaThenNotThrows() + { + using (new Scenario(Sfi)) + { + using (var session = OpenSession()) + using (var tx = session.BeginTransaction()) + { + var query = session.CreateCriteria<Blog>() + .SetFetchMode("Posts", FetchMode.Eager) + .SetCacheable(true); + query.Executing(q => q.Future<Blog>().ToList()).NotThrows(); + tx.Commit(); + } + } + } + + [Test] + public void WhenEagerLoadingWithHqlThenNotThrows() + { + using (new Scenario(Sfi)) + { + using (var session = OpenSession()) + using (var tx = session.BeginTransaction()) + { + var query = session.CreateQuery("select b from Blog b join fetch b.Posts where b.Author = : author") + .SetString("author", "Gabriel") + .SetCacheable(true); + query.Executing(q => q.List<Blog>()).NotThrows(); + tx.Commit(); + } + } + } } } \ 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-20 13:58:59
|
Revision: 5841 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5841&view=rev Author: fabiomaulo Date: 2011-05-20 13:58:52 +0000 (Fri, 20 May 2011) Log Message: ----------- Fix NH-2717 and NH-2708 Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Linq/ReWriters/RemoveUnnecessaryBodyOperators.cs trunk/nhibernate/src/NHibernate/Linq/ReWriters/ResultOperatorRewriter.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/Linq/ByMethod/CastTests.cs Modified: trunk/nhibernate/src/NHibernate/Linq/ReWriters/RemoveUnnecessaryBodyOperators.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/ReWriters/RemoveUnnecessaryBodyOperators.cs 2011-05-18 18:47:08 UTC (rev 5840) +++ trunk/nhibernate/src/NHibernate/Linq/ReWriters/RemoveUnnecessaryBodyOperators.cs 2011-05-20 13:58:52 UTC (rev 5841) @@ -1,4 +1,5 @@ -using System.Linq; +using System; +using System.Linq; using Remotion.Linq; using Remotion.Linq.Clauses; using Remotion.Linq.Clauses.ResultOperators; @@ -26,6 +27,10 @@ queryModel.BodyClauses.Remove(orderby); } } + if (resultOperator is CastResultOperator) + { + Array.ForEach(queryModel.ResultOperators.OfType<CastResultOperator>().ToArray(), castOperator=> queryModel.ResultOperators.Remove(castOperator)); + } base.VisitResultOperator(resultOperator, queryModel, index); } Modified: trunk/nhibernate/src/NHibernate/Linq/ReWriters/ResultOperatorRewriter.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/ReWriters/ResultOperatorRewriter.cs 2011-05-18 18:47:08 UTC (rev 5840) +++ trunk/nhibernate/src/NHibernate/Linq/ReWriters/ResultOperatorRewriter.cs 2011-05-20 13:58:52 UTC (rev 5841) @@ -64,6 +64,7 @@ typeof(FetchRequestBase), typeof(OfTypeResultOperator), typeof(CacheableResultOperator), + typeof(CastResultOperator), // see ProcessCast class }; private readonly List<ResultOperatorBase> resultOperators = new List<ResultOperatorBase>(); Added: trunk/nhibernate/src/NHibernate.Test/Linq/ByMethod/CastTests.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/ByMethod/CastTests.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Linq/ByMethod/CastTests.cs 2011-05-20 13:58:52 UTC (rev 5841) @@ -0,0 +1,45 @@ +using System.Linq; +using NHibernate.DomainModel.Northwind.Entities; +using NHibernate.Linq; +using NUnit.Framework; +using SharpTestsEx; + +namespace NHibernate.Test.Linq.ByMethod +{ + public class CastTests : LinqTestCase + { + [Test] + public void CastCount() + { + session.Query<Cat>() + .Cast<Animal>() + .Count().Should().Be(1); + } + + [Test] + public void CastWithWhere() + { + var pregnatMammal = (from a + in session.Query<Animal>().Cast<Cat>() + where a.Pregnant + select a).FirstOrDefault(); + pregnatMammal.Should().Not.Be.Null(); + } + + [Test] + public void CastDowncast() + { + var query = session.Query<Mammal>().Cast<Dog>(); + // the list contains at least one Cat then should Throws + query.Executing(q=> q.ToList()).Throws(); + } + + [Test, Ignore("Not fixed yet. The method OfType does not work as expected.")] + public void CastDowncastUsingOfType() + { + var query = session.Query<Animal>().OfType<Mammal>().Cast<Dog>(); + // the list contains at least one Cat then should Throws + query.Executing(q => q.ToList()).Throws(); + } + } +} \ 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-18 18:47:08 UTC (rev 5840) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-05-20 13:58:52 UTC (rev 5841) @@ -481,6 +481,7 @@ <Compile Include="Linq\BinaryBooleanExpressionTests.cs" /> <Compile Include="Linq\BinaryExpressionOrdererTests.cs" /> <Compile Include="Linq\BooleanMethodExtensionExample.cs" /> + <Compile Include="Linq\ByMethod\CastTests.cs" /> <Compile Include="Linq\ByMethod\GroupByTests.cs" /> <Compile Include="Linq\CasingTest.cs" /> <Compile Include="Linq\CollectionAssert.cs" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-05-20 15:00:17
|
Revision: 5843 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5843&view=rev Author: fabiomaulo Date: 2011-05-20 15:00:09 +0000 (Fri, 20 May 2011) Log Message: ----------- Fix NH-2701 Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Linq/ResultTransformer.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/Futures/LinqFutureFixture.cs Modified: trunk/nhibernate/src/NHibernate/Linq/ResultTransformer.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/ResultTransformer.cs 2011-05-20 14:31:58 UTC (rev 5842) +++ trunk/nhibernate/src/NHibernate/Linq/ResultTransformer.cs 2011-05-20 15:00:09 UTC (rev 5843) @@ -1,5 +1,6 @@ using System; using System.Collections; +using System.Collections.Generic; using System.Linq; using NHibernate.Transform; @@ -31,30 +32,25 @@ return collection; } - object transformResult = collection; - + IEnumerable<object> toTransform; if (collection.Count > 0 && collection[0] is object[]) { - if (((object[]) collection[0]).Length != 1) + if (((object[])collection[0]).Length != 1) { // We only expect single items throw new NotSupportedException(); } - transformResult = _listTransformation.DynamicInvoke(collection.Cast<object[]>().Select(o => o[0])); + toTransform = collection.Cast<object[]>().Select(o => o[0]); } else { - transformResult = _listTransformation.DynamicInvoke(collection); + toTransform = collection.Cast<object>().ToList(); } + object transformResult = _listTransformation.DynamicInvoke(toTransform); - if (transformResult is IList) - { - return (IList) transformResult; - } - - var list = new ArrayList {transformResult}; - return list; + var resultList = transformResult as IList; + return resultList ?? new List<object> { transformResult }; } #endregion Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/Futures/LinqFutureFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/Futures/LinqFutureFixture.cs 2011-05-20 14:31:58 UTC (rev 5842) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/Futures/LinqFutureFixture.cs 2011-05-20 15:00:09 UTC (rev 5843) @@ -42,7 +42,56 @@ tx.Commit(); } } - [Test] + + [Test] + public void CanUseSkipAndFetchManyWithToFuture() + { + using (var s = sessions.OpenSession()) + using (var tx = s.BeginTransaction()) + { + var p1 = new Person {Name = "Parent"}; + var p2 = new Person {Parent = p1, Name = "Child"}; + p1.Children.Add(p2); + s.Save(p1); + s.Save(p2); + tx.Commit(); + + s.Clear(); // we don't want caching + } + + using (var s = sessions.OpenSession()) + { + IgnoreThisTestIfMultipleQueriesArentSupportedByDriver(); + + var persons10 = s.Query<Person>() + .FetchMany(p => p.Children) + .Skip(5) + .Take(10) + .ToFuture(); + + var persons5 = s.Query<Person>() + .ToFuture(); + + using (var logSpy = new SqlLogSpy()) + { + foreach (var person in persons5) {} + + foreach (var person in persons10) {} + + var events = logSpy.Appender.GetEvents(); + Assert.AreEqual(1, events.Length); + } + } + + using (ISession s = OpenSession()) + using (ITransaction tx = s.BeginTransaction()) + { + s.Delete("from Person"); + tx.Commit(); + } + } + + [Test] public void CanUseFutureQuery() { using (var s = sessions.OpenSession()) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-05-22 10:59:55
|
Revision: 5850 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5850&view=rev Author: fabiomaulo Date: 2011-05-22 10:59:47 +0000 (Sun, 22 May 2011) Log Message: ----------- Grammar changes to support NH-2702 Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Generated/HqlLexer.cs trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Generated/HqlParser.cs trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Generated/HqlSqlWalker.cs trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Generated/SqlGenerator.cs trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Hql.g trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/HqlSqlWalker.g trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/SqlGenerator.cs trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/SqlGenerator.g trunk/nhibernate/src/NHibernate.Test/Hql/Ast/LimitClauseFixture.cs Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Generated/HqlLexer.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Generated/HqlLexer.cs 2011-05-21 13:23:05 UTC (rev 5849) +++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Generated/HqlLexer.cs 2011-05-22 10:59:47 UTC (rev 5850) @@ -1,4 +1,4 @@ -// $ANTLR 3.2 Sep 23, 2009 12:02:23 Hql.g 2011-04-11 10:19:40 +// $ANTLR 3.2 Sep 23, 2009 12:02:23 Hql.g 2011-05-22 07:45:50 // The variable 'variable' is assigned but its value is never used. #pragma warning disable 168, 219 @@ -17,15 +17,15 @@ namespace NHibernate.Hql.Ast.ANTLR { public partial class HqlLexer : Lexer { - public const int LT = 107; + public const int LT = 109; public const int EXPONENT = 130; - public const int STAR = 118; + public const int STAR = 120; public const int FLOAT_SUFFIX = 131; public const int LITERAL_by = 56; public const int CASE = 57; public const int NEW = 37; public const int FILTER_ENTITY = 76; - public const int PARAM = 123; + public const int PARAM = 106; public const int COUNT = 12; public const int NOT = 38; public const int EOF = -1; @@ -33,7 +33,7 @@ public const int QUOTED_String = 124; public const int ESCqs = 128; public const int WEIRD_IDENT = 93; - public const int OPEN_BRACKET = 120; + public const int OPEN_BRACKET = 122; public const int FULL = 23; public const int ORDER_ELEMENT = 85; public const int IS_NULL = 80; @@ -45,10 +45,10 @@ public const int EQ = 102; public const int SELECT = 45; public const int INTO = 30; - public const int NE = 105; - public const int GE = 110; + public const int NE = 107; + public const int GE = 112; public const int TAKE = 50; - public const int CONCAT = 111; + public const int CONCAT = 113; public const int ID_LETTER = 127; public const int NULL = 39; public const int ELSE = 59; @@ -75,9 +75,9 @@ public const int ALIAS = 72; public const int JAVA_CONSTANT = 100; public const int CONSTANT = 94; - public const int GT = 108; + public const int GT = 110; public const int QUERY = 86; - public const int BNOT = 112; + public const int BNOT = 114; public const int INDEX_OP = 78; public const int NUM_FLOAT = 98; public const int FROM = 22; @@ -87,7 +87,7 @@ public const int CONSTRUCTOR = 73; public const int T__133 = 133; public const int T__134 = 134; - public const int CLOSE_BRACKET = 121; + public const int CLOSE_BRACKET = 123; public const int WHERE = 55; public const int CLASS = 11; public const int MEMBER = 67; @@ -96,7 +96,7 @@ public const int ORDER = 41; public const int MAX = 35; public const int UPDATE = 53; - public const int SQL_NE = 106; + public const int SQL_NE = 108; public const int AND = 6; public const int SUM = 49; public const int ASCENDING = 8; @@ -111,11 +111,11 @@ public const int LEFT = 33; public const int SOME = 48; public const int ALL = 4; - public const int BOR = 113; + public const int BOR = 115; public const int IDENT = 125; public const int CASE2 = 74; - public const int BXOR = 114; - public const int PLUS = 116; + public const int BXOR = 116; + public const int PLUS = 118; public const int EXISTS = 19; public const int DOT = 15; public const int WITH = 63; @@ -132,23 +132,23 @@ public const int HAVING = 25; public const int MIN = 36; public const int IS_NOT_NULL = 79; - public const int MINUS = 117; + public const int MINUS = 119; public const int ELEMENTS = 17; - public const int BAND = 115; + public const int BAND = 117; public const int TRUE = 51; public const int JOIN = 32; public const int IN_LIST = 77; public const int UNION = 52; public const int OPEN = 103; - public const int COLON = 122; + public const int COLON = 105; public const int ANY = 5; public const int CLOSE = 104; public const int WHEN = 61; - public const int DIV = 119; + public const int DIV = 121; public const int DESCENDING = 14; public const int AGGREGATE = 71; public const int BETWEEN = 10; - public const int LE = 109; + public const int LE = 111; // delegates // delegators @@ -1810,8 +1810,8 @@ { int _type = EQ; int _channel = DEFAULT_TOKEN_CHANNEL; - // Hql.g:684:3: ( '=' ) - // Hql.g:684:5: '=' + // Hql.g:689:3: ( '=' ) + // Hql.g:689:5: '=' { Match('='); if (state.failed) return ; @@ -1833,8 +1833,8 @@ { int _type = LT; int _channel = DEFAULT_TOKEN_CHANNEL; - // Hql.g:685:3: ( '<' ) - // Hql.g:685:5: '<' + // Hql.g:690:3: ( '<' ) + // Hql.g:690:5: '<' { Match('<'); if (state.failed) return ; @@ -1856,8 +1856,8 @@ { int _type = GT; int _channel = DEFAULT_TOKEN_CHANNEL; - // Hql.g:686:3: ( '>' ) - // Hql.g:686:5: '>' + // Hql.g:691:3: ( '>' ) + // Hql.g:691:5: '>' { Match('>'); if (state.failed) return ; @@ -1879,8 +1879,8 @@ { int _type = SQL_NE; int _channel = DEFAULT_TOKEN_CHANNEL; - // Hql.g:687:7: ( '<>' ) - // Hql.g:687:9: '<>' + // Hql.g:692:7: ( '<>' ) + // Hql.g:692:9: '<>' { Match("<>"); if (state.failed) return ; @@ -1903,7 +1903,7 @@ { int _type = NE; int _channel = DEFAULT_TOKEN_CHANNEL; - // Hql.g:688:3: ( '!=' | '^=' ) + // Hql.g:693:3: ( '!=' | '^=' ) int alt1 = 2; int LA1_0 = input.LA(1); @@ -1926,7 +1926,7 @@ switch (alt1) { case 1 : - // Hql.g:688:5: '!=' + // Hql.g:693:5: '!=' { Match("!="); if (state.failed) return ; @@ -1934,7 +1934,7 @@ } break; case 2 : - // Hql.g:688:12: '^=' + // Hql.g:693:12: '^=' { Match("^="); if (state.failed) return ; @@ -1959,8 +1959,8 @@ { int _type = LE; int _channel = DEFAULT_TOKEN_CHANNEL; - // Hql.g:689:3: ( '<=' ) - // Hql.g:689:5: '<=' + // Hql.g:694:3: ( '<=' ) + // Hql.g:694:5: '<=' { Match("<="); if (state.failed) return ; @@ -1983,8 +1983,8 @@ { int _type = GE; int _channel = DEFAULT_TOKEN_CHANNEL; - // Hql.g:690:3: ( '>=' ) - // Hql.g:690:5: '>=' + // Hql.g:695:3: ( '>=' ) + // Hql.g:695:5: '>=' { Match(">="); if (state.failed) return ; @@ -2007,8 +2007,8 @@ { int _type = BOR; int _channel = DEFAULT_TOKEN_CHANNEL; - // Hql.g:692:5: ( '|' ) - // Hql.g:692:8: '|' + // Hql.g:697:5: ( '|' ) + // Hql.g:697:8: '|' { Match('|'); if (state.failed) return ; @@ -2030,8 +2030,8 @@ { int _type = BXOR; int _channel = DEFAULT_TOKEN_CHANNEL; - // Hql.g:693:6: ( '^' ) - // Hql.g:693:8: '^' + // Hql.g:698:6: ( '^' ) + // Hql.g:698:8: '^' { Match('^'); if (state.failed) return ; @@ -2053,8 +2053,8 @@ { int _type = BAND; int _channel = DEFAULT_TOKEN_CHANNEL; - // Hql.g:694:6: ( '&' ) - // Hql.g:694:8: '&' + // Hql.g:699:6: ( '&' ) + // Hql.g:699:8: '&' { Match('&'); if (state.failed) return ; @@ -2076,8 +2076,8 @@ { int _type = BNOT; int _channel = DEFAULT_TOKEN_CHANNEL; - // Hql.g:695:6: ( '!' ) - // Hql.g:695:8: '!' + // Hql.g:700:6: ( '!' ) + // Hql.g:700:8: '!' { Match('!'); if (state.failed) return ; @@ -2099,8 +2099,8 @@ { int _type = COMMA; int _channel = DEFAULT_TOKEN_CHANNEL; - // Hql.g:697:6: ( ',' ) - // Hql.g:697:8: ',' + // Hql.g:702:6: ( ',' ) + // Hql.g:702:8: ',' { Match(','); if (state.failed) return ; @@ -2122,8 +2122,8 @@ { int _type = OPEN; int _channel = DEFAULT_TOKEN_CHANNEL; - // Hql.g:699:5: ( '(' ) - // Hql.g:699:7: '(' + // Hql.g:704:5: ( '(' ) + // Hql.g:704:7: '(' { Match('('); if (state.failed) return ; @@ -2145,8 +2145,8 @@ { int _type = CLOSE; int _channel = DEFAULT_TOKEN_CHANNEL; - // Hql.g:700:6: ( ')' ) - // Hql.g:700:8: ')' + // Hql.g:705:6: ( ')' ) + // Hql.g:705:8: ')' { Match(')'); if (state.failed) return ; @@ -2168,8 +2168,8 @@ { int _type = OPEN_BRACKET; int _channel = DEFAULT_TOKEN_CHANNEL; - // Hql.g:701:13: ( '[' ) - // Hql.g:701:15: '[' + // Hql.g:706:13: ( '[' ) + // Hql.g:706:15: '[' { Match('['); if (state.failed) return ; @@ -2191,8 +2191,8 @@ { int _type = CLOSE_BRACKET; int _channel = DEFAULT_TOKEN_CHANNEL; - // Hql.g:702:14: ( ']' ) - // Hql.g:702:16: ']' + // Hql.g:707:14: ( ']' ) + // Hql.g:707:16: ']' { Match(']'); if (state.failed) return ; @@ -2214,8 +2214,8 @@ { int _type = CONCAT; int _channel = DEFAULT_TOKEN_CHANNEL; - // Hql.g:704:7: ( '||' ) - // Hql.g:704:9: '||' + // Hql.g:709:7: ( '||' ) + // Hql.g:709:9: '||' { Match("||"); if (state.failed) return ; @@ -2238,8 +2238,8 @@ { int _type = PLUS; int _channel = DEFAULT_TOKEN_CHANNEL; - // Hql.g:705:5: ( '+' ) - // Hql.g:705:7: '+' + // Hql.g:710:5: ( '+' ) + // Hql.g:710:7: '+' { Match('+'); if (state.failed) return ; @@ -2261,8 +2261,8 @@ { int _type = MINUS; int _channel = DEFAULT_TOKEN_CHANNEL; - // Hql.g:706:6: ( '-' ) - // Hql.g:706:8: '-' + // Hql.g:711:6: ( '-' ) + // Hql.g:711:8: '-' { Match('-'); if (state.failed) return ; @@ -2284,8 +2284,8 @@ { int _type = STAR; int _channel = DEFAULT_TOKEN_CHANNEL; - // Hql.g:707:5: ( '*' ) - // Hql.g:707:7: '*' + // Hql.g:712:5: ( '*' ) + // Hql.g:712:7: '*' { Match('*'); if (state.failed) return ; @@ -2307,8 +2307,8 @@ { int _type = DIV; int _channel = DEFAULT_TOKEN_CHANNEL; - // Hql.g:708:4: ( '/' ) - // Hql.g:708:6: '/' + // Hql.g:713:4: ( '/' ) + // Hql.g:713:6: '/' { Match('/'); if (state.failed) return ; @@ -2330,8 +2330,8 @@ { int _type = COLON; int _channel = DEFAULT_TOKEN_CHANNEL; - // Hql.g:709:6: ( ':' ) - // Hql.g:709:8: ':' + // Hql.g:714:6: ( ':' ) + // Hql.g:714:8: ':' { Match(':'); if (state.failed) return ; @@ -2353,8 +2353,8 @@ { int _type = PARAM; int _channel = DEFAULT_TOKEN_CHANNEL; - // Hql.g:710:6: ( '?' ) - // Hql.g:710:8: '?' + // Hql.g:715:6: ( '?' ) + // Hql.g:715:8: '?' { Match('?'); if (state.failed) return ; @@ -2376,11 +2376,11 @@ { int _type = IDENT; int _channel = DEFAULT_TOKEN_CHANNEL; - // Hql.g:713:2: ( ID_START_LETTER ( ID_LETTER )* ) - // Hql.g:713:4: ID_START_LETTER ( ID_LETTER )* + // Hql.g:718:2: ( ID_START_LETTER ( ID_LETTER )* ) + // Hql.g:718:4: ID_START_LETTER ( ID_LETTER )* { mID_START_LETTER(); if (state.failed) return ; - // Hql.g:713:20: ( ID_LETTER )* + // Hql.g:718:20: ( ID_LETTER )* do { int alt2 = 2; @@ -2395,7 +2395,7 @@ switch (alt2) { case 1 : - // Hql.g:713:22: ID_LETTER + // Hql.g:718:22: ID_LETTER { mID_LETTER(); if (state.failed) return ; @@ -2427,7 +2427,7 @@ { try { - // Hql.g:718:5: ( '_' | '$' | 'a' .. 'z' | 'A' .. 'Z' | '\\u0080' .. '\\ufffe' ) + // Hql.g:723:5: ( '_' | '$' | 'a' .. 'z' | 'A' .. 'Z' | '\\u0080' .. '\\ufffe' ) // Hql.g: { if ( input.LA(1) == '$' || (input.LA(1) >= 'A' && input.LA(1) <= 'Z') || input.LA(1) == '_' || (input.LA(1) >= 'a' && input.LA(1) <= 'z') || (input.LA(1) >= '\u0080' && input.LA(1) <= '\uFFFE') ) @@ -2457,7 +2457,7 @@ { try { - // Hql.g:727:5: ( ID_START_LETTER | '0' .. '9' ) + // Hql.g:732:5: ( ID_START_LETTER | '0' .. '9' ) // Hql.g: { if ( input.LA(1) == '$' || (input.LA(1) >= '0' && input.LA(1) <= '9') || (input.LA(1) >= 'A' && input.LA(1) <= 'Z') || input.LA(1) == '_' || (input.LA(1) >= 'a' && input.LA(1) <= 'z') || (input.LA(1) >= '\u0080' && input.LA(1) <= '\uFFFE') ) @@ -2489,11 +2489,11 @@ { int _type = QUOTED_String; int _channel = DEFAULT_TOKEN_CHANNEL; - // Hql.g:732:4: ( '\\'' ( ( ESCqs )=> ESCqs | ~ '\\'' )* '\\'' ) - // Hql.g:732:6: '\\'' ( ( ESCqs )=> ESCqs | ~ '\\'' )* '\\'' + // Hql.g:737:4: ( '\\'' ( ( ESCqs )=> ESCqs | ~ '\\'' )* '\\'' ) + // Hql.g:737:6: '\\'' ( ( ESCqs )=> ESCqs | ~ '\\'' )* '\\'' { Match('\''); if (state.failed) return ; - // Hql.g:732:11: ( ( ESCqs )=> ESCqs | ~ '\\'' )* + // Hql.g:737:11: ( ( ESCqs )=> ESCqs | ~ '\\'' )* do { int alt3 = 3; @@ -2519,14 +2519,14 @@ switch (alt3) { case 1 : - // Hql.g:732:13: ( ESCqs )=> ESCqs + // Hql.g:737:13: ( ESCqs )=> ESCqs { mESCqs(); if (state.failed) return ; } break; case 2 : - // Hql.g:732:31: ~ '\\'' + // Hql.g:737:31: ~ '\\'' { if ( (input.LA(1) >= '\u0000' && input.LA(1) <= '&') || (input.LA(1) >= '(' && input.LA(1) <= '\uFFFF') ) { @@ -2570,8 +2570,8 @@ { try { - // Hql.g:737:2: ( '\\'' '\\'' ) - // Hql.g:738:3: '\\'' '\\'' + // Hql.g:742:2: ( '\\'' '\\'' ) + // Hql.g:743:3: '\\'' '\\'' { Match('\''); if (state.failed) return ; Match('\''); if (state.failed) return ; @@ -2592,10 +2592,10 @@ { int _type = WS; int _channel = DEFAULT_TOKEN_CHANNEL; - // Hql.g:741:5: ( ( ' ' | '\\t' | '\\r' '\\n' | '\\n' | '\\r' ) ) - // Hql.g:741:9: ( ' ' | '\\t' | '\\r' '\\n' | '\\n' | '\\r' ) + // Hql.g:746:5: ( ( ' ' | '\\t' | '\\r' '\\n' | '\\n' | '\\r' ) ) + // Hql.g:746:9: ( ' ' | '\\t' | '\\r' '\\n' | '\\n' | '\\r' ) { - // Hql.g:741:9: ( ' ' | '\\t' | '\\r' '\\n' | '\\n' | '\\r' ) + // Hql.g:746:9: ( ' ' | '\\t' | '\\r' '\\n' | '\\n' | '\\r' ) int alt4 = 5; switch ( input.LA(1) ) { @@ -2638,21 +2638,21 @@ switch (alt4) { case 1 : - // Hql.g:741:13: ' ' + // Hql.g:746:13: ' ' { Match(' '); if (state.failed) return ; } break; case 2 : - // Hql.g:742:7: '\\t' + // Hql.g:747:7: '\\t' { Match('\t'); if (state.failed) return ; } break; case 3 : - // Hql.g:743:7: '\\r' '\\n' + // Hql.g:748:7: '\\r' '\\n' { Match('\r'); if (state.failed) return ; Match('\n'); if (state.failed) return ; @@ -2660,14 +2660,14 @@ } break; case 4 : - // Hql.g:744:7: '\\n' + // Hql.g:749:7: '\\n' { Match('\n'); if (state.failed) return ; } break; case 5 : - // Hql.g:745:7: '\\r' + // Hql.g:750:7: '\\r' { Match('\r'); if (state.failed) return ; @@ -2705,7 +2705,7 @@ IToken f4 = null; bool isDecimal=false; IToken t=null; - // Hql.g:754:2: ( '.' ( ( '0' .. '9' )+ ( EXPONENT )? (f1= FLOAT_SUFFIX )? )? | ( '0' ( ( 'x' ) ( HEX_DIGIT )+ | ( '0' .. '7' )+ )? | ( '1' .. '9' ) ( '0' .. '9' )* ) ( ( 'l' ) | {...}? ( '.' ( '0' .. '9' )* ( EXPONENT )? (f2= FLOAT_SUFFIX )? | EXPONENT (f3= FLOAT_SUFFIX )? | f4= FLOAT_SUFFIX ) )? ) + // Hql.g:759:2: ( '.' ( ( '0' .. '9' )+ ( EXPONENT )? (f1= FLOAT_SUFFIX )? )? | ( '0' ( ( 'x' ) ( HEX_DIGIT )+ | ( '0' .. '7' )+ )? | ( '1' .. '9' ) ( '0' .. '9' )* ) ( ( 'l' ) | {...}? ( '.' ( '0' .. '9' )* ( EXPONENT )? (f2= FLOAT_SUFFIX )? | EXPONENT (f3= FLOAT_SUFFIX )? | f4= FLOAT_SUFFIX ) )? ) int alt20 = 2; int LA20_0 = input.LA(1); @@ -2728,14 +2728,14 @@ switch (alt20) { case 1 : - // Hql.g:754:6: '.' ( ( '0' .. '9' )+ ( EXPONENT )? (f1= FLOAT_SUFFIX )? )? + // Hql.g:759:6: '.' ( ( '0' .. '9' )+ ( EXPONENT )? (f1= FLOAT_SUFFIX )? )? { Match('.'); if (state.failed) return ; if ( (state.backtracking==0) ) { _type = DOT; } - // Hql.g:755:4: ( ( '0' .. '9' )+ ( EXPONENT )? (f1= FLOAT_SUFFIX )? )? + // Hql.g:760:4: ( ( '0' .. '9' )+ ( EXPONENT )? (f1= FLOAT_SUFFIX )? )? int alt8 = 2; int LA8_0 = input.LA(1); @@ -2746,9 +2746,9 @@ switch (alt8) { case 1 : - // Hql.g:755:6: ( '0' .. '9' )+ ( EXPONENT )? (f1= FLOAT_SUFFIX )? + // Hql.g:760:6: ( '0' .. '9' )+ ( EXPONENT )? (f1= FLOAT_SUFFIX )? { - // Hql.g:755:6: ( '0' .. '9' )+ + // Hql.g:760:6: ( '0' .. '9' )+ int cnt5 = 0; do { @@ -2764,7 +2764,7 @@ switch (alt5) { case 1 : - // Hql.g:755:7: '0' .. '9' + // Hql.g:760:7: '0' .. '9' { MatchRange('0','9'); if (state.failed) return ; @@ -2784,7 +2784,7 @@ loop5: ; // Stops C# compiler whining that label 'loop5' has no statements - // Hql.g:755:18: ( EXPONENT )? + // Hql.g:760:18: ( EXPONENT )? int alt6 = 2; int LA6_0 = input.LA(1); @@ -2795,7 +2795,7 @@ switch (alt6) { case 1 : - // Hql.g:755:19: EXPONENT + // Hql.g:760:19: EXPONENT { mEXPONENT(); if (state.failed) return ; @@ -2804,7 +2804,7 @@ } - // Hql.g:755:30: (f1= FLOAT_SUFFIX )? + // Hql.g:760:30: (f1= FLOAT_SUFFIX )? int alt7 = 2; int LA7_0 = input.LA(1); @@ -2815,7 +2815,7 @@ switch (alt7) { case 1 : - // Hql.g:755:31: f1= FLOAT_SUFFIX + // Hql.g:760:31: f1= FLOAT_SUFFIX { int f1Start1034 = CharIndex; mFLOAT_SUFFIX(); if (state.failed) return ; @@ -2857,9 +2857,9 @@ } break; case 2 : - // Hql.g:771:4: ( '0' ( ( 'x' ) ( HEX_DIGIT )+ | ( '0' .. '7' )+ )? | ( '1' .. '9' ) ( '0' .. '9' )* ) ( ( 'l' ) | {...}? ( '.' ( '0' .. '9' )* ( EXPONENT )? (f2= FLOAT_SUFFIX )? | EXPONENT (f3= FLOAT_SUFFIX )? | f4= FLOAT_SUFFIX ) )? + // Hql.g:776:4: ( '0' ( ( 'x' ) ( HEX_DIGIT )+ | ( '0' .. '7' )+ )? | ( '1' .. '9' ) ( '0' .. '9' )* ) ( ( 'l' ) | {...}? ( '.' ( '0' .. '9' )* ( EXPONENT )? (f2= FLOAT_SUFFIX )? | EXPONENT (f3= FLOAT_SUFFIX )? | f4= FLOAT_SUFFIX ) )? { - // Hql.g:771:4: ( '0' ( ( 'x' ) ( HEX_DIGIT )+ | ( '0' .. '7' )+ )? | ( '1' .. '9' ) ( '0' .. '9' )* ) + // Hql.g:776:4: ( '0' ( ( 'x' ) ( HEX_DIGIT )+ | ( '0' .. '7' )+ )? | ( '1' .. '9' ) ( '0' .. '9' )* ) int alt13 = 2; int LA13_0 = input.LA(1); @@ -2882,14 +2882,14 @@ switch (alt13) { case 1 : - // Hql.g:771:6: '0' ( ( 'x' ) ( HEX_DIGIT )+ | ( '0' .. '7' )+ )? + // Hql.g:776:6: '0' ( ( 'x' ) ( HEX_DIGIT )+ | ( '0' .. '7' )+ )? { Match('0'); if (state.failed) return ; if ( (state.backtracking==0) ) { isDecimal = true; } - // Hql.g:772:4: ( ( 'x' ) ( HEX_DIGIT )+ | ( '0' .. '7' )+ )? + // Hql.g:777:4: ( ( 'x' ) ( HEX_DIGIT )+ | ( '0' .. '7' )+ )? int alt11 = 3; int LA11_0 = input.LA(1); @@ -2904,16 +2904,16 @@ switch (alt11) { case 1 : - // Hql.g:772:6: ( 'x' ) ( HEX_DIGIT )+ + // Hql.g:777:6: ( 'x' ) ( HEX_DIGIT )+ { - // Hql.g:772:6: ( 'x' ) - // Hql.g:772:7: 'x' + // Hql.g:777:6: ( 'x' ) + // Hql.g:777:7: 'x' { Match('x'); if (state.failed) return ; } - // Hql.g:773:5: ( HEX_DIGIT )+ + // Hql.g:778:5: ( HEX_DIGIT )+ int cnt9 = 0; do { @@ -2979,7 +2979,7 @@ switch (alt9) { case 1 : - // Hql.g:780:7: HEX_DIGIT + // Hql.g:785:7: HEX_DIGIT { mHEX_DIGIT(); if (state.failed) return ; @@ -3003,9 +3003,9 @@ } break; case 2 : - // Hql.g:782:6: ( '0' .. '7' )+ + // Hql.g:787:6: ( '0' .. '7' )+ { - // Hql.g:782:6: ( '0' .. '7' )+ + // Hql.g:787:6: ( '0' .. '7' )+ int cnt10 = 0; do { @@ -3021,7 +3021,7 @@ switch (alt10) { case 1 : - // Hql.g:782:7: '0' .. '7' + // Hql.g:787:7: '0' .. '7' { MatchRange('0','7'); if (state.failed) return ; @@ -3051,16 +3051,16 @@ } break; case 2 : - // Hql.g:784:5: ( '1' .. '9' ) ( '0' .. '9' )* + // Hql.g:789:5: ( '1' .. '9' ) ( '0' .. '9' )* { - // Hql.g:784:5: ( '1' .. '9' ) - // Hql.g:784:6: '1' .. '9' + // Hql.g:789:5: ( '1' .. '9' ) + // Hql.g:789:6: '1' .. '9' { MatchRange('1','9'); if (state.failed) return ; } - // Hql.g:784:16: ( '0' .. '9' )* + // Hql.g:789:16: ( '0' .. '9' )* do { int alt12 = 2; @@ -3075,7 +3075,7 @@ switch (alt12) { case 1 : - // Hql.g:784:17: '0' .. '9' + // Hql.g:789:17: '0' .. '9' { MatchRange('0','9'); if (state.failed) return ; @@ -3100,7 +3100,7 @@ } - // Hql.g:786:3: ( ( 'l' ) | {...}? ( '.' ( '0' .. '9' )* ( EXPONENT )? (f2= FLOAT_SUFFIX )? | EXPONENT (f3= FLOAT_SUFFIX )? | f4= FLOAT_SUFFIX ) )? + // Hql.g:791:3: ( ( 'l' ) | {...}? ( '.' ( '0' .. '9' )* ( EXPONENT )? (f2= FLOAT_SUFFIX )? | EXPONENT (f3= FLOAT_SUFFIX )? | f4= FLOAT_SUFFIX ) )? int alt19 = 3; int LA19_0 = input.LA(1); @@ -3115,10 +3115,10 @@ switch (alt19) { case 1 : - // Hql.g:786:5: ( 'l' ) + // Hql.g:791:5: ( 'l' ) { - // Hql.g:786:5: ( 'l' ) - // Hql.g:786:6: 'l' + // Hql.g:791:5: ( 'l' ) + // Hql.g:791:6: 'l' { Match('l'); if (state.failed) return ; @@ -3132,14 +3132,14 @@ } break; case 2 : - // Hql.g:789:5: {...}? ( '.' ( '0' .. '9' )* ( EXPONENT )? (f2= FLOAT_SUFFIX )? | EXPONENT (f3= FLOAT_SUFFIX )? | f4= FLOAT_SUFFIX ) + // Hql.g:794:5: {...}? ( '.' ( '0' .. '9' )* ( EXPONENT )? (f2= FLOAT_SUFFIX )? | EXPONENT (f3= FLOAT_SUFFIX )? | f4= FLOAT_SUFFIX ) { if ( !((isDecimal)) ) { if ( state.backtracking > 0 ) {state.failed = true; return ;} throw new FailedPredicateException(input, "NUM_INT", "isDecimal"); } - // Hql.g:790:4: ( '.' ( '0' .. '9' )* ( EXPONENT )? (f2= FLOAT_SUFFIX )? | EXPONENT (f3= FLOAT_SUFFIX )? | f4= FLOAT_SUFFIX ) + // Hql.g:795:4: ( '.' ( '0' .. '9' )* ( EXPONENT )? (f2= FLOAT_SUFFIX )? | EXPONENT (f3= FLOAT_SUFFIX )? | f4= FLOAT_SUFFIX ) int alt18 = 3; switch ( input.LA(1) ) { @@ -3171,10 +3171,10 @@ switch (alt18) { case 1 : - // Hql.g:790:8: '.' ( '0' .. '9' )* ( EXPONENT )? (f2= FLOAT_SUFFIX )? + // Hql.g:795:8: '.' ( '0' .. '9' )* ( EXPONENT )? (f2= FLOAT_SUFFIX )? { Match('.'); if (state.failed) return ; - // Hql.g:790:12: ( '0' .. '9' )* + // Hql.g:795:12: ( '0' .. '9' )* do { int alt14 = 2; @@ -3189,7 +3189,7 @@ switch (alt14) { case 1 : - // Hql.g:790:13: '0' .. '9' + // Hql.g:795:13: '0' .. '9' { MatchRange('0','9'); if (state.failed) return ; @@ -3204,7 +3204,7 @@ loop14: ; // Stops C# compiler whining that label 'loop14' has no statements - // Hql.g:790:24: ( EXPONENT )? + // Hql.g:795:24: ( EXPONENT )? int alt15 = 2; int LA15_0 = input.LA(1); @@ -3215,7 +3215,7 @@ switch (alt15) { case 1 : - // Hql.g:790:25: EXPONENT + // Hql.g:795:25: EXPONENT { mEXPONENT(); if (state.failed) return ; @@ -3224,7 +3224,7 @@ } - // Hql.g:790:36: (f2= FLOAT_SUFFIX )? + // Hql.g:795:36: (f2= FLOAT_SUFFIX )? int alt16 = 2; int LA16_0 = input.LA(1); @@ -3235,7 +3235,7 @@ switch (alt16) { case 1 : - // Hql.g:790:37: f2= FLOAT_SUFFIX + // Hql.g:795:37: f2= FLOAT_SUFFIX { int f2Start1236 = CharIndex; mFLOAT_SUFFIX(); if (state.failed) return ; @@ -3254,10 +3254,10 @@ } break; case 2 : - // Hql.g:791:8: EXPONENT (f3= FLOAT_SUFFIX )? + // Hql.g:796:8: EXPONENT (f3= FLOAT_SUFFIX )? { mEXPONENT(); if (state.failed) return ; - // Hql.g:791:17: (f3= FLOAT_SUFFIX )? + // Hql.g:796:17: (f3= FLOAT_SUFFIX )? int alt17 = 2; int LA17_0 = input.LA(1); @@ -3268,7 +3268,7 @@ switch (alt17) { case 1 : - // Hql.g:791:18: f3= FLOAT_SUFFIX + // Hql.g:796:18: f3= FLOAT_SUFFIX { int f3Start1254 = CharIndex; mFLOAT_SUFFIX(); if (state.failed) return ; @@ -3287,7 +3287,7 @@ } break; case 3 : - // Hql.g:792:8: f4= FLOAT_SUFFIX + // Hql.g:797:8: f4= FLOAT_SUFFIX { int f4Start1269 = CharIndex; mFLOAT_SUFFIX(); if (state.failed) return ; @@ -3344,8 +3344,8 @@ { try { - // Hql.g:814:2: ( ( '0' .. '9' | 'a' .. 'f' ) ) - // Hql.g:814:4: ( '0' .. '9' | 'a' .. 'f' ) + // Hql.g:819:2: ( ( '0' .. '9' | 'a' .. 'f' ) ) + // Hql.g:819:4: ( '0' .. '9' | 'a' .. 'f' ) { if ( (input.LA(1) >= '0' && input.LA(1) <= '9') || (input.LA(1) >= 'a' && input.LA(1) <= 'f') ) { @@ -3374,17 +3374,17 @@ { try { - // Hql.g:820:2: ( ( 'e' ) ( '+' | '-' )? ( '0' .. '9' )+ ) - // Hql.g:820:4: ( 'e' ) ( '+' | '-' )? ( '0' .. '9' )+ + // Hql.g:825:2: ( ( 'e' ) ( '+' | '-' )? ( '0' .. '9' )+ ) + // Hql.g:825:4: ( 'e' ) ( '+' | '-' )? ( '0' .. '9' )+ { - // Hql.g:820:4: ( 'e' ) - // Hql.g:820:5: 'e' + // Hql.g:825:4: ( 'e' ) + // Hql.g:825:5: 'e' { Match('e'); if (state.failed) return ; } - // Hql.g:820:10: ( '+' | '-' )? + // Hql.g:825:10: ( '+' | '-' )? int alt21 = 2; int LA21_0 = input.LA(1); @@ -3415,7 +3415,7 @@ } - // Hql.g:820:21: ( '0' .. '9' )+ + // Hql.g:825:21: ( '0' .. '9' )+ int cnt22 = 0; do { @@ -3431,7 +3431,7 @@ switch (alt22) { case 1 : - // Hql.g:820:22: '0' .. '9' + // Hql.g:825:22: '0' .. '9' { MatchRange('0','9'); if (state.failed) return ; @@ -3466,7 +3466,7 @@ { try { - // Hql.g:825:2: ( 'f' | 'd' | 'm' ) + // Hql.g:830:2: ( 'f' | 'd' | 'm' ) // Hql.g: { if ( input.LA(1) == 'd' || input.LA(1) == 'f' || input.LA(1) == 'm' ) @@ -4170,8 +4170,8 @@ // $ANTLR start "synpred1_Hql" public void synpred1_Hql_fragment() { - // Hql.g:732:13: ( ESCqs ) - // Hql.g:732:14: ESCqs + // Hql.g:737:13: ( ESCqs ) + // Hql.g:737:14: ESCqs { mESCqs(); if (state.failed) return ; Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Generated/HqlParser.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Generated/HqlParser.cs 2011-05-21 13:23:05 UTC (rev 5849) +++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Generated/HqlParser.cs 2011-05-22 10:59:47 UTC (rev 5850) @@ -1,4 +1,4 @@ -// $ANTLR 3.2 Sep 23, 2009 12:02:23 Hql.g 2011-04-11 10:19:39 +// $ANTLR 3.2 Sep 23, 2009 12:02:23 Hql.g 2011-05-22 07:45:49 // The variable 'variable' is assigned but its value is never used. #pragma warning disable 168, 219 @@ -130,6 +130,8 @@ "EQ", "OPEN", "CLOSE", + "COLON", + "PARAM", "NE", "SQL_NE", "LT", @@ -147,8 +149,6 @@ "DIV", "OPEN_BRACKET", "CLOSE_BRACKET", - "COLON", - "PARAM", "QUOTED_String", "IDENT", "ID_START_LETTER", @@ -163,14 +163,14 @@ }; public const int EXPONENT = 130; - public const int LT = 107; + public const int LT = 109; public const int FLOAT_SUFFIX = 131; - public const int STAR = 118; + public const int STAR = 120; public const int LITERAL_by = 56; public const int CASE = 57; public const int NEW = 37; public const int FILTER_ENTITY = 76; - public const int PARAM = 123; + public const int PARAM = 106; public const int COUNT = 12; public const int NOT = 38; public const int EOF = -1; @@ -178,7 +178,7 @@ public const int QUOTED_String = 124; public const int ESCqs = 128; public const int WEIRD_IDENT = 93; - public const int OPEN_BRACKET = 120; + public const int OPEN_BRACKET = 122; public const int FULL = 23; public const int ORDER_ELEMENT = 85; public const int INSERT = 29; @@ -190,11 +190,11 @@ public const int VERSIONED = 54; public const int SELECT = 45; public const int INTO = 30; - public const int NE = 105; - public const int GE = 110; + public const int NE = 107; + public const int GE = 112; public const int TAKE = 50; public const int ID_LETTER = 127; - public const int CONCAT = 111; + public const int CONCAT = 113; public const int NULL = 39; public const int ELSE = 59; public const int SELECT_FROM = 89; @@ -220,9 +220,9 @@ public const int ALIAS = 72; public const int JAVA_CONSTANT = 100; public const int CONSTANT = 94; - public const int GT = 108; + public const int GT = 110; public const int QUERY = 86; - public const int BNOT = 112; + public const int BNOT = 114; public const int INDEX_OP = 78; public const int NUM_FLOAT = 98; public const int FROM = 22; @@ -232,7 +232,7 @@ public const int CONSTRUCTOR = 73; public const int T__133 = 133; public const int T__134 = 134; - public const int CLOSE_BRACKET = 121; + public const int CLOSE_BRACKET = 123; public const int WHERE = 55; public const int CLASS = 11; public const int MEMBER = 67; @@ -241,7 +241,7 @@ public const int ORDER = 41; public const int MAX = 35; public const int UPDATE = 53; - public const int SQL_NE = 106; + public const int SQL_NE = 108; public const int AND = 6; public const int SUM = 49; public const int ASCENDING = 8; @@ -255,11 +255,11 @@ public const int LEFT = 33; public const int AVG = 9; public const int SOME = 48; - public const int BOR = 113; + public const int BOR = 115; public const int ALL = 4; public const int IDENT = 125; - public const int PLUS = 116; - public const int BXOR = 114; + public const int PLUS = 118; + public const int BXOR = 116; public const int CASE2 = 74; public const int EXISTS = 19; public const int DOT = 15; @@ -276,24 +276,24 @@ public const int SET = 46; public const int HAVING = 25; public const int MIN = 36; - public const int MINUS = 117; + public const int MINUS = 119; public const int IS_NOT_NULL = 79; - public const int BAND = 115; + public const int BAND = 117; public const int ELEMENTS = 17; public const int TRUE = 51; public const int JOIN = 32; public const int UNION = 52; public const int IN_LIST = 77; - public const int COLON = 122; + public const int COLON = 105; public const int OPEN = 103; public const int ANY = 5; public const int CLOSE = 104; public const int WHEN = 61; - public const int DIV = 119; + public const int DIV = 121; public const int DESCENDING = 14; public const int BETWEEN = 10; public const int AGGREGATE = 71; - public const int LE = 109; + public const int LE = 111; // delegates // delegators @@ -2049,11 +2049,11 @@ case NUM_FLOAT: case NUM_LONG: case OPEN: + case COLON: + case PARAM: case BNOT: case PLUS: case MINUS: - case COLON: - case PARAM: case QUOTED_String: case IDENT: { @@ -2206,7 +2206,7 @@ // AST REWRITE - // elements: path, selectedPropertiesList + // elements: selectedPropertiesList, path // token labels: // rule labels: retval // token list labels: @@ -3338,30 +3338,30 @@ { int LA33_1 = input.LA(2); - if ( (LA33_1 == EOF || LA33_1 == AS || LA33_1 == DOT || LA33_1 == FETCH || (LA33_1 >= FULL && LA33_1 <= HAVING) || LA33_1 == INNER || (LA33_1 >= JOIN && LA33_1 <= LEFT) || LA33_1 == ORDER || LA33_1 == RIGHT || LA33_1 == SKIP || LA33_1 == TAKE || LA33_1 == UNION || LA33_1 == WHERE || LA33_1 == COMMA || LA33_1 == CLOSE || LA33_1 == IDENT) ) + if ( (LA33_1 == IN) ) { - alt33 = 1; - } - else if ( (LA33_1 == IN) ) - { - int LA33_5 = input.LA(3); + int LA33_4 = input.LA(3); - if ( (LA33_5 == ELEMENTS) ) + if ( (LA33_4 == ELEMENTS) ) { alt33 = 4; } - else if ( (LA33_5 == CLASS || LA33_5 == IDENT) ) + else if ( (LA33_4 == CLASS || LA33_4 == IDENT) ) { alt33 = 2; } else { - NoViableAltException nvae_d33s5 = - new NoViableAltException("", 33, 5, input); + NoViableAltException nvae_d33s4 = + new NoViableAltException("", 33, 4, input); - throw nvae_d33s5; + throw nvae_d33s4; } } + else if ( (LA33_1 == EOF || LA33_1 == AS || LA33_1 == DOT || LA33_1 == FETCH || (LA33_1 >= FULL && LA33_1 <= HAVING) || LA33_1 == INNER || (LA33_1 >= JOIN && LA33_1 <= LEFT) || LA33_1 == ORDER || LA33_1 == RIGHT || LA33_1 == SKIP || LA33_1 == TAKE || LA33_1 == UNION || LA33_1 == WHERE || LA33_1 == COMMA || LA33_1 == CLOSE || LA33_1 == IDENT) ) + { + alt33 = 1; + } else { NoViableAltException nvae_d33s1 = @@ -3555,7 +3555,7 @@ // AST REWRITE - // elements: propertyFetch, path, asAlias + // elements: propertyFetch, asAlias, path // token labels: // rule labels: retval // token list labels: @@ -4009,7 +4009,7 @@ // AST REWRITE - // elements: path, alias + // elements: alias, path // token labels: // rule labels: retval // token list labels: @@ -4507,7 +4507,7 @@ }; // $ANTLR start "skipClause" - // Hql.g:305:1: skipClause : SKIP NUM_INT ; + // Hql.g:305:1: skipClause : SKIP ( NUM_INT | parameter ) ; public HqlParser.skipClause_return skipClause() // throws RecognitionException [1] { HqlParser.skipClause_return retval = new HqlParser.skipClause_return(); @@ -4517,14 +4517,16 @@ IToken SKIP131 = null; IToken NUM_INT132 = null; + HqlParser.parameter_return parameter133 = default(HqlParser.parameter_return); + IASTNode SKIP131_tree=null; IASTNode NUM_INT132_tree=null; try { - // Hql.g:306:2: ( SKIP NUM_INT ) - // Hql.g:306:4: SKIP NUM_INT + // Hql.g:306:2: ( SKIP ( NUM_INT | parameter ) ) + // Hql.g:306:4: SKIP ( NUM_INT | parameter ) { root_0 = (IASTNode)adaptor.GetNilNode(); @@ -4532,11 +4534,52 @@ SKIP131_tree = (IASTNode)adaptor.Create(SKIP131); root_0 = (IASTNode)adaptor.BecomeRoot(SKIP131_tree, root_0); - NUM_INT132=(IToken)Match(input,NUM_INT,FOLLOW_NUM_INT_in_skipClause1645); - NUM_INT132_tree = (IASTNode)adaptor.Create(NUM_INT132); - adaptor.AddChild(root_0, NUM_INT132_tree); + // Hql.g:306:10: ( NUM_INT | parameter ) + int alt41 = 2; + int LA41_0 = input.LA(1); + if ( (LA41_0 == NUM_INT) ) + { + alt41 = 1; + } + else if ( ((LA41_0 >= COLON && LA41_0 <= PARAM)) ) + { + alt41 = 2; + } + else + { + NoViableAltException nvae_d41s0 = + new NoViableAltException("", 41, 0, input); + throw nvae_d41s0; + } + switch (alt41) + { + case 1 : + // Hql.g:306:11: NUM_INT + { + NUM_INT132=(IToken)Match(input,NUM_INT,FOLLOW_NUM_INT_in_skipClause1646); + NUM_INT132_tree = (IASTNode)adaptor.Create(NUM_INT132); + adaptor.AddChild(root_0, NUM_INT132_tree); + + + } + break; + case 2 : + // Hql.g:306:21: parameter + { + PushFollow(FOLLOW_parameter_in_skipClause1650); + parameter133 = parameter(); + state.followingStackPointer--; + + adaptor.AddChild(root_0, parameter133.Tree); + + } + break; + + } + + } retval.Stop = input.LT(-1); @@ -4570,7 +4613,7 @@ }; // $ANTLR start "takeClause" - // Hql.g:309:1: takeClause : TAKE NUM_INT ; + // Hql.g:309:1: takeClause : TAKE ( NUM_INT | parameter ) ; public HqlParser.takeClause_return takeClause() // throws RecognitionException [1] { HqlParser.takeClause_return retval = new HqlParser.takeClause_return(); @@ -4578,28 +4621,71 @@ IASTNode root_0 = null; - IToken TAKE133 = null; - IToken NUM_INT134 = null; + IToken TAKE134 = null; + IToken NUM_INT135 = null; + HqlParser.parameter_return parameter136 = default(HqlParser.parameter_return); - IASTNode TAKE133_tree=null; - IASTNode NUM_INT134_tree=null; + IASTNode TAKE134_tree=null; + IASTNode NUM_INT135_tree=null; + try { - // Hql.g:310:2: ( TAKE NUM_INT ) - // Hql.g:310:4: TAKE NUM_INT + // Hql.g:310:2: ( TAKE ( NUM_INT | parameter ) ) + // Hql.g:310:4: TAKE ( NUM_INT | parameter ) { root_0 = (IASTNode)adaptor.GetNilNode(); - TAKE133=(IToken)Match(input,TAKE,FOLLOW_TAKE_in_takeClause1656); - TAKE133_tree = (IASTNode)adaptor.Create(TAKE133); - root_0 = (IASTNode)adaptor.BecomeRoot(TAKE133_tree, root_0); + TAKE134=(IToken)Match(input,TAKE,FOLLOW_TAKE_in_takeClause1662); + TAKE134_tree = (IASTNode)adaptor.Create(TAKE134); + root_0 = (IASTNode)adaptor.BecomeRoot(TAKE134_tree, root_0); - NUM_INT134=(IToken)Match(input,NUM_INT,FOLLOW_NUM_INT_in_takeClause1659); - NUM_INT134_tree = (IASTNode)adaptor.Create(NUM_INT134); - adaptor.AddChild(root_0, NUM_INT134_tree); + // Hql.g:310:10: ( NUM_INT | parameter ) + int alt42 = 2; + int LA42_0 = input.LA(1); + if ( (LA42_0 == NUM_INT) ) + { + alt42 = 1; + } + else if ( ((LA42_0 >= COLON && LA42_0 <= PARAM)) ) + { + alt42 = 2; + } + else + { + NoViableAltException nvae_d42s0 = + new NoViableAltException("", 42, 0, input); + throw nvae_d42s0; + } + switch (alt42) + { + case 1 : + // Hql.g:310:11: NUM_INT + { + NUM_INT135=(IToken)Match(input,NUM_INT,FOLLOW_NUM_INT_in_takeClause1666); + NUM_INT135_tree = (IASTNode)adaptor.Create(NUM_INT135); + adaptor.AddChild(root_0, NUM_INT135_tree); + + + } + break; + case 2 : + // Hql.g:310:21: parameter + { + PushFollow(FOLLOW_parameter_in_takeClause1670); + parameter136 = parameter(); + state.followingStackPointer--; + + adaptor.AddChild(root_0, parameter136.Tree); + + } + break; + + } + + } retval.Stop = input.LT(-1); @@ -4622,6 +4708,132 @@ } // $ANTLR end "takeClause" + public class parameter_return : ParserRuleReturnScope + { + private IASTNode tree; + override public object Tree + { + get { return tree; } + set { tree = (IASTNode) value; } + } + }; + + // $ANTLR start "parameter" + // Hql.g:313:1: parameter : ( COLON identifier | PARAM ( NUM_INT )? ); + public HqlParser.parameter_return parameter() // throws RecognitionException [1] + { + HqlParser.parameter_return retval = new HqlParser.parameter_return(); + retval.Start = input.LT(1); + + IASTNode root_0 = null; + + IToken COLON137 = null; + IToken PARAM139 = null; + IToken NUM_INT140 = null; + HqlParser.identifier_return identifier138 = default(HqlParser.identifier_return); + + + IASTNode COLON137_tree=null; + IASTNode PARAM139_tree=null; + IASTNode NUM_INT140_tree=null; + + try + { + // Hql.g:314:2: ( COLON identifier | PARAM ( NUM_INT )? ) + int alt44 = 2; + int LA44_0 = input.LA(1); + + if ( (LA44_0 == COLON) ) + { + alt44 = 1; + } + else if ( (LA44_0 == PARAM) ) + { + alt44 = 2; + } + else + { + NoViableAltException nvae_d44s0 = + new NoViableAltException("", 44, 0, input); + + throw nvae_d44s0; + } + switch (alt44) + { + case 1 : + // Hql.g:314:4: COLON identifier + { + root_0 = (IASTNode)adaptor.GetNilNode(); + + COLON137=(IToken)Match(input,COLON,FOLLOW_COLON_in_parameter1682); + COLON137_tree = (IASTNode)adaptor.Create(COLON137); + root_0 = (IASTNode)adaptor.BecomeRoot(COLON137_tree, root_0); + + PushFollow(FOLLOW_identifier_in_parameter1685); + identifier138 = identifier(); + state.followingStackPointer--; + + adaptor.AddChild(root_0, identifier138.Tree); + + } + break; + case 2 : + // Hql.g:315:4: PARAM ( NUM_INT )? + { + root_0 = (IASTNode)adaptor.GetNilNode(); + + PARAM139=(IToken)Match(input,PARAM,FOLLOW_PARAM_in_parameter1690); + PARAM139_tree = (IASTNode)adaptor.Create(PARAM139); + root_0 = (IASTNode)adaptor.BecomeRoot(PARAM139_tree, root_0); + + // Hql.g:315:11: ( NUM_INT )? + int alt43 = 2; + int LA43_0 = input.LA(1); + + if ( (LA43_0 == NUM_INT) ) + { + alt43 = 1; + } + switch (alt43) + { + case 1 : + // Hql.g:315:12: NUM_INT + { + NUM_INT140=(IToken)Match(input,NUM_INT,FOLLOW_NUM_INT_in_parameter1694); + NUM_INT140_tree = (IASTNode)adaptor.Create(NUM_INT140); + adaptor.AddChild(root_0, NUM_INT140_tree); + + + } + break; + + } + + + } + break; + + } + retval.Stop = input.LT(-1); + + retval.Tree = (IASTNode)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop); + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (IASTNode)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "parameter" + public class orderElement_return : ParserRuleReturnScope { private IASTNode tree; @@ -4633,7 +4845,7 @@ }; // $ANTLR start "orderElement" - // Hql.g:313:1: orderElement : expression ( ascendingOrDescending )? ; + // Hql.g:318:1: orderElement : expression ( ascendingOrDescending )? ; public HqlParser.orderElement_return orderElement() // throws RecognitionException [1] { HqlParser.orderElement_return retval = new HqlParser.orderElement_return(); @@ -4641,42 +4853,42 @@ IASTNode root_0 = null; - HqlParser.expression_return expression135 = default(HqlParser.expression_return); + HqlParser.expression_return expression141 = default(HqlParser.expression_return); - HqlParser.ascendingOrDescending_return ascendingOrDescending136 = default(HqlParser.ascendingOrDescending_return); + HqlParser.ascendingOrDescending_return ascendingOrDescending142 = default(HqlParser.ascendingOrDescending_return); try { - // Hql.g:314:2: ( expression ( ascendingOrDescending )? ) - // Hql.g:314:4: expression ( ascendingOrDescending )? + // Hql.g:319:2: ( expression ( ascendingOrDescending )? ) + // Hql.g:319:4: expression ( ascendingOrDescending )? { root_0 = (IASTNode)adaptor.GetNilNode(); - PushFollow(FOLLOW_expression_in_orderElement1670); - expression135 = expression(); + PushFollow(FOLLOW_expression_in_orderElement1707); + expression141 = expression(); state.followingStackPointer--; - adaptor.AddChild(root_0, expression135.Tree); - // Hql.g:314:15: ( ascendingOrDescending )? - int alt41 = 2; - int LA41_0 = input.LA(1); + adaptor.AddChild(root_0, expression141.Tree); + // Hql.g:319:15: ( ascendingOrDescending )? + int alt45 = 2; + int LA45_0 = input.LA(1); - if ( (LA41_0 == ASCENDING || LA41_0 == DESCENDING || (LA41_0 >= 133 && LA41_0 <= 134)) ) + if ( (LA45_0 == ASCENDING || LA45_0 == DESCENDING || (LA45_0 >= 133 && LA45_0 <= 134)) ) { - alt41 = 1; + alt45 = 1; } - switch (alt41) + switch (alt45) { case 1 : - // Hql.g:314:17: ascendingOrDescending + // Hql.g:319:17: ascendingOrDescending { - PushFollow(FOLLOW_ascendingOrDescending_in_orderElement1674); - ascendingOrDescending136 = ascendingOrDescending(); + PushFollow(FOLLOW_ascendingOrDescending_in_orderElement1711); + ascendingOrDescending142 = ascendingOrDescending(); state.followingStackPointer--; - adaptor.AddChild(root_0, ascendingOrDescending136.Tree); + adaptor.AddChild(root_0, ascendingOrDescending142.Tree); } break; @@ -4717,7 +4929,7 @@ }; // $ANTLR start "ascendingOrDescending" - // Hql.g:317:1: ascendingOrDescending : ( (a= 'asc' | a= 'ascending' ) -> ^( ASCENDING[$a.Text] ) | (d= 'desc' | d= 'descending' ) -> ^( DESCENDING[$d.Text] ) ); + // Hql.g:322:1: ascendingOrDescending : ( (a= 'asc' | a= 'ascending' ) -> ^( ASCENDING[$a.Text] ) | (d= 'desc' | d= 'descending' ) -> ^( DESCENDING[$d.Text] ) ); public HqlParser.ascendingOrDescending_return ascendingOrDescending() // throws RecognitionException [1] { HqlParser.ascendingOrDescending_return retval = new HqlParser.ascendingOrDescending_return(); @@ -4737,64 +4949,64 @@ try { - // Hql.g:318:2: ( (a= 'asc' | a= 'ascending' ) -> ^( ASCENDING[$a.Text] ) | (d= 'desc' | d= 'descending' ) -> ^( DESCENDING[$d.Text] ) ) - int alt44 = 2; - int LA44_0 = input.LA(1); + // Hql.g:323:2: ( (a= 'asc' | a= 'ascending' ) -> ^( ASCENDING[$a.Text] ) | (d= 'desc' | d= 'descending' ) -> ^( DESCENDING[$d.Text] ) ) + int alt48 = 2; + int LA48_0 = input.LA(1); - if ( (LA44_0 == ASCENDING || LA44_0 == 133) ) + ... [truncated message content] |
From: <ric...@us...> - 2011-05-22 13:28:58
|
Revision: 5852 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5852&view=rev Author: ricbrown Date: 2011-05-22 13:28:51 +0000 (Sun, 22 May 2011) Log Message: ----------- NH-2683: Added first cut of the remaining dialect functions (thanks to Vahid Nasiri for the patch). Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Criterion/ProjectionsExtensions.cs trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFixture.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/ProjectionsExtensions.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/ProjectionsExtensions.cs 2011-05-22 11:02:26 UTC (rev 5851) +++ trunk/nhibernate/src/NHibernate/Criterion/ProjectionsExtensions.cs 2011-05-22 13:28:51 UTC (rev 5852) @@ -24,15 +24,376 @@ /// Project SQL function year() /// Note: throws an exception outside of a QueryOver expression /// </summary> - public static int Year(this DateTime dateTimeProperty) + public static int YearPart(this DateTime dateTimeProperty) { throw new Exception("Not to be used directly - use inside QueryOver expression"); } - internal static IProjection ProcessYear(MethodCallExpression methodCallExpression) + internal static IProjection ProcessYearPart(MethodCallExpression methodCallExpression) { IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); return Projections.SqlFunction("year", NHibernateUtil.DateTime, property); } + + /// <summary> + /// Project SQL function day() + /// Note: throws an exception outside of a QueryOver expression + /// </summary> + public static int DayPart(this DateTime dateTimeProperty) + { + throw new Exception("Not to be used directly - use inside QueryOver expression"); + } + + internal static IProjection ProcessDayPart(MethodCallExpression methodCallExpression) + { + IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); + return Projections.SqlFunction("day", NHibernateUtil.DateTime, property); + } + + /// <summary> + /// Project SQL function month() + /// Note: throws an exception outside of a QueryOver expression + /// </summary> + public static int MonthPart(this DateTime dateTimeProperty) + { + throw new Exception("Not to be used directly - use inside QueryOver expression"); + } + + internal static IProjection ProcessMonthPart(MethodCallExpression methodCallExpression) + { + IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); + return Projections.SqlFunction("month", NHibernateUtil.DateTime, property); + } + + /// <summary> + /// Project SQL function hour() + /// Note: throws an exception outside of a QueryOver expression + /// </summary> + public static int HourPart(this DateTime dateTimeProperty) + { + throw new Exception("Not to be used directly - use inside QueryOver expression"); + } + + internal static IProjection ProcessHourPart(MethodCallExpression methodCallExpression) + { + IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); + return Projections.SqlFunction("hour", NHibernateUtil.DateTime, property); + } + + /// <summary> + /// Project SQL function minute() + /// Note: throws an exception outside of a QueryOver expression + /// </summary> + public static int MinutePart(this DateTime dateTimeProperty) + { + throw new Exception("Not to be used directly - use inside QueryOver expression"); + } + + internal static IProjection ProcessMinutePart(MethodCallExpression methodCallExpression) + { + IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); + return Projections.SqlFunction("minute", NHibernateUtil.DateTime, property); + } + + /// <summary> + /// Project SQL function second() + /// Note: throws an exception outside of a QueryOver expression + /// </summary> + public static int SecondPart(this DateTime dateTimeProperty) + { + throw new Exception("Not to be used directly - use inside QueryOver expression"); + } + + internal static IProjection ProcessSecondPart(MethodCallExpression methodCallExpression) + { + IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); + return Projections.SqlFunction("second", NHibernateUtil.DateTime, property); + } + + /// <summary> + /// Project SQL function sqrt() + /// Note: throws an exception outside of a QueryOver expression + /// </summary> + public static double Sqrt(this double numericProperty) + { + throw new Exception("Not to be used directly - use inside QueryOver expression"); + } + + internal static IProjection ProcessDoubleSqrt(MethodCallExpression methodCallExpression) + { + IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); + return Projections.SqlFunction("sqrt", NHibernateUtil.Double, property); + } + + /// <summary> + /// Project SQL function sqrt() + /// Note: throws an exception outside of a QueryOver expression + /// </summary> + public static int Sqrt(this int numericProperty) + { + throw new Exception("Not to be used directly - use inside QueryOver expression"); + } + + internal static IProjection ProcessIntSqrt(MethodCallExpression methodCallExpression) + { + IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); + return Projections.SqlFunction("sqrt", NHibernateUtil.Int32, property); + } + + /// <summary> + /// Project SQL function sqrt() + /// Note: throws an exception outside of a QueryOver expression + /// </summary> + public static Int64 Sqrt(this Int64 numericProperty) + { + throw new Exception("Not to be used directly - use inside QueryOver expression"); + } + + internal static IProjection ProcessInt64Sqrt(MethodCallExpression methodCallExpression) + { + IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); + return Projections.SqlFunction("sqrt", NHibernateUtil.Int64, property); + } + + /// <summary> + /// Project SQL function sqrt() + /// Note: throws an exception outside of a QueryOver expression + /// </summary> + public static decimal Sqrt(this decimal numericProperty) + { + throw new Exception("Not to be used directly - use inside QueryOver expression"); + } + + internal static IProjection ProcessDecimalSqrt(MethodCallExpression methodCallExpression) + { + IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); + return Projections.SqlFunction("sqrt", NHibernateUtil.Decimal, property); + } + + /// <summary> + /// Project SQL function sqrt() + /// Note: throws an exception outside of a QueryOver expression + /// </summary> + public static byte Sqrt(this byte numericProperty) + { + throw new Exception("Not to be used directly - use inside QueryOver expression"); + } + + internal static IProjection ProcessByteSqrt(MethodCallExpression methodCallExpression) + { + IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); + return Projections.SqlFunction("sqrt", NHibernateUtil.Byte, property); + } + + /// <summary> + /// Project SQL function lower() + /// Note: throws an exception outside of a QueryOver expression + /// </summary> + public static string Lower(this string stringProperty) + { + throw new Exception("Not to be used directly - use inside QueryOver expression"); + } + + internal static IProjection ProcessLower(MethodCallExpression methodCallExpression) + { + IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); + return Projections.SqlFunction("lower", NHibernateUtil.String, property); + } + + /// <summary> + /// Project SQL function upper() + /// Note: throws an exception outside of a QueryOver expression + /// </summary> + public static string Upper(this string stringProperty) + { + throw new Exception("Not to be used directly - use inside QueryOver expression"); + } + + internal static IProjection ProcessUpper(MethodCallExpression methodCallExpression) + { + IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); + return Projections.SqlFunction("upper", NHibernateUtil.String, property); + } + + /// <summary> + /// Project SQL function abs() + /// Note: throws an exception outside of a QueryOver expression + /// </summary> + public static int Abs(this int numericProperty) + { + throw new Exception("Not to be used directly - use inside QueryOver expression"); + } + + internal static IProjection ProcessIntAbs(MethodCallExpression methodCallExpression) + { + IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); + return Projections.SqlFunction("abs", NHibernateUtil.Int32, property); + } + + /// <summary> + /// Project SQL function abs() + /// Note: throws an exception outside of a QueryOver expression + /// </summary> + public static Int64 Abs(this Int64 numericProperty) + { + throw new Exception("Not to be used directly - use inside QueryOver expression"); + } + + internal static IProjection ProcessInt64Abs(MethodCallExpression methodCallExpression) + { + IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); + return Projections.SqlFunction("abs", NHibernateUtil.Int64, property); + } + + /// <summary> + /// Project SQL function abs() + /// Note: throws an exception outside of a QueryOver expression + /// </summary> + public static double Abs(this double numericProperty) + { + throw new Exception("Not to be used directly - use inside QueryOver expression"); + } + + internal static IProjection ProcessDoubleAbs(MethodCallExpression methodCallExpression) + { + IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); + return Projections.SqlFunction("abs", NHibernateUtil.Double, property); + } + + /// <summary> + /// Project SQL function trim() + /// Note: throws an exception outside of a QueryOver expression + /// </summary> + public static string TrimStr(this string stringProperty) + { + throw new Exception("Not to be used directly - use inside QueryOver expression"); + } + + internal static IProjection ProcessTrimStr(MethodCallExpression methodCallExpression) + { + IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); + return Projections.SqlFunction("trim", NHibernateUtil.String, property); + } + + /// <summary> + /// Project SQL function length() + /// Note: throws an exception outside of a QueryOver expression + /// </summary> + public static int StrLength(this string stringProperty) + { + throw new Exception("Not to be used directly - use inside QueryOver expression"); + } + + internal static IProjection ProcessStrLength(MethodCallExpression methodCallExpression) + { + IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); + return Projections.SqlFunction("length", NHibernateUtil.String, property); + } + + /// <summary> + /// Project SQL function bit_length() + /// Note: throws an exception outside of a QueryOver expression + /// </summary> + public static int BitLength(this string stringProperty) + { + throw new Exception("Not to be used directly - use inside QueryOver expression"); + } + + internal static IProjection ProcessBitLength(MethodCallExpression methodCallExpression) + { + IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); + return Projections.SqlFunction("bit_length", NHibernateUtil.String, property); + } + + /// <summary> + /// Project SQL function substring() + /// Note: throws an exception outside of a QueryOver expression + /// </summary> + public static string Substr(this string stringProperty, int startIndex, int length) + { + throw new Exception("Not to be used directly - use inside QueryOver expression"); + } + + internal static IProjection ProcessSubstr(MethodCallExpression methodCallExpression) + { + IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); + object startIndex = ExpressionProcessor.FindValue(methodCallExpression.Arguments[1]); + object length = ExpressionProcessor.FindValue(methodCallExpression.Arguments[2]); + return Projections.SqlFunction("substring", NHibernateUtil.String, property, Projections.Constant(startIndex), Projections.Constant(length)); + } + + /// <summary> + /// Project SQL function locate() + /// Note: throws an exception outside of a QueryOver expression + /// </summary> + public static int CharIndex(this string stringProperty, string theChar, int startLocation) + { + throw new Exception("Not to be used directly - use inside QueryOver expression"); + } + + internal static IProjection ProcessCharIndex(MethodCallExpression methodCallExpression) + { + IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); + object theChar = ExpressionProcessor.FindValue(methodCallExpression.Arguments[1]); + object startLocation = ExpressionProcessor.FindValue(methodCallExpression.Arguments[2]); + return Projections.SqlFunction("locate", NHibernateUtil.String, Projections.Constant(theChar), property, Projections.Constant(startLocation)); + } + + /// <summary> + /// Project SQL function coalesce() + /// Note: throws an exception outside of a QueryOver expression + /// </summary> + public static T Coalesce<T>(this T objectProperty, T replaceValueIfIsNull) + { + throw new Exception("Not to be used directly - use inside QueryOver expression"); + } + + /// <summary> + /// Project SQL function coalesce() + /// Note: throws an exception outside of a QueryOver expression + /// </summary> + public static Nullable<T> Coalesce<T>(this Nullable<T> objectProperty, T replaceValueIfIsNull) where T : struct + { + throw new Exception("Not to be used directly - use inside QueryOver expression"); + } + + internal static IProjection ProcessCoalesce(MethodCallExpression methodCallExpression) + { + IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); + object replaceValueIfIsNull = ExpressionProcessor.FindValue(methodCallExpression.Arguments[1]); + return Projections.SqlFunction("coalesce", NHibernateUtil.Object, property, Projections.Constant(replaceValueIfIsNull)); + } + + /// <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> + public static int Mod(this int numericProperty, int divisor) + { + throw new Exception("Not to be used directly - use inside QueryOver expression"); + } + + internal static IProjection ProcessMod(MethodCallExpression methodCallExpression) + { + IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); + object divisor = ExpressionProcessor.FindValue(methodCallExpression.Arguments[1]); + return Projections.SqlFunction("mod", NHibernateUtil.Int32, property, Projections.Constant(divisor)); + } } } Modified: trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs 2011-05-22 11:02:26 UTC (rev 5851) +++ trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs 2011-05-22 13:28:51 UTC (rev 5852) @@ -89,7 +89,31 @@ RegisterCustomMethodCall(() => RestrictionExtensions.IsBetween(null, null).And(null), RestrictionExtensions.ProcessIsBetween); _customProjectionProcessors = new Dictionary<string, Func<MethodCallExpression, IProjection>>(); - RegisterCustomProjection(() => ProjectionsExtensions.Year(default(DateTime)), ProjectionsExtensions.ProcessYear); + RegisterCustomProjection(() => ProjectionsExtensions.YearPart(default(DateTime)), ProjectionsExtensions.ProcessYearPart); + RegisterCustomProjection(() => ProjectionsExtensions.DayPart(default(DateTime)), ProjectionsExtensions.ProcessDayPart); + RegisterCustomProjection(() => ProjectionsExtensions.MonthPart(default(DateTime)), ProjectionsExtensions.ProcessMonthPart); + RegisterCustomProjection(() => ProjectionsExtensions.HourPart(default(DateTime)), ProjectionsExtensions.ProcessHourPart); + RegisterCustomProjection(() => ProjectionsExtensions.MinutePart(default(DateTime)), ProjectionsExtensions.ProcessMinutePart); + RegisterCustomProjection(() => ProjectionsExtensions.SecondPart(default(DateTime)), ProjectionsExtensions.ProcessSecondPart); + RegisterCustomProjection(() => ProjectionsExtensions.Sqrt(default(int)), ProjectionsExtensions.ProcessIntSqrt); + RegisterCustomProjection(() => ProjectionsExtensions.Sqrt(default(double)), ProjectionsExtensions.ProcessDoubleSqrt); + RegisterCustomProjection(() => ProjectionsExtensions.Sqrt(default(decimal)), ProjectionsExtensions.ProcessDecimalSqrt); + RegisterCustomProjection(() => ProjectionsExtensions.Sqrt(default(byte)), ProjectionsExtensions.ProcessByteSqrt); + RegisterCustomProjection(() => ProjectionsExtensions.Sqrt(default(Int64)), ProjectionsExtensions.ProcessInt64Sqrt); + RegisterCustomProjection(() => ProjectionsExtensions.Lower(string.Empty), ProjectionsExtensions.ProcessLower); + RegisterCustomProjection(() => ProjectionsExtensions.Upper(string.Empty), ProjectionsExtensions.ProcessUpper); + RegisterCustomProjection(() => ProjectionsExtensions.TrimStr(string.Empty), ProjectionsExtensions.ProcessTrimStr); + RegisterCustomProjection(() => ProjectionsExtensions.StrLength(string.Empty), ProjectionsExtensions.ProcessStrLength); + RegisterCustomProjection(() => ProjectionsExtensions.BitLength(string.Empty), ProjectionsExtensions.ProcessBitLength); + RegisterCustomProjection(() => ProjectionsExtensions.Substr(string.Empty, 0, 0), ProjectionsExtensions.ProcessSubstr); + 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(() => ProjectionsExtensions.Mod(0, 0), ProjectionsExtensions.ProcessMod); + RegisterCustomProjection(() => ProjectionsExtensions.Abs(default(int)), ProjectionsExtensions.ProcessIntAbs); + RegisterCustomProjection(() => ProjectionsExtensions.Abs(default(double)), ProjectionsExtensions.ProcessDoubleAbs); + RegisterCustomProjection(() => ProjectionsExtensions.Abs(default(Int64)), ProjectionsExtensions.ProcessInt64Abs); } private static ICriterion Eq(IProjection propertyName, object value) @@ -204,7 +228,7 @@ if (methodCallExpression.Method.Name == "First") return FindMemberExpression(methodCallExpression.Arguments[0]); - throw new Exception("Unrecognised method call in epression " + expression.ToString()); + throw new Exception("Unrecognised method call in expression " + expression.ToString()); } throw new Exception("Could not determine member from " + expression.ToString()); @@ -484,8 +508,11 @@ return "class"; } - private static string Signature(MethodInfo methodInfo) + public static string Signature(MethodInfo methodInfo) { + while (methodInfo.IsGenericMethod && !methodInfo.IsGenericMethodDefinition) + methodInfo = methodInfo.GetGenericMethodDefinition(); + return methodInfo.DeclaringType.FullName + ":" + methodInfo.ToString(); } Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFixture.cs 2011-05-22 11:02:26 UTC (rev 5851) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFixture.cs 2011-05-22 13:28:51 UTC (rev 5852) @@ -2,11 +2,11 @@ using System; using System.Linq; using System.Linq.Expressions; - +using System.Reflection; using NHibernate.Criterion; using NHibernate.Impl; - using NUnit.Framework; +using SharpTestsEx; namespace NHibernate.Test.Criteria.Lambda { @@ -155,6 +155,34 @@ Assert.AreEqual(before.ToString(), after.ToString()); } + public void NonGenericMethod(string param1) { } + public T GenericMethod<T>(T param1) { return param1; } + + [Test] + public void TestSignatureNonGeneric() + { + MethodInfo thisMethod = GetType().GetMethod("NonGenericMethod"); + + ExpressionProcessor.Signature(thisMethod).Should().Be("NHibernate.Test.Criteria.Lambda.ExpressionProcessorFixture:Void NonGenericMethod(System.String)"); + } + + [Test] + public void TestSignatureGeneric() + { + MethodInfo thisMethod = GetType().GetMethod("GenericMethod"); + + ExpressionProcessor.Signature(thisMethod).Should().Be("NHibernate.Test.Criteria.Lambda.ExpressionProcessorFixture:T GenericMethod[T](T)"); + } + + [Test] + public void TestSignatureQualifiedGeneric() + { + Expression<Func<string>> expression = () => this.GenericMethod("test"); + MethodInfo genericMethodWithQualifiedType = (expression.Body as MethodCallExpression).Method; + + ExpressionProcessor.Signature(genericMethodWithQualifiedType).Should().Be("NHibernate.Test.Criteria.Lambda.ExpressionProcessorFixture:T GenericMethod[T](T)"); + } + } } Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs 2011-05-22 11:02:26 UTC (rev 5851) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs 2011-05-22 13:28:51 UTC (rev 5852) @@ -584,7 +584,7 @@ { var persons = s.QueryOver<Person>() - .Where(p => p.BirthDate.Year() == 2008) + .Where(p => p.BirthDate.YearPart() == 2008) .List(); persons.Count.Should().Be(1); Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs 2011-05-22 11:02:26 UTC (rev 5851) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs 2011-05-22 13:28:51 UTC (rev 5852) @@ -260,11 +260,47 @@ { ICriteria expected = CreateTestCriteria(typeof(Person)) - .Add(Restrictions.Eq(Projections.SqlFunction("year", NHibernateUtil.DateTime, Projections.Property("BirthDate")), 1970)); + .Add(Restrictions.Eq(Projections.SqlFunction("year", NHibernateUtil.DateTime, Projections.Property("BirthDate")), 1970)) + .Add(Restrictions.Eq(Projections.SqlFunction("day", NHibernateUtil.DateTime, Projections.Property("BirthDate")), 1)) + .Add(Restrictions.Eq(Projections.SqlFunction("month", NHibernateUtil.DateTime, Projections.Property("BirthDate")), 1)) + .Add(Restrictions.Eq(Projections.SqlFunction("hour", NHibernateUtil.DateTime, Projections.Property("BirthDate")), 1)) + .Add(Restrictions.Eq(Projections.SqlFunction("minute", NHibernateUtil.DateTime, Projections.Property("BirthDate")), 1)) + .Add(Restrictions.Eq(Projections.SqlFunction("second", NHibernateUtil.DateTime, Projections.Property("BirthDate")), 1)) + .Add(Restrictions.Eq(Projections.SqlFunction("sqrt", NHibernateUtil.Int32, Projections.Property("Height")), 10)) + .Add(Restrictions.Eq(Projections.SqlFunction("lower", NHibernateUtil.String, Projections.Property("Name")), "test")) + .Add(Restrictions.Eq(Projections.SqlFunction("upper", NHibernateUtil.String, Projections.Property("Name")), "TEST")) + .Add(Restrictions.Eq(Projections.SqlFunction("abs", NHibernateUtil.Int32, Projections.Property("Height")), 150)) + .Add(Restrictions.Eq(Projections.SqlFunction("trim", NHibernateUtil.String, Projections.Property("Name")), "test")) + .Add(Restrictions.Eq(Projections.SqlFunction("length", NHibernateUtil.String, Projections.Property("Name")), 4)) + .Add(Restrictions.Eq(Projections.SqlFunction("bit_length", NHibernateUtil.String, Projections.Property("Name")), 32)) + .Add(Restrictions.Eq(Projections.SqlFunction("substring", NHibernateUtil.String, Projections.Property("Name"), Projections.Constant(1), Projections.Constant(2)), "te")) + .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("mod", NHibernateUtil.Int32, Projections.Property("Height"), Projections.Constant(10)), 0)); IQueryOver<Person> actual = CreateTestQueryOver<Person>() - .Where(p => p.BirthDate.Year() == 1970); + .Where(p => p.BirthDate.YearPart() == 1970) + .And(p => p.BirthDate.DayPart() == 1) + .And(p => p.BirthDate.MonthPart() == 1) + .And(p => p.BirthDate.HourPart() == 1) + .And(p => p.BirthDate.MinutePart() == 1) + .And(p => p.BirthDate.SecondPart() == 1) + .And(p => p.Height.Sqrt() == 10) + .And(p => p.Name.Lower() == "test") + .And(p => p.Name.Upper() == "TEST") + .And(p => p.Height.Abs() == 150) + .And(p => p.Name.TrimStr() == "test") + .And(p => p.Name.StrLength() == 4) + .And(p => p.Name.BitLength() == 32) + .And(p => p.Name.Substr(1, 2) == "te") + .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 => 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. |
From: <ric...@us...> - 2011-05-22 14:22:28
|
Revision: 5853 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5853&view=rev Author: ricbrown Date: 2011-05-22 14:22:22 +0000 (Sun, 22 May 2011) Log Message: ----------- NH-2683: Added projection of SQL function extensions in QueryOver. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverProjectionBuilder.cs trunk/nhibernate/src/NHibernate/Criterion/ProjectionsExtensions.cs trunk/nhibernate/src/NHibernate/Criterion/QueryOver.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/RestrictionsFixture.cs Modified: trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverProjectionBuilder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverProjectionBuilder.cs 2011-05-22 13:28:51 UTC (rev 5852) +++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverProjectionBuilder.cs 2011-05-22 14:22:22 UTC (rev 5853) @@ -173,7 +173,7 @@ /// </summary> public QueryOverProjectionBuilder<T> Select(Expression<Func<T, object>> expression) { - PushProjection(Projections.Property(expression)); + PushProjection(ExpressionProcessor.FindMemberProjection(expression.Body)); return this; } @@ -182,7 +182,7 @@ /// </summary> public QueryOverProjectionBuilder<T> Select(Expression<Func<object>> expression) { - PushProjection(Projections.Property(expression)); + PushProjection(ExpressionProcessor.FindMemberProjection(expression.Body)); return this; } Modified: trunk/nhibernate/src/NHibernate/Criterion/ProjectionsExtensions.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/ProjectionsExtensions.cs 2011-05-22 13:28:51 UTC (rev 5852) +++ trunk/nhibernate/src/NHibernate/Criterion/ProjectionsExtensions.cs 2011-05-22 14:22:22 UTC (rev 5853) @@ -32,7 +32,7 @@ internal static IProjection ProcessYearPart(MethodCallExpression methodCallExpression) { IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); - return Projections.SqlFunction("year", NHibernateUtil.DateTime, property); + return Projections.SqlFunction("year", NHibernateUtil.Int32, property); } /// <summary> @@ -47,7 +47,7 @@ internal static IProjection ProcessDayPart(MethodCallExpression methodCallExpression) { IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); - return Projections.SqlFunction("day", NHibernateUtil.DateTime, property); + return Projections.SqlFunction("day", NHibernateUtil.Int32, property); } /// <summary> @@ -62,7 +62,7 @@ internal static IProjection ProcessMonthPart(MethodCallExpression methodCallExpression) { IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); - return Projections.SqlFunction("month", NHibernateUtil.DateTime, property); + return Projections.SqlFunction("month", NHibernateUtil.Int32, property); } /// <summary> @@ -77,7 +77,7 @@ internal static IProjection ProcessHourPart(MethodCallExpression methodCallExpression) { IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); - return Projections.SqlFunction("hour", NHibernateUtil.DateTime, property); + return Projections.SqlFunction("hour", NHibernateUtil.Int32, property); } /// <summary> @@ -92,7 +92,7 @@ internal static IProjection ProcessMinutePart(MethodCallExpression methodCallExpression) { IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); - return Projections.SqlFunction("minute", NHibernateUtil.DateTime, property); + return Projections.SqlFunction("minute", NHibernateUtil.Int32, property); } /// <summary> @@ -107,7 +107,7 @@ internal static IProjection ProcessSecondPart(MethodCallExpression methodCallExpression) { IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); - return Projections.SqlFunction("second", NHibernateUtil.DateTime, property); + return Projections.SqlFunction("second", NHibernateUtil.Int32, property); } /// <summary> Modified: trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2011-05-22 13:28:51 UTC (rev 5852) +++ trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2011-05-22 14:22:22 UTC (rev 5853) @@ -392,7 +392,7 @@ List<IProjection> projectionList = new List<IProjection>(); foreach (var projection in projections) - projectionList.Add(Projections.Property(ExpressionProcessor.FindMemberExpression(projection.Body))); + projectionList.Add(ExpressionProcessor.FindMemberProjection(projection.Body)); criteria.SetProjection(projectionList.ToArray()); return this; Modified: trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs 2011-05-22 13:28:51 UTC (rev 5852) +++ trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs 2011-05-22 14:22:22 UTC (rev 5853) @@ -163,6 +163,16 @@ /// </summary> public static IProjection FindMemberProjection(Expression expression) { + if (expression is UnaryExpression) + { + UnaryExpression unaryExpression = (UnaryExpression)expression; + + if (unaryExpression.NodeType != ExpressionType.Convert) + throw new Exception("Cannot interpret member from " + expression.ToString()); + + return FindMemberProjection(unaryExpression.Operand); + } + if (expression is MethodCallExpression) { MethodCallExpression methodCallExpression = (MethodCallExpression)expression; Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs 2011-05-22 13:28:51 UTC (rev 5852) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs 2011-05-22 14:22:22 UTC (rev 5853) @@ -591,6 +591,17 @@ persons[0].Name.Should().Be("p2"); } + using (ISession s = OpenSession()) + { + var yearOfBirth = + s.QueryOver<Person>() + .Where(p => p.Name == "p2") + .Select(p => p.BirthDate.YearPart()) + .SingleOrDefault<object>(); + + yearOfBirth.GetType().Should().Be(typeof(int)); + yearOfBirth.Should().Be(2008); + } } [Test] Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs 2011-05-22 13:28:51 UTC (rev 5852) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs 2011-05-22 14:22:22 UTC (rev 5853) @@ -137,6 +137,39 @@ AssertCriteriaAreEqual(expected, actual); } + [Test] + public void SelectSingleFunction() + { + ICriteria expected = + CreateTestCriteria(typeof(Person)) + .SetProjection(Projections.SqlFunction("year", NHibernateUtil.Int32, Projections.Property("BirthDate"))); + + var actual = + CreateTestQueryOver<Person>() + .Select(p => p.BirthDate.YearPart()); + + AssertCriteriaAreEqual(expected, actual); + } + + [Test] + public void SelectMultipleFunction() + { + ICriteria expected = + CreateTestCriteria(typeof(Person), "personAlias") + .SetProjection(Projections.ProjectionList() + .Add(Projections.SqlFunction("year", NHibernateUtil.Int32, Projections.Property("BirthDate"))) + .Add(Projections.SqlFunction("month", NHibernateUtil.Int32, Projections.Property("personAlias.BirthDate")))); + + Person personAlias = null; + var actual = + CreateTestQueryOver<Person>(() => personAlias) + .SelectList(list => list + .Select(p => p.BirthDate.YearPart()) + .Select(() => personAlias.BirthDate.MonthPart())); + + AssertCriteriaAreEqual(expected, actual); + } + } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs 2011-05-22 13:28:51 UTC (rev 5852) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs 2011-05-22 14:22:22 UTC (rev 5853) @@ -260,12 +260,12 @@ { ICriteria expected = CreateTestCriteria(typeof(Person)) - .Add(Restrictions.Eq(Projections.SqlFunction("year", NHibernateUtil.DateTime, Projections.Property("BirthDate")), 1970)) - .Add(Restrictions.Eq(Projections.SqlFunction("day", NHibernateUtil.DateTime, Projections.Property("BirthDate")), 1)) - .Add(Restrictions.Eq(Projections.SqlFunction("month", NHibernateUtil.DateTime, Projections.Property("BirthDate")), 1)) - .Add(Restrictions.Eq(Projections.SqlFunction("hour", NHibernateUtil.DateTime, Projections.Property("BirthDate")), 1)) - .Add(Restrictions.Eq(Projections.SqlFunction("minute", NHibernateUtil.DateTime, Projections.Property("BirthDate")), 1)) - .Add(Restrictions.Eq(Projections.SqlFunction("second", NHibernateUtil.DateTime, Projections.Property("BirthDate")), 1)) + .Add(Restrictions.Eq(Projections.SqlFunction("year", NHibernateUtil.Int32, Projections.Property("BirthDate")), 1970)) + .Add(Restrictions.Eq(Projections.SqlFunction("day", NHibernateUtil.Int32, Projections.Property("BirthDate")), 1)) + .Add(Restrictions.Eq(Projections.SqlFunction("month", NHibernateUtil.Int32, Projections.Property("BirthDate")), 1)) + .Add(Restrictions.Eq(Projections.SqlFunction("hour", NHibernateUtil.Int32, Projections.Property("BirthDate")), 1)) + .Add(Restrictions.Eq(Projections.SqlFunction("minute", NHibernateUtil.Int32, Projections.Property("BirthDate")), 1)) + .Add(Restrictions.Eq(Projections.SqlFunction("second", NHibernateUtil.Int32, Projections.Property("BirthDate")), 1)) .Add(Restrictions.Eq(Projections.SqlFunction("sqrt", NHibernateUtil.Int32, Projections.Property("Height")), 10)) .Add(Restrictions.Eq(Projections.SqlFunction("lower", NHibernateUtil.String, Projections.Property("Name")), "test")) .Add(Restrictions.Eq(Projections.SqlFunction("upper", NHibernateUtil.String, Projections.Property("Name")), "TEST")) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2011-05-22 14:59:04
|
Revision: 5854 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5854&view=rev Author: ricbrown Date: 2011-05-22 14:58:58 +0000 (Sun, 22 May 2011) Log Message: ----------- NH-2683: Updated Sqrt() QueryOver extension to return double Modified Paths: -------------- 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/ProjectionsExtensions.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/ProjectionsExtensions.cs 2011-05-22 14:22:22 UTC (rev 5853) +++ trunk/nhibernate/src/NHibernate/Criterion/ProjectionsExtensions.cs 2011-05-22 14:58:58 UTC (rev 5854) @@ -119,70 +119,46 @@ throw new Exception("Not to be used directly - use inside QueryOver expression"); } - internal static IProjection ProcessDoubleSqrt(MethodCallExpression methodCallExpression) - { - IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); - return Projections.SqlFunction("sqrt", NHibernateUtil.Double, property); - } - /// <summary> /// Project SQL function sqrt() /// Note: throws an exception outside of a QueryOver expression /// </summary> - public static int Sqrt(this int numericProperty) + public static double Sqrt(this int numericProperty) { throw new Exception("Not to be used directly - use inside QueryOver expression"); } - internal static IProjection ProcessIntSqrt(MethodCallExpression methodCallExpression) - { - IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); - return Projections.SqlFunction("sqrt", NHibernateUtil.Int32, property); - } - /// <summary> /// Project SQL function sqrt() /// Note: throws an exception outside of a QueryOver expression /// </summary> - public static Int64 Sqrt(this Int64 numericProperty) + public static double Sqrt(this long numericProperty) { throw new Exception("Not to be used directly - use inside QueryOver expression"); } - internal static IProjection ProcessInt64Sqrt(MethodCallExpression methodCallExpression) - { - IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); - return Projections.SqlFunction("sqrt", NHibernateUtil.Int64, property); - } - /// <summary> /// Project SQL function sqrt() /// Note: throws an exception outside of a QueryOver expression /// </summary> - public static decimal Sqrt(this decimal numericProperty) + public static double Sqrt(this decimal numericProperty) { throw new Exception("Not to be used directly - use inside QueryOver expression"); } - internal static IProjection ProcessDecimalSqrt(MethodCallExpression methodCallExpression) - { - IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); - return Projections.SqlFunction("sqrt", NHibernateUtil.Decimal, property); - } - /// <summary> /// Project SQL function sqrt() /// Note: throws an exception outside of a QueryOver expression /// </summary> - public static byte Sqrt(this byte numericProperty) + public static double Sqrt(this byte numericProperty) { throw new Exception("Not to be used directly - use inside QueryOver expression"); } - internal static IProjection ProcessByteSqrt(MethodCallExpression methodCallExpression) + internal static IProjection ProcessSqrt(MethodCallExpression methodCallExpression) { IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); - return Projections.SqlFunction("sqrt", NHibernateUtil.Byte, property); + return Projections.SqlFunction("sqrt", NHibernateUtil.Double, property); } /// <summary> Modified: trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs 2011-05-22 14:22:22 UTC (rev 5853) +++ trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs 2011-05-22 14:58:58 UTC (rev 5854) @@ -95,11 +95,11 @@ RegisterCustomProjection(() => ProjectionsExtensions.HourPart(default(DateTime)), ProjectionsExtensions.ProcessHourPart); RegisterCustomProjection(() => ProjectionsExtensions.MinutePart(default(DateTime)), ProjectionsExtensions.ProcessMinutePart); RegisterCustomProjection(() => ProjectionsExtensions.SecondPart(default(DateTime)), ProjectionsExtensions.ProcessSecondPart); - RegisterCustomProjection(() => ProjectionsExtensions.Sqrt(default(int)), ProjectionsExtensions.ProcessIntSqrt); - RegisterCustomProjection(() => ProjectionsExtensions.Sqrt(default(double)), ProjectionsExtensions.ProcessDoubleSqrt); - RegisterCustomProjection(() => ProjectionsExtensions.Sqrt(default(decimal)), ProjectionsExtensions.ProcessDecimalSqrt); - RegisterCustomProjection(() => ProjectionsExtensions.Sqrt(default(byte)), ProjectionsExtensions.ProcessByteSqrt); - RegisterCustomProjection(() => ProjectionsExtensions.Sqrt(default(Int64)), ProjectionsExtensions.ProcessInt64Sqrt); + RegisterCustomProjection(() => ProjectionsExtensions.Sqrt(default(int)), ProjectionsExtensions.ProcessSqrt); + RegisterCustomProjection(() => ProjectionsExtensions.Sqrt(default(double)), ProjectionsExtensions.ProcessSqrt); + RegisterCustomProjection(() => ProjectionsExtensions.Sqrt(default(decimal)), ProjectionsExtensions.ProcessSqrt); + RegisterCustomProjection(() => ProjectionsExtensions.Sqrt(default(byte)), ProjectionsExtensions.ProcessSqrt); + RegisterCustomProjection(() => ProjectionsExtensions.Sqrt(default(long)), ProjectionsExtensions.ProcessSqrt); RegisterCustomProjection(() => ProjectionsExtensions.Lower(string.Empty), ProjectionsExtensions.ProcessLower); RegisterCustomProjection(() => ProjectionsExtensions.Upper(string.Empty), ProjectionsExtensions.ProcessUpper); RegisterCustomProjection(() => ProjectionsExtensions.TrimStr(string.Empty), ProjectionsExtensions.ProcessTrimStr); Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs 2011-05-22 14:22:22 UTC (rev 5853) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs 2011-05-22 14:58:58 UTC (rev 5854) @@ -573,7 +573,7 @@ using (ISession s = OpenSession()) using (ITransaction t = s.BeginTransaction()) { - s.Save(new Person() { Name = "p1", BirthDate = new DateTime(2009, 08, 07) }); + 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) }); @@ -602,6 +602,18 @@ yearOfBirth.GetType().Should().Be(typeof(int)); yearOfBirth.Should().Be(2008); } + + using (ISession s = OpenSession()) + { + var sqrtOfAge = + s.QueryOver<Person>() + .Where(p => p.Name == "p1") + .Select(p => p.Age.Sqrt()) + .SingleOrDefault<object>(); + + sqrtOfAge.GetType().Should().Be(typeof(double)); + string.Format("{0:0.00}", sqrtOfAge).Should().Be("9.49"); + } } [Test] Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs 2011-05-22 14:22:22 UTC (rev 5853) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs 2011-05-22 14:58:58 UTC (rev 5854) @@ -266,7 +266,7 @@ .Add(Restrictions.Eq(Projections.SqlFunction("hour", NHibernateUtil.Int32, Projections.Property("BirthDate")), 1)) .Add(Restrictions.Eq(Projections.SqlFunction("minute", NHibernateUtil.Int32, Projections.Property("BirthDate")), 1)) .Add(Restrictions.Eq(Projections.SqlFunction("second", NHibernateUtil.Int32, Projections.Property("BirthDate")), 1)) - .Add(Restrictions.Eq(Projections.SqlFunction("sqrt", NHibernateUtil.Int32, Projections.Property("Height")), 10)) + .Add(Restrictions.Eq(Projections.SqlFunction("sqrt", NHibernateUtil.Double, Projections.Property("Height")), 10d)) .Add(Restrictions.Eq(Projections.SqlFunction("lower", NHibernateUtil.String, Projections.Property("Name")), "test")) .Add(Restrictions.Eq(Projections.SqlFunction("upper", NHibernateUtil.String, Projections.Property("Name")), "TEST")) .Add(Restrictions.Eq(Projections.SqlFunction("abs", NHibernateUtil.Int32, Projections.Property("Height")), 150)) 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. |
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-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 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 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 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 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: <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-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. |