UnitOfWork RIP

This commit is contained in:
Stephan
2017-12-12 15:04:13 +01:00
parent 84f9242aa0
commit 6d4644c118
82 changed files with 2751 additions and 3130 deletions

View File

@@ -9,6 +9,7 @@ using Umbraco.Core.Logging;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.UnitOfWork;
using Umbraco.Core.Scoping;
using Umbraco.Core.Serialization;
using Umbraco.Web.Composing;
using static Umbraco.Core.Persistence.NPocoSqlExtensions.Statics;
@@ -22,9 +23,9 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
{
// we want arrays, we want them all loaded, not an enumerable
private Sql<ISqlContext> ContentSourcesSelect(IScopeUnitOfWork uow, Func<Sql<ISqlContext>, Sql<ISqlContext>> joins = null)
private Sql<ISqlContext> ContentSourcesSelect(IScope scope, Func<Sql<ISqlContext>, Sql<ISqlContext>> joins = null)
{
var sql = uow.SqlContext.Sql()
var sql = scope.SqlContext.Sql()
.Select<NodeDto>(x => Alias(x.NodeId, "Id"), x => Alias(x.UniqueId, "Uid"),
x => Alias(x.Level, "Level"), x => Alias(x.Path, "Path"), x => Alias(x.SortOrder, "SortOrder"), x => Alias(x.ParentId, "ParentId"),
@@ -63,29 +64,29 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
return sql;
}
public ContentNodeKit GetContentSource(IScopeUnitOfWork uow, int id)
public ContentNodeKit GetContentSource(IScope scope, int id)
{
var sql = ContentSourcesSelect(uow)
var sql = ContentSourcesSelect(scope)
.Where<NodeDto>(x => x.NodeObjectType == Constants.ObjectTypes.Document && x.NodeId == id)
.OrderBy<NodeDto>(x => x.Level, x => x.SortOrder);
var dto = uow.Database.Fetch<ContentSourceDto>(sql).FirstOrDefault();
var dto = scope.Database.Fetch<ContentSourceDto>(sql).FirstOrDefault();
return dto == null ? new ContentNodeKit() : CreateContentNodeKit(dto);
}
public IEnumerable<ContentNodeKit> GetAllContentSources(IScopeUnitOfWork uow)
public IEnumerable<ContentNodeKit> GetAllContentSources(IScope scope)
{
var sql = ContentSourcesSelect(uow)
var sql = ContentSourcesSelect(scope)
.Where<NodeDto>(x => x.NodeObjectType == Constants.ObjectTypes.Document)
.OrderBy<NodeDto>(x => x.Level, x => x.SortOrder);
return uow.Database.Query<ContentSourceDto>(sql).Select(CreateContentNodeKit);
return scope.Database.Query<ContentSourceDto>(sql).Select(CreateContentNodeKit);
}
public IEnumerable<ContentNodeKit> GetBranchContentSources(IScopeUnitOfWork uow, int id)
public IEnumerable<ContentNodeKit> GetBranchContentSources(IScope scope, int id)
{
var syntax = uow.SqlContext.SqlSyntax;
var sql = ContentSourcesSelect(uow, s => s
var syntax = scope.SqlContext.SqlSyntax;
var sql = ContentSourcesSelect(scope, s => s
.InnerJoin<NodeDto>("x").On<NodeDto, NodeDto>((left, right) => left.NodeId == right.NodeId || SqlText<bool>(left.Path, right.Path, (lp, rp) => $"({lp} LIKE {syntax.GetConcat(rp, "',%'")})"), aliasRight: "x"))
@@ -93,22 +94,22 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
.Where<NodeDto>(x => x.NodeId == id, "x")
.OrderBy<NodeDto>(x => x.Level, x => x.SortOrder);
return uow.Database.Query<ContentSourceDto>(sql).Select(CreateContentNodeKit);
return scope.Database.Query<ContentSourceDto>(sql).Select(CreateContentNodeKit);
}
public IEnumerable<ContentNodeKit> GetTypeContentSources(IScopeUnitOfWork uow, IEnumerable<int> ids)
public IEnumerable<ContentNodeKit> GetTypeContentSources(IScope scope, IEnumerable<int> ids)
{
var sql = ContentSourcesSelect(uow)
var sql = ContentSourcesSelect(scope)
.Where<NodeDto>(x => x.NodeObjectType == Constants.ObjectTypes.Document)
.WhereIn<ContentDto>(x => x.ContentTypeId, ids)
.OrderBy<NodeDto>(x => x.Level, x => x.SortOrder);
return uow.Database.Query<ContentSourceDto>(sql).Select(CreateContentNodeKit);
return scope.Database.Query<ContentSourceDto>(sql).Select(CreateContentNodeKit);
}
private Sql<ISqlContext> MediaSourcesSelect(IScopeUnitOfWork uow, Func<Sql<ISqlContext>, Sql<ISqlContext>> joins = null)
private Sql<ISqlContext> MediaSourcesSelect(IScope scope, Func<Sql<ISqlContext>, Sql<ISqlContext>> joins = null)
{
var sql = uow.SqlContext.Sql()
var sql = scope.SqlContext.Sql()
.Select<NodeDto>(x => Alias(x.NodeId, "Id"), x => Alias(x.UniqueId, "Uid"),
x => Alias(x.Level, "Level"), x => Alias(x.Path, "Path"), x => Alias(x.SortOrder, "SortOrder"), x => Alias(x.ParentId, "ParentId"),
@@ -134,29 +135,29 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
return sql;
}
public ContentNodeKit GetMediaSource(IScopeUnitOfWork uow, int id)
public ContentNodeKit GetMediaSource(IScope scope, int id)
{
var sql = MediaSourcesSelect(uow)
var sql = MediaSourcesSelect(scope)
.Where<NodeDto>(x => x.NodeObjectType == Constants.ObjectTypes.Media && x.NodeId == id)
.OrderBy<NodeDto>(x => x.Level, x => x.SortOrder);
var dto = uow.Database.Fetch<ContentSourceDto>(sql).FirstOrDefault();
var dto = scope.Database.Fetch<ContentSourceDto>(sql).FirstOrDefault();
return dto == null ? new ContentNodeKit() : CreateContentNodeKit(dto);
}
public IEnumerable<ContentNodeKit> GetAllMediaSources(IScopeUnitOfWork uow)
public IEnumerable<ContentNodeKit> GetAllMediaSources(IScope scope)
{
var sql = MediaSourcesSelect(uow)
var sql = MediaSourcesSelect(scope)
.Where<NodeDto>(x => x.NodeObjectType == Constants.ObjectTypes.Media)
.OrderBy<NodeDto>(x => x.Level, x => x.SortOrder);
return uow.Database.Query<ContentSourceDto>(sql).Select(CreateMediaNodeKit);
return scope.Database.Query<ContentSourceDto>(sql).Select(CreateMediaNodeKit);
}
public IEnumerable<ContentNodeKit> GetBranchMediaSources(IScopeUnitOfWork uow, int id)
public IEnumerable<ContentNodeKit> GetBranchMediaSources(IScope scope, int id)
{
var syntax = uow.SqlContext.SqlSyntax;
var sql = MediaSourcesSelect(uow, s => s
var syntax = scope.SqlContext.SqlSyntax;
var sql = MediaSourcesSelect(scope, s => s
.InnerJoin<NodeDto>("x").On<NodeDto, NodeDto>((left, right) => left.NodeId == right.NodeId || SqlText<bool>(left.Path, right.Path, (lp, rp) => $"({lp} LIKE {syntax.GetConcat(rp, "',%'")})"), aliasRight: "x"))
@@ -164,17 +165,17 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
.Where<NodeDto>(x => x.NodeId == id, "x")
.OrderBy<NodeDto>(x => x.Level, x => x.SortOrder);
return uow.Database.Query<ContentSourceDto>(sql).Select(CreateMediaNodeKit);
return scope.Database.Query<ContentSourceDto>(sql).Select(CreateMediaNodeKit);
}
public IEnumerable<ContentNodeKit> GetTypeMediaSources(IScopeUnitOfWork uow, IEnumerable<int> ids)
public IEnumerable<ContentNodeKit> GetTypeMediaSources(IScope scope, IEnumerable<int> ids)
{
var sql = MediaSourcesSelect(uow)
var sql = MediaSourcesSelect(scope)
.Where<NodeDto>(x => x.NodeObjectType == Constants.ObjectTypes.Media)
.WhereIn<ContentDto>(x => x.ContentTypeId, ids)
.OrderBy<NodeDto>(x => x.Level, x => x.SortOrder);
return uow.Database.Query<ContentSourceDto>(sql).Select(CreateMediaNodeKit);
return scope.Database.Query<ContentSourceDto>(sql).Select(CreateMediaNodeKit);
}
private static ContentNodeKit CreateContentNodeKit(ContentSourceDto dto)

View File

@@ -18,8 +18,6 @@ using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.Repositories.Implement;
using Umbraco.Core.Persistence.UnitOfWork;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Scoping;
using Umbraco.Core.Services;
using Umbraco.Core.Services.Changes;
@@ -37,10 +35,11 @@ namespace Umbraco.Web.PublishedCache.NuCache
private readonly ServiceContext _serviceContext;
private readonly IPublishedContentTypeFactory _publishedContentTypeFactory;
private readonly IScopeProvider _scopeProvider;
private readonly IScopeUnitOfWorkProvider _uowProvider;
private readonly Database _dataSource;
private readonly ILogger _logger;
private readonly Options _options;
private readonly IDocumentRepository _documentRepository;
private readonly IMediaRepository _mediaRepository;
private readonly IMemberRepository _memberRepository;
// volatile because we read it with no lock
private volatile bool _isReady;
@@ -78,7 +77,8 @@ namespace Umbraco.Web.PublishedCache.NuCache
public PublishedSnapshotService(Options options, MainDom mainDom, IRuntimeState runtime,
ServiceContext serviceContext, IPublishedContentTypeFactory publishedContentTypeFactory,
IScopeUnitOfWorkProvider uowProvider, IPublishedSnapshotAccessor publishedSnapshotAccessor, ILogger logger, IScopeProvider scopeProvider)
IPublishedSnapshotAccessor publishedSnapshotAccessor, ILogger logger, IScopeProvider scopeProvider,
IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository)
: base(publishedSnapshotAccessor)
{
//if (Interlocked.Increment(ref _singletonCheck) > 1)
@@ -86,11 +86,12 @@ namespace Umbraco.Web.PublishedCache.NuCache
_serviceContext = serviceContext;
_publishedContentTypeFactory = publishedContentTypeFactory;
_uowProvider = uowProvider;
_dataSource = new Database();
_logger = logger;
_scopeProvider = scopeProvider;
_options = options;
_documentRepository = documentRepository;
_mediaRepository = mediaRepository;
_memberRepository = memberRepository;
// we always want to handle repository events, configured or not
// assuming no repository event will trigger before the whole db is ready
@@ -105,7 +106,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
if (runtime.Level != RuntimeLevel.Run)
return;
if (_options.IgnoreLocalDb == false)
if (options.IgnoreLocalDb == false)
{
var registered = mainDom.Register(
null,
@@ -184,15 +185,15 @@ namespace Umbraco.Web.PublishedCache.NuCache
// plug repository event handlers
// these trigger within the transaction to ensure consistency
// and are used to maintain the central, database-level XML cache
DocumentRepository.UowRemovingEntity += OnContentRemovingEntity;
DocumentRepository.ScopeEntityRemove += OnContentRemovingEntity;
//ContentRepository.RemovedVersion += OnContentRemovedVersion;
DocumentRepository.UowRefreshedEntity += OnContentRefreshedEntity;
MediaRepository.UowRemovingEntity += OnMediaRemovingEntity;
DocumentRepository.ScopedEntityRefresh += OnContentRefreshedEntity;
MediaRepository.ScopeEntityRemove += OnMediaRemovingEntity;
//MediaRepository.RemovedVersion += OnMediaRemovedVersion;
MediaRepository.UowRefreshedEntity += OnMediaRefreshedEntity;
MemberRepository.UowRemovingEntity += OnMemberRemovingEntity;
MediaRepository.ScopedEntityRefresh += OnMediaRefreshedEntity;
MemberRepository.ScopeEntityRemove += OnMemberRemovingEntity;
//MemberRepository.RemovedVersion += OnMemberRemovedVersion;
MemberRepository.UowRefreshedEntity += OnMemberRefreshedEntity;
MemberRepository.ScopedEntityRefresh += OnMemberRefreshedEntity;
// plug
ContentTypeService.UowRefreshedEntity += OnContentTypeRefreshedEntity;
@@ -202,15 +203,15 @@ namespace Umbraco.Web.PublishedCache.NuCache
private void TearDownRepositoryEvents()
{
DocumentRepository.UowRemovingEntity -= OnContentRemovingEntity;
DocumentRepository.ScopeEntityRemove -= OnContentRemovingEntity;
//ContentRepository.RemovedVersion -= OnContentRemovedVersion;
DocumentRepository.UowRefreshedEntity -= OnContentRefreshedEntity;
MediaRepository.UowRemovingEntity -= OnMediaRemovingEntity;
DocumentRepository.ScopedEntityRefresh -= OnContentRefreshedEntity;
MediaRepository.ScopeEntityRemove -= OnMediaRemovingEntity;
//MediaRepository.RemovedVersion -= OnMediaRemovedVersion;
MediaRepository.UowRefreshedEntity -= OnMediaRefreshedEntity;
MemberRepository.UowRemovingEntity -= OnMemberRemovingEntity;
MediaRepository.ScopedEntityRefresh -= OnMediaRefreshedEntity;
MemberRepository.ScopeEntityRemove -= OnMemberRemovingEntity;
//MemberRepository.RemovedVersion -= OnMemberRemovedVersion;
MemberRepository.UowRefreshedEntity -= OnMemberRefreshedEntity;
MemberRepository.ScopedEntityRefresh -= OnMemberRefreshedEntity;
ContentTypeService.UowRefreshedEntity -= OnContentTypeRefreshedEntity;
MediaTypeService.UowRefreshedEntity -= OnMediaTypeRefreshedEntity;
@@ -256,20 +257,20 @@ namespace Umbraco.Web.PublishedCache.NuCache
// before I read it? NO! because the WHOLE content tree is read-locked using WithReadLocked.
// don't panic.
private void LockAndLoadContent(Action<IScopeUnitOfWork> action)
private void LockAndLoadContent(Action<IScope> action)
{
using (_contentStore.GetWriter(_scopeProvider))
{
using (var uow = _uowProvider.CreateUnitOfWork())
using (var scope = _scopeProvider.CreateScope())
{
uow.ReadLock(Constants.Locks.ContentTree);
action(uow);
uow.Complete();
scope.ReadLock(Constants.Locks.ContentTree);
action(scope);
scope.Complete();
}
}
}
private void LoadContentFromDatabaseLocked(IScopeUnitOfWork uow)
private void LoadContentFromDatabaseLocked(IScope scope)
{
// locks:
// contentStore is wlocked (1 thread)
@@ -283,13 +284,13 @@ namespace Umbraco.Web.PublishedCache.NuCache
_logger.Debug<PublishedSnapshotService>("Loading content from database...");
var sw = Stopwatch.StartNew();
var kits = _dataSource.GetAllContentSources(uow);
var kits = _dataSource.GetAllContentSources(scope);
_contentStore.SetAll(kits);
sw.Stop();
_logger.Debug<PublishedSnapshotService>("Loaded content from database (" + sw.ElapsedMilliseconds + "ms).");
}
private void LoadContentFromLocalDbLocked(IScopeUnitOfWork uow)
private void LoadContentFromLocalDbLocked(IScope scope)
{
var contentTypes = _serviceContext.ContentTypeService.GetAll()
.Select(x => _publishedContentTypeFactory.CreateContentType(PublishedItemType.Content, x));
@@ -326,20 +327,20 @@ namespace Umbraco.Web.PublishedCache.NuCache
// _contentStore.Set(contentNode);
//}
private void LockAndLoadMedia(Action<IScopeUnitOfWork> action)
private void LockAndLoadMedia(Action<IScope> action)
{
using (_mediaStore.GetWriter(_scopeProvider))
{
using (var uow = _uowProvider.CreateUnitOfWork())
using (var scope = _scopeProvider.CreateScope())
{
uow.ReadLock(Constants.Locks.MediaTree);
action(uow);
uow.Complete();
scope.ReadLock(Constants.Locks.MediaTree);
action(scope);
scope.Complete();
}
}
}
private void LoadMediaFromDatabaseLocked(IScopeUnitOfWork uow)
private void LoadMediaFromDatabaseLocked(IScope scope)
{
// locks & notes: see content
@@ -351,13 +352,13 @@ namespace Umbraco.Web.PublishedCache.NuCache
_logger.Debug<PublishedSnapshotService>("Loading media from database...");
var sw = Stopwatch.StartNew();
var kits = _dataSource.GetAllMediaSources(uow);
var kits = _dataSource.GetAllMediaSources(scope);
_mediaStore.SetAll(kits);
sw.Stop();
_logger.Debug<PublishedSnapshotService>("Loaded media from database (" + sw.ElapsedMilliseconds + "ms).");
}
private void LoadMediaFromLocalDbLocked(IScopeUnitOfWork uow)
private void LoadMediaFromLocalDbLocked(IScope scope)
{
var mediaTypes = _serviceContext.MediaTypeService.GetAll()
.Select(x => _publishedContentTypeFactory.CreateContentType(PublishedItemType.Media, x));
@@ -459,11 +460,11 @@ namespace Umbraco.Web.PublishedCache.NuCache
{
using (_domainStore.GetWriter(_scopeProvider))
{
using (var uow = _uowProvider.CreateUnitOfWork())
using (var scope = _scopeProvider.CreateScope())
{
uow.ReadLock(Constants.Locks.Domains);
scope.ReadLock(Constants.Locks.Domains);
LoadDomainsLocked();
uow.Complete();
scope.Complete();
}
}
}
@@ -527,8 +528,8 @@ namespace Umbraco.Web.PublishedCache.NuCache
publishedChanged = false;
draftChanged = false;
var contentService = _serviceContext.ContentService as ContentService;
if (contentService == null) throw new Exception("oops");
if (!(_serviceContext.ContentService is ContentService))
throw new Exception("oops");
// locks:
// content (and content types) are read-locked while reading content
@@ -542,11 +543,11 @@ namespace Umbraco.Web.PublishedCache.NuCache
if (payload.ChangeTypes.HasType(TreeChangeTypes.RefreshAll))
{
using (var uow = _uowProvider.CreateUnitOfWork())
using (var scope = _scopeProvider.CreateScope())
{
uow.ReadLock(Constants.Locks.ContentTree);
LoadContentFromDatabaseLocked(uow);
uow.Complete();
scope.ReadLock(Constants.Locks.ContentTree);
LoadContentFromDatabaseLocked(scope);
scope.Complete();
}
draftChanged = publishedChanged = true;
continue;
@@ -568,20 +569,20 @@ namespace Umbraco.Web.PublishedCache.NuCache
// fixme - should we do some RV check here? (later)
var capture = payload;
using (var uow = _uowProvider.CreateUnitOfWork())
using (var scope = _scopeProvider.CreateScope())
{
uow.ReadLock(Constants.Locks.ContentTree);
scope.ReadLock(Constants.Locks.ContentTree);
if (capture.ChangeTypes.HasType(TreeChangeTypes.RefreshBranch))
{
// ?? should we do some RV check here?
var kits = _dataSource.GetBranchContentSources(uow, capture.Id);
var kits = _dataSource.GetBranchContentSources(scope, capture.Id);
_contentStore.SetBranch(capture.Id, kits);
}
else
{
// ?? should we do some RV check here?
var kit = _dataSource.GetContentSource(uow, capture.Id);
var kit = _dataSource.GetContentSource(scope, capture.Id);
if (kit.IsEmpty)
{
_contentStore.Clear(capture.Id);
@@ -592,7 +593,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
}
}
uow.Complete();
scope.Complete();
}
// ?? cannot tell really because we're not doing RV checks
@@ -623,8 +624,8 @@ namespace Umbraco.Web.PublishedCache.NuCache
{
anythingChanged = false;
var mediaService = _serviceContext.MediaService as MediaService;
if (mediaService == null) throw new Exception("oops");
if (!(_serviceContext.MediaService is MediaService))
throw new Exception("oops");
// locks:
// see notes for content cache refresher
@@ -635,11 +636,11 @@ namespace Umbraco.Web.PublishedCache.NuCache
if (payload.ChangeTypes.HasType(TreeChangeTypes.RefreshAll))
{
using (var uow = _uowProvider.CreateUnitOfWork())
using (var scope = _scopeProvider.CreateScope())
{
uow.ReadLock(Constants.Locks.MediaTree);
LoadMediaFromDatabaseLocked(uow);
uow.Complete();
scope.ReadLock(Constants.Locks.MediaTree);
LoadMediaFromDatabaseLocked(scope);
scope.Complete();
}
anythingChanged = true;
continue;
@@ -661,20 +662,20 @@ namespace Umbraco.Web.PublishedCache.NuCache
// fixme - should we do some RV checks here? (later)
var capture = payload;
using (var uow = _uowProvider.CreateUnitOfWork())
using (var scope = _scopeProvider.CreateScope())
{
uow.ReadLock(Constants.Locks.MediaTree);
scope.ReadLock(Constants.Locks.MediaTree);
if (capture.ChangeTypes.HasType(TreeChangeTypes.RefreshBranch))
{
// ?? should we do some RV check here?
var kits = _dataSource.GetBranchMediaSources(uow, capture.Id);
var kits = _dataSource.GetBranchMediaSources(scope, capture.Id);
_mediaStore.SetBranch(capture.Id, kits);
}
else
{
// ?? should we do some RV check here?
var kit = _dataSource.GetMediaSource(uow, capture.Id);
var kit = _dataSource.GetMediaSource(scope, capture.Id);
if (kit.IsEmpty)
{
_mediaStore.Clear(capture.Id);
@@ -685,7 +686,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
}
}
uow.Complete();
scope.Complete();
}
// ?? cannot tell really because we're not doing RV checks
@@ -755,27 +756,27 @@ namespace Umbraco.Web.PublishedCache.NuCache
using (_contentStore.GetWriter(_scopeProvider))
using (_mediaStore.GetWriter(_scopeProvider))
{
var contentService = _serviceContext.ContentService as ContentService;
if (contentService == null) throw new Exception("oops");
if (!(_serviceContext.ContentService is ContentService))
throw new Exception("oops");
using (var uow = _uowProvider.CreateUnitOfWork())
{
uow.ReadLock(Constants.Locks.ContentTree);
_contentStore.UpdateDataTypes(idsA, id => CreateContentType(PublishedItemType.Content, id));
uow.Complete();
}
var mediaService = _serviceContext.MediaService as MediaService;
if (mediaService == null) throw new Exception("oops");
using (var uow = _uowProvider.CreateUnitOfWork())
{
uow.ReadLock(Constants.Locks.MediaTree);
_mediaStore.UpdateDataTypes(idsA, id => CreateContentType(PublishedItemType.Media, id));
uow.Complete();
}
using (var scope = _scopeProvider.CreateScope())
{
scope.ReadLock(Constants.Locks.ContentTree);
_contentStore.UpdateDataTypes(idsA, id => CreateContentType(PublishedItemType.Content, id));
scope.Complete();
}
if (!(_serviceContext.MediaService is MediaService))
throw new Exception("oops");
using (var scope = _scopeProvider.CreateScope())
{
scope.ReadLock(Constants.Locks.MediaTree);
_mediaStore.UpdateDataTypes(idsA, id => CreateContentType(PublishedItemType.Media, id));
scope.Complete();
}
}
((PublishedShapshot) CurrentPublishedShapshot).Resync();
}
@@ -792,13 +793,14 @@ namespace Umbraco.Web.PublishedCache.NuCache
switch (payload.ChangeType)
{
case DomainChangeTypes.RefreshAll:
var domainService = _serviceContext.DomainService as DomainService;
if (domainService == null) throw new Exception("oops");
using (var uow = _uowProvider.CreateUnitOfWork())
if (!(_serviceContext.DomainService is DomainService))
throw new Exception("oops");
using (var scope = _scopeProvider.CreateScope())
{
uow.ReadLock(Constants.Locks.Domains);
scope.ReadLock(Constants.Locks.Domains);
LoadDomainsLocked();
uow.Complete();
scope.Complete();
}
break;
case DomainChangeTypes.Remove:
@@ -876,20 +878,20 @@ namespace Umbraco.Web.PublishedCache.NuCache
// contentStore is wlocked (so readable, only no new views)
// and it can be wlocked by 1 thread only at a time
var contentService = _serviceContext.ContentService as ContentService;
if (contentService == null) throw new Exception("oops");
if (!(_serviceContext.ContentService is ContentService))
throw new Exception("oops");
var refreshedIdsA = refreshedIds.ToArray();
using (var uow = _uowProvider.CreateUnitOfWork())
using (var scope = _scopeProvider.CreateScope())
{
uow.ReadLock(Constants.Locks.ContentTypes);
scope.ReadLock(Constants.Locks.ContentTypes);
var typesA = CreateContentTypes(PublishedItemType.Content, refreshedIdsA).ToArray();
var kits = _dataSource.GetTypeContentSources(uow, refreshedIdsA);
var kits = _dataSource.GetTypeContentSources(scope, refreshedIdsA);
_contentStore.UpdateContentTypes(removedIds, typesA, kits);
_contentStore.UpdateContentTypes(CreateContentTypes(PublishedItemType.Content, otherIds.ToArray()).ToArray());
_contentStore.NewContentTypes(CreateContentTypes(PublishedItemType.Content, newIds.ToArray()).ToArray());
uow.Complete();
scope.Complete();
}
}
@@ -900,20 +902,20 @@ namespace Umbraco.Web.PublishedCache.NuCache
// mediaStore is wlocked (so readable, only no new views)
// and it can be wlocked by 1 thread only at a time
var mediaService = _serviceContext.MediaService as MediaService;
if (mediaService == null) throw new Exception("oops");
if (!(_serviceContext.MediaService is MediaService))
throw new Exception("oops");
var refreshedIdsA = refreshedIds.ToArray();
using (var uow = _uowProvider.CreateUnitOfWork())
using (var scope = _scopeProvider.CreateScope())
{
uow.ReadLock(Constants.Locks.MediaTypes);
scope.ReadLock(Constants.Locks.MediaTypes);
var typesA = CreateContentTypes(PublishedItemType.Media, refreshedIdsA).ToArray();
var kits = _dataSource.GetTypeMediaSources(uow, refreshedIdsA);
var kits = _dataSource.GetTypeMediaSources(scope, refreshedIdsA);
_mediaStore.UpdateContentTypes(removedIds, typesA, kits);
_mediaStore.UpdateContentTypes(CreateContentTypes(PublishedItemType.Media, otherIds.ToArray()).ToArray());
_mediaStore.NewContentTypes(CreateContentTypes(PublishedItemType.Media, newIds.ToArray()).ToArray());
uow.Complete();
scope.Complete();
}
}
@@ -1037,19 +1039,19 @@ namespace Umbraco.Web.PublishedCache.NuCache
// because they need to be consistent with the content that is being refreshed/removed - and that
// should be guaranteed by a DB transaction
private void OnContentRemovingEntity(DocumentRepository sender, DocumentRepository.UnitOfWorkEntityEventArgs args)
private void OnContentRemovingEntity(DocumentRepository sender, DocumentRepository.ScopedEntityEventArgs args)
{
OnRemovedEntity(args.UnitOfWork.Database, args.Entity);
OnRemovedEntity(args.Scope.Database, args.Entity);
}
private void OnMediaRemovingEntity(MediaRepository sender, MediaRepository.UnitOfWorkEntityEventArgs args)
private void OnMediaRemovingEntity(MediaRepository sender, MediaRepository.ScopedEntityEventArgs args)
{
OnRemovedEntity(args.UnitOfWork.Database, args.Entity);
OnRemovedEntity(args.Scope.Database, args.Entity);
}
private void OnMemberRemovingEntity(MemberRepository sender, MemberRepository.UnitOfWorkEntityEventArgs args)
private void OnMemberRemovingEntity(MemberRepository sender, MemberRepository.ScopedEntityEventArgs args)
{
OnRemovedEntity(args.UnitOfWork.Database, args.Entity);
OnRemovedEntity(args.Scope.Database, args.Entity);
}
private void OnRemovedEntity(IUmbracoDatabase db, IContentBase item)
@@ -1072,9 +1074,9 @@ namespace Umbraco.Web.PublishedCache.NuCache
return PropertiesImpactingAllVersions.Any(content.IsPropertyDirty);
}
private void OnContentRefreshedEntity(DocumentRepository sender, DocumentRepository.UnitOfWorkEntityEventArgs args)
private void OnContentRefreshedEntity(DocumentRepository sender, DocumentRepository.ScopedEntityEventArgs args)
{
var db = args.UnitOfWork.Database;
var db = args.Scope.Database;
var content = (Content) args.Entity;
// always refresh the edited data
@@ -1089,18 +1091,18 @@ namespace Umbraco.Web.PublishedCache.NuCache
OnRepositoryRefreshed(db, content, true);
}
private void OnMediaRefreshedEntity(MediaRepository sender, MediaRepository.UnitOfWorkEntityEventArgs args)
private void OnMediaRefreshedEntity(MediaRepository sender, MediaRepository.ScopedEntityEventArgs args)
{
var db = args.UnitOfWork.Database;
var db = args.Scope.Database;
var media = args.Entity;
// refresh the edited data
OnRepositoryRefreshed(db, media, false);
}
private void OnMemberRefreshedEntity(MemberRepository sender, MemberRepository.UnitOfWorkEntityEventArgs args)
private void OnMemberRefreshedEntity(MemberRepository sender, MemberRepository.ScopedEntityEventArgs args)
{
var db = args.UnitOfWork.Database;
var db = args.Scope.Database;
var member = args.Entity;
// refresh the edited data
@@ -1214,21 +1216,19 @@ namespace Umbraco.Web.PublishedCache.NuCache
public void RebuildContentDbCache(int groupSize = 5000, IEnumerable<int> contentTypeIds = null)
{
using (var scope = _scopeProvider.CreateScope(repositoryCacheMode: RepositoryCacheMode.Scoped))
using (var uow = _uowProvider.CreateUnitOfWork())
{
uow.ReadLock(Constants.Locks.ContentTree);
RebuildContentDbCacheLocked(uow, groupSize, contentTypeIds);
uow.Complete();
scope.ReadLock(Constants.Locks.ContentTree);
RebuildContentDbCacheLocked(scope, groupSize, contentTypeIds);
scope.Complete();
}
}
// assumes content tree lock
private void RebuildContentDbCacheLocked(IScopeUnitOfWork uow, int groupSize, IEnumerable<int> contentTypeIds)
private void RebuildContentDbCacheLocked(IScope scope, int groupSize, IEnumerable<int> contentTypeIds)
{
var contentTypeIdsA = contentTypeIds?.ToArray();
var contentObjectType = Constants.ObjectTypes.Document;
var db = uow.Database;
var db = scope.Database;
// remove all - if anything fails the transaction will rollback
if (contentTypeIds == null || contentTypeIdsA.Length == 0)
@@ -1255,8 +1255,7 @@ WHERE cmsContentNu.nodeId IN (
}
// insert back - if anything fails the transaction will rollback
var repository = uow.CreateRepository<IDocumentRepository>();
var query = _uowProvider.SqlContext.Query<IContent>();
var query = scope.SqlContext.Query<IContent>();
if (contentTypeIds != null && contentTypeIdsA.Length > 0)
query = query.WhereIn(x => x.ContentTypeId, contentTypeIdsA); // assume number of ctypes won't blow IN(...)
@@ -1265,7 +1264,7 @@ WHERE cmsContentNu.nodeId IN (
long total;
do
{
var descendants = repository.GetPage(query, pageIndex++, groupSize, out total, "Path", Direction.Ascending, true);
var descendants = _documentRepository.GetPage(query, pageIndex++, groupSize, out total, "Path", Direction.Ascending, true);
var items = new List<ContentNuDto>();
foreach (var c in descendants)
{
@@ -1284,21 +1283,19 @@ WHERE cmsContentNu.nodeId IN (
public void RebuildMediaDbCache(int groupSize = 5000, IEnumerable<int> contentTypeIds = null)
{
using (var scope = _scopeProvider.CreateScope(repositoryCacheMode: RepositoryCacheMode.Scoped))
using (var uow = _uowProvider.CreateUnitOfWork())
{
uow.ReadLock(Constants.Locks.MediaTree);
RebuildMediaDbCacheLocked(uow, groupSize, contentTypeIds);
uow.Complete();
scope.ReadLock(Constants.Locks.MediaTree);
RebuildMediaDbCacheLocked(scope, groupSize, contentTypeIds);
scope.Complete();
}
}
// assumes media tree lock
public void RebuildMediaDbCacheLocked(IScopeUnitOfWork uow, int groupSize, IEnumerable<int> contentTypeIds)
public void RebuildMediaDbCacheLocked(IScope scope, int groupSize, IEnumerable<int> contentTypeIds)
{
var contentTypeIdsA = contentTypeIds?.ToArray();
var mediaObjectType = Constants.ObjectTypes.Media;
var db = uow.Database;
var db = scope.Database;
// remove all - if anything fails the transaction will rollback
if (contentTypeIds == null || contentTypeIdsA.Length == 0)
@@ -1325,8 +1322,7 @@ WHERE cmsContentNu.nodeId IN (
}
// insert back - if anything fails the transaction will rollback
var repository = uow.CreateRepository<IMediaRepository>();
var query = _uowProvider.SqlContext.Query<IMedia>();
var query = scope.SqlContext.Query<IMedia>();
if (contentTypeIds != null && contentTypeIdsA.Length > 0)
query = query.WhereIn(x => x.ContentTypeId, contentTypeIdsA); // assume number of ctypes won't blow IN(...)
@@ -1335,7 +1331,7 @@ WHERE cmsContentNu.nodeId IN (
long total;
do
{
var descendants = repository.GetPage(query, pageIndex++, groupSize, out total, "Path", Direction.Ascending, true);
var descendants = _mediaRepository.GetPage(query, pageIndex++, groupSize, out total, "Path", Direction.Ascending, true);
var items = descendants.Select(m => GetDto(m, false)).ToArray();
db.BulkInsertRecords(items);
processed += items.Length;
@@ -1345,21 +1341,19 @@ WHERE cmsContentNu.nodeId IN (
public void RebuildMemberDbCache(int groupSize = 5000, IEnumerable<int> contentTypeIds = null)
{
using (var scope = _scopeProvider.CreateScope(repositoryCacheMode: RepositoryCacheMode.Scoped))
using (var uow = _uowProvider.CreateUnitOfWork())
{
uow.ReadLock(Constants.Locks.MemberTree);
RebuildMemberDbCacheLocked(uow, groupSize, contentTypeIds);
uow.Complete();
scope.ReadLock(Constants.Locks.MemberTree);
RebuildMemberDbCacheLocked(scope, groupSize, contentTypeIds);
scope.Complete();
}
}
// assumes member tree lock
public void RebuildMemberDbCacheLocked(IScopeUnitOfWork uow, int groupSize, IEnumerable<int> contentTypeIds)
public void RebuildMemberDbCacheLocked(IScope scope, int groupSize, IEnumerable<int> contentTypeIds)
{
var contentTypeIdsA = contentTypeIds?.ToArray();
var memberObjectType = Constants.ObjectTypes.Member;
var db = uow.Database;
var db = scope.Database;
// remove all - if anything fails the transaction will rollback
if (contentTypeIds == null || contentTypeIdsA.Length == 0)
@@ -1386,8 +1380,7 @@ WHERE cmsContentNu.nodeId IN (
}
// insert back - if anything fails the transaction will rollback
var repository = uow.CreateRepository<IMemberRepository>();
var query = _uowProvider.SqlContext.Query<IMember>();
var query = scope.SqlContext.Query<IMember>();
if (contentTypeIds != null && contentTypeIdsA.Length > 0)
query = query.WhereIn(x => x.ContentTypeId, contentTypeIdsA); // assume number of ctypes won't blow IN(...)
@@ -1396,7 +1389,7 @@ WHERE cmsContentNu.nodeId IN (
long total;
do
{
var descendants = repository.GetPage(query, pageIndex++, groupSize, out total, "Path", Direction.Ascending, true);
var descendants = _memberRepository.GetPage(query, pageIndex++, groupSize, out total, "Path", Direction.Ascending, true);
var items = descendants.Select(m => GetDto(m, false)).ToArray();
db.BulkInsertRecords(items);
processed += items.Length;
@@ -1405,23 +1398,23 @@ WHERE cmsContentNu.nodeId IN (
public bool VerifyContentDbCache()
{
using (var uow = _uowProvider.CreateUnitOfWork())
using (var scope = _scopeProvider.CreateScope())
{
uow.ReadLock(Constants.Locks.ContentTree);
var ok = VerifyContentDbCacheLocked(uow);
uow.Complete();
scope.ReadLock(Constants.Locks.ContentTree);
var ok = VerifyContentDbCacheLocked(scope);
scope.Complete();
return ok;
}
}
// assumes content tree lock
private bool VerifyContentDbCacheLocked(IScopeUnitOfWork uow)
private bool VerifyContentDbCacheLocked(IScope scope)
{
// every document should have a corresponding row for edited properties
// and if published, may have a corresponding row for published properties
var contentObjectType = Constants.ObjectTypes.Document;
var db = uow.Database;
var db = scope.Database;
var count = db.ExecuteScalar<int>(@"SELECT COUNT(*)
FROM umbracoNode
@@ -1437,22 +1430,22 @@ AND nuEdited.nodeId IS NULL OR (uDocument.published=1 AND nuPublished.nodeId IS
public bool VerifyMediaDbCache()
{
using (var uow = _uowProvider.CreateUnitOfWork())
using (var scope = _scopeProvider.CreateScope())
{
uow.ReadLock(Constants.Locks.MediaTree);
var ok = VerifyMediaDbCacheLocked(uow);
uow.Complete();
scope.ReadLock(Constants.Locks.MediaTree);
var ok = VerifyMediaDbCacheLocked(scope);
scope.Complete();
return ok;
}
}
// assumes media tree lock
public bool VerifyMediaDbCacheLocked(IScopeUnitOfWork uow)
public bool VerifyMediaDbCacheLocked(IScope scope)
{
// every media item should have a corresponding row for edited properties
var mediaObjectType = Constants.ObjectTypes.Media;
var db = uow.Database;
var db = scope.Database;
var count = db.ExecuteScalar<int>(@"SELECT COUNT(*)
FROM umbracoNode
@@ -1466,22 +1459,22 @@ AND cmsContentNu.nodeId IS NULL
public bool VerifyMemberDbCache()
{
using (var uow = _uowProvider.CreateUnitOfWork())
using (var scope = _scopeProvider.CreateScope())
{
uow.ReadLock(Constants.Locks.MemberTree);
var ok = VerifyMemberDbCacheLocked(uow);
uow.Complete();
scope.ReadLock(Constants.Locks.MemberTree);
var ok = VerifyMemberDbCacheLocked(scope);
scope.Complete();
return ok;
}
}
// assumes member tree lock
public bool VerifyMemberDbCacheLocked(IScopeUnitOfWork uow)
public bool VerifyMemberDbCacheLocked(IScope scope)
{
// every member item should have a corresponding row for edited properties
var memberObjectType = Constants.ObjectTypes.Member;
var db = uow.Database;
var db = scope.Database;
var count = db.ExecuteScalar<int>(@"SELECT COUNT(*)
FROM umbracoNode

View File

@@ -16,7 +16,6 @@ using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.Repositories.Implement;
using Umbraco.Core.Persistence.UnitOfWork;
using Umbraco.Core.Scoping;
using Umbraco.Core.Services;
using Umbraco.Core.Services.Changes;
@@ -40,6 +39,9 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
/// </remarks>
class XmlStore : IDisposable
{
private readonly IDocumentRepository _documentRepository;
private readonly IMediaRepository _mediaRepository;
private readonly IMemberRepository _memberRepository;
private XmlStoreFilePersister _persisterTask;
private volatile bool _released;
private bool _withRepositoryEvents;
@@ -49,7 +51,6 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
private readonly IEnumerable<IUrlSegmentProvider> _segmentProviders;
private readonly RoutesCache _routesCache;
private readonly ServiceContext _serviceContext; // fixme WHY
private readonly IScopeUnitOfWorkProvider _uowProvider;
private readonly IScopeProvider _scopeProvider;
#region Constructors
@@ -58,27 +59,29 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
/// Initializes a new instance of the <see cref="XmlStore"/> class.
/// </summary>
/// <remarks>The default constructor will boot the cache, load data from file or database, /// wire events in order to manage changes, etc.</remarks>
public XmlStore(ServiceContext serviceContext, IScopeProvider scopeProvider, IScopeUnitOfWorkProvider uowProvider, RoutesCache routesCache, PublishedContentTypeCache contentTypeCache,
IEnumerable<IUrlSegmentProvider> segmentProviders, IPublishedSnapshotAccessor publishedSnapshotAccessor, MainDom mainDom)
: this(serviceContext, scopeProvider, uowProvider, routesCache, contentTypeCache, segmentProviders, publishedSnapshotAccessor, mainDom, false, false)
public XmlStore(ServiceContext serviceContext, IScopeProvider scopeProvider, RoutesCache routesCache, PublishedContentTypeCache contentTypeCache,
IEnumerable<IUrlSegmentProvider> segmentProviders, IPublishedSnapshotAccessor publishedSnapshotAccessor, MainDom mainDom, IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository)
: this(serviceContext, scopeProvider, routesCache, contentTypeCache, segmentProviders, publishedSnapshotAccessor, mainDom, false, false, documentRepository, mediaRepository, memberRepository)
{ }
// internal for unit tests
// no file nor db, no config check
// fixme - er, we DO have a DB?
internal XmlStore(ServiceContext serviceContext, IScopeProvider scopeProvider, IScopeUnitOfWorkProvider uowProvider, RoutesCache routesCache, PublishedContentTypeCache contentTypeCache,
internal XmlStore(ServiceContext serviceContext, IScopeProvider scopeProvider, RoutesCache routesCache, PublishedContentTypeCache contentTypeCache,
IEnumerable<IUrlSegmentProvider> segmentProviders, IPublishedSnapshotAccessor publishedSnapshotAccessor, MainDom mainDom,
bool testing, bool enableRepositoryEvents)
bool testing, bool enableRepositoryEvents, IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository)
{
if (testing == false)
EnsureConfigurationIsValid();
_serviceContext = serviceContext;
_scopeProvider = scopeProvider;
_uowProvider = uowProvider;
_routesCache = routesCache;
_contentTypeCache = contentTypeCache;
_publishedSnapshotAccessor = publishedSnapshotAccessor;
_documentRepository = documentRepository;
_mediaRepository = mediaRepository;
_memberRepository = memberRepository;
_segmentProviders = segmentProviders;
if (testing)
@@ -96,9 +99,12 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
// internal for unit tests
// initialize with an xml document
// no events, no file nor db, no config check
internal XmlStore(XmlDocument xmlDocument)
internal XmlStore(XmlDocument xmlDocument, IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository)
{
_xmlDocument = xmlDocument;
_documentRepository = documentRepository;
_mediaRepository = mediaRepository;
_memberRepository = memberRepository;
_xmlFileEnabled = false;
// do not plug events, we may not have what it takes to handle them
@@ -107,8 +113,11 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
// internal for unit tests
// initialize with a function returning an xml document
// no events, no file nor db, no config check
internal XmlStore(Func<XmlDocument> getXmlDocument)
internal XmlStore(Func<XmlDocument> getXmlDocument, IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository)
{
_documentRepository = documentRepository;
_mediaRepository = mediaRepository;
_memberRepository = memberRepository;
GetXmlDocument = getXmlDocument ?? throw new ArgumentNullException(nameof(getXmlDocument));
_xmlFileEnabled = false;
@@ -170,15 +179,15 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
// plug repository event handlers
// these trigger within the transaction to ensure consistency
// and are used to maintain the central, database-level XML cache
DocumentRepository.UowRemovingEntity += OnContentRemovingEntity;
DocumentRepository.UowRemovingVersion += OnContentRemovingVersion;
DocumentRepository.UowRefreshedEntity += OnContentRefreshedEntity;
MediaRepository.UowRemovingEntity += OnMediaRemovingEntity;
MediaRepository.UowRemovingVersion += OnMediaRemovingVersion;
MediaRepository.UowRefreshedEntity += OnMediaRefreshedEntity;
MemberRepository.UowRemovingEntity += OnMemberRemovingEntity;
MemberRepository.UowRemovingVersion += OnMemberRemovingVersion;
MemberRepository.UowRefreshedEntity += OnMemberRefreshedEntity;
DocumentRepository.ScopeEntityRemove += OnContentRemovingEntity;
DocumentRepository.ScopeVersionRemove += OnContentRemovingVersion;
DocumentRepository.ScopedEntityRefresh += OnContentRefreshedEntity;
MediaRepository.ScopeEntityRemove += OnMediaRemovingEntity;
MediaRepository.ScopeVersionRemove += OnMediaRemovingVersion;
MediaRepository.ScopedEntityRefresh += OnMediaRefreshedEntity;
MemberRepository.ScopeEntityRemove += OnMemberRemovingEntity;
MemberRepository.ScopeVersionRemove += OnMemberRemovingVersion;
MemberRepository.ScopedEntityRefresh += OnMemberRefreshedEntity;
// plug
ContentTypeService.UowRefreshedEntity += OnContentTypeRefreshedEntity;
@@ -190,15 +199,15 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
private void ClearEvents()
{
DocumentRepository.UowRemovingEntity -= OnContentRemovingEntity;
DocumentRepository.UowRemovingVersion -= OnContentRemovingVersion;
DocumentRepository.UowRefreshedEntity -= OnContentRefreshedEntity;
MediaRepository.UowRemovingEntity -= OnMediaRemovingEntity;
MediaRepository.UowRemovingVersion -= OnMediaRemovingVersion;
MediaRepository.UowRefreshedEntity -= OnMediaRefreshedEntity;
MemberRepository.UowRemovingEntity -= OnMemberRemovingEntity;
MemberRepository.UowRemovingVersion -= OnMemberRemovingVersion;
MemberRepository.UowRefreshedEntity -= OnMemberRefreshedEntity;
DocumentRepository.ScopeEntityRemove -= OnContentRemovingEntity;
DocumentRepository.ScopeVersionRemove -= OnContentRemovingVersion;
DocumentRepository.ScopedEntityRefresh -= OnContentRefreshedEntity;
MediaRepository.ScopeEntityRemove -= OnMediaRemovingEntity;
MediaRepository.ScopeVersionRemove -= OnMediaRemovingVersion;
MediaRepository.ScopedEntityRefresh -= OnMediaRefreshedEntity;
MemberRepository.ScopeEntityRemove -= OnMemberRemovingEntity;
MemberRepository.ScopeVersionRemove -= OnMemberRemovingVersion;
MemberRepository.ScopedEntityRefresh -= OnMemberRefreshedEntity;
ContentTypeService.UowRefreshedEntity -= OnContentTypeRefreshedEntity;
MediaTypeService.UowRefreshedEntity -= OnMediaTypeRefreshedEntity;
@@ -432,17 +441,17 @@ WHERE umbracoNode.nodeObjectType = @nodeObjectType
AND (umbracoNode.id=@id)";
XmlDto xmlDto;
using (var uow = _uowProvider.CreateUnitOfWork())
using (var scope = _scopeProvider.CreateScope())
{
uow.ReadLock(Constants.Locks.MediaTree);
var xmlDtos = uow.Database.Query<XmlDto>(sql,
scope.ReadLock(Constants.Locks.MediaTree);
var xmlDtos = scope.Database.Query<XmlDto>(sql,
new
{
nodeObjectType = Constants.ObjectTypes.Media,
id = mediaId
});
xmlDto = xmlDtos.FirstOrDefault();
uow.Complete();
scope.Complete();
}
if (xmlDto == null) return null;
@@ -464,17 +473,17 @@ WHERE umbracoNode.nodeObjectType = @nodeObjectType
AND (umbracoNode.id=@id)";
XmlDto xmlDto;
using (var uow = _uowProvider.CreateUnitOfWork())
using (var scope = _scopeProvider.CreateScope())
{
uow.ReadLock(Constants.Locks.MemberTree);
var xmlDtos = uow.Database.Query<XmlDto>(sql,
scope.ReadLock(Constants.Locks.MemberTree);
var xmlDtos = scope.Database.Query<XmlDto>(sql,
new
{
nodeObjectType = Constants.ObjectTypes.Member,
id = memberId
});
xmlDto = xmlDtos.FirstOrDefault();
uow.Complete();
scope.Complete();
}
if (xmlDto == null) return null;
@@ -495,17 +504,17 @@ WHERE umbracoNode.nodeObjectType = @nodeObjectType
AND (umbracoNode.id=@id)";
XmlDto xmlDto;
using (var uow = _uowProvider.CreateUnitOfWork())
using (var scope = _scopeProvider.CreateScope())
{
uow.ReadLock(Constants.Locks.ContentTree);
var xmlDtos = uow.Database.Query<XmlDto>(sql,
scope.ReadLock(Constants.Locks.ContentTree);
var xmlDtos = scope.Database.Query<XmlDto>(sql,
new
{
nodeObjectType = Constants.ObjectTypes.Document,
id = contentId
});
xmlDto = xmlDtos.FirstOrDefault();
uow.Complete();
scope.Complete();
}
if (xmlDto == null) return null;
@@ -543,17 +552,17 @@ AND (umbracoNode.id=@id)";
var doc = (XmlDocument)Xml.Clone();
if (content == null) return doc;
using (var uow = _uowProvider.CreateUnitOfWork())
using (var scope = _scopeProvider.CreateScope())
{
uow.ReadLock(Constants.Locks.ContentTree);
var sqlSyntax = uow.SqlContext.SqlSyntax;
scope.ReadLock(Constants.Locks.ContentTree);
var sqlSyntax = scope.SqlContext.SqlSyntax;
var sql = ReadCmsPreviewXmlSql1;
sql += " @path LIKE " + sqlSyntax.GetConcat("umbracoNode.Path", "',%"); // concat(umbracoNode.path, ',%')
if (includeSubs) sql += " OR umbracoNode.path LIKE " + sqlSyntax.GetConcat("@path", "',%"); // concat(@path, ',%')
sql += ReadCmsPreviewXmlSql2;
var xmlDtos = uow.Database.Query<XmlDto>(sql,
var xmlDtos = scope.Database.Query<XmlDto>(sql,
new
{
nodeObjectType = Constants.ObjectTypes.Document,
@@ -569,7 +578,7 @@ AND (umbracoNode.id=@id)";
doc = AddOrUpdateXmlNode(doc, xmlDto);
}
uow.Complete();
scope.Complete();
}
return doc;
@@ -905,12 +914,12 @@ ORDER BY umbracoNode.level, umbracoNode.sortOrder";
XmlNode parent = null;
var parentId = 0;
using (var uow = _uowProvider.CreateUnitOfWork())
using (var scope = _scopeProvider.CreateScope())
{
uow.ReadLock(Constants.Locks.ContentTree);
scope.ReadLock(Constants.Locks.ContentTree);
// get xml
var xmlDtos = uow.Database.Query<XmlDto>(ReadTreeCmsContentXmlSql,
var xmlDtos = scope.Database.Query<XmlDto>(ReadTreeCmsContentXmlSql,
new { nodeObjectType = Constants.ObjectTypes.Document });
foreach (var xmlDto in xmlDtos)
@@ -931,7 +940,7 @@ ORDER BY umbracoNode.level, umbracoNode.sortOrder";
parent.AppendChild(xmlDto.XmlNode);
}
uow.Complete();
scope.Complete();
}
safeXml.Xml = xml;
@@ -941,16 +950,16 @@ ORDER BY umbracoNode.level, umbracoNode.sortOrder";
{
var xmlDoc = new XmlDocument();
using (var uow = _uowProvider.CreateUnitOfWork())
using (var scope = _scopeProvider.CreateScope())
{
if (nodeObjectType == Constants.ObjectTypes.Document)
uow.ReadLock(Constants.Locks.ContentTree);
scope.ReadLock(Constants.Locks.ContentTree);
else if (nodeObjectType == Constants.ObjectTypes.Media)
uow.ReadLock(Constants.Locks.MediaTree);
scope.ReadLock(Constants.Locks.MediaTree);
else if (nodeObjectType == Constants.ObjectTypes.Member)
uow.ReadLock(Constants.Locks.MemberTree);
scope.ReadLock(Constants.Locks.MemberTree);
var xmlDtos = uow.Database.Query<XmlDto>(ReadMoreCmsContentXmlSql,
var xmlDtos = scope.Database.Query<XmlDto>(ReadMoreCmsContentXmlSql,
new { /*@nodeObjectType =*/ nodeObjectType });
// Initialise the document ready for the final composition of content
@@ -982,7 +991,7 @@ ORDER BY umbracoNode.level, umbracoNode.sortOrder";
parent.AppendChild(node);
}
uow.Complete();
scope.Complete();
}
return xmlDoc;
@@ -1068,12 +1077,12 @@ ORDER BY umbracoNode.level, umbracoNode.sortOrder";
// else we have a published version
// get xml
using (var uow = _uowProvider.CreateUnitOfWork())
using (var scope = _scopeProvider.CreateScope())
{
uow.ReadLock(Constants.Locks.ContentTree);
scope.ReadLock(Constants.Locks.ContentTree);
// that query is yielding results so will only load what's needed
var xmlDtos = uow.Database.Query<XmlDto>(ReadBranchCmsContentXmlSql,
var xmlDtos = scope.Database.Query<XmlDto>(ReadBranchCmsContentXmlSql,
new
{
nodeObjectType = Constants.ObjectTypes.Document,
@@ -1174,7 +1183,7 @@ ORDER BY umbracoNode.level, umbracoNode.sortOrder";
}
}
uow.Complete();
scope.Complete();
}
publishedChanged = true;
@@ -1247,10 +1256,10 @@ ORDER BY umbracoNode.level, umbracoNode.sortOrder";
private void RefreshContentTypes(IEnumerable<int> ids)
{
using (var safeXml = GetSafeXmlWriter())
using (var uow = _uowProvider.CreateUnitOfWork())
using (var scope = _scopeProvider.CreateScope())
{
uow.ReadLock(Constants.Locks.ContentTree);
var xmlDtos = uow.Database.Query<XmlDto>(ReadCmsContentXmlForContentTypesSql,
scope.ReadLock(Constants.Locks.ContentTree);
var xmlDtos = scope.Database.Query<XmlDto>(ReadCmsContentXmlForContentTypesSql,
new { nodeObjectType = Constants.ObjectTypes.Document, /*@ids =*/ ids });
foreach (var xmlDto in xmlDtos)
@@ -1259,7 +1268,7 @@ ORDER BY umbracoNode.level, umbracoNode.sortOrder";
safeXml.Xml = AddOrUpdateXmlNode(safeXml.Xml, xmlDto);
}
uow.Complete();
scope.Complete();
safeXml.AcceptChanges();
}
}
@@ -1449,19 +1458,19 @@ ORDER BY umbracoNode.level, umbracoNode.sortOrder";
// it is not the case at the moment, instead a global lock is used whenever content is modified - well,
// almost: rollback or unpublish do not implement it - nevertheless
private static void OnContentRemovingEntity(DocumentRepository sender, DocumentRepository.UnitOfWorkEntityEventArgs args)
private static void OnContentRemovingEntity(DocumentRepository sender, DocumentRepository.ScopedEntityEventArgs args)
{
OnRemovedEntity(args.UnitOfWork.Database, args.Entity);
OnRemovedEntity(args.Scope.Database, args.Entity);
}
private static void OnMediaRemovingEntity(MediaRepository sender, MediaRepository.UnitOfWorkEntityEventArgs args)
private static void OnMediaRemovingEntity(MediaRepository sender, MediaRepository.ScopedEntityEventArgs args)
{
OnRemovedEntity(args.UnitOfWork.Database, args.Entity);
OnRemovedEntity(args.Scope.Database, args.Entity);
}
private static void OnMemberRemovingEntity(MemberRepository sender, MemberRepository.UnitOfWorkEntityEventArgs args)
private static void OnMemberRemovingEntity(MemberRepository sender, MemberRepository.ScopedEntityEventArgs args)
{
OnRemovedEntity(args.UnitOfWork.Database, args.Entity);
OnRemovedEntity(args.Scope.Database, args.Entity);
}
private static void OnRemovedEntity(IUmbracoDatabase db, IContentBase item)
@@ -1473,19 +1482,19 @@ ORDER BY umbracoNode.level, umbracoNode.sortOrder";
// note: could be optimized by using "WHERE nodeId IN (...)" delete clauses
}
private static void OnContentRemovingVersion(DocumentRepository sender, DocumentRepository.UnitOfWorkVersionEventArgs args)
private static void OnContentRemovingVersion(DocumentRepository sender, DocumentRepository.ScopedVersionEventArgs args)
{
OnRemovedVersion(args.UnitOfWork.Database, args.EntityId, args.VersionId);
OnRemovedVersion(args.Scope.Database, args.EntityId, args.VersionId);
}
private static void OnMediaRemovingVersion(MediaRepository sender, MediaRepository.UnitOfWorkVersionEventArgs args)
private static void OnMediaRemovingVersion(MediaRepository sender, MediaRepository.ScopedVersionEventArgs args)
{
OnRemovedVersion(args.UnitOfWork.Database, args.EntityId, args.VersionId);
OnRemovedVersion(args.Scope.Database, args.EntityId, args.VersionId);
}
private static void OnMemberRemovingVersion(MemberRepository sender, MemberRepository.UnitOfWorkVersionEventArgs args)
private static void OnMemberRemovingVersion(MemberRepository sender, MemberRepository.ScopedVersionEventArgs args)
{
OnRemovedVersion(args.UnitOfWork.Database, args.EntityId, args.VersionId);
OnRemovedVersion(args.Scope.Database, args.EntityId, args.VersionId);
}
private static void OnRemovedVersion(IUmbracoDatabase db, int entityId, int versionId)
@@ -1508,9 +1517,9 @@ ORDER BY umbracoNode.level, umbracoNode.sortOrder";
return PropertiesImpactingAllVersions.Any(content.IsPropertyDirty);
}
private void OnContentRefreshedEntity(DocumentRepository sender, DocumentRepository.UnitOfWorkEntityEventArgs args)
private void OnContentRefreshedEntity(DocumentRepository sender, DocumentRepository.ScopedEntityEventArgs args)
{
var db = args.UnitOfWork.Database;
var db = args.Scope.Database;
var entity = args.Entity;
// serialize edit values for preview
@@ -1549,9 +1558,9 @@ ORDER BY umbracoNode.level, umbracoNode.sortOrder";
}
private void OnMediaRefreshedEntity(MediaRepository sender, MediaRepository.UnitOfWorkEntityEventArgs args)
private void OnMediaRefreshedEntity(MediaRepository sender, MediaRepository.ScopedEntityEventArgs args)
{
var db = args.UnitOfWork.Database;
var db = args.Scope.Database;
var entity = args.Entity;
// for whatever reason we delete some xml when the media is trashed
@@ -1565,9 +1574,9 @@ ORDER BY umbracoNode.level, umbracoNode.sortOrder";
OnRepositoryRefreshed(db, dto1);
}
private void OnMemberRefreshedEntity(MemberRepository sender, MemberRepository.UnitOfWorkEntityEventArgs args)
private void OnMemberRefreshedEntity(MemberRepository sender, MemberRepository.ScopedEntityEventArgs args)
{
var db = args.UnitOfWork.Database;
var db = args.Scope.Database;
var entity = args.Entity;
var xml = EntityXmlSerializer.Serialize(_serviceContext.DataTypeService, _serviceContext.LocalizationService, entity).ToDataString();
@@ -1655,13 +1664,10 @@ ORDER BY umbracoNode.level, umbracoNode.sortOrder";
var contentTypeIdsA = contentTypeIds?.ToArray();
using (var scope = _scopeProvider.CreateScope(repositoryCacheMode: RepositoryCacheMode.None))
using (var uow = _uowProvider.CreateUnitOfWork())
{
uow.WriteLock(Constants.Locks.ContentTree);
var repository = uow.CreateRepository<IDocumentRepository>();
RebuildContentXmlLocked(uow, repository, groupSize, contentTypeIdsA);
RebuildPreviewXmlLocked(uow, repository, groupSize, contentTypeIdsA);
uow.Complete();
scope.WriteLock(Constants.Locks.ContentTree);
RebuildContentXmlLocked(scope, groupSize, contentTypeIdsA);
RebuildPreviewXmlLocked(scope, groupSize, contentTypeIdsA);
scope.Complete();
}
}
@@ -1669,22 +1675,19 @@ ORDER BY umbracoNode.level, umbracoNode.sortOrder";
public void RebuildContentXml(int groupSize = 5000, IEnumerable<int> contentTypeIds = null)
{
using (var scope = _scopeProvider.CreateScope(repositoryCacheMode: RepositoryCacheMode.None))
using (var uow = _uowProvider.CreateUnitOfWork())
{
uow.WriteLock(Constants.Locks.ContentTree);
var repository = uow.CreateRepository<IDocumentRepository>();
RebuildContentXmlLocked(uow, repository, groupSize, contentTypeIds);
uow.Complete();
scope.WriteLock(Constants.Locks.ContentTree);
RebuildContentXmlLocked(scope, groupSize, contentTypeIds);
scope.Complete();
}
}
// assumes content tree lock
private void RebuildContentXmlLocked(IScopeUnitOfWork unitOfWork, IDocumentRepository repository, int groupSize, IEnumerable<int> contentTypeIds)
private void RebuildContentXmlLocked(IScope scope, int groupSize, IEnumerable<int> contentTypeIds)
{
var contentTypeIdsA = contentTypeIds?.ToArray();
var contentObjectType = Constants.ObjectTypes.Document;
var db = unitOfWork.Database;
var db = scope.Database;
// remove all - if anything fails the transaction will rollback
if (contentTypeIds == null || contentTypeIdsA.Length == 0)
@@ -1721,7 +1724,7 @@ WHERE cmsContentXml.nodeId IN (
}
// insert back - if anything fails the transaction will rollback
var query = _uowProvider.SqlContext.Query<IContent>().Where(x => x.Published);
var query = scope.SqlContext.Query<IContent>().Where(x => x.Published);
if (contentTypeIds != null && contentTypeIdsA.Length > 0)
query = query.WhereIn(x => x.ContentTypeId, contentTypeIdsA); // assume number of ctypes won't blow IN(...)
@@ -1730,7 +1733,7 @@ WHERE cmsContentXml.nodeId IN (
long total;
do
{
var descendants = repository.GetPage(query, pageIndex++, groupSize, out total, "Path", Direction.Ascending, true);
var descendants = _documentRepository.GetPage(query, pageIndex++, groupSize, out total, "Path", Direction.Ascending, true);
const bool published = true; // contentXml contains published content!
var items = descendants.Select(c => new ContentXmlDto { NodeId = c.Id, Xml =
EntityXmlSerializer.Serialize(_serviceContext.ContentService, _serviceContext.DataTypeService, _serviceContext.UserService, _serviceContext.LocalizationService, _segmentProviders, c, published).ToDataString() }).ToArray();
@@ -1742,22 +1745,20 @@ WHERE cmsContentXml.nodeId IN (
public void RebuildPreviewXml(int groupSize = 5000, IEnumerable<int> contentTypeIds = null)
{
using (var scope = _scopeProvider.CreateScope(repositoryCacheMode: RepositoryCacheMode.None))
using (var uow = _uowProvider.CreateUnitOfWork())
{
uow.WriteLock(Constants.Locks.ContentTree);
var repository = uow.CreateRepository<IDocumentRepository>();
RebuildPreviewXmlLocked(uow, repository, groupSize, contentTypeIds);
uow.Complete();
scope.WriteLock(Constants.Locks.ContentTree);
RebuildPreviewXmlLocked(scope, groupSize, contentTypeIds);
scope.Complete();
scope.Complete();
}
}
// assumes content tree lock
private void RebuildPreviewXmlLocked(IScopeUnitOfWork unitOfWork, IDocumentRepository repository, int groupSize, IEnumerable<int> contentTypeIds)
private void RebuildPreviewXmlLocked(IScope scope, int groupSize, IEnumerable<int> contentTypeIds)
{
var contentTypeIdsA = contentTypeIds?.ToArray();
var contentObjectType = Constants.ObjectTypes.Document;
var db = unitOfWork.Database;
var db = scope.Database;
// remove all - if anything fails the transaction will rollback
if (contentTypeIds == null || contentTypeIdsA.Length == 0)
@@ -1794,7 +1795,7 @@ WHERE cmsPreviewXml.nodeId IN (
}
// insert back - if anything fails the transaction will rollback
var query = _uowProvider.SqlContext.Query<IContent>();
var query = scope.SqlContext.Query<IContent>();
if (contentTypeIds != null && contentTypeIdsA.Length > 0)
query = query.WhereIn(x => x.ContentTypeId, contentTypeIdsA); // assume number of ctypes won't blow IN(...)
@@ -1805,7 +1806,7 @@ WHERE cmsPreviewXml.nodeId IN (
{
// .GetPagedResultsByQuery implicitely adds (uDocument.newest = 1) which
// is what we want for preview (ie latest version of a content, published or not)
var descendants = repository.GetPage(query, pageIndex++, groupSize, out total, "Path", Direction.Ascending, true);
var descendants = _documentRepository.GetPage(query, pageIndex++, groupSize, out total, "Path", Direction.Ascending, true);
const bool published = true; // previewXml contains edit content!
var items = descendants.Select(c => new PreviewXmlDto
{
@@ -1820,22 +1821,19 @@ WHERE cmsPreviewXml.nodeId IN (
public void RebuildMediaXml(int groupSize = 5000, IEnumerable<int> contentTypeIds = null)
{
using (var scope = _scopeProvider.CreateScope(repositoryCacheMode: RepositoryCacheMode.None))
using (var uow = _uowProvider.CreateUnitOfWork())
{
uow.WriteLock(Constants.Locks.MediaTree);
var repository = uow.CreateRepository<IMediaRepository>();
RebuildMediaXmlLocked(uow, repository, groupSize, contentTypeIds);
uow.Complete();
scope.WriteLock(Constants.Locks.MediaTree);
RebuildMediaXmlLocked(scope, groupSize, contentTypeIds);
scope.Complete();
}
}
// assumes media tree lock
public void RebuildMediaXmlLocked(IScopeUnitOfWork unitOfWork, IMediaRepository repository, int groupSize, IEnumerable<int> contentTypeIds)
public void RebuildMediaXmlLocked(IScope scope, int groupSize, IEnumerable<int> contentTypeIds)
{
var contentTypeIdsA = contentTypeIds?.ToArray();
var mediaObjectType = Constants.ObjectTypes.Media;
var db = unitOfWork.Database;
var db = scope.Database;
// remove all - if anything fails the transaction will rollback
if (contentTypeIds == null || contentTypeIdsA.Length == 0)
@@ -1872,7 +1870,7 @@ WHERE cmsContentXml.nodeId IN (
}
// insert back - if anything fails the transaction will rollback
var query = _uowProvider.SqlContext.Query<IMedia>();
var query = scope.SqlContext.Query<IMedia>();
if (contentTypeIds != null && contentTypeIdsA.Length > 0)
query = query.WhereIn(x => x.ContentTypeId, contentTypeIdsA); // assume number of ctypes won't blow IN(...)
@@ -1881,7 +1879,7 @@ WHERE cmsContentXml.nodeId IN (
long total;
do
{
var descendants = repository.GetPage(query, pageIndex++, groupSize, out total, "Path", Direction.Ascending, true);
var descendants = _mediaRepository.GetPage(query, pageIndex++, groupSize, out total, "Path", Direction.Ascending, true);
var items = descendants.Select(m => new ContentXmlDto { NodeId = m.Id, Xml =
EntityXmlSerializer.Serialize(_serviceContext.MediaService, _serviceContext.DataTypeService, _serviceContext.UserService, _serviceContext.LocalizationService, _segmentProviders, m).ToDataString() }).ToArray();
db.BulkInsertRecords(items);
@@ -1892,22 +1890,19 @@ WHERE cmsContentXml.nodeId IN (
public void RebuildMemberXml(int groupSize = 5000, IEnumerable<int> contentTypeIds = null)
{
using (var scope = _scopeProvider.CreateScope(repositoryCacheMode: RepositoryCacheMode.None))
using (var uow = _uowProvider.CreateUnitOfWork())
{
uow.WriteLock(Constants.Locks.MemberTree);
var repository = uow.CreateRepository<IMemberRepository>();
RebuildMemberXmlLocked(uow, repository, groupSize, contentTypeIds);
uow.Complete();
scope.WriteLock(Constants.Locks.MemberTree);
RebuildMemberXmlLocked(scope, groupSize, contentTypeIds);
scope.Complete();
}
}
// assumes member tree lock
public void RebuildMemberXmlLocked(IScopeUnitOfWork unitOfWork, IMemberRepository repository, int groupSize, IEnumerable<int> contentTypeIds)
public void RebuildMemberXmlLocked(IScope scope, int groupSize, IEnumerable<int> contentTypeIds)
{
var contentTypeIdsA = contentTypeIds?.ToArray();
var memberObjectType = Constants.ObjectTypes.Member;
var db = unitOfWork.Database;
var db = scope.Database;
// remove all - if anything fails the transaction will rollback
if (contentTypeIds == null || contentTypeIdsA.Length == 0)
@@ -1944,7 +1939,7 @@ WHERE cmsContentXml.nodeId IN (
}
// insert back - if anything fails the transaction will rollback
var query = _uowProvider.SqlContext.Query<IMember>();
var query = scope.SqlContext.Query<IMember>();
if (contentTypeIds != null && contentTypeIdsA.Length > 0)
query = query.WhereIn(x => x.ContentTypeId, contentTypeIdsA); // assume number of ctypes won't blow IN(...)
@@ -1953,7 +1948,7 @@ WHERE cmsContentXml.nodeId IN (
long total;
do
{
var descendants = repository.GetPage(query, pageIndex++, groupSize, out total, "Path", Direction.Ascending, true);
var descendants = _memberRepository.GetPage(query, pageIndex++, groupSize, out total, "Path", Direction.Ascending, true);
var items = descendants.Select(m => new ContentXmlDto { NodeId = m.Id, Xml = EntityXmlSerializer.Serialize(_serviceContext.DataTypeService, _serviceContext.LocalizationService, m).ToDataString() }).ToArray();
db.BulkInsertRecords(items);
processed += items.Length;
@@ -1962,24 +1957,24 @@ WHERE cmsContentXml.nodeId IN (
public bool VerifyContentAndPreviewXml()
{
using (var uow = _uowProvider.CreateUnitOfWork())
using (var scope = _scopeProvider.CreateScope())
{
uow.ReadLock(Constants.Locks.ContentTree);
var ok = VerifyContentAndPreviewXmlLocked(uow);
uow.Complete();
scope.ReadLock(Constants.Locks.ContentTree);
var ok = VerifyContentAndPreviewXmlLocked(scope);
scope.Complete();
return ok;
}
}
// assumes content tree lock
private static bool VerifyContentAndPreviewXmlLocked(IScopeUnitOfWork unitOfWork)
private static bool VerifyContentAndPreviewXmlLocked(IScope scope)
{
// every published content item should have a corresponding row in cmsContentXml
// every content item should have a corresponding row in cmsPreviewXml
// and that row should have the key="..." attribute
var contentObjectType = Constants.ObjectTypes.Document;
var db = unitOfWork.Database;
var db = scope.Database;
var count = db.ExecuteScalar<int>(@"SELECT COUNT(*)
FROM umbracoNode
@@ -2003,25 +1998,24 @@ AND cmsPreviewXml.nodeId IS NULL OR cmsPreviewXml.xml NOT LIKE '% key=""'
public bool VerifyMediaXml()
{
using (var uow = _uowProvider.CreateUnitOfWork())
using (var scope = _scopeProvider.CreateScope())
{
uow.ReadLock(Constants.Locks.MediaTree);
var repository = uow.CreateRepository<IMediaRepository>();
var ok = VerifyMediaXmlLocked(uow, repository);
uow.Complete();
scope.ReadLock(Constants.Locks.MediaTree);
var ok = VerifyMediaXmlLocked(scope);
scope.Complete();
return ok;
}
}
// assumes media tree lock
public bool VerifyMediaXmlLocked(IScopeUnitOfWork unitOfWork, IMediaRepository repository)
public bool VerifyMediaXmlLocked(IScope scope)
{
// every non-trashed media item should have a corresponding row in cmsContentXml
// and that row should have the key="..." attribute
// fixme - where's the trashed test here?
var mediaObjectType = Constants.ObjectTypes.Media;
var db = unitOfWork.Database;
var db = scope.Database;
var count = db.ExecuteScalar<int>(@"SELECT COUNT(*)
FROM umbracoNode
@@ -2036,23 +2030,22 @@ AND cmsContentXml.nodeId IS NULL OR cmsContentXml.xml NOT LIKE '% key=""'
public bool VerifyMemberXml()
{
using (var uow = _uowProvider.CreateUnitOfWork())
using (var scope = _scopeProvider.CreateScope())
{
uow.ReadLock(Constants.Locks.MemberTree);
var repository = uow.CreateRepository<IMemberRepository>();
var ok = VerifyMemberXmlLocked(uow, repository);
uow.Complete();
scope.ReadLock(Constants.Locks.MemberTree);
var ok = VerifyMemberXmlLocked(scope);
scope.Complete();
return ok;
}
}
// assumes member tree lock
public bool VerifyMemberXmlLocked(IScopeUnitOfWork unitOfWork, IMemberRepository repository)
public bool VerifyMemberXmlLocked(IScope scope)
{
// every member item should have a corresponding row in cmsContentXml
var memberObjectType = Constants.ObjectTypes.Member;
var db = unitOfWork.Database;
var db = scope.Database;
var count = db.ExecuteScalar<int>(@"SELECT COUNT(*)
FROM umbracoNode