@opra/sqb
Version:
Opra SQB adapter package
169 lines (168 loc) • 5.99 kB
JavaScript
import { ResourceNotAvailableError } from '@opra/common';
import { EntityMetadata } from '@sqb/connect';
import { SQBAdapter } from './sqb-adapter.js';
import { SqbEntityService } from './sqb-entity-service.js';
/**
* @class SqbSingletonService
* @template T - The data type class type of the resource
*/
export class SqbSingletonService extends SqbEntityService {
/**
* Constructs a new instance
*
* @param {Type | string} dataType - The data type of the array elements.
* @param {SqbSingletonService.Options} [options] - The options for the array service.
* @constructor
*/
constructor(dataType, options) {
super(dataType, options);
this.id = options?.id || 1;
}
/**
* Asserts the existence of a resource based on the given options.
*
* @returns {Promise<void>} A Promise that resolves when the resource exists.
* @throws {ResourceNotAvailableError} If the resource does not exist.
*/
async assert(options) {
if (!(await this.exists(options)))
throw new ResourceNotAvailableError(this.getResourceName());
}
async create(input, options) {
const command = {
crud: 'create',
method: 'create',
byId: false,
input,
options,
};
return this._executeCommand(command, async () => {
const primaryFields = EntityMetadata.getPrimaryIndexColumns(this.entityMetadata);
const data = { ...command.input };
if (primaryFields.length > 1) {
if (typeof primaryFields !== 'object') {
throw new TypeError(`"${this.entityMetadata.name}" should has multiple primary key fields. So you should provide and object that contains key fields`);
}
for (const field of primaryFields) {
data[field.name] = this.id[field.name];
}
}
else
data[primaryFields[0].name] = this.id;
command.input = data;
return await this._create(command);
});
}
/**
* Deletes the singleton record
*
* @param {SqbSingletonService.DeleteOptions} [options] - The options object
* @return {Promise<number>} - A Promise that resolves to the number of records deleted
*/
async delete(options) {
const command = {
crud: 'delete',
method: 'delete',
byId: true,
documentId: this.id,
options,
};
return this._executeCommand(command, async () => {
const filter = SQBAdapter.parseFilter([
await this._getCommonFilter(command),
command.options?.filter,
]);
command.options = { ...command.options, filter };
return this._delete(command);
});
}
/**
* Checks if the singleton record exists.
*
* @param {SqbSingletonService.ExistsOptions} [options] - The options for the query (optional).
* @return {Promise<boolean>} - A Promise that resolves to a boolean indicating whether the record exists or not.
*/
async exists(options) {
const command = {
crud: 'read',
method: 'exists',
byId: true,
documentId: this.id,
options,
};
return this._executeCommand(command, async () => {
const filter = SQBAdapter.parseFilter([
await this._getCommonFilter(command),
command.options?.filter,
]);
command.options = { ...command.options, filter };
return this._exists(command);
});
}
async find(options) {
const command = {
crud: 'read',
method: 'findById',
byId: true,
documentId: this.id,
options,
};
return this._executeCommand(command, async () => {
const filter = SQBAdapter.parseFilter([
await this._getCommonFilter(command),
command.options?.filter,
]);
command.options = { ...command.options, filter };
return this._findById(command);
});
}
async get(options) {
const out = await this.find(options);
if (!out)
throw new ResourceNotAvailableError(this.getResourceName());
return out;
}
async update(input, options) {
const command = {
crud: 'update',
method: 'update',
documentId: this.id,
byId: true,
input,
options,
};
return this._executeCommand(command, async () => {
const filter = SQBAdapter.parseFilter([
await this._getCommonFilter(command),
command.options?.filter,
]);
command.options = { ...command.options, filter };
return this._update(command);
});
}
/**
* Updates the singleton and returns updated record count
*
* @param {PatchDTO<T>} input - The partial input data to update the document with.
* @param {SqbSingletonService.UpdateOptions} options - The options for updating the document.
* @returns {Promise<number>} - A promise that resolves to the number of documents modified.
*/
async updateOnly(input, options) {
const command = {
crud: 'update',
method: 'update',
documentId: this.id,
byId: true,
input,
options,
};
return this._executeCommand(command, async () => {
const filter = SQBAdapter.parseFilter([
await this._getCommonFilter(command),
command.options?.filter,
]);
command.options = { ...command.options, filter };
return this._updateOnly(command);
});
}
}