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.
105 lines
3.2 KiB
105 lines
3.2 KiB
import {Directive, OptionDefinition} from '../../cli'
|
|
import {Container, Inject, Injectable} from '../../di'
|
|
import {EventBus} from '../../event/EventBus'
|
|
import {Migrator} from '../migrations/Migrator'
|
|
import {Migrations} from '../services/Migrations'
|
|
import {RollingBackMigrationEvent} from '../migrations/events/RollingBackMigrationEvent'
|
|
import {RolledBackMigrationEvent} from '../migrations/events/RolledBackMigrationEvent'
|
|
import {EventSubscription} from '../../event/types'
|
|
import {NothingToMigrateError} from '../migrations/NothingToMigrateError'
|
|
import {CLIDirective} from '../../cli/decorators'
|
|
|
|
/**
|
|
* CLI directive that undoes applied migrations using the default Migrator.
|
|
* @fixme Support dry run mode
|
|
*/
|
|
@Injectable()
|
|
@CLIDirective()
|
|
export class RollbackDirective extends Directive {
|
|
@Inject()
|
|
protected readonly bus!: EventBus
|
|
|
|
@Inject('injector')
|
|
protected readonly injector!: Container
|
|
|
|
@Inject()
|
|
protected readonly migrations!: Migrations
|
|
|
|
/** Event bus subscriptions. */
|
|
protected subscriptions: EventSubscription[] = []
|
|
|
|
getKeywords(): string | string[] {
|
|
return ['rollback']
|
|
}
|
|
|
|
getDescription(): string {
|
|
return 'roll-back applied migrations'
|
|
}
|
|
|
|
getOptions(): OptionDefinition[] {
|
|
return [
|
|
'--identifier -i {name} | roll-back a specific migration, by identifier',
|
|
]
|
|
}
|
|
|
|
getHelpText(): string {
|
|
return [
|
|
'Use this command to undo one or more migrations that were applied.',
|
|
'',
|
|
'By default, the command will undo all of the migrations applied the last time the migrate command was run.',
|
|
'',
|
|
'To undo a specific migration, pass its identifier using the --identifier option.',
|
|
'',
|
|
].join('\n')
|
|
}
|
|
|
|
async handle(): Promise<void> {
|
|
await this.registerListeners()
|
|
|
|
const identifier = this.option('identifier')
|
|
|
|
let identifiers
|
|
if ( identifier ) {
|
|
identifiers = [identifier]
|
|
}
|
|
|
|
let error
|
|
try {
|
|
await (this.injector.make<Migrator>(Migrator)).rollback(identifiers)
|
|
} catch (e) {
|
|
if ( e instanceof NothingToMigrateError ) {
|
|
this.info(e.message)
|
|
} else {
|
|
error = e
|
|
this.error(e)
|
|
}
|
|
} finally {
|
|
await this.removeListeners()
|
|
}
|
|
|
|
if ( error ) {
|
|
throw error
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Register event-bus listeners to print messages for the user.
|
|
* @protected
|
|
*/
|
|
protected async registerListeners(): Promise<void> {
|
|
this.subscriptions.push(await this.bus.subscribe(RollingBackMigrationEvent, event => {
|
|
this.info(`Rolling-back migration ${event.migration.identifier}...`)
|
|
}))
|
|
|
|
this.subscriptions.push(await this.bus.subscribe(RolledBackMigrationEvent, event => {
|
|
this.success(`Rolled-back migration: ${event.migration.identifier}`)
|
|
}))
|
|
}
|
|
|
|
/** Remove event bus listeners before finish. */
|
|
protected async removeListeners(): Promise<void> {
|
|
await Promise.all(this.subscriptions.map(x => x.unsubscribe()))
|
|
this.subscriptions = []
|
|
}
|
|
}
|