From: <fab...@us...> - 2011-05-31 19:56:35
|
Revision: 5901 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5901&view=rev Author: fabiomaulo Date: 2011-05-31 19:56:28 +0000 (Tue, 31 May 2011) Log Message: ----------- usage of IParameterSpecification for Criteria (step 2) Modified Paths: -------------- 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/SimpleExpression.cs trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs trunk/nhibernate/src/NHibernate/NHibernate.csproj trunk/nhibernate/src/NHibernate.Test/Criteria/AddNumberProjection.cs Added Paths: ----------- trunk/nhibernate/src/NHibernate/Param/CriteriaNamedParameterSpecification.cs Modified: trunk/nhibernate/src/NHibernate/Criterion/BetweenExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/BetweenExpression.cs 2011-05-31 17:46:14 UTC (rev 5900) +++ trunk/nhibernate/src/NHibernate/Criterion/BetweenExpression.cs 2011-05-31 19:56:28 UTC (rev 5901) @@ -1,7 +1,9 @@ using System; using System.Collections.Generic; +using System.Linq; using NHibernate.Engine; using NHibernate.SqlCommand; +using NHibernate.Type; namespace NHibernate.Criterion { @@ -49,7 +51,9 @@ //TODO: add a default capacity SqlStringBuilder sqlBuilder = new SqlStringBuilder(); - //IType propertyType = criteriaQuery.GetTypeUsingProjection( criteria, _propertyName ); + IType[] parametersTypes = GetTypedValues(criteria, criteriaQuery).Select(x=> x.Type).ToArray(); + IType lowType = parametersTypes[0]; + IType highType = parametersTypes[1]; SqlString[] columnNames = CriterionUtil.GetColumnNames(_propertyName, _projection, criteriaQuery, criteria, enabledFilters); @@ -58,14 +62,15 @@ sqlBuilder .Add(columnNames[0]) .Add(" between ") - .Add(criteriaQuery.NewQueryParameter()) + .Add(criteriaQuery.NewQueryParameter(lowType).Single()) .Add(" and ") - .Add(criteriaQuery.NewQueryParameter()); + .Add(criteriaQuery.NewQueryParameter(highType).Single()); } else { bool andNeeded = false; + var lowParameters = criteriaQuery.NewQueryParameter(lowType).ToArray(); for (int i = 0; i < columnNames.Length; i++) { if (andNeeded) @@ -76,15 +81,16 @@ sqlBuilder.Add(columnNames[i]) .Add(" >= ") - .Add(criteriaQuery.NewQueryParameter()); + .Add(lowParameters[i]); } + var highParameters = criteriaQuery.NewQueryParameter(highType).ToArray(); for (int i = 0; i < columnNames.Length; i++) { sqlBuilder.Add(" AND ") .Add(columnNames[i]) .Add(" <= ") - .Add(criteriaQuery.NewQueryParameter()); + .Add(highParameters[i]); } } Modified: trunk/nhibernate/src/NHibernate/Criterion/ConstantProjection.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/ConstantProjection.cs 2011-05-31 17:46:14 UTC (rev 5900) +++ trunk/nhibernate/src/NHibernate/Criterion/ConstantProjection.cs 2011-05-31 19:56:28 UTC (rev 5901) @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using NHibernate.Engine; using NHibernate.SqlCommand; using NHibernate.Type; @@ -43,7 +44,7 @@ public override SqlString ToSqlString(ICriteria criteria, int position, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters) { return new SqlStringBuilder() - .Add(criteriaQuery.NewQueryParameter()) + .Add(criteriaQuery.NewQueryParameter(type).Single()) .Add(" as ") .Add(GetColumnAliases(position)[0]) .ToSqlString(); Modified: trunk/nhibernate/src/NHibernate/Criterion/ICriteriaQuery.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/ICriteriaQuery.cs 2011-05-31 17:46:14 UTC (rev 5900) +++ trunk/nhibernate/src/NHibernate/Criterion/ICriteriaQuery.cs 2011-05-31 19:56:28 UTC (rev 5901) @@ -1,6 +1,5 @@ using System.Collections.Generic; using NHibernate.Engine; -using NHibernate.Param; using NHibernate.SqlCommand; using NHibernate.Type; @@ -72,8 +71,9 @@ /// <summary> /// Create a new query parameter to use in a <see cref="ICriterion"/> /// </summary> + /// <param name="parameterType">The expected type of the parameter.</param> /// <returns>A new instance of a query parameter to be added to a <see cref="SqlString"/>.</returns> - Parameter NewQueryParameter(); + IEnumerable<Parameter> NewQueryParameter(IType parameterType); /// <summary> /// Creates a dummy parameter index for the supplied paged value. Modified: trunk/nhibernate/src/NHibernate/Criterion/IdentifierEqExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/IdentifierEqExpression.cs 2011-05-31 17:46:14 UTC (rev 5900) +++ trunk/nhibernate/src/NHibernate/Criterion/IdentifierEqExpression.cs 2011-05-31 19:56:28 UTC (rev 5901) @@ -1,7 +1,9 @@ using System; using System.Collections.Generic; +using System.Linq; using NHibernate.Engine; using NHibernate.SqlCommand; +using NHibernate.Type; using NHibernate.Util; namespace NHibernate.Criterion @@ -32,6 +34,8 @@ { //Implementation changed from H3.2 to use SqlString string[] columns = criteriaQuery.GetIdentifierColumns(criteria); + Parameter[] parameters = GetTypedValues(criteria, criteriaQuery).Select(x => x.Type).SelectMany(t => criteriaQuery.NewQueryParameter(t)).ToArray(); + SqlStringBuilder result = new SqlStringBuilder(4 * columns.Length + 2); if (columns.Length > 1) { @@ -48,7 +52,7 @@ result.Add(columns[i]) .Add(" = "); - AddValueOrProjection(criteria, criteriaQuery, enabledFilters, result); + AddValueOrProjection(parameters, i, criteria, criteriaQuery, enabledFilters, result); } if (columns.Length > 1) @@ -58,15 +62,15 @@ return result.ToSqlString(); } - private void AddValueOrProjection(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters, SqlStringBuilder result) + private void AddValueOrProjection(Parameter[] parameters, int paramIndex, ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters, SqlStringBuilder result) { if (_projection == null) { - result.Add(criteriaQuery.NewQueryParameter()); + result.Add(parameters[paramIndex]); } else { - SqlString sql = _projection.ToSqlString(criteria, GetHashCode(),criteriaQuery, enabledFilters); + SqlString sql = _projection.ToSqlString(criteria, GetHashCode(), criteriaQuery, enabledFilters); result.Add(StringHelper.RemoveAsAliasesFromSql(sql)); } } Modified: trunk/nhibernate/src/NHibernate/Criterion/InExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/InExpression.cs 2011-05-31 17:46:14 UTC (rev 5900) +++ trunk/nhibernate/src/NHibernate/Criterion/InExpression.cs 2011-05-31 19:56:28 UTC (rev 5901) @@ -1,6 +1,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Linq; using NHibernate.Engine; using NHibernate.SqlCommand; using NHibernate.Type; @@ -68,6 +69,7 @@ // Generate SqlString of the form: // columnName1 in (values) and columnName2 in (values) and ... + Parameter[] parameters = GetTypedValues(criteria, criteriaQuery).Select(x => x.Type).SelectMany(t => criteriaQuery.NewQueryParameter(t)).ToArray(); for (int columnIndex = 0; columnIndex < columnNames.Length; columnIndex++) { @@ -88,7 +90,7 @@ { result.Add(StringHelper.CommaSpace); } - result.Add(criteriaQuery.NewQueryParameter()); + result.Add(parameters[i]); } result.Add(")"); Modified: trunk/nhibernate/src/NHibernate/Criterion/InsensitiveLikeExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/InsensitiveLikeExpression.cs 2011-05-31 17:46:14 UTC (rev 5900) +++ trunk/nhibernate/src/NHibernate/Criterion/InsensitiveLikeExpression.cs 2011-05-31 19:56:28 UTC (rev 5901) @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using NHibernate.Dialect; using NHibernate.Engine; using NHibernate.SqlCommand; @@ -84,7 +85,7 @@ .Add(" like "); } - sqlBuilder.Add(criteriaQuery.NewQueryParameter()); + sqlBuilder.Add(criteriaQuery.NewQueryParameter(NHibernateUtil.String).Single()); return sqlBuilder.ToSqlString(); } Modified: trunk/nhibernate/src/NHibernate/Criterion/LikeExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/LikeExpression.cs 2011-05-31 17:46:14 UTC (rev 5900) +++ trunk/nhibernate/src/NHibernate/Criterion/LikeExpression.cs 2011-05-31 19:56:28 UTC (rev 5901) @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using NHibernate.Engine; using NHibernate.SqlCommand; using NHibernate.Util; @@ -79,11 +80,11 @@ lhs.Add(" like ") .Add(dialect.LowercaseFunction) .Add(StringHelper.OpenParen) - .Add(criteriaQuery.NewQueryParameter()) + .Add(criteriaQuery.NewQueryParameter(NHibernateUtil.String).Single()) .Add(StringHelper.ClosedParen); } else - lhs.Add(" like ").Add(criteriaQuery.NewQueryParameter()); + lhs.Add(" like ").Add(criteriaQuery.NewQueryParameter(NHibernateUtil.String).Single()); if (escapeChar.HasValue) lhs.Add(" escape '" + escapeChar + "'"); Modified: trunk/nhibernate/src/NHibernate/Criterion/SimpleExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/SimpleExpression.cs 2011-05-31 17:46:14 UTC (rev 5900) +++ trunk/nhibernate/src/NHibernate/Criterion/SimpleExpression.cs 2011-05-31 19:56:28 UTC (rev 5901) @@ -1,7 +1,9 @@ using System; using System.Collections.Generic; +using System.Linq; using NHibernate.Engine; using NHibernate.SqlCommand; +using NHibernate.Type; using NHibernate.Util; namespace NHibernate.Criterion @@ -86,6 +88,8 @@ this, value); + Parameter[] parameters = GetTypedValues(criteria, criteriaQuery).Select(x => x.Type).SelectMany(t => criteriaQuery.NewQueryParameter(t)).ToArray(); + if (ignoreCase) { if (columnNames.Length != 1) @@ -101,7 +105,7 @@ .Add(columnNames[0]) .Add(StringHelper.ClosedParen) .Add(Op) - .Add(criteriaQuery.NewQueryParameter()) + .Add(parameters.FirstOrDefault()) .ToSqlString(); } else @@ -117,7 +121,7 @@ sqlBuilder.Add(columnNames[i]) .Add(Op) - .Add(criteriaQuery.NewQueryParameter()); + .Add(parameters[i]); } return sqlBuilder.ToSqlString(); } Modified: trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs 2011-05-31 17:46:14 UTC (rev 5900) +++ trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs 2011-05-31 19:56:28 UTC (rev 5901) @@ -8,6 +8,7 @@ using NHibernate.Engine; using NHibernate.Hql.Util; using NHibernate.Impl; +using NHibernate.Param; using NHibernate.Persister.Collection; using NHibernate_Persister_Entity = NHibernate.Persister.Entity; using NHibernate.SqlCommand; @@ -19,10 +20,10 @@ public class CriteriaQueryTranslator : ICriteriaQuery { public static readonly string RootSqlAlias = CriteriaSpecification.RootAlias + '_'; - private static readonly IInternalLogger logger = LoggerProvider.LoggerFor(typeof(CriteriaQueryTranslator)); private const int AliasCount = 0; + private readonly string queryTranslatorId = Guid.NewGuid().ToString("N"); private readonly ICriteriaQuery outerQueryTranslator; private readonly CriteriaImpl rootCriteria; @@ -44,6 +45,7 @@ private readonly IDictionary<string, ICriteria> associationPathCriteriaMap = new LinkedHashMap<string, ICriteria>(); private readonly IDictionary<string, JoinType> associationPathJoinTypesMap = new LinkedHashMap<string, JoinType>(); private readonly IDictionary<string, ICriterion> withClauseMap = new Dictionary<string, ICriterion>(); + private readonly IList<IParameterSpecification> collectedParameterSpecifications = new List<IParameterSpecification>(); private readonly ISessionFactoryImplementor sessionFactory; private SessionFactoryHelper helper; @@ -772,9 +774,18 @@ return indexForAlias++; } - public Parameter NewQueryParameter() + public IEnumerable<Parameter> NewQueryParameter(IType parameterType) { - return Parameter.Placeholder; + // the queryTranslatorId is to avoid possible conflicts using sub-queries + string parameterName = string.Format("cr_{0}_p{1}", queryTranslatorId, collectedParameterSpecifications.Count); + var specification = new CriteriaNamedParameterSpecification(parameterName, parameterType); + collectedParameterSpecifications.Add(specification); + return specification.GetIdsForBackTrack(Factory).Select(x => + { + Parameter p = Parameter.Placeholder; + p.BackTrack = x; + return p; + }); } public int? CreatePagingParameter(int value) Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2011-05-31 17:46:14 UTC (rev 5900) +++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2011-05-31 19:56:28 UTC (rev 5901) @@ -496,6 +496,7 @@ <Compile Include="NonUniqueResultException.cs" /> <Compile Include="ObjectDeletedException.cs" /> <Compile Include="ObjectNotFoundException.cs" /> + <Compile Include="Param\CriteriaNamedParameterSpecification.cs" /> <Compile Include="Param\ParametersBackTrackExtensions.cs" /> <Compile Include="Param\QuerySkipParameterSpecification.cs" /> <Compile Include="Param\QueryTakeParameterSpecification.cs" /> Added: trunk/nhibernate/src/NHibernate/Param/CriteriaNamedParameterSpecification.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Param/CriteriaNamedParameterSpecification.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Param/CriteriaNamedParameterSpecification.cs 2011-05-31 19:56:28 UTC (rev 5901) @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using NHibernate.Engine; +using NHibernate.SqlCommand; +using NHibernate.Type; + +namespace NHibernate.Param +{ + public class CriteriaNamedParameterSpecification : IParameterSpecification + { + private const string CriteriaNamedParameterIdTemplate = "<criteria-nh{0}_span{1}>"; + private readonly string name; + + public CriteriaNamedParameterSpecification(string name, IType expectedType) + { + this.name = name; + ExpectedType = expectedType; + } + + #region IParameterSpecification Members + + public void Bind(IDbCommand command, IList<Parameter> sqlQueryParametersList, QueryParameters queryParameters, ISessionImplementor session) + { + TypedValue typedValue = queryParameters.NamedParameters[name]; + string backTrackId = GetIdsForBackTrack(session.Factory).First(); + foreach (int position in sqlQueryParametersList.GetEffectiveParameterLocations(backTrackId)) + { + ExpectedType.NullSafeSet(command, typedValue.Value, position, session); + } + } + + public IType ExpectedType { get; set; } + + public string RenderDisplayInfo() + { + const string format = "criteria: parameter-name={0}, expectedType={1}"; + return ExpectedType != null ? string.Format(format, name, ExpectedType) : string.Format(format, name, "Unknow"); + } + + public IEnumerable<string> GetIdsForBackTrack(IMapping sessionFactory) + { + int paremeterSpan = GetParemeterSpan(sessionFactory); + for (int i = 0; i < paremeterSpan; i++) + { + yield return string.Format(CriteriaNamedParameterIdTemplate, name, i); + } + } + + #endregion + + protected int GetParemeterSpan(IMapping sessionFactory) + { + if (sessionFactory == null) + { + throw new ArgumentNullException("sessionFactory"); + } + return ExpectedType.GetColumnSpan(sessionFactory); + } + + public override bool Equals(object obj) + { + return base.Equals(obj as CriteriaNamedParameterSpecification); + } + + public bool Equals(CriteriaNamedParameterSpecification other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + if (ReferenceEquals(this, other)) + { + return true; + } + return Equals(other.name, name); + } + + public override int GetHashCode() + { + return name.GetHashCode() ^ 211; + } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/AddNumberProjection.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/AddNumberProjection.cs 2011-05-31 17:46:14 UTC (rev 5900) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/AddNumberProjection.cs 2011-05-31 19:56:28 UTC (rev 5901) @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using NHibernate.Engine; using NHibernate.Criterion; using NHibernate.SqlCommand; @@ -31,7 +32,7 @@ .Add("(") .Add(projection[0]) .Add(" + ") - .Add(criteriaQuery.NewQueryParameter()) + .Add(criteriaQuery.NewQueryParameter(NHibernateUtil.Int32).Single()) .Add(") as ") .Add(GetColumnAliases(0)[0]) .ToSqlString(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |