From: <aye...@us...> - 2008-10-15 17:01:59
|
Revision: 3859 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3859&view=rev Author: ayenderahien Date: 2008-10-15 16:59:19 +0000 (Wed, 15 Oct 2008) Log Message: ----------- Fixed NH-1527 - order by with parameters in conjunction with SetMaxResults on sql 2005. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs trunk/nhibernate/src/NHibernate.Test/ProjectionFixtures/Fixture.cs Modified: trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs 2008-10-15 13:58:32 UTC (rev 3858) +++ trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs 2008-10-15 16:59:19 UTC (rev 3859) @@ -46,24 +46,24 @@ { int fromIndex = GetFromIndex(querySqlString); SqlString select = querySqlString.Substring(0, fromIndex); - List<string> columnsOrAliases; - Dictionary<string, string> aliasToColumn; + List<SqlString> columnsOrAliases; + Dictionary<SqlString, SqlString> aliasToColumn; ExtractColumnOrAliasNames(select, out columnsOrAliases, out aliasToColumn); int orderIndex = querySqlString.LastIndexOfCaseInsensitive(" order by "); SqlString from; - string[] sortExpressions; + SqlString[] sortExpressions; if (orderIndex > 0) { from = querySqlString.Substring(fromIndex, orderIndex - fromIndex).Trim(); - string orderBy = querySqlString.Substring(orderIndex).ToString().Trim(); - sortExpressions = orderBy.Substring(9).Split(','); + SqlString orderBy = querySqlString.Substring(orderIndex).Trim(); + sortExpressions = orderBy.Substring(9).Split(","); } else { from = querySqlString.Substring(fromIndex).Trim(); // Use dummy sort to avoid errors - sortExpressions = new string[] { "CURRENT_TIMESTAMP" }; + sortExpressions = new SqlString[] { new SqlString("CURRENT_TIMESTAMP"), }; } SqlStringBuilder result = @@ -85,7 +85,7 @@ } for (int i = 0; i < sortExpressions.Length; i++) { - string sortExpression = RemoveSortOrderDirection(sortExpressions[i]); + SqlString sortExpression = RemoveSortOrderDirection(sortExpressions[i]); if (!columnsOrAliases.Contains(sortExpression)) { result.Add(", query.__hibernate_sort_expr_").Add(i.ToString()).Add("__"); @@ -96,7 +96,7 @@ for (int i = 0; i < sortExpressions.Length; i++) { - string sortExpression = RemoveSortOrderDirection(sortExpressions[i]); + SqlString sortExpression = RemoveSortOrderDirection(sortExpressions[i]); if (columnsOrAliases.Contains(sortExpression)) { @@ -118,13 +118,16 @@ return result.ToSqlString(); } - private static string RemoveSortOrderDirection(string sortExpression) + private static SqlString RemoveSortOrderDirection(SqlString sortExpression) { - // Drop the ASC/DESC at the end of the sort expression which might look like "count(distinct frog.Id)desc" or "frog.Name asc". - return Regex.Replace(sortExpression.Trim(), @"(\)|\s)(?i:asc|desc)$", "$1").Trim(); + if (sortExpression.EndsWithCaseInsensitive("asc")) + return sortExpression.Substring(0, sortExpression.Length - 3).Trim(); + if (sortExpression.EndsWithCaseInsensitive("desc")) + return sortExpression.Substring(0, sortExpression.Length - 4).Trim(); + return sortExpression.Trim(); } - private static void AppendSortExpressions(ICollection<string> columnsOrAliases, string[] sortExpressions, + private static void AppendSortExpressions(ICollection<SqlString> columnsOrAliases, SqlString[] sortExpressions, SqlStringBuilder result) { for (int i = 0; i < sortExpressions.Length; i++) @@ -134,7 +137,7 @@ result.Add(", "); } - string sortExpression = RemoveSortOrderDirection(sortExpressions[i]); + SqlString sortExpression = RemoveSortOrderDirection(sortExpressions[i]); if (columnsOrAliases.Contains(sortExpression)) { result.Add(sortExpression); @@ -143,7 +146,7 @@ { result.Add("__hibernate_sort_expr_").Add(i.ToString()).Add("__"); } - if (sortExpressions[i].Trim().ToLower().EndsWith("desc")) + if (sortExpressions[i].Trim().EndsWithCaseInsensitive("desc")) { result.Add(" DESC"); } @@ -161,11 +164,11 @@ return fromIndex; } - private static void ExtractColumnOrAliasNames(SqlString select, out List<string> columnsOrAliases, - out Dictionary<string, string> aliasToColumn) + private static void ExtractColumnOrAliasNames(SqlString select, out List<SqlString> columnsOrAliases, + out Dictionary<SqlString, SqlString> aliasToColumn) { - columnsOrAliases = new List<string>(); - aliasToColumn = new Dictionary<string, string>(); + columnsOrAliases = new List<SqlString>(); + aliasToColumn = new Dictionary<SqlString, SqlString>(); IList<string> tokens = new QuotedAndParenthesisStringTokenizer(select.ToString()).GetTokens(); int index = 0; @@ -222,8 +225,8 @@ index += 2; //skip the "as" and the alias \ } - columnsOrAliases.Add(alias); - aliasToColumn[alias] = token; + columnsOrAliases.Add(new SqlString(alias)); + aliasToColumn[new SqlString(alias)] = new SqlString(token); } } Modified: trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs =================================================================== --- trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs 2008-10-15 13:58:32 UTC (rev 3858) +++ trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs 2008-10-15 16:59:19 UTC (rev 3859) @@ -1,5 +1,6 @@ using System; using System.Collections; +using System.Collections.Generic; using System.Diagnostics; using System.Text; using NHibernate.Util; @@ -734,5 +735,40 @@ { return new SubselectClauseExtractor(Compact().sqlParts).GetSqlString(); } + + public bool EndsWithCaseInsensitive(string value) + { + SqlString tempSql = Compact(); + if (tempSql.Count == 0) + { + return false; + } + + string lastPart = tempSql.sqlParts[tempSql.Count - 1] as string; + + return lastPart != null && lastPart.EndsWith(value,StringComparison.InvariantCultureIgnoreCase); + + } + + public SqlString[] Split(string splitter) + { + int iterations = 0; + SqlString temp = Compact(); + List<SqlString> results = new List<SqlString>(); + int index; + do + { + index = temp.IndexOfCaseInsensitive(splitter); + int locationOfComma = index == -1 ? + temp.Length : + index; + if (iterations++ > 100) + Debugger.Break(); + + results.Add(temp.Substring(0, locationOfComma)); + temp = temp.Substring(locationOfComma+1); + } while (index != -1); + return results.ToArray(); + } } } Modified: trunk/nhibernate/src/NHibernate.Test/ProjectionFixtures/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/ProjectionFixtures/Fixture.cs 2008-10-15 13:58:32 UTC (rev 3858) +++ trunk/nhibernate/src/NHibernate.Test/ProjectionFixtures/Fixture.cs 2008-10-15 16:59:19 UTC (rev 3859) @@ -119,5 +119,26 @@ tx.Commit(); } } + + [Test] + public void LimitingResultSetOnQueryThatIsOrderedByProjection() + { + using(var s = OpenSession()) + { + ICriteria criteria = s.CreateCriteria(typeof(TreeNode), "parent") + .Add(Restrictions.Gt("Key.Id", 0)); + + var currentAssessment = DetachedCriteria.For<TreeNode>("child") + .Add(Restrictions.EqProperty("Key.Id", "parent.Key.Id")) + .Add(Restrictions.EqProperty("Key.Area", "parent.Key.Area")) + .Add(Restrictions.Eq("Type", NodeType.Smart)) + .SetProjection(Projections.Property("Type")); + + criteria.AddOrder(Order.Asc(Projections.SubQuery(currentAssessment))) + .SetMaxResults(1000); + + criteria.List(); + } + } } } \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |