You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ibatis.apache.org by rg...@apache.org on 2009/06/28 09:03:35 UTC

svn commit: r789059 [1/2] - in /ibatis/trunk/cs/V3/src: Apache.Ibatis.DataMapper.SqlClient.Test/ Apache.Ibatis.DataMapper.SqlClient.Test/Fixtures/ Apache.Ibatis.DataMapper.SqlClient.Test/Fixtures/Mapping/ Apache.Ibatis.DataMapper/ Apache.Ibatis.DataMap...

Author: rgrabowski
Date: Sun Jun 28 07:03:34 2009
New Revision: 789059

URL: http://svn.apache.org/viewvc?rev=789059&view=rev
Log:
Merge from /branches/MappedStatementRefactor r788266:r789049

Refactored large MappedStatement class into partial classes:
 MappedStatement.ExecuteInsert.cs
 MappedStatement.ExecuteQueryForDataTable.cs
 MappedStatement.ExecuteQueryForList.cs
 MappedStatement.ExecuteQueryForMap.cs
 MappedStatement.ExecuteQueryForObject.cs
 MappedStatement.ExecuteUpdate.cs

All Execute methods call through to a single generic Execute method in MappedStatement.cs that ensures the RequestScope is created and events are raised in a consistent manner.

Enabled calls to ExecuteQueryForDataTable to be cached.

Documented that some calls to CachingStatement (i.e. those taking delegate and explicit result objects) are never cached.

Call Trim() before setting the CommandText of a stored procedure call to ensure the store procedure name is not prefixed with whitespace.

Update SqlClient.Text project from .NET 3.0 to .NET 3.5.

Expose ConfigurationSetting object in BaseTest to allow StatementNamespaceTest to run only when UseStatementNamespaces=true.

Refactored ThreadTest.

Added PostStatementEventArgs.CacheHit property that is set when the ResultObject comes from cache.

Added:
    ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/MappedStatements/MappedStatement.ExecuteInsert.cs
      - copied unchanged from r789051, ibatis/branches/MappedStatementRefactor/Apache.Ibatis.DataMapper/MappedStatements/MappedStatement.ExecuteInsert.cs
    ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/MappedStatements/MappedStatement.ExecuteQueryForDataTable.cs
      - copied unchanged from r789051, ibatis/branches/MappedStatementRefactor/Apache.Ibatis.DataMapper/MappedStatements/MappedStatement.ExecuteQueryForDataTable.cs
    ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/MappedStatements/MappedStatement.ExecuteQueryForList.cs
      - copied unchanged from r789051, ibatis/branches/MappedStatementRefactor/Apache.Ibatis.DataMapper/MappedStatements/MappedStatement.ExecuteQueryForList.cs
    ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/MappedStatements/MappedStatement.ExecuteQueryForMap.cs
      - copied unchanged from r789051, ibatis/branches/MappedStatementRefactor/Apache.Ibatis.DataMapper/MappedStatements/MappedStatement.ExecuteQueryForMap.cs
    ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/MappedStatements/MappedStatement.ExecuteQueryForObject.cs
      - copied unchanged from r789051, ibatis/branches/MappedStatementRefactor/Apache.Ibatis.DataMapper/MappedStatements/MappedStatement.ExecuteQueryForObject.cs
    ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/MappedStatements/MappedStatement.ExecuteUpdate.cs
      - copied unchanged from r789051, ibatis/branches/MappedStatementRefactor/Apache.Ibatis.DataMapper/MappedStatements/MappedStatement.ExecuteUpdate.cs
Removed:
    ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/Model/Events/PostInsertEventArgs.cs
    ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/Model/Events/PostSelectEventArgs.cs
    ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/Model/Events/PostUpdateOrDeleteEventArgs.cs
    ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/Model/Events/PreInsertEventArgs.cs
    ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/Model/Events/PreSelectEventArgs.cs
    ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/Model/Events/PreUpdateOrDeleteEventArgs.cs
Modified:
    ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test/Apache.Ibatis.DataMapper.SqlClient.Test.csproj
    ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test/Fixtures/BaseTest.cs
    ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test/Fixtures/Mapping/CacheTest.cs
    ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test/Fixtures/Mapping/EventTest.cs
    ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test/Fixtures/Mapping/StatementNamespaceTest.cs
    ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test/Fixtures/Mapping/ThreadTest.cs
    ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/Apache.Ibatis.DataMapper.csproj
    ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/DataMapper.cs
    ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/MappedStatements/CachingStatement.cs
    ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/MappedStatements/IMappedStatement.cs
    ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/MappedStatements/IMappedStatementEvents.cs
    ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/MappedStatements/MappedStatement.cs
    ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/MappedStatements/MappedStatementEventSupport.cs
    ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/Model/Cache/CacheModel.cs
    ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/Model/Events/PostStatementEventArgs.cs
    ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/Model/Events/PreStatementEventArgs.cs
    ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/Model/Statements/PreparedStatementFactory.cs

Modified: ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test/Apache.Ibatis.DataMapper.SqlClient.Test.csproj
URL: http://svn.apache.org/viewvc/ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test/Apache.Ibatis.DataMapper.SqlClient.Test.csproj?rev=789059&r1=789058&r2=789059&view=diff
==============================================================================
--- ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test/Apache.Ibatis.DataMapper.SqlClient.Test.csproj (original)
+++ ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test/Apache.Ibatis.DataMapper.SqlClient.Test.csproj Sun Jun 28 07:03:34 2009
@@ -14,7 +14,7 @@
     <OldToolsVersion>2.0</OldToolsVersion>
     <UpgradeBackupLocation>
     </UpgradeBackupLocation>
-    <TargetFrameworkVersion>v3.0</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>
@@ -45,6 +45,9 @@
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.configuration" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
     <Reference Include="System.Data" />
     <Reference Include="System.Drawing" />
     <Reference Include="System.Xml" />

Modified: ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test/Fixtures/BaseTest.cs
URL: http://svn.apache.org/viewvc/ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test/Fixtures/BaseTest.cs?rev=789059&r1=789058&r2=789059&view=diff
==============================================================================
--- ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test/Fixtures/BaseTest.cs (original)
+++ ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test/Fixtures/BaseTest.cs Sun Jun 28 07:03:34 2009
@@ -35,6 +35,7 @@
         protected static KeyConvert ConvertKey = null;
         protected static ISessionFactory sessionFactory = null;
         protected ISessionStore sessionStore = null;
+        protected ConfigurationSetting configurationSetting;
 
         /// <summary>
         /// Initialize an sqlMap
@@ -44,7 +45,7 @@
         {
             //DateTime start = DateTime.Now;
 
-            ConfigurationSetting configurationSetting = new ConfigurationSetting();
+            configurationSetting = new ConfigurationSetting();
             configurationSetting.Properties.Add("collection2Namespace", "Apache.Ibatis.DataMapper.SqlClient.Test.Domain.LineItemCollection2, Apache.Ibatis.DataMapper.SqlClient.Test");
             configurationSetting.Properties.Add("nullableInt", "int?");
 
@@ -189,6 +190,14 @@
             Assert.AreEqual("Joe.Dalton@somewhere.com", account.EmailAddress, "account.EmailAddress");
         }
 
+        protected void AssertAccount2(Account account)
+        {
+            Assert.AreEqual(2, account.Id, "account.Id");
+            Assert.AreEqual("Averel", account.FirstName, "account.FirstName");
+            Assert.AreEqual("Dalton", account.LastName, "account.LastName");
+            Assert.AreEqual("Averel.Dalton@somewhere.com", account.EmailAddress, "account.EmailAddress");
+        }
+
         /// <summary>
         /// Verify that the input account is equal to the account(id=1).
         /// </summary>

