Initial work on U4-2571 Need to optimize empty recycle bin

This commit is contained in:
Morten Christensen
2013-08-06 15:08:05 +02:00
parent 08609a887c
commit 79141ef86d
7 changed files with 108 additions and 4 deletions

View File

@@ -483,6 +483,12 @@ namespace Umbraco.Core.Persistence.Repositories
return GetByVersion(dto.ContentVersionDto.VersionId);
}
public bool EmptyRecycleBin()
{
var repo = new RecycleBinRepository(UnitOfWork);
return repo.EmptyRecycleBin(NodeObjectTypeId);
}
#endregion
/// <summary>

View File

@@ -20,5 +20,11 @@ namespace Umbraco.Core.Persistence.Repositories
/// <param name="query">Query to execute against published versions</param>
/// <returns>An enumerable list of <see cref="IContent"/></returns>
IEnumerable<IContent> GetByPublishedVersion(IQuery<IContent> query);
/// <summary>
/// Empties the Recycle Bin for deleted Content
/// </summary>
/// <returns><c>True</c> if the Recycle Bin was successfully emptied and all items deleted otherwise <c>False</c></returns>
bool EmptyRecycleBin();
}
}

View File

@@ -4,6 +4,10 @@ namespace Umbraco.Core.Persistence.Repositories
{
public interface IMediaRepository : IRepositoryVersionable<int, IMedia>
{
/// <summary>
/// Empties the Recycle Bin for media Content
/// </summary>
/// <returns><c>True</c> if the Recycle Bin was successfully emptied and all items deleted otherwise <c>False</c></returns>
bool EmptyRecycleBin();
}
}

View File

@@ -356,6 +356,16 @@ namespace Umbraco.Core.Persistence.Repositories
#endregion
#region Implementation of IMediaRepository
public bool EmptyRecycleBin()
{
var repo = new RecycleBinRepository(UnitOfWork);
return repo.EmptyRecycleBin(NodeObjectTypeId);
}
#endregion
private PropertyCollection GetPropertyCollection(int id, Guid versionId, IMediaType contentType, DateTime createDate, DateTime updateDate)
{
var sql = new Sql();

View File

@@ -0,0 +1,80 @@
using System;
using System.Collections.Generic;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Persistence.Repositories
{
internal class RecycleBinRepository
{
private readonly IDatabaseUnitOfWork _unitOfWork;
public RecycleBinRepository(IDatabaseUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public bool EmptyRecycleBin(Guid nodeObjectType)
{
try
{
var db = _unitOfWork.Database;
//Issue query to get all trashed content or media that has the Upload field as a property
//The value for each field is stored in a list: FilesToDelete<string>()
//Alias: Constants.Conventions.Media.File and ControlId: Constants.PropertyEditors.UploadField
var sql = new Sql();
sql.Select("DISTINCT(dataNvarchar)")
.From<PropertyDataDto>()
.InnerJoin<NodeDto>().On<PropertyDataDto, NodeDto>(left => left.NodeId, right => right.NodeId)
.InnerJoin<PropertyTypeDto>().On<PropertyDataDto, PropertyTypeDto>(left => left.PropertyTypeId, right => right.Id)
.InnerJoin<DataTypeDto>().On<PropertyTypeDto, DataTypeDto>(left => left.DataTypeId, right => right.DataTypeId)
.Where("umbracoNode.trashed = '1' AND umbracoNode.nodeObjectType = @NodeObjectType AND dataNvarchar IS NOT NULL AND (cmsPropertyType.Alias = @FileAlias OR cmsDataType.controlId = @ControlId)",
new { FileAlias = Constants.Conventions.Media.File, NodeObjectType = nodeObjectType, ControlId = Constants.PropertyEditors.UploadField });
var files = db.Fetch<string>(sql);
//Construct and execute delete statements for all trashed items by 'nodeObjectType'
var deletes = new List<string>
{
FormatDeleteStatement("umbracoUser2NodeNotify", "nodeId"),
FormatDeleteStatement("umbracoUser2NodePermission", "nodeId"),
FormatDeleteStatement("umbracoRelation", "parentId"),
FormatDeleteStatement("umbracoRelation", "childId"),
FormatDeleteStatement("cmsTagRelationship", "nodeId"),
FormatDeleteStatement("umbracoDomains", "domainRootStructureID"),
FormatDeleteStatement("cmsDocument", "NodeId"),
FormatDeleteStatement("cmsPropertyData", "contentNodeId"),
FormatDeleteStatement("cmsPreviewXml", "nodeId"),
FormatDeleteStatement("cmsContentVersion", "ContentId"),
FormatDeleteStatement("cmsContentXml", "nodeID"),
FormatDeleteStatement("cmsContent", "NodeId"),
"DELETE FROM umbracoNode WHERE trashed = '1' AND nodeObjectType = @NodeObjectType"
};
foreach (var delete in deletes)
{
db.Execute(delete, new { NodeObjectType = nodeObjectType });
}
//Trigger (internal) event with list of files to delete - RecycleBinEmptied
return true;
}
catch (Exception ex)
{
LogHelper.Error<RecycleBinRepository>("An error occurred while emptying the Recycle Bin: " + ex.Message, ex);
return false;
}
}
private string FormatDeleteStatement(string tableName, string keyName)
{
return
string.Format(
"DELETE FROM {0} FROM {0} as TB1 INNER JOIN umbracoNode as TB2 ON TB1.{1} = TB2.id WHERE TB2.trashed = '1' AND TB2.nodeObjectType = @NodeObjectType",
tableName, keyName);
}
}
}

View File

@@ -497,6 +497,7 @@
<Compile Include="Persistence\Repositories\MediaTypeRepository.cs" />
<Compile Include="Persistence\Repositories\PermissionRepository.cs" />
<Compile Include="Persistence\Repositories\PetaPocoRepositoryBase.cs" />
<Compile Include="Persistence\Repositories\RecycleBinRepository.cs" />
<Compile Include="Persistence\Repositories\RelationRepository.cs" />
<Compile Include="Persistence\Repositories\RelationTypeRepository.cs" />
<Compile Include="Persistence\Repositories\RepositoryBase.cs" />

View File

@@ -162,7 +162,4 @@ Global
{73529637-28F5-419C-A6BB-D094E39DE614} = {DD32977B-EF54-475B-9A1B-B97A502C6E58}
{B555AAE6-0F56-442F-AC9F-EF497DB38DE7} = {DD32977B-EF54-475B-9A1B-B97A502C6E58}
EndGlobalSection
GlobalSection(Performance) = preSolution
HasPerformanceSessions = true
EndGlobalSection
EndGlobal