Skip to content

Commit 64271ef

Browse files
committed
fix: collection responses
1 parent 21fced6 commit 64271ef

File tree

9 files changed

+132
-174
lines changed

9 files changed

+132
-174
lines changed

Intersect.Server.Core/Collections/Sorting/Sort.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44
public partial struct Sort
55
{
66

7-
public string By { get; set; }
7+
public string[] By { get; set; }
88

99
public SortDirection Direction { get; set; }
1010

1111
public static Sort From(string sortBy, SortDirection sortDirection)
1212
{
1313
return new Sort
1414
{
15-
By = sortBy,
15+
By = [sortBy],
1616
Direction = sortDirection
1717
};
1818
}

Intersect.Server.Core/Extensions/EnumerableExtensions.cs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,42 +10,40 @@ public static partial class EnumerableExtensions
1010

1111
public static IEnumerable<TValue> Sort<TValue>(
1212
this IEnumerable<TValue> queryable,
13-
IReadOnlyCollection<Sort> sort
13+
IReadOnlyCollection<Sort> sorts
1414
)
1515
{
16-
if (sort == null || sort.Count < 1)
16+
if (sorts == null || sorts.Count < 1)
1717
{
1818
return queryable;
1919
}
2020

2121
var sorted = queryable;
2222
var orderedOnce = false;
23-
foreach (var sortPair in sort)
23+
foreach (var (by, direction) in sorts.SelectMany(sort => sort.By.Select(by => (by, sort.Direction))))
2424
{
25-
if (string.IsNullOrWhiteSpace(sortPair.By))
25+
if (string.IsNullOrWhiteSpace(by))
2626
{
2727
continue;
2828
}
2929

30-
object OrderLambda(TValue entity)
31-
{
32-
return EF.Property<object>(entity, sortPair.By);
33-
}
34-
35-
if (sortPair.Direction == SortDirection.Ascending)
30+
if (direction == SortDirection.Ascending)
3631
{
3732
sorted = orderedOnce
38-
? ((IOrderedEnumerable<TValue>) sorted).ThenBy(OrderLambda)
33+
? ((IOrderedEnumerable<TValue>)sorted).ThenBy(OrderLambda)
3934
: sorted.OrderBy(OrderLambda);
4035
}
4136
else
4237
{
4338
sorted = orderedOnce
44-
? ((IOrderedEnumerable<TValue>) sorted).ThenByDescending(OrderLambda)
39+
? ((IOrderedEnumerable<TValue>)sorted).ThenByDescending(OrderLambda)
4540
: sorted.OrderByDescending(OrderLambda);
4641
}
4742

4843
orderedOnce = true;
44+
continue;
45+
46+
object OrderLambda(TValue entity) => EF.Property<object>(entity, by);
4947
}
5048

5149
return sorted;

Intersect.Server.Core/Extensions/QueryableExtensions.cs

Lines changed: 6 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -10,39 +10,11 @@ namespace Intersect.Server.Extensions;
1010
public static partial class QueryableExtensions
1111
{
1212

13-
public static IQueryable<TValue> Sort<TValue>(
14-
this IQueryable<TValue> queryable,
15-
IReadOnlyCollection<Sort> sort
16-
)
17-
{
18-
return DoSort(queryable, sort);
19-
}
20-
2113
public static bool IsOrdered<TValue>(this IQueryable<TValue> queryable)
2214
{
2315
return queryable.Expression.Type == typeof(IOrderedQueryable<TValue>);
2416
}
2517

26-
public static IOrderedQueryable<TValue> SmartOrderBy<TValue>(
27-
this IQueryable<TValue> queryable,
28-
Sort sort
29-
)
30-
{
31-
return sort.Direction == SortDirection.Ascending
32-
? queryable.OrderBy(entity => EF.Property<object>(entity, sort.By))
33-
: queryable.OrderByDescending(entity => EF.Property<object>(entity, sort.By));
34-
}
35-
36-
public static IOrderedQueryable<TValue> SmartThenBy<TValue>(
37-
this IOrderedQueryable<TValue> queryable,
38-
Sort sort
39-
)
40-
{
41-
return sort.Direction == SortDirection.Ascending
42-
? queryable.ThenBy(entity => EF.Property<object>(entity, sort.By))
43-
: queryable.ThenByDescending(entity => EF.Property<object>(entity, sort.By));
44-
}
45-
4618
public static IQueryable<TValue> SmartSort<TValue>(this IQueryable<TValue> queryable, Sort sort)
4719
{
4820
return sort.Direction == SortDirection.Ascending
@@ -55,61 +27,20 @@ public static IQueryable<TValue> SmartSortAscending<TValue>(
5527
Sort sort
5628
)
5729
{
58-
return queryable.IsOrdered()
59-
? (queryable as IOrderedQueryable<TValue>)?.ThenBy(entity => EF.Property<object>(entity, sort.By))
60-
: queryable.OrderBy(entity => EF.Property<object>(entity, sort.By));
30+
return queryable is IOrderedQueryable<TValue> orderedQueryable
31+
? orderedQueryable.ThenBy(entity => EF.Property<object>(entity, sort.By.First()))
32+
: queryable.OrderBy(entity => EF.Property<object>(entity, sort.By.First()));
6133
}
6234

6335
public static IQueryable<TValue> SmartSortDescending<TValue>(
6436
this IQueryable<TValue> queryable,
6537
Sort sort
6638
)
6739
{
68-
return queryable.IsOrdered()
69-
? (queryable as IOrderedQueryable<TValue>)?.ThenByDescending(
70-
entity => EF.Property<object>(entity, sort.By)
71-
)
72-
: queryable.OrderByDescending(entity => EF.Property<object>(entity, sort.By));
73-
}
74-
75-
public static IQueryable<TValue> DoSort<TValue>(
76-
IQueryable<TValue> queryable,
77-
IReadOnlyCollection<Sort> sort
78-
)
79-
{
80-
if (sort == null || sort.Count < 1)
81-
{
82-
return queryable;
83-
}
84-
85-
var sorted = queryable;
86-
var orderedOnce = false;
87-
foreach (var sortPair in sort)
88-
{
89-
if (string.IsNullOrWhiteSpace(sortPair.By))
90-
{
91-
continue;
92-
}
93-
94-
Expression<Func<TValue, object>> orderLambda = entity => EF.Property<object>(entity, sortPair.By);
95-
96-
if (sortPair.Direction == SortDirection.Ascending)
97-
{
98-
sorted = orderedOnce
99-
? ((IOrderedQueryable<TValue>) sorted).ThenBy(orderLambda)
100-
: sorted.OrderBy(orderLambda);
101-
}
102-
else
103-
{
104-
sorted = orderedOnce
105-
? ((IOrderedQueryable<TValue>) sorted).ThenByDescending(orderLambda)
106-
: sorted.OrderByDescending(orderLambda);
107-
}
108-
109-
orderedOnce = true;
110-
}
11140

112-
return sorted;
41+
return queryable is IOrderedQueryable<TValue> orderedQueryable
42+
? orderedQueryable.ThenByDescending(entity => EF.Property<object>(entity, sort.By.First()))
43+
: queryable.OrderByDescending(entity => EF.Property<object>(entity, sort.By.First()));
11344
}
11445

11546
}

Intersect.Server/Web/Net7/ApiService.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ internal partial class ApiService : ApplicationService<ServerContext, IApiServic
170170
sgo.AddSchemaFilterInstance(documentFilterTokenRequest.CreateSchemaFilter());
171171
sgo.SchemaFilter<GameObjectTypeSchemaFilter>();
172172
sgo.SchemaFilter<LookupKeySchemaFilter>();
173+
sgo.SchemaFilter<DictionarySchemaFilter>();
173174
sgo.EnableAnnotations(enableAnnotationsForInheritance: true, enableAnnotationsForPolymorphism: true);
174175
sgo.UseOneOfForPolymorphism();
175176
sgo.UseAllOfForInheritance();

Intersect.Server/Web/Net7/Swagger/Filters/EnumSchemaFilter.cs renamed to Intersect.Server/Web/Net7/Swagger/Filters/DictionarySchemaFilter.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
1+
using Intersect.Reflection;
12
using Microsoft.OpenApi.Models;
23
using Swashbuckle.AspNetCore.SwaggerGen;
34

45
namespace Intersect.Server.Web.Swagger.Filters;
56

6-
public sealed class EnumSchemaFilter : ISchemaFilter
7+
public sealed class DictionarySchemaFilter : ISchemaFilter
78
{
89
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
910
{
10-
if (!context.Type.IsEnum)
11+
if (!typeof(Dictionary<,>).ExtendedBy(context.Type))
1112
{
1213
return;
1314
}
15+
16+
context.Type.ToString();
1417
}
1518
}

Intersect.Server/Web/RestApi/Routes/V1/GameObjectController.cs

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -52,44 +52,51 @@ public IActionResult List(GameObjectType gameObjectType, [FromQuery] PagingInfo
5252
}
5353

5454
[HttpGet("{gameObjectType}/names")]
55-
public object Names(GameObjectType gameObjectType)
55+
public IActionResult Names(GameObjectType gameObjectType)
5656
{
57-
var lookup = GameObjectTypeExtensions.GetLookup(gameObjectType);
58-
59-
if (lookup != null)
57+
if (!gameObjectType.TryGetLookup(out var lookup))
6058
{
61-
var entries = gameObjectType == GameObjectType.Event
62-
? lookup.Where(obj => ((EventBase)obj.Value).CommonEvent).Select(t => new { t.Key, t.Value.Name }).ToDictionary(t => t.Key, t => t.Name)
63-
: lookup.Select(t => new { t.Key, t.Value.Name }).ToDictionary(t => t.Key, t => t.Name);
59+
return BadRequest($"Invalid {nameof(GameObjectType)} '{gameObjectType}'");
60+
}
6461

65-
return entries;
62+
var descriptors = lookup.Values.AsEnumerable();
63+
if (gameObjectType == GameObjectType.Event)
64+
{
65+
descriptors = descriptors.OfType<EventBase>().Where(descriptor => descriptor.CommonEvent);
6666
}
6767

68-
return BadRequest();
68+
var descriptorNames = descriptors.Select(descriptor => descriptor.Name).ToArray();
69+
70+
return Ok(
71+
new DataPage<string>(
72+
Total: descriptorNames.Length,
73+
Page: 0,
74+
PageSize: descriptorNames.Length,
75+
Count: descriptorNames.Length,
76+
descriptorNames
77+
)
78+
);
6979
}
7080

71-
[HttpGet("{gameObjectType}/{objId:guid}")]
72-
public object GameObjectById(GameObjectType gameObjectType, Guid objId)
81+
[HttpGet("{gameObjectType}/{objectId:guid}")]
82+
public object GameObjectById(GameObjectType gameObjectType, Guid objectId)
7383
{
74-
if (objId == Guid.Empty)
84+
if (objectId == default)
7585
{
76-
return BadRequest(@"Object not found!");
86+
return BadRequest($@"Invalid id '{objectId}'");
7787
}
7888

79-
var obj = GameObjectTypeExtensions.GetLookup(gameObjectType)?.Get(objId);
80-
81-
if (obj != null)
89+
if (!gameObjectType.TryGetLookup(out var lookup))
8290
{
83-
return obj;
91+
return BadRequest($"Invalid {nameof(GameObjectType)} '{gameObjectType}'");
8492
}
8593

86-
return NotFound(@"Object not found!");
94+
return !lookup.TryGetValue(objectId, out var gameObject)
95+
? NotFound($"No {gameObjectType} with id '{objectId}'")
96+
: Ok(gameObject);
8797
}
8898

8999
[HttpGet("time")]
90-
public object Time()
91-
{
92-
return TimeBase.GetTimeBase();
93-
}
100+
public IActionResult Time() => Ok(TimeBase.GetTimeBase());
94101
}
95102
}

0 commit comments

Comments
 (0)