Skip to content
This repository was archived by the owner on Apr 11, 2023. It is now read-only.

Commit 23d215b

Browse files
committed
oDataProvider: support aggregation/distinct/groupby
1 parent 8cd101c commit 23d215b

File tree

3 files changed

+88
-5
lines changed

3 files changed

+88
-5
lines changed

src/Types/StorageProviders/oData/oDataCompiler.js

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ $C('$data.storageProviders.oData.oDataModelBinderConfigCompiler', $data.modelBin
88
builder.modelBinderConfig.$type = opDef.returnType || opDef.dataType;
99
builder.modelBinderConfig.$value = function(meta, data){ return opDef.projection(data[meta.$source]); };
1010
}
11+
if (opDef.aggregate){
12+
if (opDef.returnType || opDef.dataType) builder.modelBinderConfig.$type = opDef.returnType || opDef.dataType;
13+
}
1114
}
1215
});
1316

@@ -34,7 +37,28 @@ $C('$data.storageProviders.oData.oDataCompiler', $data.Expressions.EntityExpress
3437
if(queryFragments.$expand){
3538
queryFragments.$expand = queryFragments.$expand.toString();
3639
}
37-
40+
var $apply = "";
41+
if (queryFragments.aggregate){
42+
$apply = `aggregate(${queryFragments.aggregate.join(",")})`;
43+
}
44+
if (queryFragments.groupby){
45+
queryFragments.groupby = queryFragments.groupby.filter(function(it, i, arr){ return arr.indexOf(it) == i; });
46+
$apply = queryFragments.aggregate
47+
? `groupby((${queryFragments.groupby.join(",")}),${$apply})`
48+
: `groupby((${queryFragments.groupby.join(",")}))`;
49+
}
50+
if ($apply && queryFragments.$filter){
51+
$apply = `filter(${queryFragments.$filter})/${$apply}`;
52+
}
53+
if ($apply){
54+
queryFragments = Object.assign({}, queryFragments, {
55+
aggregate: [],
56+
groupby: [],
57+
$filter: "",
58+
$select: "",
59+
$apply: $apply
60+
});
61+
}
3862

3963
query.modelBinderConfig = {};
4064
var modelBinder = $data.storageProviders.oData.oDataModelBinderConfigCompiler.create(query, this.includes, true);
@@ -271,5 +295,22 @@ $C('$data.storageProviders.oData.oDataCompiler', $data.Expressions.EntityExpress
271295
headers: compiled.headers
272296
});
273297
}
298+
},
299+
300+
VisitDistinctExpression: function (expression, context) {
301+
this.Visit(expression.source, context);
302+
context.groupby = context.groupby || [];
303+
context.groupby.push(...context.$select.split(','));
304+
},
305+
306+
VisitGroupExpression: function (expression, context) {
307+
this.Visit(expression.source, context);
308+
309+
var groupContext = Object.assign({}, context);
310+
var orderCompiler = Container.createoDataOrderCompiler(this.provider);
311+
orderCompiler.compile(expression.selector, groupContext);
312+
313+
context.groupby = context.groupby || [];
314+
context.groupby.push(...groupContext.data.split(','));
274315
}
275316
}, {});

src/Types/StorageProviders/oData/oDataProjectionCompiler.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,19 @@ $C('$data.storageProviders.oData.oDataProjectionCompiler', $data.Expressions.Ent
168168
//context.data += expression.value;
169169
context.data = context.data.slice(0, context.data.length - 1);
170170
},
171-
VisitEntityFieldOperationExpression: function (expression, context) {
172-
this.Visit(expression.source, context);
171+
VisitEntityFieldOperationExpression: function VisitEntityFieldOperationExpression(expression, context) {
172+
Guard.requireType("expression.operation", expression.operation, $data.Expressions.MemberInfoExpression);
173+
174+
var opDef = expression.operation.memberDefinition;
175+
if (opDef.aggregate){
176+
var opName = opDef.mapTo || opDef.name;
177+
context.aggregate = context.aggregate || [];
178+
179+
var temp = context.data;
180+
this.Visit(expression.source, context);
181+
var field = context.data.replace(temp, "");
182+
context.data = temp.replace(/,$/, "");
183+
context.aggregate.push(`${field} with ${opName} as ${field}`);
184+
}else this.Visit(expression.source, context);
173185
}
174186
});

src/Types/StorageProviders/oData/oDataProvider.js

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,7 +1084,35 @@ $C('$data.storageProviders.oData.oDataProvider', $data.StorageProviderBase, null
10841084
dataType: "boolean", allowedIn: [$data.Expressions.FilterExpression, $data.Expressions.OrderExpression, $data.Expressions.SomeExpression, $data.Expressions.EveryExpression],
10851085
parameters: [{ name: "@expression", dataType: 'GeometryPoint' }, { name: "in", dataType: 'GeometryPolygon' }]
10861086

1087-
}]
1087+
}],
1088+
1089+
// aggregate functions
1090+
'sum': {
1091+
allowedIn: [$data.Expressions.ProjectionExpression],
1092+
mapTo: 'sum',
1093+
aggregate: true
1094+
},
1095+
'count': {
1096+
allowedIn: [$data.Expressions.ProjectionExpression],
1097+
mapTo: 'countdistinct',
1098+
returnType: $data.Integer,
1099+
aggregate: true
1100+
},
1101+
'min': {
1102+
allowedIn: [$data.Expressions.ProjectionExpression],
1103+
mapTo: 'min',
1104+
aggregate: true
1105+
},
1106+
'max': {
1107+
allowedIn: [$data.Expressions.ProjectionExpression],
1108+
mapTo: 'max',
1109+
aggregate: true
1110+
},
1111+
'avg': {
1112+
allowedIn: [$data.Expressions.ProjectionExpression],
1113+
mapTo: 'average',
1114+
aggregate: true
1115+
}
10881116
},
10891117
enumerable: true,
10901118
writable: true
@@ -1164,7 +1192,9 @@ $C('$data.storageProviders.oData.oDataProvider', $data.StorageProviderBase, null
11641192
includeFrameName: '$count',
11651193
implementation: function(){ return 'true' }
11661194
},
1167-
find: {}
1195+
find: {},
1196+
distinct: {},
1197+
groupBy: {}
11681198
},
11691199
enumerable: true,
11701200
writable: true

0 commit comments

Comments
 (0)