Modified: ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test/Fixtures/Mapping/CacheTest.cs
URL: http://svn.apache.org/viewvc/ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test/Fixtures/Mapping/CacheTest.cs?rev=789059&r1=789058&r2=789059&view=diff
==============================================================================
--- ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test/Fixtures/Mapping/CacheTest.cs (original)
+++ ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test/Fixtures/Mapping/CacheTest.cs Sun Jun 28 07:03:34 2009
@@ -1,14 +1,13 @@
 
 using System;
 using System.Collections;
+using System.Collections.Generic;
 using System.Threading;
 using Apache.Ibatis.Common.Utilities;
 
 using Apache.Ibatis.DataMapper.MappedStatements;
-using Apache.Ibatis.DataMapper.Model.Cache.Decorators;
 using Apache.Ibatis.DataMapper.Model.Cache.Implementation;
 using Apache.Ibatis.DataMapper.SqlClient.Test.Domain;
-using Apache.Ibatis.DataMapper.SqlClient.Test.Fixtures;
 using NUnit.Framework;
 using Apache.Ibatis.DataMapper.Model.Cache;
 using Apache.Ibatis.DataMapper.Session;
@@ -86,6 +85,32 @@
         }
 
         /// <summary>
+        /// Cache error with QueryForObject<T> PostStatementEventArgs with object in cache
+        /// </summary>
+        [Test]
+        public void TestJIRA242WithCacheAndPostStatementEventArgs()
+        {
+            List<bool> postSelectedWithCacheHitCalled = new List<bool>();
+
+            IMappedStatement statement = ((IModelStoreAccessor)dataMapper).ModelStore.GetMappedStatement("GetNoAccountWithCache");
+            statement.Statement.CacheModel.Cache.Clear();
+            statement.PostSelect += (sender, e) => postSelectedWithCacheHitCalled.Add(e.CacheHit);
+
+            Account first = dataMapper.QueryForObject<Account>("GetNoAccountWithCache", 1);
+            Account second = dataMapper.QueryForObject<Account>("GetNoAccountWithCache", 1);
+            Assert.AreEqual(first.Id, second.Id);
+
+            // ensure the PostSelect event was called twice
+            Assert.IsTrue(postSelectedWithCacheHitCalled.Count == 2);
+
+            // the first time through we should get CacheHit==false because the cache is empty
+            Assert.IsFalse(postSelectedWithCacheHitCalled[0]);
+
+            // the second time through we should get CacheHit==true
+            Assert.IsTrue(postSelectedWithCacheHitCalled[1]);
+        }
+
+        /// <summary>
         /// Cache error with QueryForObjectwith object in cache
         /// </summary>
         [Test]

Modified: ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test/Fixtures/Mapping/EventTest.cs
URL: http://svn.apache.org/viewvc/ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test/Fixtures/Mapping/EventTest.cs?rev=789059&r1=789058&r2=789059&view=diff
==============================================================================
--- ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test/Fixtures/Mapping/EventTest.cs (original)
+++ ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test/Fixtures/Mapping/EventTest.cs Sun Jun 28 07:03:34 2009
@@ -60,7 +60,7 @@
             statement.PreSelect -= PreSelectEventHandler;
         }
 
-        private static void PreSelectEventHandler(object src, PreSelectEventArgs evnt)
+        private static void PreSelectEventHandler(object src, PreStatementEventArgs evnt)
         {
             Assert.That(((IMappedStatement)src).Id, Is.EqualTo("SelectAccount"));
             evnt.ParameterObject = ((int)evnt.ParameterObject) +1;
@@ -81,7 +81,7 @@
             statement.PostSelect -= PostSelectEventHandler;
         }
 
-        private static void PostSelectEventHandler(object src, PostSelectEventArgs evnt)
+        private static void PostSelectEventHandler(object src, PostStatementEventArgs evnt)
         {
             Assert.That(((IMappedStatement)src).Id, Is.EqualTo("SelectAccount"));
             Account account = (Account)evnt.ResultObject;
@@ -115,7 +115,7 @@
             statement.PreInsert -= PreInsertEventHandler;
         }
 
-        private static void PreInsertEventHandler(object src, PreInsertEventArgs evnt)
+        private static void PreInsertEventHandler(object src, PreStatementEventArgs evnt)
         {
             Assert.That(((IMappedStatement)src).Id, Is.EqualTo("InsertAccount"));
             Account account = (Account)evnt.ParameterObject;
@@ -145,7 +145,7 @@
 
         }
 
-        private static void PostInsertEventHandler(object src, PostInsertEventArgs evnt)
+        private static void PostInsertEventHandler(object src, PostStatementEventArgs evnt)
         {
             Assert.That(((IMappedStatement)src).Id, Is.EqualTo("InsertAccount"));
             Account account = (Account)evnt.ParameterObject;
@@ -174,7 +174,7 @@
             statement.PreUpdateOrDelete -= PreUpdateOrDeleteEventHandler;
         }
 
-        private static void PreUpdateOrDeleteEventHandler(object src, PreUpdateOrDeleteEventArgs evnt)
+        private static void PreUpdateOrDeleteEventHandler(object src, PreStatementEventArgs evnt)
         {
             Assert.That(((IMappedStatement)src).Id, Is.EqualTo("UpdateAccount"));
             Account account = (Account)evnt.ParameterObject;
@@ -198,7 +198,7 @@
 
         }
 
