110 lines
3.9 KiB
TypeScript
110 lines
3.9 KiB
TypeScript
import type { MikroOrmModuleAsyncOptions } from '@mikro-orm/nestjs';
|
|
import { ConfigService } from '@nestjs/config';
|
|
import { PostgreSqlDriver } from '@mikro-orm/postgresql';
|
|
// import { defineConfig } from '@mikro-orm/postgresql';
|
|
|
|
import type { Logger } from '@nestjs/common';
|
|
import { MIKRO_ORM_QUERY_LOGGER } from '../common/constants';
|
|
import { mikroOrmQueryLoggerProvider } from '../common/providers/mikro-orm-logger.provider';
|
|
|
|
const dataBaseConfig: MikroOrmModuleAsyncOptions = {
|
|
// entities: ['dist/**/*.entity.js'],
|
|
// entitiesTs: ['src/**/*.entity.ts'],
|
|
// dbName: 'your_db_name',
|
|
// type: 'postgresql',
|
|
// user: 'your_user',
|
|
// password: 'your_password',
|
|
// host: 'localhost',
|
|
// port: 5432,
|
|
// debug: true,
|
|
|
|
inject: [ConfigService, MIKRO_ORM_QUERY_LOGGER],
|
|
providers: [mikroOrmQueryLoggerProvider],
|
|
useFactory: (configService: ConfigService, logger: Logger) => {
|
|
const DB_PASS = configService.getOrThrow<string>('DB_PASS');
|
|
const DB_USER = configService.getOrThrow<string>('DB_USER');
|
|
const DB_HOST = configService.getOrThrow<string>('DB_HOST');
|
|
const DB_PORT = configService.getOrThrow<number>('DB_PORT');
|
|
const DB_NAME = configService.getOrThrow<string>('DB_NAME');
|
|
const encodedPassword = encodeURIComponent(DB_PASS);
|
|
const isProduction = configService.getOrThrow<string>('NODE_ENV') === 'production';
|
|
|
|
return ({
|
|
// entities: ['dist/**/*.entity.js'],
|
|
entitiesTs: ['src/**/*.entity.ts'],
|
|
driver: PostgreSqlDriver,
|
|
autoLoadEntities: true,
|
|
dbName: DB_NAME,
|
|
debug: !isProduction,
|
|
clientUrl: `postgres://${DB_USER}:${encodedPassword}@${DB_HOST}:${DB_PORT}`,
|
|
ensureDatabase: isProduction
|
|
? false
|
|
: {
|
|
forceCheck: true,
|
|
create: true,
|
|
schema: 'update',
|
|
},
|
|
forceUtcTimezone: true,
|
|
pool: {
|
|
min: isProduction ? 5 : 2,
|
|
max: isProduction ? 20 : 10,
|
|
idleTimeoutMillis: 30000,
|
|
acquireTimeoutMillis: 30000,
|
|
reapIntervalMillis: 1000,
|
|
createTimeoutMillis: 15000,
|
|
destroyTimeoutMillis: 5000,
|
|
},
|
|
logger: isProduction ? message => logger.log(message) : message => logger.debug(message),
|
|
schemaGenerator: {
|
|
// createForeignKey: !isProduction,
|
|
disableForeignKeys: false,
|
|
// createIndex: true,
|
|
},
|
|
migrations: {
|
|
path: './database/migrations',
|
|
pathTs: './database/migrations',
|
|
tableName: 'migrations',
|
|
transactional: true,
|
|
allOrNothing: true,
|
|
dropTables: false,
|
|
safe: true,
|
|
emit: 'ts',
|
|
},
|
|
connect: true,
|
|
allowGlobalContext: true,
|
|
driverOptions: {
|
|
connection: {
|
|
keepAlive: true,
|
|
keepAliveInitialDelayMillis: 10000,
|
|
statement_timeout: 60000,
|
|
query_timeout: 60000,
|
|
idle_in_transaction_session_timeout: 60000,
|
|
connectionTimeoutMillis: 10000,
|
|
application_name: configService.getOrThrow<string>('DB_NAME'),
|
|
},
|
|
connectionRetries: 5,
|
|
connectionRetryDelay: 3000,
|
|
validateConnection: (connection: any) => {
|
|
try {
|
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
return !!(connection && !connection.closed);
|
|
} catch (e: unknown) {
|
|
logger.error(`Connection validation failed: ${(e as Error).message}`);
|
|
return false;
|
|
}
|
|
},
|
|
poolErrorHandler: (err: Error) => {
|
|
logger.error(`PostgreSQL pool error: ${err.message}`);
|
|
if (err.message.includes('ECONNRESET') || err.message.includes('Connection terminated unexpectedly')) {
|
|
logger.warn('Connection reset detected, will attempt to reconnect');
|
|
return true;
|
|
}
|
|
return false;
|
|
},
|
|
},
|
|
});
|
|
},
|
|
};
|
|
|
|
export default dataBaseConfig;
|