You can subscribe to this list here.
2004 |
Jan
|
Feb
|
Mar
|
Apr
(248) |
May
(82) |
Jun
(90) |
Jul
(177) |
Aug
(253) |
Sep
(157) |
Oct
(151) |
Nov
(143) |
Dec
(278) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2005 |
Jan
(152) |
Feb
(107) |
Mar
(177) |
Apr
(133) |
May
(259) |
Jun
(81) |
Jul
(119) |
Aug
(306) |
Sep
(416) |
Oct
(240) |
Nov
(329) |
Dec
(206) |
2006 |
Jan
(466) |
Feb
(382) |
Mar
(153) |
Apr
(162) |
May
(133) |
Jun
(21) |
Jul
(18) |
Aug
(37) |
Sep
(97) |
Oct
(114) |
Nov
(110) |
Dec
(28) |
2007 |
Jan
(74) |
Feb
(65) |
Mar
(49) |
Apr
(76) |
May
(43) |
Jun
(15) |
Jul
(68) |
Aug
(55) |
Sep
(63) |
Oct
(59) |
Nov
(70) |
Dec
(66) |
2008 |
Jan
(71) |
Feb
(60) |
Mar
(120) |
Apr
(31) |
May
(48) |
Jun
(81) |
Jul
(107) |
Aug
(51) |
Sep
(80) |
Oct
(83) |
Nov
(83) |
Dec
(79) |
2009 |
Jan
(83) |
Feb
(110) |
Mar
(97) |
Apr
(91) |
May
(291) |
Jun
(250) |
Jul
(197) |
Aug
(58) |
Sep
(54) |
Oct
(122) |
Nov
(68) |
Dec
(34) |
2010 |
Jan
(50) |
Feb
(17) |
Mar
(63) |
Apr
(61) |
May
(84) |
Jun
(81) |
Jul
(138) |
Aug
(144) |
Sep
(78) |
Oct
(26) |
Nov
(30) |
Dec
(61) |
2011 |
Jan
(33) |
Feb
(35) |
Mar
(166) |
Apr
(221) |
May
(109) |
Jun
(76) |
Jul
(27) |
Aug
(37) |
Sep
(1) |
Oct
(4) |
Nov
(2) |
Dec
(1) |
2012 |
Jan
|
Feb
|
Mar
(2) |
Apr
(2) |
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
(1) |
Oct
|
Nov
(1) |
Dec
|
2013 |
Jan
|
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
(1) |
Sep
(3) |
Oct
(2) |
Nov
|
Dec
(1) |
2014 |
Jan
(1) |
Feb
(1) |
Mar
(3) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <pa...@us...> - 2010-11-28 19:12:19
|
Revision: 5278 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5278&view=rev Author: patearl Date: 2010-11-28 19:12:13 +0000 (Sun, 28 Nov 2010) Log Message: ----------- Fixed incorrect usages of StringHelper.Split. This is a partial fix for using composite types as HQL parameter values. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/AbstractNullnessCheckNode.cs trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/BinaryLogicOperatorNode.cs trunk/nhibernate/src/NHibernate/Id/IncrementGenerator.cs Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/AbstractNullnessCheckNode.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/AbstractNullnessCheckNode.cs 2010-11-28 04:35:11 UTC (rev 5277) +++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/AbstractNullnessCheckNode.cs 2010-11-28 19:12:13 UTC (rev 5278) @@ -142,7 +142,7 @@ nodeText = nodeText.Substring( 0, nodeText.Length - 1 ); } - string[] splits = StringHelper.Split( ", ", nodeText ); + string[] splits = nodeText.Split(new[] { ", " }, StringSplitOptions.None); if ( count != splits.Length ) { Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/BinaryLogicOperatorNode.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/BinaryLogicOperatorNode.cs 2010-11-28 04:35:11 UTC (rev 5277) +++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/BinaryLogicOperatorNode.cs 2010-11-28 19:12:13 UTC (rev 5278) @@ -221,7 +221,7 @@ { nodeText = nodeText.Substring( 0, nodeText.Length - 1 ); } - String[] splits = StringHelper.Split( ", ", nodeText ); + string[] splits = nodeText.Split(new[] { ", " }, StringSplitOptions.None); if ( count != splits.Length ) { Modified: trunk/nhibernate/src/NHibernate/Id/IncrementGenerator.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Id/IncrementGenerator.cs 2010-11-28 04:35:11 UTC (rev 5277) +++ trunk/nhibernate/src/NHibernate/Id/IncrementGenerator.cs 2010-11-28 19:12:13 UTC (rev 5278) @@ -48,7 +48,7 @@ if (!parms.TryGetValue("tables", out tableList)) parms.TryGetValue(PersistentIdGeneratorParmsNames.Tables, out tableList); - string[] tables = StringHelper.Split(", ", tableList); + string[] tables = tableList.Split(", ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); if (!parms.TryGetValue("column", out column)) parms.TryGetValue(PersistentIdGeneratorParmsNames.PK, out column); returnClass = type.ReturnedClass; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pa...@us...> - 2010-11-28 04:35:17
|
Revision: 5277 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5277&view=rev Author: patearl Date: 2010-11-28 04:35:11 +0000 (Sun, 28 Nov 2010) Log Message: ----------- Linq: Added file missing from earlier commit. Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/Linq/NullComparisonTests.cs Added: trunk/nhibernate/src/NHibernate.Test/Linq/NullComparisonTests.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/NullComparisonTests.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Linq/NullComparisonTests.cs 2010-11-28 04:35:11 UTC (rev 5277) @@ -0,0 +1,309 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NHibernate.Linq; +using NHibernate.Test.Linq.Entities; +using NUnit.Framework; + +namespace NHibernate.Test.Linq +{ + [TestFixture] + public class NullComparisonTests : LinqTestCase + { + private static readonly AnotherEntity OutputSet = new AnotherEntity {Output = "output"}; + private static readonly AnotherEntity InputSet = new AnotherEntity {Input = "input"}; + private static readonly AnotherEntity BothSame = new AnotherEntity {Input = "i/o", Output = "i/o"}; + private static readonly AnotherEntity BothNull = new AnotherEntity(); + private static readonly AnotherEntity BothDifferent = new AnotherEntity {Input = "input", Output = "output"}; + + [Test] + public void NullEquality() + { + string nullVariable = null; + string nullVariable2 = null; + string notNullVariable = "input"; + + Assert.AreEqual(5, session.CreateCriteria<AnotherEntity>().List<AnotherEntity>().Count); + + IQueryable<AnotherEntity> q; + + // Null literal against itself + q = from x in session.Query<AnotherEntity>() where null == null select x; + ExpectAll(q); + + // Null against constants + q = from x in session.Query<AnotherEntity>() where null == "value" select x; + ExpectNone(q); + q = from x in session.Query<AnotherEntity>() where "value" == null select x; + ExpectNone(q); + + // Null against variables + q = from x in session.Query<AnotherEntity>() where null == nullVariable select x; + ExpectAll(q); + q = from x in session.Query<AnotherEntity>() where null == notNullVariable select x; + ExpectNone(q); + q = from x in session.Query<AnotherEntity>() where nullVariable == null select x; + ExpectAll(q); + q = from x in session.Query<AnotherEntity>() where notNullVariable == null select x; + ExpectNone(q); + + // Null against columns + q = from x in session.Query<AnotherEntity>() where x.Input == null select x; + ExpectInputIsNull(q); + q = from x in session.Query<AnotherEntity>() where null == x.Input select x; + ExpectInputIsNull(q); + + // All null pairings with two columns. + q = from x in session.Query<AnotherEntity>() where x.Input == null && x.Output == null select x; + Expect(q, BothNull); + q = from x in session.Query<AnotherEntity>() where x.Input != null && x.Output == null select x; + Expect(q, InputSet); + q = from x in session.Query<AnotherEntity>() where x.Input == null && x.Output != null select x; + Expect(q, OutputSet); + q = from x in session.Query<AnotherEntity>() where x.Input != null && x.Output != null select x; + Expect(q, BothSame, BothDifferent); + + // Variables against variables + q = from x in session.Query<AnotherEntity>() where nullVariable == nullVariable2 select x; + ExpectAll(q); + q = from x in session.Query<AnotherEntity>() where nullVariable == notNullVariable select x; + ExpectNone(q); + q = from x in session.Query<AnotherEntity>() where notNullVariable == nullVariable select x; + ExpectNone(q); + + //// Variables against columns + q = from x in session.Query<AnotherEntity>() where nullVariable == x.Input select x; + ExpectInputIsNull(q); + q = from x in session.Query<AnotherEntity>() where notNullVariable == x.Input select x; + Expect(q, InputSet, BothDifferent); + q = from x in session.Query<AnotherEntity>() where x.Input == nullVariable select x; + ExpectInputIsNull(q); + q = from x in session.Query<AnotherEntity>() where x.Input == notNullVariable select x; + Expect(q, InputSet, BothDifferent); + + // Columns against columns + q = from x in session.Query<AnotherEntity>() where x.Input == x.Output select x; + Expect(q, BothSame); + } + + [Test] + public void NullInequality() + { + string nullVariable = null; + string nullVariable2 = null; + string notNullVariable = "input"; + + IQueryable<AnotherEntity> q; + + // Null literal against itself + q = from x in session.Query<AnotherEntity>() where null != null select x; + ExpectNone(q); + + // Null against constants + q = from x in session.Query<AnotherEntity>() where null != "value" select x; + ExpectAll(q); + q = from x in session.Query<AnotherEntity>() where "value" != null select x; + ExpectAll(q); + + // Null against variables + q = from x in session.Query<AnotherEntity>() where null != nullVariable select x; + ExpectNone(q); + q = from x in session.Query<AnotherEntity>() where null != notNullVariable select x; + ExpectAll(q); + q = from x in session.Query<AnotherEntity>() where nullVariable != null select x; + ExpectNone(q); + q = from x in session.Query<AnotherEntity>() where notNullVariable != null select x; + ExpectAll(q); + + // Null against columns. + q = from x in session.Query<AnotherEntity>() where x.Input != null select x; + ExpectInputIsNotNull(q); + q = from x in session.Query<AnotherEntity>() where null != x.Input select x; + ExpectInputIsNotNull(q); + + // Variables against variables. + q = from x in session.Query<AnotherEntity>() where nullVariable != nullVariable2 select x; + ExpectNone(q); + q = from x in session.Query<AnotherEntity>() where nullVariable != notNullVariable select x; + ExpectAll(q); + q = from x in session.Query<AnotherEntity>() where notNullVariable != nullVariable select x; + ExpectAll(q); + + // Variables against columns. + q = from x in session.Query<AnotherEntity>() where nullVariable != x.Input select x; + ExpectInputIsNotNull(q); + q = from x in session.Query<AnotherEntity>() where notNullVariable != x.Input select x; + Expect(q, BothSame); + q = from x in session.Query<AnotherEntity>() where x.Input != nullVariable select x; + ExpectInputIsNotNull(q); + q = from x in session.Query<AnotherEntity>() where x.Input != notNullVariable select x; + Expect(q, BothSame); + + // Columns against columns + q = from x in session.Query<AnotherEntity>() where x.Input != x.Output select x; + Expect(q, BothDifferent); + } + + [Test] + public void NullEqualityInverted() + { + string nullVariable = null; + string nullVariable2 = null; + string notNullVariable = "input"; + + IQueryable<AnotherEntity> q; + + // Null literal against itself + q = from x in session.Query<AnotherEntity>() where !(null == null) select x; + ExpectNone(q); + + // Null against constants + q = from x in session.Query<AnotherEntity>() where !(null == "value") select x; + ExpectAll(q); + q = from x in session.Query<AnotherEntity>() where !("value" == null) select x; + ExpectAll(q); + + // Null against variables + q = from x in session.Query<AnotherEntity>() where !(null == nullVariable) select x; + ExpectNone(q); + q = from x in session.Query<AnotherEntity>() where !(null == notNullVariable) select x; + ExpectAll(q); + q = from x in session.Query<AnotherEntity>() where !(nullVariable == null) select x; + ExpectNone(q); + q = from x in session.Query<AnotherEntity>() where !(notNullVariable == null) select x; + ExpectAll(q); + + // Null against columns + q = from x in session.Query<AnotherEntity>() where !(x.Input == null) select x; + ExpectInputIsNotNull(q); + q = from x in session.Query<AnotherEntity>() where !(null == x.Input) select x; + ExpectInputIsNotNull(q); + + // All null pairings with two columns. + q = from x in session.Query<AnotherEntity>() where !(x.Input == null && x.Output == null) select x; + Expect(q, InputSet, OutputSet, BothSame, BothDifferent); + q = from x in session.Query<AnotherEntity>() where !(x.Input != null && x.Output == null) select x; + Expect(q, OutputSet, BothNull, BothSame, BothDifferent); + q = from x in session.Query<AnotherEntity>() where !(x.Input == null && x.Output != null) select x; + Expect(q, InputSet, BothSame, BothDifferent, BothNull); + q = from x in session.Query<AnotherEntity>() where !(x.Input != null && x.Output != null) select x; + Expect(q, InputSet, OutputSet, BothNull); + + // Variables against variables + q = from x in session.Query<AnotherEntity>() where !(nullVariable == nullVariable2) select x; + ExpectNone(q); + q = from x in session.Query<AnotherEntity>() where !(nullVariable == notNullVariable) select x; + ExpectAll(q); + q = from x in session.Query<AnotherEntity>() where !(notNullVariable == nullVariable) select x; + ExpectAll(q); + + // Variables against columns + q = from x in session.Query<AnotherEntity>() where !(nullVariable == x.Input) select x; + ExpectInputIsNotNull(q); + q = from x in session.Query<AnotherEntity>() where !(notNullVariable == x.Input) select x; + Expect(q, BothSame); + q = from x in session.Query<AnotherEntity>() where !(x.Input == nullVariable) select x; + ExpectInputIsNotNull(q); + q = from x in session.Query<AnotherEntity>() where !(x.Input == notNullVariable) select x; + Expect(q, BothSame); + + // Columns against columns + q = from x in session.Query<AnotherEntity>() where !(x.Input == x.Output) select x; + Expect(q, BothDifferent); + } + + [Test] + public void NullInequalityInverted() + { + string nullVariable = null; + string nullVariable2 = null; + string notNullVariable = "input"; + + IQueryable<AnotherEntity> q; + + // Null literal against itself + q = from x in session.Query<AnotherEntity>() where !(null != null) select x; + ExpectAll(q); + + // Null against constants + q = from x in session.Query<AnotherEntity>() where !(null != "value") select x; + ExpectNone(q); + q = from x in session.Query<AnotherEntity>() where !("value" != null) select x; + ExpectNone(q); + + // Null against variables + q = from x in session.Query<AnotherEntity>() where !(null != nullVariable) select x; + ExpectAll(q); + q = from x in session.Query<AnotherEntity>() where !(null != notNullVariable) select x; + ExpectNone(q); + q = from x in session.Query<AnotherEntity>() where !(nullVariable != null) select x; + ExpectAll(q); + q = from x in session.Query<AnotherEntity>() where !(notNullVariable != null) select x; + ExpectNone(q); + + // Null against columns. + q = from x in session.Query<AnotherEntity>() where !(x.Input != null) select x; + ExpectInputIsNull(q); + q = from x in session.Query<AnotherEntity>() where !(null != x.Input) select x; + ExpectInputIsNull(q); + + // Variables against variables. + q = from x in session.Query<AnotherEntity>() where !(nullVariable != nullVariable2) select x; + ExpectAll(q); + q = from x in session.Query<AnotherEntity>() where !(nullVariable != notNullVariable) select x; + ExpectNone(q); + q = from x in session.Query<AnotherEntity>() where !(notNullVariable != nullVariable) select x; + ExpectNone(q); + + // Variables against columns. + q = from x in session.Query<AnotherEntity>() where !(nullVariable != x.Input) select x; + ExpectInputIsNull(q); + q = from x in session.Query<AnotherEntity>() where !(notNullVariable != x.Input) select x; + Expect(q, InputSet, BothDifferent); + q = from x in session.Query<AnotherEntity>() where !(x.Input != nullVariable) select x; + ExpectInputIsNull(q); + q = from x in session.Query<AnotherEntity>() where !(x.Input != notNullVariable) select x; + Expect(q, InputSet, BothDifferent); + + // Columns against columns + q = from x in session.Query<AnotherEntity>() where !(x.Input != x.Output) select x; + Expect(q, BothSame); + } + + private void ExpectAll(IQueryable<AnotherEntity> q) + { + Expect(q, BothNull, BothSame, BothDifferent, InputSet, OutputSet); + } + + private void ExpectNone(IQueryable<AnotherEntity> q) + { + Expect(q); + } + + private void ExpectInputIsNull(IQueryable<AnotherEntity> q) + { + Expect(q, BothNull, OutputSet); + } + + private void ExpectInputIsNotNull(IQueryable<AnotherEntity> q) + { + Expect(q, InputSet, BothSame, BothDifferent); + } + + private void Expect(IQueryable<AnotherEntity> q, params AnotherEntity[] entities) + { + IList<AnotherEntity> results = q.ToList().OrderBy(Key).ToList(); + IList<AnotherEntity> check = entities.OrderBy(Key).ToList(); + + Assert.AreEqual(check.Count, results.Count); + for(int i=0; i<check.Count; i++) + Assert.AreEqual(Key(check[i]), Key(results[i])); + } + + private string Key(AnotherEntity e) + { + return "Input=" + (e.Input ?? "NULL") + ", Output=" + (e.Output ?? "NULL"); + } + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pa...@us...> - 2010-11-28 03:37:37
|
Revision: 5276 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5276&view=rev Author: patearl Date: 2010-11-28 03:37:31 +0000 (Sun, 28 Nov 2010) Log Message: ----------- Linq: Added an expression visitor that provides access to parent nodes while visiting. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/NHibernate.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate/Linq/Visitors/ContextualNhExpressionTreeVisitor.cs trunk/nhibernate/src/NHibernate/Linq/Visitors/VisitorContext.cs Added: trunk/nhibernate/src/NHibernate/Linq/Visitors/ContextualNhExpressionTreeVisitor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Visitors/ContextualNhExpressionTreeVisitor.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Linq/Visitors/ContextualNhExpressionTreeVisitor.cs 2010-11-28 03:37:31 UTC (rev 5276) @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using NHibernate.Linq.Visitors; + +namespace NHibernate.Linq +{ + public class ContextualNhExpressionTreeVisitor : NhExpressionTreeVisitor + { + private Stack<VisitorContext> _contextStack; + + public ContextualNhExpressionTreeVisitor() + { + _contextStack = new Stack<VisitorContext>(); + _contextStack.Push(null); + } + + public override Expression VisitExpression(Expression expression) + { + if (expression == null) + return null; + + VisitorContext context = new VisitorContext(_contextStack.Peek(), expression); + _contextStack.Push(context); + + Expression result = base.VisitExpression(expression); + + _contextStack.Pop(); + + return result; + } + + protected VisitorContext Context + { + get { return _contextStack.Peek(); } + } + } +} Added: trunk/nhibernate/src/NHibernate/Linq/Visitors/VisitorContext.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Visitors/VisitorContext.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Linq/Visitors/VisitorContext.cs 2010-11-28 03:37:31 UTC (rev 5276) @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace NHibernate.Linq.Visitors +{ + public class VisitorContext + { + public VisitorContext(VisitorContext parent, Expression expression) + { + Parent = parent; + Expression = expression; + } + + public VisitorContext Parent { get; private set; } + public Expression Expression { get; private set; } + } +} Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2010-11-26 04:02:34 UTC (rev 5275) +++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2010-11-28 03:37:31 UTC (rev 5276) @@ -241,6 +241,8 @@ <Compile Include="ISessionFactory.cs" /> <Compile Include="ITransaction.cs" /> <Compile Include="LazyInitializationException.cs" /> + <Compile Include="Linq\Visitors\ContextualNhExpressionTreeVisitor.cs" /> + <Compile Include="Linq\Visitors\VisitorContext.cs" /> <Compile Include="Loader\Loader.cs" /> <Compile Include="Loader\OuterJoinLoader.cs" /> <Compile Include="LockMode.cs" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pa...@us...> - 2010-11-26 04:02:41
|
Revision: 5275 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5275&view=rev Author: patearl Date: 2010-11-26 04:02:34 +0000 (Fri, 26 Nov 2010) Log Message: ----------- Linq: Replaced "1" and "0" constants with "true" and "false" so they can be mapped in a dialect-specific way at the HQL level. (NH-2403) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs 2010-11-25 17:13:29 UTC (rev 5274) +++ trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs 2010-11-26 04:02:34 UTC (rev 5275) @@ -215,13 +215,13 @@ { lhs = _hqlTreeBuilder.Case( - new [] { _hqlTreeBuilder.When(lhs, _hqlTreeBuilder.Constant(1)) }, - _hqlTreeBuilder.Constant(0)); + new [] { _hqlTreeBuilder.When(lhs, _hqlTreeBuilder.Constant(true)) }, + _hqlTreeBuilder.Constant(false)); rhs = _hqlTreeBuilder.Case( - new [] { _hqlTreeBuilder.When(rhs, _hqlTreeBuilder.Constant(1)) }, - _hqlTreeBuilder.Constant(0)); + new [] { _hqlTreeBuilder.When(rhs, _hqlTreeBuilder.Constant(true)) }, + _hqlTreeBuilder.Constant(false)); return _hqlTreeBuilder.Equality(lhs, rhs); } @@ -250,13 +250,13 @@ { lhs = _hqlTreeBuilder.Case( - new [] { _hqlTreeBuilder.When(lhs, _hqlTreeBuilder.Constant(1)) }, - _hqlTreeBuilder.Constant(0)); + new [] { _hqlTreeBuilder.When(lhs, _hqlTreeBuilder.Constant(true)) }, + _hqlTreeBuilder.Constant(false)); rhs = _hqlTreeBuilder.Case( - new [] { _hqlTreeBuilder.When(rhs, _hqlTreeBuilder.Constant(1)) }, - _hqlTreeBuilder.Constant(0)); + new [] { _hqlTreeBuilder.When(rhs, _hqlTreeBuilder.Constant(true)) }, + _hqlTreeBuilder.Constant(false)); return _hqlTreeBuilder.Inequality(lhs, rhs); @@ -377,7 +377,7 @@ if (namedParameter.Value is bool) { return _hqlTreeBuilder.Equality(_hqlTreeBuilder.Parameter(namedParameter.Name).AsExpression(), - _hqlTreeBuilder.Constant(1)); + _hqlTreeBuilder.Constant(true)); } return _hqlTreeBuilder.Parameter(namedParameter.Name).AsExpression(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2010-11-25 17:13:35
|
Revision: 5274 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5274&view=rev Author: fabiomaulo Date: 2010-11-25 17:13:29 +0000 (Thu, 25 Nov 2010) Log Message: ----------- fixed bug about on-delete Modified Paths: -------------- trunk/nhibernate/doc/reference/modules/performance.xml Modified: trunk/nhibernate/doc/reference/modules/performance.xml =================================================================== --- trunk/nhibernate/doc/reference/modules/performance.xml 2010-11-25 17:08:40 UTC (rev 5273) +++ trunk/nhibernate/doc/reference/modules/performance.xml 2010-11-25 17:13:29 UTC (rev 5274) @@ -1149,7 +1149,7 @@ </para> <para> - Of course, one-shot-delete does not apply to collections mapped <literal>inverse="true"</literal>. + one-shot-delete apply to collections mapped <literal>inverse="true"</literal>. </para> </sect2> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2010-11-25 17:08:48
|
Revision: 5273 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5273&view=rev Author: fabiomaulo Date: 2010-11-25 17:08:40 +0000 (Thu, 25 Nov 2010) Log Message: ----------- Fixed some others stuff about batching Modified Paths: -------------- trunk/nhibernate/doc/reference/modules/performance.xml Modified: trunk/nhibernate/doc/reference/modules/performance.xml =================================================================== --- trunk/nhibernate/doc/reference/modules/performance.xml 2010-11-25 16:59:12 UTC (rev 5272) +++ trunk/nhibernate/doc/reference/modules/performance.xml 2010-11-25 17:08:40 UTC (rev 5273) @@ -1169,7 +1169,7 @@ <para>.NET Framework 2.0 or above is required,</para> </listitem> <listitem> - <para>only Microsoft SQL Server is supported currently,</para> + <para>the Nhibernate's drive used for your RDBMS may not supports batching,</para> </listitem> <listitem> <para>since the implementation uses reflection to access members and types @@ -1184,7 +1184,7 @@ </itemizedlist> <para> - Update batching is enabled by setting <literal>hibernate.adonet.batch_size</literal> + Update batching is enabled by setting <literal>adonet.batch_size</literal> to a non-zero value. </para> </sect1> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2010-11-25 16:59:18
|
Revision: 5272 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5272&view=rev Author: fabiomaulo Date: 2010-11-25 16:59:12 +0000 (Thu, 25 Nov 2010) Log Message: ----------- Fixed doc preface Modified Paths: -------------- trunk/nhibernate/doc/reference/modules/preface.xml Modified: trunk/nhibernate/doc/reference/modules/preface.xml =================================================================== --- trunk/nhibernate/doc/reference/modules/preface.xml 2010-11-25 16:45:58 UTC (rev 5271) +++ trunk/nhibernate/doc/reference/modules/preface.xml 2010-11-25 16:59:12 UTC (rev 5272) @@ -48,41 +48,38 @@ <para> Use this reference documentation as your primary source of information. Consider reading <emphasis>Hibernate in Action</emphasis> - (<ulink url="http://www.manning.com/bauer/" />) - or the work-in-progress <emphasis>NHibernate in Action</emphasis> - (<ulink url="http://www.manning.com/kuate/" />) if you need more help - with application design or if you prefer a step-by-step tutorial. Also visit - <ulink url="http://nhibernate.sourceforge.net/NHibernateEg/" /> for NHibernate + (java <ulink url="http://www.manning.com/bauer/" />) + or <emphasis>NHibernate in Action</emphasis> + (<ulink url="http://www.manning.com/kuate/" />) + or <emphasis>NHibernate 3.0 Cookbook</emphasis> + (<ulink url="https://www.packtpub.com/nhibernate-3-0-cookbook/book" />) + or <emphasis>NHibernate 2 Beginner's Guide</emphasis> + (<ulink url="http://www.packtpub.com/nhibernate-2-x-beginners-guide/book" />)if you need more help + with application design or if you prefer a step-by-step tutorial. Also visit + <ulink url="http://nhibernate.sourceforge.net/NHibernateEg/" /> for NHibernate tutorial with examples. </para> </listitem> - <listitem> + <listitem> + <para> + FAQs are answered on the <ulink url="http://groups.google.com/group/nhusers">NHibernate users group</ulink>. + </para> + </listitem> + <listitem> <para> - FAQs are answered on the <ulink url="http://www.nhibernate.org/">NHibernate website</ulink>. + The Community Area on the <ulink url="http://www.nhforge.org/">NHibernate website</ulink> is a good source for + design patterns and various integration solutions (ASP.NET, Windows Forms). </para> </listitem> - <listitem> - <para> - Third party demos, examples and tutorials are linked on the - <ulink url="http://www.hibernate.org/365.html">NHibernate Resources page</ulink>. - </para> - </listitem> - <listitem> - <para> - The Community Area on the NHibernate website is a good source for - design patterns and various integration solutions (ASP.NET, Windows - Forms). - </para> - </listitem> </orderedlist> <para> If you have questions, use the - <ulink url="http://forum.hibernate.org/viewforum.php?f=25">NHibernate user forum</ulink>. - We also provide a <ulink url="http://jira.nhibernate.org/">JIRA issue trackings system</ulink> + <ulink url="http://groups.google.com/group/nhusers">NHibernate user forum</ulink>. + We also provide a <ulink url="http://jira.nhforge.org/">JIRA issue trackings system</ulink> for bug reports and feature requests. If you are interested in the development of NHibernate, join the developer mailing list. If you are interested in translating this documentation into your language, contact us - on the <ulink url="http://sourceforge.net/mail/?group_id=29446">developer mailing list</ulink>. + on the <ulink url="http://groups.google.com/group/nhibernate-development">developer mailing list</ulink>. </para> </preface> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2010-11-25 16:46:04
|
Revision: 5271 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5271&view=rev Author: fabiomaulo Date: 2010-11-25 16:45:58 +0000 (Thu, 25 Nov 2010) Log Message: ----------- Cleaned some reference to NH specific version Modified Paths: -------------- trunk/nhibernate/doc/reference/modules/architecture.xml trunk/nhibernate/doc/reference/modules/filters.xml trunk/nhibernate/doc/reference/modules/nhibernate_mapping_attributes.xml trunk/nhibernate/doc/reference/modules/performance.xml trunk/nhibernate/doc/reference/modules/query_sql.xml trunk/nhibernate/doc/reference/modules/transactions.xml Modified: trunk/nhibernate/doc/reference/modules/architecture.xml =================================================================== --- trunk/nhibernate/doc/reference/modules/architecture.xml 2010-11-25 16:35:51 UTC (rev 5270) +++ trunk/nhibernate/doc/reference/modules/architecture.xml 2010-11-25 16:45:58 UTC (rev 5271) @@ -234,7 +234,7 @@ See the API documentation for the <literal>NHibernate.Context.ICurrentSessionContext</literal> interface for a detailed discussion of its contract. It defines a single method, <literal>CurrentSession()</literal>, by which the implementation is responsible for - tracking the current contextual session. Out-of-the-box, NHibernate 1.2.1 comes with several + tracking the current contextual session. Out-of-the-box, NHibernate comes with several implementations of this interface: </para> Modified: trunk/nhibernate/doc/reference/modules/filters.xml =================================================================== --- trunk/nhibernate/doc/reference/modules/filters.xml 2010-11-25 16:35:51 UTC (rev 5270) +++ trunk/nhibernate/doc/reference/modules/filters.xml 2010-11-25 16:45:58 UTC (rev 5271) @@ -2,7 +2,7 @@ <title>Filtering data</title> <para> - NHibernate 1.2 provides an innovative new approach to handling data with "visibility" rules. + NHibernate provides an innovative new approach to handling data with "visibility" rules. A <emphasis>NHibernate filter</emphasis> is a global, named, parameterized filter that may be enabled or disabled for a particular NHibernate session. </para> @@ -11,7 +11,7 @@ <title>NHibernate filters</title> <para> - NHibernate 1.2 adds the ability to pre-define filter criteria and attach those filters at both + NHibernate adds the ability to pre-define filter criteria and attach those filters at both a class and a collection level. A filter criteria is the ability to define a restriction clause very similiar to the existing "where" attribute available on the class and various collection elements. Except these filter conditions can be parameterized. The application can then make Modified: trunk/nhibernate/doc/reference/modules/nhibernate_mapping_attributes.xml =================================================================== --- trunk/nhibernate/doc/reference/modules/nhibernate_mapping_attributes.xml 2010-11-25 16:35:51 UTC (rev 5270) +++ trunk/nhibernate/doc/reference/modules/nhibernate_mapping_attributes.xml 2010-11-25 16:45:58 UTC (rev 5271) @@ -52,7 +52,7 @@ <section id="mapping-attributes-new"> <title>What's new?</title> <formalpara> - <title>NHibernate 1.2.0</title> + <title>NHibernate</title> <para>introduces many new features, improvements and changes:</para> </formalpara> <orderedlist> Modified: trunk/nhibernate/doc/reference/modules/performance.xml =================================================================== --- trunk/nhibernate/doc/reference/modules/performance.xml 2010-11-25 16:35:51 UTC (rev 5270) +++ trunk/nhibernate/doc/reference/modules/performance.xml 2010-11-25 16:45:58 UTC (rev 5271) @@ -12,7 +12,7 @@ </para> <para> - NHibernate 1.2 defines the following fetching strategies: + NHibernate defines the following fetching strategies: </para> <itemizedlist> @@ -128,7 +128,7 @@ <title>Working with lazy associations</title> <para> - By default, NHibernate 1.2 uses lazy select fetching for collections and lazy proxy + By default, NHibernate uses lazy select fetching for collections and lazy proxy fetching for single-valued associations. These defaults make sense for almost all associations in almost all applications. </para> @@ -181,7 +181,7 @@ <para> On the other hand, we often want to choose join fetching (which is non-lazy by nature) instead of select fetching in a particular transaction. We'll now see - how to customize the fetching strategy. In NHibernate 1.2, the mechanisms for + how to customize the fetching strategy. In NHibernate, the mechanisms for choosing a fetch strategy are identical for single-valued associations and collections. </para> @@ -280,7 +280,7 @@ </para> <para> - By default, NHibernate 1.2 generates proxies (at startup) for all persistent classes + By default, NHibernate generates proxies (at startup) for all persistent classes and uses them to enable lazy fetching of <literal>many-to-one</literal> and <literal>one-to-one</literal> associations. </para> @@ -1160,7 +1160,7 @@ <title>Batch updates</title> <para> - NHibernate 1.2 supports batching SQL update commands (<literal>INSERT</literal>, + NHibernate supports batching SQL update commands (<literal>INSERT</literal>, <literal>UPDATE</literal>, <literal>DELETE</literal>) with the following limitations: </para> Modified: trunk/nhibernate/doc/reference/modules/query_sql.xml =================================================================== --- trunk/nhibernate/doc/reference/modules/query_sql.xml 2010-11-25 16:35:51 UTC (rev 5270) +++ trunk/nhibernate/doc/reference/modules/query_sql.xml 2010-11-25 16:45:58 UTC (rev 5271) @@ -7,7 +7,7 @@ also provides a clean migration path from a direct SQL/ADO.NET based application to NHibernate.</para> - <para>NHibernate 1.2 allows you to specify handwritten SQL (including stored + <para>NHibernate allows you to specify handwritten SQL (including stored procedures) for all create, update, delete, and load operations.</para> <sect1 id="querysql-creating" revision="4"> @@ -505,7 +505,7 @@ <sect2 id="sp_query" revision="1"> <title>Using stored procedures for querying</title> - <para>NHibernate 1.2 introduces support for queries via stored procedures + <para>NHibernate introduces support for queries via stored procedures and functions. Most of the following documentation is equivalent for both. The stored procedure/function must return a resultset to be able to work with NHibernate. An example of such a stored function in MS SQL Server 2000 and @@ -593,7 +593,7 @@ <sect1 id="querysql-cud"> <title>Custom SQL for create, update and delete</title> - <para>NHibernate 1.2 can use custom SQL statements for create, update, and + <para>NHibernate can use custom SQL statements for create, update, and delete operations. The class and collection persisters in NHibernate already contain a set of configuration time generated strings (insertsql, deletesql, updatesql etc.). The mapping tags Modified: trunk/nhibernate/doc/reference/modules/transactions.xml =================================================================== --- trunk/nhibernate/doc/reference/modules/transactions.xml 2010-11-25 16:35:51 UTC (rev 5270) +++ trunk/nhibernate/doc/reference/modules/transactions.xml 2010-11-25 16:45:58 UTC (rev 5271) @@ -516,7 +516,7 @@ The legacy (1.0.x) behavior of NHibernate in regards to ADO.NET connection management was that a <literal>ISession</literal> would obtain a connection when it was first needed and then hold unto that connection until the session was closed. - NHibernate 1.2 introduced the notion of connection release modes to tell a session + NHibernate introduced the notion of connection release modes to tell a session how to handle its ADO.NET connections. Note that the following discussion is pertinent only to connections provided through a configured <literal>IConnectionProvider</literal>; user-supplied connections are outside the breadth of this discussion. The different @@ -569,7 +569,7 @@ </itemizedlist> <para> - As of NHibernate 1.2.0, if your application manages transactions through .NET APIs such as <literal> + As of NHibernate, if your application manages transactions through .NET APIs such as <literal> System.Transactions</literal> library, <literal>ConnectionReleaseMode.AfterTransaction</literal> may cause NHibernate to open and close several connections during one transaction, leading to unnecessary overhead and transaction promotion from local to distributed. Specifying <literal>ConnectionReleaseMode.OnClose</literal> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2010-11-25 16:35:58
|
Revision: 5270 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5270&view=rev Author: fabiomaulo Date: 2010-11-25 16:35:51 +0000 (Thu, 25 Nov 2010) Log Message: ----------- Removed obsolete doc Modified Paths: -------------- trunk/nhibernate/doc/reference/master.xml trunk/nhibernate/doc/reference/modules/basic_mapping.xml trunk/nhibernate/doc/reference/modules/query_hql.xml trunk/nhibernate/doc/reference/modules/toolset_guide.xml Modified: trunk/nhibernate/doc/reference/master.xml =================================================================== --- trunk/nhibernate/doc/reference/master.xml 2010-11-25 03:34:05 UTC (rev 5269) +++ trunk/nhibernate/doc/reference/master.xml 2010-11-25 16:35:51 UTC (rev 5270) @@ -38,7 +38,7 @@ <bookinfo> <title>NHibernate - Relational Persistence for Idiomatic .NET</title> <subtitle>NHibernate Reference Documentation</subtitle> - <releaseinfo>2.1.0</releaseinfo> + <releaseinfo>3.0.0</releaseinfo> </bookinfo> <toc /> Modified: trunk/nhibernate/doc/reference/modules/basic_mapping.xml =================================================================== --- trunk/nhibernate/doc/reference/modules/basic_mapping.xml 2010-11-25 03:34:05 UTC (rev 5269) +++ trunk/nhibernate/doc/reference/modules/basic_mapping.xml 2010-11-25 16:35:51 UTC (rev 5270) @@ -2201,7 +2201,7 @@ <para> An <emphasis>entity</emphasis> exists independently of any other objects holding - references to the entity. Contrast this with the usual Java model where an + references to the entity. Contrast this with the usual .NET model where an unreferenced object is garbage collected. Entities must be explicitly saved and deleted (except that saves and deletions may be <emphasis>cascaded</emphasis> from a parent entity to its children). This is different from the ODMG model of Modified: trunk/nhibernate/doc/reference/modules/query_hql.xml =================================================================== --- trunk/nhibernate/doc/reference/modules/query_hql.xml 2010-11-25 03:34:05 UTC (rev 5269) +++ trunk/nhibernate/doc/reference/modules/query_hql.xml 2010-11-25 16:35:51 UTC (rev 5270) @@ -23,7 +23,7 @@ <para> This manual uses lowercase HQL keywords. Some users find queries with uppercase keywords - more readable, but we find this convention ugly when embedded in Java code. + more readable, but we find this convention ugly when embedded in C# code. </para> </sect1> @@ -381,7 +381,7 @@ <para> Likewise, the special property <literal>class</literal> accesses the discriminator value - of an instance in the case of polymorphic persistence. A Java class name embedded in the + of an instance in the case of polymorphic persistence. A .Net class name embedded in the where clause will be translated to its discriminator value. </para> Modified: trunk/nhibernate/doc/reference/modules/toolset_guide.xml =================================================================== --- trunk/nhibernate/doc/reference/modules/toolset_guide.xml 2010-11-25 03:34:05 UTC (rev 5269) +++ trunk/nhibernate/doc/reference/modules/toolset_guide.xml 2010-11-25 16:35:51 UTC (rev 5270) @@ -215,64 +215,11 @@ </para> <para> - <literal>java -cp </literal><emphasis>hibernate_classpaths</emphasis> - <literal>net.sf.hibernate.tool.hbm2ddl.SchemaExport</literal> <emphasis>options mapping_files</emphasis> + You may embed <literal>SchemaExport</literal> in your application: </para> - <table frame="topbot"> - <title><literal>SchemaExport</literal> Command Line Options</title> - <tgroup cols="2"> - <colspec colwidth="1.5*"/> - <colspec colwidth="2*"/> - <thead> - <row> - <entry>Option</entry> - <entry>Description</entry> - </row> - </thead> - <tbody> - <row> - <entry><literal>--quiet</literal></entry> - <entry>don't output the script to stdout</entry> - </row> - <row> - <entry><literal>--drop</literal></entry> - <entry>only drop the tables</entry> - </row> - <row> - <entry><literal>--text</literal></entry> - <entry>don't export to the database</entry> - </row> - <row> - <entry><literal>--output=my_schema.ddl</literal></entry> - <entry>output the ddl script to a file</entry> - </row> - <row> - <entry><literal>--config=hibernate.cfg.xml</literal></entry> - <entry>read Hibernate configuration from an XML file</entry> - </row> - <row> - <entry><literal>--properties=hibernate.properties</literal></entry> - <entry>read database properties from a file</entry> - </row> - <row> - <entry><literal>--format</literal></entry> - <entry>format the generated SQL nicely in the script</entry> - </row> - <row> - <entry><literal>--delimiter=x</literal></entry> - <entry>set an end of line delimiter for the script</entry> - </row> - </tbody> - </tgroup> - </table> - - <para> - You may even embed <literal>SchemaExport</literal> in your application: - </para> - <programlisting><![CDATA[Configuration cfg = ....; -new SchemaExport(cfg).create(false, true);]]></programlisting> +new SchemaExport(cfg).Create(false, true);]]></programlisting> </sect2> @@ -377,20 +324,19 @@ <title>Code Generation</title> <para> - The Hibernate code generator may be used to generate skeletal Java implementation classes - from a Hibernate mapping file. This tool is included in the Hibernate Extensions package - (a seperate download). + The NHibernate code generator may be used to generate skeletal C# implementation classes + from a NHibernate mapping file. This tool is included in the NHibernate Contrib package + (a seperate download in http://sourceforge.net/projects/nhcontrib/). </para> <para> - <literal>hbm2java</literal> parses the mapping files and generates fully working Java - source files from these. Thus with <literal>hbm2java</literal> one could "just" provide the - <literal>.hbm</literal> files, and then don't worry about hand-writing/coding the Java files. + <literal>hbm2net</literal> parses the mapping files and generates fully working C# + source files from these. Thus with <literal>hbm2net</literal> one could "just" provide the + <literal>.hbm</literal> files, and then don't worry about hand-writing/coding the C# files. </para> <para> - <literal>java -cp</literal> <emphasis>hibernate_classpaths</emphasis> - <literal>net.sf.hibernate.tool.hbm2java.CodeGenerator</literal> <emphasis> options + <literal>hbm2net</literal> <emphasis> options mapping_files</emphasis> </para> @@ -407,616 +353,22 @@ </thead> <tbody> <row> - <entry><literal>--output=</literal><emphasis>output_dir</emphasis></entry> + <entry><literal>-output:</literal><emphasis>output_dir</emphasis></entry> <entry>root directory for generated code</entry> </row> <row> - <entry><literal>--config=</literal><emphasis>config_file</emphasis></entry> - <entry>optional file for configuring hbm2java</entry> + <entry><literal>-config:</literal><emphasis>config_file</emphasis></entry> + <entry>optional file for configuring hbm2net</entry> </row> </tbody> </tgroup> </table> - - <sect2 id="toolsetguide-s2-1" revision="4"> - <title>The config file (optional)</title> - - <para> - The config file provides for a way to specify multiple "renderers" for the source code - and to declare <literal><meta></literal> attributes that is "global" in scope. See - more about this in the <literal><meta></literal> attribute section. - </para> - - <programlisting><![CDATA[<codegen> - <meta attribute="implements">codegen.test.IAuditable</meta> - <generate renderer="net.sf.hibernate.tool.hbm2java.BasicRenderer"/> - <generate - package="autofinders.only" - suffix="Finder" - renderer="net.sf.hibernate.tool.hbm2java.FinderRenderer"/> -</codegen>]]></programlisting> - - <para> - This config file declares a global meta attribute "implements" and specify two renderers, the - default one (BasicRenderer) and a renderer that generates Finder's (See more in "Basic Finder - generation" below). - </para> - - <para> - The second renderer is provided with a package and suffix attribute. - </para> - - <para> - The package attribute specifies that the generated source files from this renderer should be - placed here instead of the package scope specified in the <literal>.hbm</literal> files. - </para> - - <para> - The suffix attribute specifies the suffix for generated files. E.g. here a file named - <literal>Foo.java</literal> would be <literal>FooFinder.java</literal> instead. - </para> - - <para> - It is also possible to send down arbitrary parameters to the renders by adding <literal><param></literal> attributes - to the <literal><generate></literal> elements. - </para> - - <para> - hbm2java currently has support for one such parameter, - namely - <literal>generate-concrete-empty-classes</literal> which - informs the BasicRenderer to only generate empty - concrete classes that extends a base class for all your - classes. The following config.xml example illustrate - this feature - </para> - - <programlisting><![CDATA[ - <codegen> - <generate prefix="Base" renderer="net.sf.hibernate.tool.hbm2java.BasicRenderer"/> - <generate renderer="net.sf.hibernate.tool.hbm2java.BasicRenderer"> - <param name="generate-concrete-empty-classes">true</param> - <param name="baseclass-prefix">Base</param> - </generate> - </codegen>]]></programlisting> - - <para> - Notice that this config.xml configure 2 (two) - renderers. One that generates the Base classes, and a - second one that just generates empty concrete classes. - </para> - </sect2> - - <sect2 id="toolsetguide-s2-2"> - <title>The <literal>meta</literal> attribute</title> - - <para> - The <literal><meta></literal> tag is a simple way of annotating the <literal>hbm.xml</literal> - with information, so tools have a natural place to store/read information that is not directly related - to the Hibernate core. - </para> - - <para> - You can use the <literal><meta></literal> tag to tell <literal>hbm2java</literal> to only - generate "protected" setters, have classes always implement a certain set of interfaces or - even have them extend a certain base class and even more. - </para> - - <para> - The following example: - </para> - - <programlisting><![CDATA[<class name="Person"> - <meta attribute="class-description"> - Javadoc for the Person class - @author Frodo - </meta> - <meta attribute="implements">IAuditable</meta> - <id name="id" type="long"> - <meta attribute="scope-set">protected</meta> - <generator class="increment"/> - </id> - <property name="name" type="string"> - <meta attribute="field-description">The name of the person</meta> - </property> -</class>]]></programlisting> - - <para> - will produce something like the following (code shortened for better understanding). Notice the - Javadoc comment and the protected set methods: - </para> - - <programlisting><![CDATA[// default package - -import java.io.Serializable; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; -import org.apache.commons.lang.builder.ToStringBuilder; - -/** - * Javadoc for the Person class - * @author Frodo - * - */ -public class Person implements Serializable, IAuditable { - - /** identifier field */ - public Long id; - - /** nullable persistent field */ - public String name; - - /** full constructor */ - public Person(java.lang.String name) { - this.name = name; - } - - /** default constructor */ - public Person() { - } - - public java.lang.Long getId() { - return this.id; - } - - protected void setId(java.lang.Long id) { - this.id = id; - } - - /** - * The name of the person - */ - public java.lang.String getName() { - return this.name; - } - - public void setName(java.lang.String name) { - this.name = name; - } - -}]]></programlisting> - - <table frame="topbot"> - <title>Supported meta tags</title> - <tgroup cols="2"> - <colspec colwidth="1.5*"/> - <colspec colwidth="2*"/> - <thead> - <row> - <entry>Attribute</entry> - <entry>Description</entry> - </row> - </thead> - <tbody> - <row> - <entry><literal>class-description</literal></entry> - <entry>inserted into the javadoc for classes</entry> - </row> - <row> - <entry><literal>field-description</literal></entry> - <entry>inserted into the javadoc for fields/properties</entry> - </row> - <row> - <entry><literal>interface</literal></entry> - <entry>If true an interface is generated instead of an class.</entry> - </row> - <row> - <entry><literal>implements</literal></entry> - <entry>interface the class should implement</entry> - </row> - <row> - <entry><literal>extends</literal></entry> - <entry>class the class should extend (ignored for subclasses)</entry> - </row> - <row> - <entry><literal>generated-class</literal></entry> - <entry>overrule the name of the actual class generated</entry> - </row> - <row> - <entry><literal>scope-class</literal></entry> - <entry>scope for class </entry> - </row> - <row> - <entry><literal>scope-set</literal></entry> - <entry>scope for setter method</entry> - </row> - <row> - <entry><literal>scope-get</literal></entry> - <entry>scope for getter method</entry> - </row> - <row> - <entry><literal>scope-field</literal></entry> - <entry>scope for actual field</entry> - </row> - <row> - <entry><literal>use-in-tostring</literal></entry> - <entry>include this property in the <literal>toString()</literal></entry> - </row> - <row> - <entry><literal>implement-equals</literal></entry> - <entry>include a <literal>equals()</literal> and <literal>hashCode()</literal> method in this class.</entry> - </row> - <row> - <entry><literal>use-in-equals</literal></entry> - <entry>include this property in the <literal>equals()</literal> and <literal>hashCode()</literal> method.</entry> - </row> - <row> - <entry><literal>bound</literal></entry> - <entry>add propertyChangeListener support for a property</entry> - </row> - <row> - <entry><literal>constrained</literal></entry> - <entry>bound + vetoChangeListener support for a property</entry> - </row> - <row> - <entry><literal>gen-property</literal></entry> - <entry>property will not be generated if false (use with care)</entry> - </row> - <row> - <entry><literal>property-type</literal></entry> - <entry>Overrides the default type of property. Use this with any tag's to specify the concrete type instead of just Object.</entry> - </row> - <row> - <entry><literal>class-code</literal></entry> - <entry>Extra code that will inserted at the end of the class</entry> - </row> - <row> - <entry><literal>extra-import</literal></entry> - <entry>Extra import that will inserted at the end of all other imports</entry> - </row> - <row> - <entry><literal>finder-method</literal></entry> - <entry>see "Basic finder generator" below</entry> - </row> - <row> - <entry><literal>session-method</literal></entry> - <entry>see "Basic finder generator" below</entry> - </row> - </tbody> - </tgroup> - </table> - - <para> - Attributes declared via the <literal><meta></literal> tag are per default - "inherited" inside an <literal>hbm.xml</literal> file. - </para> - - <para> - What does that mean? It means that if you e.g want to have all your classes - implement <literal>IAuditable</literal> then you just add an - <literal><meta attribute="implements">IAuditable</meta></literal> in the top of - the <literal>hbm.xml</literal> file, just after - <literal><hibernate-mapping></literal>. Now all classes defined in that - <literal>hbm.xml</literal> file will implement <literal>IAuditable</literal>! - (Except if a class also has an "implements" meta attribute, because local specified - meta tags always overrules/replaces any inherited meta tags). - </para> - - <para> - Note: This applies to <emphasis>all</emphasis> <literal><meta></literal>-tags. - Thus it can also e.g. be used to specify that all fields should be declare protected, - instead of the default private. This is done by adding <literal><meta - attribute="scope-field">protected</meta></literal> at e.g. just under the - <literal><class></literal> tag and all fields of that class will be protected. - </para> - - <para> - To avoid having a <literal><meta></literal>-tag inherited then you can simply - specify <literal>inherit="false"</literal> for the attribute, e.g. - <literal><meta attribute="scope-class" inherit="false">public abstract</meta></literal> - will restrict the "class-scope" to the current class, not the subclasses. - </para> - - </sect2> - - <sect2 id="toolsetguide-s2-3"> - <title>Basic finder generator</title> - - <para> - It is now possible to have <literal>hbm2java</literal> generate basic finders for - Hibernate properties. This requires two things in the <literal>hbm.xml</literal> - files. - </para> - - <para> - The first is an indication of which fields you want to generate finders for. You indicate - that with a meta block inside a property tag such as: - </para> - - <programlisting><![CDATA[<property name="name" column="name" type="string"> - <meta attribute="finder-method">findByName</meta> -</property>]]></programlisting> - - <para> - The finder method name will be the text enclosed in the meta tags. - </para> - - <para> - The second is to create a config file for hbm2java of the format: - </para> - - <programlisting><![CDATA[<codegen> - <generate renderer="net.sf.hibernate.tool.hbm2java.BasicRenderer"/> - <generate suffix="Finder" renderer="net.sf.hibernate.tool.hbm2java.FinderRenderer"/> -</codegen>]]></programlisting> - - <para> - And then use the param to <literal>hbm2java --config=xxx.xml</literal> where - <literal>xxx.xml</literal> is the config file you just created. - </para> - - <para> - An optional parameter is meta tag at the class level of the format: - </para> - - <programlisting><![CDATA[<meta attribute="session-method"> - com.whatever.SessionTable.getSessionTable().getSession(); -</meta>]]></programlisting> - - <para> - Which would be the way in which you get sessions if you use the - <emphasis>Thread Local Session</emphasis> pattern (documented in the Design Patterns - area of the Hibernate website). - </para> - - </sect2> - - <sect2 id="toolsetguide-s2-4"> - <title>Velocity based renderer/generator</title> - - <para>It is now possible to use velocity as an alternative rendering mechanism. - The follwing config.xml shows how to configure hbm2java to use its velocity renderer. - </para> - - <programlisting><![CDATA[ - <codegen> - <generate renderer="net.sf.hibernate.tool.hbm2java.VelocityRenderer"> - <param name="template">pojo.vm</param> - </generate> - </codegen>]]></programlisting> - <para> - The parameter named <literal>template</literal> is a resource path to the velocity macro file you want to use. - This file must be available via the classpath for hbm2java. Thus remember to add the directory where pojo.vm - is located to your ant task or shell script. (The default location is <literal>./tools/src/velocity</literal>) + A more detailed guide of <literal>hbm2net</literal> is available in + http://nhforge.org/blogs/nhibernate/archive/2009/12/12/t4-hbm2net-alpha-2.aspx </para> - - <para> - Be aware that the current <literal>pojo.vm</literal> generates only the most basic parts of the java beans. - It is not as complete and feature rich as the default renderer - primarily a lot of the <literal>meta</literal> tags - are not supported. - </para> - </sect2> - - </sect1> - - <sect1 id="toolsetguide-s3"> - <title>Mapping File Generation</title> - <para> - A skeletal mapping file may be generated from compiled persistent classes using - a command line utility called <literal>MapGenerator</literal>. This utility is part of - the Hibernate Extensions package. - </para> - - <para> - The Hibernate mapping generator provides a mechanism to produce mappings from - compiled classes. It uses Java reflection to find <emphasis>properties</emphasis> - and uses heuristics to guess an appropriate mapping from the property type. - The generated mapping is intended to be a starting point only. There is no way to produce - a full Hibernate mapping without extra input from the user. However, the tool does - take away some of the repetitive "grunt" work involved in producing a mapping. - </para> - - <para> - Classes are added to the mapping one at a time. The tool will reject - classes that it judges are are not <emphasis>Hibernate persistable</emphasis>. - </para> - - <para> - To be <emphasis>Hibernate persistable</emphasis> a class - </para> - - <itemizedlist spacing="compact"> - <listitem> - <para>must not be a primitive type</para> - </listitem> - <listitem> - <para>must not be an array</para> - </listitem> - <listitem> - <para>must not be an interface</para> - </listitem> - <listitem> - <para>must not be a nested class</para> - </listitem> - <listitem> - <para>must have a default (zero argument) constructor.</para> - </listitem> - </itemizedlist> - - <para> - Note that interfaces and nested classes actually are persistable by Hibernate, but - this would not usually be intended by the user. - </para> - - <para> - <literal>MapGenerator</literal> will climb the superclass chain of all added classes attempting - to add as many Hibernate persistable superclasses as possible to the same database table. - The search stops as soon as a property is found that has a name appearing on a list of - <emphasis>candidate UID names</emphasis>. - </para> - - <para> - The default list of candidate UID property names is: <literal>uid</literal>, <literal>UID</literal>, - <literal>id</literal>, <literal>ID</literal>, <literal>key</literal>, <literal>KEY</literal>, - <literal>pk</literal>, <literal>PK</literal>. - </para> - - <para> - Properties are discovered when there are two methods in the class, a setter and a getter, where the - type of the setter's single argument is the same as the return type of the zero argument getter, - and the setter returns <literal>void</literal>. Furthermore, the setter's name must start with the - string <literal>set</literal> and either the getter's name starts with <literal>get</literal> or - the getter's name starts with <literal>is</literal> and the type of the property is boolean. In - either case, the remainder of their names must match. This matching portion is the name of - the property, except that the initial character of the property name is made lower case if - the second letter is lower case. - </para> - - <para> - The rules for determining the database type of each property are as follows: - </para> - - <orderedlist spacing="compact"> - <listitem> - <para> - If the Java type is <literal>Hibernate.basic()</literal>, then the property is a - simple column of that type. - </para> - </listitem> - <listitem> - <para> - For <literal>hibernate.type.Type</literal> custom types and <literal>PersistentEnum</literal> - a simple column is used as well. - </para> - </listitem> - <listitem> - <para> - If the property type is an array, then a Hibernate array is used, and <literal>MapGenerator</literal> - attempts to reflect on the array element type. - </para> - </listitem> - <listitem> - <para> - If the property has type <literal>java.util.List</literal>, <literal>java.util.Map</literal>, or - <literal>java.util.Set</literal>, then the corresponding Hibernate types are used, but - <literal>MapGenerator</literal> cannot further process the insides of these types. - </para> - </listitem> - <listitem> - <para> - If the property's type is any other class, <literal>MapGenerator</literal> defers the decision - on the database representation until all classes have been processed. At this point, if the - class was discovered through the superclass search described above, then the property is - an <literal>many-to-one</literal> association. If the class has any properties, then it is - a <literal>component</literal>. Otherwise it is serializable, or not persistable. - </para> - </listitem> - </orderedlist> - - <sect2 id="toolsetguide-s3-1"> - <title>Running the tool</title> - - <para> - The tool writes XML mappings to standard out and/or to a file. - </para> - - <para> - When invoking the tool you must place your compiled classes on the classpath. - </para> - - <para> - <literal>java -cp </literal><emphasis>hibernate_and_your_class_classpaths</emphasis> - <literal>net.sf.hibernate.tool.class2hbm.MapGenerator</literal> <emphasis>options and - classnames</emphasis> - </para> - - <para> - There are two modes of operation: command line or interactive. - </para> - - <para> - The interactive mode is selected by providing the single command line argument - <literal>--interact</literal>. This mode provides a prompt response console. Using it you - can set the UID property name for each class using the <literal>uid=XXX</literal> command - where <literal>XXX</literal> is the UID property name. Other command alternatives are simply - a fully qualified class name, or the command done which emits the XML and terminates. - </para> - - <para> - In command line mode the arguments are the options below interspersed with fully qualified - class names of the classes to be processed. Most of the options are meant to be used - multiple times; each use affects subsequently added classes. - </para> - - <table frame="topbot"> - <title>MapGenerator Command Line Options</title> - <tgroup cols="2"> - <colspec colwidth="1*"/> - <colspec colwidth="2*"/> - <thead> - <row> - <entry>Option</entry> - <entry>Description</entry> - </row> - </thead> - <tbody> - <row> - <entry><literal>--quiet</literal></entry> - <entry>don't output the O-R Mapping to stdout</entry> - </row> - <row> - <entry><literal>--setUID=uid</literal></entry> - <entry>set the list of candidate UIDs to the singleton uid</entry> - </row> - <row> - <entry><literal>--addUID=uid</literal></entry> - <entry>add uid to the front of the list of candidate UIDs</entry> - </row> - <row> - <entry><literal>--select=</literal><emphasis>mode</emphasis></entry> - <entry>mode use select mode <emphasis>mode</emphasis>(e.g., - <emphasis>distinct</emphasis> or <emphasis>all</emphasis>) for subsequently - added classes</entry> - </row> - <row> - <entry><literal>--depth=<small-int></literal></entry> - <entry>limit the depth of component data recursion for subsequently added classes</entry> - </row> - <row> - <entry><literal>--output=my_mapping.xml</literal></entry> - <entry>output the O-R Mapping to a file</entry> - </row> - <row> - <entry><emphasis>full.class.Name</emphasis></entry> - <entry>add the class to the mapping</entry> - </row> - <row> - <entry><literal>--abstract=</literal><emphasis>full.class.Name</emphasis></entry> - <entry>see below</entry> - </row> - </tbody> - </tgroup> - </table> - - <para> - The abstract switch directs the map generator tool to ignore specific super classes so - that classes with common inheritance are not mapped to one large table. For instance, - consider these class hierarchies: - </para> - - <para> - <literal>Animal-->Mammal-->Human</literal> - </para> - <para> - <literal>Animal-->Mammal-->Marsupial-->Kangaroo</literal> - </para> - - <para> - If the <literal>--abstract</literal>switch is <emphasis>not</emphasis> used, all classes will - be mapped as subclasses of <literal>Animal</literal>, resulting in one large table containing - all the properties of all the classes plus a discriminator column to indicate which subclass is - actually stored. If <literal>Mammal</literal> is marked as <literal>abstract</literal>, - <literal>Human</literal> and <literal>Marsupial</literal> will be mapped to - separate <literal><class></literal> declarations and stored in separate tables. - <literal>Kangaroo</literal> will still be a subclass of <literal>Marsupial</literal> - unless <literal>Marsupial</literal> is also marked as <literal>abstract</literal>. - </para> - - </sect2> - </sect1> </chapter> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pa...@us...> - 2010-11-25 03:34:12
|
Revision: 5269 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5269&view=rev Author: patearl Date: 2010-11-25 03:34:05 +0000 (Thu, 25 Nov 2010) Log Message: ----------- Utilize simple SQL equality in expressions that may involve null values. (NH-2402) Fixed missing cases in Linq null (in)equality handling. Fixed Linq query caching when the same variable alternates between null and non-null values. (part of NH-2397) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionKeyVisitor.cs trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs trunk/nhibernate/src/NHibernate.Test/DbScripts/MsSql2008DialectLinqReadonlyCreateScript.sql trunk/nhibernate/src/NHibernate.Test/Linq/Entities/AnotherEntity.cs trunk/nhibernate/src/NHibernate.Test/Linq/Mappings/AnotherEntity.hbm.xml trunk/nhibernate/src/NHibernate.Test/Linq/NorthwindDbCreator.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionKeyVisitor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionKeyVisitor.cs 2010-11-21 17:36:14 UTC (rev 5268) +++ trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionKeyVisitor.cs 2010-11-25 03:34:05 UTC (rev 5269) @@ -77,7 +77,11 @@ if (_constantToParameterMap.TryGetValue(expression, out param)) { - _string.Append(param.Name); + // Nulls generate different query plans. X = variable generates a different query depending on if variable is null or not. + if (param.Value == null) + _string.Append("NULL"); + else + _string.Append(param.Name); } else { Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs 2010-11-21 17:36:14 UTC (rev 5268) +++ trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs 2010-11-25 03:34:05 UTC (rev 5269) @@ -226,34 +226,22 @@ return _hqlTreeBuilder.Equality(lhs, rhs); } - // Also check for nullability - if (expression.Left.Type.IsNullableOrReference() || expression.Right.Type.IsNullableOrReference()) + // Check for nulls on left or right. + if (expression.Right is ConstantExpression + && expression.Right.Type.IsNullableOrReference() + && ((ConstantExpression)expression.Right).Value == null) { - // TODO - yuck. This clone is needed because the AST tree nodes are not immutable, - // and sharing nodes between multiple branches will cause issues in the hqlSqlWalker phase - - // a node, x, gets visited during the walk and updated to refer to a real property. Later in - // the walk, x get revisited (since we copied it here), but now the type doesn't match what - // the parser expects. So we can't share. Implementing Clone() on HqlTreeNode would be better - // that doing a full visit of the Expression tree. Allowing shared nodes in the AST would be better - // still, but might be more work - var lhs2 = VisitExpression(expression.Left).AsExpression(); - var rhs2 = VisitExpression(expression.Right).AsExpression(); - - if (expression.Right is ConstantExpression - && expression.Right.Type.IsNullableOrReference() - && ((ConstantExpression)expression.Right).Value == null) - { - return _hqlTreeBuilder.IsNull(lhs2); - } - - return _hqlTreeBuilder.BooleanOr( - _hqlTreeBuilder.BooleanAnd( - _hqlTreeBuilder.IsNull(lhs), - _hqlTreeBuilder.IsNull(rhs)), - _hqlTreeBuilder.Equality(lhs2, rhs2) - ); + return _hqlTreeBuilder.IsNull(lhs); } + if (expression.Left is ConstantExpression + && expression.Left.Type.IsNullableOrReference() + && ((ConstantExpression)expression.Left).Value == null) + { + return _hqlTreeBuilder.IsNull(rhs); + } + + // Nothing was null, use standard equality. return _hqlTreeBuilder.Equality(lhs, rhs); case ExpressionType.NotEqual: @@ -274,36 +262,24 @@ } - // Also check for nullability - if (expression.Left.Type.IsNullableOrReference() || expression.Right.Type.IsNullableOrReference()) + // Check for nulls on left or right. + if (expression.Right is ConstantExpression + && expression.Right.Type.IsNullableOrReference() + && ((ConstantExpression)expression.Right).Value == null) { - var lhs2 = VisitExpression(expression.Left).AsExpression(); - var rhs2 = VisitExpression(expression.Right).AsExpression(); - var lhs3 = VisitExpression(expression.Left).AsExpression(); - var rhs3 = VisitExpression(expression.Right).AsExpression(); - - if (expression.Right is ConstantExpression - && expression.Right.Type.IsNullableOrReference() - && ((ConstantExpression)expression.Right).Value == null) - { - return _hqlTreeBuilder.IsNotNull(lhs2); - } - - return - _hqlTreeBuilder.BooleanOr( - _hqlTreeBuilder.BooleanOr( - _hqlTreeBuilder.BooleanAnd( - _hqlTreeBuilder.IsNull(lhs), - _hqlTreeBuilder.IsNotNull(rhs)), - _hqlTreeBuilder.BooleanAnd( - _hqlTreeBuilder.IsNotNull(lhs2), - _hqlTreeBuilder.IsNull(rhs2)) - ), - _hqlTreeBuilder.Inequality(lhs3, rhs3)); + return _hqlTreeBuilder.IsNotNull(lhs); } - return _hqlTreeBuilder.Inequality(lhs, rhs); + if (expression.Left is ConstantExpression + && expression.Left.Type.IsNullableOrReference() + && ((ConstantExpression)expression.Left).Value == null) + { + return _hqlTreeBuilder.IsNotNull(rhs); + } + // Nothing was null, use standard inequality. + return _hqlTreeBuilder.Inequality(lhs, rhs); + case ExpressionType.And: return _hqlTreeBuilder.BitwiseAnd(lhs, rhs); Modified: trunk/nhibernate/src/NHibernate.Test/DbScripts/MsSql2008DialectLinqReadonlyCreateScript.sql =================================================================== (Binary files differ) Modified: trunk/nhibernate/src/NHibernate.Test/Linq/Entities/AnotherEntity.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/Entities/AnotherEntity.cs 2010-11-21 17:36:14 UTC (rev 5268) +++ trunk/nhibernate/src/NHibernate.Test/Linq/Entities/AnotherEntity.cs 2010-11-25 03:34:05 UTC (rev 5269) @@ -4,5 +4,6 @@ { public virtual int Id { get; set; } public virtual string Output { get; set; } + public virtual string Input { get; set; } } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/Linq/Mappings/AnotherEntity.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/Mappings/AnotherEntity.hbm.xml 2010-11-21 17:36:14 UTC (rev 5268) +++ trunk/nhibernate/src/NHibernate.Test/Linq/Mappings/AnotherEntity.hbm.xml 2010-11-25 03:34:05 UTC (rev 5269) @@ -5,5 +5,6 @@ <generator class="native" /> </id> <property name="Output" /> + <property name="Input" /> </class> </hibernate-mapping> Modified: trunk/nhibernate/src/NHibernate.Test/Linq/NorthwindDbCreator.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/NorthwindDbCreator.cs 2010-11-21 17:36:14 UTC (rev 5268) +++ trunk/nhibernate/src/NHibernate.Test/Linq/NorthwindDbCreator.cs 2010-11-25 03:34:05 UTC (rev 5269) @@ -20,7 +20,7 @@ IsActive = true, Entity = new AnotherEntity() { - Output = "this is output..." + Output = "output" } }, new Role() @@ -143,6 +143,16 @@ animals[1].Children = new[] { animals[5] }.ToList(); + List<AnotherEntity> otherEntities = new List<AnotherEntity>(); + // AnotherEntity with only Output set is created above. + otherEntities.Add(new AnotherEntity { Input = "input" }); + otherEntities.Add(new AnotherEntity { Input = "i/o", Output = "i/o" }); + otherEntities.Add(new AnotherEntity()); // Input and Output both null. + otherEntities.Add(new AnotherEntity { Input = "input", Output = "output" }); + + foreach (AnotherEntity otherEntity in otherEntities) + session.Save(otherEntity); + foreach (Role role in roles) session.Save(role); Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-11-21 17:36:14 UTC (rev 5268) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-11-25 03:34:05 UTC (rev 5269) @@ -448,6 +448,7 @@ <Compile Include="Linq\MethodCallTests.cs" /> <Compile Include="Linq\MiscellaneousTextFixture.cs" /> <Compile Include="Linq\NorthwindDbCreator.cs" /> + <Compile Include="Linq\NullComparisonTests.cs" /> <Compile Include="Linq\ObjectDumper.cs" /> <Compile Include="Linq\OrderByTests.cs" /> <Compile Include="Linq\PagingTests.cs" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jul...@us...> - 2010-11-21 17:36:20
|
Revision: 5268 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5268&view=rev Author: julian-maughan Date: 2010-11-21 17:36:14 +0000 (Sun, 21 Nov 2010) Log Message: ----------- Micro optimization in DefaultFlushEntityEventListener, by Andr?\195?\169s G. Aragoneses (ref. NH-2413) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Event/Default/DefaultFlushEntityEventListener.cs Modified: trunk/nhibernate/src/NHibernate/Event/Default/DefaultFlushEntityEventListener.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Event/Default/DefaultFlushEntityEventListener.cs 2010-11-21 17:14:48 UTC (rev 5267) +++ trunk/nhibernate/src/NHibernate/Event/Default/DefaultFlushEntityEventListener.cs 2010-11-21 17:36:14 UTC (rev 5268) @@ -10,15 +10,15 @@ namespace NHibernate.Event.Default { - /// <summary> - /// An event that occurs for each entity instance at flush time + /// <summary> + /// An event that occurs for each entity instance at flush time /// </summary> [Serializable] public class DefaultFlushEntityEventListener : IFlushEntityEventListener { private static readonly IInternalLogger log = LoggerProvider.LoggerFor(typeof(DefaultFlushEntityEventListener)); - /// <summary> + /// <summary> /// Flushes a single entity's state to the database, by scheduling an update action, if necessary /// </summary> public virtual void OnFlushEntity(FlushEntityEvent @event) @@ -106,11 +106,12 @@ if (persister.CanExtractIdOutOfEntity) { - object oid = persister.GetIdentifier(obj, entityMode); if (id == null) { throw new AssertionFailure("null id in " + persister.EntityName + " entry (don't flush the Session after an exception occurs)"); } + + object oid = persister.GetIdentifier(obj, entityMode); if (!persister.IdentifierType.IsEqual(id, oid, EntityMode.Poco)) { throw new HibernateException("identifier of an instance of " + persister.EntityName + " was altered from " + id + " to " + oid); @@ -147,7 +148,7 @@ if (!types[prop].IsEqual(current[prop], loadedVal, entityMode)) { throw new HibernateException("immutable natural identifier of an instance of " + persister.EntityName - + " was altered"); + + " was altered"); } } } @@ -227,7 +228,7 @@ if (!entry.IsBeingReplicated) { - // give the Interceptor a chance to process property values, if the properties + // give the Interceptor a chance to process property values, if the properties // were modified by the Interceptor, we need to set them back to the object intercepted = HandleInterception(@event); } @@ -259,8 +260,8 @@ // schedule the update // note that we intentionally do _not_ pass in currentPersistentState! session.ActionQueue.AddAction( - new EntityUpdateAction(entry.Id, values, dirtyProperties, - @event.HasDirtyCollection, entry.LoadedState, entry.Version, + new EntityUpdateAction(entry.Id, values, dirtyProperties, + @event.HasDirtyCollection, entry.LoadedState, entry.Version, nextVersion, entity, persister, session)); return intercepted; @@ -328,8 +329,8 @@ bool isVersionIncrementRequired = IsVersionIncrementRequired(@event, entry, persister, dirtyProperties); - object nextVersion = isVersionIncrementRequired ? - Versioning.Increment(entry.Version, persister.VersionType, @event.Session) : + object nextVersion = isVersionIncrementRequired ? + Versioning.Increment(entry.Version, persister.VersionType, @event.Session) : entry.Version; //use the current version Versioning.SetVersion(values, nextVersion, persister); @@ -351,12 +352,12 @@ bool isVersionIncrementRequired = entry.Status != Status.Deleted && !persister.IsVersionPropertyGenerated && - (dirtyProperties == null || + (dirtyProperties == null || Versioning.IsVersionIncrementRequired(dirtyProperties, @event.HasDirtyCollection, persister.PropertyVersionability)); return isVersionIncrementRequired; } - /// <summary> + /// <summary> /// Performs all necessary checking to determine if an entity needs an SQL update /// to synchronize its state to the database. Modifies the event by side-effect! /// Note: this method is quite slow, avoid calling if possible! This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jul...@us...> - 2010-11-21 17:14:56
|
Revision: 5267 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5267&view=rev Author: julian-maughan Date: 2010-11-21 17:14:48 +0000 (Sun, 21 Nov 2010) Log Message: ----------- In the Criteria API, fix the way in which query parameters are generated, so that they are in the same order as the parameters in the SQL statement (ref. NH-2409). Reverses a design change introduced in r3458 (see NH-1280). Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Criterion/AggregateProjection.cs trunk/nhibernate/src/NHibernate/Criterion/BetweenExpression.cs trunk/nhibernate/src/NHibernate/Criterion/ConstantProjection.cs trunk/nhibernate/src/NHibernate/Criterion/ICriteriaQuery.cs trunk/nhibernate/src/NHibernate/Criterion/IdentifierEqExpression.cs trunk/nhibernate/src/NHibernate/Criterion/InExpression.cs trunk/nhibernate/src/NHibernate/Criterion/InsensitiveLikeExpression.cs trunk/nhibernate/src/NHibernate/Criterion/LikeExpression.cs trunk/nhibernate/src/NHibernate/Criterion/Order.cs trunk/nhibernate/src/NHibernate/Criterion/SQLCriterion.cs trunk/nhibernate/src/NHibernate/Criterion/SimpleExpression.cs trunk/nhibernate/src/NHibernate/Criterion/SimpleSubqueryExpression.cs trunk/nhibernate/src/NHibernate/Criterion/SubqueryExpression.cs trunk/nhibernate/src/NHibernate/Criterion/SubqueryProjection.cs trunk/nhibernate/src/NHibernate/Loader/AbstractEntityJoinWalker.cs trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaJoinWalker.cs trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs trunk/nhibernate/src/NHibernate.Test/Criteria/AddNumberProjection.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2409/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2409/Contest.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2409/Fixture.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2409/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2409/Message.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2409/MessageReading.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2409/User.cs Modified: trunk/nhibernate/src/NHibernate/Criterion/AggregateProjection.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/AggregateProjection.cs 2010-11-20 13:12:25 UTC (rev 5266) +++ trunk/nhibernate/src/NHibernate/Criterion/AggregateProjection.cs 2010-11-21 17:14:48 UTC (rev 5267) @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using NHibernate.SqlCommand; +using NHibernate.Engine; using NHibernate.Type; using NHibernate.Util; @@ -47,25 +48,24 @@ return new IType[] {criteriaQuery.GetType(criteria, propertyName)}; } - public override SqlString ToSqlString(ICriteria criteria, int loc, ICriteriaQuery criteriaQuery, - IDictionary<string, IFilter> enabledFilters) + public override SqlString ToSqlString(ICriteria criteria, int loc, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters) { if (projection != null) { return new SqlString(new object[] - { - aggregate, "(", - StringHelper.RemoveAsAliasesFromSql(projection.ToSqlString(criteria, loc, criteriaQuery, - enabledFilters)), ") as y", - loc.ToString(), "_" - }); + { + aggregate, "(", + StringHelper.RemoveAsAliasesFromSql(projection.ToSqlString(criteria, loc, criteriaQuery, + enabledFilters)), ") as y", + loc.ToString(), "_" + }); } else { return new SqlString(new object[] - {aggregate, "(", criteriaQuery.GetColumn(criteria, propertyName), ") as y", loc.ToString(), "_"}); + {aggregate, "(", criteriaQuery.GetColumn(criteria, propertyName), ") as y", loc.ToString(), "_"}); } } @@ -74,10 +74,17 @@ get { return false; } } - public override SqlString ToGroupSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, - IDictionary<string, IFilter> enabledFilters) + public override SqlString ToGroupSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters) { throw new InvalidOperationException("not a grouping projection"); } + + public override TypedValue[] GetTypedValues(ICriteria criteria, ICriteriaQuery criteriaQuery) + { + if (projection != null) + return projection.GetTypedValues(criteria, criteriaQuery); + + return base.GetTypedValues(criteria, criteriaQuery); + } } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Criterion/BetweenExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/BetweenExpression.cs 2010-11-20 13:12:25 UTC (rev 5266) +++ trunk/nhibernate/src/NHibernate/Criterion/BetweenExpression.cs 2010-11-21 17:14:48 UTC (rev 5267) @@ -1,10 +1,10 @@ +using System; +using System.Collections.Generic; +using NHibernate.Engine; +using NHibernate.SqlCommand; + namespace NHibernate.Criterion { - using System; - using System.Collections.Generic; - using Engine; - using SqlCommand; - /// <summary> /// An <see cref="ICriterion"/> that represents a "between" constraint. /// </summary> @@ -23,11 +23,11 @@ /// <param name="_projection">The _projection.</param> /// <param name="_lo">The _lo.</param> /// <param name="_hi">The _hi.</param> - public BetweenExpression(IProjection _projection, object _lo, object _hi) + public BetweenExpression(IProjection projection, object lo, object hi) { - this._projection = _projection; - this._lo = _lo; - this._hi = _hi; + this._projection = projection; + this._lo = lo; + this._hi = hi; } /// <summary> @@ -44,8 +44,7 @@ _hi = hi; } - public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, - IDictionary<string, IFilter> enabledFilters) + public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters) { //TODO: add a default capacity SqlStringBuilder sqlBuilder = new SqlStringBuilder(); @@ -54,7 +53,6 @@ SqlString[] columnNames = CriterionUtil.GetColumnNames(_propertyName, _projection, criteriaQuery, criteria, enabledFilters); - criteriaQuery.AddUsedTypedValues(GetTypedValues(criteria, criteriaQuery)); if (columnNames.Length == 1) { sqlBuilder @@ -107,7 +105,6 @@ return null; } - /// <summary></summary> public override string ToString() { return _propertyName + " between " + _lo + " and " + _hi; Modified: trunk/nhibernate/src/NHibernate/Criterion/ConstantProjection.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/ConstantProjection.cs 2010-11-20 13:12:25 UTC (rev 5266) +++ trunk/nhibernate/src/NHibernate/Criterion/ConstantProjection.cs 2010-11-21 17:14:48 UTC (rev 5267) @@ -1,11 +1,11 @@ +using System; +using System.Collections.Generic; +using NHibernate.Engine; +using NHibernate.SqlCommand; +using NHibernate.Type; + namespace NHibernate.Criterion { - using System; - using System.Collections.Generic; - using Engine; - using SqlCommand; - using Type; - /// <summary> /// This is useful if we want to send a value to the database /// </summary> @@ -14,17 +14,17 @@ { private readonly object value; private readonly IType type; - public ConstantProjection(object value):this(value,NHibernateUtil.GuessType(value.GetType())) + + public ConstantProjection(object value) : this(value, NHibernateUtil.GuessType(value.GetType())) { - } - public ConstantProjection(object value,IType type) + + public ConstantProjection(object value, IType type) { this.value = value; this.type = type; } - public override bool IsAggregate { get { return false; } @@ -42,7 +42,6 @@ public override SqlString ToSqlString(ICriteria criteria, int position, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters) { - criteriaQuery.AddUsedTypedValues(new TypedValue[] { new TypedValue(type, value, EntityMode.Poco) }); return new SqlStringBuilder() .AddParameter() .Add(" as ") Modified: trunk/nhibernate/src/NHibernate/Criterion/ICriteriaQuery.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/ICriteriaQuery.cs 2010-11-20 13:12:25 UTC (rev 5266) +++ trunk/nhibernate/src/NHibernate/Criterion/ICriteriaQuery.cs 2010-11-21 17:14:48 UTC (rev 5267) @@ -13,27 +13,27 @@ { ISessionFactoryImplementor Factory { get; } - /// <summary> Get the name of the column mapped by a property path, ignoring projection alias</summary> + /// <summary>Get the name of the column mapped by a property path, ignoring projection alias</summary> string GetColumn(ICriteria criteria, string propertyPath); - /// <summary> Get the names of the columns mapped by a property path, ignoring projection aliases</summary> + /// <summary>Get the names of the columns mapped by a property path, ignoring projection aliases</summary> string[] GetColumns(ICriteria criteria, string propertyPath); - /// <summary> Get the type of a property path, ignoring projection aliases</summary> + /// <summary>Get the type of a property path, ignoring projection aliases</summary> IType GetType(ICriteria criteria, string propertyPath); string[] GetColumnAliasesUsingProjection(ICriteria criteria, string propertyPath); - /// <summary> Get the names of the columns mapped by a property path</summary> + /// <summary>Get the names of the columns mapped by a property path</summary> string[] GetColumnsUsingProjection(ICriteria criteria, string propertyPath); - /// <summary> Get the type of a property path</summary> + /// <summary>Get the type of a property path</summary> IType GetTypeUsingProjection(ICriteria criteria, string propertyPath); - /// <summary> Get the a typed value for the given property value.</summary> + /// <summary>Get the a typed value for the given property value.</summary> TypedValue GetTypedValue(ICriteria criteria, string propertyPath, object value); - /// <summary> Get the entity name of an entity</summary> + /// <summary>Get the entity name of an entity</summary> string GetEntityName(ICriteria criteria); /// <summary> @@ -42,7 +42,7 @@ /// </summary> string GetEntityName(ICriteria criteria, string propertyPath); - /// <summary> Get the root table alias of an entity</summary> + /// <summary>Get the root table alias of an entity</summary> string GetSQLAlias(ICriteria subcriteria); /// <summary> @@ -51,13 +51,13 @@ /// </summary> string GetSQLAlias(ICriteria criteria, string propertyPath); - /// <summary> Get the property name, given a possibly qualified property name</summary> + /// <summary>Get the property name, given a possibly qualified property name</summary> string GetPropertyName(string propertyName); - /// <summary> Get the identifier column names of this entity</summary> + /// <summary>Get the identifier column names of this entity</summary> string[] GetIdentifierColumns(ICriteria subcriteria); - /// <summary> Get the identifier type of this entity</summary> + /// <summary>Get the identifier type of this entity</summary> IType GetIdentifierType(ICriteria subcriteria); TypedValue GetTypedIdentifierValue(ICriteria subcriteria, object value); @@ -67,12 +67,6 @@ int GetIndexForAlias(); /// <summary> - /// When adding values to the query string it is imperative that they are reported via this function back to the query builder. - /// Do not report the same item multiple times as it will be assumed to be a separate parameter. - /// </summary> - void AddUsedTypedValues(TypedValue [] values); - - /// <summary> /// Creates a dummy parameter index for the supplied paged value. /// Returns null if the Dialect does not support limit parameters /// </summary> Modified: trunk/nhibernate/src/NHibernate/Criterion/IdentifierEqExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/IdentifierEqExpression.cs 2010-11-20 13:12:25 UTC (rev 5266) +++ trunk/nhibernate/src/NHibernate/Criterion/IdentifierEqExpression.cs 2010-11-21 17:14:48 UTC (rev 5267) @@ -62,7 +62,6 @@ { if (_projection == null) { - criteriaQuery.AddUsedTypedValues(GetTypedValues(criteria,criteriaQuery)); result.AddParameter(); } else @@ -74,6 +73,9 @@ public override TypedValue[] GetTypedValues(ICriteria criteria, ICriteriaQuery criteriaQuery) { + if (_projection != null) + return _projection.GetTypedValues(criteria, criteriaQuery); + return new TypedValue[] {criteriaQuery.GetTypedIdentifierValue(criteria, value)}; } Modified: trunk/nhibernate/src/NHibernate/Criterion/InExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/InExpression.cs 2010-11-20 13:12:25 UTC (rev 5266) +++ trunk/nhibernate/src/NHibernate/Criterion/InExpression.cs 2010-11-21 17:14:48 UTC (rev 5267) @@ -1,15 +1,15 @@ using System; using System.Collections; +using System.Collections.Generic; using NHibernate.Engine; using NHibernate.SqlCommand; using NHibernate.Type; using NHibernate.Util; -using System.Collections.Generic; namespace NHibernate.Criterion { /// <summary> - /// An <see cref="ICriterion"/> that constrains the property + /// An <see cref="ICriterion"/> that constrains the property /// to a specified list of values. /// </summary> /// <remarks> @@ -27,17 +27,12 @@ /// </summary> /// <param name="projection">The projection.</param> /// <param name="_values">The _values.</param> - public InExpression(IProjection projection, object[] _values) + public InExpression(IProjection projection, object[] values) { _projection = projection; - this._values = _values; + _values = values; } - /// <summary> - /// - /// </summary> - /// <param name="propertyName"></param> - /// <param name="values"></param> public InExpression(string propertyName, object[] values) { _propertyName = propertyName; @@ -46,15 +41,14 @@ public override IProjection[] GetProjections() { - if(_projection != null) + if (_projection != null) { return new IProjection[] { _projection }; } return null; } - public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, - IDictionary<string, IFilter> enabledFilters) + public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters) { if (_projection == null) { @@ -75,7 +69,6 @@ // Generate SqlString of the form: // columnName1 in (values) and columnName2 in (values) and ... - criteriaQuery.AddUsedTypedValues(GetTypedValues(criteria, criteriaQuery)); for (int columnIndex = 0; columnIndex < columnNames.Length; columnIndex++) { SqlString columnName = columnNames[columnIndex]; @@ -124,7 +117,7 @@ else { IType[] types = _projection.GetTypes(criteria, criteriaQuery); - if(types.Length!=1) + if (types.Length != 1) { throw new QueryException("Cannot use projections that return more than a single column with InExpression"); } @@ -142,10 +135,8 @@ for (int j = 0; j < _values.Length; j++) { object subval = _values[j] == null - ? - null - : - actype.GetPropertyValues(_values[j], EntityMode.Poco)[i]; + ? null + : actype.GetPropertyValues(_values[j], EntityMode.Poco)[i]; list.Add(new TypedValue(types[i], subval, EntityMode.Poco)); } } @@ -167,7 +158,6 @@ protected set { _values = value; } } - /// <summary></summary> public override string ToString() { return (_projection ?? (object)_propertyName) + " in (" + StringHelper.ToString(_values) + ')'; Modified: trunk/nhibernate/src/NHibernate/Criterion/InsensitiveLikeExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/InsensitiveLikeExpression.cs 2010-11-20 13:12:25 UTC (rev 5266) +++ trunk/nhibernate/src/NHibernate/Criterion/InsensitiveLikeExpression.cs 2010-11-21 17:14:48 UTC (rev 5267) @@ -1,11 +1,11 @@ +using System; +using System.Collections.Generic; +using NHibernate.Dialect; +using NHibernate.Engine; +using NHibernate.SqlCommand; + namespace NHibernate.Criterion { - using System; - using System.Collections.Generic; - using Dialect; - using Engine; - using SqlCommand; - /// <summary> /// An <see cref="ICriterion"/> that represents an "like" constraint /// that is <b>not</b> case sensitive. @@ -58,15 +58,13 @@ { } - public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, - IDictionary<string, IFilter> enabledFilters) + public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters) { //TODO: add default capacity SqlStringBuilder sqlBuilder = new SqlStringBuilder(); SqlString[] columnNames = CriterionUtil.GetColumnNames(propertyName, projection, criteriaQuery, criteria, enabledFilters); - criteriaQuery.AddUsedTypedValues(GetTypedValues(criteria,criteriaQuery)); if (columnNames.Length != 1) { throw new HibernateException("insensitive like may only be used with single-column properties"); @@ -93,23 +91,31 @@ public override TypedValue[] GetTypedValues(ICriteria criteria, ICriteriaQuery criteriaQuery) { - return CriterionUtil.GetTypedValues(criteriaQuery, criteria, projection, propertyName, value.ToString().ToLower()); + List<TypedValue> typedValues = new List<TypedValue>(); + + if (projection != null) + { + typedValues.AddRange(projection.GetTypedValues(criteria, criteriaQuery)); + typedValues.AddRange(CriterionUtil.GetTypedValues(criteriaQuery, criteria, projection, null, value.ToString().ToLower())); + } + else + typedValues.Add(criteriaQuery.GetTypedValue(criteria, propertyName, value.ToString().ToLower())); + + return typedValues.ToArray(); } public override IProjection[] GetProjections() { - if(projection != null) + if (projection != null) { return new IProjection[] { projection }; } return null; } - /// <summary></summary> public override string ToString() { return (projection ?? (object)propertyName) + " ilike " + value; } - } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Criterion/LikeExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/LikeExpression.cs 2010-11-20 13:12:25 UTC (rev 5266) +++ trunk/nhibernate/src/NHibernate/Criterion/LikeExpression.cs 2010-11-21 17:14:48 UTC (rev 5267) @@ -1,7 +1,7 @@ using System; +using System.Collections.Generic; using NHibernate.Engine; using NHibernate.SqlCommand; -using System.Collections.Generic; using NHibernate.Util; namespace NHibernate.Criterion @@ -10,7 +10,7 @@ /// An <see cref="ICriterion"/> that represents an "like" constraint. /// </summary> /// <remarks> - /// The case sensitivity depends on the database settings for string + /// The case sensitivity depends on the database settings for string /// comparisons. Use <see cref="InsensitiveLikeExpression"/> if the /// string comparison should not be case sensitive. /// </remarks> @@ -73,8 +73,6 @@ else lhs.Add(columns[0]); - criteriaQuery.AddUsedTypedValues(GetTypedValues(criteria, criteriaQuery)); - if (ignoreCase) { Dialect.Dialect dialect = criteriaQuery.Factory.Dialect; @@ -89,14 +87,13 @@ if (escapeChar.HasValue) lhs.Add(" escape '" + escapeChar + "'"); + return lhs.ToSqlString(); } public override TypedValue[] GetTypedValues(ICriteria criteria, ICriteriaQuery criteriaQuery) { - return new TypedValue[] { - new TypedValue(NHibernateUtil.String, value, EntityMode.Poco), - }; + return new TypedValue[] { new TypedValue(NHibernateUtil.String, value, EntityMode.Poco) }; } public override IProjection[] GetProjections() Modified: trunk/nhibernate/src/NHibernate/Criterion/Order.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/Order.cs 2010-11-20 13:12:25 UTC (rev 5266) +++ trunk/nhibernate/src/NHibernate/Criterion/Order.cs 2010-11-21 17:14:48 UTC (rev 5267) @@ -1,8 +1,8 @@ using System; using System.Collections.Generic; using System.Text; +using NHibernate.Criterion; using NHibernate.Engine; -using NHibernate.Criterion; using NHibernate.SqlCommand; namespace NHibernate.Criterion @@ -11,43 +11,36 @@ /// Represents an order imposed upon a <see cref="ICriteria"/> /// result set. /// </summary> + /// <remarks> + /// Should Order implement ICriteriaQuery? + /// </remarks> [Serializable] public class Order { protected bool ascending; protected string propertyName; protected IProjection projection; - /// <summary> - /// Constructor for Order. - /// </summary> - /// <param name="projection"></param> - /// <param name="ascending"></param> + public Order(IProjection projection, bool ascending) { this.projection = projection; this.ascending = ascending; } - /// <summary> - /// Constructor for Order. - /// </summary> - /// <param name="propertyName"></param> - /// <param name="ascending"></param> public Order(string propertyName, bool ascending) { this.propertyName = propertyName; this.ascending = ascending; } - /// <summary> /// Render the SQL fragment /// </summary> public virtual SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery) { - if(projection!=null) + if (projection!=null) { - SqlString sb=new SqlString(); + SqlString sb = new SqlString(); SqlString produced = this.projection.ToSqlString(criteria, 0, criteriaQuery, new Dictionary<string, IFilter>()); SqlString truncated = NHibernate.Util.StringHelper.RemoveAsAliasesFromSql(produced); sb = sb.Append(truncated); @@ -131,5 +124,13 @@ { return new Order(propertyName, false); } + + public TypedValue[] GetTypedValues(ICriteria criteria, ICriteriaQuery criteriaQuery) + { + if (projection != null) + return projection.GetTypedValues(criteria, criteriaQuery); + + return new TypedValue[0]; // not using parameters for ORDER BY columns + } } } Modified: trunk/nhibernate/src/NHibernate/Criterion/SQLCriterion.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/SQLCriterion.cs 2010-11-20 13:12:25 UTC (rev 5266) +++ trunk/nhibernate/src/NHibernate/Criterion/SQLCriterion.cs 2010-11-21 17:14:48 UTC (rev 5267) @@ -32,7 +32,6 @@ public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters) { - criteriaQuery.AddUsedTypedValues(GetTypedValues(criteria, criteriaQuery)); return _sql.Replace("{alias}", criteriaQuery.GetSQLAlias(criteria)); } @@ -46,7 +45,6 @@ return null; } - /// <summary></summary> public override string ToString() { return _sql.ToString(); Modified: trunk/nhibernate/src/NHibernate/Criterion/SimpleExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/SimpleExpression.cs 2010-11-20 13:12:25 UTC (rev 5266) +++ trunk/nhibernate/src/NHibernate/Criterion/SimpleExpression.cs 2010-11-21 17:14:48 UTC (rev 5267) @@ -77,10 +77,15 @@ public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters) { SqlString[] columnNames = - CriterionUtil.GetColumnNamesForSimpleExpression(propertyName, _projection, criteriaQuery, criteria, enabledFilters, - this, value); + CriterionUtil.GetColumnNamesForSimpleExpression( + propertyName, + _projection, + criteriaQuery, + criteria, + enabledFilters, + this, + value); - criteriaQuery.AddUsedTypedValues(GetTypedValues(criteria, criteriaQuery)); if (ignoreCase) { if (columnNames.Length != 1) @@ -120,20 +125,29 @@ public override TypedValue[] GetTypedValues(ICriteria criteria, ICriteriaQuery criteriaQuery) { + List<TypedValue> typedValues = new List<TypedValue>(); object icvalue = ignoreCase ? value.ToString().ToLower() : value; - return CriterionUtil.GetTypedValues(criteriaQuery, criteria, _projection,propertyName, icvalue); + + if (_projection != null) + { + typedValues.AddRange(_projection.GetTypedValues(criteria, criteriaQuery)); + typedValues.AddRange(CriterionUtil.GetTypedValues(criteriaQuery, criteria, _projection, null, icvalue)); + } + else + typedValues.Add(criteriaQuery.GetTypedValue(criteria, propertyName, icvalue)); + + return typedValues.ToArray(); } public override IProjection[] GetProjections() { - if(_projection != null) + if (_projection != null) { return new IProjection[] { _projection }; } return null; } - /// <summary></summary> public override string ToString() { return (_projection ?? (object)propertyName) + Op + value; Modified: trunk/nhibernate/src/NHibernate/Criterion/SimpleSubqueryExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/SimpleSubqueryExpression.cs 2010-11-20 13:12:25 UTC (rev 5266) +++ trunk/nhibernate/src/NHibernate/Criterion/SimpleSubqueryExpression.cs 2010-11-21 17:14:48 UTC (rev 5267) @@ -14,12 +14,10 @@ internal SimpleSubqueryExpression(Object value, String op, String quantifier, DetachedCriteria dc) : base(op, quantifier, dc) - { this.value = value; } - public override TypedValue[] GetTypedValues(ICriteria criteria, ICriteriaQuery criteriaQuery) { TypedValue[] superTv = base.GetTypedValues(criteria, criteriaQuery); @@ -31,7 +29,6 @@ protected override SqlString ToLeftSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery) { - criteriaQuery.AddUsedTypedValues(GetTypedValues(criteria, criteriaQuery)); return SqlString.Parameter; } } Modified: trunk/nhibernate/src/NHibernate/Criterion/SubqueryExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/SubqueryExpression.cs 2010-11-20 13:12:25 UTC (rev 5266) +++ trunk/nhibernate/src/NHibernate/Criterion/SubqueryExpression.cs 2010-11-21 17:14:48 UTC (rev 5267) @@ -14,25 +14,24 @@ { private readonly CriteriaImpl criteriaImpl; private readonly String quantifier; - private readonly bool prefixOp; - private readonly String op; + private readonly bool prefixOp; + private readonly String op; private QueryParameters parameters; private IType[] types; [NonSerialized] private CriteriaQueryTranslator innerQuery; - protected SubqueryExpression(String op, String quantifier, DetachedCriteria dc) - :this(op, quantifier, dc, true) - { - - } + protected SubqueryExpression(String op, String quantifier, DetachedCriteria dc) + :this(op, quantifier, dc, true) + { + } protected SubqueryExpression(String op, String quantifier, DetachedCriteria dc, bool prefixOp) { criteriaImpl = dc.GetCriteriaImpl(); this.quantifier = quantifier; - this.prefixOp = prefixOp; - this.op = op; + this.prefixOp = prefixOp; + this.op = op; } public IType[] GetTypes() @@ -42,8 +41,7 @@ protected abstract SqlString ToLeftSqlString(ICriteria criteria, ICriteriaQuery outerQuery); - public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, - IDictionary<string, IFilter> enabledFilters) + public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters) { InitializeInnerQueryAndParameters(criteriaQuery); @@ -80,27 +78,27 @@ buf.Add(" ").Add(op).Add(" "); } - if (quantifier != null && prefixOp) + if (quantifier != null && prefixOp) { buf.Add(quantifier).Add(" "); } - - buf.Add("(").Add(sql).Add(")"); + + buf.Add("(").Add(sql).Add(")"); - if(quantifier!=null && prefixOp==false) - { - buf.Add(" ").Add(quantifier); - } + if (quantifier != null && prefixOp == false) + { + buf.Add(" ").Add(quantifier); + } - return buf.ToSqlString(); + return buf.ToSqlString(); } public override string ToString() { - if(prefixOp) - return string.Format("{0} {1} ({2})", op, quantifier, criteriaImpl); - return string.Format("{0} ({1}) {2}", op, criteriaImpl, quantifier); - + if(prefixOp) + return string.Format("{0} {1} ({2})", op, quantifier, criteriaImpl); + + return string.Format("{0} ({1}) {2}", op, criteriaImpl, quantifier); } public override TypedValue[] GetTypedValues(ICriteria criteria, ICriteriaQuery criteriaQuery) @@ -123,19 +121,28 @@ public void InitializeInnerQueryAndParameters(ICriteriaQuery criteriaQuery) { - ISessionFactoryImplementor factory = criteriaQuery.Factory; - innerQuery = - new CriteriaQueryTranslator(factory, criteriaImpl, //implicit polymorphism not supported (would need a union) - criteriaImpl.EntityOrClassName, criteriaQuery.GenerateSQLAlias(), criteriaQuery); - if (innerQuery.HasProjection) + if (innerQuery == null) { - parameters = innerQuery.GetQueryParameters(); - types = innerQuery.ProjectedTypes; + ISessionFactoryImplementor factory = criteriaQuery.Factory; + + innerQuery = + new CriteriaQueryTranslator( + factory, + criteriaImpl, //implicit polymorphism not supported (would need a union) + criteriaImpl.EntityOrClassName, + criteriaQuery.GenerateSQLAlias(), + criteriaQuery); + + if (innerQuery.HasProjection) + { + parameters = innerQuery.GetQueryParameters(); + types = innerQuery.ProjectedTypes; + } + else + { + types = null; + } } - else - { - types = null; - } } public ICriteria Criteria @@ -144,4 +151,4 @@ get { return criteriaImpl; } } } -} +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Criterion/SubqueryProjection.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/SubqueryProjection.cs 2010-11-20 13:12:25 UTC (rev 5266) +++ trunk/nhibernate/src/NHibernate/Criterion/SubqueryProjection.cs 2010-11-21 17:14:48 UTC (rev 5267) @@ -1,12 +1,12 @@ using System; +using System.Collections.Generic; +using NHibernate.Engine; using NHibernate.Impl; using NHibernate.SqlCommand; using NHibernate.Type; namespace NHibernate.Criterion { - using System.Collections.Generic; - /// <summary> /// A property value, or grouped property value /// </summary> @@ -19,6 +19,7 @@ { _subQuery = subquery; } + public override string ToString() { return _subQuery.ToString(); @@ -43,17 +44,17 @@ public override SqlString ToSqlString(ICriteria criteria, int loc, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters) { SqlString sqlStringSubquery = _subQuery.ToSqlString(criteria, criteriaQuery, enabledFilters); - return sqlStringSubquery.Append(new SqlString(new object[] - { - " as y", - loc.ToString(), - "_" - })); + return sqlStringSubquery.Append(new SqlString(new object[] { " as y", loc.ToString(), "_" } )); } public override SqlString ToGroupSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters) { throw new InvalidOperationException("not a grouping projection"); } + + public override TypedValue[] GetTypedValues(ICriteria criteria, ICriteriaQuery criteriaQuery) + { + return _subQuery.GetTypedValues(criteria, criteriaQuery); + } } } Modified: trunk/nhibernate/src/NHibernate/Loader/AbstractEntityJoinWalker.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/AbstractEntityJoinWalker.cs 2010-11-20 13:12:25 UTC (rev 5266) +++ trunk/nhibernate/src/NHibernate/Loader/AbstractEntityJoinWalker.cs 2010-11-21 17:14:48 UTC (rev 5267) @@ -1,10 +1,10 @@ using System.Collections.Generic; using NHibernate.Engine; +using NHibernate.Loader.Criteria; using NHibernate.Persister.Entity; using NHibernate.SqlCommand; using NHibernate.Type; using NHibernate.Util; -using NHibernate.Loader.Criteria; namespace NHibernate.Loader { @@ -13,16 +13,14 @@ private readonly IOuterJoinLoadable persister; private readonly string alias; - public AbstractEntityJoinWalker(IOuterJoinLoadable persister, ISessionFactoryImplementor factory, - IDictionary<string, IFilter> enabledFilters) + public AbstractEntityJoinWalker(IOuterJoinLoadable persister, ISessionFactoryImplementor factory, IDictionary<string, IFilter> enabledFilters) : base(factory, enabledFilters) { this.persister = persister; alias = GenerateRootAlias(persister.EntityName); } - public AbstractEntityJoinWalker(string rootSqlAlias, IOuterJoinLoadable persister, ISessionFactoryImplementor factory, - IDictionary<string, IFilter> enabledFilters) + public AbstractEntityJoinWalker(string rootSqlAlias, IOuterJoinLoadable persister, ISessionFactoryImplementor factory, IDictionary<string, IFilter> enabledFilters) : base(factory, enabledFilters) { this.persister = persister; @@ -35,26 +33,17 @@ IList<OuterJoinableAssociation> allAssociations = new List<OuterJoinableAssociation>(associations); allAssociations.Add( new OuterJoinableAssociation(persister.EntityType, null, null, alias, JoinType.LeftOuterJoin, null, Factory, - new CollectionHelper.EmptyMapClass<string, IFilter>())); + new CollectionHelper.EmptyMapClass<string, IFilter>())); InitPersisters(allAssociations, lockMode); InitStatementString(whereString, orderByString, lockMode); } - protected void InitProjection(CriteriaQueryTranslator translator, - IDictionary<string, IFilter> enabledFilters, LockMode lockMode) + protected void InitProjection(SqlString projectionString, SqlString whereString, SqlString orderByString, SqlString groupByString, SqlString havingString, IDictionary<string, IFilter> enabledFilters, LockMode lockMode) { - // the order of the calls here is important, as the join clauses can contain parameter bindings - SqlString projectionString = translator.GetSelect(enabledFilters); WalkEntityTree(persister, Alias); - SqlString whereString = translator.GetWhereCondition(enabledFilters); - SqlString orderByString = translator.GetOrderBy(); - SqlString groupByString = translator.GetGroupBy(); - SqlString havingString = translator.GetHavingCondition(enabledFilters); - Persisters = new ILoadable[0]; - InitStatementString(projectionString, whereString, orderByString, groupByString.ToString(), - havingString, lockMode); + InitStatementString(projectionString, whereString, orderByString, groupByString.ToString(), havingString, lockMode); } private void InitStatementString(SqlString condition, SqlString orderBy, LockMode lockMode) @@ -62,16 +51,14 @@ InitStatementString(null, condition, orderBy, string.Empty, null, lockMode); } - private void InitStatementString(SqlString projection,SqlString condition, - SqlString orderBy,string groupBy, SqlString having, LockMode lockMode) + private void InitStatementString(SqlString projection,SqlString condition, SqlString orderBy, string groupBy, SqlString having, LockMode lockMode) { int joins = CountEntityPersisters(associations); Suffixes = BasicLoader.GenerateSuffixes(joins + 1); JoinFragment ojf = MergeOuterJoins(associations); - SqlString selectClause = projection - ?? - new SqlString(persister.SelectFragment(alias, Suffixes[joins]) + SelectString(associations)); + SqlString selectClause = + projection ?? new SqlString(persister.SelectFragment(alias, Suffixes[joins]) + SelectString(associations)); SqlSelectBuilder select = new SqlSelectBuilder(Factory) .SetLockMode(lockMode) @@ -92,8 +79,7 @@ /// <summary> /// The superclass deliberately excludes collections /// </summary> - protected override bool IsJoinedFetchEnabled(IAssociationType type, FetchMode config, - CascadeStyle cascadeStyle) + protected override bool IsJoinedFetchEnabled(IAssociationType type, FetchMode config, CascadeStyle cascadeStyle) { return IsJoinedFetchEnabledInMapping(config, type); } Modified: trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaJoinWalker.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaJoinWalker.cs 2010-11-20 13:12:25 UTC (rev 5266) +++ trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaJoinWalker.cs 2010-11-21 17:14:48 UTC (rev 5267) @@ -42,7 +42,14 @@ { resultTypes = translator.ProjectedTypes; - InitProjection(translator, enabledFilters, LockMode.None); + InitProjection( + translator.GetSelect(enabledFilters), + translator.GetWhereCondition(enabledFilters), + translator.GetOrderBy(), + translator.GetGroupBy(), + translator.GetHavingCondition(enabledFilters), + enabledFilters, + LockMode.None); } else { Modified: trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs 2010-11-20 13:12:25 UTC (rev 5266) +++ trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs 2010-11-21 17:14:48 UTC (rev 5267) @@ -1,6 +1,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Linq; using System.Text; using Iesi.Collections.Generic; using NHibernate.Criterion; @@ -8,7 +9,7 @@ using NHibernate.Hql.Util; using NHibernate.Impl; using NHibernate.Persister.Collection; -using NHibernate.Persister.Entity; +using NHibernate_Persister_Entity = NHibernate.Persister.Entity; using NHibernate.SqlCommand; using NHibernate.Type; using NHibernate.Util; @@ -106,18 +107,6 @@ public QueryParameters GetQueryParameters() { - ArrayList values = new ArrayList(usedTypedValues.Count); - List<IType> types = new List<IType>(usedTypedValues.Count); - - foreach (TypedValue value in usedTypedValues) - { - values.Add(value.Value); - types.Add(value.Type); - } - - object[] valueArray = values.ToArray(); - IType[] typeArray = types.ToArray(); - RowSelection selection = new RowSelection(); selection.FirstRow = rootCriteria.FirstResult; selection.MaxRows = rootCriteria.MaxResults; @@ -130,6 +119,14 @@ ICriteria subcriteria = GetAliasedCriteria(me.Key); lockModes[GetSQLAlias(subcriteria)] = me.Value; } + + List<TypedValue> typedValues = new List<TypedValue>(); + + // NH-specific: Get parameters for projections first + if (this.HasProjection) + { + typedValues.AddRange(rootCriteria.Projection.GetTypedValues(rootCriteria, this)); + } foreach (CriteriaImpl.Subcriteria subcriteria in rootCriteria.IterateSubcriteria()) { @@ -138,13 +135,69 @@ { lockModes[GetSQLAlias(subcriteria)] = lm; } + // Get parameters that may be used in JOINs + if (subcriteria.WithClause != null) + { + typedValues.AddRange(subcriteria.WithClause.GetTypedValues(subcriteria, this)); + } } + + List<TypedValue> groupedTypedValues = new List<TypedValue>(); + + // Type and value gathering for the WHERE clause needs to come AFTER lock mode gathering, + // because the lock mode gathering loop now contains join clauses which can contain + // parameter bindings (as in the HQL WITH clause). + foreach(CriteriaImpl.CriterionEntry ce in rootCriteria.IterateExpressionEntries()) + { + bool criteriaContainsGroupedProjections = false; + IProjection[] projections = ce.Criterion.GetProjections(); + if (projections != null) + { + foreach (IProjection projection in projections) + { + if (projection.IsGrouped) + { + criteriaContainsGroupedProjections = true; + break; + } + } + } + + if (criteriaContainsGroupedProjections) + // GROUP BY/HAVING parameters need to be added after WHERE parameters - so don't add them + // to typedValues yet + groupedTypedValues.AddRange(ce.Criterion.GetTypedValues(ce.Criteria, this)); + else + typedValues.AddRange(ce.Criterion.GetTypedValues(ce.Criteria, this)); + } + + // NH-specific: GROUP BY/HAVING parameters need to appear after WHERE parameters + if (groupedTypedValues.Count > 0) + { + typedValues.AddRange(groupedTypedValues); + } + + // NH-specific: To support expressions/projections used in ORDER BY + foreach(CriteriaImpl.OrderEntry oe in rootCriteria.IterateOrderings()) + { + typedValues.AddRange(oe.Order.GetTypedValues(oe.Criteria, this)); + } + return - new QueryParameters(typeArray, valueArray, lockModes, selection, rootCriteria.Cacheable, rootCriteria.CacheRegion, - rootCriteria.Comment, rootCriteria.LookupByNaturalKey, rootCriteria.ResultTransformer, _tempPagingParameterIndexes); + new QueryParameters( + typedValues.Select(tv => tv.Type).ToArray(), + typedValues.Select(tv => tv.Value).ToArray(), + lockModes, + selection, + rootCriteria.Cacheable, + rootCriteria.CacheRegion, + rootCriteria.Comment, + rootCriteria.LookupByNaturalKey, + rootCriteria.ResultTransformer, + _tempPagingParameterIndexes); } - + public SqlString GetGroupBy() { if (rootCriteria.Projection.IsGrouped) @@ -366,7 +419,7 @@ private void CreateCriteriaEntityNameMap() { // initialize the rootProvider first - ICriteriaInfoProvider rootProvider = new EntityCriteriaInfoProvider((IQueryable)sessionFactory.GetEntityPersister(rootEntityName)); + ICriteriaInfoProvider rootProvider = new EntityCriteriaInfoProvider((NHibernate_Persister_Entity.IQueryable)sessionFactory.GetEntityPersister(rootEntityName)); criteriaInfoMap.Add(rootCriteria, rootProvider); nameCriteriaInfoMap.Add(rootProvider.Name, rootProvider); @@ -384,7 +437,7 @@ { foreach (KeyValuePair<string, ICriteria> me in associationPathCriteriaMap) { - IJoinable joinable = GetPathJoinable(me.Key); + NHibernate_Persister_Entity.IJoinable joinable = GetPathJoinable(me.Key); if (joinable != null && joinable.IsCollection) { criteriaCollectionPersisters.Add((ICollectionPersister)joinable); @@ -392,10 +445,10 @@ } } - private IJoinable GetPathJoinable(string path) + private Persister.Entity.IJoinable GetPathJoinable(string path) { - IJoinable last = (IJoinable)Factory.GetEntityPersister(rootEntityName); - IPropertyMapping lastEntity = (IPropertyMapping)last; + NHibernate_Persister_Entity.IJoinable last = (NHibernate_Persister_Entity.IJoinable)Factory.GetEntityPersister(rootEntityName); + NHibernate_Persister_Entity.IPropertyMapping lastEntity = (NHibernate_Persister_Entity.IPropertyMapping)last; string componentPath = ""; @@ -417,7 +470,7 @@ IAssociationType atype = (IAssociationType)type; last = atype.GetAssociatedJoinable(Factory); - lastEntity = (IPropertyMapping)Factory.GetEntityPersister(atype.GetAssociatedEntityName(Factory)); + lastEntity = (NHibernate_Persister_Entity.IPropertyMapping)Factory.GetEntityPersister(atype.GetAssociatedEntityName(Factory)); componentPath = ""; } else if (type.IsComponentType) @@ -466,7 +519,7 @@ } else { - provider = new EntityCriteriaInfoProvider((IQueryable)sessionFactory.GetEntityPersister( + provider = new EntityCriteriaInfoProvider((NHibernate_Persister_Entity.IQueryable)sessionFactory.GetEntityPersister( atype.GetAssociatedEntityName( sessionFactory) )); @@ -564,18 +617,18 @@ public string[] GetIdentifierColumns(ICriteria subcriteria) { - string[] idcols = ((ILoadable)GetPropertyMapping(GetEntityName(subcriteria))).IdentifierColumnNames; + string[] idcols = ((NHibernate_Persister_Entity.ILoadable)GetPropertyMapping(GetEntityName(subcriteria))).IdentifierColumnNames; return StringHelper.Qualify(GetSQLAlias(subcriteria), idcols); } public IType GetIdentifierType(ICriteria subcriteria) { - return ((ILoadable)GetPropertyMapping(GetEntityName(subcriteria))).IdentifierType; + return ((NHibernate_Persister_Entity.ILoadable)GetPropertyMapping(GetEntityName(subcriteria))).IdentifierType; } public TypedValue GetTypedIdentifierValue(ICriteria subcriteria, object value) { - ILoadable loadable = (ILoadable)GetPropertyMapping(GetEntityName(subcriteria)); + NHibernate_Persister_Entity.ILoadable loadable = (NHibernate_Persister_Entity.ILoadable)GetPropertyMapping(GetEntityName(subcriteria)); return new TypedValue(loadable.IdentifierType, value, EntityMode.Poco); } @@ -641,7 +694,7 @@ var entityClass = value as System.Type; if (entityClass != null) { - IQueryable q = helper.FindQueryableUsingImports(entityClass.FullName); + NHibernate_Persister_Entity.IQueryable q = helper.FindQueryableUsingImports(entityClass.FullName); if (q != null && q.DiscriminatorValue != null) { @@ -653,7 +706,7 @@ return new TypedValue(GetTypeUsingProjection(subcriteria, propertyName), value, EntityMode.Poco); } - private IPropertyMapping GetPropertyMapping(string entityName) + private Persister.Entity.IPropertyMapping GetPropertyMapping(string entityName) { ICriteriaInfoProvider info ; if (nameCriteriaInfoMap.TryGetValue(entityName, out info)==false) @@ -720,21 +773,6 @@ return indexForAlias++; } - public void AddUsedTypedValues(TypedValue[] values) - { - if (values != null) - { - if (outerQueryTranslator != null) - { - outerQueryTranslator.AddUsedTypedValues(values); - } - else - { - usedTypedValues.AddRange(values); - } - } - } - public int? CreatePagingParameter(int value) { if (!Factory.Dialect.SupportsVariableLimit) Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/AddNumberProjection.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/AddNumberProjection.cs 2010-11-20 13:12:25 UTC (rev 5266) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/AddNumberProjection.cs 2010-11-21 17:14:48 UTC (rev 5267) @@ -1,13 +1,12 @@ using System; +using System.Collections.Generic; +using NHibernate.Engine; +using NHibernate.Criterion; +using NHibernate.SqlCommand; +using NHibernate.Type; namespace NHibernate.Test.Criteria { - using System.Collections.Generic; - using Engine; - using Criterion; - using SqlCommand; - using Type; - public class AddNumberProjection : SimpleProjection { private readonly string propertyName; @@ -27,7 +26,7 @@ public override SqlString ToSqlString(ICriteria criteria, int position, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters) { string[] projection = criteriaQuery.GetColumnsUsingProjection(criteria, propertyName); - criteriaQuery.AddUsedTypedValues(GetTypedValues(criteria, criteriaQuery)); + return new SqlStringBuilder() .Add("(") .Add(projection[0]) @@ -54,8 +53,7 @@ get { return false; } } - public override SqlString ToGroupSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, - IDictionary<string, IFilter> enabledFilters) + public override SqlString ToGroupSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters) { throw new InvalidOperationException("not a grouping projection"); } Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2409/Contest.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2409/Contest.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2409/Contest.cs 2010-11-21 17:14:48 UTC (rev 5267) @@ -0,0 +1,7 @@ +namespace NHibernate.Test.NHSpecificTest.NH2409 +{ + public class Contest + { + public virtual int Id { get; set; } + } +} Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2409/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2409/Fixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2409/Fixture.cs 2010-11-21 17:14:48 UTC (rev 5267) @@ -0,0 +1,60 @@ +using System; +using System.Linq; +using NHibernate.Criterion; +using NHibernate.SqlCommand; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.NH2409 +{ + [TestFixture] + public class Fixture : BugTestCase + { + [Test] + public void Bug() + { + using (var session = OpenSession()) + using (var tx = session.BeginTransaction()) + { + var contest1 = new Contest {Id = 1}; + var contest2 = new Contest {Id = 2}; + var user = new User(); + + var message = new Message {Contest = contest2 }; + + session.Save(contest1); + session.Save(contest2); + session.Save(user); + + session.Save(message); + tx.Commit(); + } + + using (var session = OpenSession()) + { + var contest2 = session.CreateCriteria<Contest>().Add(Restrictions.IdEq(2)).UniqueResult<Contest>(); + var user = session.CreateCriteria<User>().List<User>().Single(); + + var msgs = session.CreateCriteria<Message>() + .Add(Restrictions.Eq("Contest", contest2)) + .CreateAlias("Readings", "mr", JoinType.LeftOuterJoin, Restrictions.Eq("mr.User", user)) + .List<Message>(); + + Assert.AreEqual(1, msgs.Count, "We should be able to find our message despite any left outer joins"); + } + } + + protected override void OnTearDown() + { + using (var session = OpenSession()) + using (var tx = session.BeginTransaction()) + { + session.Delete("from Contest"); + session.Delete("from User"); + session.Delete("from Message"); + session.Delete("from MessageReading"); + tx.Commit(); + } + base.OnTearDown(); + } + } +} Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2409/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2409/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2409/Mappings.hbm.xml 2010-11-21 17:14:48 UTC (rev 5267) @@ -0,0 +1,38 @@ +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" + namespace="NHibernate.Test.NHSpecificTest.NH2409" + assembly="NHibernate.Test"> + <class name="Contest" lazy="true"> + <id name="Id"> + <generator class="assigned" /> + </id> + </class> + + <class name="Message" lazy="true"> + <id name="Id"> + <generator class="native" /> + </id> + + <many-to-one name="Contest" class="Contest" column="ContestId"/> + + <bag name="Readings" cascade="all" inverse="true"> + <key column="MessageReadingId"/> + <one-to-many class="MessageReading"/> + </bag> + </class> + + <class name="MessageReading" lazy="true"> + <id name="Id"> + <generator class="native" /> + </id> + + <many-to-one name="User" + class="User" column="UserId"/> + </class> + + <class name="User" lazy="true" table="`User`"> + <id name="Id"> + <generator class="native" /> + </id> + </class> + +</hibernate-mapping> Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2409/Message.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2409/Message.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2409/Message.cs 2010-11-21 17:14:48 UTC (rev 5267) @@ -0,0 +1,13 @@ +using System.Collections.Generic; + +namespace NHibernate.Test.NHSpecificTest.NH2409 +{ + public class Message + { + public virtual int Id { get; set; } + + public virtual Contest Contest { get; set; } + + public virtual IList<MessageReading> Readings { get; set; } + } +} Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2409/MessageReading.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2409/MessageReading.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2409/MessageReading.cs 2010-11-21 17:14:48 UTC (rev 5267) @@ -0,0 +1,9 @@ +namespace NHibernate.Test.NHSpecificTest.NH2409 +{ + public class MessageReading + { + public virtual int Id { get; set; } + + public virtual User User { get; set; } + } +} Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2409/User.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2409/User.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2409/User.cs 2010-11-21 17:14:48 UTC (rev 5267) @@ -0,0 +1,7 @@ +namespace NHibernate.Test.NHSpecificTest.NH2409 +{ + public class User + { + public virtual int Id { get; set; } + } +} Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-11-20 13:12:25 UTC (rev 5266) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-11-21 17:14:48 UTC (rev 5267) @@ -30,7 +30,7 @@ <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> <UseVSHostingProcess>false</UseVSHostingProcess> - <NoWarn>3001%3b3002%3b3003%3b3004%3b3005</NoWarn> + <NoWarn>3001%3b3002%3b3003%3b3004%3b3005</NoWarn> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <DebugType>pdbonly</DebugType> @@ -42,7 +42,7 @@ <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> <UseVSHostingProcess>false</UseVSHostingProcess> - <NoWarn>3001%3b3002%3b3003%3b3004%3b3005</NoWarn> + <NoWarn>3001%3b3002%3b3003%3b3004%3b3005</NoWarn> </PropertyGroup> <ItemGroup> <Reference Include="Antlr3.Runtime, Version=3.1.0.39271, Culture=neutral, PublicKeyToken=3a9cab8f8d22bfb7, processorArchitecture=MSIL"> @@ -542,6 +542,11 @@ <Compile Include="NHSpecificTest\NH2392\Fixture.cs" /> <Compile Include="NHSpecificTest\NH2392\PhoneNumber.cs" /> <Compile Include="NHSpecificTest\NH2392\PhoneNumberUserType.cs" /> + <Compile Include="NHSpecificTest\NH2409\Contest.cs" /> + <Compile Include="NHSpecificTest\NH2409\Fixture.cs" /> + <Compile Include="NHSpecificTest\NH2409\Message.cs" /> + <Compile Include="NHSpecificTest\NH2409\MessageReading.cs" /> + <Compile Include="NHSpecificTest\NH2409\User.cs" /> <Compile Include="PolymorphicGetAndLoad\Domain.cs" /> <Compile Include="PolymorphicGetAndLoad\PolymorphicGetAndLoadTest.cs" /> <Compile Include="TypesTest\CharClass.cs" /> @@ -1834,6 +1839,7 @@ <EmbeddedResource Include="NHSpecificTest\NH2202\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH1869\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2392\Mappings.hbm.xml" /> + <EmbeddedResource Include="NHSpecificTest\NH2409\Mappings.hbm.xml" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\NHibernate.ByteCode.Castle\NHibernate.ByteCode.Castle.csproj"> @@ -2699,6 +2705,7 @@ </ItemGroup> <ItemGroup> <Folder Include="NHSpecificTest\NH2392" /> + <Folder Include="NHSpecificTest\NH2409" /> <Folder Include="Properties\" /> </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2010-11-20 13:12:32
|
Revision: 5266 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5266&view=rev Author: fabiomaulo Date: 2010-11-20 13:12:25 +0000 (Sat, 20 Nov 2010) Log Message: ----------- Actualization to Castle 2.5.2 Modified Paths: -------------- trunk/nhibernate/lib/net/3.5/Castle.Core.dll trunk/nhibernate/lib/net/3.5/Castle.Core.pdb trunk/nhibernate/lib/net/3.5/Castle.Core.xml Modified: trunk/nhibernate/lib/net/3.5/Castle.Core.dll =================================================================== (Binary files differ) Modified: trunk/nhibernate/lib/net/3.5/Castle.Core.pdb =================================================================== (Binary files differ) Modified: trunk/nhibernate/lib/net/3.5/Castle.Core.xml =================================================================== --- trunk/nhibernate/lib/net/3.5/Castle.Core.xml 2010-11-20 12:07:51 UTC (rev 5265) +++ trunk/nhibernate/lib/net/3.5/Castle.Core.xml 2010-11-20 13:12:25 UTC (rev 5266) @@ -1011,46 +1011,53 @@ </summary> <value></value> </member> - <member name="T:Castle.Components.DictionaryAdapter.AttributesUtil"> + <member name="T:Castle.Core.Internal.AttributesUtil"> <summary> - Helper class for retrieving attributes. + Helper class for retrieving attributes. </summary> </member> - <member name="M:Castle.Components.DictionaryAdapter.AttributesUtil.GetTypeAttribute``1(System.Type)"> + <member name="M:Castle.Core.Internal.AttributesUtil.GetAttribute``1(System.Reflection.ICustomAttributeProvider)"> <summary> - Gets the type attribute. + Gets the attribute. </summary> - <param name="type">The type.</param> - <returns>The type attribute.</returns> + <param name = "member">The member.</param> + <returns>The member attribute.</returns> </member> - <member name="M:Castle.Components.DictionaryAdapter.AttributesUtil.GetAttribute``1(System.Reflection.MemberInfo)"> + <member name="M:Castle.Core.Internal.AttributesUtil.GetAttributes``1(System.Reflection.ICustomAttributeProvider)"> <summary> - Gets the attribute. + Gets the attributes. Does not consider inherited attributes! </summary> - <param name="member">The member.</param> - <returns>The member attribute.</returns> + <param name = "member">The member.</param> + <returns>The member attributes.</returns> </member> - <member name="M:Castle.Components.DictionaryAdapter.AttributesUtil.GetTypeAttributes``1(System.Type)"> + <member name="M:Castle.Core.Internal.AttributesUtil.GetTypeAttribute``1(System.Type)"> <summary> - Gets the type attributes. + Gets the type attribute. </summary> - <param name="type">The type.</param> - <returns>The type attributes.</returns> + <param name = "type">The type.</param> + <returns>The type attribute.</returns> </member> - <member name="M:Castle.Components.DictionaryAdapter.AttributesUtil.GetAttributes``1(System.Reflection.MemberInfo)"> + <member name="M:Castle.Core.Internal.AttributesUtil.GetTypeAttributes``1(System.Type)"> <summary> - Gets the attributes. + Gets the type attributes. </summary> - <param name="member">The member.</param> - <returns>The member attributes.</returns> + <param name = "type">The type.</param> + <returns>The type attributes.</returns> </member> - <member name="M:Castle.Components.DictionaryAdapter.AttributesUtil.GetTypeConverter(System.Reflection.MemberInfo)"> + <member name="M:Castle.Core.Internal.AttributesUtil.GetTypeConverter(System.Reflection.MemberInfo)"> <summary> - Gets the type converter. + Gets the type converter. </summary> - <param name="member">The member.</param> + <param name = "member">The member.</param> <returns></returns> </member> + <member name="M:Castle.Core.Internal.AttributesUtil.HasAttribute``1(System.Reflection.ICustomAttributeProvider)"> + <summary> + Gets the attribute. + </summary> + <param name = "member">The member.</param> + <returns>The member attribute.</returns> + </member> <member name="T:Castle.Components.DictionaryAdapter.IDynamicValue`1"> <summary> Contract for typed dynamic value resolution. @@ -1088,11 +1095,11 @@ </member> <member name="M:Castle.DynamicProxy.IInvocation.GetConcreteMethod"> <summary> - Returns the concrete instantiation of the <see cref="P:Castle.DynamicProxy.IInvocation.Method"/>, with any generic + Returns the concrete instantiation of the <see cref="P:Castle.DynamicProxy.IInvocation.Method"/> on the proxy, with any generic parameters bound to real types. </summary> <returns> - The concrete instantiation of the <see cref="P:Castle.DynamicProxy.IInvocation.Method"/>, or the <see cref="P:Castle.DynamicProxy.IInvocation.Method"/> if + The concrete instantiation of the <see cref="P:Castle.DynamicProxy.IInvocation.Method"/> on the proxy, or the <see cref="P:Castle.DynamicProxy.IInvocation.Method"/> if not a generic method. </returns> <remarks>Can be slower than calling <see cref="P:Castle.DynamicProxy.IInvocation.Method"/>.</remarks> @@ -1101,10 +1108,11 @@ <summary> Returns the concrete instantiation of <see cref="P:Castle.DynamicProxy.IInvocation.MethodInvocationTarget"/>, with any generic parameters bound to real types. + For interface proxies, this will point to the <see cref="T:System.Reflection.MethodInfo"/> on the target class. </summary> <returns>The concrete instantiation of <see cref="P:Castle.DynamicProxy.IInvocation.MethodInvocationTarget"/>, or <see cref="P:Castle.DynamicProxy.IInvocation.MethodInvocationTarget"/> if not a generic method.</returns> - <remarks>Can be slower than calling <see cref="P:Castle.DynamicProxy.IInvocation.MethodInvocationTarget"/>.</remarks> + <remarks>In debug builds this can be slower than calling <see cref="P:Castle.DynamicProxy.IInvocation.MethodInvocationTarget"/>.</remarks> </member> <member name="M:Castle.DynamicProxy.IInvocation.Proceed"> <summary> @@ -1150,7 +1158,7 @@ </member> <member name="P:Castle.DynamicProxy.IInvocation.Method"> <summary> - Gets the <see cref="T:System.Reflection.MethodInfo"/> representing the method being invoked. + Gets the <see cref="T:System.Reflection.MethodInfo"/> representing the method being invoked on the proxy. </summary> <value>The <see cref="T:System.Reflection.MethodInfo"/> representing the method being invoked.</value> </member> @@ -1549,7 +1557,7 @@ <summary> Returns list of all unique interfaces implemented given types, including their base interfaces. </summary> - <param name="types"></param> + <param name = "types"></param> <returns></returns> </member> <member name="M:Castle.DynamicProxy.Generators.MetaEvent.#ctor(System.String,System.Type,System.Type,Castle.DynamicProxy.Generators.MetaMethod,Castle.DynamicProxy.Generators.MetaMethod,System.Reflection.EventAttributes)"> @@ -4390,7 +4398,7 @@ </summary> <param name="type">The <see cref="T:System.Type"/></param> <param name="defaultValue"> - The Default value returned if the convertion fails. + The Default value returned if the conversion fails. </param> <returns>The Value converted into the specified type.</returns> </member> @@ -4744,7 +4752,7 @@ </summary> <remarks> Implementors should return <c>true</c> - only if the given identificator is supported + only if the given identifier is supported by the resource factory </remarks> <param name="uri"></param> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2010-11-20 12:07:57
|
Revision: 5265 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5265&view=rev Author: fabiomaulo Date: 2010-11-20 12:07:51 +0000 (Sat, 20 Nov 2010) Log Message: ----------- actualized releasenotes for release Modified Paths: -------------- trunk/nhibernate/releasenotes.txt Modified: trunk/nhibernate/releasenotes.txt =================================================================== --- trunk/nhibernate/releasenotes.txt 2010-11-10 06:54:12 UTC (rev 5264) +++ trunk/nhibernate/releasenotes.txt 2010-11-20 12:07:51 UTC (rev 5265) @@ -1,6 +1,4 @@ -Build 3.0.0.CR1 -============================= -** Known BREAKING CHANGES from NH2.1.1.GA to NH3.0.0.CR1 +** Known BREAKING CHANGES from NH2.1.1.GA to NH3.0.0.GA ##### Design time ##### * [NH-2392] - ICompositeUserType.NullSafeSet method signature changed @@ -15,11 +13,15 @@ * [NH-2284] - Obsolete members removed * Related to [NH-2358]: DateTimeOffset type now works as a DateTimeOffset instead a "surrogate" of DateTime -Build 3.0.0.CR1 +Build 3.0.0.CR1 (rev5265) ============================= +** Bug + * [NH-1897] - boolean discriminator formulas broken on PostgreSQL + * [NH-2154] - Booleans may not be used in expression HQL in PostgreSQLDialect + ** Patch - * [NH-2392] - ICompositeUserType support for cases where not all parameters should be set (such as dynamic-update) + * [NH-2392] - ICompositeUserType support for cases where not all parameters should be set (such as dynamic-update) Build 3.0.0.Beta2 (rev5254) ============================= This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2010-11-10 06:54:19
|
Revision: 5264 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5264&view=rev Author: ricbrown Date: 2010-11-10 06:54:12 +0000 (Wed, 10 Nov 2010) Log Message: ----------- QueryOver - pushed Skip/Take up to base class so that paging can be applied to IQueryOver<T> as well as IQueryOver<T,U> Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs trunk/nhibernate/src/NHibernate/IQueryOver.cs Modified: trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2010-11-07 16:26:04 UTC (rev 5263) +++ trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2010-11-10 06:54:12 UTC (rev 5264) @@ -116,12 +116,12 @@ /// <returns></returns> public QueryOver<TRoot,TRoot> ToRowCountQuery() { - return + return (QueryOver<TRoot,TRoot>) Clone() + .Select(Projections.RowCount()) .ClearOrders() .Skip(0) - .Take(RowSelection.NoValue) - .Select(Projections.RowCount()); + .Take(RowSelection.NoValue); } /// <summary> @@ -130,12 +130,12 @@ /// <returns></returns> public QueryOver<TRoot,TRoot> ToRowCountInt64Query() { - return + return (QueryOver<TRoot,TRoot>) Clone() + .Select(Projections.RowCountInt64()) .ClearOrders() .Skip(0) - .Take(RowSelection.NoValue) - .Select(Projections.RowCountInt64()); + .Take(RowSelection.NoValue); } /// <summary> @@ -146,6 +146,42 @@ return new QueryOver<TRoot,TRoot>((CriteriaImpl)criteria.Clone()); } + public QueryOver<TRoot> ClearOrders() + { + criteria.ClearOrders(); + return this; + } + + public QueryOver<TRoot> Skip(int firstResult) + { + criteria.SetFirstResult(firstResult); + return this; + } + + public QueryOver<TRoot> Take(int maxResults) + { + criteria.SetMaxResults(maxResults); + return this; + } + + public QueryOver<TRoot> Cacheable() + { + criteria.SetCacheable(true); + return this; + } + + public QueryOver<TRoot> CacheMode(CacheMode cacheMode) + { + criteria.SetCacheMode(cacheMode); + return this; + } + + public QueryOver<TRoot> CacheRegion(string cacheRegion) + { + criteria.SetCacheRegion(cacheRegion); + return this; + } + /// <summary> /// Method to allow comparison of detached query in Lambda expression /// e.g., p => p.Name == myQuery.As<string> @@ -197,6 +233,24 @@ IQueryOver<TRoot,TRoot> IQueryOver<TRoot>.Clone() { return Clone(); } + IQueryOver<TRoot> IQueryOver<TRoot>.ClearOrders() + { return ClearOrders(); } + + IQueryOver<TRoot> IQueryOver<TRoot>.Skip(int firstResult) + { return Skip(firstResult); } + + IQueryOver<TRoot> IQueryOver<TRoot>.Take(int maxResults) + { return Take(maxResults); } + + IQueryOver<TRoot> IQueryOver<TRoot>.Cacheable() + { return Cacheable(); } + + IQueryOver<TRoot> IQueryOver<TRoot>.CacheMode(CacheMode cacheMode) + { return CacheMode(cacheMode); } + + IQueryOver<TRoot> IQueryOver<TRoot>.CacheRegion(string cacheRegion) + { return CacheRegion(cacheRegion); } + } /// <summary> @@ -364,48 +418,12 @@ return new QueryOverOrderBuilder<TRoot,TSubType>(this, path, true); } - public QueryOver<TRoot,TSubType> ClearOrders() - { - criteria.ClearOrders(); - return this; - } - public QueryOver<TRoot,TSubType> TransformUsing(IResultTransformer resultTransformer) { criteria.SetResultTransformer(resultTransformer); return this; } - public QueryOver<TRoot,TSubType> Skip(int firstResult) - { - criteria.SetFirstResult(firstResult); - return this; - } - - public QueryOver<TRoot,TSubType> Take(int maxResults) - { - criteria.SetMaxResults(maxResults); - return this; - } - - public QueryOver<TRoot,TSubType> Cacheable() - { - criteria.SetCacheable(true); - return this; - } - - public QueryOver<TRoot,TSubType> CacheMode(CacheMode cacheMode) - { - criteria.SetCacheMode(cacheMode); - return this; - } - - public QueryOver<TRoot,TSubType> CacheRegion(string cacheRegion) - { - criteria.SetCacheRegion(cacheRegion); - return this; - } - public QueryOverSubqueryBuilder<TRoot,TSubType> WithSubquery { get { return new QueryOverSubqueryBuilder<TRoot,TSubType>(this); } @@ -718,27 +736,9 @@ IQueryOverOrderBuilder<TRoot,TSubType> IQueryOver<TRoot,TSubType>.ThenByAlias(Expression<Func<object>> path) { return new IQueryOverOrderBuilder<TRoot,TSubType>(this, path, true); } - IQueryOver<TRoot,TSubType> IQueryOver<TRoot, TSubType>.ClearOrders() - { return ClearOrders(); } - IQueryOver<TRoot,TSubType> IQueryOver<TRoot,TSubType>.TransformUsing(IResultTransformer resultTransformer) { return TransformUsing(resultTransformer); } - IQueryOver<TRoot,TSubType> IQueryOver<TRoot,TSubType>.Skip(int firstResult) - { return Skip(firstResult); } - - IQueryOver<TRoot,TSubType> IQueryOver<TRoot,TSubType>.Take(int maxResults) - { return Take(maxResults); } - - IQueryOver<TRoot,TSubType> IQueryOver<TRoot,TSubType>.Cacheable() - { return Cacheable(); } - - IQueryOver<TRoot,TSubType> IQueryOver<TRoot,TSubType>.CacheMode(CacheMode cacheMode) - { return CacheMode(cacheMode); } - - IQueryOver<TRoot,TSubType> IQueryOver<TRoot,TSubType>.CacheRegion(string cacheRegion) - { return CacheRegion(cacheRegion); } - IQueryOverSubqueryBuilder<TRoot,TSubType> IQueryOver<TRoot,TSubType>.WithSubquery { get { return new IQueryOverSubqueryBuilder<TRoot,TSubType>(this); } } Modified: trunk/nhibernate/src/NHibernate/IQueryOver.cs =================================================================== --- trunk/nhibernate/src/NHibernate/IQueryOver.cs 2010-11-07 16:26:04 UTC (rev 5263) +++ trunk/nhibernate/src/NHibernate/IQueryOver.cs 2010-11-10 06:54:12 UTC (rev 5264) @@ -120,6 +120,40 @@ /// </summary> IQueryOver<TRoot,TRoot> Clone(); + /// <summary> + /// Clear all orders from the query. + /// </summary> + IQueryOver<TRoot> ClearOrders(); + + /// <summary> + /// Set the first result to be retrieved + /// </summary> + /// <param name="firstResult"></param> + IQueryOver<TRoot> Skip(int firstResult); + + /// <summary> + /// Set a limit upon the number of objects to be retrieved + /// </summary> + /// <param name="maxResults"></param> + IQueryOver<TRoot> Take(int maxResults); + + /// <summary> + /// Enable caching of this query result set + /// </summary> + IQueryOver<TRoot> Cacheable(); + + /// <summary> Override the cache mode for this particular query. </summary> + /// <param name="cacheMode">The cache mode to use. </param> + /// <returns> this (for method chaining) </returns> + IQueryOver<TRoot> CacheMode(CacheMode cacheMode); + + /// <summary> + /// Set the name of the cache region. + /// </summary> + /// <param name="cacheRegion">the name of a query cache region, or <see langword="null" /> + /// for the default query cache</param> + IQueryOver<TRoot> CacheRegion(string cacheRegion); + } /// <summary> @@ -301,45 +335,11 @@ IQueryOverOrderBuilder<TRoot,TSubType> ThenByAlias(Expression<Func<object>> path); /// <summary> - /// Clear all orders from the query. - /// </summary> - IQueryOver<TRoot, TSubType> ClearOrders(); - - /// <summary> /// Transform the results using the supplied IResultTransformer /// </summary> IQueryOver<TRoot,TSubType> TransformUsing(IResultTransformer resultTransformer); /// <summary> - /// Set the first result to be retrieved - /// </summary> - /// <param name="firstResult"></param> - IQueryOver<TRoot,TSubType> Skip(int firstResult); - - /// <summary> - /// Set a limit upon the number of objects to be retrieved - /// </summary> - /// <param name="maxResults"></param> - IQueryOver<TRoot,TSubType> Take(int maxResults); - - /// <summary> - /// Enable caching of this query result set - /// </summary> - IQueryOver<TRoot,TSubType> Cacheable(); - - /// <summary> Override the cache mode for this particular query. </summary> - /// <param name="cacheMode">The cache mode to use. </param> - /// <returns> this (for method chaining) </returns> - IQueryOver<TRoot,TSubType> CacheMode(CacheMode cacheMode); - - /// <summary> - /// Set the name of the cache region. - /// </summary> - /// <param name="cacheRegion">the name of a query cache region, or <see langword="null" /> - /// for the default query cache</param> - IQueryOver<TRoot,TSubType> CacheRegion(string cacheRegion); - - /// <summary> /// Add a subquery expression /// </summary> IQueryOverSubqueryBuilder<TRoot,TSubType> WithSubquery { get; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jul...@us...> - 2010-11-07 16:26:10
|
Revision: 5263 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5263&view=rev Author: julian-maughan Date: 2010-11-07 16:26:04 +0000 (Sun, 07 Nov 2010) Log Message: ----------- Changed projects to suppress CLS-compliance compiler warnings: CS3001-3005 (Debug and Release configurations). Improves visibility of more relevant warnings. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/NHibernate.csproj trunk/nhibernate/src/NHibernate.ByteCode.Castle/NHibernate.ByteCode.Castle.csproj trunk/nhibernate/src/NHibernate.ByteCode.Castle.Tests/NHibernate.ByteCode.Castle.Tests.csproj trunk/nhibernate/src/NHibernate.ByteCode.LinFu/NHibernate.ByteCode.LinFu.csproj trunk/nhibernate/src/NHibernate.ByteCode.LinFu.Tests/NHibernate.ByteCode.LinFu.Tests.csproj trunk/nhibernate/src/NHibernate.ByteCode.Spring/NHibernate.ByteCode.Spring.csproj trunk/nhibernate/src/NHibernate.ByteCode.Spring.Tests/NHibernate.ByteCode.Spring.Tests.csproj trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2010-11-07 15:52:07 UTC (rev 5262) +++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2010-11-07 16:26:04 UTC (rev 5263) @@ -30,7 +30,7 @@ <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> <DocumentationFile>bin\Debug-2.0\NHibernate.XML</DocumentationFile> - <NoWarn>1591</NoWarn> + <NoWarn>1591%3b3001%3b3002%3b3003%3b3004%3b3005</NoWarn> <WarningsAsErrors>1717;1574</WarningsAsErrors> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> @@ -42,6 +42,7 @@ <DefineConstants>TRACE;NET_2_0</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> + <NoWarn>3001%3b3002%3b3003%3b3004%3b3005</NoWarn> </PropertyGroup> <ItemGroup> <Reference Include="System" /> Modified: trunk/nhibernate/src/NHibernate.ByteCode.Castle/NHibernate.ByteCode.Castle.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.ByteCode.Castle/NHibernate.ByteCode.Castle.csproj 2010-11-07 15:52:07 UTC (rev 5262) +++ trunk/nhibernate/src/NHibernate.ByteCode.Castle/NHibernate.ByteCode.Castle.csproj 2010-11-07 16:26:04 UTC (rev 5263) @@ -23,6 +23,7 @@ <DefineConstants>DEBUG;TRACE</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> + <NoWarn>3001%3b3002%3b3003%3b3004%3b3005</NoWarn> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <DebugType>pdbonly</DebugType> @@ -31,6 +32,7 @@ <DefineConstants>TRACE</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> + <NoWarn>3001%3b3002%3b3003%3b3004%3b3005</NoWarn> </PropertyGroup> <ItemGroup> <Reference Include="Castle.Core, Version=1.1.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL"> Modified: trunk/nhibernate/src/NHibernate.ByteCode.Castle.Tests/NHibernate.ByteCode.Castle.Tests.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.ByteCode.Castle.Tests/NHibernate.ByteCode.Castle.Tests.csproj 2010-11-07 15:52:07 UTC (rev 5262) +++ trunk/nhibernate/src/NHibernate.ByteCode.Castle.Tests/NHibernate.ByteCode.Castle.Tests.csproj 2010-11-07 16:26:04 UTC (rev 5263) @@ -23,6 +23,7 @@ <DefineConstants>DEBUG;TRACE</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> + <NoWarn>3001%3b3002%3b3003%3b3004%3b3005</NoWarn> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <DebugType>pdbonly</DebugType> @@ -31,6 +32,7 @@ <DefineConstants>TRACE</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> + <NoWarn>3001%3b3002%3b3003%3b3004%3b3005</NoWarn> </PropertyGroup> <ItemGroup> <Reference Include="Castle.Core, Version=1.1.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL"> Modified: trunk/nhibernate/src/NHibernate.ByteCode.LinFu/NHibernate.ByteCode.LinFu.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.ByteCode.LinFu/NHibernate.ByteCode.LinFu.csproj 2010-11-07 15:52:07 UTC (rev 5262) +++ trunk/nhibernate/src/NHibernate.ByteCode.LinFu/NHibernate.ByteCode.LinFu.csproj 2010-11-07 16:26:04 UTC (rev 5263) @@ -23,6 +23,7 @@ <DefineConstants>DEBUG;TRACE</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> + <NoWarn>3001%3b3002%3b3003%3b3004%3b3005</NoWarn> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <DebugType>pdbonly</DebugType> @@ -31,6 +32,7 @@ <DefineConstants>TRACE</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> + <NoWarn>3001%3b3002%3b3003%3b3004%3b3005</NoWarn> </PropertyGroup> <ItemGroup> <Reference Include="System" /> Modified: trunk/nhibernate/src/NHibernate.ByteCode.LinFu.Tests/NHibernate.ByteCode.LinFu.Tests.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.ByteCode.LinFu.Tests/NHibernate.ByteCode.LinFu.Tests.csproj 2010-11-07 15:52:07 UTC (rev 5262) +++ trunk/nhibernate/src/NHibernate.ByteCode.LinFu.Tests/NHibernate.ByteCode.LinFu.Tests.csproj 2010-11-07 16:26:04 UTC (rev 5263) @@ -23,6 +23,7 @@ <DefineConstants>DEBUG;TRACE</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> + <NoWarn>3001%3b3002%3b3003%3b3004%3b3005</NoWarn> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <DebugType>pdbonly</DebugType> @@ -31,6 +32,7 @@ <DefineConstants>TRACE</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> + <NoWarn>3001%3b3002%3b3003%3b3004%3b3005</NoWarn> </PropertyGroup> <ItemGroup> <Reference Include="Iesi.Collections, Version=1.0.1.0, Culture=neutral, PublicKeyToken=aa95f207798dfdb4, processorArchitecture=MSIL"> Modified: trunk/nhibernate/src/NHibernate.ByteCode.Spring/NHibernate.ByteCode.Spring.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.ByteCode.Spring/NHibernate.ByteCode.Spring.csproj 2010-11-07 15:52:07 UTC (rev 5262) +++ trunk/nhibernate/src/NHibernate.ByteCode.Spring/NHibernate.ByteCode.Spring.csproj 2010-11-07 16:26:04 UTC (rev 5263) @@ -23,6 +23,7 @@ <DefineConstants>DEBUG;TRACE</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> + <NoWarn>3001%3b3002%3b3003%3b3004%3b3005</NoWarn> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <DebugType>pdbonly</DebugType> @@ -31,6 +32,7 @@ <DefineConstants>TRACE</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> + <NoWarn>3001%3b3002%3b3003%3b3004%3b3005</NoWarn> </PropertyGroup> <ItemGroup> <Reference Include="antlr.runtime, Version=2.7.6.2, Culture=neutral, PublicKeyToken=65e474d141e25e07, processorArchitecture=MSIL"> Modified: trunk/nhibernate/src/NHibernate.ByteCode.Spring.Tests/NHibernate.ByteCode.Spring.Tests.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.ByteCode.Spring.Tests/NHibernate.ByteCode.Spring.Tests.csproj 2010-11-07 15:52:07 UTC (rev 5262) +++ trunk/nhibernate/src/NHibernate.ByteCode.Spring.Tests/NHibernate.ByteCode.Spring.Tests.csproj 2010-11-07 16:26:04 UTC (rev 5263) @@ -23,6 +23,7 @@ <DefineConstants>DEBUG;TRACE</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> + <NoWarn>3001%3b3002%3b3003%3b3004%3b3005</NoWarn> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <DebugType>pdbonly</DebugType> @@ -31,6 +32,7 @@ <DefineConstants>TRACE</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> + <NoWarn>3001%3b3002%3b3003%3b3004%3b3005</NoWarn> </PropertyGroup> <ItemGroup> <Reference Include="antlr.runtime, Version=2.7.6.2, Culture=neutral, PublicKeyToken=65e474d141e25e07, processorArchitecture=MSIL"> Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-11-07 15:52:07 UTC (rev 5262) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-11-07 16:26:04 UTC (rev 5263) @@ -30,6 +30,7 @@ <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> <UseVSHostingProcess>false</UseVSHostingProcess> + <NoWarn>3001%3b3002%3b3003%3b3004%3b3005</NoWarn> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <DebugType>pdbonly</DebugType> @@ -41,6 +42,7 @@ <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> <UseVSHostingProcess>false</UseVSHostingProcess> + <NoWarn>3001%3b3002%3b3003%3b3004%3b3005</NoWarn> </PropertyGroup> <ItemGroup> <Reference Include="Antlr3.Runtime, Version=3.1.0.39271, Culture=neutral, PublicKeyToken=3a9cab8f8d22bfb7, processorArchitecture=MSIL"> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jul...@us...> - 2010-11-07 15:52:15
|
Revision: 5262 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5262&view=rev Author: julian-maughan Date: 2010-11-07 15:52:07 +0000 (Sun, 07 Nov 2010) Log Message: ----------- Refactor: Moved methods from TypeFactory to new class, TypeHelper (as-per Hibernate). Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Action/EntityUpdateAction.cs trunk/nhibernate/src/NHibernate/Cache/Entry/CacheEntry.cs trunk/nhibernate/src/NHibernate/Cache/StandardQueryCache.cs trunk/nhibernate/src/NHibernate/Engine/TwoPhaseLoad.cs trunk/nhibernate/src/NHibernate/Event/Default/AbstractReassociateEventListener.cs trunk/nhibernate/src/NHibernate/Event/Default/AbstractSaveEventListener.cs trunk/nhibernate/src/NHibernate/Event/Default/DefaultDeleteEventListener.cs trunk/nhibernate/src/NHibernate/Event/Default/DefaultLoadEventListener.cs trunk/nhibernate/src/NHibernate/Event/Default/DefaultMergeEventListener.cs trunk/nhibernate/src/NHibernate/Impl/MultipleQueriesCacheAssembler.cs trunk/nhibernate/src/NHibernate/NHibernate.csproj trunk/nhibernate/src/NHibernate/Persister/Entity/AbstractEntityPersister.cs trunk/nhibernate/src/NHibernate/Type/ComponentType.cs trunk/nhibernate/src/NHibernate/Type/TypeFactory.cs Added Paths: ----------- trunk/nhibernate/src/NHibernate/Type/TypeHelper.cs Modified: trunk/nhibernate/src/NHibernate/Action/EntityUpdateAction.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Action/EntityUpdateAction.cs 2010-11-07 15:51:01 UTC (rev 5261) +++ trunk/nhibernate/src/NHibernate/Action/EntityUpdateAction.cs 2010-11-07 15:52:07 UTC (rev 5262) @@ -90,7 +90,7 @@ // get the updated snapshot of the entity state by cloning current state; // it is safe to copy in place, since by this time no-one else (should have) // has a reference to the array - TypeFactory.DeepCopy(state, persister.PropertyTypes, persister.PropertyCheckability, state, Session); + TypeHelper.DeepCopy(state, persister.PropertyTypes, persister.PropertyCheckability, state, Session); if (persister.HasUpdateGeneratedProperties) { // this entity defines property generation, so process those generated Modified: trunk/nhibernate/src/NHibernate/Cache/Entry/CacheEntry.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Cache/Entry/CacheEntry.cs 2010-11-07 15:51:01 UTC (rev 5261) +++ trunk/nhibernate/src/NHibernate/Cache/Entry/CacheEntry.cs 2010-11-07 15:52:07 UTC (rev 5262) @@ -21,7 +21,7 @@ public CacheEntry(object[] state, IEntityPersister persister, bool unfetched, object version, ISessionImplementor session, object owner) { //disassembled state gets put in a new array (we write to cache by value!) - disassembledState = TypeFactory.Disassemble(state, persister.PropertyTypes, null, session, owner); + disassembledState = TypeHelper.Disassemble(state, persister.PropertyTypes, null, session, owner); subclass = persister.EntityName; lazyPropertiesAreUnfetched = unfetched || !persister.IsLazyPropertiesCacheable; this.version = version; @@ -76,7 +76,7 @@ IInterceptor interceptor, ISessionImplementor session) { //assembled state gets put in a new array (we read from cache by value!) - object[] assembledProps = TypeFactory.Assemble(values, persister.PropertyTypes, session, result); + object[] assembledProps = TypeHelper.Assemble(values, persister.PropertyTypes, session, result); //from h3.2 TODO: reuse the PreLoadEvent PreLoadEvent preLoadEvent = new PreLoadEvent((IEventSource) session); Modified: trunk/nhibernate/src/NHibernate/Cache/StandardQueryCache.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Cache/StandardQueryCache.cs 2010-11-07 15:51:01 UTC (rev 5261) +++ trunk/nhibernate/src/NHibernate/Cache/StandardQueryCache.cs 2010-11-07 15:52:07 UTC (rev 5262) @@ -83,7 +83,7 @@ } else { - cacheable.Add(TypeFactory.Disassemble((object[]) result[i], returnTypes, null, session, null)); + cacheable.Add(TypeHelper.Disassemble((object[]) result[i], returnTypes, null, session, null)); } } queryCache.Put(key, cacheable); @@ -123,7 +123,7 @@ } else { - TypeFactory.BeforeAssemble((object[])cacheable[i], returnTypes, session); + TypeHelper.BeforeAssemble((object[])cacheable[i], returnTypes, session); } } IList result = new List<object>(cacheable.Count - 1); @@ -137,7 +137,7 @@ } else { - result.Add(TypeFactory.Assemble((object[])cacheable[i], returnTypes, session, null)); + result.Add(TypeHelper.Assemble((object[])cacheable[i], returnTypes, session, null)); } } catch (UnresolvableObjectException) Modified: trunk/nhibernate/src/NHibernate/Engine/TwoPhaseLoad.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Engine/TwoPhaseLoad.cs 2010-11-07 15:51:01 UTC (rev 5261) +++ trunk/nhibernate/src/NHibernate/Engine/TwoPhaseLoad.cs 2010-11-07 15:52:07 UTC (rev 5262) @@ -128,7 +128,7 @@ else { //take a snapshot - TypeFactory.DeepCopy(hydratedState, persister.PropertyTypes, persister.PropertyUpdateability, hydratedState, session); + TypeHelper.DeepCopy(hydratedState, persister.PropertyTypes, persister.PropertyUpdateability, hydratedState, session); persistenceContext.SetEntryStatus(entityEntry, Status.Loaded); } Modified: trunk/nhibernate/src/NHibernate/Event/Default/AbstractReassociateEventListener.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Event/Default/AbstractReassociateEventListener.cs 2010-11-07 15:51:01 UTC (rev 5261) +++ trunk/nhibernate/src/NHibernate/Event/Default/AbstractReassociateEventListener.cs 2010-11-07 15:52:07 UTC (rev 5262) @@ -40,7 +40,7 @@ //get a snapshot object[] values = persister.GetPropertyValues(entity, source.EntityMode); - TypeFactory.DeepCopy(values, persister.PropertyTypes, persister.PropertyUpdateability, values, source); + TypeHelper.DeepCopy(values, persister.PropertyTypes, persister.PropertyUpdateability, values, source); object version = Versioning.GetVersion(values, persister); EntityEntry newEntry = source.PersistenceContext.AddEntity(entity, Status.Loaded, values, key, version, LockMode.None, true, persister, false, true); Modified: trunk/nhibernate/src/NHibernate/Event/Default/AbstractSaveEventListener.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Event/Default/AbstractSaveEventListener.cs 2010-11-07 15:51:01 UTC (rev 5261) +++ trunk/nhibernate/src/NHibernate/Event/Default/AbstractSaveEventListener.cs 2010-11-07 15:52:07 UTC (rev 5262) @@ -245,7 +245,7 @@ persister.SetPropertyValues(entity, values, source.EntityMode); } - TypeFactory.DeepCopy(values, types, persister.PropertyUpdateability, values, source); + TypeHelper.DeepCopy(values, types, persister.PropertyUpdateability, values, source); new ForeignKeys.Nullifier(entity, false, useIdentityColumn, source).NullifyTransientReferences(values, types); new Nullability(source).CheckNullability(values, persister, false); Modified: trunk/nhibernate/src/NHibernate/Event/Default/DefaultDeleteEventListener.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Event/Default/DefaultDeleteEventListener.cs 2010-11-07 15:51:01 UTC (rev 5261) +++ trunk/nhibernate/src/NHibernate/Event/Default/DefaultDeleteEventListener.cs 2010-11-07 15:52:07 UTC (rev 5262) @@ -221,7 +221,7 @@ // TypeFactory.deepCopy( currentState, propTypes, persister.getPropertyUpdateability(), deletedState, session ); bool[] copyability = new bool[propTypes.Length]; ArrayHelper.Fill(copyability, true); - TypeFactory.DeepCopy(currentState, propTypes, copyability, deletedState, session); + TypeHelper.DeepCopy(currentState, propTypes, copyability, deletedState, session); return deletedState; } Modified: trunk/nhibernate/src/NHibernate/Event/Default/DefaultLoadEventListener.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Event/Default/DefaultLoadEventListener.cs 2010-11-07 15:51:01 UTC (rev 5261) +++ trunk/nhibernate/src/NHibernate/Event/Default/DefaultLoadEventListener.cs 2010-11-07 15:52:07 UTC (rev 5262) @@ -463,7 +463,7 @@ IType[] types = subclassPersister.PropertyTypes; object[] values = entry.Assemble(result, id, subclassPersister, session.Interceptor, session); // intializes result by side-effect - TypeFactory.DeepCopy(values, types, subclassPersister.PropertyUpdateability, values, session); + TypeHelper.DeepCopy(values, types, subclassPersister.PropertyUpdateability, values, session); object version = Versioning.GetVersion(values, subclassPersister); if (log.IsDebugEnabled) Modified: trunk/nhibernate/src/NHibernate/Event/Default/DefaultMergeEventListener.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Event/Default/DefaultMergeEventListener.cs 2010-11-07 15:51:01 UTC (rev 5261) +++ trunk/nhibernate/src/NHibernate/Event/Default/DefaultMergeEventListener.cs 2010-11-07 15:52:07 UTC (rev 5262) @@ -350,7 +350,7 @@ protected virtual void CopyValues(IEntityPersister persister, object entity, object target, ISessionImplementor source, IDictionary copyCache) { object[] copiedValues = - TypeFactory.Replace(persister.GetPropertyValues(entity, source.EntityMode), + TypeHelper.Replace(persister.GetPropertyValues(entity, source.EntityMode), persister.GetPropertyValues(target, source.EntityMode), persister.PropertyTypes, source, target, copyCache); @@ -368,14 +368,14 @@ // replacement to associations types (value types were already replaced // during the first pass) copiedValues = - TypeFactory.ReplaceAssociations(persister.GetPropertyValues(entity, source.EntityMode), + TypeHelper.ReplaceAssociations(persister.GetPropertyValues(entity, source.EntityMode), persister.GetPropertyValues(target, source.EntityMode), persister.PropertyTypes, source, target, copyCache, foreignKeyDirection); } else { copiedValues = - TypeFactory.Replace(persister.GetPropertyValues(entity, source.EntityMode), + TypeHelper.Replace(persister.GetPropertyValues(entity, source.EntityMode), persister.GetPropertyValues(target, source.EntityMode), persister.PropertyTypes, source, target, copyCache, foreignKeyDirection); } Modified: trunk/nhibernate/src/NHibernate/Impl/MultipleQueriesCacheAssembler.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/MultipleQueriesCacheAssembler.cs 2010-11-07 15:51:01 UTC (rev 5261) +++ trunk/nhibernate/src/NHibernate/Impl/MultipleQueriesCacheAssembler.cs 2010-11-07 15:52:07 UTC (rev 5262) @@ -34,7 +34,7 @@ } else { - singleQueryCached.Add(TypeFactory.Disassemble((object[]) objToCache, assemblers, null, session, null)); + singleQueryCached.Add(TypeHelper.Disassemble((object[]) objToCache, assemblers, null, session, null)); } } cacheable.Add(singleQueryCached); @@ -59,7 +59,7 @@ } else { - queryResults.Add(TypeFactory.Assemble((object[]) fromCache, assemblers, session, owner)); + queryResults.Add(TypeHelper.Assemble((object[]) fromCache, assemblers, session, owner)); } } result.Add(queryResults); Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2010-11-07 15:51:01 UTC (rev 5261) +++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2010-11-07 15:52:07 UTC (rev 5262) @@ -412,6 +412,7 @@ <Compile Include="Type\TimeType.cs" /> <Compile Include="Type\TrueFalseType.cs" /> <Compile Include="Type\TypeFactory.cs" /> + <Compile Include="Type\TypeHelper.cs" /> <Compile Include="Type\TypeType.cs" /> <Compile Include="Type\UInt16Type.cs" /> <Compile Include="Type\UInt32Type.cs" /> Modified: trunk/nhibernate/src/NHibernate/Persister/Entity/AbstractEntityPersister.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Persister/Entity/AbstractEntityPersister.cs 2010-11-07 15:51:01 UTC (rev 5261) +++ trunk/nhibernate/src/NHibernate/Persister/Entity/AbstractEntityPersister.cs 2010-11-07 15:52:07 UTC (rev 5262) @@ -3515,7 +3515,7 @@ public virtual int[] FindDirty(object[] currentState, object[] previousState, object entity, ISessionImplementor session) { - int[] props = TypeFactory.FindDirty( + int[] props = TypeHelper.FindDirty( entityMetamodel.Properties, currentState, previousState, propertyColumnUpdateable, HasUninitializedLazyProperties(entity, session.EntityMode), session); if (props == null) @@ -3531,7 +3531,7 @@ public virtual int[] FindModified(object[] old, object[] current, object entity, ISessionImplementor session) { - int[] props = TypeFactory.FindModified( + int[] props = TypeHelper.FindModified( entityMetamodel.Properties, current, old, propertyColumnUpdateable, HasUninitializedLazyProperties(entity, session.EntityMode), session); if (props == null) { Modified: trunk/nhibernate/src/NHibernate/Type/ComponentType.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Type/ComponentType.cs 2010-11-07 15:51:01 UTC (rev 5261) +++ trunk/nhibernate/src/NHibernate/Type/ComponentType.cs 2010-11-07 15:52:07 UTC (rev 5262) @@ -376,7 +376,7 @@ object result = target ?? Instantiate(owner, session); EntityMode entityMode = session.EntityMode; - object[] values = TypeFactory.Replace(GetPropertyValues(original, entityMode), GetPropertyValues(result, entityMode), propertyTypes, session, owner, copiedAlready); + object[] values = TypeHelper.Replace(GetPropertyValues(original, entityMode), GetPropertyValues(result, entityMode), propertyTypes, session, owner, copiedAlready); SetPropertyValues(result, values, entityMode); return result; @@ -390,7 +390,7 @@ object result = target ?? Instantiate(owner, session); EntityMode entityMode = session.EntityMode; - object[] values = TypeFactory.Replace(GetPropertyValues(original, entityMode), GetPropertyValues(result, entityMode), propertyTypes, session, owner, copyCache, foreignKeyDirection); + object[] values = TypeHelper.Replace(GetPropertyValues(original, entityMode), GetPropertyValues(result, entityMode), propertyTypes, session, owner, copyCache, foreignKeyDirection); SetPropertyValues(result, values, entityMode); return result; Modified: trunk/nhibernate/src/NHibernate/Type/TypeFactory.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Type/TypeFactory.cs 2010-11-07 15:51:01 UTC (rev 5261) +++ trunk/nhibernate/src/NHibernate/Type/TypeFactory.cs 2010-11-07 15:52:07 UTC (rev 5262) @@ -8,10 +8,7 @@ using NHibernate.Bytecode; using NHibernate.Classic; using NHibernate.Engine; -using NHibernate.Intercept; -using NHibernate.Properties; using NHibernate.SqlTypes; -using NHibernate.Tuple; using NHibernate.UserTypes; using NHibernate.Util; using System.Runtime.CompilerServices; @@ -24,7 +21,7 @@ /// <remarks> /// Applications should use static methods and constants on NHibernate.NHibernateUtil if the default /// IType is good enough. For example, the TypeFactory should only be used when the String needs - /// to have a length of 300 instead of 255. At this point NHibernate.String does not get you the + /// to have a length of 300 instead of 255. At this point NHibernate.String does not get you the /// correct IType. Instead use TypeFactory.GetString(300) and keep a local variable that holds /// a reference to the IType. /// </remarks> @@ -44,11 +41,11 @@ private static readonly System.Type[] GenericCollectionSimpleSignature = new[] { typeof(string), typeof(string), typeof(bool) }; /* - * Maps the string representation of the type to the IType. The string + * Maps the string representation of the type to the IType. The string * representation is how the type will appear in the mapping file and in * name of the IType.Name. The list below provides a few examples of how * the Key/Value pair will be. - * + * * key -> value * "System.DateTime" -> instance of DateTimeType * "System.DateTime, fully assembly name" -> instance of DateTimeType @@ -86,7 +83,7 @@ RegisterType(nhibernateType, typeAliases); } - private static void RegisterType(System.Type systemType, IType nhibernateType, + private static void RegisterType(System.Type systemType, IType nhibernateType, IEnumerable<string> aliases, GetNullableTypeWithLength ctorLength) { var typeAliases = new List<string>(aliases); @@ -108,7 +105,7 @@ { var typeAliases = new List<string> { - systemType.FullName, + systemType.FullName, systemType.AssemblyQualifiedName, }; if (systemType.IsValueType) @@ -276,15 +273,15 @@ /// <returns>The Type of Classification</returns> /// <remarks> /// This parses through the string and makes the assumption that no class - /// name and no assembly name will contain the <c>"("</c>. + /// name and no assembly name will contain the <c>"("</c>. /// <para> - /// If it finds - /// the <c>"("</c> and then finds a <c>","</c> afterwards then it is a - /// <c>TypeClassification.PrecisionScale</c>. + /// If it finds + /// the <c>"("</c> and then finds a <c>","</c> afterwards then it is a + /// <c>TypeClassification.PrecisionScale</c>. /// </para> /// <para> /// If it finds the <c>"("</c> - /// and doesn't find a <c>","</c> afterwards, then it is a + /// and doesn't find a <c>","</c> afterwards, then it is a /// <c>TypeClassification.Length</c>. /// </para> /// <para> @@ -320,7 +317,7 @@ /// <summary> /// Given the name of a Hibernate type such as Decimal, Decimal(19,0) - /// , Int32, or even NHibernate.Type.DecimalType, NHibernate.Type.DecimalType(19,0), + /// , Int32, or even NHibernate.Type.DecimalType, NHibernate.Type.DecimalType(19,0), /// NHibernate.Type.Int32Type, then return an instance of NHibernate.Type.IType /// </summary> /// <param name="name">The name of the type.</param> @@ -341,7 +338,7 @@ } // if we get to here then the basic type with the length or precision/scale - // combination doesn't exists - so lets figure out which one we have and + // combination doesn't exists - so lets figure out which one we have and // invoke the appropriate delegate TypeClassification typeClassification = GetTypeClassification(name); @@ -430,8 +427,8 @@ } /// <summary> - /// Uses heuristics to deduce a NHibernate type given a string naming the - /// type. + /// Uses heuristics to deduce a NHibernate type given a string naming the + /// type. /// </summary> /// <param name="typeName"></param> /// <returns>An instance of <c>NHibernate.Type.IType</c></returns> @@ -439,9 +436,9 @@ /// When looking for the NHibernate type it will look in the cache of the Basic types first. /// If it doesn't find it in the cache then it uses the typeName to get a reference to the /// Class (Type in .NET). Once we get the reference to the .NET class we check to see if it - /// implements IType, ICompositeUserType, IUserType, ILifecycle (Association), or + /// implements IType, ICompositeUserType, IUserType, ILifecycle (Association), or /// IPersistentEnum. If none of those are implemented then we will serialize the Type to the - /// database using NHibernate.Type.SerializableType(typeName) + /// database using NHibernate.Type.SerializableType(typeName) /// </remarks> public static IType HeuristicType(string typeName) { @@ -449,8 +446,8 @@ } /// <summary> - /// Uses heuristics to deduce a NHibernate type given a string naming the - /// type. + /// Uses heuristics to deduce a NHibernate type given a string naming the + /// type. /// </summary> /// <param name="typeName">the type name</param> /// <param name="parameters">parameters for the type</param> @@ -563,7 +560,7 @@ /// <returns>A BinaryType</returns> /// <remarks> /// In addition to returning the BinaryType it will also ensure that it has - /// been added to the basicNameMap with the keys <c>Byte[](length)</c> and + /// been added to the basicNameMap with the keys <c>Byte[](length)</c> and /// <c>NHibernate.Type.BinaryType(length)</c>. /// </remarks> [MethodImpl(MethodImplOptions.Synchronized)] @@ -621,7 +618,7 @@ /// <para> /// In addition to returning the SerializableType it will also ensure that it has /// been added to the basicNameMap with the keys <c>Type.FullName</c> (the result - /// of <c>IType.Name</c> and <c>Type.AssemblyQualifiedName</c>. This is different + /// of <c>IType.Name</c> and <c>Type.AssemblyQualifiedName</c>. This is different /// from the other items put in the basicNameMap because it is uses the AQN and the /// FQN as opposed to the short name used in the maps and the FQN. /// </para> @@ -876,284 +873,6 @@ return (CollectionType)mi.Invoke(Instance.CollectionTypeFactory, new object[] { role, propertyRef, false }); } - /// <summary> Deep copy a series of values from one array to another... </summary> - /// <param name="values">The values to copy (the source) </param> - /// <param name="types">The value types </param> - /// <param name="copy">an array indicating which values to include in the copy </param> - /// <param name="target">The array into which to copy the values </param> - /// <param name="session">The originating session </param> - public static void DeepCopy(object[] values, IType[] types, bool[] copy, object[] target, ISessionImplementor session) - { - for (int i = 0; i < types.Length; i++) - { - if (copy[i]) - { - if (values[i] == LazyPropertyInitializer.UnfetchedProperty || values[i] == BackrefPropertyAccessor.Unknown) - { - target[i] = values[i]; - } - else - { - target[i] = types[i].DeepCopy(values[i], session.EntityMode, session.Factory); - } - } - } - } - - /// <summary> Apply the <see cref="ICacheAssembler.BeforeAssemble"/> operation across a series of values. </summary> - /// <param name="row">The values </param> - /// <param name="types">The value types </param> - /// <param name="session">The originating session </param> - public static void BeforeAssemble(object[] row, ICacheAssembler[] types, ISessionImplementor session) - { - for (int i = 0; i < types.Length; i++) - { - if (row[i] != LazyPropertyInitializer.UnfetchedProperty && row[i] != BackrefPropertyAccessor.Unknown) - { - types[i].BeforeAssemble(row[i], session); - } - } - } - /// <summary> - /// Determine if any of the given field values are dirty, - /// returning an array containing indexes of - /// the dirty fields or null if no fields are dirty. - /// </summary> - public static int[] FindDirty( - StandardProperty[] properties, - object[] x, - object[] y, - bool[][] includeColumns, - bool anyUninitializedProperties, - ISessionImplementor session) - { - int[] results = null; - int count = 0; - int span = properties.Length; - - for (int i = 0; i < span; i++) - { - bool dirty = - // TODO H3: x[ i ] != LazyPropertyInitializer.UnfetchedProperty && //x is the "current" state - properties[i].IsDirtyCheckable(anyUninitializedProperties) - && properties[i].Type.IsDirty(y[i], x[i], includeColumns[i], session); - - if (dirty) - { - if (results == null) - { - results = new int[span]; - } - results[count++] = i; - } - } - if (count == 0) - { - return null; - } - else - { - int[] trimmed = new int[count]; - System.Array.Copy(results, 0, trimmed, 0, count); - return trimmed; - } - } - - /// <summary> - /// Determine if any of the given field values are modified, - /// returning an array containing indexes of - /// the dirty fields or null if no fields are modified. - /// </summary> - public static int[] FindModified( - StandardProperty[] properties, - object[] x, - object[] y, - bool[][] includeColumns, - bool anyUninitializedProperties, - ISessionImplementor session) - { - int[] results = null; - int count = 0; - int span = properties.Length; - - for (int i = 0; i < span; i++) - { - bool dirty = - // TODO H3: x[ i ] != LazyPropertyInitializer.UnfetchedProperty && //x is the "current" state - properties[i].IsDirtyCheckable(anyUninitializedProperties) - && properties[i].Type.IsModified(y[i], x[i], includeColumns[i], session); - - if (dirty) - { - if (results == null) - { - results = new int[span]; - } - results[count++] = i; - } - } - if (count == 0) - { - return null; - } - else - { - int[] trimmed = new int[count]; - System.Array.Copy(results, 0, trimmed, 0, count); - return trimmed; - } - } - - /// <summary> - /// - /// </summary> - /// <param name="row"></param> - /// <param name="types"></param> - /// <param name="session"></param> - /// <param name="owner"></param> - /// <returns></returns> - public static object[] Assemble(object[] row, ICacheAssembler[] types, ISessionImplementor session, object owner) - { - object[] assembled = new object[row.Length]; - for (int i = 0; i < row.Length; i++) - { - assembled[i] = types[i].Assemble(row[i], session, owner); - } - return assembled; - } - - /// <summary> Apply the {@link Type#disassemble} operation across a series of values. </summary> - /// <param name="row">The values </param> - /// <param name="types">The value types </param> - /// <param name="nonCacheable">An array indicating which values to include in the disassembled state </param> - /// <param name="session">The originating session </param> - /// <param name="owner">The entity "owning" the values </param> - /// <returns> The disassembled state </returns> - public static object[] Disassemble(object[] row, ICacheAssembler[] types, bool[] nonCacheable, ISessionImplementor session, object owner) - { - object[] disassembled = new object[row.Length]; - for (int i = 0; i < row.Length; i++) - { - if (nonCacheable != null && nonCacheable[i]) - { - disassembled[i] = LazyPropertyInitializer.UnfetchedProperty; - } - else if (row[i] == LazyPropertyInitializer.UnfetchedProperty || row[i] == BackrefPropertyAccessor.Unknown) - { - disassembled[i] = row[i]; - } - else - { - disassembled[i] = types[i].Disassemble(row[i], session, owner); - } - } - return disassembled; - } - - - /// <summary> - /// Apply the <see cref="IType.Replace(object, object, ISessionImplementor, object, IDictionary)"/> operation across a series of values. - /// </summary> - /// <param name="original">The source of the state </param> - /// <param name="target">The target into which to replace the source values. </param> - /// <param name="types">The value types </param> - /// <param name="session">The originating session </param> - /// <param name="owner">The entity "owning" the values </param> - /// <param name="copiedAlready">Represent a cache of already replaced state </param> - /// <returns> The replaced state </returns> - public static object[] Replace(object[] original, object[] target, IType[] types, ISessionImplementor session, - object owner, IDictionary copiedAlready) - { - object[] copied = new object[original.Length]; - for (int i = 0; i < original.Length; i++) - { - copied[i] = types[i].Replace(original[i], target[i], session, owner, copiedAlready); - } - return copied; - } - - /// <summary> - /// Apply the <see cref="IType.Replace(object, object, ISessionImplementor, object, IDictionary, ForeignKeyDirection)"/> - /// operation across a series of values. - /// </summary> - /// <param name="original">The source of the state </param> - /// <param name="target">The target into which to replace the source values. </param> - /// <param name="types">The value types </param> - /// <param name="session">The originating session </param> - /// <param name="owner">The entity "owning" the values </param> - /// <param name="copyCache">A map representing a cache of already replaced state </param> - /// <param name="foreignKeyDirection">FK directionality to be applied to the replacement </param> - /// <returns> The replaced state </returns> - public static object[] Replace(object[] original, object[] target, IType[] types, - ISessionImplementor session, object owner, IDictionary copyCache, ForeignKeyDirection foreignKeyDirection) - { - object[] copied = new object[original.Length]; - for (int i = 0; i < types.Length; i++) - { - if (original[i] == LazyPropertyInitializer.UnfetchedProperty || original[i] == BackrefPropertyAccessor.Unknown) - { - copied[i] = target[i]; - } - else - copied[i] = types[i].Replace(original[i], target[i], session, owner, copyCache, foreignKeyDirection); - } - return copied; - } - - /// <summary> - /// Apply the <see cref="IType.Replace(object, object, ISessionImplementor, object, IDictionary, ForeignKeyDirection)"/> - /// operation across a series of values, as - /// long as the corresponding <see cref="IType"/> is an association. - /// </summary> - /// <param name="original">The source of the state </param> - /// <param name="target">The target into which to replace the source values. </param> - /// <param name="types">The value types </param> - /// <param name="session">The originating session </param> - /// <param name="owner">The entity "owning" the values </param> - /// <param name="copyCache">A map representing a cache of already replaced state </param> - /// <param name="foreignKeyDirection">FK directionality to be applied to the replacement </param> - /// <returns> The replaced state </returns> - /// <remarks> - /// If the corresponding type is a component type, then apply <see cref="ReplaceAssociations"/> - /// across the component subtypes but do not replace the component value itself. - /// </remarks> - public static object[] ReplaceAssociations(object[] original, object[] target, IType[] types, - ISessionImplementor session, object owner, IDictionary copyCache, ForeignKeyDirection foreignKeyDirection) - { - object[] copied = new object[original.Length]; - for (int i = 0; i < types.Length; i++) - { - if (original[i] == LazyPropertyInitializer.UnfetchedProperty || original[i] == BackrefPropertyAccessor.Unknown) - { - copied[i] = target[i]; - } - else if (types[i].IsComponentType) - { - // need to extract the component values and check for subtype replacements... - IAbstractComponentType componentType = (IAbstractComponentType)types[i]; - IType[] subtypes = componentType.Subtypes; - object[] origComponentValues = original[i] == null ? new object[subtypes.Length] : componentType.GetPropertyValues(original[i], session); - object[] targetComponentValues = target[i] == null ? new object[subtypes.Length] : componentType.GetPropertyValues(target[i], session); - - object[] componentCopy = ReplaceAssociations(origComponentValues, targetComponentValues, subtypes, session, null, copyCache, foreignKeyDirection); - - if (!componentType.IsAnyType && target[i] != null) - componentType.SetPropertyValues(target[i], componentCopy, session.EntityMode); - - copied[i] = target[i]; - } - else if (!types[i].IsAssociationType) - { - copied[i] = target[i]; - } - else - { - copied[i] = types[i].Replace(original[i], target[i], session, owner, copyCache, foreignKeyDirection); - } - } - return copied; - } - public static CollectionType CustomCollection(string typeName, IDictionary<string, string> typeParameters, string role, string propertyRef, bool embedded) { Added: trunk/nhibernate/src/NHibernate/Type/TypeHelper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Type/TypeHelper.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Type/TypeHelper.cs 2010-11-07 15:52:07 UTC (rev 5262) @@ -0,0 +1,304 @@ +using System; +using System.Collections; +using NHibernate.Engine; +using NHibernate.Intercept; +using NHibernate.Properties; +using NHibernate.Tuple; + +namespace NHibernate.Type +{ + /// <summary> + /// Collection of convenience methods relating to operations across arrays of types... + /// </summary> + public static class TypeHelper + { + /// <summary>Deep copy a series of values from one array to another</summary> + /// <param name="values">The values to copy (the source)</param> + /// <param name="types">The value types</param> + /// <param name="copy">An array indicating which values to include in the copy</param> + /// <param name="target">The array into which to copy the values</param> + /// <param name="session">The originating session</param> + public static void DeepCopy(object[] values, IType[] types, bool[] copy, object[] target, ISessionImplementor session) + { + for (int i = 0; i < types.Length; i++) + { + if (copy[i]) + { + if (values[i] == LazyPropertyInitializer.UnfetchedProperty || values[i] == BackrefPropertyAccessor.Unknown) + { + target[i] = values[i]; + } + else + { + target[i] = types[i].DeepCopy(values[i], session.EntityMode, session.Factory); + } + } + } + } + + /// <summary>Apply the <see cref="ICacheAssembler.BeforeAssemble" /> operation across a series of values.</summary> + /// <param name="row">The values</param> + /// <param name="types">The value types</param> + /// <param name="session">The originating session</param> + public static void BeforeAssemble(object[] row, ICacheAssembler[] types, ISessionImplementor session) + { + for (int i = 0; i < types.Length; i++) + { + if (row[i] != LazyPropertyInitializer.UnfetchedProperty && row[i] != BackrefPropertyAccessor.Unknown) + { + types[i].BeforeAssemble(row[i], session); + } + } + } + + /// <summary> + /// Apply the <see cref="ICacheAssembler.Assemble" /> operation across a series of values. + /// </summary> + /// <param name="row">The values</param> + /// <param name="types">The value types</param> + /// <param name="session">The originating session</param> + /// <param name="owner">The entity "owning" the values</param> + /// <returns></returns> + public static object[] Assemble(object[] row, ICacheAssembler[] types, ISessionImplementor session, object owner) + { + object[] assembled = new object[row.Length]; + for (int i = 0; i < row.Length; i++) + { + assembled[i] = types[i].Assemble(row[i], session, owner); + } + return assembled; + } + + /// <summary>Apply the <see cref="ICacheAssembler.Disassemble" /> operation across a series of values.</summary> + /// <param name="row">The values</param> + /// <param name="types">The value types</param> + /// <param name="nonCacheable">An array indicating which values to include in the disassembled state</param> + /// <param name="session">The originating session</param> + /// <param name="owner">The entity "owning" the values</param> + /// <returns> The disassembled state</returns> + public static object[] Disassemble(object[] row, ICacheAssembler[] types, bool[] nonCacheable, ISessionImplementor session, object owner) + { + object[] disassembled = new object[row.Length]; + for (int i = 0; i < row.Length; i++) + { + if (nonCacheable != null && nonCacheable[i]) + { + disassembled[i] = LazyPropertyInitializer.UnfetchedProperty; + } + else if (row[i] == LazyPropertyInitializer.UnfetchedProperty || row[i] == BackrefPropertyAccessor.Unknown) + { + disassembled[i] = row[i]; + } + else + { + disassembled[i] = types[i].Disassemble(row[i], session, owner); + } + } + return disassembled; + } + + /// <summary> + /// Apply the <see cref="IType.Replace(object, object, ISessionImplementor, object, IDictionary)" /> operation across a series of values. + /// </summary> + /// <param name="original">The source of the state</param> + /// <param name="target">The target into which to replace the source values.</param> + /// <param name="types">The value types</param> + /// <param name="session">The originating session</param> + /// <param name="owner">The entity "owning" the values</param> + /// <param name="copiedAlready">Represent a cache of already replaced state</param> + /// <returns> The replaced state</returns> + public static object[] Replace(object[] original, object[] target, IType[] types, ISessionImplementor session, + object owner, IDictionary copiedAlready) + { + object[] copied = new object[original.Length]; + for (int i = 0; i < original.Length; i++) + { + copied[i] = types[i].Replace(original[i], target[i], session, owner, copiedAlready); + } + return copied; + } + + /// <summary> + /// Apply the <see cref="IType.Replace(object, object, ISessionImplementor, object, IDictionary, ForeignKeyDirection)" /> + /// operation across a series of values. + /// </summary> + /// <param name="original">The source of the state</param> + /// <param name="target">The target into which to replace the source values.</param> + /// <param name="types">The value types</param> + /// <param name="session">The originating session</param> + /// <param name="owner">The entity "owning" the values</param> + /// <param name="copyCache">A map representing a cache of already replaced state</param> + /// <param name="foreignKeyDirection">FK directionality to be applied to the replacement</param> + /// <returns> The replaced state</returns> + public static object[] Replace(object[] original, object[] target, IType[] types, + ISessionImplementor session, object owner, IDictionary copyCache, ForeignKeyDirection foreignKeyDirection) + { + object[] copied = new object[original.Length]; + for (int i = 0; i < types.Length; i++) + { + if (original[i] == LazyPropertyInitializer.UnfetchedProperty || original[i] == BackrefPropertyAccessor.Unknown) + { + copied[i] = target[i]; + } + else + copied[i] = types[i].Replace(original[i], target[i], session, owner, copyCache, foreignKeyDirection); + } + return copied; + } + + /// <summary> + /// Apply the <see cref="IType.Replace(object, object, ISessionImplementor, object, IDictionary, ForeignKeyDirection)" /> + /// operation across a series of values, as long as the corresponding <see cref="IType"/> is an association. + /// </summary> + /// <param name="original">The source of the state</param> + /// <param name="target">The target into which to replace the source values.</param> + /// <param name="types">The value types</param> + /// <param name="session">The originating session</param> + /// <param name="owner">The entity "owning" the values</param> + /// <param name="copyCache">A map representing a cache of already replaced state</param> + /// <param name="foreignKeyDirection">FK directionality to be applied to the replacement</param> + /// <returns> The replaced state</returns> + /// <remarks> + /// If the corresponding type is a component type, then apply <see cref="ReplaceAssociations" /> + /// across the component subtypes but do not replace the component value itself. + /// </remarks> + public static object[] ReplaceAssociations(object[] original, object[] target, IType[] types, + ISessionImplementor session, object owner, IDictionary copyCache, ForeignKeyDirection foreignKeyDirection) + { + object[] copied = new object[original.Length]; + for (int i = 0; i < types.Length; i++) + { + if (original[i] == LazyPropertyInitializer.UnfetchedProperty || original[i] == BackrefPropertyAccessor.Unknown) + { + copied[i] = target[i]; + } + else if (types[i].IsComponentType) + { + // need to extract the component values and check for subtype replacements... + IAbstractComponentType componentType = (IAbstractComponentType)types[i]; + IType[] subtypes = componentType.Subtypes; + object[] origComponentValues = original[i] == null ? new object[subtypes.Length] : componentType.GetPropertyValues(original[i], session); + object[] targetComponentValues = target[i] == null ? new object[subtypes.Length] : componentType.GetPropertyValues(target[i], session); + + object[] componentCopy = ReplaceAssociations(origComponentValues, targetComponentValues, subtypes, session, null, copyCache, foreignKeyDirection); + + if (!componentType.IsAnyType && target[i] != null) + componentType.SetPropertyValues(target[i], componentCopy, session.EntityMode); + + copied[i] = target[i]; + } + else if (!types[i].IsAssociationType) + { + copied[i] = target[i]; + } + else + { + copied[i] = types[i].Replace(original[i], target[i], session, owner, copyCache, foreignKeyDirection); + } + } + return copied; + } + + /// <summary> + /// <para>Determine if any of the given field values are dirty, returning an array containing + /// indices of the dirty fields.</para> + /// <para>If it is determined that no fields are dirty, null is returned.</para> + /// </summary> + /// <param name="properties">The property definitions</param> + /// <param name="x">The current state of the entity</param> + /// <param name="y">The baseline state of the entity</param> + /// <param name="includeColumns">Columns to be included in the dirty checking, per property</param> + /// <param name="anyUninitializedProperties">Does the entity currently hold any uninitialized property values?</param> + /// <param name="session">The session from which the dirty check request originated.</param> + /// <returns>Array containing indices of the dirty properties, or null if no properties considered dirty.</returns> + public static int[] FindDirty(StandardProperty[] properties, + object[] currentState, + object[] previousState, + bool[][] includeColumns, + bool anyUninitializedProperties, + ISessionImplementor session) + { + int[] results = null; + int count = 0; + int span = properties.Length; + + for (int i = 0; i < span; i++) + { + bool dirty = + // TODO H3: x[ i ] != LazyPropertyInitializer.UnfetchedProperty && //x is the "current" state + properties[i].IsDirtyCheckable(anyUninitializedProperties) + && properties[i].Type.IsDirty(previousState[i], currentState[i], includeColumns[i], session); + + if (dirty) + { + if (results == null) + { + results = new int[span]; + } + results[count++] = i; + } + } + if (count == 0) + { + return null; + } + else + { + int[] trimmed = new int[count]; + System.Array.Copy(results, 0, trimmed, 0, count); + return trimmed; + } + } + + /// <summary> + /// <para>Determine if any of the given field values are modified, returning an array containing + /// indices of the modified fields.</para> + /// <para>If it is determined that no fields are dirty, null is returned.</para> + /// </summary> + /// <param name="properties">The property definitions</param> + /// <param name="x">The current state of the entity</param> + /// <param name="y">The baseline state of the entity</param> + /// <param name="includeColumns">Columns to be included in the mod checking, per property</param> + /// <param name="anyUninitializedProperties">Does the entity currently hold any uninitialized property values?</param> + /// <param name="session">The session from which the dirty check request originated.</param> + /// <returns>Array containing indices of the modified properties, or null if no properties considered modified.</returns> + public static int[] FindModified(StandardProperty[] properties, + object[] currentState, + object[] previousState, + bool[][] includeColumns, + bool anyUninitializedProperties, + ISessionImplementor session) + { + int[] results = null; + int count = 0; + int span = properties.Length; + + for (int i = 0; i < span; i++) + { + bool dirty = + // TODO H3: x[ i ] != LazyPropertyInitializer.UnfetchedProperty && //x is the "current" state + properties[i].IsDirtyCheckable(anyUninitializedProperties) + && properties[i].Type.IsModified(previousState[i], currentState[i], includeColumns[i], session); + + if (dirty) + { + if (results == null) + { + results = new int[span]; + } + results[count++] = i; + } + } + if (count == 0) + { + return null; + } + else + { + int[] trimmed = new int[count]; + System.Array.Copy(results, 0, trimmed, 0, count); + return trimmed; + } + } + } +} \ 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: <jul...@us...> - 2010-11-07 15:51:07
|
Revision: 5261 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5261&view=rev Author: julian-maughan Date: 2010-11-07 15:51:01 +0000 (Sun, 07 Nov 2010) Log Message: ----------- Issue NH-2392 incorrectly described as an Improvement. Changed to Patch. Modified Paths: -------------- trunk/nhibernate/releasenotes.txt Modified: trunk/nhibernate/releasenotes.txt =================================================================== --- trunk/nhibernate/releasenotes.txt 2010-11-07 13:37:31 UTC (rev 5260) +++ trunk/nhibernate/releasenotes.txt 2010-11-07 15:51:01 UTC (rev 5261) @@ -18,7 +18,7 @@ Build 3.0.0.CR1 ============================= -** Improvement +** Patch * [NH-2392] - ICompositeUserType support for cases where not all parameters should be set (such as dynamic-update) Build 3.0.0.Beta2 (rev5254) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2010-11-07 13:37:38
|
Revision: 5260 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5260&view=rev Author: ricbrown Date: 2010-11-07 13:37:31 +0000 (Sun, 07 Nov 2010) Log Message: ----------- QueryOver - added missing overload to allow private property access to order-by Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverOrderBuilder.cs trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs trunk/nhibernate/src/NHibernate/IQueryOver.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs Modified: trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverOrderBuilder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverOrderBuilder.cs 2010-11-02 11:59:09 UTC (rev 5259) +++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverOrderBuilder.cs 2010-11-07 13:37:31 UTC (rev 5260) @@ -18,6 +18,9 @@ public QueryOverOrderBuilder(QueryOver<TRoot,TSubType> root, Expression<Func<object>> path, bool isAlias) : base(root, path, isAlias) {} + public QueryOverOrderBuilder(QueryOver<TRoot,TSubType> root, IProjection projection) : base(root, projection) + {} + } public class IQueryOverOrderBuilder<TRoot,TSubType> : QueryOverOrderBuilderBase<IQueryOver<TRoot,TSubType>, TRoot, TSubType> @@ -29,6 +32,9 @@ public IQueryOverOrderBuilder(IQueryOver<TRoot,TSubType> root, Expression<Func<object>> path, bool isAlias) : base(root, path, isAlias) {} + public IQueryOverOrderBuilder(IQueryOver<TRoot,TSubType> root, IProjection projection) : base(root, projection) + {} + } public class QueryOverOrderBuilderBase<TReturn, TRoot, TSubType> where TReturn : IQueryOver<TRoot, TSubType> @@ -37,6 +43,7 @@ protected TReturn root; protected LambdaExpression path; protected bool isAlias; + protected IProjection projection; protected QueryOverOrderBuilderBase(TReturn root, Expression<Func<TSubType, object>> path) { @@ -52,11 +59,25 @@ this.isAlias = isAlias; } + protected QueryOverOrderBuilderBase(TReturn root, IProjection projection) + { + this.root = root; + this.projection = projection; + } + + private void AddOrder(Func<string, Order> orderStringDelegate, Func<IProjection, Order> orderDelegate) + { + if (projection != null) + root.UnderlyingCriteria.AddOrder(orderDelegate(projection)); + else + root.UnderlyingCriteria.AddOrder(ExpressionProcessor.ProcessOrder(path, orderStringDelegate, isAlias)); + } + public TReturn Asc { get { - this.root.UnderlyingCriteria.AddOrder(ExpressionProcessor.ProcessOrder(path, Order.Asc, isAlias)); + AddOrder(Order.Asc, Order.Asc); return this.root; } } @@ -65,7 +86,7 @@ { get { - this.root.UnderlyingCriteria.AddOrder(ExpressionProcessor.ProcessOrder(path, Order.Desc, isAlias)); + AddOrder(Order.Desc, Order.Desc); return this.root; } } Modified: trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2010-11-02 11:59:09 UTC (rev 5259) +++ trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2010-11-07 13:37:31 UTC (rev 5260) @@ -334,6 +334,11 @@ return new QueryOverOrderBuilder<TRoot,TSubType>(this, path, false); } + public QueryOverOrderBuilder<TRoot,TSubType> OrderBy(IProjection projection) + { + return new QueryOverOrderBuilder<TRoot,TSubType>(this, projection); + } + public QueryOverOrderBuilder<TRoot,TSubType> OrderByAlias(Expression<Func<object>> path) { return new QueryOverOrderBuilder<TRoot,TSubType>(this, path, true); @@ -349,6 +354,11 @@ return new QueryOverOrderBuilder<TRoot,TSubType>(this, path, false); } + public QueryOverOrderBuilder<TRoot,TSubType> ThenBy(IProjection projection) + { + return new QueryOverOrderBuilder<TRoot,TSubType>(this, projection); + } + public QueryOverOrderBuilder<TRoot,TSubType> ThenByAlias(Expression<Func<object>> path) { return new QueryOverOrderBuilder<TRoot,TSubType>(this, path, true); @@ -690,6 +700,9 @@ IQueryOverOrderBuilder<TRoot,TSubType> IQueryOver<TRoot,TSubType>.OrderBy(Expression<Func<object>> path) { return new IQueryOverOrderBuilder<TRoot,TSubType>(this, path, false); } + IQueryOverOrderBuilder<TRoot,TSubType> IQueryOver<TRoot,TSubType>.OrderBy(IProjection projection) + { return new IQueryOverOrderBuilder<TRoot,TSubType>(this, projection); } + IQueryOverOrderBuilder<TRoot,TSubType> IQueryOver<TRoot,TSubType>.OrderByAlias(Expression<Func<object>> path) { return new IQueryOverOrderBuilder<TRoot,TSubType>(this, path, true); } @@ -699,6 +712,9 @@ IQueryOverOrderBuilder<TRoot,TSubType> IQueryOver<TRoot,TSubType>.ThenBy(Expression<Func<object>> path) { return new IQueryOverOrderBuilder<TRoot,TSubType>(this, path, false); } + IQueryOverOrderBuilder<TRoot,TSubType> IQueryOver<TRoot,TSubType>.ThenBy(IProjection projection) + { return new IQueryOverOrderBuilder<TRoot,TSubType>(this, projection); } + IQueryOverOrderBuilder<TRoot,TSubType> IQueryOver<TRoot,TSubType>.ThenByAlias(Expression<Func<object>> path) { return new IQueryOverOrderBuilder<TRoot,TSubType>(this, path, true); } Modified: trunk/nhibernate/src/NHibernate/IQueryOver.cs =================================================================== --- trunk/nhibernate/src/NHibernate/IQueryOver.cs 2010-11-02 11:59:09 UTC (rev 5259) +++ trunk/nhibernate/src/NHibernate/IQueryOver.cs 2010-11-07 13:37:31 UTC (rev 5260) @@ -263,6 +263,11 @@ IQueryOverOrderBuilder<TRoot,TSubType> OrderBy(Expression<Func<object>> path); /// <summary> + /// Order by arbitrary IProjection (e.g., to allow protected member access) + /// </summary> + IQueryOverOrderBuilder<TRoot,TSubType> OrderBy(IProjection projection); + + /// <summary> /// Add order for an aliased projection expressed as a lambda expression /// </summary> /// <param name="path">Lambda expression</param> @@ -284,6 +289,11 @@ IQueryOverOrderBuilder<TRoot,TSubType> ThenBy(Expression<Func<object>> path); /// <summary> + /// Order by arbitrary IProjection (e.g., to allow protected member access) + /// </summary> + IQueryOverOrderBuilder<TRoot,TSubType> ThenBy(IProjection projection); + + /// <summary> /// Add order for an aliased projection expressed as a lambda expression /// </summary> /// <param name="path">Lambda expression</param> Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs 2010-11-02 11:59:09 UTC (rev 5259) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs 2010-11-07 13:37:31 UTC (rev 5260) @@ -164,13 +164,15 @@ CreateTestCriteria(typeof(Person)) .SetProjection(Projections.Property("Name")) .Add(Restrictions.Eq("Name", "test name")) - .Add(Restrictions.Not(Restrictions.Eq("Name", "not test name"))); + .Add(Restrictions.Not(Restrictions.Eq("Name", "not test name"))) + .AddOrder(Order.Desc(Projections.Property("Name"))); IQueryOver<Person> actual = CreateTestQueryOver<Person>() .Select(Projections.Property("Name")) .Where(Restrictions.Eq("Name", "test name")) - .And(Restrictions.Not(Restrictions.Eq("Name", "not test name"))); + .And(Restrictions.Not(Restrictions.Eq("Name", "not test name"))) + .OrderBy(Projections.Property("Name")).Desc; AssertCriteriaAreEqual(expected, actual); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jul...@us...> - 2010-11-02 11:59:18
|
Revision: 5259 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5259&view=rev Author: julian-maughan Date: 2010-11-02 11:59:09 +0000 (Tue, 02 Nov 2010) Log Message: ----------- Change to ICompositeUserType.NullSafeSet to cater for cases where not all parameters should be set (such as dynamic-update). Contributed by Patrick Earl (ref. NH-2392) Modified Paths: -------------- trunk/nhibernate/releasenotes.txt trunk/nhibernate/src/NHibernate/Type/CompositeCustomType.cs trunk/nhibernate/src/NHibernate/UserTypes/ICompositeUserType.cs trunk/nhibernate/src/NHibernate.DomainModel/DoubleStringType.cs trunk/nhibernate/src/NHibernate.DomainModel/MultiplicityType.cs trunk/nhibernate/src/NHibernate.DomainModel/NHibernate.DomainModel.csproj trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1763/EmptyStringUserType.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2324/CompositeUserType.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2392/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2392/A.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2392/Fixture.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2392/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2392/PhoneNumber.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2392/PhoneNumberUserType.cs Modified: trunk/nhibernate/releasenotes.txt =================================================================== --- trunk/nhibernate/releasenotes.txt 2010-11-02 11:48:40 UTC (rev 5258) +++ trunk/nhibernate/releasenotes.txt 2010-11-02 11:59:09 UTC (rev 5259) @@ -2,6 +2,9 @@ ============================= ** Known BREAKING CHANGES from NH2.1.1.GA to NH3.0.0.CR1 + ##### Design time ##### + * [NH-2392] - ICompositeUserType.NullSafeSet method signature changed + ##### Run time ##### * [NH-2199] - null values in maps/dictionaries are no longer silenty ignored/deleted * [NH-1894] - SybaseAnywhereDialect has been removed, and replaced with SybaseASA9Dialect. @@ -15,6 +18,8 @@ Build 3.0.0.CR1 ============================= +** Improvement + * [NH-2392] - ICompositeUserType support for cases where not all parameters should be set (such as dynamic-update) Build 3.0.0.Beta2 (rev5254) ============================= Modified: trunk/nhibernate/src/NHibernate/Type/CompositeCustomType.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Type/CompositeCustomType.cs 2010-11-02 11:48:40 UTC (rev 5258) +++ trunk/nhibernate/src/NHibernate/Type/CompositeCustomType.cs 2010-11-02 11:59:09 UTC (rev 5259) @@ -1,6 +1,7 @@ using System; using System.Collections; using System.Data; +using System.Linq; using System.Reflection; using System.Xml; @@ -11,9 +12,6 @@ namespace NHibernate.Type { - /// <summary> - /// Summary description for CompositeCustomType. - /// </summary> [Serializable] public class CompositeCustomType : AbstractType, IAbstractComponentType { @@ -51,24 +49,16 @@ } } - /// <summary></summary> public virtual IType[] Subtypes { get { return userType.PropertyTypes; } } - /// <summary></summary> public virtual string[] PropertyNames { get { return userType.PropertyNames; } } - /// <summary> - /// - /// </summary> - /// <param name="component"></param> - /// <param name="session"></param> - /// <returns></returns> public virtual object[] GetPropertyValues(object component, ISessionImplementor session) { return GetPropertyValues(component, session.EntityMode); @@ -101,11 +91,6 @@ return userType.GetPropertyValue(component, i); } - /// <summary> - /// - /// </summary> - /// <param name="i"></param> - /// <returns></returns> public virtual CascadeStyle GetCascadeStyle(int i) { return CascadeStyle.None; @@ -121,21 +106,12 @@ get { return false; } } - /// <summary></summary> public override bool IsComponentType { get { return true; } } - /// <summary> - /// - /// </summary> - /// <param name="cached"></param> - /// <param name="session"></param> - /// <param name="owner"></param> - /// <returns></returns> - public override object Assemble(object cached, ISessionImplementor session, - object owner) + public override object Assemble(object cached, ISessionImplementor session, object owner) { return userType.Assemble(cached, session, owner); } @@ -150,11 +126,6 @@ return userType.Disassemble(value, session); } - /// <summary> - /// - /// </summary> - /// <param name="mapping"></param> - /// <returns></returns> public override int GetColumnSpan(IMapping mapping) { IType[] types = userType.PropertyTypes; @@ -166,45 +137,26 @@ return n; } - /// <summary></summary> public override string Name { get { return name; } } - /// <summary></summary> public override System.Type ReturnedClass { get { return userType.ReturnedClass; } } - /// <summary></summary> public override bool IsMutable { get { return userType.IsMutable; } } - /// <summary> - /// - /// </summary> - /// <param name="rs"></param> - /// <param name="name"></param> - /// <param name="session"></param> - /// <param name="owner"></param> - /// <returns></returns> public override object NullSafeGet(IDataReader rs, string name, ISessionImplementor session, object owner) { return userType.NullSafeGet(rs, new string[] {name}, session, owner); } - /// <summary> - /// - /// </summary> - /// <param name="rs"></param> - /// <param name="names"></param> - /// <param name="session"></param> - /// <param name="owner"></param> - /// <returns></returns> public override object NullSafeGet(IDataReader rs, string[] names, ISessionImplementor session, object owner) { return userType.NullSafeGet(rs, names, session, owner); @@ -212,19 +164,15 @@ public override void NullSafeSet(IDbCommand st, object value, int index, bool[] settable, ISessionImplementor session) { - userType.NullSafeSet(st, value, index, session); + userType.NullSafeSet(st, value, index, settable, session); } public override void NullSafeSet(IDbCommand cmd, object value, int index, ISessionImplementor session) { - userType.NullSafeSet(cmd, value, index, session); + bool[] settable = Enumerable.Repeat(true, GetColumnSpan(session.Factory)).ToArray(); + userType.NullSafeSet(cmd, value, index, settable, session); } - /// <summary> - /// - /// </summary> - /// <param name="mapping"></param> - /// <returns></returns> public override SqlType[] SqlTypes(IMapping mapping) { IType[] types = userType.PropertyTypes; @@ -241,12 +189,6 @@ return result; } - /// <summary> - /// - /// </summary> - /// <param name="value"></param> - /// <param name="factory"></param> - /// <returns></returns> public override string ToLoggableString(object value, ISessionFactoryImplementor factory) { return value == null ? "null" : value.ToString(); @@ -277,8 +219,7 @@ get { return null; } } - public override object Replace(object original, object current, ISessionImplementor session, object owner, - IDictionary copiedAlready) + public override object Replace(object original, object current, ISessionImplementor session, object owner, IDictionary copiedAlready) { return userType.Replace(original, current, session, owner); } Modified: trunk/nhibernate/src/NHibernate/UserTypes/ICompositeUserType.cs =================================================================== --- trunk/nhibernate/src/NHibernate/UserTypes/ICompositeUserType.cs 2010-11-02 11:48:40 UTC (rev 5258) +++ trunk/nhibernate/src/NHibernate/UserTypes/ICompositeUserType.cs 2010-11-02 11:59:09 UTC (rev 5259) @@ -9,23 +9,23 @@ /// A UserType that may be dereferenced in a query. /// This interface allows a custom type to define "properties". /// These need not necessarily correspond to physical .NET style properties. - /// - /// A ICompositeUserType may be used in almost every way + /// + /// A ICompositeUserType may be used in almost every way /// that a component may be used. It may even contain many-to-one /// associations. - /// + /// /// Implementors must be immutable and must declare a public /// default constructor. - /// + /// /// Unlike UserType, cacheability does not depend upon - /// serializability. Instead, Assemble() and + /// serializability. Instead, Assemble() and /// Disassemble() provide conversion to/from a cacheable /// representation. /// </summary> public interface ICompositeUserType { /// <summary> - /// Get the "property names" that may be used in a query. + /// Get the "property names" that may be used in a query. /// </summary> string[] PropertyNames { get; } @@ -80,16 +80,18 @@ /// <returns></returns> object NullSafeGet(IDataReader dr, string[] names, ISessionImplementor session, object owner); - /// <summary> - /// Write an instance of the mapped class to a prepared statement. - /// Implementors should handle possibility of null values. - /// A multi-column type should be written to parameters starting from index. - /// </summary> - /// <param name="cmd"></param> - /// <param name="value"></param> - /// <param name="index"></param> - /// <param name="session"></param> - void NullSafeSet(IDbCommand cmd, object value, int index, ISessionImplementor session); + /// <summary> + /// Write an instance of the mapped class to a prepared statement. + /// Implementors should handle possibility of null values. + /// A multi-column type should be written to parameters starting from index. + /// If a property is not settable, skip it and don't increment the index. + /// </summary> + /// <param name="cmd"></param> + /// <param name="value"></param> + /// <param name="index"></param> + /// <param name="settable"></param> + /// <param name="session"></param> + void NullSafeSet(IDbCommand cmd, object value, int index, bool[] settable, ISessionImplementor session); /// <summary> /// Return a deep copy of the persistent state, stopping at entities and at collections. @@ -128,7 +130,7 @@ /// with a new (original) value from the detached entity we are merging. For immutable /// objects, or null values, it is safe to simply return the first parameter. For /// mutable objects, it is safe to return a copy of the first parameter. However, since - /// composite user types often define component values, it might make sense to recursively + /// composite user types often define component values, it might make sense to recursively /// replace component values in the target object. /// </summary> object Replace(object original, object target, ISessionImplementor session, object owner); Modified: trunk/nhibernate/src/NHibernate.DomainModel/DoubleStringType.cs =================================================================== --- trunk/nhibernate/src/NHibernate.DomainModel/DoubleStringType.cs 2010-11-02 11:48:40 UTC (rev 5258) +++ trunk/nhibernate/src/NHibernate.DomainModel/DoubleStringType.cs 2010-11-02 11:59:09 UTC (rev 5259) @@ -58,12 +58,12 @@ } - public void NullSafeSet(IDbCommand st, Object value, int index, ISessionImplementor session) + public void NullSafeSet(IDbCommand st, Object value, int index, bool[] settable, ISessionImplementor session) { string[] strings = (value == null) ? new string[2] : (string[]) value; - NHibernateUtil.String.NullSafeSet(st, strings[0], index, session); - NHibernateUtil.String.NullSafeSet(st, strings[1], index + 1, session); + if (settable[0]) NHibernateUtil.String.NullSafeSet(st, strings[0], index++, session); + if (settable[1]) NHibernateUtil.String.NullSafeSet(st, strings[1], index, session); } public string[] PropertyNames Modified: trunk/nhibernate/src/NHibernate.DomainModel/MultiplicityType.cs =================================================================== --- trunk/nhibernate/src/NHibernate.DomainModel/MultiplicityType.cs 2010-11-02 11:48:40 UTC (rev 5258) +++ trunk/nhibernate/src/NHibernate.DomainModel/MultiplicityType.cs 2010-11-02 11:59:09 UTC (rev 5259) @@ -1,6 +1,6 @@ using System; using System.Data; - +using System.Linq; using NHibernate.Engine; using NHibernate.Type; using NHibernate.UserTypes; @@ -84,7 +84,7 @@ return m; } - public void NullSafeSet(IDbCommand st, Object value, int index, ISessionImplementor session) + public void NullSafeSet(IDbCommand st, Object value, int index, bool[] settable, ISessionImplementor session) { Multiplicity o = (Multiplicity) value; GlarchProxy g; @@ -99,8 +99,8 @@ g = o.glarch; c = o.count; } - NHibernateUtil.Int32.NullSafeSet(st, c, index, session); - NHibernateUtil.Entity(typeof(Glarch)).NullSafeSet(st, g, index + 1, session); + if (settable[0]) NHibernateUtil.Int32.NullSafeSet(st, c, index, session); + NHibernateUtil.Entity(typeof(Glarch)).NullSafeSet(st, g, index + 1, settable.Skip(1).ToArray(), session); } public object DeepCopy(object value) Modified: trunk/nhibernate/src/NHibernate.DomainModel/NHibernate.DomainModel.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.DomainModel/NHibernate.DomainModel.csproj 2010-11-02 11:48:40 UTC (rev 5258) +++ trunk/nhibernate/src/NHibernate.DomainModel/NHibernate.DomainModel.csproj 2010-11-02 11:59:09 UTC (rev 5259) @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5"> <PropertyGroup> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> @@ -40,6 +40,9 @@ </PropertyGroup> <ItemGroup> <Reference Include="System" /> + <Reference Include="System.Core"> + <RequiredTargetFramework>3.5</RequiredTargetFramework> + </Reference> <Reference Include="System.Data" /> <Reference Include="System.Xml" /> <Reference Include="Iesi.Collections, Version=1.0.1.0, Culture=neutral, PublicKeyToken=aa95f207798dfdb4"> Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1763/EmptyStringUserType.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1763/EmptyStringUserType.cs 2010-11-02 11:48:40 UTC (rev 5258) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1763/EmptyStringUserType.cs 2010-11-02 11:59:09 UTC (rev 5259) @@ -1,12 +1,10 @@ using System; +using System.Data; using NHibernate.Engine; using NHibernate.UserTypes; namespace NHibernate.Test.NHSpecificTest.NH1763 { - /// <summary> - /// Summary description for EmptyStringUserType - /// </summary> [Serializable] public class EmptyStringUserType : ICompositeUserType { @@ -65,18 +63,20 @@ return NHibernateUtil.String.NullSafeGet(rs, names[0], session, owner); } - public void NullSafeSet(System.Data.IDbCommand st, Object value, int index, NHibernate.Engine.ISessionImplementor session) + public void NullSafeSet(System.Data.IDbCommand st, Object value, int index, bool[] settable, NHibernate.Engine.ISessionImplementor session) { - string str = null; - if (value != null) str = value.ToString().Trim(); - if (str == String.Empty) + if (settable[0]) { - str = null; - NHibernateUtil.String.NullSafeSet(st, str, index, session); + string str = null; + if (value != null) str = value.ToString().Trim(); + if (str == String.Empty) + { + str = null; + NHibernateUtil.String.NullSafeSet(st, str, index, session); + } + else + NHibernateUtil.String.NullSafeSet(st, value, index, session); } - else - NHibernateUtil.String.NullSafeSet(st, value, index, session); - } public Object GetPropertyValue(Object component, int property) @@ -86,17 +86,13 @@ public void SetPropertyValue(Object object1, int i, Object object2) { - } - #region ICompositeUserType Members - public int GetHashCode(object x) { return x == null ? typeof(string).GetHashCode() : x.GetHashCode(); - } public object Replace(object original, object target, ISessionImplementor session, object owner) @@ -104,7 +100,6 @@ return DeepCopy(original); } - #endregion } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2324/CompositeUserType.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2324/CompositeUserType.cs 2010-11-02 11:48:40 UTC (rev 5258) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2324/CompositeUserType.cs 2010-11-02 11:59:09 UTC (rev 5259) @@ -23,8 +23,7 @@ { return true; } - else if (x == null || - y == null) + else if (x == null || y == null) { return false; } @@ -42,11 +41,7 @@ { get { - return new[] - { - "DataA", - "DataB" - }; + return new[] { "DataA", "DataB" }; } } @@ -59,10 +54,10 @@ get { return new IType[] - { - NHibernateUtil.DateTime, - NHibernateUtil.DateTime - }; + { + NHibernateUtil.DateTime, + NHibernateUtil.DateTime + }; } } @@ -141,19 +136,20 @@ /// <param name="cmd"></param> /// <param name="value"></param> /// <param name="index"></param> + /// <param name="settable"></param> /// <param name="session"></param> - public void NullSafeSet(IDbCommand cmd, object value, int index, ISessionImplementor session) + public void NullSafeSet(IDbCommand cmd, object value, int index, bool[] settable, ISessionImplementor session) { if (value == null) { - ((IDataParameter) cmd.Parameters[index]).Value = DBNull.Value; - ((IDataParameter) cmd.Parameters[index + 1]).Value = DBNull.Value; + if (settable[0]) ((IDataParameter) cmd.Parameters[index++]).Value = DBNull.Value; + if (settable[1]) ((IDataParameter) cmd.Parameters[index]).Value = DBNull.Value; } else { var data = (CompositeData) value; - NHibernateUtil.DateTime.Set(cmd, data.DataA, index); - NHibernateUtil.DateTime.Set(cmd, data.DataB, index + 1); + if (settable[0]) NHibernateUtil.DateTime.Set(cmd, data.DataA, index++); + if (settable[1]) NHibernateUtil.DateTime.Set(cmd, data.DataB, index); } } Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2392/A.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2392/A.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2392/A.cs 2010-11-02 11:59:09 UTC (rev 5259) @@ -0,0 +1,13 @@ +using System; +using System.Collections; + +namespace NHibernate.Test.NHSpecificTest.NH2392 +{ + public class A + { + public int? Id { get; set; } + public string StringData1 { get; set; } + public PhoneNumber MyPhone { get; set; } + public string StringData2 { get; set; } + } +} Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2392/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2392/Fixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2392/Fixture.cs 2010-11-02 11:59:09 UTC (rev 5259) @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NHibernate.Criterion; +using NHibernate.Linq; +using NHibernate.Linq.Functions; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.NH2392 +{ + [TestFixture] + public class Fixture : BugTestCase + { + protected override void OnTearDown() + { + using (ISession s = sessions.OpenSession()) + { + s.Delete("from A"); + s.Flush(); + } + } + + [Test] + public void CompositeUserTypeSettability() + { + ISession s = OpenSession(); + try + { + s.Save(new A { StringData1 = "first", StringData2 = "second" }); + s.Flush(); + } + finally + { + s.Close(); + } + + s = OpenSession(); + try + { + A a = s.CreateCriteria<A>().List<A>().First(); + a.MyPhone = new PhoneNumber(1, null); + s.Save(a); + s.Flush(); + } + finally + { + s.Close(); + } + + s = OpenSession(); + try + { + A a = s.CreateCriteria<A>().List<A>().First(); + a.MyPhone = new PhoneNumber(1, "555-1234"); + s.Save(a); + s.Flush(); + } + finally + { + s.Close(); + } + } + } +} Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2392/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2392/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2392/Mappings.hbm.xml 2010-11-02 11:59:09 UTC (rev 5259) @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernate.Test" namespace="NHibernate.Test.NHSpecificTest.NH2392"> + <class name="A" table="a" lazy="false" optimistic-lock="dirty" dynamic-update="true"> + <id name="Id" column="id" unsaved-value="null"> + <generator class="native" /> + </id> + <property name="StringData1"/> + <property name="MyPhone" type="NHibernate.Test.NHSpecificTest.NH2392.PhoneNumberUserType, NHibernate.Test"> + <column name="MyPhoneCountryCode"/> + <column name="MyPhoneNumber"/> + </property> + <property name="StringData2"/> + </class> +</hibernate-mapping> Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2392/PhoneNumber.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2392/PhoneNumber.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2392/PhoneNumber.cs 2010-11-02 11:59:09 UTC (rev 5259) @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace NHibernate.Test.NHSpecificTest.NH2392 +{ + public class PhoneNumber + { + public PhoneNumber(int countryCode, string number) + { + CountryCode = countryCode; + Number = number; + } + + public int CountryCode { get; private set; } + public string Number { get; private set; } + } +} Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2392/PhoneNumberUserType.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2392/PhoneNumberUserType.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2392/PhoneNumberUserType.cs 2010-11-02 11:59:09 UTC (rev 5259) @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using NHibernate.Engine; +using NHibernate.Type; +using NHibernate.UserTypes; + +namespace NHibernate.Test.NHSpecificTest.NH2392 +{ + class PhoneNumberUserType : ICompositeUserType + { + public string[] PropertyNames + { + get { return new[] { "CountryCode", "Number" }; } + } + + public IType[] PropertyTypes + { + get { return new[] { NHibernateUtil.Int32, NHibernateUtil.String }; } + } + + public object GetPropertyValue(object component, int property) + { + PhoneNumber phone = (PhoneNumber)component; + + switch (property) + { + case 0: return phone.CountryCode; + case 1: return phone.Number; + default: throw new NotImplementedException(); + } + } + + public void SetPropertyValue(object component, int property, object value) + { + throw new NotImplementedException(); + } + + public System.Type ReturnedClass + { + get { return typeof(PhoneNumber); } + } + + public bool Equals(object x, object y) + { + if (ReferenceEquals(x, null) && ReferenceEquals(y, null)) + return true; + + if (ReferenceEquals(x, null) || ReferenceEquals(y, null)) + return false; + + return x.Equals(y); + } + + public int GetHashCode(object x) + { + return x.GetHashCode(); + } + + public object NullSafeGet(IDataReader dr, string[] names, ISessionImplementor session, object owner) + { + if (dr.IsDBNull(dr.GetOrdinal(names[0]))) + return null; + + return new PhoneNumber( + (int)NHibernateUtil.Int32.NullSafeGet(dr, names[0], session, owner), + (string)NHibernateUtil.String.NullSafeGet(dr, names[1], session, owner)); + } + + public void NullSafeSet(IDbCommand cmd, object value, int index, bool[] settable, ISessionImplementor session) + { + object countryCode = value == null ? null : (int?)((PhoneNumber)value).CountryCode; + object number = value == null ? null : ((PhoneNumber)value).Number; + + if (settable[0]) NHibernateUtil.Int32.NullSafeSet(cmd, countryCode, index++, session); + if (settable[1]) NHibernateUtil.String.NullSafeSet(cmd, number, index, session); + } + + public object DeepCopy(object value) + { + return value; + } + + public bool IsMutable + { + get { return false; } + } + + public object Disassemble(object value, ISessionImplementor session) + { + return value; + } + + public object Assemble(object cached, ISessionImplementor session, object owner) + { + return cached; + } + + public object Replace(object original, object target, ISessionImplementor session, object owner) + { + return original; + } + } +} Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-11-02 11:48:40 UTC (rev 5258) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-11-02 11:59:09 UTC (rev 5259) @@ -536,6 +536,10 @@ <Compile Include="NHSpecificTest\NH2378\Fixture.cs" /> <Compile Include="NHSpecificTest\NH2378\TestEntity.cs" /> <Compile Include="NHSpecificTest\NH2378\TestEntityDto.cs" /> + <Compile Include="NHSpecificTest\NH2392\A.cs" /> + <Compile Include="NHSpecificTest\NH2392\Fixture.cs" /> + <Compile Include="NHSpecificTest\NH2392\PhoneNumber.cs" /> + <Compile Include="NHSpecificTest\NH2392\PhoneNumberUserType.cs" /> <Compile Include="PolymorphicGetAndLoad\Domain.cs" /> <Compile Include="PolymorphicGetAndLoad\PolymorphicGetAndLoadTest.cs" /> <Compile Include="TypesTest\CharClass.cs" /> @@ -1827,6 +1831,7 @@ <EmbeddedResource Include="NHSpecificTest\NH1136\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2202\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH1869\Mappings.hbm.xml" /> + <EmbeddedResource Include="NHSpecificTest\NH2392\Mappings.hbm.xml" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\NHibernate.ByteCode.Castle\NHibernate.ByteCode.Castle.csproj"> @@ -2691,6 +2696,7 @@ <EmbeddedResource Include="DynamicEntity\Tuplizer\Customer.hbm.xml" /> </ItemGroup> <ItemGroup> + <Folder Include="NHSpecificTest\NH2392" /> <Folder Include="Properties\" /> </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jul...@us...> - 2010-11-02 11:48:46
|
Revision: 5258 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5258&view=rev Author: julian-maughan Date: 2010-11-02 11:48:40 +0000 (Tue, 02 Nov 2010) Log Message: ----------- Updated release notes for 3.0.0.CR1 Modified Paths: -------------- trunk/nhibernate/releasenotes.txt Modified: trunk/nhibernate/releasenotes.txt =================================================================== --- trunk/nhibernate/releasenotes.txt 2010-11-02 10:56:42 UTC (rev 5257) +++ trunk/nhibernate/releasenotes.txt 2010-11-02 11:48:40 UTC (rev 5258) @@ -1,6 +1,7 @@ -Build 3.0.0.Alpha3 +Build 3.0.0.CR1 ============================= -** Known BREAKING CHANGES from NH2.1.1.GA to NH3.0.0 +** Known BREAKING CHANGES from NH2.1.1.GA to NH3.0.0.CR1 + ##### Run time ##### * [NH-2199] - null values in maps/dictionaries are no longer silenty ignored/deleted * [NH-1894] - SybaseAnywhereDialect has been removed, and replaced with SybaseASA9Dialect. @@ -11,6 +12,10 @@ * [NH-2284] - Obsolete members removed * Related to [NH-2358]: DateTimeOffset type now works as a DateTimeOffset instead a "surrogate" of DateTime +Build 3.0.0.CR1 +============================= + + Build 3.0.0.Beta2 (rev5254) ============================= @@ -23,7 +28,6 @@ * [NH-1799] - Change SQL Server dialect to support variable limits * [NH-2376] - Allow IDisposable for event-listeners - ** Patch * [NH-2342] - Added XDocument type * [NH-2378] - Don't currently support idents of type Int16 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2010-11-02 10:56:49
|
Revision: 5257 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5257&view=rev Author: fabiomaulo Date: 2010-11-02 10:56:42 +0000 (Tue, 02 Nov 2010) Log Message: ----------- Fix NH-1897 Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Dialect/PostgreSQLDialect.cs Modified: trunk/nhibernate/src/NHibernate/Dialect/PostgreSQLDialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/PostgreSQLDialect.cs 2010-11-02 07:02:17 UTC (rev 5256) +++ trunk/nhibernate/src/NHibernate/Dialect/PostgreSQLDialect.cs 2010-11-02 10:56:42 UTC (rev 5257) @@ -207,5 +207,10 @@ return "on commit drop"; } } + + public override string ToBooleanValueString(bool value) + { + return value ? "TRUE" : "FALSE"; + } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2010-11-02 07:02:24
|
Revision: 5256 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5256&view=rev Author: ricbrown Date: 2010-11-02 07:02:17 +0000 (Tue, 02 Nov 2010) Log Message: ----------- Added first-cut of QueryOver documentation. Modified Paths: -------------- trunk/nhibernate/doc/reference/master.xml Added Paths: ----------- trunk/nhibernate/doc/reference/modules/query_queryover.xml Modified: trunk/nhibernate/doc/reference/master.xml =================================================================== --- trunk/nhibernate/doc/reference/master.xml 2010-10-31 19:13:38 UTC (rev 5255) +++ trunk/nhibernate/doc/reference/master.xml 2010-11-02 07:02:17 UTC (rev 5256) @@ -16,6 +16,7 @@ <!ENTITY batch SYSTEM "modules/batch.xml"> <!ENTITY query-hql SYSTEM "modules/query_hql.xml"> <!ENTITY query-criteria SYSTEM "modules/query_criteria.xml"> +<!ENTITY query-queryover SYSTEM "modules/query_queryover.xml"> <!ENTITY query-sql SYSTEM "modules/query_sql.xml"> <!ENTITY filters SYSTEM "modules/filters.xml"> <!ENTITY performance SYSTEM "modules/performance.xml"> @@ -63,6 +64,7 @@ &batch; &query-hql; &query-criteria; + &query-queryover; &query-sql; &filters; Added: trunk/nhibernate/doc/reference/modules/query_queryover.xml =================================================================== --- trunk/nhibernate/doc/reference/modules/query_queryover.xml (rev 0) +++ trunk/nhibernate/doc/reference/modules/query_queryover.xml 2010-11-02 07:02:17 UTC (rev 5256) @@ -0,0 +1,361 @@ +<chapter id="queryqueryover"> + <title>QueryOver Queries</title> + + <para> + The ICriteria API + is NHibernate's implementation of Query Object. + NHibernate 3.0 introduces the QueryOver api, which combines the use of + Extension Methods + and + Lambda Expressions + (both new in .Net 3.5) to provide a statically typesafe wrapper round the ICriteria API. + </para> + <para> + QueryOver uses Lambda Expressions to provide some extra + syntax to remove the 'magic strings' from your ICriteria queries. + </para> + <para> + So, for example: + </para> + <programlisting><![CDATA[.Add(Expression.Eq("Name", "Smith"))]]></programlisting> + <para>becomes:</para> + <programlisting><![CDATA[.Where<Person>(p => p.Name == "Smith")]]></programlisting> + <para> + With this kind of syntax there are no 'magic strings', and refactoring tools like + 'Find All References', and 'Refactor->Rename' work perfectly. + </para> + <para> + Note: QueryOver is intended to remove the references to 'magic strings' + from the ICriteria API while maintaining it's opaqueness. It is <emphasis role="underline">not</emphasis> a LINQ provider; + NHibernate has a built-in Linq provider for this. + </para> + + <sect1 id="queryqueryover-querystructure"> + <title>Structure of a Query</title> + + <para> + Queries are created from an ISession using the syntax: + </para> + <programlisting><![CDATA[IList<Cat> cats = + session.QueryOver<Cat>() + .Where(c => c.Name == "Max") + .List();]]></programlisting> + <para> </para> + <para> + Detached QueryOver (analagous to DetachedCriteria) can be created, and then used with an ISession using: + </para> + <programlisting><![CDATA[QueryOver<Cat> query = + QueryOver.Of<Cat>() + .Where(c => c.Name == "Paddy"); + +IList<Cat> cats = + query.GetExecutableQueryOver(session) + .List();]]></programlisting> + + <para> + Queries can be built up to use restrictions, projections, and ordering using + a fluent inline syntax: + </para> + <programlisting><![CDATA[var catNames = + session.QueryOver<Cat>() + .WhereRestrictionOn(c => c.Age).IsBetween(2).And(8) + .Select(c => c.Name) + .OrderBy(c => c.Name).Asc + .List<string>();]]></programlisting> + + </sect1> + + <sect1 id="queryqueryover-simpleexpressions"> + <title>Simple Expressions</title> + + <para> + The Restrictions class (used by ICriteria) has been extended to include overloads + that allow Lambda Expression syntax. The Where() method works for simple expressions (<, <=, ==, !=, >, >=) + so instead of: + </para> + <programlisting><![CDATA[ICriterion equalCriterion = Restrictions.Eq("Name", "Max")]]></programlisting> + <para> + You can write: + </para> + <programlisting><![CDATA[ICriterion equalCriterion = Restrictions.Where<Cat>(c => c.Name == "Max")]]></programlisting> + <para> </para> + <para> + Since the QueryOver class (and IQueryOver interface) is generic and knows the type of the query, + there is an inline syntax for restrictions that does not require the additional qualification + of class name. So you can also write: + </para> + <programlisting><![CDATA[var cats = + session.QueryOver<Cat>() + .Where(c => c.Name == "Max") + .And(c => c.Age > 4) + .List();]]></programlisting> + <para> + Note, the methods Where() and And() are semantically identical; the And() method is purely to allow + QueryOver to look similar to HQL/SQL. + </para> + <para> </para> + <para> + Boolean comparisons can be made directly instead of comparing to true/false: + </para> + <programlisting><![CDATA[ .Where(p => p.IsParent) + .And(p => !p.IsRetired)]]></programlisting> + <para> </para> + <para> + Simple expressions can also be combined using the || and && operators. So ICriteria like: + </para> + <programlisting><![CDATA[ .Add(Restrictions.And( + Restrictions.Eq("Name", "test name"), + Restrictions.Or( + Restrictions.Gt("Age", 21), + Restrictions.Eq("HasCar", true))))]]></programlisting> + <para> + Can be written in QueryOver as: + </para> + <programlisting><![CDATA[ .Where(p => p.Name == "test name" && (p.Age > 21 || p.HasCar))]]></programlisting> + <para> </para> + <para> + Each of the corresponding overloads in the QueryOver API allows the use of regular ICriterion + to allow access to private properties. + </para> + <programlisting><![CDATA[ .Where(Restrictions.Eq("Name", "Max"))]]></programlisting> + <para> </para> + <para> + It is worth noting that the QueryOver API is built on top of the ICriteria API. Internally the structures are the same, so at runtime + the statement below, and the statement above, are stored as exactly the same ICriterion. The actual Lambda Expression is not stored + in the query. + </para> + <programlisting><![CDATA[ .Where(c => c.Name == "Max")]]></programlisting> + + </sect1> + + <sect1 id="queryqueryover-additionalrestrictions"> + <title>Additional Restrictions</title> + + <para> + Some SQL operators/functions do not have a direct equivalent in C#. + (e.g., the SQL <literal>where name like '%anna%'</literal>). + These operators have overloads for QueryOver in the Restrictions class, so you can write: + </para> + <programlisting><![CDATA[ .Where(Restrictions.On<Cat>(c => c.Name).IsLike("%anna%"))]]></programlisting> + <para> + There is also an inline syntax to avoid the qualification of the type: + </para> + <programlisting><![CDATA[ .WhereRestrictionOn(c => c.Name).IsLike("%anna%")]]></programlisting> + <para> </para> + <para> + While simple expressions (see above) can be combined using the || and && operators, this is not possible with the other + restrictions. So this ICriteria: + </para> + <programlisting><![CDATA[ .Add(Restrictions.Or( + Restrictions.Gt("Age", 5) + Restrictions.In("Name", new string[] { "Max", "Paddy" })))]]></programlisting> + <para> + Would have to be written as: + </para> + <programlisting><![CDATA[ .Add(Restrictions.Or( + Restrictions.Where<Cat>(c => c.Age > 5) + Restrictions.On<Cat>(c => c.Name).IsIn(new string[] { "Max", "Paddy" })))]]></programlisting> + + </sect1> + + <sect1 id="queryqueryover-associations"> + <title>Associations</title> + + <para> + QueryOver can navigate association paths using JoinQueryOver() (analagous to ICriteria.CreateCriteria() to create sub-criteria). + </para> + <para> + The factory method QuerOver<T>() on ISession returns an IQueryOver<T>. + More accurately, it returns an IQueryOver<T,T> (which inherits from IQueryOver<T>). + </para> + <para> + An IQueryOver has two types of interest; the root type (the type of entity that the query returns), + and the type of the 'current' entity being queried. For example, the following query uses + a join to create a sub-QueryOver (analagous to creating sub-criteria in the ICriteria API): + </para> + <programlisting><![CDATA[IQueryOver<Cat,Kitten> catQuery = + session.QueryOver<Cat>() + .JoinQueryOver(c => c.Kittens) + .Where(k => k.Name == "Tiddles");]]></programlisting> + <para> + The JoinQueryOver returns a new instance of the IQueryOver than has its root at the Kittens collection. + The default type for restrictions is now Kitten (restricting on the name 'Tiddles' in the above example), + while calling .List() will return an IList<Cat>. The type IQueryOver<Cat,Kitten> inherits from IQueryOver<Cat>. + </para> + <para> + Note, the overload for JoinQueryOver takes an IEnumerable<T>, and the C# compiler infers the type from that. + If your collection type is not IEnumerable<T>, then you need to qualify the type of the sub-criteria: + </para> + <programlisting>IQueryOver<Cat,Kitten> catQuery = + session.QueryOver<Cat>() + .JoinQueryOver<<emphasis>Kitten</emphasis>>(c => c.Kittens) + .Where(k => k.Name == "Tiddles");</programlisting> + <para> </para> + <para> + The default join is an inner-join. Each of the additional join types can be specified using + the methods <code>.Inner, .Left, .Right,</code> or <code>.Full</code>. + For example, to left outer-join on Kittens use: + </para> + <programlisting><![CDATA[IQueryOver<Cat,Kitten> catQuery = + session.QueryOver<Cat>() + .Left.JoinQueryOver(c => c.Kittens) + .Where(k => k.Name == "Tiddles");]]></programlisting> + + </sect1> + + <sect1 id="queryqueryover-aliases"> + <title>Aliases</title> + + <para> + In the traditional ICriteria interface aliases are assigned using 'magic strings', however their value + does not correspond to a name in the object domain. For example, when an alias is assigned using + <code>.CreateAlias("Kitten", "kittenAlias")</code>, the string "kittenAlias" does not correspond + to a property or class in the domain. + </para> + <para> + In QueryOver, aliases are assigned using an empty variable. + The variable can be declared anywhere (but should + be <code>null</code> at runtime). The compiler can then check the syntax against the variable is + used correctly, but at runtime the variable is not evaluated (it's just used as a placeholder for + the alias). + </para> + <para> + Each Lambda Expression function in QueryOver has a corresponding overload to allow use of aliases, + and a .JoinAlias function to traverse associations using aliases without creating a sub-QueryOver. + </para> + <programlisting><![CDATA[Cat catAlias = null; +Kitten kittenAlias = null; + +IQueryOver<Cat,Cat> catQuery = + session.QueryOver<Cat>(() => catAlias) + .JoinAlias(() => catAlias.Kittens, () => kittenAlias) + .Where(() => catAlias.Age > 5) + .And(() => kittenAlias.Name == "Tiddles");]]></programlisting> + + </sect1> + + <sect1 id="queryqueryover-projections"> + <title>Projections</title> + + <para> + Simple projections of the properties of the root type can be added using the <code>.Select</code> method + which can take multiple Lambda Expression arguments: + </para> + <programlisting><![CDATA[IList selection = + session.QueryOver<Cat>() + .Select( + c => c.Name, + c => c.Age) + .List<object[]>();]]></programlisting> + <para> + Because this query no longer returns a Cat, the return type must be explicitly specified. + If a single property is projected, the return type can be specified using: + </para> + <programlisting><![CDATA[IList<int> ages = + session.QueryOver<Cat>() + .Select(c => c.Age) + .List<int>();]]></programlisting> + <para> + However, if multiple properties are projected, then the returned list will contain + object arrays, as per a projection + in ICriteria. This could be fed into an anonymous type using: + </para> + <programlisting><![CDATA[var catDetails = + session.QueryOver<Cat>() + .Select( + c => c.Name, + c => c.Age) + .List<object[]>() + .Select(properties => new { + CatName = (string)properties[0], + CatAge = (int)properties[1], + }); + +Console.WriteLine(catDetails[0].CatName); +Console.WriteLine(catDetails[0].CatAge);]]></programlisting> + <para> + Note that the second <code>.Select</code> call in this example is an extension method on IEnumerable<T> supplied in System.Linq; + it is not part of NHibernate. + </para> + <para> </para> + <para> + QueryOver allows arbitrary IProjection to be added (allowing private properties to be projected). The Projections factory + class also has overloads to allow Lambda Expressions to be used: + </para> + <programlisting><![CDATA[IList selection = + session.QueryOver<Cat>() + .Select(Projections.ProjectionList() + .Add(Projections.Property<Cat>(c => c.Name)) + .Add(Projections.Avg<Cat>(c => c.Age))) + .List<object[]>();]]></programlisting> + <para> </para> + <para> + In addition there is an inline syntax for creating projection lists that does not require the explicit class qualification: + </para> + <programlisting><![CDATA[IList selection = + session.QueryOver<Cat>() + .SelectList(list => list + .Select(c => c.Name) + .SelectAvg(c => c.Age)) + .List<object[]>();]]></programlisting> + <para> </para> + <para> + Projections can also have arbitrary aliases assigned to them to allow result transformation. + If there is a CatSummary DTO class defined as: + </para> + <programlisting><![CDATA[public class CatSummary +{ + public string Name { get; set; } + public int AverageAge { get; set; } +}]]></programlisting> + <para> + ... then aliased projections can be used with the AliasToBean<T> transformer: + </para> + <programlisting><![CDATA[CatSummary summaryDto = null; +IList<CatSummary> catReport = + session.QueryOver<Cat>() + .SelectList(list => list + .SelectGroup(c => c.Name).WithAlias(() => summaryDto.Name) + .SelectAvg(c => c.Age).WithAlias(() => summaryDto.AverageAge)) + .TransformUsing(Transformers.AliasToBean<CatSummary>()) + .List<CatSummary>();]]></programlisting> + + </sect1> + + <sect1 id="queryqueryover-subqueries"> + <title>Subqueries</title> + + <para> + The Subqueries factory class has overloads to allow Lambda Expressions to express sub-query + restrictions. For example: + </para> + <programlisting><![CDATA[QueryOver<Cat> maximumAge = + QueryOver.Of<Cat>() + .SelectList(p => p.SelectMax(c => c.Age)); + +IList<Cat> oldestCats = + session.QueryOver<Cat>() + .Where(Subqueries.WhereProperty<Cat>(c => c.Age).Eq(maximumAge)) + .List();]]></programlisting> + <para> </para> + <para> + The inline syntax allows you to use subqueries without requalifying the type: + </para> + <programlisting><![CDATA[IList<Cat> oldestCats = + session.QueryOver<Cat>() + .WithSubquery.WhereProperty(c => c.Age).Eq(maximumAge) + .List();]]></programlisting> + <para> </para> + <para> + There is an extension method <code>As()</code> on (a detached) QueryOver that allows you to cast it to any type. + This is used in conjunction with the overloads <code>Where(), WhereAll(),</code> and <code>WhereSome()</code> + to allow use of the built-in C# operators for comparison, so the above query can be written as: + </para> + <programlisting><![CDATA[IList<Cat> oldestCats = + session.QueryOver<Cat>() + .WithSubquery.Where(c => c.Age == maximumAge.As<int>()) + .List();]]></programlisting> + + </sect1> + +</chapter> \ 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...> - 2010-10-31 19:13:44
|
Revision: 5255 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5255&view=rev Author: fabiomaulo Date: 2010-10-31 19:13:38 +0000 (Sun, 31 Oct 2010) Log Message: ----------- Actualized version of actual trunk Modified Paths: -------------- trunk/nhibernate/build-common/common.xml Modified: trunk/nhibernate/build-common/common.xml =================================================================== --- trunk/nhibernate/build-common/common.xml 2010-10-31 18:43:37 UTC (rev 5254) +++ trunk/nhibernate/build-common/common.xml 2010-10-31 19:13:38 UTC (rev 5255) @@ -84,7 +84,7 @@ effectively SP0). --> - <property name="project.version" value="3.0.0.Beta2" overwrite="false" /> + <property name="project.version" value="3.0.0.CR1" overwrite="false" /> <!-- Compute short project version (major.minor) using a regex --> <regex input="${project.version}" pattern="^(?'shortversion'\d+\.\d+)" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2010-10-31 18:43:43
|
Revision: 5254 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5254&view=rev Author: fabiomaulo Date: 2010-10-31 18:43:37 +0000 (Sun, 31 Oct 2010) Log Message: ----------- Preparing release Modified Paths: -------------- trunk/nhibernate/releasenotes.txt Modified: trunk/nhibernate/releasenotes.txt =================================================================== --- trunk/nhibernate/releasenotes.txt 2010-10-25 03:14:09 UTC (rev 5253) +++ trunk/nhibernate/releasenotes.txt 2010-10-31 18:43:37 UTC (rev 5254) @@ -11,6 +11,24 @@ * [NH-2284] - Obsolete members removed * Related to [NH-2358]: DateTimeOffset type now works as a DateTimeOffset instead a "surrogate" of DateTime +Build 3.0.0.Beta2 (rev5254) +============================= + +** Bug + * [NH-1155] - SubselectFetch doesn't take into account paging + * [NH-2371] - Exception is thrown when using SetMaxResults on query using MySQL + * [NH-2374] - ForeignGenerator does not support EntityMode.Map + +** Improvement + * [NH-1799] - Change SQL Server dialect to support variable limits + * [NH-2376] - Allow IDisposable for event-listeners + + +** Patch + * [NH-2342] - Added XDocument type + * [NH-2378] - Don't currently support idents of type Int16 + * [NH-2391] - Updated Chapter 4 + Build 3.0.0.Beta1 (rev5241) ============================= This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |