Skip to content

Commit e9404ab

Browse files
committed
Stubing out the alternative API for sum-avg that only allowed one aggregate at a time without aliasing.
1 parent a405663 commit e9404ab

File tree

2 files changed

+100
-11
lines changed

2 files changed

+100
-11
lines changed

packages/firestore/src/lite-api/aggregate.ts

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,16 @@ import { CountQueryRunner } from '../core/count_query_runner';
2121
import { cast } from '../util/input_validation';
2222

2323
import {
24-
AggregateField,
24+
AggregateField, AggregateFieldSpec,
2525
AggregateQuerySnapshot,
26-
AggregateSpec
26+
AggregateSpec, AggregateType, AggregateFieldType, AggregateData
2727
} from './aggregate_types';
2828
import { getDatastore } from './components';
2929
import { Firestore } from './database';
3030
import { Query, queryEqual } from './reference';
3131
import { LiteUserDataWriter } from './reference_impl';
32+
import {FieldPath} from "./field_path";
33+
import {AggregateQueryRunner} from "../core/aggregate_query_runner";
3234

3335
/**
3436
* Calculates the number of documents in the result set of the given query,
@@ -53,6 +55,77 @@ export function getCount(
5355
return new CountQueryRunner(query, datastore, userDataWriter).run();
5456
}
5557

58+
export function getAggregateFromServer<T extends AggregateSpec>(
59+
query: Query<unknown>,
60+
aggregates: T
61+
): Promise<AggregateQuerySnapshot<T>>;
62+
63+
export function getAggregateFromServer<T extends AggregateFieldType>(
64+
query: Query<unknown>,
65+
aggregateField: T
66+
): Promise<AggregateQuerySnapshot<T>>;
67+
68+
export function getAggregateFromServer<T extends AggregateSpec | AggregateFieldType>(
69+
query: Query<unknown>,
70+
aggregateFieldOrSpec: T
71+
): Promise<AggregateQuerySnapshot<T>> {
72+
let aggregateSpec: AggregateSpec | undefined;
73+
74+
if (aggregateFieldOrSpec instanceof AggregateField) {
75+
aggregateSpec = {[aggregateFieldOrSpec.aggregateType]: aggregateFieldOrSpec};
76+
}
77+
else {
78+
aggregateSpec = aggregateFieldOrSpec;
79+
}
80+
81+
return new Promise(resolve => {
82+
const data: any = {};
83+
for (const key in aggregateSpec) {
84+
const field = aggregateSpec[key];
85+
switch (field.aggregateType) {
86+
case "count":
87+
data[key] = 1;
88+
break;
89+
case "sum":
90+
data[key] = 1;
91+
break;
92+
case "average":
93+
data[key] = 1;
94+
break;
95+
}
96+
}
97+
resolve(new AggregateQuerySnapshot(query, data))
98+
})
99+
}
100+
101+
export function sum(field: string | FieldPath): AggregateField<number, 'sum'> {
102+
return new AggregateField('sum', field);
103+
}
104+
105+
export function average(field: string | FieldPath): AggregateField<number | null, 'average'> {
106+
return new AggregateField('average', field);
107+
}
108+
109+
export function count(): AggregateField<number, 'count'> {
110+
return new AggregateField('count');
111+
}
112+
113+
/**
114+
* Compares two 'AggregateField` instances for equality.
115+
*
116+
* @param left
117+
* @param right
118+
*/
119+
export function aggregateFieldEqual(
120+
left: AggregateField<unknown, AggregateType>,
121+
right: AggregateField<unknown, AggregateType>
122+
): boolean {
123+
return left instanceof AggregateField &&
124+
right instanceof AggregateField &&
125+
left.field == right.field &&
126+
left.aggregateType == right.aggregateType;
127+
}
128+
56129
/**
57130
* Compares two `AggregateQuerySnapshot` instances for equality.
58131
*

packages/firestore/src/lite-api/aggregate_types.ts

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,29 @@
1616
*/
1717

1818
import { Query } from './reference';
19+
import {FieldPath} from "./field_path";
20+
import {average, count, sum} from './aggregate';
21+
22+
export type AggregateType = 'average' | 'count' | 'sum';
1923

2024
/**
2125
* Represents an aggregation that can be performed by Firestore.
2226
*/
23-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
24-
export class AggregateField<T> {
27+
export class AggregateField<R, A extends AggregateType = 'count'> {
2528
/** A type string to uniquely identify instances of this class. */
26-
type = 'AggregateField';
29+
readonly type = 'AggregateField';
30+
31+
constructor(public readonly aggregateType: A, public readonly field?: string | FieldPath) {
32+
}
2733
}
2834

2935
/**
3036
* The union of all `AggregateField` types that are supported by Firestore.
3137
*/
32-
export type AggregateFieldType = AggregateField<number>;
38+
export type AggregateFieldType =
39+
ReturnType<typeof count>
40+
| ReturnType<typeof sum>
41+
| ReturnType<typeof average>
3342

3443
/**
3544
* A type whose property values are all `AggregateField` objects.
@@ -43,14 +52,21 @@ export interface AggregateSpec {
4352
* result of the aggregation performed by the corresponding `AggregateField`
4453
* from the input `AggregateSpec`.
4554
*/
46-
export type AggregateSpecData<T extends AggregateSpec> = {
47-
[P in keyof T]: T[P] extends AggregateField<infer U> ? U : never;
55+
export type AggregateSpecData<T extends AggregateSpec > = {
56+
[P in keyof T]: T[P] extends AggregateField<infer U, any> ? U : never;
4857
};
4958

59+
export type AggregateFieldSpec<T extends AggregateFieldType> =
60+
T extends AggregateField<infer R, infer A> ? Record<A, T> : never;
61+
62+
export type AggregateData<T extends AggregateSpec | AggregateFieldType> =
63+
T extends AggregateSpec ? AggregateSpecData<T> :
64+
T extends AggregateFieldType ? AggregateFieldSpec<T> : never;
65+
5066
/**
5167
* The results of executing an aggregation query.
5268
*/
53-
export class AggregateQuerySnapshot<T extends AggregateSpec> {
69+
export class AggregateQuerySnapshot<T extends AggregateSpec | AggregateFieldType> {
5470
/** A type string to uniquely identify instances of this class. */
5571
readonly type = 'AggregateQuerySnapshot';
5672

@@ -63,7 +79,7 @@ export class AggregateQuerySnapshot<T extends AggregateSpec> {
6379
/** @hideconstructor */
6480
constructor(
6581
query: Query<unknown>,
66-
private readonly _data: AggregateSpecData<T>
82+
private readonly _data: AggregateData<T>
6783
) {
6884
this.query = query;
6985
}
@@ -79,7 +95,7 @@ export class AggregateQuerySnapshot<T extends AggregateSpec> {
7995
* @returns The results of the aggregations performed over the underlying
8096
* query.
8197
*/
82-
data(): AggregateSpecData<T> {
98+
data(): AggregateData<T> {
8399
return this._data;
84100
}
85101
}

0 commit comments

Comments
 (0)