Ensures the deletions are wrapped in a transaction - for performance and to mitigate db corruption if one of the deletes fails.
This commit is contained in:
@@ -25,26 +25,24 @@ namespace Umbraco.Core.Persistence.Repositories
|
|||||||
|
|
||||||
public bool EmptyRecycleBin(Guid nodeObjectType)
|
public bool EmptyRecycleBin(Guid nodeObjectType)
|
||||||
{
|
{
|
||||||
try
|
var db = _unitOfWork.Database;
|
||||||
{
|
|
||||||
var db = _unitOfWork.Database;
|
|
||||||
|
|
||||||
//Issue query to get all trashed content or media that has the Upload field as a property
|
//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>()
|
//The value for each field is stored in a list: FilesToDelete<string>()
|
||||||
//Alias: Constants.Conventions.Media.File and ControlId: Constants.PropertyEditors.UploadField
|
//Alias: Constants.Conventions.Media.File and ControlId: Constants.PropertyEditors.UploadField
|
||||||
var sql = new Sql();
|
var sql = new Sql();
|
||||||
sql.Select("DISTINCT(dataNvarchar)")
|
sql.Select("DISTINCT(dataNvarchar)")
|
||||||
.From<PropertyDataDto>()
|
.From<PropertyDataDto>()
|
||||||
.InnerJoin<NodeDto>().On<PropertyDataDto, NodeDto>(left => left.NodeId, right => right.NodeId)
|
.InnerJoin<NodeDto>().On<PropertyDataDto, NodeDto>(left => left.NodeId, right => right.NodeId)
|
||||||
.InnerJoin<PropertyTypeDto>().On<PropertyDataDto, PropertyTypeDto>(left => left.PropertyTypeId, right => right.Id)
|
.InnerJoin<PropertyTypeDto>().On<PropertyDataDto, PropertyTypeDto>(left => left.PropertyTypeId, right => right.Id)
|
||||||
.InnerJoin<DataTypeDto>().On<PropertyTypeDto, DataTypeDto>(left => left.DataTypeId, right => right.DataTypeId)
|
.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)",
|
.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 });
|
new { FileAlias = Constants.Conventions.Media.File, NodeObjectType = nodeObjectType, ControlId = Constants.PropertyEditors.UploadField });
|
||||||
|
|
||||||
var files = db.Fetch<string>(sql);
|
var files = db.Fetch<string>(sql);
|
||||||
|
|
||||||
//Construct and execute delete statements for all trashed items by 'nodeObjectType'
|
//Construct and execute delete statements for all trashed items by 'nodeObjectType'
|
||||||
var deletes = new List<string>
|
var deletes = new List<string>
|
||||||
{
|
{
|
||||||
FormatDeleteStatement("umbracoUser2NodeNotify", "nodeId"),
|
FormatDeleteStatement("umbracoUser2NodeNotify", "nodeId"),
|
||||||
FormatDeleteStatement("umbracoUser2NodePermission", "nodeId"),
|
FormatDeleteStatement("umbracoUser2NodePermission", "nodeId"),
|
||||||
@@ -61,20 +59,30 @@ namespace Umbraco.Core.Persistence.Repositories
|
|||||||
"DELETE FROM umbracoNode WHERE trashed = '1' AND nodeObjectType = @NodeObjectType"
|
"DELETE FROM umbracoNode WHERE trashed = '1' AND nodeObjectType = @NodeObjectType"
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var delete in deletes)
|
//Wraps in transaction - this improves performance and also ensures
|
||||||
{
|
// that if any of the deletions fails that the whole thing is rolled back.
|
||||||
db.Execute(delete, new { NodeObjectType = nodeObjectType });
|
using (var trans = db.GetTransaction())
|
||||||
}
|
|
||||||
|
|
||||||
//Trigger (internal) event with list of files to delete - RecycleBinEmptied
|
|
||||||
RecycleBinEmptied.RaiseEvent(new RecycleBinEventArgs(nodeObjectType, files), this);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
{
|
||||||
LogHelper.Error<RecycleBinRepository>("An error occurred while emptying the Recycle Bin: " + ex.Message, ex);
|
try
|
||||||
return false;
|
{
|
||||||
|
foreach (var delete in deletes)
|
||||||
|
{
|
||||||
|
db.Execute(delete, new { NodeObjectType = nodeObjectType });
|
||||||
|
}
|
||||||
|
|
||||||
|
trans.Complete();
|
||||||
|
|
||||||
|
//Trigger (internal) event with list of files to delete - RecycleBinEmptied
|
||||||
|
RecycleBinEmptied.RaiseEvent(new RecycleBinEventArgs(nodeObjectType, files), this);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
trans.Dispose();
|
||||||
|
LogHelper.Error<RecycleBinRepository>("An error occurred while emptying the Recycle Bin: " + ex.Message, ex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user