Centralize configure-able factory classes
This commit is contained in:
@@ -1,86 +1,23 @@
|
||||
import {
|
||||
AbstractFactory,
|
||||
DependencyRequirement,
|
||||
PropertyDependency,
|
||||
isInstantiable,
|
||||
DEPENDENCY_KEYS_METADATA_KEY,
|
||||
Instantiable,
|
||||
Injectable,
|
||||
Inject,
|
||||
FactoryProducer,
|
||||
getPropertyInjectionMetadata,
|
||||
} from '../../di'
|
||||
import {Collection, ErrorWithContext} from '../../util'
|
||||
import {Logging} from '../../service/Logging'
|
||||
import {Config} from '../../service/Config'
|
||||
import {Instantiable, FactoryProducer} from '../../di'
|
||||
import {Migrator} from './Migrator'
|
||||
import {DatabaseMigrator} from './DatabaseMigrator'
|
||||
import {ConfiguredSingletonFactory} from '../../di/factory/ConfiguredSingletonFactory'
|
||||
|
||||
/**
|
||||
* A dependency injection factory that matches the abstract Migrator class
|
||||
* and produces an instance of the configured session driver implementation.
|
||||
*/
|
||||
@Injectable()
|
||||
@FactoryProducer()
|
||||
export class MigratorFactory extends AbstractFactory<Migrator> {
|
||||
@Inject()
|
||||
protected readonly logging!: Logging
|
||||
|
||||
@Inject()
|
||||
protected readonly config!: Config
|
||||
|
||||
constructor() {
|
||||
super({})
|
||||
export class MigratorFactory extends ConfiguredSingletonFactory<Migrator> {
|
||||
protected getConfigKey(): string {
|
||||
return 'database.migrations.driver'
|
||||
}
|
||||
|
||||
produce(): Migrator {
|
||||
return new (this.getMigratorClass())()
|
||||
protected getDefaultImplementation(): Instantiable<Migrator> {
|
||||
return DatabaseMigrator
|
||||
}
|
||||
|
||||
match(something: unknown): boolean {
|
||||
return something === Migrator
|
||||
}
|
||||
|
||||
getDependencyKeys(): Collection<DependencyRequirement> {
|
||||
const meta = Reflect.getMetadata(DEPENDENCY_KEYS_METADATA_KEY, this.getMigratorClass())
|
||||
if ( meta ) {
|
||||
return meta
|
||||
}
|
||||
|
||||
return new Collection<DependencyRequirement>()
|
||||
}
|
||||
|
||||
getInjectedProperties(): Collection<PropertyDependency> {
|
||||
const meta = new Collection<PropertyDependency>()
|
||||
let currentToken = this.getMigratorClass()
|
||||
|
||||
do {
|
||||
const loadedMeta = getPropertyInjectionMetadata(currentToken)
|
||||
if ( loadedMeta ) {
|
||||
meta.concat(loadedMeta)
|
||||
}
|
||||
currentToken = Object.getPrototypeOf(currentToken)
|
||||
} while (Object.getPrototypeOf(currentToken) !== Function.prototype && Object.getPrototypeOf(currentToken) !== Object.prototype)
|
||||
|
||||
return meta
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the instantiable class of the configured migrator backend.
|
||||
* @protected
|
||||
* @return Instantiable<Migrator>
|
||||
*/
|
||||
protected getMigratorClass(): Instantiable<Migrator> {
|
||||
const MigratorClass = this.config.get('database.migrations.driver', DatabaseMigrator)
|
||||
|
||||
if ( !isInstantiable(MigratorClass) || !(MigratorClass.prototype instanceof Migrator) ) {
|
||||
const e = new ErrorWithContext('Provided migration driver class does not extend from @extollo/lib.Migrator')
|
||||
e.context = {
|
||||
configKey: 'database.migrations.driver',
|
||||
class: MigratorClass.toString(),
|
||||
}
|
||||
}
|
||||
|
||||
return MigratorClass
|
||||
protected getAbstractImplementation(): any {
|
||||
return Migrator
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import {collect, Collection, ErrorWithContext, Maybe} from '../../util'
|
||||
import {HasSubtree} from './relation/HasSubtree'
|
||||
import {Related} from './relation/decorators'
|
||||
import {HasTreeParent} from './relation/HasTreeParent'
|
||||
import {ModelBuilder} from './ModelBuilder'
|
||||
|
||||
/**
|
||||
* Model implementation with helpers for querying tree-structured data.
|
||||
@@ -44,6 +45,12 @@ export abstract class TreeModel<T extends TreeModel<T>> extends Model<T> {
|
||||
|
||||
public static readonly parentIdField = 'parent_id'
|
||||
|
||||
/** @override to include the tree fields */
|
||||
public static query<T2 extends Model<T2>>(): ModelBuilder<T2> {
|
||||
return super.query<T2>()
|
||||
.fields(this.rightTreeField, this.leftTreeField, this.parentIdField)
|
||||
}
|
||||
|
||||
/**
|
||||
* @override to eager-load the subtree by default
|
||||
* @protected
|
||||
@@ -52,6 +59,13 @@ export abstract class TreeModel<T extends TreeModel<T>> extends Model<T> {
|
||||
|
||||
protected removedChildren: Collection<TreeModel<T>> = collect()
|
||||
|
||||
/** @override to include the tree fields */
|
||||
public query(): ModelBuilder<T> {
|
||||
const ctor = this.constructor as typeof TreeModel
|
||||
return super.query()
|
||||
.fields(ctor.leftTreeField, ctor.rightTreeField, ctor.parentIdField)
|
||||
}
|
||||
|
||||
/** Get the left tree number for this model. */
|
||||
public leftTreeNum(): Maybe<number> {
|
||||
const ctor = this.constructor as typeof TreeModel
|
||||
|
||||
Reference in New Issue
Block a user