76 lines
2.5 KiB
TypeScript
76 lines
2.5 KiB
TypeScript
import {Container, Inject, Singleton} from '../../di'
|
|
import {DatabaseService} from '../DatabaseService'
|
|
import {PostgresConnection} from '../connection/PostgresConnection'
|
|
import {ErrorWithContext} from '../../util'
|
|
import {Unit} from '../../lifecycle/Unit'
|
|
import {Config} from '../../service/Config'
|
|
import {Logging} from '../../service/Logging'
|
|
import {MigratorFactory} from '../migrations/MigratorFactory'
|
|
import {SQLiteConnection} from '../connection/SQLiteConnection'
|
|
|
|
/**
|
|
* Application unit responsible for loading and creating database connections from config.
|
|
*/
|
|
@Singleton()
|
|
export class Database extends Unit {
|
|
@Inject()
|
|
protected readonly config!: Config
|
|
|
|
@Inject()
|
|
protected readonly dbService!: DatabaseService
|
|
|
|
@Inject()
|
|
protected readonly logging!: Logging
|
|
|
|
@Inject('injector')
|
|
protected readonly injector!: Container
|
|
|
|
/**
|
|
* Load the `database.connections` config and register Connection instances for each config.
|
|
* Automatically initializes the connections.
|
|
*/
|
|
public async up(): Promise<void> {
|
|
const connections = this.config.get('database.connections')
|
|
const promises = []
|
|
|
|
// Register the migrator factory
|
|
this.injector.registerFactory(this.injector.make(MigratorFactory))
|
|
|
|
for ( const key in connections ) {
|
|
if ( !Object.prototype.hasOwnProperty.call(connections, key) ) {
|
|
continue
|
|
}
|
|
|
|
const config = connections[key]
|
|
|
|
this.logging.info(`Initializing database connection: ${key}`)
|
|
this.logging.verbose(config)
|
|
|
|
let conn
|
|
if ( config?.dialect === 'postgres' ) {
|
|
conn = <PostgresConnection> this.app().make(PostgresConnection, key, config)
|
|
} else if ( config?.dialect === 'sqlite' ) {
|
|
conn = <SQLiteConnection> this.app().make(SQLiteConnection, key, config)
|
|
} else {
|
|
const e = new ErrorWithContext(`Invalid or missing database dialect: ${config.dialect}. Should be one of: postgres`)
|
|
e.context = { connectionName: key }
|
|
throw e
|
|
}
|
|
|
|
this.dbService.register(key, conn)
|
|
promises.push(conn.init())
|
|
}
|
|
|
|
await Promise.all(promises)
|
|
this.logging.info('Database connections opened.')
|
|
}
|
|
|
|
/**
|
|
* Close the configured connections cleanly before exit.
|
|
*/
|
|
public async down(): Promise<void> {
|
|
await Promise.all(this.dbService.names()
|
|
.map(name => this.dbService.get(name).close()))
|
|
}
|
|
}
|