-        private static void PostUpdateOrDeleteEventHandler(object src, PostUpdateOrDeleteEventArgs evnt)
+        private static void PostUpdateOrDeleteEventHandler(object src, PostStatementEventArgs evnt)
         {
             Assert.That(((IMappedStatement)src).Id, Is.EqualTo("UpdateAccount"));
             Account account = (Account)evnt.ParameterObject;

Modified: ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test/Fixtures/Mapping/StatementNamespaceTest.cs
URL: http://svn.apache.org/viewvc/ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test/Fixtures/Mapping/StatementNamespaceTest.cs?rev=789059&r1=789058&r2=789059&view=diff
==============================================================================
--- ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test/Fixtures/Mapping/StatementNamespaceTest.cs (original)
+++ ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test/Fixtures/Mapping/StatementNamespaceTest.cs Sun Jun 28 07:03:34 2009
@@ -44,8 +44,16 @@
         /// </summary>
         [Test] 
         public void TestQueryForObject() {
-            Account account = dataMapper.QueryForObject("Account.GetAccountViaResultClass", 1) as Account;
-            AssertAccount1(account);
+
+            if (configurationSetting.UseStatementNamespaces)
+            {
+                Account account = dataMapper.QueryForObject("Account.GetAccountViaResultClass", 1) as Account;
+                AssertAccount1(account);
+            }
+            else
+            {
+                Assert.Ignore("UseStatementNamespaces is false, skipping");
+            }
         }
 
         /// <summary>
@@ -55,14 +63,22 @@
         /// </summary>
         [Test]
         public void TestListMapping() {
-            Order order = (Order) dataMapper.QueryForObject("Order.GetOrderWithLineItemsUsingStatementNamespaces", 1);
-
-            AssertOrder1(order);
-
-            // Check IList collection
-            Assert.IsNotNull(order.LineItemsIList);
-            Assert.AreEqual(3, order.LineItemsIList.Count);
 
+            if (configurationSetting.UseStatementNamespaces)
+            {
+                Order order =
+                    (Order) dataMapper.QueryForObject("Order.GetOrderWithLineItemsUsingStatementNamespaces", 1);
+
+                AssertOrder1(order);
+
+                // Check IList collection
+                Assert.IsNotNull(order.LineItemsIList);
+                Assert.AreEqual(3, order.LineItemsIList.Count);
+            }
+            else
+            {
+                Assert.Ignore("UseStatementNamespaces is false, skipping");
+            }
         }
 
         /// <summary>
@@ -73,12 +89,20 @@
         /// </summary>
         [Test] 
         public void TestInsertSelectKey() {
-            Category category = new Category();
-            category.Name = "toto";
-            category.Guid = Guid.NewGuid();
 
-            int key = (int)dataMapper.Insert("Category.InsertCategoryViaInsertStatement", category);
-            Assert.AreEqual(1, key);
+            if (configurationSetting.UseStatementNamespaces)
+            {
+                Category category = new Category();
+                category.Name = "toto";
+                category.Guid = Guid.NewGuid();
+
+                int key = (int) dataMapper.Insert("Category.InsertCategoryViaInsertStatement", category);
+                Assert.AreEqual(1, key);
+            }
+            else
+            {
+                Assert.Ignore("UseStatementNamespaces is false, skipping");
+            }
         }
 
         #endregion

Modified: ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test/Fixtures/Mapping/ThreadTest.cs
URL: http://svn.apache.org/viewvc/ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test/Fixtures/Mapping/ThreadTest.cs?rev=789059&r1=789058&r2=789059&view=diff
==============================================================================
--- ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test/Fixtures/Mapping/ThreadTest.cs (original)
+++ ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test/Fixtures/Mapping/ThreadTest.cs Sun Jun 28 07:03:34 2009
@@ -1,10 +1,6 @@
 using System;
-using System.Reflection;
 using System.Threading;
-using Apache.Ibatis.Common.Logging;
-using Apache.Ibatis.DataMapper.Session;
 using Apache.Ibatis.DataMapper.SqlClient.Test.Domain;
-using Apache.Ibatis.DataMapper.SqlClient.Test.Fixtures;
 using NUnit.Framework;
 
 namespace Apache.Ibatis.DataMapper.SqlClient.Test.Fixtures.Mapping
@@ -15,9 +11,6 @@
     [TestFixture] 
     public class ThreadTest: BaseTest
     {
-        private static readonly ILog _logger = LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType );
-
-        private static readonly int numberOfThreads = 10;
         private readonly ManualResetEvent startEvent = new ManualResetEvent(false);
         private readonly ManualResetEvent stopEvent = new ManualResetEvent(false);
 
@@ -41,105 +34,78 @@
 
         #endregion
 
-        #region Thread test
-
         [Test]
         public void TestCommonUsageMultiThread()
         {
-            const int threadCount = 10;
+            // 10 threads for 5 seconds
+            RunThreadsForDuration(10, 5, i =>
+             {
+                 string prefix = String.Format("[Thread #{0:00} HashCode: {1:00}]: ", i, Thread.CurrentThread.GetHashCode());
+
+                 // ???
+                 Assert.IsNull(sessionStore.CurrentSession);
+
+                 Console.WriteLine(prefix + "Beginning");
+                 int parameter = i % 2 == 0 ? 2 : 1; // check parity of current thread
+                 Account account = (Account)dataMapper.QueryForObject("GetAccountViaColumnIndex", parameter);
+                 Assert.IsNull(sessionStore.CurrentSession);
+                 Console.WriteLine(prefix + "AssertAccount" + parameter);
+                 if (parameter == 1)
+                 {
+                     AssertAccount1(account);
+                 }
+                 else
+                 {
+                     AssertAccount2(account);
+                 }
+                 Console.WriteLine(prefix + "Ending");
+             });
+        }
 
-            Thread[] threads = new Thread[threadCount];
-			
-            for(int i = 0; i < threadCount; i++)
+        public void RunThreadsForDuration(int numberOfThreads, int duration, Action<int> action)
+        {
+            Thread[] threads = new Thread[numberOfThreads];
+            for (int i = 0; i < numberOfThreads; i++)
             {
-                threads[i] = new Thread(new ThreadStart(ExecuteMethodUntilSignal));
-                threads[i].Start();
+                threads[i] = new Thread(ExecuteUntilSignal);
+                threads[i].Start(new CurrentThreadActionInfo(i, action));
             }
-
             startEvent.Set();
-
-            Thread.CurrentThread.Join(1 * 2000);
-
+            Thread.CurrentThread.Join(1000 * duration);
             stopEvent.Set();
+
+            // give things time to stop ???
+            Thread.Sleep(2000);
         }
 
-        public void ExecuteMethodUntilSignal()
+        public void ExecuteUntilSignal(object state)
         {
-            startEvent.WaitOne(int.MaxValue, false);
+            var actionInfo = (CurrentThreadActionInfo)state;
 
+            Console.WriteLine("Queueing thread #{0} until all threads are ready to start...", actionInfo.CurrentThread);
+
+            startEvent.WaitOne(int.MaxValue, false);
             while (!stopEvent.WaitOne(1, false))
             {
-                Assert.IsNull(sessionStore.CurrentSession);
-
-                Console.WriteLine("Begin Thread : " + Thread.CurrentThread.GetHashCode());
-
-                Account account = (Account)dataMapper.QueryForObject("GetAccountViaColumnIndex", 1);
-
-                Assert.IsNull(sessionStore.CurrentSession);
-
-                Assert.AreEqual(1, account.Id, "account.Id");
-                Assert.AreEqual("Joe", account.FirstName, "account.FirstName");
-                Assert.AreEqual("Dalton", account.LastName, "account.LastName");
-
-                Console.WriteLine("End Thread : " + Thread.CurrentThread.GetHashCode());
+                actionInfo.Invoke();
             }
         }
 
-        /// <summary>
-        /// Test BeginTransaction, CommitTransaction
-        /// </summary>
-        [Test] 
-        public void TestThread() 
+        class CurrentThreadActionInfo
         {
-            Account account = NewAccount6();
-
-            try 
-            {
-                Thread[] threads = new Thread[numberOfThreads];
-
-                AccessTest accessTest = new AccessTest();
+            public int CurrentThread { get; private set; }
+            public Action<int> Action { get; private set; }
 
-                for (int i = 0; i < numberOfThreads; i++) 
-                {
-                    Thread thread = new Thread(new ThreadStart(accessTest.GetAccount));
-                    threads[i] = thread;
-                }
-                for (int i = 0; i < numberOfThreads; i++) 
-                {
-                    threads[i].Start();
-                }
-            } 
-            finally 
+            public CurrentThreadActionInfo(int currentThread, Action<int> action)
             {
+                CurrentThread = currentThread;
+                Action = action;
             }
 
-        }
-
-        #endregion
-
-        /// <summary>
-        /// Summary description for AccessTest.
-        /// </summary>
-        private class AccessTest
-        {
-		
-            /// <summary>
-            /// Get an account
-            /// </summary>
-            public void GetAccount()
+            public void Invoke()
             {
-                ISessionStore sessionStore = ((IModelStoreAccessor)dataMapper).ModelStore.SessionStore;
-
-                Assert.IsNull(sessionStore.CurrentSession);
-
-                Account account = (Account)dataMapper.QueryForObject("GetAccountViaColumnIndex", 1);
-
-                Assert.IsNull(sessionStore.CurrentSession);
-
-                Assert.AreEqual(1, account.Id, "account.Id");
-                Assert.AreEqual("Joe", account.FirstName, "account.FirstName");
-                Assert.AreEqual("Dalton", account.LastName, "account.LastName");
+                Action(CurrentThread);
             }
-        }	
+        }
     }
 }
\ No newline at end of file

Modified: ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/Apache.Ibatis.DataMapper.csproj
URL: http://svn.apache.org/viewvc/ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/Apache.Ibatis.DataMapper.csproj?rev=789059&r1=789058&r2=789059&view=diff
==============================================================================
--- ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/Apache.Ibatis.DataMapper.csproj (original)
+++ ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/Apache.Ibatis.DataMapper.csproj Sun Jun 28 07:03:34 2009
@@ -1,7 +1,7 @@
 <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
   <PropertyGroup>
     <ProjectType>Local</ProjectType>
