Skip to content
This repository was archived by the owner on Dec 14, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/Collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,11 +197,9 @@ class Collection <T extends Entity, P extends Entity> implements ICollection<T,
* Entry point for building queries.
*/
public query(): Query<T> {
const fields = getRepository(this._Entity.prototype.constructor.name).fields;
return new Query(
this._Entity,
this,
fields,
this._native,
);
}
Expand Down
56 changes: 39 additions & 17 deletions src/Query.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { firestore } from 'firebase/app';
import { Entity } from '.';
import { IFieldMeta, ICollection, IQuery } from './types';
import { IFieldMeta, IFieldWithEntityMeta, IEntity, ICollection, IQuery} from './types';
import QuerySnapshot from './QuerySnapshot';
import { getRepository } from './store';

/**
* Firestorm representation of a query. Queries can be chained
Expand All @@ -12,7 +13,6 @@ export default class Query<T extends Entity> implements IQuery<T> {
private _Entity: new () => T;
private _collection: ICollection<T>;
private _native: firestore.Query;
private _fields: Map<string, IFieldMeta>;

/**
* Create a collection query for an [[Entity]].
Expand All @@ -24,40 +24,63 @@ export default class Query<T extends Entity> implements IQuery<T> {
public constructor(
Entity: new () => T,
collection: ICollection<T>,
fields: Map<string, IFieldMeta>,
native: firestore.Query,
) {
this._Entity = Entity;
this._collection = collection;
this._fields = fields;
this._native = native;
}

/**
* Gets field path string from property key or property path array
* @param propertyOrPropPathArray
*/
private getFieldPath(propertyOrPropPathArray: keyof T | [keyof T, ...string[]]): string {
const propPathArray =
Array.isArray(propertyOrPropPathArray) ?
propertyOrPropPathArray :
[propertyOrPropPathArray];

let propertyIdx = 0;
let Entity = this._Entity as new () => IEntity;
let paths = [];

do {
const { fields } = getRepository(Entity.prototype.constructor.name);
const property = propPathArray[propertyIdx];
const field = fields.get(property as string) as IFieldWithEntityMeta;
if (!field) {
throw new Error(`Could not find property in ${this._collection.path}`);
}
paths.push(field.name);
propertyIdx++;
Entity = field.entity;
} while (propertyIdx < propPathArray.length)

return paths.join('.');
}

/**
* Applies a where filter to the query.
* @param property The property to query.
* @param op The operation to apply.
* @param value The value to test for.
*/
public where(property: keyof T, op: firestore.WhereFilterOp, value: any): Query<T> {
const field = this._fields.get(property as string);
if (field) {
return this.appendNativeQuery(this._native.where(field.name, op, value));
}
throw new Error(`Could not find property in ${this._collection.path}`);
public where(propertyOrPropPathArray: keyof T | [keyof T, ...string[]], op: firestore.WhereFilterOp, value: any): Query<T> {
const fieldPath = this.getFieldPath(propertyOrPropPathArray);

return this.appendNativeQuery(this._native.where(fieldPath, op, value));
}

/**
* Applies an order by filter to the query.
* @param property The property to order by.
* @param sort The order direction. Default value is ascending.
*/
public orderBy(property: keyof T, sort?: firestore.OrderByDirection): Query<T> {
const field = this._fields.get(property as string);
if (field) {
return this.appendNativeQuery(this._native.orderBy(field.name, sort));
}
throw new Error(`Could not find property in ${this._collection.path}`);
public orderBy(propertyOrPropPathArray: keyof T | [keyof T, ...string[]], sort?: firestore.OrderByDirection): Query<T> {
const fieldPath = this.getFieldPath(propertyOrPropPathArray);

return this.appendNativeQuery(this._native.orderBy(fieldPath, sort));
}

/**
Expand Down Expand Up @@ -131,7 +154,6 @@ export default class Query<T extends Entity> implements IQuery<T> {
return new Query(
this._Entity,
this._collection,
this._fields,
query,
);
}
Expand Down
4 changes: 2 additions & 2 deletions src/types/collection.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ export interface IEntity {
}

export interface IQuery <T extends IEntity> {
where(property: keyof T, op: firestore.WhereFilterOp, value: any): IQuery<T>;
orderBy(property: keyof T, sort?: firestore.OrderByDirection): IQuery<T>;
where(property: keyof T | [keyof T, ...string[]], op: firestore.WhereFilterOp, value: any): IQuery<T>;
orderBy(property: keyof T | [keyof T, ...string[]], sort?: firestore.OrderByDirection): IQuery<T>;
limit(amount: number): IQuery<T>;
startAt(...fieldValues: any[]): IQuery<T>;
startAfter(...fieldValues: any[]): Query<T>;
Expand Down