Тесты работают, TS билдится
This commit is contained in:
1 parent
e08d9757bb
commit
9f3a64d76f
36 files changed
+17901
No files matched your search
+116
@@ -0,0 +1,116 @@
|
||||
import { Entity } from './entity'
|
||||
import { Storage } from './storage'
|
||||
|
||||
export class ErrFoundNotUniqEntity extends Error {}
|
||||
export class ErrEntityNotFound extends Error {}
|
||||
|
||||
export abstract class Repo<T extends Entity<any>> {
|
||||
protected _storage: Storage
|
||||
protected _entity: T
|
||||
|
||||
protected _limit: number = 0
|
||||
protected _offset: number = 0
|
||||
|
||||
/**
|
||||
* Возвращает объект соотв. сущности, например new App()
|
||||
*/
|
||||
abstract Entity(): T
|
||||
|
||||
/**
|
||||
* Возвращает название коллекции/таблицы/... хранящей записи соотв. сущностей
|
||||
*/
|
||||
abstract Name(): string
|
||||
|
||||
// @ts-ignore
|
||||
_transformer: (obj: any) => any
|
||||
|
||||
constructor(storage: Storage) {
|
||||
this._storage = storage
|
||||
this._entity = this.Entity()
|
||||
this.resetTransformer()
|
||||
}
|
||||
|
||||
resetTransformer() {
|
||||
this._transformer = function (obj: any): any {
|
||||
const entity = this.Entity()
|
||||
entity.data.fromObject(obj)
|
||||
entity._id = obj._id
|
||||
return entity
|
||||
}
|
||||
}
|
||||
|
||||
get storage(): Storage {
|
||||
return this._storage
|
||||
}
|
||||
|
||||
async save(entity: T): Promise<this> {
|
||||
const uniqKey = entity.data.uniqKey()
|
||||
entity._id = await this._storage.save(this.Name(), uniqKey, entity.data.toObject())
|
||||
return this
|
||||
}
|
||||
|
||||
async findById(id: string): Promise<T | null> {
|
||||
const uniqKey = this.Entity().data.uniqKey()
|
||||
const cursor = await this._storage.find(this.Name(), { [uniqKey]: id })
|
||||
const entryList = await cursor.toArray()
|
||||
if (entryList.length > 1) {
|
||||
throw new ErrFoundNotUniqEntity(
|
||||
`found few (${entryList.length}) entries in ${this.Name()} for id ${id}`
|
||||
)
|
||||
}
|
||||
if (entryList.length == 0) {
|
||||
throw new ErrEntityNotFound(`not found entry in [${this.Name()}] for id [${id}]`)
|
||||
}
|
||||
|
||||
return this._transformer(entryList[0])
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @protected
|
||||
*/
|
||||
async _findByParams(params: {}, limit?: number, order?: {}): Promise<T[]> {
|
||||
const cursor = await this._storage.find(this.Name(), params)
|
||||
if (limit && limit > 0) await cursor.limit(limit)
|
||||
if (order) await cursor.sort(order)
|
||||
const data = await cursor.toArray()
|
||||
const list = []
|
||||
for (let item of data) {
|
||||
list.push(this._transformer(item))
|
||||
}
|
||||
|
||||
return list
|
||||
}
|
||||
|
||||
async findMany(params: object, order?: object): Promise<T[]> {
|
||||
const cursor = await this._storage.find(this.Name(), params)
|
||||
if (this._offset > 0) await cursor.skip(this._offset)
|
||||
if (this._limit > 0) await cursor.limit(this._limit)
|
||||
if (order) await cursor.sort(order)
|
||||
const data = await cursor.toArray()
|
||||
const list = []
|
||||
for (let item of data) {
|
||||
list.push(this._transformer(item))
|
||||
}
|
||||
|
||||
return list
|
||||
}
|
||||
|
||||
shift(limit = 0, offset = 0) {
|
||||
this._limit = limit
|
||||
this._offset = offset
|
||||
return this
|
||||
}
|
||||
|
||||
async count(query?: object): Promise<number> {
|
||||
return this._storage.count(this.Name(), query)
|
||||
}
|
||||
|
||||
async remove(entity: T, silent = true): Promise<this> {
|
||||
const idName = entity.data.uniqKey()
|
||||
const id = entity.getUniqKey()
|
||||
const ok = await this._storage.remove(this.Name(), idName, id)
|
||||
if (!silent && !ok) throw new ErrEntityNotFound(`can not remove entry in ${this.Name()} for id ${id}`)
|
||||
return this
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user