Skip to content

Commit 5fe08d9

Browse files
Undo Take < 0 logic; introduce IsSummaryQuery flag (#469)
1 parent b2ab9c8 commit 5fe08d9

5 files changed

Lines changed: 92 additions & 40 deletions

File tree

net/DevExtreme.AspNet.Data.Tests/DataSourceLoaderTests.cs

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -475,37 +475,6 @@ public void Load_Select_NoAnonTypeLimits(bool? remoteSelect) {
475475
);
476476
}
477477

478-
[Theory]
479-
[InlineData(false, false)]
480-
[InlineData(false, true)]
481-
[InlineData(true, false)]
482-
[InlineData(true, true)]
483-
public void Load_NegativeTake(bool remoteGrouping, bool group) {
484-
var loadOptions = new SampleLoadOptions {
485-
Filter = new[] { "this", "<", "100" },
486-
RemoteGrouping = remoteGrouping,
487-
Take = -1,
488-
TotalSummary = new[] {
489-
new SummaryInfo { Selector = "this", SummaryType = "sum" }
490-
}
491-
};
492-
493-
if(group) {
494-
loadOptions.Group = new[] {
495-
new GroupingInfo { Selector = "any", IsExpanded = !remoteGrouping }
496-
};
497-
loadOptions.GroupSummary = new[] {
498-
new SummaryInfo { Selector = "any", SummaryType = "any" }
499-
};
500-
}
501-
502-
var loadResult = DataSourceLoader.Load(new[] { 1, 1, 2, 2, 100 }, loadOptions);
503-
Assert.Null(loadResult.data);
504-
Assert.Equal(6m, loadResult.summary[0]);
505-
506-
Assert.Single(loadOptions.ExpressionLog);
507-
}
508-
509478
[Theory]
510479
[InlineData(false, true)]
511480
[InlineData(false, false)]
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using Xunit;
5+
6+
namespace DevExtreme.AspNet.Data.Tests {
7+
8+
public class IsSummaryQueryTests {
9+
10+
[Theory]
11+
[MemberData(nameof(CombinatorialBool), 4)]
12+
public void Case(bool remoteGrouping, bool requireTotalCount, bool hasGroups, bool hasSummary) {
13+
var loadOptions = new SampleLoadOptions {
14+
IsSummaryQuery = true,
15+
RemoteGrouping = remoteGrouping,
16+
RequireTotalCount = requireTotalCount,
17+
Filter = new[] { "this", "<", "100" }
18+
};
19+
if(hasGroups) {
20+
loadOptions.Group = new[] {
21+
new GroupingInfo { Selector = "any", IsExpanded = !remoteGrouping }
22+
};
23+
loadOptions.GroupSummary = new[] {
24+
new SummaryInfo { Selector = "any", SummaryType = "any" }
25+
};
26+
}
27+
if(hasSummary) {
28+
loadOptions.TotalSummary = new[] {
29+
new SummaryInfo { Selector = "this", SummaryType = "sum" }
30+
};
31+
}
32+
33+
var loadResult = DataSourceLoader.Load(new[] { 1, 1, 2, 2, 100 }, loadOptions);
34+
35+
Assert.Null(loadResult.data);
36+
37+
if(hasSummary)
38+
Assert.Equal(6m, loadResult.summary[0]);
39+
else
40+
Assert.Null(loadResult.summary);
41+
42+
// Refer to RemoteGroupExpressionCompiler.MakeAggregatingProjection
43+
var implicitTotalCount = hasSummary && remoteGrouping;
44+
45+
if(requireTotalCount || implicitTotalCount)
46+
Assert.True(loadResult.totalCount > 0);
47+
else
48+
Assert.Equal(-1, loadResult.totalCount);
49+
50+
var expectedExpressionCount = 0;
51+
52+
if(requireTotalCount && !implicitTotalCount) {
53+
expectedExpressionCount++;
54+
Assert.Contains(loadOptions.ExpressionLog, line => line.EndsWith(".Where(obj => (obj < 100)).Count()"));
55+
}
56+
57+
if(hasSummary) {
58+
expectedExpressionCount++;
59+
if(remoteGrouping)
60+
Assert.Contains(loadOptions.ExpressionLog, line => line.Contains(".GroupBy(obj => new AnonType())"));
61+
else
62+
Assert.Contains(loadOptions.ExpressionLog, line => line.EndsWith(".Where(obj => (obj < 100))"));
63+
}
64+
65+
Assert.Equal(expectedExpressionCount, loadOptions.ExpressionLog.Count);
66+
}
67+
68+
public static IEnumerable<object[]> CombinatorialBool(int count) {
69+
var combinationCount = 1 << count;
70+
for(var i = 0; i < combinationCount; i++) {
71+
yield return Enumerable.Range(0, count)
72+
.Select(bit => (i & 1 << bit) != 0)
73+
.Cast<object>()
74+
.ToArray();
75+
}
76+
}
77+
}
78+
79+
}