-    <ProductVersion>9.0.21022</ProductVersion>
+    <ProductVersion>9.0.30729</ProductVersion>
     <SchemaVersion>2.0</SchemaVersion>
     <ProjectGuid>{F3E45F39-3224-4EAD-B138-EB5CC0E32824}</ProjectGuid>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -27,7 +27,7 @@
     <UpgradeBackupLocation>
     </UpgradeBackupLocation>
     <OldToolsVersion>2.0</OldToolsVersion>
-    <TargetFrameworkVersion>v3.0</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <OutputPath>bin\Debug\</OutputPath>
@@ -86,6 +86,9 @@
       <Name>System</Name>
     </Reference>
     <Reference Include="System.configuration" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
     <Reference Include="System.Data">
       <Name>System.Data</Name>
     </Reference>
@@ -123,6 +126,12 @@
     <Compile Include="Configuration\Module\ResultMapModuleBuilder.cs" />
     <Compile Include="Configuration\Module\TypeAliasModuleBuilder.cs" />
     <Compile Include="Configuration\Module\TypeHandlerModuleBuilder.cs" />
+    <Compile Include="MappedStatements\MappedStatement.ExecuteInsert.cs" />
+    <Compile Include="MappedStatements\MappedStatement.ExecuteQueryForDataTable.cs" />
+    <Compile Include="MappedStatements\MappedStatement.ExecuteQueryForList.cs" />
+    <Compile Include="MappedStatements\MappedStatement.ExecuteQueryForMap.cs" />
+    <Compile Include="MappedStatements\MappedStatement.ExecuteQueryForObject.cs" />
+    <Compile Include="MappedStatements\MappedStatement.ExecuteUpdate.cs" />
     <Compile Include="MappedStatements\ResultStrategy\DataRowStrategy.cs" />
     <Compile Include="Model\Cache\BaseCache.cs" />
     <Compile Include="Model\Cache\Decorators\LoggingCache.cs" />
@@ -198,12 +207,6 @@
     <Compile Include="Model\Events\PrePropertyEventArgs.cs" />
     <Compile Include="Model\Events\PreStatementEventArgs.cs" />
     <Compile Include="Model\Events\BaseStatementEventArgs.cs" />
-    <Compile Include="Model\Events\PostInsertEventArgs.cs" />
-    <Compile Include="Model\Events\PostSelectEventArgs.cs" />
-    <Compile Include="Model\Events\PostUpdateOrDeleteEventArgs.cs" />
-    <Compile Include="Model\Events\PreInsertEventArgs.cs" />
-    <Compile Include="Model\Events\PreSelectEventArgs.cs" />
-    <Compile Include="Model\Events\PreUpdateOrDeleteEventArgs.cs" />
     <Compile Include="Model\ParameterMapping\InlineParemeterMapBuilder.cs" />
     <Compile Include="Model\ResultMapping\ArgumentPropertyCollection.cs" />
     <Compile Include="Model\ResultMapping\IResultMapEvents.cs" />

Modified: ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/DataMapper.cs
URL: http://svn.apache.org/viewvc/ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/DataMapper.cs?rev=789059&r1=789058&r2=789059&view=diff
==============================================================================
--- ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/DataMapper.cs (original)
+++ ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/DataMapper.cs Sun Jun 28 07:03:34 2009
@@ -79,9 +79,9 @@
         /// </returns>
         public object Insert(string statementId, object parameterObject)
         {
-            using (DataMapperLocalSessionScope sessionScope = new DataMapperLocalSessionScope(sessionStore, sessionFactory))
+            using (var sessionScope = new DataMapperLocalSessionScope(sessionStore, sessionFactory))
             {
-                IMappedStatement statement = modelStore.GetMappedStatement(statementId);
+                IMappedStatement statement = GetMappedStatement(statementId);
                 return statement.ExecuteInsert(sessionScope.Session, parameterObject);
             }
         }
@@ -135,9 +135,9 @@
                 throw new DataMapperException("resultObject parameter must be instantiated before being passed to QueryForList");
             }
 
-            using (DataMapperLocalSessionScope sessionScope = new DataMapperLocalSessionScope(sessionStore, sessionFactory))
+            using (var sessionScope = new DataMapperLocalSessionScope(sessionStore, sessionFactory))
             {
-                IMappedStatement statement = modelStore.GetMappedStatement(statementId);
+                IMappedStatement statement = GetMappedStatement(statementId);
                 statement.ExecuteQueryForList(sessionScope.Session, parameterObject, resultObject);
             }
         }
@@ -154,9 +154,9 @@
         /// <returns>A List of result objects.</returns>
         public IList QueryForList(string statementId, object parameterObject)
         {
-            using (DataMapperLocalSessionScope sessionScope = new DataMapperLocalSessionScope(sessionStore, sessionFactory))
+            using (var sessionScope = new DataMapperLocalSessionScope(sessionStore, sessionFactory))
             {
-                IMappedStatement statement = modelStore.GetMappedStatement(statementId);
+                IMappedStatement statement = GetMappedStatement(statementId);
                 return statement.ExecuteQueryForList(sessionScope.Session, parameterObject);
             }
         }
@@ -192,9 +192,9 @@
         /// <exception cref="DataMapperException">If a transaction is not in progress, or the database throws an exception.</exception>
         public IDictionary QueryForMap(string statementId, object parameterObject, string keyProperty, string valueProperty)
         {
-            using (DataMapperLocalSessionScope sessionScope = new DataMapperLocalSessionScope(sessionStore, sessionFactory))
+            using (var sessionScope = new DataMapperLocalSessionScope(sessionStore, sessionFactory))
             {
-                IMappedStatement statement = modelStore.GetMappedStatement(statementId);
+                IMappedStatement statement = GetMappedStatement(statementId);
                 return statement.ExecuteQueryForMap(sessionScope.Session, parameterObject, keyProperty, valueProperty);
             }
         }
@@ -217,9 +217,9 @@
         /// <exception cref="DataMapperException">If a transaction is not in progress, or the database throws an exception.</exception>
         public IDictionary QueryForMapWithRowDelegate(string statementId, object parameterObject, string keyProperty, string valueProperty, DictionaryRowDelegate rowDelegate)
         {
-            using (DataMapperLocalSessionScope sessionScope = new DataMapperLocalSessionScope(sessionStore, sessionFactory))
+            using (var sessionScope = new DataMapperLocalSessionScope(sessionStore, sessionFactory))
             {
-                IMappedStatement statement = modelStore.GetMappedStatement(statementId);
+                IMappedStatement statement = GetMappedStatement(statementId);
                 return statement.ExecuteQueryForMapWithRowDelegate(sessionScope.Session, parameterObject, keyProperty, valueProperty, rowDelegate);
             }
         }
@@ -236,9 +236,9 @@
         /// </returns>
         public object QueryForObject(string statementId, object parameterObject, object resultObject)
         {
-            using (DataMapperLocalSessionScope sessionScope = new DataMapperLocalSessionScope(sessionStore, sessionFactory))
+            using (var sessionScope = new DataMapperLocalSessionScope(sessionStore, sessionFactory))
             {
-                IMappedStatement statement = modelStore.GetMappedStatement(statementId);
+                IMappedStatement statement = GetMappedStatement(statementId);
                 return statement.ExecuteQueryForObject(sessionScope.Session, parameterObject, resultObject);
             }
         }
