From: <ric...@us...> - 2009-09-15 21:41:10
|
Revision: 4714 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4714&view=rev Author: ricbrown Date: 2009-09-15 21:41:03 +0000 (Tue, 15 Sep 2009) Log Message: ----------- Merge r4713 (Simplify filter parameter reordering and possible fix for NH-1908 threading issue.) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Loader/QueryLoader.cs trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/QueryTranslatorImpl.cs trunk/nhibernate/src/NHibernate/Hql/Classic/QueryTranslator.cs trunk/nhibernate/src/NHibernate/Loader/Collection/SubselectCollectionLoader.cs trunk/nhibernate/src/NHibernate/Loader/Collection/SubselectOneToManyLoader.cs trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs trunk/nhibernate/src/NHibernate/Loader/Loader.cs trunk/nhibernate/src/NHibernate/Param/ParameterTranslationsImpl.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1908ThreadSafety/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1908ThreadSafety/Fixture.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1908ThreadSafety/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1908ThreadSafety/Model.cs Modified: trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs 2009-09-15 21:39:54 UTC (rev 4713) +++ trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs 2009-09-15 21:41:03 UTC (rev 4714) @@ -39,6 +39,7 @@ private object _optionalId; private string _comment; private bool _readOnly; + private IDictionary<int, int> _adjustedParameterLocations; private SqlString processedSQL; @@ -286,15 +287,12 @@ /************** Filters ********************************/ - private void AdjustPostionalParameterLocations(int parameterIndex) + public int FindAdjustedParameterLocation(int parameterIndex) { - for (int i = 0; i < _positionalParameterLocations.Length; i++) - { - if (_positionalParameterLocations[i] >= parameterIndex) - { - _positionalParameterLocations[i]++; - } - } + if (_adjustedParameterLocations == null) + return parameterIndex; + + return _adjustedParameterLocations[parameterIndex]; } public void ProcessFilters(SqlString sql, ISessionImplementor session) @@ -314,7 +312,9 @@ var result = new SqlStringBuilder(); - int parameterIndex = 0; // keep track of the positional parameter + int originalParameterIndex = 0; // keep track of the positional parameter + int newParameterIndex = 0; + _adjustedParameterLocations = new Dictionary<int, int>(); foreach (var part in sql.Parts) { @@ -329,7 +329,9 @@ // types for the named parameters are added later to the end of the list. // see test fixture NH-1098 - parameterIndex++; + _adjustedParameterLocations[originalParameterIndex] = newParameterIndex; + originalParameterIndex++; + newParameterIndex++; continue; } @@ -358,9 +360,8 @@ result.AddParameter(); filteredParameterTypes.Add(type); filteredParameterValues.Add(elementValue); - filteredParameterLocations.Add(parameterIndex); - AdjustPostionalParameterLocations(parameterIndex); - parameterIndex++; + filteredParameterLocations.Add(newParameterIndex); + newParameterIndex++; if (i < coll.Count) { result.Add(", "); @@ -376,9 +377,8 @@ result.AddParameter(); filteredParameterTypes.Add(type); filteredParameterValues.Add(value); - filteredParameterLocations.Add(parameterIndex); - AdjustPostionalParameterLocations(parameterIndex); - parameterIndex++; + filteredParameterLocations.Add(newParameterIndex); + newParameterIndex++; } } } @@ -401,7 +401,7 @@ for (int i = 0; i < _positionalParameterLocations.Length; i++) { - int location = _positionalParameterLocations[i]; + int location = FindAdjustedParameterLocation(_positionalParameterLocations[i]); object value = _positionalParameterValues[i]; IType type = _positionalParameterTypes[i]; ArrayHelper.SafeSetValue(values, location, value); @@ -428,7 +428,7 @@ int[] locations = getNamedParameterLocations(name); for (int i = 0; i < locations.Length; i++) { - int location = locations[i]; + int location = FindAdjustedParameterLocation(locations[i]); // can still clash with positional parameters // could consider throwing an exception to locate problem (NH-1098) Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Loader/QueryLoader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Loader/QueryLoader.cs 2009-09-15 21:39:54 UTC (rev 4713) +++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Loader/QueryLoader.cs 2009-09-15 21:41:03 UTC (rev 4714) @@ -58,11 +58,6 @@ get { return HasSubselectLoadableCollections(); } } - protected override void AdjustNamedParameterLocationsForQueryParameters(QueryParameters parameters) - { - _queryTranslator.AdjustNamedParameterLocationsForQueryParameters(parameters); - } - protected override SqlString ApplyLocks(SqlString sql, IDictionary<string, LockMode> lockModes, Dialect.Dialect dialect) { Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/QueryTranslatorImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/QueryTranslatorImpl.cs 2009-09-15 21:39:54 UTC (rev 4713) +++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/QueryTranslatorImpl.cs 2009-09-15 21:41:03 UTC (rev 4714) @@ -464,11 +464,6 @@ throw new QueryExecutionRequestException("Not supported for DML operations", _hql); } } - - public void AdjustNamedParameterLocationsForQueryParameters(QueryParameters parameters) - { - ((ParameterTranslationsImpl) GetParameterTranslations()).AdjustNamedParameterLocationsForQueryParameters(parameters); - } } internal class HqlParseEngine Modified: trunk/nhibernate/src/NHibernate/Hql/Classic/QueryTranslator.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Classic/QueryTranslator.cs 2009-09-15 21:39:54 UTC (rev 4713) +++ trunk/nhibernate/src/NHibernate/Hql/Classic/QueryTranslator.cs 2009-09-15 21:41:03 UTC (rev 4714) @@ -705,21 +705,6 @@ return o.ToArray(); } - protected override void AdjustNamedParameterLocationsForQueryParameters(QueryParameters parameters) - { - foreach (int existingParameterLocation in parameters.FilteredParameterLocations) - { - foreach (IList<int> namedParameterLocations in namedParameters.Values) - { - for (int index = 0; index < namedParameterLocations.Count; index++) - { - if (namedParameterLocations[index] >= existingParameterLocation) - namedParameterLocations[index]++; - } - } - } - } - public static string ScalarName(int x, int y) { return new StringBuilder() Modified: trunk/nhibernate/src/NHibernate/Loader/Collection/SubselectCollectionLoader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Collection/SubselectCollectionLoader.cs 2009-09-15 21:39:54 UTC (rev 4713) +++ trunk/nhibernate/src/NHibernate/Loader/Collection/SubselectCollectionLoader.cs 2009-09-15 21:41:03 UTC (rev 4714) @@ -43,23 +43,5 @@ { return namedParameterLocMap[name]; } - - protected override void AdjustNamedParameterLocationsForQueryParameters(QueryParameters parameters) - { - if (namedParameterLocMap == null) - return; - - foreach (int existingParameterLocation in parameters.FilteredParameterLocations) - { - foreach (IList<int> namedParameterLocations in namedParameterLocMap.Values) - { - for (int index = 0; index < namedParameterLocations.Count; index++) - { - if (namedParameterLocations[index] >= existingParameterLocation) - namedParameterLocations[index]++; - } - } - } - } } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Loader/Collection/SubselectOneToManyLoader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Collection/SubselectOneToManyLoader.cs 2009-09-15 21:39:54 UTC (rev 4713) +++ trunk/nhibernate/src/NHibernate/Loader/Collection/SubselectOneToManyLoader.cs 2009-09-15 21:41:03 UTC (rev 4714) @@ -45,24 +45,5 @@ { return namedParameterLocMap[name]; } - - protected override void AdjustNamedParameterLocationsForQueryParameters(QueryParameters parameters) - { - if (namedParameterLocMap == null) - return; - - foreach (int existingParameterLocation in parameters.FilteredParameterLocations) - { - foreach (IList<int> namedParameterLocations in namedParameterLocMap.Values) - { - for (int index = 0; index < namedParameterLocations.Count; index++) - { - if (namedParameterLocations[index] >= existingParameterLocation) - namedParameterLocations[index]++; - } - } - } - } - } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs 2009-09-15 21:39:54 UTC (rev 4713) +++ trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs 2009-09-15 21:41:03 UTC (rev 4714) @@ -320,30 +320,6 @@ } } - protected override void AdjustNamedParameterLocationsForQueryParameters(QueryParameters parameters) - { - var existingParameterLocations = parameters.FilteredParameterLocations.GetEnumerator(); - while (existingParameterLocations.MoveNext()) - { - foreach (string name in parameters.NamedParameters.Keys) - { - object locations = namedParameterBindPoints[name]; - if (locations is int) - { - namedParameterBindPoints[name] = ((int)locations) + 1; - } - else - { - IList locationsList = (IList)locations; - for (int i = 0; i < locationsList.Count; i++) - { - locationsList[i] = ((int)locationsList[i]) + 1; - } - } - } - } - } - protected override void AutoDiscoverTypes(IDataReader rs) { MetaData metadata = new MetaData(rs); Modified: trunk/nhibernate/src/NHibernate/Loader/Loader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Loader.cs 2009-09-15 21:39:54 UTC (rev 4713) +++ trunk/nhibernate/src/NHibernate/Loader/Loader.cs 2009-09-15 21:41:03 UTC (rev 4714) @@ -1174,7 +1174,6 @@ protected virtual SqlString ProcessFilters(QueryParameters parameters, ISessionImplementor session) { parameters.ProcessFilters(SqlString, session); - AdjustNamedParameterLocationsForQueryParameters(parameters); return parameters.FilteredSQL; } @@ -1269,15 +1268,6 @@ throw new AssertionFailure("no named parameters"); } - protected virtual void AdjustNamedParameterLocationsForQueryParameters(QueryParameters parameters) - { - // if you support named parameter locations (by overriding GetNamedParameterLocs), then you might need to - // allow for the locations to be adjusted by introduced filtered parameters by overriding - // this method too. - if ((parameters.NamedParameters != null) && (parameters.NamedParameters.Keys.Count > 0)) - throw new AssertionFailure(GetType() + " must override to handle implementation of named parameter locations"); - } - /// <summary> /// Fetch a <c>IDbCommand</c>, call <c>SetMaxRows</c> and then execute it, /// advance to the first result and return an SQL <c>IDataReader</c> @@ -1734,6 +1724,7 @@ for (int index = 0; index < parameters.PositionalParameterTypes.Length; index++) { int location = parameters.PositionalParameterLocations[index]; + location = parameters.FindAdjustedParameterLocation(location); IType type = parameters.PositionalParameterTypes[index]; ArrayHelper.SafeSetValue(paramTypeList, location, type); span += type.GetColumnSpan(Factory); @@ -1760,6 +1751,7 @@ for (int i = 0; i < locs.Length; i++) { int location = locs[i]; + location = parameters.FindAdjustedParameterLocation(location); // can still clash with positional parameters // could consider throwing an exception to locate problem (NH-1098) Modified: trunk/nhibernate/src/NHibernate/Param/ParameterTranslationsImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Param/ParameterTranslationsImpl.cs 2009-09-15 21:39:54 UTC (rev 4713) +++ trunk/nhibernate/src/NHibernate/Param/ParameterTranslationsImpl.cs 2009-09-15 21:41:03 UTC (rev 4714) @@ -67,21 +67,6 @@ } } - public void AdjustNamedParameterLocationsForQueryParameters(QueryParameters parameters) - { - // NH Different behaviour NH-1776 - // Analyze all named parameters declared after filters - // in general all named parameters but depend on the complexity of the query (see sub query) - RestoreOriginalParameterLocations(); - foreach (int filterParameterLocation in parameters.FilteredParameterLocations) - { - foreach (ParameterInfo entry in _namedParameters.Values) - { - entry.IncrementLocationAfterFilterLocation(filterParameterLocation); - } - } - } - public int GetOrdinalParameterSqlLocation(int ordinalPosition) { return GetOrdinalParameterInfo(ordinalPosition).SqlLocations[0]; @@ -117,14 +102,6 @@ get { return _ordinalParameters.Length; } } - private void RestoreOriginalParameterLocations() - { - foreach (ParameterInfo entry in _namedParameters.Values) - { - entry.RestoreOriginalParameterLocations(); - } - } - private ParameterInfo GetOrdinalParameterInfo(int ordinalPosition) { // remember that ordinal parameters numbers are 1-based!!! @@ -170,24 +147,5 @@ } public IType ExpectedType { get; private set; } - - public void RestoreOriginalParameterLocations() - { - for (int i = 0; i < sqlLocations.Length; i++) - { - sqlLocations[i] = originalLocation[i]; - } - } - - public void IncrementLocationAfterFilterLocation(int filterParameterLocation) - { - for (int i = 0; i < sqlLocations.Length; i++) - { - if (sqlLocations[i] >= filterParameterLocation) - { - sqlLocations[i]++; - } - } - } } } \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1908ThreadSafety/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1908ThreadSafety/Fixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1908ThreadSafety/Fixture.cs 2009-09-15 21:41:03 UTC (rev 4714) @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.NH1908ThreadSafety +{ + [TestFixture] + public class Fixture : BugTestCase + { + [Test] + public void UsingFiltersIsThreadSafe() + { + var errors = new List<Exception>(); + var threads = new List<Thread>(); + for (int i = 0; i < 50; i++) + { + var thread = new Thread(() => + { + try + { + ScenarioRunningWithMultiThreading(); + } + catch (Exception ex) + { + lock (errors) + errors.Add(ex); + } + }); + thread.Start(); + threads.Add(thread); + } + + foreach (var thread in threads) + { + thread.Join(); + } + + Assert.AreEqual(0, errors.Count); + } + + private void ScenarioRunningWithMultiThreading() + { + using (var session = sessions.OpenSession()) + { + session + .EnableFilter("CurrentOnly") + .SetParameter("date", DateTime.Now); + + session.CreateQuery( + @" + select u + from Order u + left join fetch u.ActiveOrderLines + where + u.Email = :email + ") + .SetString("email", "st...@bu...") + .UniqueResult<Order>(); + } + } + } +} Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1908ThreadSafety/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1908ThreadSafety/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1908ThreadSafety/Mappings.hbm.xml 2009-09-15 21:41:03 UTC (rev 4714) @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" + assembly="NHibernate.Test" + namespace="NHibernate.Test.NHSpecificTest.NH1908ThreadSafety"> + + <class name="Order" table="Orders"> + <id name="Id" type="Int64" unsaved-value="none"> + <generator class="assigned"/> + </id> + <property name="Email" type="String" not-null="true"/> + <bag name="ActiveOrderLines" inverse="true" cascade="none" lazy="true" + optimistic-lock="false"> + <key column="OrderId"/> + <one-to-many class="OrderLine"/> + <filter name="CurrentOnly"/> + </bag> + </class> + + <class name="OrderLine" discriminator-value="null"> + <id name="Id" type="Int64" unsaved-value="none"> + <generator class="assigned"/> + </id> + <property name="ValidUntil"/> + <filter name="CurrentOnly"/> + </class> + + <filter-def name="CurrentOnly" condition="ValidUntil > :date"> + <filter-param name="date" type="DateTime"/> + </filter-def> +</hibernate-mapping> Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1908ThreadSafety/Model.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1908ThreadSafety/Model.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1908ThreadSafety/Model.cs 2009-09-15 21:41:03 UTC (rev 4714) @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; + +namespace NHibernate.Test.NHSpecificTest.NH1908ThreadSafety +{ + public class Order + { + public virtual long Id { get; set; } + public virtual IList<OrderLine> ActiveOrderLines { get; set;} + public virtual string Email { get; set; } + } + + public class OrderLine + { + public virtual long Id { get; set; } + public virtual DateTime ValidUntil { get; set; } + } +} Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-09-15 21:39:54 UTC (rev 4713) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-09-15 21:41:03 UTC (rev 4714) @@ -580,6 +580,8 @@ <Compile Include="NHSpecificTest\NH1905\Model.cs" /> <Compile Include="NHSpecificTest\NH1907\Fixture.cs" /> <Compile Include="NHSpecificTest\NH1907\MyType.cs" /> + <Compile Include="NHSpecificTest\NH1908ThreadSafety\Fixture.cs" /> + <Compile Include="NHSpecificTest\NH1908ThreadSafety\Model.cs" /> <Compile Include="NHSpecificTest\NH1908\Fixture.cs" /> <Compile Include="NHSpecificTest\NH1908\Model.cs" /> <Compile Include="NHSpecificTest\NH1911\Fixture.cs" /> @@ -2006,6 +2008,7 @@ <EmbeddedResource Include="Criteria\Lambda\Mappings.hbm.xml" /> <EmbeddedResource Include="CfgTest\Loquacious\EntityToCache.hbm.xml" /> <Content Include="DynamicEntity\package.html" /> + <EmbeddedResource Include="NHSpecificTest\NH1908ThreadSafety\Mappings.hbm.xml" /> <EmbeddedResource Include="Tools\hbm2ddl\SchemaUpdate\1_Person.hbm.xml" /> <EmbeddedResource Include="Tools\hbm2ddl\SchemaUpdate\2_Person.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH1938\Mappings.hbm.xml" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |