Skip to content

Commit eb44f4a

Browse files
New Query API (#3390)
* New Query API * Review * Update Validation tests * One more test fix * Fix * Lint * Imports
1 parent cf8696e commit eb44f4a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1537
-1136
lines changed

packages/firestore/exp-types/index.d.ts

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -284,28 +284,50 @@ export class Query<T = DocumentData> {
284284
protected constructor();
285285
readonly type: 'query' | 'collection';
286286
readonly firestore: FirebaseFirestore;
287-
where(
288-
fieldPath: string | FieldPath,
289-
opStr: WhereFilterOp,
290-
value: any
291-
): Query<T>;
292-
orderBy(
293-
fieldPath: string | FieldPath,
294-
directionStr?: OrderByDirection
295-
): Query<T>;
296-
limit(limit: number): Query<T>;
297-
limitToLast(limit: number): Query<T>;
298-
startAt(snapshot: DocumentSnapshot<any>): Query<T>;
299-
startAt(...fieldValues: any[]): Query<T>;
300-
startAfter(snapshot: DocumentSnapshot<any>): Query<T>;
301-
startAfter(...fieldValues: any[]): Query<T>;
302-
endBefore(snapshot: DocumentSnapshot<any>): Query<T>;
303-
endBefore(...fieldValues: any[]): Query<T>;
304-
endAt(snapshot: DocumentSnapshot<any>): Query<T>;
305-
endAt(...fieldValues: any[]): Query<T>;
287+
306288
withConverter<U>(converter: FirestoreDataConverter<U>): Query<U>;
307289
}
308290

291+
export type QueryConstraintType =
292+
| 'where'
293+
| 'orderBy'
294+
| 'limit'
295+
| 'limitToLast'
296+
| 'startAt'
297+
| 'startAfter'
298+
| 'endAt'
299+
| 'endBefore';
300+
301+
export class QueryConstraint {
302+
private constructor();
303+
readonly type: QueryConstraintType;
304+
}
305+
306+
export function query<T>(
307+
query: CollectionReference<T> | Query<T>,
308+
...constraints: QueryConstraint[]
309+
): Query<T>;
310+
311+
export function where(
312+
fieldPath: string | FieldPath,
313+
opStr: WhereFilterOp,
314+
value: any
315+
): QueryConstraint;
316+
export function orderBy(
317+
fieldPath: string | FieldPath,
318+
directionStr?: OrderByDirection
319+
): QueryConstraint;
320+
export function limit(limit: number): QueryConstraint;
321+
export function limitToLast(limit: number): QueryConstraint;
322+
export function startAt(snapshot: DocumentSnapshot<any>): QueryConstraint;
323+
export function startAt(...fieldValues: any[]): QueryConstraint;
324+
export function startAfter(snapshot: DocumentSnapshot<any>): QueryConstraint;
325+
export function startAfter(...fieldValues: any[]): QueryConstraint;
326+
export function endBefore(snapshot: DocumentSnapshot<any>): QueryConstraint;
327+
export function endBefore(...fieldValues: any[]): QueryConstraint;
328+
export function endAt(snapshot: DocumentSnapshot<any>): QueryConstraint;
329+
export function endAt(...fieldValues: any[]): QueryConstraint;
330+
309331
export class QuerySnapshot<T = DocumentData> {
310332
private constructor();
311333
readonly query: Query<T>;

packages/firestore/exp/index.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,21 @@ export { SnapshotMetadata } from '../src/api/database';
4747
export {
4848
DocumentReference,
4949
CollectionReference,
50+
QueryConstraint,
5051
Query,
5152
doc,
5253
collection,
5354
collectionGroup,
54-
parent
55+
parent,
56+
startAt,
57+
startAfter,
58+
endAt,
59+
endBefore,
60+
query,
61+
limit,
62+
limitToLast,
63+
where,
64+
orderBy
5565
} from '../lite/src/api/reference';
5666

5767
export { runTransaction, Transaction } from './src/api/transaction';

packages/firestore/exp/test/shim.ts

Lines changed: 36 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import {
4848
onSnapshot,
4949
onSnapshotsInSync,
5050
parent,
51+
query,
5152
queryEqual,
5253
refEqual,
5354
runTransaction,
@@ -57,7 +58,15 @@ import {
5758
terminate,
5859
updateDoc,
5960
waitForPendingWrites,
60-
writeBatch
61+
writeBatch,
62+
endAt,
63+
endBefore,
64+
startAfter,
65+
startAt,
66+
limitToLast,
67+
limit,
68+
orderBy,
69+
where
6170
} from '../../exp/index';
6271
import { UntypedFirestoreDataConverter } from '../../src/api/user_data_reader';
6372
import { isPartialObserver, PartialObserver } from '../../src/api/observer';
@@ -453,7 +462,7 @@ export class Query<T = legacy.DocumentData> implements legacy.Query<T> {
453462
): Query<T> {
454463
return new Query<T>(
455464
this.firestore,
456-
this._delegate.where(unwrap(fieldPath), opStr, unwrap(value))
465+
query(this._delegate, where(unwrap(fieldPath), opStr, unwrap(value)))
457466
);
458467
}
459468

@@ -463,63 +472,44 @@ export class Query<T = legacy.DocumentData> implements legacy.Query<T> {
463472
): Query<T> {
464473
return new Query<T>(
465474
this.firestore,
466-
this._delegate.orderBy(unwrap(fieldPath), directionStr)
475+
query(this._delegate, orderBy(unwrap(fieldPath), directionStr))
467476
);
468477
}
469478

470-
limit(limit: number): Query<T> {
471-
return new Query<T>(this.firestore, this._delegate.limit(limit));
479+
limit(n: number): Query<T> {
480+
return new Query<T>(this.firestore, query(this._delegate, limit(n)));
472481
}
473482

474-
limitToLast(limit: number): Query<T> {
475-
return new Query<T>(this.firestore, this._delegate.limitToLast(limit));
483+
limitToLast(n: number): Query<T> {
484+
return new Query<T>(this.firestore, query(this._delegate, limitToLast(n)));
476485
}
477486

478487
startAt(...args: any[]): Query<T> {
479-
if (args[0] instanceof DocumentSnapshot) {
480-
return new Query(
481-
this.firestore,
482-
this._delegate.startAt(args[0]._delegate)
483-
);
484-
} else {
485-
return new Query(this.firestore, this._delegate.startAt(...unwrap(args)));
486-
}
488+
return new Query(
489+
this.firestore,
490+
query(this._delegate, startAt(...unwrap(args)))
491+
);
487492
}
488493

489494
startAfter(...args: any[]): Query<T> {
490-
if (args[0] instanceof DocumentSnapshot) {
491-
return new Query(
492-
this.firestore,
493-
this._delegate.startAfter(args[0]._delegate)
494-
);
495-
} else {
496-
return new Query(
497-
this.firestore,
498-
this._delegate.startAfter(...unwrap(args))
499-
);
500-
}
495+
return new Query(
496+
this.firestore,
497+
query(this._delegate, startAfter(...unwrap(args)))
498+
);
501499
}
502500

503501
endBefore(...args: any[]): Query<T> {
504-
if (args[0] instanceof DocumentSnapshot) {
505-
return new Query(
506-
this.firestore,
507-
this._delegate.endBefore(args[0]._delegate)
508-
);
509-
} else {
510-
return new Query(
511-
this.firestore,
512-
this._delegate.endBefore(...unwrap(args))
513-
);
514-
}
502+
return new Query(
503+
this.firestore,
504+
query(this._delegate, endBefore(...unwrap(args)))
505+
);
515506
}
516507

517508
endAt(...args: any[]): Query<T> {
518-
if (args[0] instanceof DocumentSnapshot) {
519-
return new Query(this.firestore, this._delegate.endAt(args[0]._delegate));
520-
} else {
521-
return new Query(this.firestore, this._delegate.endAt(...unwrap(args)));
522-
}
509+
return new Query(
510+
this.firestore,
511+
query(this._delegate, endAt(...unwrap(args)))
512+
);
523513
}
524514

525515
isEqual(other: legacy.Query<T>): boolean {
@@ -776,6 +766,10 @@ function unwrap(value: any): any {
776766
return value._delegate;
777767
} else if (value instanceof DocumentReference) {
778768
return value._delegate;
769+
} else if (value instanceof DocumentSnapshot) {
770+
return value._delegate;
771+
} else if (value instanceof QueryDocumentSnapshot) {
772+
return value._delegate;
779773
} else if (isPlainObject(value)) {
780774
const obj: any = {};
781775
for (const key in value) {

packages/firestore/lite-types/index.d.ts

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -238,28 +238,50 @@ export class Query<T = DocumentData> {
238238
protected constructor();
239239
readonly type: 'query' | 'collection';
240240
readonly firestore: FirebaseFirestore;
241-
where(
242-
fieldPath: string | FieldPath,
243-
opStr: WhereFilterOp,
244-
value: any
245-
): Query<T>;
246-
orderBy(
247-
fieldPath: string | FieldPath,
248-
directionStr?: OrderByDirection
249-
): Query<T>;
250-
limit(limit: number): Query<T>;
251-
limitToLast(limit: number): Query<T>;
252-
startAt(snapshot: DocumentSnapshot<any>): Query<T>;
253-
startAt(...fieldValues: any[]): Query<T>;
254-
startAfter(snapshot: DocumentSnapshot<any>): Query<T>;
255-
startAfter(...fieldValues: any[]): Query<T>;
256-
endBefore(snapshot: DocumentSnapshot<any>): Query<T>;
257-
endBefore(...fieldValues: any[]): Query<T>;
258-
endAt(snapshot: DocumentSnapshot<any>): Query<T>;
259-
endAt(...fieldValues: any[]): Query<T>;
241+
260242
withConverter<U>(converter: FirestoreDataConverter<U>): Query<U>;
261243
}
262244

245+
export type QueryConstraintType =
246+
| 'where'
247+
| 'orderBy'
248+
| 'limit'
249+
| 'limitToLast'
250+
| 'startAt'
251+
| 'startAfter'
252+
| 'endAt'
253+
| 'endBefore';
254+
255+
export class QueryConstraint {
256+
private constructor();
257+
readonly type: QueryConstraintType;
258+
}
259+
260+
export function query<T>(
261+
query: CollectionReference<T> | Query<T>,
262+
...constraints: QueryConstraint[]
263+
): Query<T>;
264+
265+
export function where(
266+
fieldPath: string | FieldPath,
267+
opStr: WhereFilterOp,
268+
value: any
269+
): QueryConstraint;
270+
export function orderBy(
271+
fieldPath: string | FieldPath,
272+
directionStr?: OrderByDirection
273+
): QueryConstraint;
274+
export function limit(limit: number): QueryConstraint;
275+
export function limitToLast(limit: number): QueryConstraint;
276+
export function startAt(snapshot: DocumentSnapshot<any>): QueryConstraint;
277+
export function startAt(...fieldValues: any[]): QueryConstraint;
278+
export function startAfter(snapshot: DocumentSnapshot<any>): QueryConstraint;
279+
export function startAfter(...fieldValues: any[]): QueryConstraint;
280+
export function endBefore(snapshot: DocumentSnapshot<any>): QueryConstraint;
281+
export function endBefore(...fieldValues: any[]): QueryConstraint;
282+
export function endAt(snapshot: DocumentSnapshot<any>): QueryConstraint;
283+
export function endAt(...fieldValues: any[]): QueryConstraint;
284+
263285
export class QuerySnapshot<T = DocumentData> {
264286
private constructor();
265287
readonly query: Query<T>;

packages/firestore/lite/index.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export {
3030
export {
3131
DocumentReference,
3232
Query,
33+
QueryConstraint,
3334
CollectionReference,
3435
collection,
3536
collectionGroup,
@@ -42,7 +43,16 @@ export {
4243
updateDoc,
4344
addDoc,
4445
refEqual,
45-
queryEqual
46+
queryEqual,
47+
startAt,
48+
startAfter,
49+
endAt,
50+
endBefore,
51+
query,
52+
limit,
53+
limitToLast,
54+
where,
55+
orderBy
4656
} from './src/api/reference';
4757

4858
// TOOD(firestorelite): Add tests when Queries are usable

0 commit comments

Comments
 (0)