@@ -273,9 +273,9 @@
         /// <returns>A List of result objects.</returns>
         public IList QueryWithRowDelegate(string statementId, object parameterObject, RowDelegate rowDelegate)
         {
-            using (DataMapperLocalSessionScope sessionScope = new DataMapperLocalSessionScope(sessionStore, sessionFactory))
+            using (var sessionScope = new DataMapperLocalSessionScope(sessionStore, sessionFactory))
             {
-                IMappedStatement statement = modelStore.GetMappedStatement(statementId);
+                IMappedStatement statement = GetMappedStatement(statementId);
                 return statement.ExecuteQueryForRowDelegate(sessionScope.Session, parameterObject, rowDelegate);
             }
         }
@@ -294,9 +294,9 @@
         /// <returns>The number of rows effected.</returns>
         public int Update(string statementId, object parameterObject)
         {
-            using (DataMapperLocalSessionScope sessionScope = new DataMapperLocalSessionScope(sessionStore, sessionFactory))
+            using (var sessionScope = new DataMapperLocalSessionScope(sessionStore, sessionFactory))
             {
-                IMappedStatement statement = modelStore.GetMappedStatement(statementId);
+                IMappedStatement statement = GetMappedStatement(statementId);
                 return statement.ExecuteUpdate(sessionScope.Session, parameterObject);
             }
         }
@@ -318,9 +318,9 @@
         /// <exception cref="DataMapperException">If a transaction is not in progress, or the database throws an exception.</exception>
         public IDictionary<K, V> QueryForDictionary<K, V>(string statementId, object parameterObject, string keyProperty, string valueProperty)
         {
-            using (DataMapperLocalSessionScope sessionScope = new DataMapperLocalSessionScope(sessionStore, sessionFactory))
+            using (var sessionScope = new DataMapperLocalSessionScope(sessionStore, sessionFactory))
             {
-                IMappedStatement statement = modelStore.GetMappedStatement(statementId);
+                IMappedStatement statement = GetMappedStatement(statementId);
                 return statement.ExecuteQueryForDictionary<K, V>(sessionScope.Session, parameterObject, keyProperty, valueProperty);
             }
         }
@@ -362,9 +362,9 @@
         /// <exception cref="DataMapperException">If a transaction is not in progress, or the database throws an exception.</exception>
         public IDictionary<K, V> QueryForDictionary<K, V>(string statementId, object parameterObject, string keyProperty, string valueProperty, DictionaryRowDelegate<K, V> rowDelegate)
         {
-            using (DataMapperLocalSessionScope sessionScope = new DataMapperLocalSessionScope(sessionStore, sessionFactory))
+            using (var sessionScope = new DataMapperLocalSessionScope(sessionStore, sessionFactory))
             {
-                IMappedStatement statement = modelStore.GetMappedStatement(statementId);
+                IMappedStatement statement = GetMappedStatement(statementId);
                 return statement.ExecuteQueryForDictionary(sessionScope.Session, parameterObject, keyProperty, valueProperty, rowDelegate);
             }
         }
@@ -382,9 +382,9 @@
         /// </returns>
         public T QueryForObject<T>(string statementId, object parameterObject, T instanceObject)
         {
-            using (DataMapperLocalSessionScope sessionScope = new DataMapperLocalSessionScope(sessionStore, sessionFactory))
+            using (var sessionScope = new DataMapperLocalSessionScope(sessionStore, sessionFactory))
             {
-                IMappedStatement statement = modelStore.GetMappedStatement(statementId);
+                IMappedStatement statement = GetMappedStatement(statementId);
                 return statement.ExecuteQueryForObject(sessionScope.Session, parameterObject, instanceObject);
             }
         }
@@ -404,7 +404,7 @@
         /// </returns>
         public T QueryForObject<T>(string statementId, object parameterObject)
         {
-            return QueryForObject<T>(statementId, parameterObject, default(T));
+            return QueryForObject(statementId, parameterObject, default(T));
         }
 
         /// <summary>
@@ -420,9 +420,9 @@
         /// <returns>A List of result objects.</returns>
         public IList<T> QueryForList<T>(string statementId, object parameterObject)
         {
-            using (DataMapperLocalSessionScope sessionScope = new DataMapperLocalSessionScope(sessionStore, sessionFactory))
+            using (var sessionScope = new DataMapperLocalSessionScope(sessionStore, sessionFactory))
             {
-                IMappedStatement statement = modelStore.GetMappedStatement(statementId);
+                IMappedStatement statement = GetMappedStatement(statementId);
                 return statement.ExecuteQueryForList<T>(sessionScope.Session, parameterObject);
             }
         }
@@ -445,9 +445,9 @@
                 throw new DataMapperException("resultObject parameter must be instantiated before being passed to SqlMapper.QueryForList");
             }
 
-            using (DataMapperLocalSessionScope sessionScope = new DataMapperLocalSessionScope(sessionStore, sessionFactory))
+            using (var sessionScope = new DataMapperLocalSessionScope(sessionStore, sessionFactory))
             {
-                IMappedStatement statement = modelStore.GetMappedStatement(statementId);
+                IMappedStatement statement = GetMappedStatement(statementId);
                 statement.ExecuteQueryForList(sessionScope.Session, parameterObject, resultObject);
             }
         }
@@ -467,9 +467,9 @@
         /// <returns>A List of result objects.</returns>
         public IList<T> QueryWithRowDelegate<T>(string statementId, object parameterObject, RowDelegate<T> rowDelegate)
         {
-            using (DataMapperLocalSessionScope sessionScope = new DataMapperLocalSessionScope(sessionStore, sessionFactory))
+            using (var sessionScope = new DataMapperLocalSessionScope(sessionStore, sessionFactory))
             {
-                IMappedStatement statement = modelStore.GetMappedStatement(statementId);
+                IMappedStatement statement = GetMappedStatement(statementId);
                 return statement.ExecuteQueryForRowDelegate(sessionScope.Session, parameterObject, rowDelegate);
             }
         }
@@ -496,9 +496,9 @@
         /// <returns>A DataTable</returns>
         public DataTable QueryForDataTable(string statementId, object parameterObject)
         {
-            using (DataMapperLocalSessionScope sessionScope = new DataMapperLocalSessionScope(sessionStore, sessionFactory))
+            using (var sessionScope = new DataMapperLocalSessionScope(sessionStore, sessionFactory))
             {
-                IMappedStatement statement = modelStore.GetMappedStatement(statementId);
+                IMappedStatement statement = GetMappedStatement(statementId);
                 return statement.ExecuteQueryForDataTable(sessionScope.Session, parameterObject);
             }
         }
@@ -517,5 +517,10 @@
 
         #endregion
 
+        private IMappedStatement GetMappedStatement(string statementId)
+        {
+            return modelStore.GetMappedStatement(statementId);
+        }
+
     }
 }

