diff --git a/packages/firestore/src/api/database.ts b/packages/firestore/src/api/database.ts index a367aca33ea..e9b76c8a693 100644 --- a/packages/firestore/src/api/database.ts +++ b/packages/firestore/src/api/database.ts @@ -25,7 +25,6 @@ import { FirestoreClient } from '../core/firestore_client'; import { Bound, Direction, - fieldFilter, Filter, OrderBy, Query as InternalQuery, @@ -1333,7 +1332,7 @@ export class Query implements firestore.Query { value ); } - const filter = fieldFilter(fieldPath, relationOp, fieldValue); + const filter = Filter.create(fieldPath, relationOp, fieldValue); this.validateNewFilter(filter); return new Query(this._query.addFilter(filter), this.firestore); } diff --git a/packages/firestore/src/core/query.ts b/packages/firestore/src/core/query.ts index 154ed59a563..17375e31106 100644 --- a/packages/firestore/src/core/query.ts +++ b/packages/firestore/src/core/query.ts @@ -390,10 +390,35 @@ export class Query { } } -export interface Filter { - matches(doc: Document): boolean; - canonicalId(): string; - isEqual(filter: Filter): boolean; +export abstract class Filter { + abstract matches(doc: Document): boolean; + abstract canonicalId(): string; + abstract isEqual(filter: Filter): boolean; + + /** + * Creates a filter based on the provided arguments. + */ + static create(field: FieldPath, op: RelationOp, value: FieldValue): Filter { + if (value.isEqual(NullValue.INSTANCE)) { + if (op !== RelationOp.EQUAL) { + throw new FirestoreError( + Code.INVALID_ARGUMENT, + 'Invalid query. You can only perform equals comparisons on null.' + ); + } + return new NullFilter(field); + } else if (value.isEqual(DoubleValue.NAN)) { + if (op !== RelationOp.EQUAL) { + throw new FirestoreError( + Code.INVALID_ARGUMENT, + 'Invalid query. You can only perform equals comparisons on NaN.' + ); + } + return new NanFilter(field); + } else { + return new RelationFilter(field, op, value); + } + } } export class RelationOp { @@ -434,12 +459,14 @@ export class RelationOp { } } -export class RelationFilter implements Filter { +export class RelationFilter extends Filter { constructor( public field: FieldPath, public op: RelationOp, public value: FieldValue - ) {} + ) { + super(); + } matches(doc: Document): boolean { if (this.field.isKeyField()) { @@ -528,8 +555,10 @@ export class RelationFilter implements Filter { /** * Filter that matches 'null' values. */ -export class NullFilter implements Filter { - constructor(public field: FieldPath) {} +export class NullFilter extends Filter { + constructor(public field: FieldPath) { + super(); + } matches(doc: Document): boolean { const val = doc.field(this.field); @@ -556,8 +585,10 @@ export class NullFilter implements Filter { /** * Filter that matches 'NaN' values. */ -export class NanFilter implements Filter { - constructor(public field: FieldPath) {} +export class NanFilter extends Filter { + constructor(public field: FieldPath) { + super(); + } matches(doc: Document): boolean { const val = doc.field(this.field).value(); @@ -581,35 +612,6 @@ export class NanFilter implements Filter { } } -/** - * Creates a filter based on the provided arguments. - */ -export function fieldFilter( - field: FieldPath, - op: RelationOp, - value: FieldValue -): Filter { - if (value.isEqual(NullValue.INSTANCE)) { - if (op !== RelationOp.EQUAL) { - throw new FirestoreError( - Code.INVALID_ARGUMENT, - 'Invalid query. You can only perform equals ' + 'comparisons on null.' - ); - } - return new NullFilter(field); - } else if (value.isEqual(DoubleValue.NAN)) { - if (op !== RelationOp.EQUAL) { - throw new FirestoreError( - Code.INVALID_ARGUMENT, - 'Invalid query. You can only perform equals ' + 'comparisons on NaN.' - ); - } - return new NanFilter(field); - } else { - return new RelationFilter(field, op, value); - } -} - /** * The direction of sorting in an order by. */ diff --git a/packages/firestore/test/util/helpers.ts b/packages/firestore/test/util/helpers.ts index 706d61de7bc..5a1ce01b879 100644 --- a/packages/firestore/test/util/helpers.ts +++ b/packages/firestore/test/util/helpers.ts @@ -28,7 +28,6 @@ import { DatabaseId } from '../../src/core/database_info'; import { Bound, Direction, - fieldFilter, Filter, OrderBy, Query, @@ -175,7 +174,7 @@ export function blob(...bytes: number[]): Blob { export function filter(path: string, op: string, value: AnyJs): Filter { const dataValue = wrap(value); const operator = RelationOp.fromString(op); - return fieldFilter(field(path), operator, dataValue); + return Filter.create(field(path), operator, dataValue); } export function setMutation(