|
From: <aye...@us...> - 2008-10-15 13:59:33
|
Revision: 3858
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3858&view=rev
Author: ayenderahien
Date: 2008-10-15 13:58:32 +0000 (Wed, 15 Oct 2008)
Log Message:
-----------
Fixing NH-1526 - Cannot use projection for Count in OrderBy
Fixing NH-1029 - Misleading SQL Query on exception
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/AdoNet/AbstractBatcher.cs
trunk/nhibernate/src/NHibernate/Criterion/CountProjection.cs
trunk/nhibernate/src/NHibernate/Exceptions/ADOExceptionHelper.cs
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate.Test/ProjectionFixtures/
trunk/nhibernate/src/NHibernate.Test/ProjectionFixtures/Fixture.cs
trunk/nhibernate/src/NHibernate.Test/ProjectionFixtures/Key.cs
trunk/nhibernate/src/NHibernate.Test/ProjectionFixtures/Mapping.hbm.xml
trunk/nhibernate/src/NHibernate.Test/ProjectionFixtures/NodeType.cs
trunk/nhibernate/src/NHibernate.Test/ProjectionFixtures/TreeNode.cs
Modified: trunk/nhibernate/src/NHibernate/AdoNet/AbstractBatcher.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/AdoNet/AbstractBatcher.cs 2008-10-15 12:03:06 UTC (rev 3857)
+++ trunk/nhibernate/src/NHibernate/AdoNet/AbstractBatcher.cs 2008-10-15 13:58:32 UTC (rev 3858)
@@ -193,7 +193,15 @@
{
CheckReaders();
Prepare(cmd);
- return cmd.ExecuteNonQuery();
+ try
+ {
+ return cmd.ExecuteNonQuery();
+ }
+ catch (Exception e)
+ {
+ e.Data["actual-sql-query"] = cmd.CommandText;
+ throw;
+ }
}
public IDataReader ExecuteReader(IDbCommand cmd)
@@ -201,9 +209,18 @@
CheckReaders();
Prepare(cmd);
- IDataReader reader = cmd.ExecuteReader();
+ IDataReader reader;
+ try
+ {
+ reader = cmd.ExecuteReader();
+ }
+ catch (Exception e)
+ {
+ e.Data["actual-sql-query"] = cmd.CommandText;
+ throw;
+ }
- if (!factory.ConnectionProvider.Driver.SupportsMultipleOpenReaders)
+ if (!factory.ConnectionProvider.Driver.SupportsMultipleOpenReaders)
{
reader = new NHybridDataReader(reader);
}
Modified: trunk/nhibernate/src/NHibernate/Criterion/CountProjection.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/CountProjection.cs 2008-10-15 12:03:06 UTC (rev 3857)
+++ trunk/nhibernate/src/NHibernate/Criterion/CountProjection.cs 2008-10-15 13:58:32 UTC (rev 3858)
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using NHibernate.SqlCommand;
using NHibernate.Type;
+using NHibernate.Util;
namespace NHibernate.Criterion
{
@@ -34,7 +35,19 @@
{
buf.Add("distinct ");
}
- buf.Add(criteriaQuery.GetColumn(criteria, propertyName)).Add(") as y").Add(position.ToString()).Add("_");
+ string column;
+ if(projection!=null)
+ {
+ column =
+ StringHelper.RemoveAsAliasesFromSql(projection.ToSqlString(criteria, position, criteriaQuery,
+ enabledFilters)).ToString();
+ }
+ else
+ {
+ column = criteriaQuery.GetColumn(criteria, propertyName);
+ }
+
+ buf.Add(column).Add(") as y").Add(position.ToString()).Add("_");
return buf.ToSqlString();
}
Modified: trunk/nhibernate/src/NHibernate/Exceptions/ADOExceptionHelper.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Exceptions/ADOExceptionHelper.cs 2008-10-15 12:03:06 UTC (rev 3857)
+++ trunk/nhibernate/src/NHibernate/Exceptions/ADOExceptionHelper.cs 2008-10-15 13:58:32 UTC (rev 3858)
@@ -8,15 +8,11 @@
namespace NHibernate.Exceptions
{
- public sealed class ADOExceptionHelper
+ public static class ADOExceptionHelper
{
public const string SQLNotAvailable = "SQL not available";
- private ADOExceptionHelper()
- {
- }
-
- /// <summary>
+ /// <summary>
/// Converts the given SQLException into NHibernate's ADOException hierarchy, as well as performing
/// appropriate logging.
/// </summary>
@@ -27,6 +23,7 @@
/// <returns> The converted <see cref="ADOException"/>.</returns>
public static ADOException Convert(ISQLExceptionConverter converter, Exception sqlException, string message, SqlString sql)
{
+ sql = TryGetActualSqlQuery(sqlException, sql);
ADOExceptionReporter.LogExceptions(sqlException, ExtendMessage(message, sql, null, null));
return converter.Convert(sqlException, message, sql);
}
@@ -41,13 +38,16 @@
/// <returns> The converted <see cref="ADOException"/>.</returns>
public static ADOException Convert(ISQLExceptionConverter converter, Exception sqlException, string message)
{
- return Convert(converter, sqlException, message, new SqlString(SQLNotAvailable));
+ SqlString sql = new SqlString(SQLNotAvailable);
+ sql = TryGetActualSqlQuery(sqlException, sql);
+ return Convert(converter, sqlException, message, sql);
}
public static ADOException Convert(ISQLExceptionConverter converter, Exception sqle, string message, SqlString sql,
object[] parameterValues, IDictionary<string, TypedValue> namedParameters)
{
- string extendMessage = ExtendMessage(message, sql, parameterValues, namedParameters);
+ sql = TryGetActualSqlQuery(sqle, sql);
+ string extendMessage = ExtendMessage(message, sql, parameterValues, namedParameters);
ADOExceptionReporter.LogExceptions(sqle, extendMessage);
return new ADOException(extendMessage, sqle, sql);
}
@@ -100,5 +100,13 @@
sb.Append(Environment.NewLine);
return sb.ToString();
}
+
+ public static SqlString TryGetActualSqlQuery(Exception sqle, SqlString sql)
+ {
+ string query = (string)sqle.Data["actual-sql-query"];
+ if(query!=null)
+ sql = new SqlString(query);
+ return sql;
+ }
}
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2008-10-15 12:03:06 UTC (rev 3857)
+++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2008-10-15 13:58:32 UTC (rev 3858)
@@ -757,6 +757,10 @@
<Compile Include="Ondelete\ParentChildFixture.cs" />
<Compile Include="Ondelete\Person.cs" />
<Compile Include="Ondelete\Salesperson.cs" />
+ <Compile Include="ProjectionFixtures\Key.cs" />
+ <Compile Include="ProjectionFixtures\Fixture.cs" />
+ <Compile Include="ProjectionFixtures\NodeType.cs" />
+ <Compile Include="ProjectionFixtures\TreeNode.cs" />
<Compile Include="PropertyRef\A.cs" />
<Compile Include="PropertyRef\B.cs" />
<Compile Include="PropertyRef\KeyPropertyRefFixture.cs" />
@@ -1499,6 +1503,7 @@
<EmbeddedResource Include="Cascade\JobBatch.hbm.xml" />
<EmbeddedResource Include="Deletetransient\Person.hbm.xml" />
<Content Include="DynamicEntity\package.html" />
+ <EmbeddedResource Include="ProjectionFixtures\Mapping.hbm.xml" />
<EmbeddedResource Include="NHSpecificTest\NH1033\Mappings.hbm.xml" />
<EmbeddedResource Include="EntityModeTest\Multi\Stock.hbm.xml" />
<EmbeddedResource Include="EntityModeTest\Multi\Valuation.hbm.xml" />
Property changes on: trunk/nhibernate/src/NHibernate.Test/ProjectionFixtures
___________________________________________________________________
Added: bugtraq:url
+ http://jira.nhibernate.org/browse/%BUGID%
Added: bugtraq:logregex
+ NH-\d+
Added: trunk/nhibernate/src/NHibernate.Test/ProjectionFixtures/Fixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/ProjectionFixtures/Fixture.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/ProjectionFixtures/Fixture.cs 2008-10-15 13:58:32 UTC (rev 3858)
@@ -0,0 +1,123 @@
+using System;
+using NHibernate;
+using NHibernate.Criterion;
+using NHibernate.Test.PropertyRef;
+using NUnit.Framework;
+
+namespace NHibernate.Test.ProjectionFixtures
+{
+ [TestFixture]
+ public class Fixture : TestCase
+ {
+ protected override System.Collections.IList Mappings
+ {
+ get { return new string[] { "ProjectionFixtures.Mapping.hbm.xml" }; }
+ }
+
+ protected override string MappingsAssembly
+ {
+ get { return "NHibernate.Test"; }
+ }
+
+ protected override void OnSetUp()
+ {
+ using(var s = sessions.OpenSession())
+ using(var tx = s.BeginTransaction())
+ {
+ var root = new TreeNode
+ {
+ Key = new Key {Id = 1, Area = 2},
+ Type = NodeType.Plain
+ };
+ var child = new TreeNode
+ {
+ Key = new Key { Id = 11, Area = 2 },
+ Type = NodeType.Blue
+ };
+ var grandchild = new TreeNode
+ {
+ Key = new Key {Id = 111, Area = 2},
+ Type = NodeType.Smart
+ };
+ root.DirectChildren.Add(child);
+ child.Parent = root;
+ grandchild.Parent = child;
+ child.DirectChildren.Add(grandchild);
+
+ s.Save(root);
+ s.Save(child);
+ s.Save(grandchild);
+
+ tx.Commit();
+ }
+ }
+
+ protected override void OnTearDown()
+ {
+ using(var s = sessions.OpenSession())
+ using (var tx = s.BeginTransaction())
+ {
+ s.Delete("from TreeNode");
+
+ tx.Commit();
+ }
+ }
+
+
+ [Test]
+ [ExpectedException(typeof(ADOException), ExpectedMessage = @"could not execute query
+[ SELECT this_.Id as y0_, count(this_.Area) as y1_ FROM TreeNode this_ WHERE this_.Id = @p0 ]
+Positional parameters: #0>2
+[SQL: SELECT this_.Id as y0_, count(this_.Area) as y1_ FROM TreeNode this_ WHERE this_.Id = @p0]")]
+ public void ErrorFromDBWillGiveTheActualSQLExecuted()
+ {
+ DetachedCriteria projection = DetachedCriteria.For<TreeNode>("child")
+ .Add(Restrictions.Eq("child.Key.Id", 2))
+ .SetProjection(
+ Projections.ProjectionList()
+ .Add(Projections.Property("child.Key.Id"))
+ .Add(Projections.Count("child.Key.Area"))
+ );
+
+ using (var s = sessions.OpenSession())
+ using (var tx = s.BeginTransaction())
+ {
+ var criteria = projection.GetExecutableCriteria(s);
+ criteria.List();
+
+ tx.Commit();
+ }
+ }
+
+ [Test]
+ public void AggregatingHirearchyWithCount()
+ {
+ var root = new Key {Id = 1, Area = 2};
+
+ DetachedCriteria projection = DetachedCriteria.For<TreeNode>("child")
+ .Add(Restrictions.Eq("Parent.id", root))
+ .Add(Restrictions.Gt("Key.Id", 0))
+ .Add(Restrictions.Eq("Type", NodeType.Blue))
+ .CreateAlias("DirectChildren", "grandchild")
+ .SetProjection(
+ Projections.ProjectionList()
+ .Add(Projections.GroupProperty("child.Key.Id"))
+ .Add(Projections.GroupProperty("child.Key.Area"))
+ .Add(Projections.Count(Projections.Property("grandchild.Key.Id")))
+ );
+
+ using(var s = sessions.OpenSession())
+ using(var tx = s.BeginTransaction())
+ {
+ var criteria = projection.GetExecutableCriteria(s);
+ var list = criteria.List();
+ Assert.AreEqual(1, list.Count);
+ var tuple = (object[]) list[0];
+ Assert.AreEqual(11, tuple[0]);
+ Assert.AreEqual(2, tuple[1]);
+ Assert.AreEqual(1, tuple[2]);
+ tx.Commit();
+ }
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/ProjectionFixtures/Key.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/ProjectionFixtures/Key.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/ProjectionFixtures/Key.cs 2008-10-15 13:58:32 UTC (rev 3858)
@@ -0,0 +1,31 @@
+namespace NHibernate.Test.ProjectionFixtures
+{
+ public class Key
+ {
+ public virtual int Id { get; set; }
+ public virtual int Area { get; set; }
+
+ public virtual bool Equals(Key obj)
+ {
+ if (ReferenceEquals(null, obj)) return false;
+ if (ReferenceEquals(this, obj)) return true;
+ return obj.Id == Id && obj.Area == Area;
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (ReferenceEquals(null, obj)) return false;
+ if (ReferenceEquals(this, obj)) return true;
+ if (obj.GetType() != typeof (Key)) return false;
+ return Equals((Key) obj);
+ }
+
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ return (Id*397) ^ Area;
+ }
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/ProjectionFixtures/Mapping.hbm.xml
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/ProjectionFixtures/Mapping.hbm.xml (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/ProjectionFixtures/Mapping.hbm.xml 2008-10-15 13:58:32 UTC (rev 3858)
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
+ assembly="NHibernate.Test"
+ namespace="NHibernate.Test.ProjectionFixtures">
+
+ <class name="TreeNode">
+ <composite-id name="Key">
+ <key-property name="Id" />
+ <key-property name="Area" />
+ </composite-id>
+ <many-to-one name="Parent">
+ <column name="Parent"/>
+ <column name="ParentArea"/>
+ </many-to-one>
+ <set name="DirectChildren">
+ <key>
+ <column name="Parent"/>
+ <column name="ParentArea"/>
+ </key>
+ <one-to-many class="TreeNode"/>
+ </set>
+ <property name="Type"/>
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/ProjectionFixtures/NodeType.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/ProjectionFixtures/NodeType.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/ProjectionFixtures/NodeType.cs 2008-10-15 13:58:32 UTC (rev 3858)
@@ -0,0 +1,9 @@
+namespace NHibernate.Test.ProjectionFixtures
+{
+ public enum NodeType
+ {
+ Smart,
+ Plain,
+ Blue
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/ProjectionFixtures/TreeNode.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/ProjectionFixtures/TreeNode.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/ProjectionFixtures/TreeNode.cs 2008-10-15 13:58:32 UTC (rev 3858)
@@ -0,0 +1,18 @@
+using Iesi.Collections.Generic;
+using NHibernate.Test.ProjectionFixtures;
+
+namespace NHibernate.Test.ProjectionFixtures
+{
+ public class TreeNode
+ {
+ public virtual Key Key { get; set; }
+ public virtual TreeNode Parent { get; set; }
+ public virtual NodeType Type { get; set; }
+ public virtual ISet<TreeNode> DirectChildren { get; set; }
+
+ public TreeNode()
+ {
+ DirectChildren = new HashedSet<TreeNode>();
+ }
+ }
+}
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|