Modified: ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/MappedStatements/CachingStatement.cs
URL: http://svn.apache.org/viewvc/ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/MappedStatements/CachingStatement.cs?rev=789059&r1=789058&r2=789059&view=diff
==============================================================================
--- ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/MappedStatements/CachingStatement.cs (original)
+++ ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/MappedStatements/CachingStatement.cs Sun Jun 28 07:03:34 2009
@@ -48,12 +48,15 @@
     [DebuggerDisplay("MappedStatement: {mappedStatement.Id}")]
     public sealed class CachingStatement : MappedStatementEventSupport, IMappedStatement
 	{
-		private readonly MappedStatement mappedStatement =null;
+        // Func<T1, T2, T3, T4, T5, TResult>
+        delegate T RequestRunner<T>(RequestScope requestScope, ISession session, object parameter, CacheKey cacheKey, out bool cacheHit);
+
+        private readonly MappedStatement mappedStatement;
 
 		/// <summary>
         /// Event launch on Execute query
 		/// </summary>
-        public event EventHandler<ExecuteEventArgs> Execute = delegate { };
+        public event EventHandler<ExecuteEventArgs> Executed = delegate { };
 
 		/// <summary>
 		/// Constructor
@@ -108,7 +111,21 @@
         /// <returns>The object</returns>
         public DataTable ExecuteQueryForDataTable(ISession session, object parameterObject)
         {
-            return mappedStatement.ExecuteQueryForDataTable(session, parameterObject);
+            RequestRunner<DataTable> requestRunner = delegate(RequestScope requestscope, ISession session2, object parameter, CacheKey cachekey, out bool cachehit)
+            {
+                cachehit = true;
+                DataTable dataTable = Statement.CacheModel[cachekey] as DataTable;
+                if (dataTable == null)
+                {
+                    cachehit = false;
+                    dataTable = mappedStatement.RunQueryForDataTable(requestscope, session, parameter);
+                    Statement.CacheModel[cachekey] = dataTable;
+                }
+
+                return dataTable;
+            };
+
+            return CachingStatementExecute(PreSelectEventKey, PostSelectEventKey, session, parameterObject, "ExecuteQueryForDataTable", requestRunner);
         }
 
 		/// <summary>
@@ -124,34 +141,34 @@
 		///<exception cref="Apache.Ibatis.DataMapper.Exceptions.DataMapperException">If a transaction is not in progress, or the database throws an exception.</exception>
 		public IDictionary ExecuteQueryForMap(ISession session, object parameterObject, string keyProperty, string valueProperty)
 		{
-			IDictionary map = new Hashtable();
-
-			RequestScope request = Statement.Sql.GetRequestScope(this, parameterObject, session);
-
-			mappedStatement.PreparedCommand.Create( request, session, Statement, parameterObject );
-
-			CacheKey cacheKey = GetCacheKey(request);
-			cacheKey.Update("ExecuteQueryForMap");
-			if (keyProperty!=null)
-			{
-				cacheKey.Update(keyProperty);
-			}
-			if (valueProperty!=null)
-			{
-				cacheKey.Update(valueProperty);
-			}
+            // this doesn't need to be in its own RunQueryForCachedMap method because the class is sealed and can't be called by anyone else
+            RequestRunner<IDictionary> requestRunner = delegate(RequestScope requestscope, ISession session2, object parameter, CacheKey cachekey, out bool cachehit)
+               {
+                   if (keyProperty != null)
+                   {
+                       cachekey.Update(keyProperty);
+                   }
+                   if (valueProperty != null)
+                   {
+                       cachekey.Update(valueProperty);
+                   }
+
+                   cachehit = true;
+                   IDictionary map = Statement.CacheModel[cachekey] as IDictionary;
+                   if (map == null)
+                   {
+                       cachehit = false;
+                       map = mappedStatement.RunQueryForMap(requestscope, session, parameter, keyProperty, valueProperty, null);
+                       Statement.CacheModel[cachekey] = map;
+                   }
 
-			map = Statement.CacheModel[cacheKey] as IDictionary;
-			if (map == null) 
-			{
-				map = mappedStatement.RunQueryForMap( request, session, parameterObject, keyProperty, valueProperty, null );
-                Statement.CacheModel[cacheKey] = map;
-			}
+                   return map;
+               };
 
-			return map;
+            return CachingStatementExecute(PreSelectEventKey, PostSelectEventKey, session, parameterObject, "ExecuteQueryForMap", requestRunner);
 		}
 
-        #region ExecuteQueryForMap .NET 2.0
+	    #region ExecuteQueryForMap .NET 2.0
 	    
         /// <summary>
         /// Executes the SQL and retuns all rows selected in a map that is keyed on the property named
@@ -166,36 +183,40 @@
         ///<exception cref="Apache.Ibatis.DataMapper.Exceptions.DataMapperException">If a transaction is not in progress, or the database throws an exception.</exception>
         public IDictionary<K, V> ExecuteQueryForDictionary<K, V>(ISession session, object parameterObject, string keyProperty, string valueProperty)
         {
-            IDictionary<K, V> map = new Dictionary<K, V>();
-            RequestScope request = Statement.Sql.GetRequestScope(this, parameterObject, session);
-
-            mappedStatement.PreparedCommand.Create(request, session, Statement, parameterObject);
+            // this doesn't need to be in its own RunQueryForCachedDictionary method because the class is sealed and can't be called by anyone else
+            RequestRunner<IDictionary<K, V>> requestRunner = delegate(RequestScope requestScope, ISession session2, object parameter, CacheKey cacheKey, out bool cacheHit)
+             {
+                 if (keyProperty != null)
+                 {
+                     cacheKey.Update(keyProperty);
+                 }
+                 if (valueProperty != null)
+                 {
+                     cacheKey.Update(valueProperty);
+                 }
+
+                 cacheHit = true;
+                 IDictionary<K, V> map = Statement.CacheModel[cacheKey] as IDictionary<K, V>;
+                 if (map == null)
+                 {
+                     cacheHit = false;
+                     map = mappedStatement.RunQueryForDictionary<K, V>(requestScope, session2, parameter, keyProperty, valueProperty, null);
+                     Statement.CacheModel[cacheKey] = map;
+                 }
 
-            CacheKey cacheKey = GetCacheKey(request);
-            cacheKey.Update("ExecuteQueryForMap");
-            if (keyProperty != null)
-            {
-                cacheKey.Update(keyProperty);
-            }
-            if (valueProperty != null)
-            {
-                cacheKey.Update(valueProperty);
-            }
-
-            map = Statement.CacheModel[cacheKey] as IDictionary<K, V>;
-            if (map == null)
-            {
-                map = mappedStatement.RunQueryForDictionary<K, V>(request, session, parameterObject, keyProperty, valueProperty, null);
-                Statement.CacheModel[cacheKey] = map;
-            }
+                 return map;
+             };
 
-            return map;
+            return CachingStatementExecute(PreSelectEventKey, PostSelectEventKey, session, parameterObject, "ExecuteQueryForDictionary", requestRunner);
         }
 
         /// <summary>
         /// Runs a query with a custom object that gets a chance 
         /// to deal with each row as it is processed.
         /// </summary>
+        /// <remarks>
+        /// This method always bypasses the cache.
+        /// </remarks>
         /// <param name="session">The session used to execute the statement</param>
         /// <param name="parameterObject">The object used to set the parameters in the SQL. </param>
         /// <param name="keyProperty">The property of the result object to be used as the key. </param>
@@ -205,7 +226,7 @@
         /// <exception cref="Apache.Ibatis.DataMapper.Exceptions.DataMapperException">If a transaction is not in progress, or the database throws an exception.</exception>
         public IDictionary<K, V> ExecuteQueryForDictionary<K, V>(ISession session, object parameterObject, string keyProperty, string valueProperty, DictionaryRowDelegate<K, V> rowDelegate)
         {
-            return mappedStatement.ExecuteQueryForDictionary<K, V>(session, parameterObject, keyProperty, valueProperty, rowDelegate);
+            return mappedStatement.ExecuteQueryForDictionary(session, parameterObject, keyProperty, valueProperty, rowDelegate);
         }
         #endregion
         
@@ -213,6 +234,9 @@
 		/// Execute an update statement. Also used for delete statement.
 		/// Return the number of row effected.
 		/// </summary>
+        /// <remarks>
+        /// This method always bypasses the cache.
+        /// </remarks>
 		/// <param name="session">The session used to execute the statement.</param>
 		/// <param name="parameterObject">The object used to set the parameters in the SQL.</param>
 		/// <returns>The number of row effected.</returns>
@@ -225,6 +249,9 @@
 		/// Execute an insert statement. Fill the parameter object with 
 		/// the ouput parameters if any, also could return the insert generated key
 		/// </summary>
+        /// <remarks>
+        /// This method always bypasses the cache.
+        /// </remarks>
 		/// <param name="session">The session</param>
 		/// <param name="parameterObject">The parameter object used to fill the statement.</param>
 		/// <returns>Can return the insert generated key.</returns>
@@ -238,6 +265,9 @@
         /// <summary>
 		/// Executes the SQL and and fill a strongly typed collection.
 		/// </summary>
+        /// <remarks>
+        /// This method always bypasses the cache.
+        /// </remarks>
 		/// <param name="session">The session used to execute the statement.</param>
 		/// <param name="parameterObject">The object used to set the parameters in the SQL.</param>
 		/// <param name="resultObject">A strongly typed collection of result objects.</param>
@@ -254,33 +284,33 @@
         /// <returns>A List of result objects.</returns>
         public IList ExecuteQueryForList(ISession session, object parameterObject)
         {
-            IList list = null;
-
-            object param = RaisePreEvent<PreSelectEventArgs>(PreSelectEvent, parameterObject);
-
-            RequestScope request = Statement.Sql.GetRequestScope(this, param, session);
-
-            mappedStatement.PreparedCommand.Create(request, session, Statement, param);
+            // this doesn't need to be in its own RunQueryForCachedList method because the class is sealed and can't be called by anyone else
+            RequestRunner<IList> requestRunner = delegate(RequestScope requestScope, ISession session2, object parameter, CacheKey cacheKey, out bool cacheHit)
+             {
+                 cacheHit = true;
+                 IList list = Statement.CacheModel[cacheKey] as IList;
+                 if (list == null)
+                 {
+                     cacheHit = false;
+                     list = mappedStatement.RunQueryForList(requestScope, session, parameter, null, null);
+                     Statement.CacheModel[cacheKey] = list;
+                 }
+                 return list;
+             };
 
-            CacheKey cacheKey = GetCacheKey(request);
-            cacheKey.Update("ExecuteQueryForList");
-
-            list = Statement.CacheModel[cacheKey] as IList;
-            if (list == null)
-            {
-                list = mappedStatement.RunQueryForList(request, session, param);
-                Statement.CacheModel[cacheKey] = list;
-            }
-
-            return RaisePostEvent<IList, PostSelectEventArgs>(PostSelectEvent, param, list);
+            return CachingStatementExecute(PreSelectEventKey, PostSelectEventKey, session, parameterObject, "ExecuteQueryForList", requestRunner);
         }
-        #endregion
+
+	    #endregion
 
         #region ExecuteQueryForList .NET 2.0
 
         /// <summary>
         /// Executes the SQL and and fill a strongly typed collection.
         /// </summary>
+        /// <remarks>
+        /// This method always bypasses the cache.
+        /// </remarks>
         /// <param name="session">The session used to execute the statement.</param>
         /// <param name="parameterObject">The object used to set the parameters in the SQL.</param>
         /// <param name="resultObject">A strongly typed collection of result objects.</param>
@@ -297,25 +327,23 @@
         /// <returns>A List of result objects.</returns>
         public IList<T> ExecuteQueryForList<T>(ISession session, object parameterObject)
         {
-            IList<T> list = null;
-
-            object param = RaisePreEvent<PreSelectEventArgs>(PreSelectEvent, parameterObject);
-
-            RequestScope request = Statement.Sql.GetRequestScope(this, param, session);
-
-            mappedStatement.PreparedCommand.Create(request, session, Statement, param);
-
-            CacheKey cacheKey = GetCacheKey(request);
-            cacheKey.Update("ExecuteQueryForList");
-
-            list = Statement.CacheModel[cacheKey] as IList<T>;
-            if (list == null)
+            // this doesn't need to be in its own RunQueryForCachedList method because the class is sealed and can't be called by anyone else
+            RequestRunner<IList<T>> requestRunner = delegate(RequestScope requestScope, ISession session2, object parameter, CacheKey cacheKey, out bool cacheHit)
             {
-                list = mappedStatement.RunQueryForList<T>(request, session, param);
-                Statement.CacheModel[cacheKey] = list;
-            }
-            return RaisePostEvent<IList<T>, PostSelectEventArgs>(PostSelectEvent, param, list);
+                cacheHit = true;
+                IList<T> list = Statement.CacheModel[cacheKey] as IList<T>;
+                if (list == null)
+                {
+                    cacheHit = false;
+                    list = mappedStatement.RunQueryForList<T>(requestScope, session, parameter, null, null);
+                    Statement.CacheModel[cacheKey] = list;
+                }
+                return list;
+            };
+
+            return CachingStatementExecute(PreSelectEventKey, PostSelectEventKey, session, parameterObject, "ExecuteQueryForList", requestRunner);
         }
