|
From: <fab...@us...> - 2011-03-22 17:01:20
|
Revision: 5500
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5500&view=rev
Author: fabiomaulo
Date: 2011-03-22 17:01:13 +0000 (Tue, 22 Mar 2011)
Log Message:
-----------
Fix NH-2591
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/AdoNet/AbstractBatcher.cs
trunk/nhibernate/src/NHibernate/Cfg/Environment.cs
trunk/nhibernate/src/NHibernate/Cfg/Loquacious/DbIntegrationConfiguration.cs
trunk/nhibernate/src/NHibernate/Cfg/Loquacious/IBatcherConfiguration.cs
trunk/nhibernate/src/NHibernate/Cfg/Loquacious/IDbIntegrationConfiguration.cs
trunk/nhibernate/src/NHibernate/Cfg/SettingsFactory.cs
trunk/nhibernate/src/NHibernate/nhibernate-configuration.xsd
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate.Test/Insertordering/
trunk/nhibernate/src/NHibernate.Test/Insertordering/Group.cs
trunk/nhibernate/src/NHibernate.Test/Insertordering/InsertOrderingFixture.cs
trunk/nhibernate/src/NHibernate.Test/Insertordering/Mapping.hbm.xml
trunk/nhibernate/src/NHibernate.Test/Insertordering/Membership.cs
trunk/nhibernate/src/NHibernate.Test/Insertordering/User.cs
Modified: trunk/nhibernate/src/NHibernate/AdoNet/AbstractBatcher.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/AdoNet/AbstractBatcher.cs 2011-03-22 05:14:35 UTC (rev 5499)
+++ trunk/nhibernate/src/NHibernate/AdoNet/AbstractBatcher.cs 2011-03-22 17:01:13 UTC (rev 5500)
@@ -122,7 +122,7 @@
}
}
- public IDbCommand PrepareBatchCommand(CommandType type, SqlString sql, SqlType[] parameterTypes)
+ public virtual IDbCommand PrepareBatchCommand(CommandType type, SqlString sql, SqlType[] parameterTypes)
{
/* NH:
* The code inside this block was added for a strange behaviour
Modified: trunk/nhibernate/src/NHibernate/Cfg/Environment.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Cfg/Environment.cs 2011-03-22 05:14:35 UTC (rev 5499)
+++ trunk/nhibernate/src/NHibernate/Cfg/Environment.cs 2011-03-22 17:01:13 UTC (rev 5500)
@@ -162,6 +162,9 @@
public const string LinqToHqlGeneratorsRegistry = "linqtohql.generatorsregistry";
+ /// <summary> Enable ordering of insert statements for the purpose of more effecient batching.</summary>
+ public const string OrderInserts = "order_inserts";
+
private static readonly Dictionary<string, string> GlobalProperties;
private static IBytecodeProvider BytecodeProviderInstance;
Modified: trunk/nhibernate/src/NHibernate/Cfg/Loquacious/DbIntegrationConfiguration.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Cfg/Loquacious/DbIntegrationConfiguration.cs 2011-03-22 05:14:35 UTC (rev 5499)
+++ trunk/nhibernate/src/NHibernate/Cfg/Loquacious/DbIntegrationConfiguration.cs 2011-03-22 17:01:13 UTC (rev 5500)
@@ -207,6 +207,18 @@
return dbc;
}
+ public IBatcherConfiguration OrderingInserts()
+ {
+ dbc.Configuration.SetProperty(Environment.OrderInserts, true.ToString().ToLowerInvariant());
+ return this;
+ }
+
+ public IBatcherConfiguration DisablingInsertsOrdering()
+ {
+ dbc.Configuration.SetProperty(Environment.OrderInserts, false.ToString().ToLowerInvariant());
+ return this;
+ }
+
#endregion
}
@@ -337,6 +349,11 @@
set { configuration.SetProperty(Environment.BatchSize, value.ToString()); }
}
+ public bool OrderInserts
+ {
+ set { configuration.SetProperty(Environment.OrderInserts, value.ToString().ToLowerInvariant()); }
+ }
+
public void TransactionFactory<TFactory>() where TFactory : ITransactionFactory
{
configuration.SetProperty(Environment.TransactionStrategy, typeof(TFactory).AssemblyQualifiedName);
Modified: trunk/nhibernate/src/NHibernate/Cfg/Loquacious/IBatcherConfiguration.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Cfg/Loquacious/IBatcherConfiguration.cs 2011-03-22 05:14:35 UTC (rev 5499)
+++ trunk/nhibernate/src/NHibernate/Cfg/Loquacious/IBatcherConfiguration.cs 2011-03-22 17:01:13 UTC (rev 5500)
@@ -5,5 +5,7 @@
{
IBatcherConfiguration Through<TBatcher>() where TBatcher : IBatcherFactory;
IDbIntegrationConfiguration Each(short batchSize);
+ IBatcherConfiguration OrderingInserts();
+ IBatcherConfiguration DisablingInsertsOrdering();
}
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Cfg/Loquacious/IDbIntegrationConfiguration.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Cfg/Loquacious/IDbIntegrationConfiguration.cs 2011-03-22 05:14:35 UTC (rev 5499)
+++ trunk/nhibernate/src/NHibernate/Cfg/Loquacious/IDbIntegrationConfiguration.cs 2011-03-22 17:01:13 UTC (rev 5500)
@@ -47,6 +47,7 @@
void Batcher<TBatcher>() where TBatcher : IBatcherFactory;
short BatchSize { set; }
+ bool OrderInserts { set; }
void TransactionFactory<TFactory>() where TFactory : ITransactionFactory;
Modified: trunk/nhibernate/src/NHibernate/Cfg/SettingsFactory.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Cfg/SettingsFactory.cs 2011-03-22 05:14:35 UTC (rev 5499)
+++ trunk/nhibernate/src/NHibernate/Cfg/SettingsFactory.cs 2011-03-22 17:01:13 UTC (rev 5500)
@@ -229,6 +229,10 @@
// TODO: Environment.BatchVersionedData
settings.AdoBatchSize = PropertiesHelper.GetInt32(Environment.BatchSize, properties, 0);
+ bool orderInserts = PropertiesHelper.GetBoolean(Environment.OrderInserts, properties, (settings.AdoBatchSize > 0));
+ log.Info("Order SQL inserts for batching: " + EnabledDisabled(orderInserts));
+ settings.IsOrderInsertsEnabled = orderInserts;
+
bool wrapResultSets = PropertiesHelper.GetBoolean(Environment.WrapResultSets, properties, false);
log.Debug("Wrap result sets: " + EnabledDisabled(wrapResultSets));
settings.IsWrapResultSetsEnabled = wrapResultSets;
Modified: trunk/nhibernate/src/NHibernate/nhibernate-configuration.xsd
===================================================================
--- trunk/nhibernate/src/NHibernate/nhibernate-configuration.xsd 2011-03-22 05:14:35 UTC (rev 5499)
+++ trunk/nhibernate/src/NHibernate/nhibernate-configuration.xsd 2011-03-22 17:01:13 UTC (rev 5500)
@@ -114,7 +114,8 @@
<xs:enumeration value="use_sql_comments" />
<xs:enumeration value="format_sql" />
<xs:enumeration value="collectiontype.factory_class" />
- </xs:restriction>
+ <xs:enumeration value="order_inserts" />
+ </xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:extension>
Added: trunk/nhibernate/src/NHibernate.Test/Insertordering/Group.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Insertordering/Group.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/Insertordering/Group.cs 2011-03-22 17:01:13 UTC (rev 5500)
@@ -0,0 +1,8 @@
+namespace NHibernate.Test.Insertordering
+{
+ public class Group
+ {
+ public virtual int Id { get; protected set; }
+ public virtual string Name { get; set; }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/Insertordering/InsertOrderingFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Insertordering/InsertOrderingFixture.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/Insertordering/InsertOrderingFixture.cs 2011-03-22 17:01:13 UTC (rev 5500)
@@ -0,0 +1,146 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Data;
+using NHibernate.AdoNet;
+using NHibernate.Cfg;
+using NHibernate.Cfg.Loquacious;
+using NHibernate.Engine;
+using NHibernate.SqlCommand;
+using NHibernate.SqlTypes;
+using NUnit.Framework;
+using SharpTestsEx;
+
+namespace NHibernate.Test.Insertordering
+{
+ public class InsertOrderingFixture : TestCase
+ {
+ const int batchSize = 10;
+ const int instancesPerEach = 12;
+ const int typesOfEntities = 3;
+ protected override IList Mappings
+ {
+ get { return new[] {"Insertordering.Mapping.hbm.xml"}; }
+ }
+
+ protected override string MappingsAssembly
+ {
+ get { return "NHibernate.Test"; }
+ }
+
+ protected override void Configure(Configuration configuration)
+ {
+ configuration.DataBaseIntegration(x =>
+ {
+ x.BatchSize = batchSize;
+ x.OrderInserts = true;
+ x.Batcher<StatsBatcherFactory>();
+ });
+ }
+
+ [Test]
+ public void BatchOrdering()
+ {
+ using (ISession s = OpenSession())
+ using (s.BeginTransaction())
+ {
+ for (int i = 0; i < instancesPerEach; i++)
+ {
+ var user = new User {UserName = "user-" + i};
+ var group = new Group {Name = "group-" + i};
+ s.Save(user);
+ s.Save(group);
+ user.AddMembership(group);
+ }
+ StatsBatcher.Reset();
+ s.Transaction.Commit();
+ }
+
+ int expectedBatchesPerEntity = (instancesPerEach / batchSize) + ((instancesPerEach % batchSize) == 0 ? 0 : 1);
+ StatsBatcher.BatchSizes.Count.Should().Be(expectedBatchesPerEntity * typesOfEntities);
+
+ using (ISession s = OpenSession())
+ {
+ s.BeginTransaction();
+ IList users = s.CreateQuery("from User u left join fetch u.Memberships m left join fetch m.Group").List();
+ foreach (object user in users)
+ {
+ s.Delete(user);
+ }
+ s.Transaction.Commit();
+ }
+ }
+
+ #region Nested type: StatsBatcher
+
+ public class StatsBatcher : SqlClientBatchingBatcher
+ {
+ private static string batchSQL;
+ private static IList<int> batchSizes = new List<int>();
+ private static int currentBatch = -1;
+
+ public StatsBatcher(ConnectionManager connectionManager, IInterceptor interceptor)
+ : base(connectionManager, interceptor) {}
+
+ public static IList<int> BatchSizes
+ {
+ get { return batchSizes; }
+ }
+
+ public static void Reset()
+ {
+ batchSizes = new List<int>();
+ currentBatch = -1;
+ batchSQL = null;
+ }
+
+ public override IDbCommand PrepareBatchCommand(CommandType type, SqlString sql, SqlType[] parameterTypes)
+ {
+ IDbCommand result = base.PrepareBatchCommand(type, sql, parameterTypes);
+ string sqlstring = sql.ToString();
+ if (batchSQL == null || !sqlstring.Equals(batchSQL))
+ {
+ currentBatch++;
+ batchSQL = sqlstring;
+ batchSizes.Insert(currentBatch, 0);
+ Console.WriteLine("--------------------------------------------------------");
+ Console.WriteLine("Preparing statement [" + batchSQL + "]");
+ }
+ return result;
+ }
+
+ public override void AddToBatch(IExpectation expectation)
+ {
+ batchSizes[currentBatch]++;
+ Console.WriteLine("Adding to batch [" + batchSQL + "]");
+ base.AddToBatch(expectation);
+ }
+
+ protected override void DoExecuteBatch(IDbCommand ps)
+ {
+ Console.WriteLine("executing batch [" + batchSQL + "]");
+ Console.WriteLine("--------------------------------------------------------");
+ batchSQL = null;
+ base.DoExecuteBatch(ps);
+ }
+ }
+
+ #endregion
+
+ #region Nested type: StatsBatcherFactory
+
+ public class StatsBatcherFactory : IBatcherFactory
+ {
+ #region IBatcherFactory Members
+
+ public IBatcher CreateBatcher(ConnectionManager connectionManager, IInterceptor interceptor)
+ {
+ return new StatsBatcher(connectionManager, interceptor);
+ }
+
+ #endregion
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/Insertordering/Mapping.hbm.xml
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Insertordering/Mapping.hbm.xml (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/Insertordering/Mapping.hbm.xml 2011-03-22 17:01:13 UTC (rev 5500)
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<hibernate-mapping
+ xmlns="urn:nhibernate-mapping-2.2"
+ namespace="NHibernate.Test.Insertordering"
+ assembly="NHibernate.Test">
+
+ <class name="User" table="INS_ORD_USR">
+ <id name="Id">
+ <generator class="increment"/>
+ </id>
+ <property name="UserName" column="USR_NM" />
+ <set name="Memberships" inverse="true" cascade="all" access="field.camelcase">
+ <key column="USR_ID"/>
+ <one-to-many class="Membership"/>
+ </set>
+ </class>
+
+ <class name="Group" table="INS_ORD_GRP">
+ <id name="Id">
+ <generator class="increment"/>
+ </id>
+ <property name="Name"/>
+ </class>
+
+ <class name="Membership" table="INS_ORD_MEM">
+ <id name="Id">
+ <generator class="increment" />
+ </id>
+ <many-to-one name="User" class="User" column="USR_ID" cascade="all"/>
+ <many-to-one name="Group" class="Group" column="GRP_ID" cascade="all"/>
+ <property name="ActivationDate" type="timestamp" column="JN_DT"/>
+ </class>
+</hibernate-mapping>
Added: trunk/nhibernate/src/NHibernate.Test/Insertordering/Membership.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Insertordering/Membership.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/Insertordering/Membership.cs 2011-03-22 17:01:13 UTC (rev 5500)
@@ -0,0 +1,23 @@
+using System;
+
+namespace NHibernate.Test.Insertordering
+{
+ public class Membership
+ {
+ protected Membership() {}
+
+ public Membership(User user, Group @group) : this(user, group, DateTime.Now) {}
+
+ public Membership(User user, Group @group, DateTime activationDate)
+ {
+ User = user;
+ Group = group;
+ ActivationDate = activationDate;
+ }
+
+ public virtual int Id { get; protected set; }
+ public virtual User User { get; private set; }
+ public virtual Group Group { get; private set; }
+ public virtual DateTime ActivationDate { get; private set; }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate.Test/Insertordering/User.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Insertordering/User.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/Insertordering/User.cs 2011-03-22 17:01:13 UTC (rev 5500)
@@ -0,0 +1,27 @@
+using System.Collections.Generic;
+using Iesi.Collections.Generic;
+
+namespace NHibernate.Test.Insertordering
+{
+ public class User
+ {
+ private ISet<Membership> memberships;
+ public User()
+ {
+ memberships = new HashedSet<Membership>();
+ }
+ public virtual int Id { get; protected set; }
+ public virtual string UserName { get; set; }
+ public virtual IEnumerable<Membership> Memberships
+ {
+ get { return memberships; }
+ }
+
+ public virtual Membership AddMembership(Group group)
+ {
+ var membership = new Membership(this, group);
+ memberships.Add(membership);
+ return membership;
+ }
+ }
+}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-03-22 05:14:35 UTC (rev 5499)
+++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-03-22 17:01:13 UTC (rev 5500)
@@ -459,6 +459,10 @@
<Compile Include="Immutable\Info.cs" />
<Compile Include="Immutable\Party.cs" />
<Compile Include="Immutable\Plan.cs" />
+ <Compile Include="Insertordering\Group.cs" />
+ <Compile Include="Insertordering\InsertOrderingFixture.cs" />
+ <Compile Include="Insertordering\Membership.cs" />
+ <Compile Include="Insertordering\User.cs" />
<Compile Include="LazyOneToOne\Employee.cs" />
<Compile Include="LazyOneToOne\Employment.cs" />
<Compile Include="LazyOneToOne\LazyOneToOneTest.cs" />
@@ -2472,6 +2476,7 @@
<EmbeddedResource Include="NHSpecificTest\NH1291AnonExample\Mappings.hbm.xml" />
</ItemGroup>
<ItemGroup>
+ <EmbeddedResource Include="Insertordering\Mapping.hbm.xml" />
<EmbeddedResource Include="NHSpecificTest\NH2530\Mappings.hbm.xml" />
<EmbeddedResource Include="DynamicProxyTests\InterfaceProxySerializationTests\ProxyImpl.hbm.xml" />
<EmbeddedResource Include="NHSpecificTest\NH2565\Mappings.hbm.xml" />
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|