Presupuestador_web/server/src/contexts/common/infrastructure/sequelize/SequelizeAdapter.ts

162 lines
4.2 KiB
TypeScript
Raw Normal View History

2024-04-23 15:29:38 +00:00
import { config } from "@/config";
import rTracer from "cls-rtracer";
import { DataTypes, Sequelize } from "sequelize";
import { initLogger } from "@/infrastructure/logger";
import * as glob from "glob";
import * as path from "path";
import { IAdapter } from "../../domain";
import { InfrastructureError } from "../InfrastructureError";
import {
SequelizeBusinessTransaction,
SequelizeBusinessTransactionType,
} from "./SequelizeBusinessTransaction";
import { ISequelizeModels } from "./SequelizeModel.interface";
import { ISequelizeQueryBuilder } from "./queryBuilder/SequelizeQueryBuilder";
//import * as dotenv from "dotenv";
//dotenv.config();
export interface ISequelizeAdapter extends IAdapter {
queryBuilder: ISequelizeQueryBuilder;
2024-04-24 10:48:49 +00:00
startTransaction: () => SequelizeBusinessTransactionType;
2024-04-23 15:29:38 +00:00
getModel: (modelName: string) => any;
hasModel: (modelName: string) => boolean;
}
export class SequelizeAdapter implements ISequelizeAdapter {
// eslint-disable-next-line no-use-before-define
private static instance: SequelizeAdapter;
public static getInstance(params: {
queryBuilder: ISequelizeQueryBuilder;
}): SequelizeAdapter {
if (!SequelizeAdapter.instance) {
SequelizeAdapter.instance = SequelizeAdapter.create(params);
}
return SequelizeAdapter.instance;
}
private static create(params: { queryBuilder: ISequelizeQueryBuilder }) {
const { queryBuilder } = params;
const connection = initConnection();
2024-05-16 11:56:46 +00:00
const models = registerModels(connection);
return new SequelizeAdapter(connection, models, queryBuilder);
2024-04-23 15:29:38 +00:00
}
private _connection: Sequelize;
private _models: ISequelizeModels;
private _queryBuilder: ISequelizeQueryBuilder;
protected constructor(
connection: Sequelize,
models: ISequelizeModels,
queryBuilder: ISequelizeQueryBuilder,
) {
this._connection = connection;
this._models = models;
this._queryBuilder = queryBuilder;
}
get queryBuilder(): ISequelizeQueryBuilder {
return this._queryBuilder;
}
public startTransaction(): SequelizeBusinessTransactionType {
return new SequelizeBusinessTransaction(this._connection);
}
public sync(params) {
return this._connection.sync(params);
}
2024-05-19 22:04:23 +00:00
public getModel(modelName: string): any {
2024-04-23 15:29:38 +00:00
if (this.hasModel(modelName)) {
return this._models[modelName];
}
throw InfrastructureError.create(
InfrastructureError.RESOURCE_NOT_FOUND_ERROR,
2024-05-16 11:56:46 +00:00
`[SequelizeAdapter] ${modelName} sequelize model not exists!`,
2024-04-23 15:29:38 +00:00
);
}
public hasModel(modelName: string): boolean {
return !!this._models[modelName];
}
}
function initConnection(): Sequelize {
const { username, password, database, host, dialect, port } = config.database;
const logger = initLogger(rTracer);
logger.debug("=========================> CONECTO A SEQUELIZE");
return new Sequelize(database, username, password, {
host,
dialect,
port,
dialectOptions: {
multipleStatements: true,
dateStrings: true,
typeCast: true,
//timezone: "Z",
},
pool: {
max: 5,
min: 0,
acquire: 60000,
idle: 10000,
},
logQueryParameters: true,
logging: (sql, timing) => console.debug(sql), //logger.debug(sql, timing),
define: {
charset: "utf8mb4",
collate: "utf8mb4_unicode_ci",
//freezeTableName: true,
underscored: true,
timestamps: true,
},
});
}
2024-05-16 11:56:46 +00:00
function registerModels(connection: Sequelize): ISequelizeModels {
2024-04-23 15:29:38 +00:00
const cwd = path.resolve(`${__dirname}/../../../`);
const models: ISequelizeModels = {};
// Get all models
const globOptions = {
cwd,
nocase: true,
nodir: true,
absolute: true,
};
glob.sync("**/*.model.{js,ts}", globOptions).forEach(function (file) {
console.log(`>> ${file}`);
// eslint-disable-next-line @typescript-eslint/no-var-requires
const modelDef = require(path.join(file)).default;
const model =
typeof modelDef === "function" ? modelDef(connection, DataTypes) : false;
if (model) models[model.name] = model;
});
for (const modelName in models) {
const model = models[modelName];
if (model.associate) {
model.associate(connection, models);
}
if (model.hooks) {
model.hooks(connection);
}
}
return models;
}