+       
         #endregion
 
         #region ExecuteQueryForObject
@@ -330,31 +358,27 @@
 		/// <returns>The object</returns>
 		public object ExecuteQueryForObject(ISession session, object parameterObject, object resultObject)
 		{
-			object obj = null;
-
-            object param = RaisePreEvent<PreSelectEventArgs>(PreSelectEvent, parameterObject);
-
-            RequestScope request = Statement.Sql.GetRequestScope(this, param, session);
-
-            mappedStatement.PreparedCommand.Create(request, session, Statement, param);
-
-			CacheKey cacheKey = GetCacheKey(request);
-			cacheKey.Update("ExecuteQueryForObject");
-
-            obj = Statement.CacheModel[cacheKey];
-			// check if this query has alreay been run 
-            if (obj == CacheModel.NULL_OBJECT) 
-			{ 
-				// convert the marker object back into a null value 
-				obj = null; 
-			} 
-			else if (obj ==null)
-			{
-                obj = mappedStatement.RunQueryForObject(request, session, param, resultObject);
-                Statement.CacheModel[cacheKey] = obj;
-			}
+            // this doesn't need to be in its own RunQueryForCachedObject method because the class is sealed and can't be called by anyone else
+            RequestRunner<object> requestRunner = delegate(RequestScope requestScope, ISession session2, object parameter, CacheKey cacheKey, out bool cacheHit)
+            {
+                cacheHit = true;
+                object obj = Statement.CacheModel[cacheKey];
+                // check if this query has alreay been run 
+                if (obj == CacheModel.NULL_OBJECT)
+                {
+                    // convert the marker object back into a null value 
+                    obj = null;
+                }
+                else if (obj == null)
+                {
+                    cacheHit = false;
+                    obj = mappedStatement.RunQueryForObject(requestScope, session, parameter, resultObject);
+                    Statement.CacheModel[cacheKey] = obj;
+                }
+                return obj;
+            };
 
-            return RaisePostEvent<object, PostSelectEventArgs>(PostSelectEvent, param, obj);
+            return CachingStatementExecute(PreSelectEventKey, PostSelectEventKey, session, parameterObject, "ExecuteQueryForObject", requestRunner);
         }
         
         #endregion
