public static ResponseBase GetCollection(SapphireDbContext db, QueryCommand command, HttpInformation information, IServiceProvider serviceProvider) { SapphireDatabaseOptions sapphireDatabaseOptions = serviceProvider.GetService <SapphireDatabaseOptions>(); if (sapphireDatabaseOptions.DisableIncludePrefilter && command.Prefilters.Any(p => p is IncludePrefilter)) { throw new IncludeNotAllowedException(command.CollectionName); } Type dbContextType = db.GetType(); KeyValuePair <Type, string> property = dbContextType.GetDbSetType(command.CollectionName); if (property.Key == null) { throw new CollectionNotFoundException(command.CollectionName); } if (!property.Key.CanQuery(information, serviceProvider)) { throw new UnauthorizedException("Not allowed to query values from collection"); } IQueryable <object> collectionValues = db.GetCollectionValues(property, command.Prefilters); QueryResponse queryResponse = new QueryResponse() { ReferenceId = command.ReferenceId, }; IAfterQueryPrefilter afterQueryPrefilter = command.Prefilters.OfType <IAfterQueryPrefilter>().FirstOrDefault(); if (afterQueryPrefilter != null) { afterQueryPrefilter.Initialize(property.Key); queryResponse.Result = afterQueryPrefilter.Execute(collectionValues); } else { IEnumerable <object> values = collectionValues.AsEnumerable(); ModelAttributesInfo modelAttributesInfo = property.Key.GetModelAttributesInfo(); if (modelAttributesInfo.QueryEntryAuthAttributes.Any()) { values = values.Where(value => property.Key.CanQueryEntry(information, serviceProvider, value)); } values = values.Select(v => v.GetAuthenticatedQueryModel(information, serviceProvider)); queryResponse.Result = values.ToList(); } return(queryResponse); }
public static ResponseBase GetCollection(SapphireDbContext db, QueryCommand command, HttpInformation information, IServiceProvider serviceProvider) { Type dbContextType = db.GetType(); KeyValuePair <Type, string> property = dbContextType.GetDbSetType(command.CollectionName); if (property.Key != null) { if (!property.Key.CanQuery(information, serviceProvider)) { return(command.CreateExceptionResponse <QueryResponse>( "Not allowed to query values from collection")); } IQueryable <object> collectionValues = db.GetCollectionValues(serviceProvider, information, property, command.Prefilters); QueryResponse queryResponse = new QueryResponse() { ReferenceId = command.ReferenceId, }; IAfterQueryPrefilter afterQueryPrefilter = command.Prefilters.OfType <IAfterQueryPrefilter>().FirstOrDefault(); if (afterQueryPrefilter != null) { afterQueryPrefilter.Initialize(property.Key); queryResponse.Result = afterQueryPrefilter.Execute(collectionValues); } else { IEnumerable <object> values = collectionValues.AsEnumerable(); AuthModelInfo authModelInfo = property.Key.GetAuthModelInfos(); if (authModelInfo.QueryEntryAuthAttributes.Any()) { values = values.Where(value => property.Key.CanQueryEntry(information, serviceProvider, value)); } values = values.Select(v => v.GetAuthenticatedQueryModel(information, serviceProvider)); queryResponse.Result = values.ToList(); } return(queryResponse); } return(command.CreateExceptionResponse <QueryResponse>("No set for collection was found.")); }
public static ResponseBase GetCollection(SapphireDbContext db, IQueryCommand command, KeyValuePair <Type, string> property, List <IPrefilterBase> prefilters, HttpInformation information, IServiceProvider serviceProvider) { if (!property.Key.CanQuery(information, serviceProvider)) { throw new UnauthorizedException("Not allowed to query values from collection"); } IQueryable <object> collectionValues = db.GetCollectionValues(property, prefilters); QueryResponse queryResponse = new QueryResponse() { ReferenceId = command.ReferenceId, }; IAfterQueryPrefilter afterQueryPrefilter = prefilters.OfType <IAfterQueryPrefilter>().FirstOrDefault(); if (afterQueryPrefilter != null) { queryResponse.Result = afterQueryPrefilter.Execute(collectionValues); } else { IEnumerable <object> values = collectionValues.AsEnumerable(); ModelAttributesInfo modelAttributesInfo = property.Key.GetModelAttributesInfo(); if (modelAttributesInfo.QueryEntryAuthAttributes.Any()) { values = values.Where(value => property.Key.CanQueryEntry(information, serviceProvider, value)); } values = values.Select(v => v.GetAuthenticatedQueryModel(information, serviceProvider)); queryResponse.Result = values.ToList(); } return(queryResponse); }
private void HandleReloadOfCollectionData(Type dbContextType, KeyValuePair <Type, string> property, PrefilterContainer prefilterContainer, List <Subscription> equalCollectionSubscriptions, Guid handlingId) { try { if (!prefilterContainer.StartHandling(handlingId)) { return; } SapphireDbContext db = dbContextAccessor.GetContext(dbContextType, serviceProvider); IQueryable <object> collectionValues = db.GetCollectionValues(property, prefilterContainer.Prefilters); IAfterQueryPrefilter afterQueryPrefilter = prefilterContainer.Prefilters.OfType <IAfterQueryPrefilter>().FirstOrDefault(); if (afterQueryPrefilter != null) { afterQueryPrefilter.Initialize(property.Key); object result = afterQueryPrefilter.Execute(collectionValues); Parallel.ForEach(equalCollectionSubscriptions, subscription => { Task.Run(() => { _ = subscription.Connection.Send(new QueryResponse() { ReferenceId = subscription.ReferenceId, Result = result }); }); }); } else { List <object> values = collectionValues.ToList(); Parallel.ForEach(equalCollectionSubscriptions, subscription => { Task.Run(() => { _ = subscription.Connection.Send(new QueryResponse() { ReferenceId = subscription.ReferenceId, Result = values .Where(v => property.Key.CanQueryEntry(subscription.Connection.Information, serviceProvider, v)) .Select(v => v.GetAuthenticatedQueryModel(subscription.Connection.Information, serviceProvider)) .ToList() }); }); }); } } finally { prefilterContainer.FinishHandling(); } }
public void HandleSubscription(CollectionSubscription subscription, Type dbContextType, IServiceProvider requestServiceProvider, ConnectionBase connection, KeyValuePair <Type, string> property, List <ChangeResponse> collectionChanges, List <ChangeResponse> allChanges) { try { bool anyCollectionChanges = collectionChanges.Any(); if ((anyCollectionChanges && subscription.Prefilters.Any(prefilter => prefilter is IAfterQueryPrefilter || prefilter is TakePrefilter || prefilter is SkipPrefilter)) || HasIncludePrefilterWithChange(subscription, allChanges)) { SapphireDbContext db = dbContextAccessor.GetContext(dbContextType, requestServiceProvider); IQueryable <object> collectionValues = db.GetCollectionValues(requestServiceProvider, connection.Information, property, subscription.Prefilters); IAfterQueryPrefilter afterQueryPrefilter = subscription.Prefilters.OfType <IAfterQueryPrefilter>().FirstOrDefault(); if (afterQueryPrefilter != null) { afterQueryPrefilter.Initialize(property.Key); _ = connection.Send(new QueryResponse() { ReferenceId = subscription.ReferenceId, Result = afterQueryPrefilter.Execute(collectionValues) }); } else { _ = connection.Send(new QueryResponse() { ReferenceId = subscription.ReferenceId, Result = collectionValues .AsEnumerable() .Select(v => v.GetAuthenticatedQueryModel(connection.Information, serviceProvider)) .ToList() }); } } else if (anyCollectionChanges) { IEnumerable <WherePrefilter> wherePrefilters = subscription.Prefilters.OfType <WherePrefilter>(); foreach (WherePrefilter wherePrefilter in wherePrefilters) { wherePrefilter.Initialize(property.Key); Func <object, bool> whereFunction = wherePrefilter.WhereExpression.Compile(); collectionChanges = collectionChanges.Where((change) => whereFunction(change.Value)).ToList(); } collectionChanges.ForEach(change => { object value = change.Value.GetAuthenticatedQueryModel(connection.Information, requestServiceProvider); _ = connection.Send(change.CreateResponse(subscription.ReferenceId, value)); }); } } catch (Exception ex) { SubscribeCommand tempErrorCommand = new SubscribeCommand() { CollectionName = subscription.CollectionName, ReferenceId = subscription.ReferenceId, Prefilters = subscription.Prefilters }; _ = connection.Send(tempErrorCommand.CreateExceptionResponse <ResponseBase>(ex)); logger.LogError( $"Error handling subscription '{subscription.ReferenceId}' of {subscription.CollectionName}"); logger.LogError(ex.Message); } }
public void HandleSubscription(CollectionSubscription subscription, Type dbContextType, IServiceProvider requestServiceProvider, ConnectionBase connection, KeyValuePair <Type, string> property, List <ChangeResponse> collectionChanges, List <ChangeResponse> allChanges) { try { bool anyCollectionChanges = collectionChanges.Any(); if ((anyCollectionChanges && subscription.Prefilters.Any(prefilter => prefilter is IAfterQueryPrefilter || prefilter is TakePrefilter || prefilter is SkipPrefilter)) || HasIncludePrefilterWithChange(subscription, allChanges)) { SapphireDbContext db = dbContextAccessor.GetContext(dbContextType, requestServiceProvider); IQueryable <object> collectionValues = db.GetCollectionValues(requestServiceProvider, connection.Information, property, subscription.Prefilters); IAfterQueryPrefilter afterQueryPrefilter = subscription.Prefilters.OfType <IAfterQueryPrefilter>().FirstOrDefault(); if (afterQueryPrefilter != null) { afterQueryPrefilter.Initialize(property.Key); _ = connection.Send(new QueryResponse() { ReferenceId = subscription.ReferenceId, Result = afterQueryPrefilter.Execute(collectionValues) }); } else { _ = connection.Send(new QueryResponse() { ReferenceId = subscription.ReferenceId, Result = collectionValues .AsEnumerable() .Select(v => v.GetAuthenticatedQueryModel(connection.Information, serviceProvider)) .ToList() }); } } else if (anyCollectionChanges) { IEnumerable <WherePrefilter> wherePrefilters = subscription.Prefilters.OfType <WherePrefilter>(); List <ChangeResponse> oldValuesUnloadResponses = new List <ChangeResponse>(); List <ChangeResponse> newValuesLoadResponses = new List <ChangeResponse>(); foreach (WherePrefilter wherePrefilter in wherePrefilters) { wherePrefilter.Initialize(property.Key); // Values that did change know do match the oldValuesUnloadResponses.AddRange( collectionChanges .Where(change => change.State == ChangeResponse.ChangeState.Modified && !wherePrefilter.WhereExpressionCompiled(change.Value) && wherePrefilter.WhereExpressionCompiled(change.OriginalValue)) .Select(change => { ChangeResponse newChangeResponse = change.CreateResponse(null, change.Value); newChangeResponse.State = ChangeResponse.ChangeState.Deleted; return(newChangeResponse); }) ); newValuesLoadResponses.AddRange( collectionChanges .Where(change => change.State == ChangeResponse.ChangeState.Modified && wherePrefilter.WhereExpressionCompiled(change.Value) && !wherePrefilter.WhereExpressionCompiled(change.OriginalValue)) .Select(change => { ChangeResponse newChangeResponse = change.CreateResponse(null, change.Value); newChangeResponse.State = ChangeResponse.ChangeState.Added; return(newChangeResponse); }) ); collectionChanges = collectionChanges .Where((change) => wherePrefilter.WhereExpressionCompiled(change.Value)).ToList(); } IEnumerable <ChangeResponse> changesForWherePrefilter = oldValuesUnloadResponses .Concat(newValuesLoadResponses) .GroupBy(v => v.Value) .Select(g => g.LastOrDefault()); collectionChanges = collectionChanges.Concat(changesForWherePrefilter).ToList(); ChangesResponse changesResponse = new ChangesResponse() { ReferenceId = subscription.ReferenceId, Changes = collectionChanges.Select(change => { object value = change.Value.GetAuthenticatedQueryModel(connection.Information, requestServiceProvider); return(change.CreateResponse(subscription.ReferenceId, value)); }).ToList() }; if (changesResponse.Changes.Any()) { _ = connection.Send(changesResponse); } } } catch (Exception ex) { SubscribeCommand tempErrorCommand = new SubscribeCommand() { CollectionName = subscription.CollectionName, ReferenceId = subscription.ReferenceId, Prefilters = subscription.Prefilters }; _ = connection.Send(tempErrorCommand.CreateExceptionResponse <ResponseBase>(ex)); logger.LogError( $"Error handling subscription '{subscription.ReferenceId}' of {subscription.CollectionName}"); logger.LogError(ex.Message); } }