UNPKG

@citrineos/data

Version:

The OCPP data module which includes all persistence layer implementation.

116 lines 5.18 kB
// SPDX-FileCopyrightText: 2025 Contributors to the CitrineOS Project // // SPDX-License-Identifier: Apache-2.0 import { CrudRepository } from '@citrineos/base'; import {} from 'sequelize-typescript'; import { DefaultSequelizeInstance } from '../util.js'; import { Logger } from 'tslog'; import { QueryTypes } from 'sequelize'; export class SequelizeRepository extends CrudRepository { s; namespace; logger; constructor(config, namespace, logger, sequelizeInstance) { super(); this.s = sequelizeInstance ?? DefaultSequelizeInstance.getInstance(config, logger); this.namespace = namespace; this.logger = logger ? logger.getSubLogger({ name: this.constructor.name }) : new Logger({ name: this.constructor.name }); } async readByKey(tenantId, key, namespace = this.namespace) { return await this.s.models[namespace].findByPk(key).then((row) => row); } async readAllByQuery(tenantId, query, namespace = this.namespace) { return await this.s.models[namespace] .findAll(query) .then((row) => row); } async readAllBySqlString(tenantId, sqlString, _namespace = this.namespace) { return await this.s.query(`${sqlString}`, { type: QueryTypes.SELECT }); } async readNextValue(tenantId, columnName, query, startValue, namespace = this.namespace) { const options = query ? query : undefined; const maxValue = await this.s.models[namespace].max(columnName, options); if (maxValue === null || maxValue === undefined) { // maxValue can be 0, so we need to specifically check for null or undefined return startValue ?? 1; } if (typeof maxValue !== 'number' || isNaN(maxValue)) { throw new Error(`Max value ${maxValue} on ${columnName} is invalid.`); } return maxValue + 1; } async existsByKey(tenantId, key, namespace = this.namespace) { return await this.s.models[namespace].findByPk(key).then((row) => row !== null); } async existByQuery(tenantId, query, namespace = this.namespace) { return await this.s.models[namespace].findAll(query).then((row) => row.length); } async findAndCount(tenantId, options, namespace = this.namespace) { return this.s.models[namespace].findAndCountAll(options); } async _create(tenantId, value, _namespace = this.namespace) { return await value.save(); } async _bulkCreate(tenantId, values, namespace = this.namespace) { return await this.s.models[namespace].bulkCreate(values); } async _createByKey(tenantId, value, key, namespace = this.namespace) { const primaryKey = this.s.models[namespace].primaryKeyAttribute; value.setDataValue(primaryKey, key); return (await this.s.models[namespace].create(value.toJSON())); } async _readOrCreateByQuery(tenantId, query, namespace = this.namespace) { return await this.s.models[namespace] .findOrCreate(query) .then((result) => [result[0], result[1]]); } async _updateByKey(tenantId, value, key, namespace = this.namespace) { const primaryKey = this.s.models[namespace].primaryKeyAttribute; return await this._updateAllByQuery(tenantId, value, { where: { [primaryKey]: key } }, namespace).then((rows) => (rows && rows.length === 1 ? rows[0] : undefined)); } async _updateAllByQuery(tenantId, value, query, namespace = this.namespace) { const updateOptions = query; updateOptions.returning = true; // Lengthy type conversion to satisfy sequelize-typescript return await this.s.models[namespace] .update(value, updateOptions) .then((result) => result[1]); } async _deleteByKey(tenantId, key, namespace = this.namespace) { return this.s.transaction(async (transaction) => { const entryToDelete = await this.s.models[namespace] .findByPk(key, { transaction }) .then((row) => row); if (entryToDelete) { await this.s.models[namespace].destroy({ where: { [this.s.models[namespace].primaryKeyAttribute]: key }, transaction, }); return entryToDelete; } else { return undefined; } }); } async _deleteAllByQuery(tenantId, query, namespace = this.namespace) { return this.s.transaction(async (transaction) => { const entriesToDelete = await this.s.models[namespace] .findAll({ ...query, transaction, }) .then((rows) => rows); const deletedCount = await this.s.models[namespace].destroy({ ...query, transaction }); if (entriesToDelete.length === deletedCount) { return entriesToDelete; } else { throw new Error(`Deleted ${deletedCount} entries, expected ${entriesToDelete.length}`); } }); } } //# sourceMappingURL=Base.js.map