PageRenderTime 56ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/Serenity.Services/RequestHandlers/Delete/DeleteRequestHandler.cs

https://gitlab.com/pgksunilkumar/Serenity
C# | 262 lines | 214 code | 48 blank | 0 comment | 35 complexity | da410c82e347ea68b72760bb5332cbd1 MD5 | raw file
  1. using Serenity.Data;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Data;
  5. using System.Globalization;
  6. using System.Linq;
  7. using System.Reflection;
  8. namespace Serenity.Services
  9. {
  10. public class DeleteRequestHandler<TRow, TDeleteRequest, TDeleteResponse> : IDeleteRequestHandler, IDeleteRequestProcessor
  11. where TRow : Row, IIdRow, new()
  12. where TDeleteRequest: DeleteRequest
  13. where TDeleteResponse : DeleteResponse, new()
  14. {
  15. protected TRow Row;
  16. protected TDeleteResponse Response;
  17. protected TDeleteRequest Request;
  18. protected static IEnumerable<IDeleteBehavior> cachedBehaviors;
  19. protected IEnumerable<IDeleteBehavior> behaviors;
  20. public DeleteRequestHandler()
  21. {
  22. this.StateBag = new Dictionary<string, object>();
  23. this.behaviors = GetBehaviors();
  24. }
  25. protected virtual IEnumerable<IDeleteBehavior> GetBehaviors()
  26. {
  27. if (cachedBehaviors == null)
  28. {
  29. cachedBehaviors = RowDeleteBehaviors<TRow>.Default.Concat(
  30. this.GetType().GetCustomAttributes().OfType<IDeleteBehavior>()).ToList();
  31. }
  32. return cachedBehaviors;
  33. }
  34. public IDbConnection Connection
  35. {
  36. get { return UnitOfWork.Connection; }
  37. }
  38. protected virtual void OnBeforeDelete()
  39. {
  40. foreach (var behavior in behaviors)
  41. behavior.OnBeforeDelete(this);
  42. }
  43. protected virtual BaseCriteria GetDisplayOrderFilter()
  44. {
  45. return DisplayOrderFilterHelper.GetDisplayOrderFilterFor(Row);
  46. }
  47. protected virtual void OnAfterDelete()
  48. {
  49. var displayOrderRow = Row as IDisplayOrderRow;
  50. if (displayOrderRow != null)
  51. {
  52. var filter = GetDisplayOrderFilter();
  53. DisplayOrderHelper.ReorderValues(Connection, displayOrderRow, filter, -1, 1, false);
  54. }
  55. foreach (var behavior in behaviors)
  56. behavior.OnAfterDelete(this);
  57. }
  58. protected virtual void ValidateRequest()
  59. {
  60. foreach (var behavior in behaviors)
  61. behavior.OnValidateRequest(this);
  62. }
  63. protected virtual void PrepareQuery(SqlQuery query)
  64. {
  65. query.SelectTableFields();
  66. foreach (var behavior in behaviors)
  67. behavior.OnPrepareQuery(this, query);
  68. }
  69. protected virtual void LoadEntity()
  70. {
  71. var idField = (Field)Row.IdField;
  72. var id = idField.ConvertValue(Request.EntityId, CultureInfo.InvariantCulture);
  73. var query = new SqlQuery()
  74. .Dialect(Connection.GetDialect())
  75. .From(Row)
  76. .WhereEqual(idField, id);
  77. PrepareQuery(query);
  78. if (!query.GetFirst(Connection))
  79. throw DataValidation.EntityNotFoundError(Row, Request.EntityId);
  80. }
  81. protected virtual void ExecuteDelete()
  82. {
  83. var isDeletedRow = Row as IIsActiveDeletedRow;
  84. var deleteLogRow = Row as IDeleteLogRow;
  85. var idField = (Field)Row.IdField;
  86. var id = idField.ConvertValue(Request.EntityId, CultureInfo.InvariantCulture);
  87. if (isDeletedRow == null && deleteLogRow == null)
  88. {
  89. if (new SqlDelete(Row.Table)
  90. .WhereEqual(idField, id)
  91. .Execute(Connection) != 1)
  92. throw DataValidation.EntityNotFoundError(Row, id);
  93. }
  94. else
  95. {
  96. if (isDeletedRow != null)
  97. {
  98. var updateLogRow = Row as IUpdateLogRow;
  99. var update = new SqlUpdate(Row.Table)
  100. .Set(isDeletedRow.IsActiveField, -1)
  101. .WhereEqual(idField, id)
  102. .Where(new Criteria(isDeletedRow.IsActiveField) >= 0);
  103. if (deleteLogRow != null)
  104. {
  105. update.Set(deleteLogRow.DeleteDateField, DateTimeField.ToDateTimeKind(DateTime.Now,
  106. deleteLogRow.DeleteDateField.DateTimeKind))
  107. .Set((Field)deleteLogRow.DeleteUserIdField, Authorization.UserId.TryParseID());
  108. }
  109. else if (updateLogRow != null)
  110. {
  111. update.Set(updateLogRow.UpdateDateField, DateTimeField.ToDateTimeKind(DateTime.Now,
  112. updateLogRow.UpdateDateField.DateTimeKind))
  113. .Set((Field)updateLogRow.UpdateUserIdField, Authorization.UserId.TryParseID());
  114. }
  115. if (update.Execute(Connection) != 1)
  116. throw DataValidation.EntityNotFoundError(Row, id);
  117. }
  118. else //if (deleteLogRow != null)
  119. {
  120. if (new SqlUpdate(Row.Table)
  121. .Set(deleteLogRow.DeleteDateField, DateTimeField.ToDateTimeKind(DateTime.Now,
  122. deleteLogRow.DeleteDateField.DateTimeKind))
  123. .Set((Field)deleteLogRow.DeleteUserIdField, Authorization.UserId.TryParseID())
  124. .WhereEqual(idField, id)
  125. .Where(new Criteria((Field)deleteLogRow.DeleteUserIdField).IsNull())
  126. .Execute(Connection) != 1)
  127. throw DataValidation.EntityNotFoundError(Row, id);
  128. }
  129. }
  130. InvalidateCacheOnCommit();
  131. }
  132. protected virtual void InvalidateCacheOnCommit()
  133. {
  134. var attr = typeof(TRow).GetCustomAttribute<TwoLevelCachedAttribute>(false);
  135. if (attr != null)
  136. {
  137. BatchGenerationUpdater.OnCommit(this.UnitOfWork, Row.GetFields().GenerationKey);
  138. foreach (var key in attr.GenerationKeys)
  139. BatchGenerationUpdater.OnCommit(this.UnitOfWork, key);
  140. }
  141. }
  142. protected virtual void DoAudit()
  143. {
  144. foreach (var behavior in behaviors)
  145. behavior.OnAudit(this);
  146. }
  147. protected virtual void OnReturn()
  148. {
  149. foreach (var behavior in behaviors)
  150. behavior.OnReturn(this);
  151. }
  152. protected virtual void ValidatePermissions()
  153. {
  154. var attr = (PermissionAttributeBase)typeof(TRow).GetCustomAttribute<DeletePermissionAttribute>(false) ??
  155. typeof(TRow).GetCustomAttribute<ModifyPermissionAttribute>(false);
  156. if (attr != null)
  157. {
  158. if (attr.Permission.IsNullOrEmpty())
  159. Authorization.ValidateLoggedIn();
  160. else
  161. Authorization.ValidatePermission(attr.Permission);
  162. }
  163. }
  164. public TDeleteResponse Process(IUnitOfWork unitOfWork, TDeleteRequest request)
  165. {
  166. StateBag.Clear();
  167. if (unitOfWork == null)
  168. throw new ArgumentNullException("unitOfWork");
  169. ValidatePermissions();
  170. UnitOfWork = unitOfWork;
  171. Request = request;
  172. Response = new TDeleteResponse();
  173. if (request.EntityId == null)
  174. throw DataValidation.RequiredError("EntityId");
  175. Row = new TRow();
  176. var idField = (Field)Row.IdField;
  177. LoadEntity();
  178. ValidateRequest();
  179. var isDeletedRow = Row as IIsActiveDeletedRow;
  180. var deleteLogRow = Row as IDeleteLogRow;
  181. if ((isDeletedRow != null &&
  182. isDeletedRow.IsActiveField[Row] < 0) ||
  183. (deleteLogRow != null &&
  184. !((Field)deleteLogRow.DeleteUserIdField).IsNull(Row)))
  185. Response.WasAlreadyDeleted = true;
  186. else
  187. {
  188. OnBeforeDelete();
  189. ExecuteDelete();
  190. OnAfterDelete();
  191. DoAudit();
  192. }
  193. OnReturn();
  194. return Response;
  195. }
  196. DeleteResponse IDeleteRequestProcessor.Process(IUnitOfWork uow, DeleteRequest request)
  197. {
  198. return Process(uow, (TDeleteRequest)request);
  199. }
  200. public IUnitOfWork UnitOfWork { get; protected set; }
  201. DeleteRequest IDeleteRequestHandler.Request { get { return this.Request; } }
  202. DeleteResponse IDeleteRequestHandler.Response { get { return this.Response; } }
  203. Row IDeleteRequestHandler.Row { get { return this.Row; } }
  204. public IDictionary<string, object> StateBag { get; private set; }
  205. }
  206. public class DeleteRequestHandler<TRow> : DeleteRequestHandler<TRow, DeleteRequest, DeleteResponse>
  207. where TRow : Row, IIdRow, new()
  208. {
  209. }
  210. public interface IDeleteRequestProcessor
  211. {
  212. DeleteResponse Process(IUnitOfWork uow, DeleteRequest request);
  213. }
  214. }