public Task <ResponseBase> Handle(HttpInformation context, DeleteCommand command) { SapphireDbContext db = GetContext(command.ContextName); KeyValuePair <Type, string> property = db.GetType().GetDbSetType(command.CollectionName); if (property.Key != null) { try { object[] primaryKeys = property.Key.GetPrimaryKeyValues(db, command.PrimaryKeys); object value = db.Find(property.Key, primaryKeys); if (!property.Key.CanRemove(context, value, serviceProvider)) { return(Task.FromResult(command.CreateExceptionResponse <DeleteResponse>( "The user is not authorized for this action."))); } if (value != null) { property.Key.ExecuteHookMethods <RemoveEventAttribute>(ModelStoreEventAttributeBase.EventType.Before, value, context, serviceProvider); db.Remove(value); property.Key.ExecuteHookMethods <RemoveEventAttribute>(ModelStoreEventAttributeBase.EventType.BeforeSave, value, context, serviceProvider); db.SaveChanges(); property.Key.ExecuteHookMethods <RemoveEventAttribute>(ModelStoreEventAttributeBase.EventType.After, value, context, serviceProvider); return(Task.FromResult <ResponseBase>(new DeleteResponse() { ReferenceId = command.ReferenceId })); } return(Task.FromResult(command.CreateExceptionResponse <DeleteResponse>("The value was not found."))); } catch (Exception ex) { return(Task.FromResult(command.CreateExceptionResponse <DeleteResponse>(ex))); } } return(Task.FromResult(command.CreateExceptionResponse <DeleteResponse>("No set for collection was found."))); }
public async Task <ResponseBase> Handle(HttpInformation context, InvokeCommand command, ExecutionContext executionContext) { SapphireDbContext db = GetContext(command.ContextName); KeyValuePair <Type, string> property = db.GetType().GetDbSetType(command.CollectionName); if (property.Key == null) { throw new CollectionNotFoundException(command.ContextName, command.CollectionName); } object[] primaryKeys = property.Key.GetPrimaryKeyValues(db, command.PrimaryKeys); object value = db.Find(property.Key, primaryKeys); if (value == null) { throw new ValueNotFoundException(command.ContextName, command.CollectionName, primaryKeys); } MethodInfo methodInfo = ReflectionMethodHelper.GetMethodInfo(property.Key, command.Action); if (methodInfo == null) { throw new MethodNotFoundException(property.Key.Name, command.Action); } if (methodInfo.GetCustomAttribute <InvokableAttribute>() == null) { throw new NotInvokableException(command.ContextName, command.CollectionName, command.Action); } object result = methodInfo.Invoke(value, methodInfo.CreateParameters(context, serviceProvider, command.Parameters, db)); if (result != null) { result = await ActionHelper.HandleAsyncResult(result); } logger.LogInformation("Executed {CollectionName}.{ActionName}. ExecutionId: {ExecutionId}", property.Value, methodInfo.Name, executionContext.Id); return(new InvokeResponse() { ReferenceId = command.ReferenceId, Result = result }); }
private ResponseBase InitializeUpdate(UpdateCommand command, KeyValuePair <Type, string> property, HttpInformation context, SapphireDbContext db) { object updateValue = command.UpdateValue.ToObject(property.Key); if (!property.Key.CanUpdate(context, updateValue, serviceProvider)) { return(command.CreateExceptionResponse <UpdateResponse>("The user is not authorized for this action.")); } object[] primaryKeys = property.Key.GetPrimaryKeyValues(db, updateValue); object value = db.Find(property.Key, primaryKeys); if (value != null) { db.Entry(value).State = EntityState.Detached; return(SaveChangesToDb(property, value, updateValue, db, context, command)); } return(command.CreateExceptionResponse <UpdateResponse>("No value to update was found")); }
private ResponseBase InitializeUpdate(UpdateRangeCommand command, KeyValuePair <Type, string> property, HttpInformation context, SapphireDbContext db) { object[] updateValues = command.UpdateValues.Values <JObject>().Select(newValue => newValue.ToObject(property.Key)).ToArray(); UpdateRangeResponse response = new UpdateRangeResponse { ReferenceId = command.ReferenceId, Results = updateValues.Select(updateValue => { if (!property.Key.CanUpdate(context, updateValue, serviceProvider)) { return(command.CreateExceptionResponse <UpdateResponse>( "The user is not authorized for this action.")); } object[] primaryKeys = property.Key.GetPrimaryKeyValues(db, updateValue); object value = db.Find(property.Key, primaryKeys); if (value != null) { db.Entry(value).State = EntityState.Detached; return(ApplyChangesToDb(property, value, updateValue, db, context)); } return(command.CreateExceptionResponse <UpdateResponse>("No value to update was found")); }).ToList() }; db.SaveChanges(); foreach (object value in updateValues) { property.Key.ExecuteHookMethods <UpdateEventAttribute>(ModelStoreEventAttributeBase.EventType.After, value, context, serviceProvider); } return(response); }
public async Task <ResponseBase> Handle(HttpInformation context, DeleteRangeCommand command, ExecutionContext executionContext) { SapphireDbContext db = GetContext(command.ContextName); KeyValuePair <Type, string> property = db.GetType().GetDbSetType(command.CollectionName); if (property.Key == null) { throw new CollectionNotFoundException(command.ContextName, command.CollectionName); } if (property.Key.GetModelAttributesInfo().DisableDeleteAttribute != null) { throw new OperationDisabledException("Delete", command.ContextName, command.CollectionName); } List <object> removedValues = new List <object>(); DeleteRangeResponse response; bool updateRejected; do { updateRejected = false; response = new DeleteRangeResponse { ReferenceId = command.ReferenceId, Results = command.Values.Select(valuePrimaryKeys => { object[] primaryKeys = property.Key.GetPrimaryKeyValues(db, valuePrimaryKeys); object value = db.Find(property.Key, primaryKeys); if (value == null) { throw new ValueNotFoundException(command.ContextName, command.CollectionName, primaryKeys); } if (value is SapphireOfflineEntity valueOfflineEntity && valuePrimaryKeys.TryGetValue("modifiedOn", out JValue modifiedOn)) { DateTimeOffset commandModifiedOn = modifiedOn.ToObject <DateTimeOffset>(); if (!valueOfflineEntity.ModifiedOn.EqualWithTolerance(commandModifiedOn, db.Database.ProviderName)) { throw new DeleteRejectedException(command.ContextName, command.CollectionName, primaryKeys); } } if (!property.Key.CanDelete(context, value, serviceProvider)) { throw new UnauthorizedException("The user is not authorized for this action"); } int insteadOfExecuteCount = property.Key.ExecuteHookMethods <DeleteEventAttribute>( ModelStoreEventAttributeBase.EventType.InsteadOf, value, null, context, serviceProvider, db); if (insteadOfExecuteCount > 0) { return(new DeleteResponse()); } property.Key.ExecuteHookMethods <DeleteEventAttribute>( ModelStoreEventAttributeBase.EventType.Before, value, null, context, serviceProvider, db); db.Remove(value); property.Key.ExecuteHookMethods <DeleteEventAttribute>( ModelStoreEventAttributeBase.EventType.BeforeSave, value, null, context, serviceProvider, db); removedValues.Add(value); return(new DeleteResponse() { Value = value, ReferenceId = command.ReferenceId }); }).ToList() }; try { db.SaveChanges(); } catch (DbUpdateConcurrencyException) { foreach (EntityEntry entityEntry in db.ChangeTracker.Entries()) { await entityEntry.ReloadAsync(); } updateRejected = true; } } while (updateRejected); foreach (object value in removedValues) { property.Key.ExecuteHookMethods <DeleteEventAttribute>( ModelStoreEventAttributeBase.EventType.After, value, null, context, serviceProvider, db); } return(response); } }
private async Task <ResponseBase> InitializeUpdate(UpdateRangeCommand command, KeyValuePair <Type, string> property, HttpInformation context, SapphireDbContext db) { bool updateRejected; List <ValidatedResponseBase> updateResults; do { updateRejected = false; updateResults = command.Entries.Select <UpdateEntry, ValidatedResponseBase>((updateEntry) => { object[] primaryKeys = property.Key.GetPrimaryKeyValuesFromJson(db, updateEntry.Value); object dbValue = db.Find(property.Key, primaryKeys); if (dbValue == null) { if (property.Key.JsonContainsData(db, updateEntry.Value)) { updateEntry.Value.Merge(updateEntry.UpdatedProperties); object completeValue = updateEntry.Value.ToObject(property.Key); return(CreateRangeCommandHandler.SetPropertiesAndValidate <UpdateEventAttribute>(db, property, completeValue, context, serviceProvider)); } throw new ValueNotFoundException(command.ContextName, command.CollectionName, primaryKeys); } if (!property.Key.CanUpdate(context, dbValue, serviceProvider)) { throw new UnauthorizedException("The user is not authorized for this action."); } return(ApplyChangesToDb(command, property, dbValue, updateEntry.Value, updateEntry.UpdatedProperties, db, context)); }).ToList(); try { db.SaveChanges(); } catch (DbUpdateConcurrencyException) { foreach (EntityEntry entityEntry in db.ChangeTracker.Entries()) { await entityEntry.ReloadAsync(); } updateRejected = true; } } while (updateRejected); foreach (ValidatedResponseBase response in updateResults) { if (response.Value != null) { property.Key.ExecuteHookMethods <UpdateEventAttribute>(ModelStoreEventAttributeBase.EventType.After, response.Value, null, context, serviceProvider); } } return(new UpdateRangeResponse { ReferenceId = command.ReferenceId, Results = updateResults }); }
public async Task <ResponseBase> Handle(HttpInformation context, DeleteRangeCommand command) { SapphireDbContext db = GetContext(command.ContextName); KeyValuePair <Type, string> property = db.GetType().GetDbSetType(command.CollectionName); if (property.Key != null) { try { List <object> removedValues = new List <object>(); DeleteRangeResponse response; bool updateRejected; do { updateRejected = false; response = new DeleteRangeResponse { ReferenceId = command.ReferenceId, Results = command.Values.Select(valuePrimaryKeys => { object[] primaryKeys = property.Key.GetPrimaryKeyValues(db, valuePrimaryKeys); object value = db.Find(property.Key, primaryKeys); if (value != null) { if (value is SapphireOfflineEntity valueOfflineEntity && valuePrimaryKeys.TryGetValue("modifiedOn", out JValue modifiedOn)) { DateTime commandModifiedOn = modifiedOn.ToObject <DateTime>(); if (valueOfflineEntity.ModifiedOn.RoundToMilliseconds() != commandModifiedOn.RoundToMilliseconds()) { return((DeleteResponse)command.CreateExceptionResponse <DeleteResponse>( "Deletion rejected. The object state has changed.")); } } if (!property.Key.CanRemove(context, value, serviceProvider)) { return((DeleteResponse)command.CreateExceptionResponse <DeleteResponse>( "The user is not authorized for this action.")); } property.Key.ExecuteHookMethods <RemoveEventAttribute>( ModelStoreEventAttributeBase.EventType.Before, value, context, serviceProvider); db.Remove(value); property.Key.ExecuteHookMethods <RemoveEventAttribute>( ModelStoreEventAttributeBase.EventType.BeforeSave, value, context, serviceProvider); removedValues.Add(value); return(new DeleteResponse() { Value = value, ReferenceId = command.ReferenceId }); } return((DeleteResponse)command.CreateExceptionResponse <DeleteResponse>( "The value was not found.")); }).ToList() }; try { db.SaveChanges(); } catch (DbUpdateConcurrencyException) { foreach (EntityEntry entityEntry in db.ChangeTracker.Entries()) { await entityEntry.ReloadAsync(); } updateRejected = true; } } while (updateRejected); foreach (object value in removedValues) { property.Key.ExecuteHookMethods <RemoveEventAttribute>( ModelStoreEventAttributeBase.EventType.After, value, context, serviceProvider); } return(response); } catch (Exception ex) { return(command.CreateExceptionResponse <DeleteResponse>(ex)); } } return(command.CreateExceptionResponse <DeleteResponse>("No set for collection was found.")); }
private async Task <ResponseBase> InitializeUpdate(UpdateRangeCommand command, KeyValuePair <Type, string> property, HttpInformation context, SapphireDbContext db) { List <object> updateValues = command.Entries.Select(e => e.Value) .Select(newValue => newValue.ToObject(property.Key)) .ToList(); UpdateRangeResponse response; bool updateRejected; do { updateRejected = false; response = new UpdateRangeResponse { ReferenceId = command.ReferenceId, Results = updateValues.Select((updateValue, index) => { if (!property.Key.CanUpdate(context, updateValue, serviceProvider)) { return((UpdateResponse)command.CreateExceptionResponse <UpdateResponse>( "The user is not authorized for this action.")); } object[] primaryKeys = property.Key.GetPrimaryKeyValues(db, updateValue); object value = db.Find(property.Key, primaryKeys); if (value != null) { object previousValue = command.Entries[index].Previous?.ToObject(property.Key); return(ApplyChangesToDb(property, value, updateValue, previousValue, db, context)); } return((ValidatedResponseBase)CreateRangeCommandHandler .SetPropertiesAndValidate <UpdateEventAttribute>(db, property, updateValue, context, serviceProvider)); }).ToList() }; try { db.SaveChanges(); } catch (DbUpdateConcurrencyException) { foreach (EntityEntry entityEntry in db.ChangeTracker.Entries()) { await entityEntry.ReloadAsync(); } updateRejected = true; } } while (updateRejected); foreach (object value in updateValues) { property.Key.ExecuteHookMethods <UpdateEventAttribute>(ModelStoreEventAttributeBase.EventType.After, value, context, serviceProvider); } return(response); }