Standard libraries that lift up your code.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

72 lines
2.3 KiB

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'
/**
* 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 {
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()))
}
}