-
-
Notifications
You must be signed in to change notification settings - Fork 154
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add
MaxDepth
for recursive queries
- Loading branch information
1 parent
09f409b
commit ad6ab87
Showing
29 changed files
with
662 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
22 changes: 22 additions & 0 deletions
22
src/Riok.Mapperly.Abstractions/MapperMaxRecursionDepthAttribute.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
namespace Riok.Mapperly.Abstractions; | ||
|
||
/// <summary> | ||
/// Defines the maximum recursion depth that an IQueryable mapping will use. | ||
/// </summary> | ||
[AttributeUsage(AttributeTargets.Method)] | ||
public sealed class MapperMaxRecursionDepthAttribute : Attribute | ||
{ | ||
/// <summary> | ||
/// Defines the maximum recursion depth that an IQueryable mapping will use. | ||
/// </summary> | ||
/// <param name="maxRecursionDepth">The maximum recursion depth used when mapping IQueryable members.</param> | ||
public MapperMaxRecursionDepthAttribute(int maxRecursionDepth) | ||
{ | ||
MaxRecursionDepth = maxRecursionDepth; | ||
} | ||
|
||
/// <summary> | ||
/// The maximum recursion depth used when mapping IQueryable members. | ||
/// </summary> | ||
public int MaxRecursionDepth { get; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
42 changes: 42 additions & 0 deletions
42
src/Riok.Mapperly/Descriptors/MappingRecursionDepthTracker.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
using System.Collections.Immutable; | ||
|
||
namespace Riok.Mapperly.Descriptors; | ||
|
||
/// <summary> | ||
/// Immutable wrapper for <see cref="ImmutableDictionary<TypeMappingKey, int>"/> which tracks the parent types for a mapping. | ||
/// Used to detect self referential loops. | ||
/// </summary> | ||
/// <param name="parentTypes">Dictionary tracking how many times a type has been seen.</param> | ||
public readonly struct MappingRecursionDepthTracker(ImmutableDictionary<TypeMappingKey, int> parentTypes) | ||
{ | ||
/// <summary> | ||
/// Increments how many times a <see cref="TypeMappingKey"/> has been mapped. | ||
/// Used to track how many times a parent context has mapped a type. | ||
/// </summary> | ||
/// <param name="typeMappingKey">The mapped type.</param> | ||
/// <returns>A new <see cref="MappingRecursionDepthTracker"/> with the updated key.</returns> | ||
public MappingRecursionDepthTracker AddOrIncrement(TypeMappingKey typeMappingKey) | ||
{ | ||
var mappingRecursionCount = parentTypes.GetValueOrDefault(typeMappingKey); | ||
var newParentTypes = parentTypes.SetItem(typeMappingKey, mappingRecursionCount + 1); | ||
return new(newParentTypes); | ||
} | ||
|
||
/// <summary> | ||
/// Gets the number of times a <see cref="TypeMappingKey"/> has been mapped by the parent contexts. | ||
/// </summary> | ||
/// <param name="typeMappingKey">The candidate mapping.</param> | ||
/// <returns>The number of times the <see cref="TypeMappingKey"/> has been mapped.</returns> | ||
public int GetDepth(TypeMappingKey typeMappingKey) => parentTypes.GetValueOrDefault(typeMappingKey); | ||
|
||
/// <summary> | ||
/// Creates a new <see cref="MappingRecursionDepthTracker"/> containing the initial type mapping. | ||
/// </summary> | ||
/// <param name="mappingKey">Initial <see cref="TypeMappingKey"/> value.</param> | ||
/// <returns>A <see cref="MappingRecursionDepthTracker"/> containing the initial type mapping.</returns> | ||
public static MappingRecursionDepthTracker Create(TypeMappingKey mappingKey) | ||
{ | ||
var dict = ImmutableDictionary<TypeMappingKey, int>.Empty; | ||
return new(dict.Add(mappingKey, 1)); | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
src/Riok.Mapperly/Descriptors/Mappings/DefaultMemberMapping.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CSharp.Syntax; | ||
using static Riok.Mapperly.Emit.Syntax.SyntaxFactoryHelper; | ||
|
||
namespace Riok.Mapperly.Descriptors.Mappings; | ||
|
||
/// <summary> | ||
/// Represents a mapping that returns default. | ||
/// <code> | ||
/// target = default; | ||
/// </code> | ||
/// </summary> | ||
public class DefaultMemberMapping(ITypeSymbol sourceType, ITypeSymbol targetType) : NewInstanceMapping(sourceType, targetType) | ||
{ | ||
public override ExpressionSyntax Build(TypeMappingBuildContext ctx) => DefaultLiteral(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.