diff --git a/src/SQLCE4Umbraco/SqlCeApplicationBlock.cs b/src/SQLCE4Umbraco/SqlCeApplicationBlock.cs
index fd778bbfb3..2dd0f26e90 100644
--- a/src/SQLCE4Umbraco/SqlCeApplicationBlock.cs
+++ b/src/SQLCE4Umbraco/SqlCeApplicationBlock.cs
@@ -240,7 +240,7 @@ namespace SqlCE4Umbraco
{
var cmd = trx == null ? new SqlCeCommand(commandText, conn) : new SqlCeCommand(commandText, conn, trx);
AttachParameters(cmd, commandParameters);
- return cmd.ExecuteReader(CommandBehavior.CloseConnection);
+ return cmd.ExecuteReader();
}
catch
{
diff --git a/src/Umbraco.Core/ApplicationContext.cs b/src/Umbraco.Core/ApplicationContext.cs
index 88c2d65926..4be0787a31 100644
--- a/src/Umbraco.Core/ApplicationContext.cs
+++ b/src/Umbraco.Core/ApplicationContext.cs
@@ -422,10 +422,17 @@ namespace Umbraco.Core
this.ApplicationCache = null;
if (_databaseContext != null) //need to check the internal field here
{
+ if (_databaseContext.ScopeProvider.AmbientScope != null)
+ {
+ var scope = _databaseContext.ScopeProvider.AmbientScope;
+ scope.Dispose();
+ }
+ /*
if (DatabaseContext.IsDatabaseConfigured && DatabaseContext.Database != null)
{
DatabaseContext.Database.Dispose();
- }
+ }
+ */
}
this.DatabaseContext = null;
this.Services = null;
diff --git a/src/Umbraco.Core/DatabaseContext.cs b/src/Umbraco.Core/DatabaseContext.cs
index ec5607f641..43a755a780 100644
--- a/src/Umbraco.Core/DatabaseContext.cs
+++ b/src/Umbraco.Core/DatabaseContext.cs
@@ -113,8 +113,9 @@ namespace Umbraco.Core
{
get
{
- var scope = ScopeProvider.AmbientScope;
- return scope != null ? scope.Database : ScopeProvider.CreateNoScope().Database;
+ return ScopeProvider.AmbientOrNoScope.Database;
+ //var scope = ScopeProvider.AmbientScope;
+ //return scope != null ? scope.Database : ScopeProvider.CreateNoScope().Database;
}
}
diff --git a/src/Umbraco.Core/Persistence/DefaultDatabaseFactory.cs b/src/Umbraco.Core/Persistence/DefaultDatabaseFactory.cs
index 69026962ac..46a2defd66 100644
--- a/src/Umbraco.Core/Persistence/DefaultDatabaseFactory.cs
+++ b/src/Umbraco.Core/Persistence/DefaultDatabaseFactory.cs
@@ -22,7 +22,7 @@ namespace Umbraco.Core.Persistence
//private static readonly object Locker = new object();
// bwc imposes a weird x-dependency between database factory and scope provider...
- public ScopeProvider ScopeProvider { get; set; }
+ public IScopeProviderInternal ScopeProvider { get; set; }
///
/// Constructor accepting custom connection string
@@ -61,8 +61,9 @@ namespace Umbraco.Core.Persistence
public UmbracoDatabase CreateDatabase()
{
- var scope = ScopeProvider.AmbientScope;
- return scope != null ? scope.Database : ScopeProvider.CreateNoScope().Database;
+ return ScopeProvider.AmbientOrNoScope.Database;
+ //var scope = ScopeProvider.AmbientScope;
+ //return scope != null ? scope.Database : ScopeProvider.CreateNoScope().Database;
/*
UmbracoDatabase database;
diff --git a/src/Umbraco.Core/Persistence/PetaPoco.cs b/src/Umbraco.Core/Persistence/PetaPoco.cs
index b569b1c45d..ecd5280012 100644
--- a/src/Umbraco.Core/Persistence/PetaPoco.cs
+++ b/src/Umbraco.Core/Persistence/PetaPoco.cs
@@ -332,8 +332,16 @@ namespace Umbraco.Core.Persistence
if (_transactionDepth == 1)
{
OpenSharedConnection();
- _transaction = _sharedConnection.BeginTransaction(isolationLevel);
- _transactionCancelled = false;
+ try
+ {
+ _transaction = _sharedConnection.BeginTransaction(isolationLevel);
+ }
+
+ catch (Exception e)
+ {
+ throw;
+ }
+ _transactionCancelled = false;
OnBeginTransaction();
}
else if (isolationLevel > _transaction.IsolationLevel)
diff --git a/src/Umbraco.Core/Persistence/Repositories/NotificationsRepository.cs b/src/Umbraco.Core/Persistence/Repositories/NotificationsRepository.cs
index 9e6e3cf47c..aa7ebeacc8 100644
--- a/src/Umbraco.Core/Persistence/Repositories/NotificationsRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/NotificationsRepository.cs
@@ -9,7 +9,7 @@ using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
{
- internal class NotificationsRepository
+ internal class NotificationsRepository : IDisposable
{
private readonly IDatabaseUnitOfWork _unitOfWork;
@@ -102,5 +102,10 @@ namespace Umbraco.Core.Persistence.Repositories
_unitOfWork.Database.Insert(dto);
return new Notification(dto.NodeId, dto.UserId, dto.Action, nodeType);
}
+
+ public void Dispose()
+ {
+ _unitOfWork.Dispose();
+ }
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/UmbracoDatabase.cs b/src/Umbraco.Core/Persistence/UmbracoDatabase.cs
index 44a3db9424..46284b1a2d 100644
--- a/src/Umbraco.Core/Persistence/UmbracoDatabase.cs
+++ b/src/Umbraco.Core/Persistence/UmbracoDatabase.cs
@@ -57,6 +57,20 @@ namespace Umbraco.Core.Persistence
///
internal bool EnableSqlTrace { get; set; }
+ public bool InTransaction { get; private set; }
+
+ public override void OnBeginTransaction()
+ {
+ base.OnBeginTransaction();
+ InTransaction = true;
+ }
+
+ public override void OnEndTransaction()
+ {
+ base.OnEndTransaction();
+ InTransaction = false;
+ }
+
#if DEBUG_DATABASES
private const bool EnableSqlTraceDefault = true;
#else
diff --git a/src/Umbraco.Core/Persistence/UnitOfWork/PetaPocoUnitOfWork.cs b/src/Umbraco.Core/Persistence/UnitOfWork/PetaPocoUnitOfWork.cs
index 6c71614c1a..6499ea29fe 100644
--- a/src/Umbraco.Core/Persistence/UnitOfWork/PetaPocoUnitOfWork.cs
+++ b/src/Umbraco.Core/Persistence/UnitOfWork/PetaPocoUnitOfWork.cs
@@ -10,15 +10,16 @@ namespace Umbraco.Core.Persistence.UnitOfWork
///
internal class PetaPocoUnitOfWork : DisposableObject, IDatabaseUnitOfWork
{
- private readonly IScope _scope;
-
- ///
- /// Used for testing
- ///
- internal Guid InstanceId { get; private set; }
-
- private Guid _key;
private readonly Queue _operations = new Queue();
+ private readonly IScopeProvider _scopeProvider;
+ private bool _completeScope = true; // scope is completed by default
+ private IScope _scope;
+ private Guid _key;
+
+ ///
+ /// Used for testing
+ ///
+ internal Guid InstanceId { get; private set; }
///
/// Creates a new unit of work instance
@@ -29,7 +30,7 @@ namespace Umbraco.Core.Persistence.UnitOfWork
///
internal PetaPocoUnitOfWork(IScopeProvider scopeProvider)
{
- _scope = scopeProvider.CreateScope();
+ _scopeProvider = scopeProvider;
_key = Guid.NewGuid();
InstanceId = Guid.NewGuid();
}
@@ -102,34 +103,34 @@ namespace Umbraco.Core.Persistence.UnitOfWork
///
internal void Commit(Action transactionCompleting)
{
- using (var transaction = Database.GetTransaction())
+ // this happens in a scope-managed transaction
+
+ // in case anything goes wrong
+ _completeScope = false;
+
+ while (_operations.Count > 0)
{
- while (_operations.Count > 0)
+ var operation = _operations.Dequeue();
+ switch (operation.Type)
{
- var operation = _operations.Dequeue();
- switch (operation.Type)
- {
- case TransactionType.Insert:
- operation.Repository.PersistNewItem(operation.Entity);
- break;
- case TransactionType.Delete:
- operation.Repository.PersistDeletedItem(operation.Entity);
- break;
- case TransactionType.Update:
- operation.Repository.PersistUpdatedItem(operation.Entity);
- break;
- }
+ case TransactionType.Insert:
+ operation.Repository.PersistNewItem(operation.Entity);
+ break;
+ case TransactionType.Delete:
+ operation.Repository.PersistDeletedItem(operation.Entity);
+ break;
+ case TransactionType.Update:
+ operation.Repository.PersistUpdatedItem(operation.Entity);
+ break;
}
-
- //Execute the callback if there is one
- if (transactionCompleting != null)
- {
- transactionCompleting(Database);
- }
-
- transaction.Complete();
}
+ if (transactionCompleting != null)
+ transactionCompleting(Database);
+
+ // all is ok
+ _completeScope = true;
+
// Clear everything
_operations.Clear();
_key = Guid.NewGuid();
@@ -140,7 +141,16 @@ namespace Umbraco.Core.Persistence.UnitOfWork
get { return _key; }
}
- public UmbracoDatabase Database {get { return _scope.Database; } }
+ public UmbracoDatabase Database
+ {
+ get
+ {
+ if (_scope == null)
+ //throw new InvalidOperationException("Out-of-scope UnitOfWork.");
+ _scope = _scopeProvider.CreateScope();
+ return _scope.Database;
+ }
+ }
#region Operation
@@ -179,7 +189,11 @@ namespace Umbraco.Core.Persistence.UnitOfWork
protected override void DisposeResources()
{
_operations.Clear();
+ if (_scope == null) return;
+
+ if (_completeScope) _scope.Complete();
_scope.Dispose();
+ _scope = null;
}
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Scoping/IScope.cs b/src/Umbraco.Core/Scoping/IScope.cs
index f56fcdd018..e379273f58 100644
--- a/src/Umbraco.Core/Scoping/IScope.cs
+++ b/src/Umbraco.Core/Scoping/IScope.cs
@@ -4,11 +4,24 @@ using Umbraco.Core.Persistence;
namespace Umbraco.Core.Scoping
{
+ ///
+ /// Represents a scope.
+ ///
public interface IScope : IDisposeOnRequestEnd // implies IDisposable
{
+ ///
+ /// Gets the scope database.
+ ///
UmbracoDatabase Database { get; }
+
+ ///
+ /// Gets the scope event messages.
+ ///
IList Messages { get; }
+ ///
+ /// Completes the scope.
+ ///
void Complete();
}
}
diff --git a/src/Umbraco.Core/Scoping/IScopeProvider.cs b/src/Umbraco.Core/Scoping/IScopeProvider.cs
index 112a467cc3..e6237b3af9 100644
--- a/src/Umbraco.Core/Scoping/IScopeProvider.cs
+++ b/src/Umbraco.Core/Scoping/IScopeProvider.cs
@@ -1,10 +1,47 @@
namespace Umbraco.Core.Scoping
{
+ ///
+ /// Provides scopes.
+ ///
public interface IScopeProvider
{
+ ///
+ /// Creates an ambient scope.
+ ///
+ /// The created ambient scope.
+ ///
+ /// The created scope becomes the ambient scope.
+ /// If an ambient scope already exists, it becomes the parent of the created scope.
+ /// When the created scope is disposed, the parent scope becomes the ambient scope again.
+ ///
IScope CreateScope();
+
+ ///
+ /// Creates a detached scope.
+ ///
+ /// A detached scope.
+ ///
+ /// A detached scope is not ambient and has no parent.
+ /// It is meant to be attached by .
+ ///
IScope CreateDetachedScope();
+
+ ///
+ /// Attaches a scope.
+ ///
+ /// The scope to attach.
+ ///
+ /// Only a scope created by can be attached.
+ ///
void AttachScope(IScope scope);
+
+ ///
+ /// Detaches a scope.
+ ///
+ /// The detached scope.
+ ///
+ /// Only a scope previously attached by can be detached.
+ ///
IScope DetachScope();
}
}
diff --git a/src/Umbraco.Core/Scoping/IScopeProviderInternal.cs b/src/Umbraco.Core/Scoping/IScopeProviderInternal.cs
index 8726efbfb6..856d30a4da 100644
--- a/src/Umbraco.Core/Scoping/IScopeProviderInternal.cs
+++ b/src/Umbraco.Core/Scoping/IScopeProviderInternal.cs
@@ -1,8 +1,28 @@
namespace Umbraco.Core.Scoping
{
+ ///
+ /// Provices scopes.
+ ///
+ /// Extends with internal features.
internal interface IScopeProviderInternal : IScopeProvider
{
- IScope AmbientScope { get; set; }
- IScope CreateNoScope();
+ ///
+ /// Gets the ambient scope.
+ ///
+ IScope AmbientScope { get; }
+
+ // fixme
+ IScope AmbientOrNoScope { get; }
+
+ ///
+ /// Creates a instance.
+ ///
+ /// The created ambient scope.
+ ///
+ /// The created scope becomes the ambient scope.
+ /// If an ambient scope already exists, throws.
+ /// The instance can be eventually replaced by a real instance.
+ ///
+ //IScope CreateNoScope();
}
}
diff --git a/src/Umbraco.Core/Scoping/NoScope.cs b/src/Umbraco.Core/Scoping/NoScope.cs
index d72d201060..5f67c28d94 100644
--- a/src/Umbraco.Core/Scoping/NoScope.cs
+++ b/src/Umbraco.Core/Scoping/NoScope.cs
@@ -8,6 +8,7 @@ namespace Umbraco.Core.Scoping
internal class NoScope : IScope
{
private readonly ScopeProvider _scopeProvider;
+ private bool _disposed;
private UmbracoDatabase _database;
private IList _messages;
@@ -17,18 +18,44 @@ namespace Umbraco.Core.Scoping
_scopeProvider = scopeProvider;
}
- public bool HasDatabase { get { return _database != null; } }
+ //public bool HasDatabase { get { return _database != null; } }
public UmbracoDatabase Database
{
- get { return _database ?? (_database = _scopeProvider.DatabaseFactory.CreateNewDatabase()); }
+ get
+ {
+ EnsureNotDisposed();
+ return _database ?? (_database = _scopeProvider.DatabaseFactory.CreateNewDatabase());
+ }
}
- public bool HasMessages { get { return _messages != null; } }
+ public UmbracoDatabase DatabaseOrNull
+ {
+ get
+ {
+ EnsureNotDisposed();
+ return _database;
+ }
+ }
+
+ //public bool HasMessages { get { return _messages != null; } }
public IList Messages
{
- get { return _messages ?? (_messages = new List()); }
+ get
+ {
+ EnsureNotDisposed();
+ return _messages ?? (_messages = new List());
+ }
+ }
+
+ public IList MessagesOrNull
+ {
+ get
+ {
+ EnsureNotDisposed();
+ return _messages;
+ }
}
public void Complete()
@@ -36,9 +63,17 @@ namespace Umbraco.Core.Scoping
throw new NotImplementedException();
}
+ private void EnsureNotDisposed()
+ {
+ if (_disposed)
+ throw new ObjectDisposedException("this");
+ }
+
public void Dispose()
{
+ EnsureNotDisposed();
_scopeProvider.Disposing(this);
+ _disposed = true;
GC.SuppressFinalize(this);
}
}
diff --git a/src/Umbraco.Core/Scoping/Scope.cs b/src/Umbraco.Core/Scoping/Scope.cs
index 327adec8ca..8956688faa 100644
--- a/src/Umbraco.Core/Scoping/Scope.cs
+++ b/src/Umbraco.Core/Scoping/Scope.cs
@@ -5,77 +5,100 @@ using Umbraco.Core.Persistence;
namespace Umbraco.Core.Scoping
{
+ // note - scope is not thread-safe obviously
+
internal class Scope : IScope
{
private readonly ScopeProvider _scopeProvider;
+ private bool _disposed;
private bool? _completed;
private UmbracoDatabase _database;
private IList _messages;
+ // initializes a new scope
public Scope(ScopeProvider scopeProvider, bool detachable = false)
{
_scopeProvider = scopeProvider;
Detachable = detachable;
}
+ // initializes a new scope in a nested scopes chain, with its parent
public Scope(ScopeProvider scopeProvider, Scope parent)
: this(scopeProvider)
{
ParentScope = parent;
}
+ // initializes a new scope, replacing a NoScope instance
public Scope(ScopeProvider scopeProvider, NoScope noScope)
: this(scopeProvider)
{
- // stealing everything from NoScope
- _database = noScope.HasDatabase ? noScope.Database : null;
- _messages = noScope.HasMessages ? noScope.Messages : null;
- if (_database != null)
- {
- // must not be in a transaction
- if (_database.Connection != null)
- throw new Exception();
- }
+ // steal everything from NoScope
+ _database = noScope.DatabaseOrNull;
+ _messages = noScope.MessagesOrNull;
+
+ // make sure the NoScope can be replaced ie not in a transaction
+ if (_database != null && _database.InTransaction)
+ throw new Exception("NoScope instance is not free.");
}
+ // a value indicating whether the scope is detachable
+ // ie whether it was created by CreateDetachedScope
public bool Detachable { get; private set; }
+ // the parent scope (in a nested scopes chain)
public Scope ParentScope { get; set; }
+ // the original scope (when attaching a detachable scope)
public Scope OrigScope { get; set; }
- public bool HasDatabase
- {
- get { return ParentScope == null ? _database != null : ParentScope.HasDatabase; }
- }
+ //public bool HasDatabase
+ //{
+ // get { return ParentScope == null ? _database != null : ParentScope.HasDatabase; }
+ //}
+ ///
public UmbracoDatabase Database
{
get
{
+ EnsureNotDisposed();
if (ParentScope != null) return ParentScope.Database;
if (_database != null)
{
- if (_database.Connection == null) // stolen from noScope
+ if (_database.InTransaction == false) // stolen from noScope
_database.BeginTransaction(); // a scope implies a transaction, always
+ // fixme - what-if exception?
return _database;
}
- _database = _scopeProvider.DatabaseFactory.CreateNewDatabase();
- _database.BeginTransaction(); // a scope implies a transaction, always
- return _database;
+ var database = _scopeProvider.DatabaseFactory.CreateNewDatabase();
+ database.BeginTransaction(); // a scope implies a transaction, always
+ // fixme - should dispose db on exception?
+ return _database = database;
}
}
- public bool HasMessages
+ public UmbracoDatabase DatabaseOrNull
{
- get { return ParentScope == null ? _messages != null : ParentScope.HasMessages; }
+ get
+ {
+ EnsureNotDisposed();
+ return ParentScope == null ? _database : ParentScope.DatabaseOrNull;
+ }
}
+ //public bool HasMessages
+ //{
+ // get { return ParentScope == null ? _messages != null : ParentScope.HasMessages; }
+ //}
+
+ ///
public IList Messages
{
get
{
+ EnsureNotDisposed();
if (ParentScope != null) return ParentScope.Messages;
if (_messages == null)
_messages = new List();
@@ -83,6 +106,16 @@ namespace Umbraco.Core.Scoping
}
}
+ public IList MessagesOrNull
+ {
+ get
+ {
+ EnsureNotDisposed();
+ return ParentScope == null ? _messages : ParentScope.MessagesOrNull;
+ }
+ }
+
+ ///
public void Complete()
{
if (_completed.HasValue == false)
@@ -111,9 +144,17 @@ namespace Umbraco.Core.Scoping
}
}
+ private void EnsureNotDisposed()
+ {
+ if (_disposed)
+ throw new ObjectDisposedException("this");
+ }
+
public void Dispose()
{
+ EnsureNotDisposed();
_scopeProvider.Disposing(this, _completed);
+ _disposed = true;
GC.SuppressFinalize(this);
}
}
diff --git a/src/Umbraco.Core/Scoping/ScopeProvider.cs b/src/Umbraco.Core/Scoping/ScopeProvider.cs
index f3b139827c..c2b918f812 100644
--- a/src/Umbraco.Core/Scoping/ScopeProvider.cs
+++ b/src/Umbraco.Core/Scoping/ScopeProvider.cs
@@ -66,31 +66,29 @@ namespace Umbraco.Core.Scoping
}
}
+ ///
public IScope AmbientScope
{
get { return StaticAmbientScope; }
set { StaticAmbientScope = value; }
}
- // fixme should we do...
- // using (var s = scopeProvider.AttachScope(other))
- // {
- // }
- // can't because disposing => detach or commit? cannot tell!
- // var scope = scopeProvider.CreateScope();
- // scope = scopeProvider.Detach();
- // scope.Detach();
- // scopeProvider.Attach(scope);
- // ... do things ...
- // scopeProvider.Detach();
- // scopeProvider.Attach(scope);
- // scope.Dispose();
+ ///
+ public IScope AmbientOrNoScope
+ {
+ get
+ {
+ return AmbientScope ?? (AmbientScope = new NoScope(this));
+ }
+ }
+ ///
public IScope CreateDetachedScope()
{
return new Scope(this, true);
}
+ ///
public void AttachScope(IScope other)
{
var otherScope = other as Scope;
@@ -119,6 +117,7 @@ namespace Umbraco.Core.Scoping
AmbientScope = otherScope;
}
+ ///
public IScope DetachScope()
{
var ambient = AmbientScope;
@@ -141,17 +140,20 @@ namespace Umbraco.Core.Scoping
return scope;
}
+ ///
public IScope CreateScope()
{
var ambient = AmbientScope;
if (ambient == null)
return AmbientScope = new Scope(this);
+ // replace noScope with a real one
var noScope = ambient as NoScope;
if (noScope != null)
{
// peta poco nulls the shared connection after each command unless there's a trx
- if (noScope.HasDatabase && noScope.Database.Connection != null)
+ var database = noScope.DatabaseOrNull;
+ if (database != null && database.InTransaction)
throw new Exception();
return AmbientScope = new Scope(this, noScope);
}
@@ -162,13 +164,6 @@ namespace Umbraco.Core.Scoping
return AmbientScope = new Scope(this, scope);
}
- public IScope CreateNoScope()
- {
- var ambient = AmbientScope;
- if (ambient != null) throw new Exception();
- return AmbientScope = new NoScope(this);
- }
-
public void Disposing(IScope disposing, bool? completed = null)
{
if (disposing != AmbientScope)
@@ -178,7 +173,13 @@ namespace Umbraco.Core.Scoping
if (noScope != null)
{
// fixme - kinda legacy
- if (noScope.HasDatabase) noScope.Database.Dispose();
+ var noScopeDatabase = noScope.DatabaseOrNull;
+ if (noScopeDatabase != null)
+ {
+ if (noScopeDatabase.InTransaction)
+ throw new Exception();
+ noScopeDatabase.Dispose();
+ }
AmbientScope = null;
return;
}
@@ -198,27 +199,19 @@ namespace Umbraco.Core.Scoping
// fixme - a scope is in a transaction only if ... there is a db transaction, or always?
// what shall we do with events if not in a transaction?
+ // fixme - when completing... the db should be released, no need to dispose the db?
// note - messages
// at the moment we are totally not filtering the messages based on completion
// status, so whether the scope is committed or rolled back makes no difference
+ var database = scope.DatabaseOrNull;
+ if (database == null) return;
+
if (completed.HasValue && completed.Value)
- {
- var database = scope.HasDatabase ? scope.Database : null;
- if (database != null)
- {
- database.CompleteTransaction();
- }
- }
+ database.CompleteTransaction();
else
- {
- var database = scope.HasDatabase ? scope.Database : null;
- if (database != null)
- {
- database.AbortTransaction();
- }
- }
+ database.AbortTransaction();
}
}
}
diff --git a/src/Umbraco.Tests/ApplicationContextTests.cs b/src/Umbraco.Tests/ApplicationContextTests.cs
index 61dabf6e3b..255093f325 100644
--- a/src/Umbraco.Tests/ApplicationContextTests.cs
+++ b/src/Umbraco.Tests/ApplicationContextTests.cs
@@ -10,6 +10,7 @@ using Umbraco.Core.Models;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Profiling;
+using Umbraco.Core.Scoping;
using Umbraco.Core.Services;
namespace Umbraco.Tests
@@ -26,7 +27,7 @@ namespace Umbraco.Tests
migrationEntryService.Setup(x => x.FindEntry(It.IsAny(), It.IsAny()))
.Returns(Mock.Of());
- var dbCtx = new Mock(Mock.Of(), Mock.Of(), new SqlCeSyntaxProvider(), "test");
+ var dbCtx = new Mock(Mock.Of(), Mock.Of(), new SqlCeSyntaxProvider(), "test");
dbCtx.Setup(x => x.IsDatabaseConfigured).Returns(true);
dbCtx.Setup(x => x.CanConnect).Returns(true);
@@ -48,7 +49,7 @@ namespace Umbraco.Tests
migrationEntryService.Setup(x => x.FindEntry(It.IsAny(), It.IsAny()))
.Returns((IMigrationEntry)null);
- var dbCtx = new Mock(Mock.Of(), Mock.Of(), new SqlCeSyntaxProvider(), "test");
+ var dbCtx = new Mock(Mock.Of(), Mock.Of(), new SqlCeSyntaxProvider(), "test");
dbCtx.Setup(x => x.IsDatabaseConfigured).Returns(true);
dbCtx.Setup(x => x.CanConnect).Returns(true);
@@ -68,7 +69,7 @@ namespace Umbraco.Tests
var migrationEntryService = new Mock();
- var dbCtx = new Mock(Mock.Of(), Mock.Of(), new SqlCeSyntaxProvider(), "test");
+ var dbCtx = new Mock(Mock.Of(), Mock.Of(), new SqlCeSyntaxProvider(), "test");
dbCtx.Setup(x => x.IsDatabaseConfigured).Returns(true);
dbCtx.Setup(x => x.CanConnect).Returns(true);
@@ -88,7 +89,7 @@ namespace Umbraco.Tests
var migrationEntryService = new Mock();
- var dbCtx = new Mock(Mock.Of(), Mock.Of(), new SqlCeSyntaxProvider(), "test");
+ var dbCtx = new Mock(Mock.Of(), Mock.Of(), new SqlCeSyntaxProvider(), "test");
dbCtx.Setup(x => x.IsDatabaseConfigured).Returns(false);
dbCtx.Setup(x => x.CanConnect).Returns(true);
@@ -108,7 +109,7 @@ namespace Umbraco.Tests
var migrationEntryService = new Mock();
- var dbCtx = new Mock(Mock.Of(), Mock.Of(), new SqlCeSyntaxProvider(), "test");
+ var dbCtx = new Mock(Mock.Of(), Mock.Of(), new SqlCeSyntaxProvider(), "test");
dbCtx.Setup(x => x.IsDatabaseConfigured).Returns(true);
dbCtx.Setup(x => x.CanConnect).Returns(false);
diff --git a/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs b/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs
index 32bbd34a77..f3af12279c 100644
--- a/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs
+++ b/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs
@@ -25,7 +25,7 @@ namespace Umbraco.Tests.Cache.PublishedCache
PublishedContentModelFactoryResolver.Current = new PublishedContentModelFactoryResolver();
base.FreezeResolution();
}
-
+
[Test]
public void Get_Root_Docs()
{
@@ -35,7 +35,7 @@ namespace Umbraco.Tests.Cache.PublishedCache
var mRoot2 = global::umbraco.cms.businesslogic.media.Media.MakeNew("MediaRoot2", mType, user, -1);
var mChild1 = global::umbraco.cms.businesslogic.media.Media.MakeNew("Child1", mType, user, mRoot1.Id);
var mChild2 = global::umbraco.cms.businesslogic.media.Media.MakeNew("Child2", mType, user, mRoot2.Id);
-
+
var ctx = GetUmbracoContext("/test", 1234);
var cache = new ContextualPublishedMediaCache(new PublishedMediaCache(ctx.Application), ctx);
var roots = cache.GetAtRoot();
@@ -125,7 +125,7 @@ namespace Umbraco.Tests.Cache.PublishedCache
{
child1, child2
});
-
+
Assert.AreEqual(2, dicDoc.Children.Count());
Assert.AreEqual(222333, dicDoc.Children.ElementAt(0).Id);
Assert.AreEqual(444555, dicDoc.Children.ElementAt(1).Id);
@@ -187,7 +187,7 @@ namespace Umbraco.Tests.Cache.PublishedCache
private XmlDocument GetMediaXml()
{
var xml = @"
-
@@ -195,12 +195,12 @@ namespace Umbraco.Tests.Cache.PublishedCache
]>
-
+
-
+
-
+
";
@@ -210,8 +210,8 @@ namespace Umbraco.Tests.Cache.PublishedCache
return xmlDoc;
}
- private Dictionary GetDictionary(
- int id,
+ private Dictionary GetDictionary(
+ int id,
Guid key,
int parentId,
string idKey,
@@ -241,13 +241,13 @@ namespace Umbraco.Tests.Cache.PublishedCache
{"parentID", parentId.ToString()}
};
}
-
+
private PublishedMediaCache.DictionaryPublishedContent GetDictionaryDocument(
string idKey = "id",
string templateKey = "template",
string nodeNameKey = "nodeName",
string nodeTypeAliasKey = "nodeTypeAlias",
- string pathKey = "path",
+ string pathKey = "path",
int idVal = 1234,
Guid keyVal = default(Guid),
int parentIdVal = 321,
@@ -265,12 +265,12 @@ namespace Umbraco.Tests.Cache.PublishedCache
a => null,
//we're not going to test this so ignore
(dd, n) => new List(),
- (dd, a) => dd.Properties.FirstOrDefault(x => x.PropertyTypeAlias.InvariantEquals(a)),
+ (dd, a) => dd.Properties.FirstOrDefault(x => x.PropertyTypeAlias.InvariantEquals(a)),
null,
false),
//callback to get the children
(dd, n) => children,
- (dd, a) => dd.Properties.FirstOrDefault(x => x.PropertyTypeAlias.InvariantEquals(a)),
+ (dd, a) => dd.Properties.FirstOrDefault(x => x.PropertyTypeAlias.InvariantEquals(a)),
null,
false);
return dicDoc;
@@ -300,7 +300,7 @@ namespace Umbraco.Tests.Cache.PublishedCache
if (!updateDateVal.HasValue)
updateDateVal = DateTime.Parse("2012-01-03");
- DoAssert((IPublishedContent)dicDoc, idVal, keyVal, templateIdVal, sortOrderVal, urlNameVal, nodeTypeAliasVal, nodeTypeIdVal, writerNameVal,
+ DoAssert((IPublishedContent)dicDoc, idVal, keyVal, templateIdVal, sortOrderVal, urlNameVal, nodeTypeAliasVal, nodeTypeIdVal, writerNameVal,
creatorNameVal, writerIdVal, creatorIdVal, pathVal, createDateVal, updateDateVal, levelVal);
//now validate the parentId that has been parsed, this doesn't exist on the IPublishedContent
@@ -345,9 +345,9 @@ namespace Umbraco.Tests.Cache.PublishedCache
Assert.AreEqual(createDateVal.Value, doc.CreateDate);
Assert.AreEqual(updateDateVal.Value, doc.UpdateDate);
Assert.AreEqual(levelVal, doc.Level);
-
+
}
-
+
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Tests/Persistence/Repositories/NotificationsRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/NotificationsRepositoryTest.cs
index 54387a03f9..f2aa367ffd 100644
--- a/src/Umbraco.Tests/Persistence/Repositories/NotificationsRepositoryTest.cs
+++ b/src/Umbraco.Tests/Persistence/Repositories/NotificationsRepositoryTest.cs
@@ -22,19 +22,20 @@ namespace Umbraco.Tests.Persistence.Repositories
{
var provider = new PetaPocoUnitOfWorkProvider(Logger);
var unitOfWork = provider.GetUnitOfWork();
- var repo = new NotificationsRepository(unitOfWork);
+ using (var repo = new NotificationsRepository(unitOfWork))
+ {
+ var node = new NodeDto { CreateDate = DateTime.Now, Level = 1, NodeObjectType = Guid.Parse(Constants.ObjectTypes.ContentItem), ParentId = -1, Path = "-1,123", SortOrder = 1, Text = "hello", Trashed = false, UniqueId = Guid.NewGuid(), UserId = 0 };
+ var result = unitOfWork.Database.Insert(node);
+ var entity = Mock.Of(e => e.Id == node.NodeId);
+ var user = Mock.Of(e => e.Id == node.UserId);
- var node = new NodeDto {CreateDate = DateTime.Now, Level = 1, NodeObjectType = Guid.Parse(Constants.ObjectTypes.ContentItem), ParentId = -1, Path = "-1,123", SortOrder = 1, Text = "hello", Trashed = false, UniqueId = Guid.NewGuid(), UserId = 0};
- var result = unitOfWork.Database.Insert(node);
- var entity = Mock.Of(e => e.Id == node.NodeId);
- var user = Mock.Of(e => e.Id == node.UserId);
+ var notification = repo.CreateNotification(user, entity, "A");
- var notification = repo.CreateNotification(user, entity, "A");
-
- Assert.AreEqual("A", notification.Action);
- Assert.AreEqual(node.NodeId, notification.EntityId);
- Assert.AreEqual(node.NodeObjectType, notification.EntityType);
- Assert.AreEqual(node.UserId, notification.UserId);
+ Assert.AreEqual("A", notification.Action);
+ Assert.AreEqual(node.NodeId, notification.EntityId);
+ Assert.AreEqual(node.NodeObjectType, notification.EntityType);
+ Assert.AreEqual(node.UserId, notification.UserId);
+ }
}
[Test]
@@ -42,25 +43,26 @@ namespace Umbraco.Tests.Persistence.Repositories
{
var provider = new PetaPocoUnitOfWorkProvider(Logger);
var unitOfWork = provider.GetUnitOfWork();
- var repo = new NotificationsRepository(unitOfWork);
-
- var userDto = new UserDto { ContentStartId = -1, Email = "test" , Login = "test" , MediaStartId = -1, Password = "test" , Type = 1, UserName = "test" , UserLanguage = "en" };
- unitOfWork.Database.Insert(userDto);
-
- var userNew = Mock.Of(e => e.Id == userDto.Id);
- var userAdmin = Mock.Of(e => e.Id == 0);
-
- for (var i = 0; i < 10; i++)
+ using (var repo = new NotificationsRepository(unitOfWork))
{
- var node = new NodeDto { CreateDate = DateTime.Now, Level = 1, NodeObjectType = Guid.Parse(Constants.ObjectTypes.ContentItem), ParentId = -1, Path = "-1," + i, SortOrder = 1, Text = "hello" + i, Trashed = false, UniqueId = Guid.NewGuid(), UserId = 0 };
- var result = unitOfWork.Database.Insert(node);
- var entity = Mock.Of(e => e.Id == node.NodeId);
- var notification = repo.CreateNotification((i % 2 == 0) ? userAdmin : userNew, entity, i.ToString(CultureInfo.InvariantCulture));
+ var userDto = new UserDto { ContentStartId = -1, Email = "test", Login = "test", MediaStartId = -1, Password = "test", Type = 1, UserName = "test", UserLanguage = "en" };
+ unitOfWork.Database.Insert(userDto);
+
+ var userNew = Mock.Of(e => e.Id == userDto.Id);
+ var userAdmin = Mock.Of(e => e.Id == 0);
+
+ for (var i = 0; i < 10; i++)
+ {
+ var node = new NodeDto { CreateDate = DateTime.Now, Level = 1, NodeObjectType = Guid.Parse(Constants.ObjectTypes.ContentItem), ParentId = -1, Path = "-1," + i, SortOrder = 1, Text = "hello" + i, Trashed = false, UniqueId = Guid.NewGuid(), UserId = 0 };
+ var result = unitOfWork.Database.Insert(node);
+ var entity = Mock.Of(e => e.Id == node.NodeId);
+ var notification = repo.CreateNotification((i % 2 == 0) ? userAdmin : userNew, entity, i.ToString(CultureInfo.InvariantCulture));
+ }
+
+ var notifications = repo.GetUserNotifications(userAdmin);
+
+ Assert.AreEqual(5, notifications.Count());
}
-
- var notifications = repo.GetUserNotifications(userAdmin);
-
- Assert.AreEqual(5, notifications.Count());
}
[Test]
@@ -68,26 +70,27 @@ namespace Umbraco.Tests.Persistence.Repositories
{
var provider = new PetaPocoUnitOfWorkProvider(Logger);
var unitOfWork = provider.GetUnitOfWork();
- var repo = new NotificationsRepository(unitOfWork);
-
- var node1 = new NodeDto { CreateDate = DateTime.Now, Level = 1, NodeObjectType = Guid.Parse(Constants.ObjectTypes.ContentItem), ParentId = -1, Path = "-1,1", SortOrder = 1, Text = "hello1", Trashed = false, UniqueId = Guid.NewGuid(), UserId = 0 };
- unitOfWork.Database.Insert(node1);
- var entity1 = Mock.Of(e => e.Id == node1.NodeId);
- var node2 = new NodeDto { CreateDate = DateTime.Now, Level = 1, NodeObjectType = Guid.Parse(Constants.ObjectTypes.ContentItem), ParentId = -1, Path = "-1,2", SortOrder = 1, Text = "hello2", Trashed = false, UniqueId = Guid.NewGuid(), UserId = 0 };
- unitOfWork.Database.Insert(node2);
- var entity2 = Mock.Of(e => e.Id == node2.NodeId);
-
- for (var i = 0; i < 10; i++)
+ using (var repo = new NotificationsRepository(unitOfWork))
{
- var userDto = new UserDto { ContentStartId = -1, Email = "test" + i, Login = "test" + i, MediaStartId = -1, Password = "test", Type = 1, UserName = "test" + i, UserLanguage = "en" };
- unitOfWork.Database.Insert(userDto);
- var userNew = Mock.Of(e => e.Id == userDto.Id);
- var notification = repo.CreateNotification(userNew, (i % 2 == 0) ? entity1 : entity2, i.ToString(CultureInfo.InvariantCulture));
+ var node1 = new NodeDto { CreateDate = DateTime.Now, Level = 1, NodeObjectType = Guid.Parse(Constants.ObjectTypes.ContentItem), ParentId = -1, Path = "-1,1", SortOrder = 1, Text = "hello1", Trashed = false, UniqueId = Guid.NewGuid(), UserId = 0 };
+ unitOfWork.Database.Insert(node1);
+ var entity1 = Mock.Of(e => e.Id == node1.NodeId);
+ var node2 = new NodeDto { CreateDate = DateTime.Now, Level = 1, NodeObjectType = Guid.Parse(Constants.ObjectTypes.ContentItem), ParentId = -1, Path = "-1,2", SortOrder = 1, Text = "hello2", Trashed = false, UniqueId = Guid.NewGuid(), UserId = 0 };
+ unitOfWork.Database.Insert(node2);
+ var entity2 = Mock.Of(e => e.Id == node2.NodeId);
+
+ for (var i = 0; i < 10; i++)
+ {
+ var userDto = new UserDto { ContentStartId = -1, Email = "test" + i, Login = "test" + i, MediaStartId = -1, Password = "test", Type = 1, UserName = "test" + i, UserLanguage = "en" };
+ unitOfWork.Database.Insert(userDto);
+ var userNew = Mock.Of(e => e.Id == userDto.Id);
+ var notification = repo.CreateNotification(userNew, (i % 2 == 0) ? entity1 : entity2, i.ToString(CultureInfo.InvariantCulture));
+ }
+
+ var notifications = repo.GetEntityNotifications(entity1);
+
+ Assert.AreEqual(5, notifications.Count());
}
-
- var notifications = repo.GetEntityNotifications(entity1);
-
- Assert.AreEqual(5, notifications.Count());
}
[Test]
@@ -95,26 +98,27 @@ namespace Umbraco.Tests.Persistence.Repositories
{
var provider = new PetaPocoUnitOfWorkProvider(Logger);
var unitOfWork = provider.GetUnitOfWork();
- var repo = new NotificationsRepository(unitOfWork);
-
- var node1 = new NodeDto { CreateDate = DateTime.Now, Level = 1, NodeObjectType = Guid.Parse(Constants.ObjectTypes.ContentItem), ParentId = -1, Path = "-1,1", SortOrder = 1, Text = "hello1", Trashed = false, UniqueId = Guid.NewGuid(), UserId = 0 };
- unitOfWork.Database.Insert(node1);
- var entity1 = Mock.Of(e => e.Id == node1.NodeId);
- var node2 = new NodeDto { CreateDate = DateTime.Now, Level = 1, NodeObjectType = Guid.Parse(Constants.ObjectTypes.ContentItem), ParentId = -1, Path = "-1,2", SortOrder = 1, Text = "hello2", Trashed = false, UniqueId = Guid.NewGuid(), UserId = 0 };
- unitOfWork.Database.Insert(node2);
- var entity2 = Mock.Of(e => e.Id == node2.NodeId);
-
- for (var i = 0; i < 10; i++)
+ using (var repo = new NotificationsRepository(unitOfWork))
{
- var userDto = new UserDto { ContentStartId = -1, Email = "test" + i, Login = "test" + i, MediaStartId = -1, Password = "test", Type = 1, UserName = "test" + i, UserLanguage = "en" };
- unitOfWork.Database.Insert(userDto);
- var userNew = Mock.Of(e => e.Id == userDto.Id);
- var notification = repo.CreateNotification(userNew, (i % 2 == 0) ? entity1 : entity2, i.ToString(CultureInfo.InvariantCulture));
+ var node1 = new NodeDto { CreateDate = DateTime.Now, Level = 1, NodeObjectType = Guid.Parse(Constants.ObjectTypes.ContentItem), ParentId = -1, Path = "-1,1", SortOrder = 1, Text = "hello1", Trashed = false, UniqueId = Guid.NewGuid(), UserId = 0 };
+ unitOfWork.Database.Insert(node1);
+ var entity1 = Mock.Of(e => e.Id == node1.NodeId);
+ var node2 = new NodeDto { CreateDate = DateTime.Now, Level = 1, NodeObjectType = Guid.Parse(Constants.ObjectTypes.ContentItem), ParentId = -1, Path = "-1,2", SortOrder = 1, Text = "hello2", Trashed = false, UniqueId = Guid.NewGuid(), UserId = 0 };
+ unitOfWork.Database.Insert(node2);
+ var entity2 = Mock.Of(e => e.Id == node2.NodeId);
+
+ for (var i = 0; i < 10; i++)
+ {
+ var userDto = new UserDto { ContentStartId = -1, Email = "test" + i, Login = "test" + i, MediaStartId = -1, Password = "test", Type = 1, UserName = "test" + i, UserLanguage = "en" };
+ unitOfWork.Database.Insert(userDto);
+ var userNew = Mock.Of(e => e.Id == userDto.Id);
+ var notification = repo.CreateNotification(userNew, (i % 2 == 0) ? entity1 : entity2, i.ToString(CultureInfo.InvariantCulture));
+ }
+
+ var delCount = repo.DeleteNotifications(entity1);
+
+ Assert.AreEqual(5, delCount);
}
-
- var delCount = repo.DeleteNotifications(entity1);
-
- Assert.AreEqual(5, delCount);
}
[Test]
@@ -122,25 +126,26 @@ namespace Umbraco.Tests.Persistence.Repositories
{
var provider = new PetaPocoUnitOfWorkProvider(Logger);
var unitOfWork = provider.GetUnitOfWork();
- var repo = new NotificationsRepository(unitOfWork);
-
- var userDto = new UserDto { ContentStartId = -1, Email = "test", Login = "test", MediaStartId = -1, Password = "test", Type = 1, UserName = "test", UserLanguage = "en" };
- unitOfWork.Database.Insert(userDto);
-
- var userNew = Mock.Of(e => e.Id == userDto.Id);
- var userAdmin = Mock.Of(e => e.Id == 0);
-
- for (var i = 0; i < 10; i++)
+ using (var repo = new NotificationsRepository(unitOfWork))
{
- var node = new NodeDto { CreateDate = DateTime.Now, Level = 1, NodeObjectType = Guid.Parse(Constants.ObjectTypes.ContentItem), ParentId = -1, Path = "-1," + i, SortOrder = 1, Text = "hello" + i, Trashed = false, UniqueId = Guid.NewGuid(), UserId = 0 };
- var result = unitOfWork.Database.Insert(node);
- var entity = Mock.Of(e => e.Id == node.NodeId);
- var notification = repo.CreateNotification((i % 2 == 0) ? userAdmin : userNew, entity, i.ToString(CultureInfo.InvariantCulture));
+ var userDto = new UserDto { ContentStartId = -1, Email = "test", Login = "test", MediaStartId = -1, Password = "test", Type = 1, UserName = "test", UserLanguage = "en" };
+ unitOfWork.Database.Insert(userDto);
+
+ var userNew = Mock.Of(e => e.Id == userDto.Id);
+ var userAdmin = Mock.Of(e => e.Id == 0);
+
+ for (var i = 0; i < 10; i++)
+ {
+ var node = new NodeDto { CreateDate = DateTime.Now, Level = 1, NodeObjectType = Guid.Parse(Constants.ObjectTypes.ContentItem), ParentId = -1, Path = "-1," + i, SortOrder = 1, Text = "hello" + i, Trashed = false, UniqueId = Guid.NewGuid(), UserId = 0 };
+ var result = unitOfWork.Database.Insert(node);
+ var entity = Mock.Of(e => e.Id == node.NodeId);
+ var notification = repo.CreateNotification((i % 2 == 0) ? userAdmin : userNew, entity, i.ToString(CultureInfo.InvariantCulture));
+ }
+
+ var delCount = repo.DeleteNotifications(userAdmin);
+
+ Assert.AreEqual(5, delCount);
}
-
- var delCount = repo.DeleteNotifications(userAdmin);
-
- Assert.AreEqual(5, delCount);
}
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Tests/Scoping/ScopeTests.cs b/src/Umbraco.Tests/Scoping/ScopeTests.cs
new file mode 100644
index 0000000000..d84b4fc554
--- /dev/null
+++ b/src/Umbraco.Tests/Scoping/ScopeTests.cs
@@ -0,0 +1,391 @@
+using System;
+using NUnit.Framework;
+using Umbraco.Core.Persistence;
+using Umbraco.Core.Scoping;
+using Umbraco.Tests.TestHelpers;
+
+namespace Umbraco.Tests.Scoping
+{
+ [TestFixture]
+ [DatabaseTestBehavior(DatabaseBehavior.EmptyDbFilePerTest)]
+ public class ScopeTests : BaseDatabaseFactoryTest
+ {
+ // setup
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ // initialization leaves a NoScope around, remove it
+ var scope = DatabaseContext.ScopeProvider.AmbientScope;
+ Assert.IsNotNull(scope);
+ Assert.IsInstanceOf(scope);
+ scope.Dispose();
+ Assert.IsNull(DatabaseContext.ScopeProvider.AmbientScope); // gone
+ }
+
+ [Test]
+ public void SimpleCreateScope()
+ {
+ var scopeProvider = DatabaseContext.ScopeProvider;
+
+ Assert.IsNull(scopeProvider.AmbientScope);
+ using (var scope = scopeProvider.CreateScope())
+ {
+ Assert.IsInstanceOf(scope);
+ Assert.IsNotNull(scopeProvider.AmbientScope);
+ Assert.AreSame(scope, scopeProvider.AmbientScope);
+ }
+ Assert.IsNull(scopeProvider.AmbientScope);
+ }
+
+ [Test]
+ public void SimpleCreateScopeDatabase()
+ {
+ var scopeProvider = DatabaseContext.ScopeProvider;
+
+ UmbracoDatabase database;
+
+ Assert.IsNull(scopeProvider.AmbientScope);
+ using (var scope = scopeProvider.CreateScope())
+ {
+ Assert.IsInstanceOf(scope);
+ Assert.IsNotNull(scopeProvider.AmbientScope);
+ Assert.AreSame(scope, scopeProvider.AmbientScope);
+ database = scope.Database; // populates scope's database
+ Assert.IsNotNull(database);
+ Assert.IsNotNull(database.Connection); // in a transaction
+ }
+ Assert.IsNull(scopeProvider.AmbientScope);
+ Assert.IsNull(database.Connection); // poof gone
+ }
+
+ [Test]
+ public void NestedCreateScope()
+ {
+ var scopeProvider = DatabaseContext.ScopeProvider;
+
+ Assert.IsNull(scopeProvider.AmbientScope);
+ using (var scope = scopeProvider.CreateScope())
+ {
+ Assert.IsInstanceOf(scope);
+ Assert.IsNotNull(scopeProvider.AmbientScope);
+ Assert.AreSame(scope, scopeProvider.AmbientScope);
+ using (var nested = scopeProvider.CreateScope())
+ {
+ Assert.IsInstanceOf(nested);
+ Assert.IsNotNull(scopeProvider.AmbientScope);
+ Assert.AreSame(nested, scopeProvider.AmbientScope);
+ Assert.AreSame(scope, ((Scope) nested).ParentScope);
+ }
+ }
+ Assert.IsNull(scopeProvider.AmbientScope);
+ }
+
+ [Test]
+ public void NestedCreateScopeDatabase()
+ {
+ var scopeProvider = DatabaseContext.ScopeProvider;
+
+ UmbracoDatabase database;
+
+ Assert.IsNull(scopeProvider.AmbientScope);
+ using (var scope = scopeProvider.CreateScope())
+ {
+ Assert.IsInstanceOf(scope);
+ Assert.IsNotNull(scopeProvider.AmbientScope);
+ Assert.AreSame(scope, scopeProvider.AmbientScope);
+ database = scope.Database; // populates scope's database
+ Assert.IsNotNull(database);
+ Assert.IsNotNull(database.Connection); // in a transaction
+ using (var nested = scopeProvider.CreateScope())
+ {
+ Assert.IsInstanceOf(nested);
+ Assert.IsNotNull(scopeProvider.AmbientScope);
+ Assert.AreSame(nested, scopeProvider.AmbientScope);
+ Assert.AreSame(scope, ((Scope)nested).ParentScope);
+ Assert.AreSame(database, nested.Database);
+ }
+ Assert.IsNotNull(database.Connection); // still
+ }
+ Assert.IsNull(scopeProvider.AmbientScope);
+ Assert.IsNull(database.Connection); // poof gone
+ }
+
+ [Test]
+ public void SimpleNoScope()
+ {
+ var scopeProvider = DatabaseContext.ScopeProvider;
+
+ Assert.IsNull(scopeProvider.AmbientScope);
+ using (var scope = scopeProvider.AmbientOrNoScope)
+ {
+ Assert.IsInstanceOf(scope);
+ Assert.IsNotNull(scopeProvider.AmbientScope);
+ Assert.AreSame(scope, scopeProvider.AmbientScope);
+ }
+ Assert.IsNull(scopeProvider.AmbientScope);
+ }
+
+ [Test]
+ public void SimpleNoScopeDatabase()
+ {
+ var scopeProvider = DatabaseContext.ScopeProvider;
+
+ UmbracoDatabase database;
+
+ Assert.IsNull(scopeProvider.AmbientScope);
+ using (var scope = scopeProvider.AmbientOrNoScope)
+ {
+ Assert.IsInstanceOf(scope);
+ Assert.IsNotNull(scopeProvider.AmbientScope);
+ Assert.AreSame(scope, scopeProvider.AmbientScope);
+ database = scope.Database; // populates scope's database
+ Assert.IsNotNull(database);
+ Assert.IsNull(database.Connection); // no transaction
+ }
+ Assert.IsNull(scopeProvider.AmbientScope);
+ Assert.IsNull(database.Connection); // still
+ }
+
+ [Test]
+ public void NestedNoScope()
+ {
+ var scopeProvider = DatabaseContext.ScopeProvider;
+
+ Assert.IsNull(scopeProvider.AmbientScope);
+ var scope = scopeProvider.AmbientOrNoScope;
+ Assert.IsInstanceOf(scope);
+ Assert.IsNotNull(scopeProvider.AmbientScope);
+ Assert.AreSame(scope, scopeProvider.AmbientScope);
+
+ using (var nested = scopeProvider.CreateScope())
+ {
+ Assert.IsInstanceOf(nested);
+ Assert.IsNotNull(scopeProvider.AmbientScope);
+ Assert.AreSame(nested, scopeProvider.AmbientScope);
+
+ // nested does not have a parent
+ Assert.IsNull(((Scope) nested).ParentScope);
+ }
+
+ // and when nested is gone, scope is gone
+ Assert.IsNull(scopeProvider.AmbientScope);
+ }
+
+ [Test]
+ public void NestedNoScopeDatabase()
+ {
+ var scopeProvider = DatabaseContext.ScopeProvider;
+
+ Assert.IsNull(scopeProvider.AmbientScope);
+ var scope = scopeProvider.AmbientOrNoScope;
+ Assert.IsInstanceOf(scope);
+ Assert.IsNotNull(scopeProvider.AmbientScope);
+ Assert.AreSame(scope, scopeProvider.AmbientScope);
+ var database = scope.Database;
+ Assert.IsNotNull(database);
+ Assert.IsNull(database.Connection); // no transaction
+
+ using (var nested = scopeProvider.CreateScope())
+ {
+ Assert.IsInstanceOf(nested);
+ Assert.IsNotNull(scopeProvider.AmbientScope);
+ Assert.AreSame(nested, scopeProvider.AmbientScope);
+ var nestedDatabase = nested.Database; // causes transaction
+ Assert.AreSame(database, nestedDatabase); // stolen
+ Assert.IsNotNull(database.Connection); // no more
+
+ // nested does not have a parent
+ Assert.IsNull(((Scope)nested).ParentScope);
+ }
+
+ // and when nested is gone, scope is gone
+ Assert.IsNull(scopeProvider.AmbientScope);
+ Assert.IsNull(database.Connection); // poof gone
+ }
+
+ [Test]
+ public void NestedNoScopeFail()
+ {
+ var scopeProvider = DatabaseContext.ScopeProvider;
+
+ Assert.IsNull(scopeProvider.AmbientScope);
+ var scope = scopeProvider.AmbientOrNoScope;
+ Assert.IsInstanceOf(scope);
+ Assert.IsNotNull(scopeProvider.AmbientScope);
+ Assert.AreSame(scope, scopeProvider.AmbientScope);
+ var database = scope.Database;
+ Assert.IsNotNull(database);
+ Assert.IsNull(database.Connection); // no transaction
+ database.BeginTransaction();
+ Assert.IsNotNull(database.Connection); // now there is one
+
+ Assert.Throws(() =>
+ {
+ // could not steal the database
+ /*var nested =*/ scopeProvider.CreateScope();
+ });
+
+ // cleanup
+ database.CompleteTransaction();
+ }
+
+ [Test]
+ public void NoScopeNested()
+ {
+ var scopeProvider = DatabaseContext.ScopeProvider;
+
+ Assert.IsNull(scopeProvider.AmbientScope);
+ using (var scope = scopeProvider.CreateScope())
+ {
+ Assert.IsInstanceOf(scope);
+ Assert.IsNotNull(scopeProvider.AmbientScope);
+ Assert.AreSame(scope, scopeProvider.AmbientScope);
+
+ // AmbientOrNoScope returns the ambient scope
+ Assert.AreSame(scope, scopeProvider.AmbientOrNoScope);
+ }
+ }
+
+ [Test]
+ public void Transaction()
+ {
+ var scopeProvider = DatabaseContext.ScopeProvider;
+ var noScope = scopeProvider.AmbientOrNoScope;
+ var database = noScope.Database;
+ database.Execute("CREATE TABLE tmp (id INT, name NVARCHAR(64))");
+
+ using (var scope = scopeProvider.CreateScope())
+ {
+ scope.Database.Execute("INSERT INTO tmp (id, name) VALUES (1, 'a')");
+ var n = scope.Database.ExecuteScalar("SELECT name FROM tmp WHERE id=1");
+ Assert.AreEqual("a", n);
+ }
+
+ using (var scope = scopeProvider.CreateScope())
+ {
+ var n = scope.Database.ExecuteScalar("SELECT name FROM tmp WHERE id=1");
+ Assert.IsNull(n);
+ }
+
+ using (var scope = scopeProvider.CreateScope())
+ {
+ scope.Database.Execute("INSERT INTO tmp (id, name) VALUES (1, 'a')");
+ scope.Complete();
+ }
+
+ using (var scope = scopeProvider.CreateScope())
+ {
+ var n = scope.Database.ExecuteScalar("SELECT name FROM tmp WHERE id=1");
+ Assert.AreEqual("a", n);
+ }
+ }
+
+ [Test]
+ public void NestedTransactionInnerFail()
+ {
+ var scopeProvider = DatabaseContext.ScopeProvider;
+ var noScope = scopeProvider.AmbientOrNoScope;
+ var database = noScope.Database;
+ database.Execute("CREATE TABLE tmp (id INT, name NVARCHAR(64))");
+
+ using (var scope = scopeProvider.CreateScope())
+ {
+ scope.Database.Execute("INSERT INTO tmp (id, name) VALUES (1, 'a')");
+ var n = scope.Database.ExecuteScalar("SELECT name FROM tmp WHERE id=1");
+ Assert.AreEqual("a", n);
+
+ using (var nested = scopeProvider.CreateScope())
+ {
+ nested.Database.Execute("INSERT INTO tmp (id, name) VALUES (2, 'b')");
+ var nn = scope.Database.ExecuteScalar("SELECT name FROM tmp WHERE id=2");
+ Assert.AreEqual("b", nn);
+ }
+
+ n = scope.Database.ExecuteScalar("SELECT name FROM tmp WHERE id=2");
+ Assert.AreEqual("b", n);
+
+ scope.Complete();
+ }
+
+ using (var scope = scopeProvider.CreateScope())
+ {
+ var n = scope.Database.ExecuteScalar("SELECT name FROM tmp WHERE id=1");
+ Assert.IsNull(n);
+ n = scope.Database.ExecuteScalar("SELECT name FROM tmp WHERE id=2");
+ Assert.IsNull(n);
+ }
+ }
+
+ [Test]
+ public void NestedTransactionOuterFail()
+ {
+ var scopeProvider = DatabaseContext.ScopeProvider;
+ var noScope = scopeProvider.AmbientOrNoScope;
+ var database = noScope.Database;
+ database.Execute("CREATE TABLE tmp (id INT, name NVARCHAR(64))");
+
+ using (var scope = scopeProvider.CreateScope())
+ {
+ scope.Database.Execute("INSERT INTO tmp (id, name) VALUES (1, 'a')");
+ var n = scope.Database.ExecuteScalar("SELECT name FROM tmp WHERE id=1");
+ Assert.AreEqual("a", n);
+
+ using (var nested = scopeProvider.CreateScope())
+ {
+ nested.Database.Execute("INSERT INTO tmp (id, name) VALUES (2, 'b')");
+ var nn = scope.Database.ExecuteScalar("SELECT name FROM tmp WHERE id=2");
+ Assert.AreEqual("b", nn);
+ nested.Complete();
+ }
+
+ n = scope.Database.ExecuteScalar("SELECT name FROM tmp WHERE id=2");
+ Assert.AreEqual("b", n);
+ }
+
+ using (var scope = scopeProvider.CreateScope())
+ {
+ var n = scope.Database.ExecuteScalar("SELECT name FROM tmp WHERE id=1");
+ Assert.IsNull(n);
+ n = scope.Database.ExecuteScalar("SELECT name FROM tmp WHERE id=2");
+ Assert.IsNull(n);
+ }
+ }
+
+ [Test]
+ public void NestedTransactionComplete()
+ {
+ var scopeProvider = DatabaseContext.ScopeProvider;
+ var noScope = scopeProvider.AmbientOrNoScope;
+ var database = noScope.Database;
+ database.Execute("CREATE TABLE tmp (id INT, name NVARCHAR(64))");
+
+ using (var scope = scopeProvider.CreateScope())
+ {
+ scope.Database.Execute("INSERT INTO tmp (id, name) VALUES (1, 'a')");
+ var n = scope.Database.ExecuteScalar("SELECT name FROM tmp WHERE id=1");
+ Assert.AreEqual("a", n);
+
+ using (var nested = scopeProvider.CreateScope())
+ {
+ nested.Database.Execute("INSERT INTO tmp (id, name) VALUES (2, 'b')");
+ var nn = scope.Database.ExecuteScalar("SELECT name FROM tmp WHERE id=2");
+ Assert.AreEqual("b", nn);
+ nested.Complete();
+ }
+
+ n = scope.Database.ExecuteScalar("SELECT name FROM tmp WHERE id=2");
+ Assert.AreEqual("b", n);
+ scope.Complete();
+ }
+
+ using (var scope = scopeProvider.CreateScope())
+ {
+ var n = scope.Database.ExecuteScalar("SELECT name FROM tmp WHERE id=1");
+ Assert.AreEqual("a", n);
+ n = scope.Database.ExecuteScalar("SELECT name FROM tmp WHERE id=2");
+ Assert.AreEqual("b", n);
+ }
+ }
+ }
+}
diff --git a/src/Umbraco.Tests/Security/BackOfficeCookieManagerTests.cs b/src/Umbraco.Tests/Security/BackOfficeCookieManagerTests.cs
index 320ab400d3..92250487b1 100644
--- a/src/Umbraco.Tests/Security/BackOfficeCookieManagerTests.cs
+++ b/src/Umbraco.Tests/Security/BackOfficeCookieManagerTests.cs
@@ -11,6 +11,7 @@ using Umbraco.Core.Logging;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Profiling;
+using Umbraco.Core.Scoping;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web;
using Umbraco.Web.Routing;
@@ -28,7 +29,7 @@ namespace Umbraco.Tests.Security
//should force app ctx to show not-configured
ConfigurationManager.AppSettings.Set("umbracoConfigurationStatus", "");
- var dbCtx = new Mock(Mock.Of(), Mock.Of(), Mock.Of(), "test");
+ var dbCtx = new Mock(Mock.Of(), Mock.Of(), Mock.Of(), "test");
dbCtx.Setup(x => x.IsDatabaseConfigured).Returns(false);
var appCtx = new ApplicationContext(
@@ -53,7 +54,7 @@ namespace Umbraco.Tests.Security
[Test]
public void ShouldAuthenticateRequest_When_Configured()
{
- var dbCtx = new Mock(Mock.Of(), Mock.Of(), Mock.Of(), "test");
+ var dbCtx = new Mock(Mock.Of(), Mock.Of(), Mock.Of(), "test");
dbCtx.Setup(x => x.IsDatabaseConfigured).Returns(true);
var appCtx = new ApplicationContext(
diff --git a/src/Umbraco.Tests/Services/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs
index 72a58861e2..46af227ecd 100644
--- a/src/Umbraco.Tests/Services/ContentServiceTests.cs
+++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs
@@ -81,7 +81,7 @@ namespace Umbraco.Tests.Services
Assert.IsTrue(moveResult.Success);
- //re-get with the fixed/moved path
+ //re-get with the fixed/moved path
content = contentService.GetById(content.Id);
Assert.AreEqual("-1,-20," + content.Id, content.Path);
@@ -270,7 +270,7 @@ namespace Umbraco.Tests.Services
content2.SetTags("tags", new[] { "hello", "world", "some", "tags" }, true);
contentService.Publish(content2);
- // Act
+ // Act
contentService.MoveToRecycleBin(content1);
// Assert
@@ -306,7 +306,7 @@ namespace Umbraco.Tests.Services
content2.SetTags("tags", new[] { "hello", "world", "some", "tags" }, true);
contentService.Publish(content2);
- // Act
+ // Act
contentService.MoveToRecycleBin(content1);
contentService.MoveToRecycleBin(content2);
@@ -339,7 +339,7 @@ namespace Umbraco.Tests.Services
content2.SetTags("tags", new[] { "hello", "world", "some", "tags" }, true);
contentService.Publish(content2);
- // Act
+ // Act
contentService.UnPublish(content1);
contentService.UnPublish(content2);
@@ -375,7 +375,7 @@ namespace Umbraco.Tests.Services
contentService.UnPublish(content1);
contentService.UnPublish(content2);
- // Act
+ // Act
contentService.Publish(content1);
// Assert
@@ -411,7 +411,7 @@ namespace Umbraco.Tests.Services
contentService.MoveToRecycleBin(content1);
contentService.MoveToRecycleBin(content2);
- // Act
+ // Act
contentService.Move(content1, -1);
contentService.Publish(content1);
@@ -839,8 +839,10 @@ namespace Umbraco.Tests.Services
bool published = contentService.Publish(content, 0);
var provider = new PetaPocoUnitOfWorkProvider(Logger);
- var uow = provider.GetUnitOfWork();
- Assert.IsTrue(uow.Database.Exists(content.Id));
+ using (var uow = provider.GetUnitOfWork())
+ {
+ Assert.IsTrue(uow.Database.Exists(content.Id));
+ }
// Act
bool unpublished = contentService.UnPublish(content, 0);
@@ -850,8 +852,10 @@ namespace Umbraco.Tests.Services
Assert.That(unpublished, Is.True);
Assert.That(content.Published, Is.False);
- uow = provider.GetUnitOfWork();
- Assert.IsFalse(uow.Database.Exists(content.Id));
+ using (var uow = provider.GetUnitOfWork())
+ {
+ Assert.IsFalse(uow.Database.Exists(content.Id));
+ }
}
///
@@ -947,7 +951,7 @@ namespace Umbraco.Tests.Services
// Act
contentService.RePublishAll(new int[] { allContent.Last().ContentTypeId });
- // Assert
+ // Assert
using (var uow = provider.GetUnitOfWork())
{
Assert.AreEqual(allContent.Count(), uow.Database.ExecuteScalar("select count(*) from cmsContentXml"));
diff --git a/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs b/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs
index 6bd44c2bdd..dc3a0e83b6 100644
--- a/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs
+++ b/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs
@@ -72,6 +72,12 @@ namespace Umbraco.Tests.TestHelpers
GetDbProviderName(),
Logger);
+ // fixme - bah
+ var scopeProvider = new ScopeProvider(null);
+ if (scopeProvider.AmbientScope != null)
+ scopeProvider.AmbientScope.Dispose();
+ scopeProvider.AmbientScope = null;
+
base.Initialize();
using (ProfilingLogger.TraceDuration("init"))
diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj
index 1f5e324142..cd7010310c 100644
--- a/src/Umbraco.Tests/Umbraco.Tests.csproj
+++ b/src/Umbraco.Tests/Umbraco.Tests.csproj
@@ -168,6 +168,7 @@
+
diff --git a/src/umbraco.cms/businesslogic/Content.cs b/src/umbraco.cms/businesslogic/Content.cs
index 4b942d453f..b64e4cf678 100644
--- a/src/umbraco.cms/businesslogic/Content.cs
+++ b/src/umbraco.cms/businesslogic/Content.cs
@@ -149,7 +149,7 @@ namespace umbraco.cms.businesslogic
{
_contentType = new ContentType(contentTypeId);
}
- catch
+ catch (Exception e)
{
return null;
}
diff --git a/src/umbraco.datalayer/SqlHelper.cs b/src/umbraco.datalayer/SqlHelper.cs
index 4420e8bde0..10d1183abb 100644
--- a/src/umbraco.datalayer/SqlHelper.cs
+++ b/src/umbraco.datalayer/SqlHelper.cs
@@ -359,11 +359,12 @@ namespace umbraco.DataLayer
internal class CurrentConnectionUsing : IDisposable
{
- public static MethodInfo OpenMethod { get; private set; }
- public static MethodInfo CloseMethod { get; private set; }
+ private static MethodInfo OpenMethod { get; set; }
+ //private static MethodInfo CloseMethod { get; set; }
- private static readonly object Factory;
- private static readonly MethodInfo CreateMethod;
+ private static readonly object ScopeProvider;
+ private static readonly PropertyInfo ScopeProviderAmbientOrNoScopeProperty;
+ private static readonly PropertyInfo ScopeDatabaseProperty;
private static readonly PropertyInfo ConnectionProperty;
private static readonly FieldInfo TransactionField;
private static readonly PropertyInfo InnerConnectionProperty;
@@ -378,23 +379,30 @@ namespace umbraco.DataLayer
var applicationContextType = coreAssembly.GetType("Umbraco.Core.ApplicationContext");
var databaseContextType = coreAssembly.GetType("Umbraco.Core.DatabaseContext");
- var defaultDatabaseFactoryType = coreAssembly.GetType("Umbraco.Core.Persistence.DefaultDatabaseFactory");
var umbracoDatabaseType = coreAssembly.GetType("Umbraco.Core.Persistence.UmbracoDatabase");
var databaseType = coreAssembly.GetType("Umbraco.Core.Persistence.Database");
+ var scopeProviderType = coreAssembly.GetType("Umbraco.Core.Scoping.IScopeProviderInternal");
+ var scopeType = coreAssembly.GetType("Umbraco.Core.Scoping.IScope");
- var currentProperty = applicationContextType.GetProperty("Current", BindingFlags.Static | BindingFlags.Public);
- var applicationContext = currentProperty.GetValue(null, NoArgs);
+ var applicationContextCurrentProperty = applicationContextType.GetProperty("Current", BindingFlags.Static | BindingFlags.Public);
+ if (applicationContextCurrentProperty == null) throw new Exception("oops: applicationContextCurrentProperty.");
+ var applicationContext = applicationContextCurrentProperty.GetValue(null, NoArgs);
- var databaseContextProperty = applicationContextType.GetProperty("DatabaseContext", BindingFlags.Instance | BindingFlags.Public);
- var databaseContext = databaseContextProperty.GetValue(applicationContext, NoArgs);
+ var applicationContextDatabaseContextProperty = applicationContextType.GetProperty("DatabaseContext", BindingFlags.Instance | BindingFlags.Public);
+ if (applicationContextDatabaseContextProperty == null) throw new Exception("oops: applicationContextDatabaseContextProperty.");
+ var databaseContext = applicationContextDatabaseContextProperty.GetValue(applicationContext, NoArgs);
- var factoryField = databaseContextType.GetField("_factory", BindingFlags.Instance | BindingFlags.NonPublic);
- Factory = factoryField.GetValue(databaseContext);
+ var databaseContextScopeProviderField = databaseContextType.GetField("ScopeProvider", BindingFlags.Instance | BindingFlags.NonPublic);
+ if (databaseContextScopeProviderField == null) throw new Exception("oops: databaseContextScopeProviderField.");
+ ScopeProvider = databaseContextScopeProviderField.GetValue(databaseContext);
- CreateMethod = defaultDatabaseFactoryType.GetMethod("CreateDatabase", BindingFlags.Instance | BindingFlags.Public);
+ ScopeProviderAmbientOrNoScopeProperty = scopeProviderType.GetProperty("AmbientOrNoScope", BindingFlags.Instance | BindingFlags.Public);
+ if (ScopeProviderAmbientOrNoScopeProperty == null) throw new Exception("oops: ScopeProviderAmbientOrNoScopeProperty.");
+ ScopeDatabaseProperty = scopeType.GetProperty("Database", BindingFlags.Instance | BindingFlags.Public);
+ if (ScopeDatabaseProperty == null) throw new Exception("oops: ScopeDatabaseProperty.");
OpenMethod = databaseType.GetMethod("OpenSharedConnection", BindingFlags.Instance | BindingFlags.Public);
- CloseMethod = databaseType.GetMethod("CloseSharedConnection", BindingFlags.Instance | BindingFlags.Public);
+ //CloseMethod = databaseType.GetMethod("CloseSharedConnection", BindingFlags.Instance | BindingFlags.Public);
ConnectionProperty = umbracoDatabaseType.GetProperty("Connection", BindingFlags.Instance | BindingFlags.Public);
TransactionField = databaseType.GetField("_transaction", BindingFlags.Instance | BindingFlags.NonPublic);
@@ -408,7 +416,8 @@ namespace umbraco.DataLayer
public CurrentConnectionUsing()
{
- _database = CreateMethod.Invoke(Factory, NoArgs);
+ var scope = ScopeProviderAmbientOrNoScopeProperty.GetValue(ScopeProvider);
+ _database = ScopeDatabaseProperty.GetValue(scope);
var connection = ConnectionProperty.GetValue(_database, NoArgs);
// we have to open to make sure that we *do* have a connection
diff --git a/src/umbraco.datalayer/SqlHelpers/MySql/MySqlHelper.cs b/src/umbraco.datalayer/SqlHelpers/MySql/MySqlHelper.cs
index 2e76941c21..c1a530f8f4 100644
--- a/src/umbraco.datalayer/SqlHelpers/MySql/MySqlHelper.cs
+++ b/src/umbraco.datalayer/SqlHelpers/MySql/MySqlHelper.cs
@@ -122,12 +122,12 @@ namespace umbraco.DataLayer.SqlHelpers.MySql
{
using (var cc = UseCurrentConnection)
{
- return new MySqlDataReader(ExecuteReader((MSC.MySqlConnection) cc.Connection, (MSC.MySqlTransaction) cc.Transaction, commandText, parameters, true));
+ return new MySqlDataReader(ExecuteReader((MSC.MySqlConnection) cc.Connection, (MSC.MySqlTransaction) cc.Transaction, commandText, parameters));
}
}
// copied & adapted from MySqlHelper
- private static MSC.MySqlDataReader ExecuteReader(MSC.MySqlConnection connection, MSC.MySqlTransaction trx, string commandText, MSC.MySqlParameter[] commandParameters, bool externalConn)
+ private static MSC.MySqlDataReader ExecuteReader(MSC.MySqlConnection connection, MSC.MySqlTransaction trx, string commandText, MSC.MySqlParameter[] commandParameters)
{
MSC.MySqlCommand mySqlCommand = new MSC.MySqlCommand();
mySqlCommand.Connection = connection;
@@ -139,7 +139,7 @@ namespace umbraco.DataLayer.SqlHelpers.MySql
foreach (var commandParameter in commandParameters)
mySqlCommand.Parameters.Add(commandParameter);
}
- MSC.MySqlDataReader mySqlDataReader = !externalConn ? mySqlCommand.ExecuteReader(CommandBehavior.CloseConnection) : mySqlCommand.ExecuteReader();
+ MSC.MySqlDataReader mySqlDataReader = mySqlCommand.ExecuteReader();
mySqlCommand.Parameters.Clear();
return mySqlDataReader;
}