DataSource.ts 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import { DataSource, EntityTarget, LoggerOptions, ObjectLiteral, Repository } from 'typeorm'
  2. import { MysqlConnectionOptions } from 'typeorm/driver/mysql/MysqlConnectionOptions'
  3. import { TypeORMRevision } from '../Infra/TypeORM/TypeORMRevision'
  4. import { Env } from './Env'
  5. import { SqliteConnectionOptions } from 'typeorm/driver/sqlite/SqliteConnectionOptions'
  6. export class AppDataSource {
  7. private dataSource: DataSource | undefined
  8. constructor(private env: Env) {}
  9. getRepository<Entity extends ObjectLiteral>(target: EntityTarget<Entity>): Repository<Entity> {
  10. if (!this.dataSource) {
  11. throw new Error('DataSource not initialized')
  12. }
  13. return this.dataSource.getRepository(target)
  14. }
  15. async initialize(): Promise<void> {
  16. this.env.load()
  17. const isConfiguredForMySQL = this.env.get('DB_TYPE') === 'mysql'
  18. const maxQueryExecutionTime = this.env.get('DB_MAX_QUERY_EXECUTION_TIME', true)
  19. ? +this.env.get('DB_MAX_QUERY_EXECUTION_TIME', true)
  20. : 45_000
  21. const commonDataSourceOptions = {
  22. maxQueryExecutionTime,
  23. entities: [TypeORMRevision],
  24. migrations: [`${__dirname}/../../migrations/${isConfiguredForMySQL ? 'mysql' : 'sqlite'}/*.js`],
  25. migrationsRun: true,
  26. logging: <LoggerOptions>this.env.get('DB_DEBUG_LEVEL', true) ?? 'info',
  27. }
  28. if (isConfiguredForMySQL) {
  29. const inReplicaMode = this.env.get('DB_REPLICA_HOST', true) ? true : false
  30. const replicationConfig = {
  31. master: {
  32. host: this.env.get('DB_HOST'),
  33. port: parseInt(this.env.get('DB_PORT')),
  34. username: this.env.get('DB_USERNAME'),
  35. password: this.env.get('DB_PASSWORD'),
  36. database: this.env.get('DB_DATABASE'),
  37. },
  38. slaves: [
  39. {
  40. host: this.env.get('DB_REPLICA_HOST', true),
  41. port: parseInt(this.env.get('DB_PORT')),
  42. username: this.env.get('DB_USERNAME'),
  43. password: this.env.get('DB_PASSWORD'),
  44. database: this.env.get('DB_DATABASE'),
  45. },
  46. ],
  47. removeNodeErrorCount: 10,
  48. restoreNodeTimeout: 5,
  49. }
  50. const mySQLDataSourceOptions: MysqlConnectionOptions = {
  51. ...commonDataSourceOptions,
  52. type: 'mysql',
  53. charset: 'utf8mb4',
  54. supportBigNumbers: true,
  55. bigNumberStrings: false,
  56. replication: inReplicaMode ? replicationConfig : undefined,
  57. host: inReplicaMode ? undefined : this.env.get('DB_HOST'),
  58. port: inReplicaMode ? undefined : parseInt(this.env.get('DB_PORT')),
  59. username: inReplicaMode ? undefined : this.env.get('DB_USERNAME'),
  60. password: inReplicaMode ? undefined : this.env.get('DB_PASSWORD'),
  61. database: inReplicaMode ? undefined : this.env.get('DB_DATABASE'),
  62. }
  63. this.dataSource = new DataSource(mySQLDataSourceOptions)
  64. } else {
  65. const sqliteDataSourceOptions: SqliteConnectionOptions = {
  66. ...commonDataSourceOptions,
  67. type: 'sqlite',
  68. database: this.env.get('DB_SQLITE_DATABASE_PATH'),
  69. enableWAL: true,
  70. busyErrorRetry: 2000,
  71. }
  72. this.dataSource = new DataSource(sqliteDataSourceOptions)
  73. }
  74. await this.dataSource.initialize()
  75. }
  76. }