public IReadOnlyCollection <ResourceFieldAttribute> GetSparseFieldSetForSerializer(ResourceContext resourceContext) { if (!_visitedTable.ContainsKey(resourceContext)) { var inputFields = _lazySourceTable.Value.ContainsKey(resourceContext) ? _lazySourceTable.Value[resourceContext] : GetResourceFields(resourceContext); var inputExpression = new SparseFieldSetExpression(inputFields); var outputExpression = _resourceDefinitionAccessor.OnApplySparseFieldSet(resourceContext.ResourceType, inputExpression); HashSet <ResourceFieldAttribute> outputFields; if (outputExpression == null) { outputFields = GetResourceFields(resourceContext); } else { outputFields = new HashSet <ResourceFieldAttribute>(inputFields); outputFields.IntersectWith(outputExpression.Fields); } _visitedTable[resourceContext] = outputFields; } return(_visitedTable[resourceContext]); }
/// <inheritdoc /> public SparseFieldSetExpression OnApplySparseFieldSet(Type resourceType, SparseFieldSetExpression existingSparseFieldSet) { ArgumentGuard.NotNull(resourceType, nameof(resourceType)); dynamic resourceDefinition = ResolveResourceDefinition(resourceType); return(resourceDefinition.OnApplySparseFieldSet(existingSparseFieldSet)); }
public override SparseFieldSetExpression OnApplySparseFieldSet(SparseFieldSetExpression existingSparseFieldSet) { _hitCounter.TrackInvocation <Lyric>(ResourceDefinitionHitCounter.ExtensibilityPoint.OnApplySparseFieldSet); return(_lyricPermissionProvider.CanViewText ? base.OnApplySparseFieldSet(existingSparseFieldSet) : existingSparseFieldSet.Excluding <Lyric>(lyric => lyric.Text, ResourceGraph)); }
public override SparseFieldSetExpression OnApplySparseFieldSet(SparseFieldSetExpression existingSparseFieldSet) { _lyricPermissionProvider.HitCount++; return(_lyricPermissionProvider.CanViewText ? base.OnApplySparseFieldSet(existingSparseFieldSet) : existingSparseFieldSet.Excluding <Lyric>(lyric => lyric.Text, ResourceGraph)); }
public IDictionary <ResourceFieldAttribute, QueryLayer> GetSecondaryProjectionForRelationshipEndpoint(ResourceContext secondaryResourceContext) { var secondaryIdAttribute = secondaryResourceContext.Attributes.Single(a => a.Property.Name == nameof(Identifiable.Id)); var sparseFieldSet = new SparseFieldSetExpression(new[] { secondaryIdAttribute }); var secondaryProjection = GetSparseFieldSetProjection(new[] { sparseFieldSet }, secondaryResourceContext) ?? new Dictionary <ResourceFieldAttribute, QueryLayer>(); secondaryProjection[secondaryIdAttribute] = null; return(secondaryProjection); }
/// <inheritdoc /> public SparseFieldSetExpression OnApplySparseFieldSet(Type resourceType, SparseFieldSetExpression existingSparseFieldSet) { if (resourceType == null) { throw new ArgumentNullException(nameof(resourceType)); } dynamic resourceDefinition = ResolveResourceDefinition(resourceType); return(resourceDefinition.OnApplySparseFieldSet(existingSparseFieldSet)); }
private IDictionary <ResourceFieldAttribute, QueryLayer> GetProjectionForRelationship(ResourceContext secondaryResourceContext) { var secondaryIdAttribute = GetIdAttribute(secondaryResourceContext); var sparseFieldSet = new SparseFieldSetExpression(new[] { secondaryIdAttribute }); var secondaryProjection = GetSparseFieldSetProjection(new[] { sparseFieldSet }, secondaryResourceContext) ?? new Dictionary <ResourceFieldAttribute, QueryLayer>(); secondaryProjection[secondaryIdAttribute] = null; return(secondaryProjection); }
private SparseFieldSetExpression GetSparseFieldSet(string parameterValue, ResourceContext resourceContext) { SparseFieldSetExpression sparseFieldSet = _sparseFieldSetParser.Parse(parameterValue, resourceContext); if (sparseFieldSet == null) { // We add ID on an incoming empty fieldset, so that callers can distinguish between no fieldset and an empty one. AttrAttribute idAttribute = resourceContext.Attributes.Single(attribute => attribute.Property.Name == nameof(Identifiable.Id)); return(new SparseFieldSetExpression(ArrayFactory.Create(idAttribute))); } return(sparseFieldSet); }
public SparseFieldSetExpression Parse(string source, ResourceContext resourceContext) { ArgumentGuard.NotNull(resourceContext, nameof(resourceContext)); _resourceContext = resourceContext; Tokenize(source); SparseFieldSetExpression expression = ParseSparseFieldSet(); AssertTokenStackIsEmpty(); return(expression); }
/// <inheritdoc /> public virtual void Read(string parameterName, StringValues parameterValue) { _lastParameterName = parameterName; try { ResourceContext targetResource = GetSparseFieldType(parameterName); SparseFieldSetExpression sparseFieldSet = GetSparseFieldSet(parameterValue, targetResource); _sparseFieldTable[targetResource] = sparseFieldSet; } catch (QueryParseException exception) { throw new InvalidQueryStringParameterException(parameterName, "The specified fieldset is invalid.", exception.Message, exception); } }
public IReadOnlyCollection <AttrAttribute> GetIdAttributeSetForRelationshipQuery(ResourceContext resourceContext) { ArgumentGuard.NotNull(resourceContext, nameof(resourceContext)); AttrAttribute idAttribute = resourceContext.Attributes.Single(attr => attr.Property.Name == nameof(Identifiable.Id)); var inputExpression = new SparseFieldSetExpression(idAttribute.AsArray()); // Intentionally not cached, as we are fetching ID only (ignoring any sparse fieldset that came from query string). SparseFieldSetExpression outputExpression = _resourceDefinitionAccessor.OnApplySparseFieldSet(resourceContext.ResourceType, inputExpression); HashSet <AttrAttribute> outputAttributes = outputExpression == null ? new HashSet <AttrAttribute>() : outputExpression.Fields.OfType <AttrAttribute>().ToHashSet(); outputAttributes.Add(idAttribute); return(outputAttributes); }
/// <inheritdoc/> public void Read(string parameterName, StringValues parameterValue) { _lastParameterName = parameterName; try { ResourceFieldChainExpression scope = GetScope(parameterName); SparseFieldSetExpression sparseFieldSet = GetSparseFieldSet(parameterValue, scope); var expressionInScope = new ExpressionInScope(scope, sparseFieldSet); _constraints.Add(expressionInScope); } catch (QueryParseException exception) { throw new InvalidQueryStringParameterException(parameterName, "The specified fieldset is invalid.", exception.Message, exception); } }
/// <inheritdoc /> public QueryLayer WrapLayerForSecondaryEndpoint <TId>(QueryLayer secondaryLayer, ResourceContext primaryResourceContext, TId primaryId, RelationshipAttribute secondaryRelationship) { var innerInclude = secondaryLayer.Include; secondaryLayer.Include = null; var primaryIdAttribute = primaryResourceContext.Attributes.Single(x => x.Property.Name == nameof(Identifiable.Id)); var sparseFieldSet = new SparseFieldSetExpression(new[] { primaryIdAttribute }); var primaryProjection = GetSparseFieldSetProjection(new[] { sparseFieldSet }, primaryResourceContext) ?? new Dictionary <ResourceFieldAttribute, QueryLayer>(); primaryProjection[secondaryRelationship] = secondaryLayer; primaryProjection[primaryIdAttribute] = null; return(new QueryLayer(primaryResourceContext) { Include = RewriteIncludeForSecondaryEndpoint(innerInclude, secondaryRelationship), Filter = CreateFilterById(primaryId, primaryResourceContext), Projection = primaryProjection }); }
public IReadOnlyCollection <ResourceFieldAttribute> GetSparseFieldSetForQuery(ResourceContext resourceContext) { ArgumentGuard.NotNull(resourceContext, nameof(resourceContext)); if (!_visitedTable.ContainsKey(resourceContext)) { SparseFieldSetExpression inputExpression = _lazySourceTable.Value.ContainsKey(resourceContext) ? new SparseFieldSetExpression(_lazySourceTable.Value[resourceContext]) : null; SparseFieldSetExpression outputExpression = _resourceDefinitionAccessor.OnApplySparseFieldSet(resourceContext.ResourceType, inputExpression); HashSet <ResourceFieldAttribute> outputFields = outputExpression == null ? new HashSet <ResourceFieldAttribute>() : outputExpression.Fields.ToHashSet(); _visitedTable[resourceContext] = outputFields; } return(_visitedTable[resourceContext]); }
/// <inheritdoc /> public QueryLayer WrapLayerForSecondaryEndpoint <TId>(QueryLayer secondaryLayer, ResourceContext primaryResourceContext, TId primaryId, RelationshipAttribute secondaryRelationship) { if (secondaryLayer == null) { throw new ArgumentNullException(nameof(secondaryLayer)); } if (primaryResourceContext == null) { throw new ArgumentNullException(nameof(primaryResourceContext)); } if (secondaryRelationship == null) { throw new ArgumentNullException(nameof(secondaryRelationship)); } var innerInclude = secondaryLayer.Include; secondaryLayer.Include = null; var primaryIdAttribute = GetIdAttribute(primaryResourceContext); var sparseFieldSet = new SparseFieldSetExpression(new[] { primaryIdAttribute }); var primaryProjection = GetSparseFieldSetProjection(new[] { sparseFieldSet }, primaryResourceContext) ?? new Dictionary <ResourceFieldAttribute, QueryLayer>(); primaryProjection[secondaryRelationship] = secondaryLayer; primaryProjection[primaryIdAttribute] = null; var primaryFilter = GetFilter(Array.Empty <QueryExpression>(), primaryResourceContext); return(new QueryLayer(primaryResourceContext) { Include = RewriteIncludeForSecondaryEndpoint(innerInclude, secondaryRelationship), Filter = CreateFilterByIds(new[] { primaryId }, primaryIdAttribute, primaryFilter), Projection = primaryProjection }); }
/// <summary> /// Enables to extend, replace or remove a sparse fieldset that is being applied on a set of this resource type. /// Tip: Use <see cref="SparseFieldSetExpressionExtensions.Including{TResource}"/> and <see cref="SparseFieldSetExpressionExtensions.Excluding{TResource}"/> /// to safely change the fieldset without worrying about nulls. /// </summary> /// <remarks> /// This method executes twice for a single request: first to select which fields to retrieve from the data store and then to /// select which fields to serialize. Including extra fields from this method will retrieve them, but not include them in the json output. /// This enables you to expose calculated properties whose value depends on a field that is not in the sparse fieldset. /// </remarks> /// <param name="existingSparseFieldSet">The incoming sparse fieldset from query string. /// At query execution time, this is <c>null</c> if the query string contains no sparse fieldset. /// At serialization time, this contains all viewable fields if the query string contains no sparse fieldset. /// </param> /// <returns> /// The new sparse fieldset, or <c>null</c> to discard the existing sparse fieldset and select all viewable fields. /// </returns> public virtual SparseFieldSetExpression OnApplySparseFieldSet(SparseFieldSetExpression existingSparseFieldSet) { return(existingSparseFieldSet); }
public SparseFieldSetExpression OnApplySparseFieldSet(Type resourceType, SparseFieldSetExpression existingSparseFieldSet) { return(existingSparseFieldSet); }
public SparseFieldSetExpression OnApplySparseFieldSet(SparseFieldSetExpression existingSparseFieldSet) { throw new NotImplementedException(); }