net/DevExtreme.AspNet.Data/DataSourceLoadContext.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ partial class DataSourceLoadContext {
8888

8989
public IReadOnlyList<GroupingInfo> Group => _options.Group;
9090

91-
public bool HasGroups => Take > -1 && !IsEmpty(Group);
91+
public bool HasGroups => !IsSummaryQuery && !IsEmpty(Group);
9292

9393
public bool ShouldEmptyGroups {
9494
get {
@@ -260,6 +260,8 @@ public bool ExpandLinqSumType {
260260
}
261261
}
262262

263+
public bool IsSummaryQuery => _options.IsSummaryQuery;
264+
263265
public bool IsRemoteTotalSummary => UseRemoteGrouping && !SummaryIsTotalCountOnly && HasSummary && !HasGroups;
264266
}
265267

net/DevExtreme.AspNet.Data/DataSourceLoadOptionsBase.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections;
3+
using System.ComponentModel;
34
using System.Linq;
45
using System.Linq.Expressions;
56

@@ -29,6 +30,9 @@ public class DataSourceLoadOptionsBase {
2930
/// </summary>
3031
public bool IsCountQuery { get; set; }
3132

33+
[EditorBrowsable(EditorBrowsableState.Never)]
34+
public bool IsSummaryQuery { get; set; }
35+
3236
/// <summary>
3337
/// The number of data objects to be skipped from the start of the resulting set.
3438
/// </summary>

net/DevExtreme.AspNet.Data/DataSourceLoaderImpl.cs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public async Task<LoadResult> LoadAsync() {
4444
if(Context.IsCountQuery)
4545
return new LoadResult { totalCount = await ExecTotalCountAsync() };
4646

47-
if(Context.Take < 0)
47+
if(Context.IsSummaryQuery)
4848
return await LoadAggregatesOnlyAsync();
4949

5050
var result = new LoadResult();
@@ -122,13 +122,11 @@ await ExecExprAsync<S>(loadExpr),
122122
async Task<LoadResult> LoadAggregatesOnlyAsync() {
123123
var result = new LoadResult();
124124

125-
if(Context.HasTotalSummary) {
126-
if(Context.IsRemoteTotalSummary) {
127-
await ContinueWithAggregationAsync<S>(null, null, result, false);
128-
} else {
129-
var data = await ExecExprAsync<S>(CreateBuilder().BuildLoadExpr(false));
130-
await ContinueWithAggregationAsync(data, new DefaultAccessor<S>(), result, false);
131-
}
125+
if(!Context.HasTotalSummary || Context.IsRemoteTotalSummary) {
126+
await ContinueWithAggregationAsync<S>(null, null, result, false);
127+
} else {
128+
var data = await ExecExprAsync<S>(CreateBuilder().BuildLoadExpr(false));
129+
await ContinueWithAggregationAsync(data, new DefaultAccessor<S>(), result, false);
132130
}
133131

134132
return result;

0 commit comments

Comments
 (0)