@@ -371,35 +395,35 @@
         /// <returns>The object</returns>
         public T ExecuteQueryForObject<T>(ISession session, object parameterObject, T resultObject)
         {
-            T obj = default(T);
-
-            object param = RaisePreEvent<PreSelectEventArgs>(PreSelectEvent, parameterObject);
-
-            RequestScope request = Statement.Sql.GetRequestScope(this, param, session);
+            // this doesn't need to be in its own RunQueryForCachedObject method because the class is sealed and can't be called by anyone else
+            RequestRunner<T> requestRunner = delegate(RequestScope requestScope, ISession session2, object parameter, CacheKey cacheKey, out bool cacheHit)
+            {
+                T obj; 
 
-            mappedStatement.PreparedCommand.Create(request, session, Statement, param);
+                cacheHit = false;
+                object cacheObjet = Statement.CacheModel[cacheKey];
+                // check if this query has alreay been run 
+                if (cacheObjet is T)
+                {
+                    cacheHit = true;
+                    obj = (T)cacheObjet;
+                }
+                else if (cacheObjet == CacheModel.NULL_OBJECT)
+                {
+                    // convert the marker object back into a null value 
+                    cacheHit = true;
+                    obj = default(T);
+                }
+                else //if ((object)obj == null)
+                {
+                    obj = mappedStatement.RunQueryForObject(requestScope, session, parameter, resultObject);
+                    Statement.CacheModel[cacheKey] = obj;
+                }
 
-            CacheKey cacheKey = GetCacheKey(request);
-            cacheKey.Update("ExecuteQueryForObject");
+                return obj;
+            };
 
-            object cacheObjet = Statement.CacheModel[cacheKey];
-            // check if this query has alreay been run 
-            if (cacheObjet is T)
-            {
-                obj = (T)cacheObjet;
-            }
-            else if (cacheObjet == CacheModel.NULL_OBJECT)
-            {
-                // convert the marker object back into a null value 
-                obj = default(T);
-            }
-            else //if ((object)obj == null)
-            {
-                obj = (T)mappedStatement.RunQueryForObject(request, session, param, resultObject);
-                Statement.CacheModel[cacheKey] = obj;
-            }
-
-            return RaisePostEvent<T, PostSelectEventArgs>(PostSelectEvent, param, obj);
+            return CachingStatementExecute(PreSelectEventKey, PostSelectEventKey, session, parameterObject, "ExecuteQueryForObject", requestRunner);
         }
         
         #endregion
@@ -408,11 +432,15 @@
 		/// Runs a query with a custom object that gets a chance 
 		/// to deal with each row as it is processed.
 		/// </summary>
+        /// <remarks>
+        /// This method always bypasses the cache.
+        /// </remarks>
 		/// <param name="session">The session used to execute the statement.</param>
 		/// <param name="parameterObject">The object used to set the parameters in the SQL.</param>
 		/// <param name="rowDelegate"></param>
 		public IList ExecuteQueryForRowDelegate(ISession session, object parameterObject, RowDelegate rowDelegate)
 		{
+            // TODO: investigate allow the cached data to be processed by a different rowDelegate...add rowDelegate to the CacheKey ???
 			return mappedStatement.ExecuteQueryForRowDelegate(session, parameterObject, rowDelegate);
 		}
 
@@ -420,18 +448,25 @@
         /// Runs a query with a custom object that gets a chance 
         /// to deal with each row as it is processed.
         /// </summary>
+        /// <remarks>
+        /// This method always bypasses the cache.
+        /// </remarks>
         /// <param name="session">The session used to execute the statement.</param>
         /// <param name="parameterObject">The object used to set the parameters in the SQL.</param>
         /// <param name="rowDelegate"></param>
         public IList<T> ExecuteQueryForRowDelegate<T>(ISession session, object parameterObject, RowDelegate<T> rowDelegate)
         {
-            return mappedStatement.ExecuteQueryForRowDelegate<T>(session, parameterObject, rowDelegate);
+            // TODO: investigate allow the cached data to be processed by a different rowDelegate...add rowDelegate to the CacheKey ???
+            return mappedStatement.ExecuteQueryForRowDelegate(session, parameterObject, rowDelegate);
         }
 
 		/// <summary>
 		/// Runs a query with a custom object that gets a chance 
 		/// to deal with each row as it is processed.
 		/// </summary>
+        /// <remarks>
+        /// This method always bypasses the cache.
+        /// </remarks>
 		/// <param name="session">The session used to execute the statement</param>
 		/// <param name="parameterObject">The object used to set the parameters in the SQL. </param>
 		/// <param name="keyProperty">The property of the result object to be used as the key. </param>
@@ -441,6 +476,7 @@
 		/// <exception cref="Apache.Ibatis.DataMapper.Exceptions.DataMapperException">If a transaction is not in progress, or the database throws an exception.</exception>
 		public IDictionary ExecuteQueryForMapWithRowDelegate(ISession session, object parameterObject, string keyProperty, string valueProperty, DictionaryRowDelegate rowDelegate)
 		{
+            // TODO: investigate allow the cached data to be processed by a different rowDelegate...add rowDelegate to the CacheKey ???
 			return mappedStatement.ExecuteQueryForMapWithRowDelegate(session, parameterObject, keyProperty, valueProperty, rowDelegate);
 		}
 
@@ -476,5 +512,27 @@
             //}
 			return cacheKey;
 		}
+
+        /// <summary>
+        /// Ensures all the related Execute methods are run in a consistent manner with pre and post events.
+        /// </summary>
+        /// <remarks>
+        /// Based off of MappedStatement.Execute
+        /// </remarks>
+        private T CachingStatementExecute<T>(object preEvent, object postEvent, ISession session, object parameterObject, string baseCacheKey, RequestRunner<T> requestRunner)
+        {
+            object paramPreEvent = RaisePreEvent(preEvent, parameterObject);
+
+            RequestScope requestScope = Statement.Sql.GetRequestScope(this, paramPreEvent, session);
+            mappedStatement.PreparedCommand.Create(requestScope, session, Statement, paramPreEvent);
+
+            CacheKey cacheKey = GetCacheKey(requestScope);
+            cacheKey.Update(baseCacheKey);
+
+            bool cacheHit;
+            T result = requestRunner(requestScope, session, paramPreEvent, cacheKey, out cacheHit);
+
+            return RaisePostEvent(postEvent, paramPreEvent, result, cacheHit);
+        }
     }
 }

Modified: ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/MappedStatements/IMappedStatement.cs
URL: http://svn.apache.org/viewvc/ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/MappedStatements/IMappedStatement.cs?rev=789059&r1=789058&r2=789059&view=diff
==============================================================================
--- ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/MappedStatements/IMappedStatement.cs (original)
+++ ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/MappedStatements/IMappedStatement.cs Sun Jun 28 07:03:34 2009
@@ -50,7 +50,7 @@
 		/// <summary>
 		/// Event launch on exceute query
 		/// </summary>
-        event EventHandler<ExecuteEventArgs> Execute;
+        event EventHandler<ExecuteEventArgs> Executed;
 
 		#endregion 
 

Modified: ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/MappedStatements/IMappedStatementEvents.cs
URL: http://svn.apache.org/viewvc/ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/MappedStatements/IMappedStatementEvents.cs?rev=789059&r1=789058&r2=789059&view=diff
==============================================================================
--- ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/MappedStatements/IMappedStatementEvents.cs (original)
+++ ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/MappedStatements/IMappedStatementEvents.cs Sun Jun 28 07:03:34 2009
@@ -33,11 +33,11 @@
     /// </summary>
     public interface IMappedStatementEvents
     {
-        event EventHandler<PreInsertEventArgs> PreInsert;
-        event EventHandler<PreSelectEventArgs> PreSelect;
-        event EventHandler<PreUpdateOrDeleteEventArgs> PreUpdateOrDelete;
-        event EventHandler<PostInsertEventArgs> PostInsert;
-        event EventHandler<PostSelectEventArgs> PostSelect;
-        event EventHandler<PostUpdateOrDeleteEventArgs> PostUpdateOrDelete;
+        event EventHandler<PreStatementEventArgs> PreInsert;
+        event EventHandler<PreStatementEventArgs> PreSelect;
+        event EventHandler<PreStatementEventArgs> PreUpdateOrDelete;
+        event EventHandler<PostStatementEventArgs> PostInsert;
+        event EventHandler<PostStatementEventArgs> PostSelect;
+        event EventHandler<PostStatementEventArgs> PostUpdateOrDelete;
     }
 }