From: <jul...@us...> - 2010-09-26 02:53:59
|
Revision: 5220 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5220&view=rev Author: julian-maughan Date: 2010-09-26 02:53:50 +0000 (Sun, 26 Sep 2010) Log Message: ----------- Added support for projections using composite keys and components (NH-2202). See also HHH-1088 (r19110). Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Criterion/AliasedProjection.cs trunk/nhibernate/src/NHibernate/Criterion/Distinct.cs trunk/nhibernate/src/NHibernate/Criterion/IProjection.cs trunk/nhibernate/src/NHibernate/Criterion/ProjectionList.cs trunk/nhibernate/src/NHibernate/Criterion/PropertyProjection.cs trunk/nhibernate/src/NHibernate/Criterion/SimpleProjection.cs trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs trunk/nhibernate/src/NHibernate/NHibernate.csproj trunk/nhibernate/src/NHibernate.Test/Criteria/Course.cs trunk/nhibernate/src/NHibernate.Test/Criteria/CriteriaQueryTest.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Enrolment.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Enrolment.hbm.xml trunk/nhibernate/src/NHibernate.Test/Criteria/Student.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate/Criterion/IEnhancedProjection.cs trunk/nhibernate/src/NHibernate.Test/Criteria/CityState.cs trunk/nhibernate/src/NHibernate.Test/Criteria/CourseMeeting.cs trunk/nhibernate/src/NHibernate.Test/Criteria/CourseMeetingId.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2202/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2202/Fixture.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2202/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2202/Model.cs Modified: trunk/nhibernate/src/NHibernate/Criterion/AliasedProjection.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/AliasedProjection.cs 2010-09-25 20:07:30 UTC (rev 5219) +++ trunk/nhibernate/src/NHibernate/Criterion/AliasedProjection.cs 2010-09-26 02:53:50 UTC (rev 5220) @@ -1,14 +1,14 @@ using System; +using System.Collections.Generic; + using NHibernate.SqlCommand; +using NHibernate.Engine; using NHibernate.Type; namespace NHibernate.Criterion { - using System.Collections.Generic; - using Engine; - [Serializable] - public class AliasedProjection : IProjection + public class AliasedProjection : IEnhancedProjection { private readonly IProjection projection; private readonly string alias; @@ -36,9 +36,9 @@ public virtual IType[] GetTypes(String alias, ICriteria criteria, ICriteriaQuery criteriaQuery) { - return this.alias.Equals(alias) ? - GetTypes(criteria, criteriaQuery) : - null; + return this.alias.Equals(alias) + ? GetTypes(criteria, criteriaQuery) + : null; } public virtual string[] GetColumnAliases(int loc) @@ -48,10 +48,24 @@ public virtual string[] GetColumnAliases(string alias, int loc) { - return this.alias.Equals(alias) ? - GetColumnAliases(loc) : - null; + return this.alias.Equals(alias) + ? GetColumnAliases(loc) + : null; } + + public string[] GetColumnAliases(int position, ICriteria criteria, ICriteriaQuery criteriaQuery) + { + return projection is IEnhancedProjection + ? ((IEnhancedProjection)projection).GetColumnAliases(position, criteria, criteriaQuery) + : this.GetColumnAliases(position); + } + + public string[] GetColumnAliases(string alias, int position, ICriteria criteria, ICriteriaQuery criteriaQuery) + { + return this.alias.Equals(alias) + ? GetColumnAliases(position, criteria, criteriaQuery) + : null; + } public virtual string[] Aliases { @@ -84,4 +98,4 @@ return projection.ToString() + " as " + alias; } } -} +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Criterion/Distinct.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/Distinct.cs 2010-09-25 20:07:30 UTC (rev 5219) +++ trunk/nhibernate/src/NHibernate/Criterion/Distinct.cs 2010-09-26 02:53:50 UTC (rev 5220) @@ -1,14 +1,13 @@ using System; +using System.Collections.Generic; +using NHibernate.Engine; using NHibernate.SqlCommand; using NHibernate.Type; namespace NHibernate.Criterion { - using System.Collections.Generic; - using Engine; - [Serializable] - public class Distinct : IProjection + public class Distinct : IEnhancedProjection { private readonly IProjection projection; @@ -42,11 +41,25 @@ { return projection.GetColumnAliases(loc); } + + public virtual string[] GetColumnAliases(int position, ICriteria criteria, ICriteriaQuery criteriaQuery) + { + return projection is IEnhancedProjection + ? ((IEnhancedProjection)projection).GetColumnAliases(position, criteria, criteriaQuery) + : GetColumnAliases(position); + } public virtual string[] GetColumnAliases(string alias, int loc) { return projection.GetColumnAliases(alias, loc); } + + public virtual string[] GetColumnAliases(string alias, int position, ICriteria criteria, ICriteriaQuery criteriaQuery) + { + return projection is IEnhancedProjection + ? ((IEnhancedProjection)projection).GetColumnAliases(alias, position, criteria, criteriaQuery) + : GetColumnAliases(alias, position); + } public virtual string[] Aliases { @@ -79,4 +92,4 @@ return "distinct " + projection.ToString(); } } -} +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate/Criterion/IEnhancedProjection.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/IEnhancedProjection.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Criterion/IEnhancedProjection.cs 2010-09-26 02:53:50 UTC (rev 5220) @@ -0,0 +1,33 @@ +using System; + +namespace NHibernate.Criterion +{ + /// <summary> + /// An "enhanced" Projection for a <see cref="ICriteria" /> query. + /// </summary> + public interface IEnhancedProjection : IProjection + { + /// <summary> + /// Get the SQL column aliases used by this projection for the columns it writes for inclusion into the + /// <code>SELECT</code> clause <see cref="IProjection.ToSqlString" />. NHibernate always uses column aliases + /// to extract data from the <see cref="System.Data.IDataReader" />, so it is important that these be implemented + /// correctly in order for NHibernate to be able to extract these values correctly. + /// </summary> + /// <param name="position">Just as in <see cref="IProjection.ToSqlString" />, represents the number of columns rendered prior to this projection.</param> + /// <param name="criteria">The local criteria to which this project is attached (for resolution).</param> + /// <param name="criteriaQuery">The overall criteria query instance.</param> + /// <returns>The columns aliases.</returns> + string[] GetColumnAliases(int position, ICriteria criteria, ICriteriaQuery criteriaQuery); + + /// <summary> + /// Get the SQL column aliases used by this projection for the columns it writes for inclusion into the + /// <code>SELECT</code> clause (<see cref="IProjection.ToSqlString" />) for a particular criteria-level alias. + /// </summary> + /// <param name="alias">The criteria-level alias.</param> + /// <param name="position">Just as in <see cref="IProjection.ToSqlString" />, represents the number of columns rendered prior to this projection.</param> + /// <param name="criteria">The local criteria to which this project is attached (for resolution).</param> + /// <param name="criteriaQuery">The overall criteria query instance.</param> + /// <returns>The columns aliases.</returns> + string[] GetColumnAliases(string alias, int position, ICriteria criteria, ICriteriaQuery criteriaQuery); + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Criterion/IProjection.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/IProjection.cs 2010-09-25 20:07:30 UTC (rev 5219) +++ trunk/nhibernate/src/NHibernate/Criterion/IProjection.cs 2010-09-26 02:53:50 UTC (rev 5220) @@ -1,13 +1,12 @@ using System; +using System.Collections.Generic; using NHibernate.SqlCommand; +using NHibernate.Engine; +using NHibernate.Loader.Criteria; using NHibernate.Type; namespace NHibernate.Criterion { - using System.Collections.Generic; - using Engine; - using NHibernate.Loader.Criteria; - public interface IProjection { /// <summary> Modified: trunk/nhibernate/src/NHibernate/Criterion/ProjectionList.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/ProjectionList.cs 2010-09-25 20:07:30 UTC (rev 5219) +++ trunk/nhibernate/src/NHibernate/Criterion/ProjectionList.cs 2010-09-26 02:53:50 UTC (rev 5220) @@ -1,16 +1,18 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq.Expressions; + +using NHibernate.Engine; using NHibernate.Impl; using NHibernate.SqlCommand; using NHibernate.Type; +using NHibernate.Util; namespace NHibernate.Criterion { - using Engine; - [Serializable] - public class ProjectionList : IProjection + public class ProjectionList : IEnhancedProjection { private IList<IProjection> elements = new List<IProjection>(); @@ -60,8 +62,8 @@ for (int i = 0; i < Length; i++) { IProjection proj = this[i]; - buf.Add(proj.ToSqlString(criteria, loc, criteriaQuery,enabledFilters)); - loc += proj.GetColumnAliases(loc).Length; + buf.Add(proj.ToSqlString(criteria, loc, criteriaQuery, enabledFilters)); + loc += GetColumnAliases(loc, criteria, criteriaQuery, proj).Length; if (i < elements.Count - 1) { buf.Add(", "); @@ -89,7 +91,7 @@ return buf.ToSqlString(); } - public String[] GetColumnAliases(int loc) + public string[] GetColumnAliases(int loc) { IList<string> aliases = new List<string>(Length); @@ -105,7 +107,7 @@ return result; } - public String[] GetColumnAliases(string alias, int loc) + public string[] GetColumnAliases(string alias, int loc) { for (int i = 0; i < Length; i++) { @@ -115,7 +117,44 @@ } return null; } + + public string[] GetColumnAliases(int position, ICriteria criteria, ICriteriaQuery criteriaQuery) + { + IList result = new ArrayList(this.Length); + for (int i = 0; i < this.Length; i++) + { + string[] colAliases = ProjectionList.GetColumnAliases(position, criteria, criteriaQuery, this[i]); + ArrayHelper.AddAll(result, colAliases); + position += colAliases.Length; + } + return ArrayHelper.ToStringArray(result); + } + + public string[] GetColumnAliases(string alias, int position, ICriteria criteria, ICriteriaQuery criteriaQuery) + { + for (int i = 0; i < this.Length; i++) + { + string[] result = GetColumnAliases(alias, position, criteria, criteriaQuery, this[i]); + if (result != null) return result; + position += GetColumnAliases(position, criteria, criteriaQuery, this[i]).Length; + } + return null; + } + + private static string[] GetColumnAliases(int position, ICriteria criteria, ICriteriaQuery criteriaQuery, IProjection projection) + { + return projection is IEnhancedProjection + ? ((IEnhancedProjection)projection).GetColumnAliases(position, criteria, criteriaQuery) + : projection.GetColumnAliases(position); + } + private static string[] GetColumnAliases(string alias, int position, ICriteria criteria, ICriteriaQuery criteriaQuery, IProjection projection) + { + return projection is IEnhancedProjection + ? ((IEnhancedProjection)projection).GetColumnAliases(alias, position, criteria, criteriaQuery) + : projection.GetColumnAliases(alias, position); + } + public IType[] GetTypes(string alias, ICriteria criteria, ICriteriaQuery criteriaQuery) { for (int i = 0; i < Length; i++) Modified: trunk/nhibernate/src/NHibernate/Criterion/PropertyProjection.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/PropertyProjection.cs 2010-09-25 20:07:30 UTC (rev 5219) +++ trunk/nhibernate/src/NHibernate/Criterion/PropertyProjection.cs 2010-09-26 02:53:50 UTC (rev 5220) @@ -1,11 +1,10 @@ using System; +using System.Collections.Generic; using NHibernate.SqlCommand; using NHibernate.Type; namespace NHibernate.Criterion { - using System.Collections.Generic; - /// <summary> /// A property value, or grouped property value /// </summary> @@ -53,13 +52,18 @@ public override SqlString ToSqlString(ICriteria criteria, int loc, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters) { - return new SqlString(new object[] - { - criteriaQuery.GetColumn(criteria, propertyName), - " as y", - loc.ToString(), - "_" - }); + SqlStringBuilder s = new SqlStringBuilder(); + string[] cols = criteriaQuery.GetColumnsUsingProjection(criteria, propertyName); + for (int i = 0; i < cols.Length; i++) + { + s.Add(cols[i]); + s.Add(" as y"); + s.Add((loc + i).ToString()); + s.Add("_"); + if (i < cols.Length - 1) + s.Add(", "); + } + return s.ToSqlString(); } public override SqlString ToGroupSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters) @@ -71,4 +75,4 @@ return new SqlString(criteriaQuery.GetColumn(criteria, propertyName)); } } -} +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Criterion/SimpleProjection.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/SimpleProjection.cs 2010-09-25 20:07:30 UTC (rev 5219) +++ trunk/nhibernate/src/NHibernate/Criterion/SimpleProjection.cs 2010-09-26 02:53:50 UTC (rev 5220) @@ -1,17 +1,16 @@ using System; +using System.Collections.Generic; using NHibernate.SqlCommand; +using NHibernate.Engine; using NHibernate.Type; namespace NHibernate.Criterion { - using System.Collections.Generic; - using Engine; - /// <summary> /// A single-column projection that may be aliased /// </summary> [Serializable] - public abstract class SimpleProjection : IProjection + public abstract class SimpleProjection : IEnhancedProjection { public IProjection As(string alias) { @@ -32,7 +31,24 @@ { return new string[] {"y" + loc + "_"}; } + + public string[] GetColumnAliases(string alias, int position, ICriteria criteria, ICriteriaQuery criteriaQuery) + { + return GetColumnAliases(alias, position); + } + public String[] GetColumnAliases(int position, ICriteria criteria, ICriteriaQuery criteriaQuery) + { + int numColumns = this.GetColumnCount(criteria, criteriaQuery); + string[] aliases = new string[numColumns]; + for (int i = 0; i < numColumns; i++) + { + aliases[i] = "y" + position + "_"; + position++; + } + return aliases; + } + public virtual string[] Aliases { get { return new String[1]; } @@ -44,7 +60,6 @@ public abstract bool IsAggregate { get; } - /// <summary> /// Gets the typed values for parameters in this projection /// </summary> @@ -59,5 +74,16 @@ public abstract SqlString ToSqlString(ICriteria criteria, int position, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters); public abstract IType[] GetTypes(ICriteria criteria, ICriteriaQuery criteriaQuery); + + private int GetColumnCount(ICriteria criteria, ICriteriaQuery criteriaQuery) + { + IType[] types = this.GetTypes(criteria, criteriaQuery); + int count = 0; + for (int i = 0; i < types.Length; i++) + { + count += types[i].GetColumnSpan(criteriaQuery.Factory); + } + return count; + } } } Modified: trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs 2010-09-25 20:07:30 UTC (rev 5219) +++ trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs 2010-09-26 02:53:50 UTC (rev 5220) @@ -8,6 +8,7 @@ using NHibernate.SqlCommand; using NHibernate.Transform; using NHibernate.Type; +using NHibernate.Util; namespace NHibernate.Loader.Criteria { @@ -84,10 +85,21 @@ IType[] types = translator.ProjectedTypes; result = new object[types.Length]; string[] columnAliases = translator.ProjectedColumnAliases; - - for (int i = 0; i < result.Length; i++) + + for (int i = 0, position = 0; i < result.Length; i++) { - result[i] = types[i].NullSafeGet(rs, columnAliases[i], session, null); + int numColumns = types[i].GetColumnSpan(session.Factory); + + if ( numColumns > 1 ) + { + string[] typeColumnAliases = ArrayHelper.Slice(columnAliases, position, numColumns); + result[i] = types[i].NullSafeGet(rs, typeColumnAliases, session, null); + } + else + { + result[i] = types[i].NullSafeGet(rs, columnAliases[position], session, null); + } + position += numColumns; } aliases = translator.ProjectedAliases; } Modified: trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs 2010-09-25 20:07:30 UTC (rev 5219) +++ trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs 2010-09-26 02:53:50 UTC (rev 5220) @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Text; using Iesi.Collections.Generic; - using NHibernate.Criterion; using NHibernate.Engine; using NHibernate.Hql.Util; @@ -172,7 +171,12 @@ public string[] ProjectedColumnAliases { - get { return rootCriteria.Projection.GetColumnAliases(0); } + get + { + return rootCriteria.Projection is IEnhancedProjection + ? ((IEnhancedProjection)rootCriteria.Projection).GetColumnAliases(0, rootCriteria, this) + : rootCriteria.Projection.GetColumnAliases(0); + } } public string[] ProjectedAliases @@ -402,7 +406,7 @@ IType type = lastEntity.ToType(componentPath); if (type.IsAssociationType) { - if(type.IsCollectionType) + if(type.IsCollectionType) { // ignore joinables for composite collections var collectionType = (CollectionType)type; @@ -535,8 +539,7 @@ } /// <summary> - /// Get the names of the columns constrained - /// by this criterion. + /// Get the names of the columns constrained by this criterion. /// </summary> public string[] GetColumnsUsingProjection(ICriteria subcriteria, string propertyName) { Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2010-09-25 20:07:30 UTC (rev 5219) +++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2010-09-26 02:53:50 UTC (rev 5220) @@ -109,6 +109,7 @@ <Compile Include="Connection\DriverConnectionProvider.cs" /> <Compile Include="Connection\IConnectionProvider.cs" /> <Compile Include="Connection\UserSuppliedConnectionProvider.cs" /> + <Compile Include="Criterion\IEnhancedProjection.cs" /> <Compile Include="Dialect\DB2Dialect.cs" /> <Compile Include="Dialect\Dialect.cs" /> <Compile Include="Dialect\FirebirdDialect.cs" /> Added: trunk/nhibernate/src/NHibernate.Test/Criteria/CityState.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/CityState.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/CityState.cs 2010-09-26 02:53:50 UTC (rev 5220) @@ -0,0 +1,31 @@ +using System; + +namespace NHibernate.Test.Criteria +{ + [Serializable] + public class CityState + { + private string city; + private string state; + + public CityState() {} + + public CityState(string city, string state) + { + this.city = city; + this.state = state; + } + + public virtual string City + { + get { return this.city; } + set { this.city = value; } + } + + public virtual string State + { + get { return this.state; } + set { this.state = value; } + } + } +} Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Course.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Course.cs 2010-09-25 20:07:30 UTC (rev 5219) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Course.cs 2010-09-26 02:53:50 UTC (rev 5220) @@ -1,23 +1,30 @@ using System; +using Iesi.Collections.Generic; namespace NHibernate.Test.Criteria { public class Course { private string courseCode; - + private string description; + private ISet<CourseMeeting> courseMeetings = new HashedSet<CourseMeeting>(); + public virtual string CourseCode { get { return courseCode; } set { courseCode = value; } } - private string description; - public virtual string Description { get { return description; } set { description = value; } } + + public virtual ISet<CourseMeeting> CourseMeetings + { + get { return courseMeetings; } + set { courseMeetings = value; } + } } } \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/Criteria/CourseMeeting.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/CourseMeeting.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/CourseMeeting.cs 2010-09-26 02:53:50 UTC (rev 5220) @@ -0,0 +1,28 @@ +namespace NHibernate.Test.Criteria +{ + public class CourseMeeting + { + private CourseMeetingId id; + private Course course; + + public CourseMeeting() { } + + public CourseMeeting(Course course, string day, int period, string location) + { + this.id = new CourseMeetingId(course, day, period, location); + this.course = course; + } + + public virtual CourseMeetingId Id + { + get { return id; } + set { id = value; } + } + + public virtual Course Course + { + get { return course; } + set { course = value; } + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/Criteria/CourseMeetingId.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/CourseMeetingId.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/CourseMeetingId.cs 2010-09-26 02:53:50 UTC (rev 5220) @@ -0,0 +1,60 @@ +using System; + +namespace NHibernate.Test.Criteria +{ + [Serializable] + public class CourseMeetingId + { + private string courseCode; + private string day; + private int period; + private string location; + + public CourseMeetingId() { } + + public CourseMeetingId(Course course, string day, int period, string location) + { + this.courseCode = course.CourseCode; + this.day = day; + this.period = period; + this.location = location; + } + + public virtual string CourseCode + { + get { return courseCode; } + set { courseCode = value; } + } + + public virtual string Day + { + get { return day; } + set { day = value; } + } + + public virtual int Period + { + get { return period; } + set { period = value; } + } + + public virtual string Location + { + get { return location; } + set { location = value; } + } + + public override bool Equals(object obj) + { + CourseMeetingId that = obj as CourseMeetingId; + if (that == null) + return false; + return courseCode == that.CourseCode && day == that.Day && period == that.Period && location == that.Location; + } + + public override int GetHashCode() + { + return courseCode.GetHashCode() ^ day.GetHashCode() ^ period.GetHashCode() ^ location.GetHashCode(); + } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/CriteriaQueryTest.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/CriteriaQueryTest.cs 2010-09-25 20:07:30 UTC (rev 5219) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/CriteriaQueryTest.cs 2010-09-26 02:53:50 UTC (rev 5220) @@ -67,7 +67,7 @@ using (ISession session = OpenSession()) { - // finds all courses which contain '%' as the first char in the description + // finds all courses which contain '%' as the first char in the description Course example = new Course(); example.Description = "&%%"; IList result = @@ -237,8 +237,14 @@ t.Commit(); session.Close(); } - + [Test] + [Ignore("To be implemented")] + public void SubselectWithComponent() + { + } + + [Test] public void CloningCriteria() { ISession s = OpenSession(); @@ -255,7 +261,7 @@ } [Test] - public void CloningCriteria_AddCount_RemoveOrderring() + public void CloningCriteria_AddCount_RemoveOrdering() { ISession s = OpenSession(); ITransaction t = s.BeginTransaction(); @@ -353,7 +359,7 @@ [Test] public void SubqueryPagination() - { + { using (ISession session = OpenSession()) using (ITransaction t = session.BeginTransaction()) { @@ -690,7 +696,7 @@ Enrolment key = new Enrolment(); key.CourseCode = "HIB"; - key.StudentNumber = 101;// xam + key.StudentNumber = 101;// xam //since we didn't load xam's entrollments before (skipped by orderring) //it should not be already loaded Enrolment shouldNotBeLoaded = (Enrolment)s.Load(typeof(Enrolment), key); @@ -1228,6 +1234,7 @@ object[] array = (object[])s.CreateCriteria(typeof(Enrolment)) .SetProjection(Projections.ProjectionList().Add(p1).Add(p2)) .UniqueResult(); + Assert.AreEqual(7, array.Length); IList list = s.CreateCriteria(typeof(Enrolment)) @@ -1249,8 +1256,20 @@ t.Commit(); s.Close(); } + + [Test] + [Ignore("To be implemented")] + public void DistinctProjectionsOfComponents() + { + } [Test] + [Ignore("To be implemented")] + public void GroupByComponent() + { + } + + [Test] public void CloningProjectionsUsingProperty() { ISession s = OpenSession(); @@ -1479,8 +1498,182 @@ t.Rollback(); s.Close(); } + + [Test] + public void ProjectedEmbeddedCompositeId() + { + using (ISession s = OpenSession()) + using (ITransaction t = s.BeginTransaction()) + { + Course course = new Course(); + course.CourseCode = "HIB"; + course.Description = "Hibernate Training"; + s.Save(course); + + Student gavin = new Student(); + gavin.Name = "Gavin King"; + gavin.StudentNumber = 667; + s.Save(gavin); + + Student xam = new Student(); + xam.Name = "Max Rydahl Andersen"; + xam.StudentNumber = 101; + s.Save(xam); + + Enrolment enrolment = new Enrolment(); + enrolment.Course = course; + enrolment.CourseCode = course.CourseCode; + enrolment.Semester = 1; + enrolment.Year = 1999; + enrolment.Student = xam; + enrolment.StudentNumber = xam.StudentNumber; + gavin.Enrolments.Add(enrolment); + s.Save(enrolment); + + enrolment = new Enrolment(); + enrolment.Course = course; + enrolment.CourseCode = course.CourseCode; + enrolment.Semester = 3; + enrolment.Year = 1998; + enrolment.Student = gavin; + enrolment.StudentNumber = gavin.StudentNumber; + gavin.Enrolments.Add(enrolment); + s.Save(enrolment); + + s.Flush(); + + IList enrolments = (IList)s.CreateCriteria<Enrolment>() + .SetProjection(Projections.Id()) + .List(); + + t.Rollback(); + } + } + + [Test] + public void ProjectedListIncludesEmbeddedCompositeId() + { + using (ISession s = OpenSession()) + using (ITransaction t = s.BeginTransaction()) + { + Course course = new Course(); + course.CourseCode = "HIB"; + course.Description = "Hibernate Training"; + s.Save(course); + + Student gavin = new Student(); + gavin.Name = "Gavin King"; + gavin.StudentNumber = 667; + s.Save(gavin); + + Student xam = new Student(); + xam.Name = "Max Rydahl Andersen"; + xam.StudentNumber = 101; + s.Save(xam); + + Enrolment enrolment = new Enrolment(); + enrolment.Course = course; + enrolment.CourseCode = course.CourseCode; + enrolment.Semester = 1; + enrolment.Year = 1999; + enrolment.Student = xam; + enrolment.StudentNumber = xam.StudentNumber; + gavin.Enrolments.Add(enrolment); + s.Save(enrolment); + + enrolment = new Enrolment(); + enrolment.Course = course; + enrolment.CourseCode = course.CourseCode; + enrolment.Semester = 3; + enrolment.Year = 1998; + enrolment.Student = gavin; + enrolment.StudentNumber = gavin.StudentNumber; + gavin.Enrolments.Add(enrolment); + s.Save(enrolment); + + s.Flush(); + + IList data = (IList)s.CreateCriteria<Enrolment>() + .SetProjection(Projections.ProjectionList() + .Add(Projections.Property("Semester")) + .Add(Projections.Property("Year")) + .Add(Projections.Id())) + .List(); + + t.Rollback(); + } + } + + [Test] + public void ProjectedCompositeId() + { + using (ISession s = OpenSession()) + using (ITransaction t = s.BeginTransaction()) + { + Course course = new Course(); + course.CourseCode = "HIB"; + course.Description = "Hibernate Training"; + course.CourseMeetings.Add(new CourseMeeting(course, "Monday", 1, "1313 Mockingbird Lane")); + s.Save(course); + s.Flush(); + + IList data = (IList)s.CreateCriteria<CourseMeeting>().SetProjection(Projections.Id()).List(); + t.Rollback(); + } + } + [Test] + [Ignore("To be implemented")] + public void ProjectedCompositeIdWithAlias() + { + } + + [Test] + public void ProjectedComponent() + { + using (ISession s = OpenSession()) + using (ITransaction t = s.BeginTransaction()) + { + Student gaith = new Student(); + gaith.Name = "Gaith Bell"; + gaith.StudentNumber = 123; + gaith.CityState = new CityState("Chicago", "Illinois"); + s.Save(gaith); + s.Flush(); + + IList cityStates = (IList)s.CreateCriteria<Student>() + .SetProjection(Projections.Property("CityState")) + .List(); + + t.Rollback(); + } + } + + [Test] + public void ProjectedListIncludesComponent() + { + using (ISession s = OpenSession()) + using (ITransaction t = s.BeginTransaction()) + { + Student gaith = new Student(); + gaith.Name = "Gaith Bell"; + gaith.StudentNumber = 123; + gaith.CityState = new CityState("Chicago", "Illinois"); + s.Save(gaith); + s.Flush(); + + IList data = (IList)s.CreateCriteria<Student>() + .SetProjection(Projections.ProjectionList() + .Add(Projections.Property("CityState")) + .Add(Projections.Property("Name"))) + .List(); + + t.Rollback(); + } + } + + [Test] public void CloningProjectedId() { ISession s = OpenSession(); @@ -1871,7 +2064,7 @@ t.Commit(); } } - + [Test] public void TransformToRowCountTest() { @@ -1910,53 +2103,53 @@ } [Test] - public void OrderProjectionAliasedTest() - { - ISession session = OpenSession(); - ITransaction t = session.BeginTransaction(); + public void OrderProjectionAliasedTest() + { + ISession session = OpenSession(); + ITransaction t = session.BeginTransaction(); - Course courseA = new Course(); - courseA.CourseCode = "HIB-A"; - courseA.Description = "Hibernate Training A"; - session.Save(courseA); + Course courseA = new Course(); + courseA.CourseCode = "HIB-A"; + courseA.Description = "Hibernate Training A"; + session.Save(courseA); - Student gavin = new Student(); - gavin.Name = "Gavin King"; - gavin.StudentNumber = 232; - gavin.PreferredCourse = courseA; - session.Save(gavin); + Student gavin = new Student(); + gavin.Name = "Gavin King"; + gavin.StudentNumber = 232; + gavin.PreferredCourse = courseA; + session.Save(gavin); - Student leonardo = new Student(); - leonardo.Name = "Leonardo Quijano"; - leonardo.StudentNumber = 233; - leonardo.PreferredCourse = courseA; - session.Save(leonardo); + Student leonardo = new Student(); + leonardo.Name = "Leonardo Quijano"; + leonardo.StudentNumber = 233; + leonardo.PreferredCourse = courseA; + session.Save(leonardo); - Student johnDoe = new Student(); - johnDoe.Name = "John Doe"; - johnDoe.StudentNumber = 235; - johnDoe.PreferredCourse = null; - session.Save(johnDoe); + Student johnDoe = new Student(); + johnDoe.Name = "John Doe"; + johnDoe.StudentNumber = 235; + johnDoe.PreferredCourse = null; + session.Save(johnDoe); - IProjection conditional = + IProjection conditional = Projections.Conditional( - Restrictions.Eq("Name", "Gavin King"), - Projections.Constant("Name"), + Restrictions.Eq("Name", "Gavin King"), + Projections.Constant("Name"), Projections.Constant("AnotherName")); - ICriteria criteria = session.CreateCriteria(typeof(Student)); - criteria.SetMaxResults(1); - criteria.SetFirstResult(1); - IList result = criteria.SetProjection(Projections.Alias(conditional, "CheckName")) - .AddOrder(Order.Asc("CheckName")) - .List(); + ICriteria criteria = session.CreateCriteria(typeof(Student)); + criteria.SetMaxResults(1); + criteria.SetFirstResult(1); + IList result = criteria.SetProjection(Projections.Alias(conditional, "CheckName")) + .AddOrder(Order.Asc("CheckName")) + .List(); - session.Delete(gavin); - session.Delete(leonardo); - session.Delete(johnDoe); - session.Delete(courseA); - t.Commit(); - session.Close(); + session.Delete(gavin); + session.Delete(leonardo); + session.Delete(johnDoe); + session.Delete(courseA); + t.Commit(); + session.Close(); } [Test] Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Enrolment.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Enrolment.cs 2010-09-25 20:07:30 UTC (rev 5219) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Enrolment.cs 2010-09-26 02:53:50 UTC (rev 5220) @@ -6,47 +6,42 @@ public class Enrolment { private Student student; - + private Course course; + private long studentNumber; + private string courseCode = string.Empty; + private short year; + private short semester; + public virtual Student Student { get { return student; } set { student = value; } } - private Course course; - public virtual Course Course { get { return course; } set { course = value; } } - private long studentNumber; - public virtual long StudentNumber { get { return studentNumber; } set { studentNumber = value; } } - private string courseCode = string.Empty; - public virtual string CourseCode { get { return courseCode; } set { courseCode = value; } } - private short year; - public virtual short Year { get { return year; } set { year = value; } } - private short semester; - public virtual short Semester { get { return semester; } Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Enrolment.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Enrolment.hbm.xml 2010-09-25 20:07:30 UTC (rev 5219) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Enrolment.hbm.xml 2010-09-26 02:53:50 UTC (rev 5220) @@ -1,5 +1,6 @@ <?xml version="1.0"?> -<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" +<hibernate-mapping + xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernate.Test" namespace="NHibernate.Test.Criteria"> @@ -8,19 +9,39 @@ <generator class="assigned"/> </id> <property name="Description"/> + <set name="CourseMeetings" inverse="true" cascade="all-delete-orphan"> + <key column="CourseCode"/> + <one-to-many class="CourseMeeting"/> + </set> </class> + <class name="CourseMeeting"> + <composite-id name="Id" class="CourseMeetingId"> + <key-property name="CourseCode"/> + <key-property name="Day"/> + <key-property name="Period"/> + <key-property name="Location"/> + </composite-id> + <many-to-one name="Course" insert="false" update="false"> + <column name="courseCode"/> + </many-to-one> + </class> + <class name="Student"> <id name="StudentNumber"> - <column name="studentId"/> + <column name="studentId"/> <generator class="assigned"/> </id> <property name="Name" not-null="true"/> + <component name="CityState"> + <property name="City" column="address_city"/> + <property name="State" column="address_state"/> + </component> <set name="Enrolments" inverse="true" cascade="delete" fetch="subselect"> <key column="studentId"/> <one-to-many class="Enrolment"/> </set> - <many-to-one name="PreferredCourse" column="preferredCourseCode"/> + <many-to-one name="PreferredCourse" column="preferredCourseCode"/> </class> <class name="Enrolment"> Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Student.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Student.cs 2010-09-25 20:07:30 UTC (rev 5219) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Student.cs 2010-09-26 02:53:50 UTC (rev 5220) @@ -6,31 +6,35 @@ public class Student { private long studentNumber; - + private string name; + private CityState cityState; + private Course preferredCourse; + private ISet enrolments = new HashedSet(); + public virtual long StudentNumber { get { return studentNumber; } set { studentNumber = value; } } - private string name; - public virtual string Name { get { return name; } set { name = value; } } + + public virtual CityState CityState + { + get { return cityState; } + set { cityState = value; } + } - private Course preferredCourse; - public virtual Course PreferredCourse { get { return preferredCourse; } set { preferredCourse = value; } } - private ISet enrolments = new HashedSet(); - public virtual ISet Enrolments { get { return enrolments; } Property changes on: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2202 ___________________________________________________________________ Added: bugtraq:url + http://jira.nhibernate.org/browse/%BUGID% Added: bugtraq:logregex + NH-\d+ Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2202/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2202/Fixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2202/Fixture.cs 2010-09-26 02:53:50 UTC (rev 5220) @@ -0,0 +1,58 @@ +namespace NHibernate.Test.NHSpecificTest.NH2202 +{ + using System.Linq; + using Criterion; + using NUnit.Framework; + + [TestFixture] + public class Fixture : BugTestCase + { + protected override void OnSetUp() + { + base.OnSetUp(); + + using (var s = OpenSession()) + using (var tx = s.BeginTransaction()) + { + var emp = new Employee() {EmployeeId = 1, NationalId = 1000}; + emp.Addresses.Add(new EmployeeAddress() { Employee = emp, Type = "Postal" }); + emp.Addresses.Add(new EmployeeAddress() { Employee = emp, Type = "Shipping" }); + s.Save(emp); + tx.Commit(); + } + } + + protected override void OnTearDown() + { + using (var s = OpenSession()) + using (var tx = s.BeginTransaction()) + { + s.Delete("from EmployeeAddress"); + tx.Commit(); + } + + using (var s = OpenSession()) + using (var tx = s.BeginTransaction()) + { + s.Delete("from Employee"); + tx.Commit(); + } + + base.OnTearDown(); + } + + [Test] + public void CanProjectEmployeeFromAddressUsingCriteria() + { + using (var s = OpenSession()) + { + var employees = s.CreateCriteria<EmployeeAddress>("x3") + .Add(Restrictions.Eq("Type", "Postal")) + .SetProjection(Projections.Property("Employee")) + .List<Employee>(); + + Assert.That(employees.FirstOrDefault(), Is.InstanceOf<Employee>()); + } + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2202/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2202/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2202/Mappings.hbm.xml 2010-09-26 02:53:50 UTC (rev 5220) @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping + xmlns="urn:nhibernate-mapping-2.2" + assembly="NHibernate.Test" + namespace="NHibernate.Test.NHSpecificTest.NH2202"> + + <class name="Employee"> + + <composite-id> + <key-property name="NationalId" /> + <key-property name="EmployeeId" /> + </composite-id> + + <set name="Addresses" cascade="save-update"> + <key> + <column name="NationalId" /> + <column name="EmployeeId" /> + </key> + <one-to-many class="EmployeeAddress"/> + </set> + + </class> + + <class name="EmployeeAddress"> + + <composite-id> + <key-many-to-one name="Employee" class="Employee"> + <column name="NationalId" /> + <column name="EmployeeId" /> + </key-many-to-one> + <key-property name="Type" /> + </composite-id> + + </class> + +</hibernate-mapping> \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2202/Model.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2202/Model.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2202/Model.cs 2010-09-26 02:53:50 UTC (rev 5220) @@ -0,0 +1,77 @@ +using System; +using Iesi.Collections; + +namespace NHibernate.Test.NHSpecificTest.NH2202 +{ + public class Employee + { + private ISet _addresses; + + public virtual int NationalId { get; set; } + public virtual int EmployeeId { get; set; } + + public virtual ISet Addresses + { + get + { + return _addresses ?? (_addresses = new HashedSet()); + } + set + { + _addresses = value; + } + } + + public virtual bool Equals(Employee other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return other.NationalId == NationalId && other.EmployeeId == EmployeeId; + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != typeof (Employee)) return false; + return Equals((Employee) obj); + } + + public override int GetHashCode() + { + unchecked + { + return (NationalId*397) ^ EmployeeId; + } + } + } + + public class EmployeeAddress + { + public virtual Employee Employee { get; set; } + public virtual string Type { get; set; } + + public virtual bool Equals(EmployeeAddress other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Equals(other.Employee, Employee) && Equals(other.Type, Type); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != typeof (EmployeeAddress)) return false; + return Equals((EmployeeAddress) obj); + } + + public override int GetHashCode() + { + unchecked + { + return ((Employee != null ? Employee.GetHashCode() : 0)*397) ^ (Type != null ? Type.GetHashCode() : 0); + } + } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-09-25 20:07:30 UTC (rev 5219) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-09-26 02:53:50 UTC (rev 5220) @@ -164,7 +164,10 @@ <Compile Include="ConventionsTestCase.cs" /> <Compile Include="Criteria\AddNumberProjection.cs" /> <Compile Include="Criteria\Animal.cs" /> + <Compile Include="Criteria\CityState.cs" /> <Compile Include="Criteria\Course.cs" /> + <Compile Include="Criteria\CourseMeeting.cs" /> + <Compile Include="Criteria\CourseMeetingId.cs" /> <Compile Include="Criteria\CriteriaQueryTest.cs" /> <Compile Include="Criteria\DetachedCriteriaSerializable.cs" /> <Compile Include="Criteria\Enrolment.cs" /> @@ -474,6 +477,8 @@ <Compile Include="NHSpecificTest\NH2148\BugFixture.cs" /> <Compile Include="NHSpecificTest\NH2148\Domain.cs" /> <Compile Include="NHSpecificTest\NH2188\AppDomainWithMultipleSearchPath.cs" /> + <Compile Include="NHSpecificTest\NH2202\Fixture.cs" /> + <Compile Include="NHSpecificTest\NH2202\Model.cs" /> <Compile Include="NHSpecificTest\NH2224\Domain.cs" /> <Compile Include="NHSpecificTest\NH2224\Fixture.cs" /> <Compile Include="NHSpecificTest\NH2245\Fixture.cs" /> @@ -1791,6 +1796,7 @@ <EmbeddedResource Include="NHSpecificTest\NH2322\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2278\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH1136\Mappings.hbm.xml" /> + <EmbeddedResource Include="NHSpecificTest\NH2202\Mappings.hbm.xml" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\NHibernate.ByteCode.Castle\NHibernate.ByteCode.Castle.csproj"> @@ -2644,6 +2650,7 @@ <EmbeddedResource Include="DynamicEntity\Tuplizer\Customer.hbm.xml" /> </ItemGroup> <ItemGroup> + <Folder Include="NHSpecificTest\NH2202" /> <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. |