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.