diff --git a/src/commondao/common.dao.ts b/src/commondao/common.dao.ts index 99f5d8c..6607720 100644 --- a/src/commondao/common.dao.ts +++ b/src/commondao/common.dao.ts @@ -88,8 +88,8 @@ export class CommonDao< } // CREATE - create(input: Partial, opt: CommonDaoOptions = {}): Saved { - let bm = this.cfg.hooks!.beforeCreate!(input) as BM + create(part: Partial, opt: CommonDaoOptions = {}): Saved { + let bm = this.cfg.hooks!.beforeCreate!(part) as BM bm = this.validateAndConvert(bm, this.cfg.bmSchema, DBModelType.BM, opt) // If no SCHEMA - return as is @@ -124,29 +124,18 @@ export class CommonDao< return bm || null } - async getByIdOrCreate( - id: string, - bmToCreate: Partial, - opt?: CommonDaoOptions, - ): Promise> { - const bm = await this.getById(id, opt) - if (bm) return bm - - return this.create({ ...bmToCreate, id }, opt) - } - - async getByIdOrEmpty(id: string, opt?: CommonDaoOptions): Promise> { + async getByIdOrEmpty(id: string, part: Partial, opt?: CommonDaoOptions): Promise> { const bm = await this.getById(id, opt) if (bm) return bm - return this.create({ id } as Partial, opt) + return this.create({ ...part, id }, opt) } - async getByIdAsDBMOrEmpty(id: string, opt?: CommonDaoOptions): Promise { + async getByIdAsDBMOrEmpty(id: string, part: Partial, opt?: CommonDaoOptions): Promise { const dbm = await this.getByIdAsDBM(id, opt) if (dbm) return dbm - const bm: BM = this.create({ id } as Partial, opt) as any + const bm: BM = this.create({ ...part, id }, opt) as any return await this.bmToDBM(bm, opt) } @@ -614,7 +603,7 @@ export class CommonDao< ): Promise> { return await this.save( { - ...(await this.getByIdOrCreate(id, patch, opt)), + ...(await this.getByIdOrEmpty(id, patch, opt)), ...patch, } as any, opt, diff --git a/src/kv/commonKeyValueDao.ts b/src/kv/commonKeyValueDao.ts index be82a78..212ff9a 100644 --- a/src/kv/commonKeyValueDao.ts +++ b/src/kv/commonKeyValueDao.ts @@ -26,8 +26,9 @@ export interface CommonKeyValueDaoCfg { logStarted?: boolean hooks?: { - mapValueToBuffer(v: T): Promise - mapBufferToValue(b: Buffer): Promise + mapValueToBuffer?: (v: T) => Promise + mapBufferToValue?: (b: Buffer) => Promise + beforeCreate?: (v: Partial) => Partial } } @@ -45,19 +46,46 @@ export class CommonKeyValueDao { await this.cfg.db.createTable(this.cfg.table, opt) } + create(input: Partial = {}): T { + return { + ...this.cfg.hooks?.beforeCreate?.(input), + } as T + } + async getById(id?: string): Promise { if (!id) return null const [r] = await this.getByIds([id]) return r?.[1] || null } + async getByIdOrEmpty(id: string, part: Partial = {}): Promise { + const [r] = await this.getByIds([id]) + if (r) return r[1] + + return { + ...this.cfg.hooks?.beforeCreate?.({}), + ...part, + } as T + } + + async patch(id: string, patch: Partial): Promise { + const v: T = { + ...(await this.getByIdOrEmpty(id)), + ...patch, + } + + await this.save(id, v) + + return v + } + async getByIds(ids: string[]): Promise[]> { const entries = await this.cfg.db.getByIds(this.cfg.table, ids) if (!this.cfg.hooks?.mapBufferToValue) return entries as any return await pMap(entries, async ([id, buf]) => [ id, - await this.cfg.hooks!.mapBufferToValue(buf), + await this.cfg.hooks!.mapBufferToValue!(buf), ]) } @@ -73,7 +101,7 @@ export class CommonKeyValueDao { } else { bufferEntries = await pMap(entries, async ([id, v]) => [ id, - await this.cfg.hooks!.mapValueToBuffer(v), + await this.cfg.hooks!.mapValueToBuffer!(v), ]) } @@ -100,7 +128,7 @@ export class CommonKeyValueDao { // todo: consider it when readableMap supports `errorMode: SUPPRESS` // readableMap(this.cfg.db.streamValues(this.cfg.table, limit), async buf => await this.cfg.hooks!.mapBufferToValue(buf)) return this.cfg.db.streamValues(this.cfg.table, limit).pipe( - transformMap(async buf => await this.cfg.hooks!.mapBufferToValue(buf), { + transformMap(async buf => await this.cfg.hooks!.mapBufferToValue!(buf), { errorMode: ErrorMode.SUPPRESS, // cause .pipe cannot propagate errors }), ) @@ -112,7 +140,7 @@ export class CommonKeyValueDao { } return this.cfg.db.streamEntries(this.cfg.table, limit).pipe( - transformMap(async ([id, buf]) => [id, await this.cfg.hooks!.mapBufferToValue(buf)], { + transformMap(async ([id, buf]) => [id, await this.cfg.hooks!.mapBufferToValue!(buf)], { errorMode: ErrorMode.SUPPRESS, // cause .pipe cannot propagate errors }), )