From: <dav...@us...> - 2008-12-30 19:41:36
|
Revision: 3968 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3968&view=rev Author: davybrion Date: 2008-12-30 19:41:26 +0000 (Tue, 30 Dec 2008) Log Message: ----------- fix for NH-1609 Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs trunk/nhibernate/src/NHibernate/Driver/DriverBase.cs trunk/nhibernate/src/NHibernate/Driver/IDriver.cs trunk/nhibernate/src/NHibernate/Driver/SqlStringFormatter.cs trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1609/Fixture.cs Modified: trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs 2008-12-28 22:20:58 UTC (rev 3967) +++ trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs 2008-12-30 19:41:26 UTC (rev 3968) @@ -989,14 +989,6 @@ } /// <summary> - /// How we separate the queries when we use multiply queries. - /// </summary> - public virtual string MultipleQueriesSeparator - { - get { return ";"; } - } - - /// <summary> /// The syntax used to drop a foreign key constraint from a table. /// </summary> /// <param name="constraintName">The name of the foreign key constraint to drop.</param> Modified: trunk/nhibernate/src/NHibernate/Driver/DriverBase.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Driver/DriverBase.cs 2008-12-28 22:20:58 UTC (rev 3967) +++ trunk/nhibernate/src/NHibernate/Driver/DriverBase.cs 2008-12-30 19:41:26 UTC (rev 3968) @@ -166,7 +166,7 @@ private void SetCommandText(IDbCommand cmd, SqlString sqlString) { - SqlStringFormatter formatter = new SqlStringFormatter(this); + SqlStringFormatter formatter = new SqlStringFormatter(this, MultipleQueriesSeparator); formatter.Format(sqlString); cmd.CommandText = formatter.GetFormattedText(); } @@ -227,5 +227,10 @@ { get { return false; } } + + public virtual string MultipleQueriesSeparator + { + get { return ";"; } + } } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Driver/IDriver.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Driver/IDriver.cs 2008-12-28 22:20:58 UTC (rev 3967) +++ trunk/nhibernate/src/NHibernate/Driver/IDriver.cs 2008-12-30 19:41:26 UTC (rev 3968) @@ -66,6 +66,11 @@ bool SupportsMultipleQueries { get; } /// <summary> + /// How we separate the queries when we use multiply queries. + /// </summary> + string MultipleQueriesSeparator { get; } + + /// <summary> /// Generates an IDbCommand from the SqlString according to the requirements of the DataProvider. /// </summary> /// <param name="type">The <see cref="CommandType"/> of the command to generate.</param> Modified: trunk/nhibernate/src/NHibernate/Driver/SqlStringFormatter.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Driver/SqlStringFormatter.cs 2008-12-28 22:20:58 UTC (rev 3967) +++ trunk/nhibernate/src/NHibernate/Driver/SqlStringFormatter.cs 2008-12-30 19:41:26 UTC (rev 3968) @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Text; using NHibernate.SqlCommand; @@ -6,17 +7,23 @@ { public class SqlStringFormatter : ISqlStringVisitor { - private StringBuilder result = new StringBuilder(); + private readonly StringBuilder result = new StringBuilder(); private int parameterIndex = 0; - private ISqlParameterFormatter formatter; + private readonly ISqlParameterFormatter formatter; + private readonly string multipleQueriesSeparator; - public SqlStringFormatter(ISqlParameterFormatter formatter) + private readonly Dictionary<int, int> queryIndexToNumberOfPreceedingParameters = new Dictionary<int, int>(); + private readonly Dictionary<int, int> parameterIndexToQueryIndex = new Dictionary<int, int>(); + + public SqlStringFormatter(ISqlParameterFormatter formatter, string multipleQueriesSeparator) { this.formatter = formatter; + this.multipleQueriesSeparator = multipleQueriesSeparator; } public void Format(SqlString text) { + DetermineNumberOfPreceedingParametersForEachQuery(text); text.Visit(this); } @@ -37,10 +44,62 @@ void ISqlStringVisitor.Parameter(Parameter parameter) { - string name = formatter.GetParameterName( - parameter.OriginalPositionInQuery ?? parameterIndex); + string name; + + if (queryIndexToNumberOfPreceedingParameters.Count == 0) + { + // there's only one query... no need to worry about indexes of parameters of previous queries + name = formatter.GetParameterName(parameter.OriginalPositionInQuery ?? parameterIndex); + } + else + { + // multiple queries... in case the parameters were switched around (for SQL paging for instance) we need + // to keep the number of preceeding parameters (in previous queries of the batch) into account + if (parameter.OriginalPositionInQuery != null) + { + name = formatter.GetParameterName(GetNumberOfPreceedingParameters() + parameter.OriginalPositionInQuery.Value); + } + else + { + name = formatter.GetParameterName(parameterIndex); + } + } + parameterIndex++; result.Append(name); } + + private int GetNumberOfPreceedingParameters() + { + int queryIndex = parameterIndexToQueryIndex[parameterIndex]; + return queryIndexToNumberOfPreceedingParameters[queryIndex]; + } + + private void DetermineNumberOfPreceedingParametersForEachQuery(SqlString text) + { + int currentParameterIndex = 0; + int currentQueryParameterCount = 0; + int currentQueryIndex = 0; + + foreach (object part in text.Parts) + { + if (part.ToString().Equals(multipleQueriesSeparator)) + { + queryIndexToNumberOfPreceedingParameters[currentQueryIndex] = currentParameterIndex - currentQueryParameterCount; + currentQueryParameterCount = 0; + currentQueryIndex++; + continue; + } + + Parameter parameter = part as Parameter; + + if (parameter != null) + { + parameterIndexToQueryIndex[currentParameterIndex] = currentQueryIndex; + currentQueryParameterCount++; + currentParameterIndex++; + } + } + } } } Modified: trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs 2008-12-28 22:20:58 UTC (rev 3967) +++ trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs 2008-12-30 19:41:26 UTC (rev 3968) @@ -174,7 +174,7 @@ parameters.Add(queryParameters); SqlCommandInfo commandInfo = loader.GetQueryStringAndTypes(session, queryParameters); sqlString = sqlString.Append(commandInfo.Text) - .Append(dialect.MultipleQueriesSeparator) + .Append(session.Factory.ConnectionProvider.Driver.MultipleQueriesSeparator) .Append(Environment.NewLine); types.AddRange(commandInfo.ParameterTypes); } Modified: trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs 2008-12-28 22:20:58 UTC (rev 3967) +++ trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs 2008-12-30 19:41:26 UTC (rev 3968) @@ -581,7 +581,7 @@ parameters.Add(queryParameters); queryParameters = GetFilteredQueryParameters(queryParameters, translator); SqlCommandInfo commandInfo = translator.GetQueryStringAndTypes(session, queryParameters); - sqlString = sqlString.Append(commandInfo.Text).Append(dialect.MultipleQueriesSeparator).Append(Environment.NewLine); + sqlString = sqlString.Append(commandInfo.Text).Append(session.Factory.ConnectionProvider.Driver.MultipleQueriesSeparator).Append(Environment.NewLine); types.AddRange(commandInfo.ParameterTypes); } } Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1609/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1609/Fixture.cs 2008-12-28 22:20:58 UTC (rev 3967) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1609/Fixture.cs 2008-12-30 19:41:26 UTC (rev 3968) @@ -8,7 +8,6 @@ namespace NHibernate.Test.NHSpecificTest.NH1609 { [TestFixture] - [Ignore("not fixed yet")] public class Fixture : BugTestCase { [Test] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |