UNPKG

@openhps/core

Version:

Open Hybrid Positioning System - Core component

130 lines (120 loc) 4.65 kB
import { Constructor } from '../data/decorators/'; import { DataServiceDriver, DataServiceOptions } from './DataServiceDriver'; import { FilterQuery } from './FilterQuery'; import { FindOptions } from './FindOptions'; import { MemoryQueryEvaluator } from './MemoryQueryEvaluator'; export class MemoryDataService<I, T> extends DataServiceDriver<I, T> { protected _data: Map<I, any> = new Map(); constructor(dataType: Constructor<T>, options?: DataServiceOptions<T>) { super(dataType, options); } public findByUID(uid: I): Promise<T> { return new Promise<T>((resolve, reject) => { if (this._data.has(uid)) { resolve(this.options.deserialize(this._data.get(uid))); } else { reject(`${this.dataType.name} with identifier #${uid} not found!`); } }); } public findOne(query?: FilterQuery<T>, options: FindOptions = {}): Promise<T> { return new Promise<T>((resolve, reject) => { this.findAll(query, { limit: 1, sort: options.sort, }) .then((results) => { if (results.length > 0) { return resolve(results[0]); } else { resolve(undefined); } }) .catch(reject); }); } public findAll(query?: FilterQuery<T>, options: FindOptions = {}): Promise<T[]> { return new Promise<T[]>((resolve) => { options.limit = options.limit || this._data.size; let data: T[] = []; this._data.forEach((object) => { if (MemoryQueryEvaluator.evaluate(object, query)) { data.push(object); if (!options.sort && data.length >= options.limit) { return; } } }); if (options.sort) { data = data .sort((a, b) => options.sort .map((s) => { const res1 = MemoryQueryEvaluator.getValueFromPath(s[1] > 0 ? a : b, s[0])[1]; const res2 = MemoryQueryEvaluator.getValueFromPath(s[1] > 0 ? b : a, s[0])[1]; if (typeof res1 === 'number') { return res1 - res2; } else if (typeof res1 === 'string') { return res1.localeCompare(res2); } else { return 0; } }) .reduce((a, b) => a + b), ) .slice(0, options.limit); } data = data.map(this.options.deserialize); resolve(data); }); } public insert(id: I, object: T): Promise<T> { return new Promise<T>((resolve) => { if (id && object) { this._data.set(id, this.options.serialize(object)); resolve(object); } else { resolve(undefined); } }); } public delete(id: I): Promise<void> { return new Promise<void>((resolve, reject) => { if (this._data.has(id)) { this._data.delete(id); resolve(); } else { reject(`Unable to delete! ${this.dataType.name} with identifier #${id} not found!`); } }); } public count(filter?: FilterQuery<T>): Promise<number> { return new Promise((resolve) => { if (filter === undefined) { resolve(this._data.size); } else { let count = 0; for (const [, value] of this._data) { if (MemoryQueryEvaluator.evaluate(value, filter)) { count++; } } resolve(count); } }); } public deleteAll(filter?: FilterQuery<T>): Promise<void> { return new Promise((resolve) => { if (filter === undefined) { this._data = new Map(); } else { for (const [key, value] of this._data) { if (MemoryQueryEvaluator.evaluate(value, filter)) { this.delete(key); } } } resolve(); }); } }