User: mzywitza
Date: 2010/01/11 10:39 AM

Added:
 /ActiveRecord/trunk/src/Castle.ActiveRecord.Tests/Conversation/
  ConversationScenarioTest.cs
 /ActiveRecord/trunk/src/Castle.ActiveRecord/Framework/Scopes/
  ConversationalScope.cs, IConversation.cs, IScopeConversation.cs, 
ScopedConversation.cs

Modified:
 /ActiveRecord/trunk/src/
  Changes.txt
 /ActiveRecord/trunk/src/Castle.ActiveRecord.Tests/
  Castle.ActiveRecord.Tests-vs2008.csproj
 /ActiveRecord/trunk/src/Castle.ActiveRecord/
  Castle.ActiveRecord-vs2008.csproj

Log:
 Added basic support for CpBT.

File Changes:

Directory: /ActiveRecord/trunk/src/Castle.ActiveRecord/
=======================================================

File [modified]: Castle.ActiveRecord-vs2008.csproj
Delta lines: +69 -0
===================================================================

--- 
ActiveRecord/trunk/src/Castle.ActiveRecord/Framework/Scopes/ConversationalScope.cs
                          (rev 0)
+++ 
ActiveRecord/trunk/src/Castle.ActiveRecord/Framework/Scopes/ConversationalScope.cs
  2010-01-11 17:39:37 UTC (rev 6627)
@@ -0,0 +1,69 @@
+// Copyright 2004-2009 Castle Project - http://www.castleproject.org/
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// 
+//     http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+namespace Castle.ActiveRecord
+{
+       using System;
+       using Framework.Scopes;
+       using NHibernate;
+
+       /// <summary>
+       /// Scope-implementation making use of a <see 
cref="ScopedConversation"/>.
+       /// </summary>
+       public class ConversationalScope : AbstractScope
+       {
+               /// <summary>
+               /// The conversation to use.
+               /// </summary>
+               protected IScopeConversation conversation;
+
+               /// <summary>
+               /// Minimum constructor which sets at least the conversation to
+               /// use.
+               /// </summary>
+               /// <param name="conversation"></param>
+               public ConversationalScope(IScopeConversation conversation)
+                       : base(FlushAction.Config, 
SessionScopeType.Transactional)
+               {
+                       this.conversation = conversation;
+               }
+
+               /// <summary>
+               /// Notifies the <see cref="conversation"/> that the session has
+               /// failed.
+               /// </summary>
+               /// <param name="session">The failed sessions.</param>
+               public override void FailSession(ISession session)
+               {
+                       throw new NotImplementedException();
+               }
+               
+               /// <summary>
+               /// Always <c>true</c>, we take sessions from the <see 
cref="IConversation"/>.
+               /// </summary>
+               public override bool WantsToCreateTheSession { get { return 
true; } }
+
+
+               /// <summary>
+               /// Delegate opening session to <see cref="IConversation"/>
+               /// </summary>
+               /// <param name="sessionFactory">The factory to use for this 
type</param>
+               /// <param name="interceptor">An interceptor to include</param>
+               /// <returns>A valid session from the <see 
cref="ISessionFactory"/>.</returns>
+               public override ISession OpenSession(ISessionFactory 
sessionFactory, IInterceptor interceptor)
+               {
+                       return conversation.GetSession(sessionFactory, 
interceptor);
+               }
+       }
+}

Directory: /ActiveRecord/trunk/src/Castle.ActiveRecord.Tests/
=============================================================

File [modified]: Castle.ActiveRecord.Tests-vs2008.csproj
Delta lines: +140 -0
===================================================================

--- 
ActiveRecord/trunk/src/Castle.ActiveRecord.Tests/Conversation/ConversationScenarioTest.cs
                           (rev 0)
+++ 
ActiveRecord/trunk/src/Castle.ActiveRecord.Tests/Conversation/ConversationScenarioTest.cs
   2010-01-11 17:39:37 UTC (rev 6627)
