UNPKG

@opra/sqb

Version:

Opra SQB adapter package

309 lines (308 loc) 10.1 kB
import { ResourceNotAvailableError } from '@opra/common'; import { SQBAdapter } from './sqb-adapter.js'; import { SqbEntityService } from './sqb-entity-service.js'; /** * Service for managing a collection of entities backed by an SQB data source. * * @typeParam T - The entity type managed by this service */ export class SqbCollectionService extends SqbEntityService { /** * Default maximum number of records returned by `findMany`. */ defaultLimit; /** * Constructs a new instance. * * @param dataType - The data type of the collection elements. * @param options - Options for the collection service. */ constructor(dataType, options) { super(dataType, options); this.defaultLimit = options?.defaultLimit || 100; } /** * Asserts that a resource with the given ID exists. * Throws {@link ResourceNotAvailableError} if it does not. * * @param id - The ID of the resource to check. * @param options - Optional existence check options. * @throws {@link ResourceNotAvailableError} If the resource does not exist. */ async assert(id, options) { if (!(await this.exists(id, options))) throw new ResourceNotAvailableError(this.getResourceName(), id); } async create(input, options) { const command = { crud: 'create', method: 'create', byId: false, input, options, }; return this._executeCommand(command, () => this._create(command)); } /** * Creates a new resource without returning it. * * @param input - The input data for the new resource. * @param options - Optional create options. */ async createOnly(input, options) { const command = { crud: 'create', method: 'createOnly', byId: false, input, options, }; return this._executeCommand(command, () => this._createOnly(command)); } /** * Returns the number of records matching the given options. * * @param options - Options for the count operation. * @returns The number of matching records. */ async count(options) { const command = { crud: 'read', method: 'count', byId: false, options, }; return this._executeCommand(command, async () => { const filter = SQBAdapter.prepareFilter([ await this._getCommonFilter(command), command.options?.filter, ]); command.options = { ...command.options, filter }; return this._count(command); }); } /** * Deletes the record with the given ID. * * @param id - The ID of the record to delete. * @param options - Optional delete options. * @returns The number of records deleted. */ async delete(id, options) { const command = { crud: 'delete', method: 'delete', byId: true, documentId: id, options, }; return this._executeCommand(command, async () => { const filter = SQBAdapter.prepareFilter([ await this._getCommonFilter(command), command.options?.filter, ]); command.options = { ...command.options, filter }; return this._delete(command); }); } /** * Deletes all records matching the given options. * * @param options - Options including filter criteria. * @returns The number of records deleted. */ async deleteMany(options) { const command = { crud: 'delete', method: 'deleteMany', byId: false, options, }; return this._executeCommand(command, async () => { const filter = SQBAdapter.prepareFilter([ await this._getCommonFilter(command), command.options?.filter, ]); command.options = { ...command.options, filter }; return this._deleteMany(command); }); } /** * Checks whether a record with the given ID exists. * * @param id - The ID to check. * @param options - Optional query options. * @returns `true` if the record exists, `false` otherwise. */ async exists(id, options) { const command = { crud: 'read', method: 'exists', byId: true, documentId: id, options, }; return this._executeCommand(command, async () => { const filter = SQBAdapter.prepareFilter([ await this._getCommonFilter(command), command.options?.filter, ]); command.options = { ...command.options, filter }; return this._exists(command); }); } /** * Checks whether any record matching the given options exists. * * @param options - Optional query options. * @returns `true` if at least one matching record exists, `false` otherwise. */ async existsOne(options) { const command = { crud: 'read', method: 'existsOne', byId: false, options, }; return this._executeCommand(command, async () => { const filter = SQBAdapter.prepareFilter([ await this._getCommonFilter(command), command.options?.filter, ]); command.options = { ...command.options, filter }; return this._existsOne(command); }); } async findById(id, options) { const command = { crud: 'read', method: 'findById', byId: true, documentId: id, options, }; return this._executeCommand(command, async () => { const documentFilter = await this._getCommonFilter(command); const filter = SQBAdapter.prepareFilter([ documentFilter, command.options?.filter, ]); command.options = { ...command.options, filter }; return this._findById(command); }); } async findOne(options) { const command = { crud: 'read', method: 'findOne', byId: false, options, }; return this._executeCommand(command, async () => { const filter = SQBAdapter.prepareFilter([ await this._getCommonFilter(command), command.options?.filter, ]); command.options = { ...command.options, filter }; return this._findOne(command); }); } async findMany(options) { const command = { crud: 'read', method: 'findMany', byId: false, options, }; return this._executeCommand(command, async () => { const filter = SQBAdapter.prepareFilter([ await this._getCommonFilter(command), command.options?.filter, ]); const limit = command.options?.limit || this.defaultLimit; command.options = { ...command.options, filter, limit }; return this._findMany(command); }); } async findManyWithCount(options) { const [items, count] = await Promise.all([ this.findMany(options), this.count(options), ]); return { count, items }; } async get(id, options) { const out = await this.findById(id, options); if (!out) throw new ResourceNotAvailableError(this.getResourceName(), id); return out; } async update(id, input, options) { const command = { crud: 'update', method: 'update', documentId: id, byId: true, input, options, }; return this._executeCommand(command, async () => { const filter = SQBAdapter.prepareFilter([ await this._getCommonFilter(command), command.options?.filter, ]); command.options = { ...command.options, filter }; return this._update(command); }); } /** * Updates a record by ID without returning it. * * @param id - The ID of the record to update. * @param input - The fields to update. * @param options - Optional update options. * @returns The number of records modified. */ async updateOnly(id, input, options) { const command = { crud: 'update', method: 'update', documentId: id, byId: true, input, options, }; return this._executeCommand(command, async () => { const filter = SQBAdapter.prepareFilter([ await this._getCommonFilter(command), command.options?.filter, ]); command.options = { ...command.options, filter }; return this._updateOnly(command); }); } /** * Updates all records matching the given options. * * @param input - The fields to update. * @param options - Options including filter criteria. * @returns The number of records modified. */ async updateMany(input, options) { const command = { crud: 'update', method: 'updateMany', byId: false, input, options, }; return this._executeCommand(command, async () => { const filter = SQBAdapter.prepareFilter([ await this._getCommonFilter(command), command.options?.filter, ]); command.options = { ...command.options, filter }; return this._updateMany(command); }); } }