@@ -0,0 +1,141 @@
+// Copyright 2004-2009 Castle Project - http://www.castleproject.org/
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// 
+//     http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+namespace Castle.ActiveRecord.Tests.Conversation
+{
+    using System;
+    using System.Linq;
+    using NHibernate;
+    using NUnit.Framework;
+
+    [TestFixture]
+    public class ConversationScenarioTest : NUnitInMemoryTest
+    {
+        public override Type[] GetTypes()
+        {
+            return new[] {typeof (BlogLazy), typeof (PostLazy)};
+        }
+
+        [Test]
+        public void BasicScenario()
+        {
+            // Arrange
+            ArrangeRecords();
+
+               // Act
+            IScopeConversation conversation = new ScopedConversation();
+            BlogLazy queriedBlog;
+            using (new ConversationalScope(conversation))
+            {
+                queriedBlog = BlogLazy.Find(1);
+            }
+
+            // No scope here
+            var fetchedPosts = queriedBlog.PublishedPosts;
+            var firstPost = fetchedPosts[0] as PostLazy;
+            firstPost.Published = false;
+
+            using (new ConversationalScope(conversation))
+            {
+                firstPost.SaveAndFlush();
+                queriedBlog.Refresh();
+            }
+
+            // Assert
+
+            // Again, we're querying lazy properties out of scope
+            Assert.That(queriedBlog.PublishedPosts, Is.Empty);
+            Assert.That(queriedBlog.Posts, Is.Not.Empty);
+
+            conversation.Dispose();
+        }
+
+       private void ArrangeRecords()
+       {
+               BlogLazy blog = new BlogLazy()
+                                       {
+                                               Author = "Markus",
+                                               Name = "Conversations"
+                                       };
+               PostLazy post = new PostLazy()
+                                       {
+                                               Blog = blog,
+                                               Category = "Scenario",
+                                               Title = "The Convesration is 
here",
+                                               Contents = "A new way for AR in 
fat clients",
+                                               Created = new DateTime(2010, 1, 
1),
+                                               Published = true
+                                       };
+               blog.Save();
+               post.Save();
+       }
+
+       [Test]
+               public void CanCancelConversations()
+               {
+                       ArrangeRecords();
+               using (var conversation = new ScopedConversation())
+               {
+                       BlogLazy blog = null;
+                       using (new ConversationalScope(conversation))
+                       {
+                               blog = BlogLazy.FindAll().First();
+                       }
+
+                       blog.Author = "Somebody else";
+
+                       using (new ConversationalScope(conversation))
+                       {
+                               blog.SaveAndFlush();
+                       }
+
+                       conversation.Cancel();
+               }
+                       Assert.That(BlogLazy.FindAll().First().Author, 
Is.EqualTo("Markus"));
+               }
+    }
+
+       [TestFixture]
+       public class ScopedConversationTests : NUnitInMemoryTest
+       {
+               public override Type[] GetTypes()
+               {
+                       return new[] { typeof(BlogLazy), typeof(PostLazy) };
+               }
+               
+               [Test]
+               public void SessionsAreKeptThroughoutTheConversation()
+               {
+                       IScopeConversation conversation = new 
ScopedConversation();
+                       ISession session = null;
+
+                       using (new ConversationalScope(conversation))
+                       {
+                               BlogLazy.FindAll();
+                               session = BlogLazy.Holder.CreateSession(typeof 
(BlogLazy));
+                       }
+
+                       Assert.That(session.IsOpen);
+
+                       using (new ConversationalScope(conversation))
+                       {
+                               BlogLazy.FindAll();
+                               
Assert.That(BlogLazy.Holder.CreateSession(typeof(BlogLazy)), 
Is.SameAs(session));
+                       }
+
+                       conversation.Dispose();
+                       Assert.That(session.IsOpen, Is.False);
+               }
+       }

Directory: /ActiveRecord/trunk/src/Castle.ActiveRecord.Tests/Conversation/
==========================================================================

File [added]: ConversationScenarioTest.cs
Delta lines: +2 -0
===================================================================

--- ActiveRecord/trunk/src/Changes.txt  2010-01-11 17:35:16 UTC (rev 6626)
+++ ActiveRecord/trunk/src/Changes.txt  2010-01-11 17:39:37 UTC (rev 6627)
@@ -13,7 +13,9 @@
     guid.comb for guids
     assigned for strings
     native otherwise
+- Added basic support for CpBT (see IConversation interface and tests for 
usage)
 
+
 - Bugs fixed:
   AR-ISSUE-157

Directory: /ActiveRecord/trunk/src/Castle.ActiveRecord/Framework/Scopes/
========================================================================

File [added]: ConversationalScope.cs
Delta lines: +30 -0
===================================================================

--- 
ActiveRecord/trunk/src/Castle.ActiveRecord/Framework/Scopes/IConversation.cs    
                            (rev 0)
+++ 
ActiveRecord/trunk/src/Castle.ActiveRecord/Framework/Scopes/IConversation.cs    
    2010-01-11 17:39:37 UTC (rev 6627)
@@ -0,0 +1,30 @@
+// Copyright 2004-2009 Castle Project - http://www.castleproject.org/
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// 
+//     http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+namespace Castle.ActiveRecord
+{
+    using System;
+
+       /// <summary>
+    /// Conversations allow to define broader units of work
+    /// than <see cref="SessionScope"/> allows to.
+    /// </summary>
+    public interface IConversation : IDisposable
+    {
+               /// <summary>
+               /// Cancels all changes made in this session.
+               /// </summary>
+               void Cancel();
+    }
+}

File [added]: IConversation.cs
Delta lines: +34 -0
===================================================================

--- 
ActiveRecord/trunk/src/Castle.ActiveRecord/Framework/Scopes/IScopeConversation.cs
                           (rev 0)
+++ 
ActiveRecord/trunk/src/Castle.ActiveRecord/Framework/Scopes/IScopeConversation.cs
   2010-01-11 17:39:37 UTC (rev 6627)
@@ -0,0 +1,34 @@
+// Copyright 2004-2009 Castle Project - http://www.castleproject.org/
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// 
+//     http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+namespace Castle.ActiveRecord
+{
+       using NHibernate;
+
+       /// <summary>
+       /// Interface for specific conversations using the ActiveRecord
+       /// scope machinery. 
+       /// </summary>
+       public interface IScopeConversation : IConversation
+       {
+               /// <summary>
+               /// Looks up or creates an <see cref="ISession"/> using the
+               /// specified <see cref="ISessionFactory"/>.
+               /// </summary>
+               /// <param name="factory">The factory to use.</param>
+               /// <param name="interceptor">An interceptor to include.</param>
+               /// <returns>An open session.</returns>
+               ISession GetSession(ISessionFactory factory, IInterceptor 
interceptor);
+       }
+}

File [added]: IScopeConversation.cs
Delta lines: +83 -0
===================================================================

--- 
ActiveRecord/trunk/src/Castle.ActiveRecord/Framework/Scopes/ScopedConversation.cs
                           (rev 0)
+++ 
ActiveRecord/trunk/src/Castle.ActiveRecord/Framework/Scopes/ScopedConversation.cs
   2010-01-11 17:39:37 UTC (rev 6627)
@@ -0,0 +1,83 @@
+// Copyright 2004-2009 Castle Project - http://www.castleproject.org/
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// 
+//     http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+namespace Castle.ActiveRecord
+{
+       using System;
+       using System.Collections.Generic;
+       using System.Threading;
+       using Framework;
+       using Framework.Scopes;
+       using NHibernate;
+
+       /// <summary>
+       /// An <see cref="IConversation"/> implementation using 
+       /// <see cref="AbstractScope"/>.
+       /// </summary>
+       public class ScopedConversation : IScopeConversation
+       {
+               private bool canceled = false;
+
+               /// <inheritDoc />
+               public void Dispose()
+               {
+                       //todo: Add possibility to rollback on failure
+                       foreach (var session in openedSessions.Values)
+                       {
+                               if (canceled)
+                                       session.Transaction.Rollback();
+                               else
+                               {
+                                       session.Transaction.Commit();
+                                       session.Flush();
+                               }
+
+                               session.Dispose();
+                       }
+               }
+
+               /// <inheritDoc />
+               public void Cancel()
+               {
+                       canceled = true;
+               }
+
+               /// <inheritDoc />
+               public ISession GetSession(ISessionFactory factory, 
IInterceptor interceptor)
+               {
+                       if (canceled)
+                       {
+                               throw new ActiveRecordException(
+                                       "A session was requested from a 
conversation that has "+
+                    "been already canceled. Please check that after the "+
+                                       "cancellation of a conversation no more 
"+
+                    "ConversationalScopes are opened using it.");
+                       }
+                       if (!openedSessions.ContainsKey(factory))
+                               CreateSession(factory, interceptor);
+                       return openedSessions[factory];
+               }
+
+               private void CreateSession(ISessionFactory factory, 
IInterceptor interceptor)
+               {
+                       var session = factory.OpenSession(interceptor);
+                       session.BeginTransaction();
+                       // todo: allow to configure this
+                       session.FlushMode = FlushMode.Auto;
+                       openedSessions.Add(factory,session);
+               }
+
+               private Dictionary<ISessionFactory, ISession> openedSessions = 
new Dictionary<ISessionFactory,ISession>();
+       }
+}

File [added]: ScopedConversation.cs
Delta lines: +1 -0
===================================================================

--- 
ActiveRecord/trunk/src/Castle.ActiveRecord.Tests/Castle.ActiveRecord.Tests-vs2008.csproj
    2010-01-11 17:35:16 UTC (rev 6626)
+++ 
ActiveRecord/trunk/src/Castle.ActiveRecord.Tests/Castle.ActiveRecord.Tests-vs2008.csproj
    2010-01-11 17:39:37 UTC (rev 6627)
@@ -337,6 +337,7 @@
     <Compile Include="CompositeUserTypeTestCase.cs" />
     <Compile Include="Config\ConfigureTests.cs" />
     <Compile Include="Config\StorageConfigurationTests.cs" />
+    <Compile Include="Conversation\ConversationScenarioTest.cs" />
     <Compile Include="DefaultConfigurationsTestCase.cs" />
     <Compile Include="FetchTestCase.cs" />

Directory: /ActiveRecord/trunk/src/
===================================

File [modified]: Changes.txt
Delta lines: +0 -0
===================================================================

-- 
You received this message because you are subscribed to the Google Groups 
"Castle Project Commits" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/castle-project-commits?hl=en.


Reply via email to