Add query executed event; forward model events to global event bus
continuous-integration/drone/push Build is passing Details

orm-types
Garrett Mills 3 years ago
parent 61731c4ebd
commit c264d45927
Signed by: garrettmills
GPG Key ID: D2BF5FBA8298F246

@ -2,6 +2,9 @@ import {ErrorWithContext} from '../../util'
import {QueryResult} from '../types'
import {SQLDialect} from '../dialect/SQLDialect'
import {AppClass} from '../../lifecycle/AppClass'
import {Inject, Injectable} from '../../di'
import {EventBus} from '../../event/EventBus'
import {QueryExecutedEvent} from './event/QueryExecutedEvent'
/**
* Error thrown when a connection is used before it is ready.
@ -18,7 +21,10 @@ export class ConnectionNotReadyError extends ErrorWithContext {
* Abstract base class for database connections.
* @abstract
*/
@Injectable()
export abstract class Connection extends AppClass {
@Inject()
protected bus!: EventBus
constructor(
/**
@ -64,4 +70,14 @@ export abstract class Connection extends AppClass {
// public abstract tables(database_name: string): Promise<Collection<Table>>
// public abstract table(database_name: string, table_name: string): Promise<Table | undefined>
/**
* Fire a QueryExecutedEvent for the given query string.
* @param query
* @protected
*/
protected async queryExecuted(query: string): Promise<void> {
const event = new QueryExecutedEvent(this.name, this, query)
await this.bus.dispatch(event)
}
}

@ -54,6 +54,7 @@ export class PostgresConnection extends Connection {
try {
const result = await this.client.query(query)
await this.queryExecuted(query)
return {
rows: collect(result.rows),

@ -0,0 +1,67 @@
import {Event} from '../../../event/Event'
import {Inject, Injectable} from '../../../di'
import {InvalidJSONStateError, JSONState} from '../../../util'
import {Connection} from '../Connection'
import {DatabaseService} from '../../DatabaseService'
/**
* Event fired when a query is executed.
*/
@Injectable()
export class QueryExecutedEvent extends Event {
@Inject()
protected database!: DatabaseService
/**
* The name of the connection where the query was executed.
* @protected
*/
public connectionName!: string
/**
* The connection where the query was executed.
*/
public connection!: Connection
/**
* The query that was executed.
*/
public query!: string
constructor(
connectionName?: string,
connection?: Connection,
query?: string,
) {
super()
if ( connectionName ) {
this.connectionName = connectionName
}
if ( connection ) {
this.connection = connection
}
if ( query ) {
this.query = query
}
}
async dehydrate(): Promise<JSONState> {
return {
connectionName: this.connectionName,
query: this.query,
}
}
rehydrate(state: JSONState): void {
if ( !state.connectionName || !state.query ) {
throw new InvalidJSONStateError('Missing connectionName or query from QueryExecutedEvent state.')
}
this.query = String(state.query)
this.connectionName = String(state.connectionName)
this.connection = this.database.get(this.connectionName)
}
}

@ -16,13 +16,17 @@ import {ModelUpdatingEvent} from './events/ModelUpdatingEvent'
import {ModelUpdatedEvent} from './events/ModelUpdatedEvent'
import {ModelCreatingEvent} from './events/ModelCreatingEvent'
import {ModelCreatedEvent} from './events/ModelCreatedEvent'
import {EventBus} from '../../event/EventBus'
/**
* Base for classes that are mapped to tables in a database.
*/
export abstract class Model<T extends Model<T>> extends AppClass implements Bus {
@Inject()
protected readonly logging!: Logging;
protected readonly logging!: Logging
@Inject()
protected readonly bus!: EventBus
/**
* The name of the connection this model should run through.
@ -819,6 +823,8 @@ export abstract class Model<T extends Model<T>> extends AppClass implements Bus
const eventClass: StaticClass<typeof event, typeof event> = event.constructor as StaticClass<Dispatchable, Dispatchable>
await this.modelEventBusSubscribers.where('event', '=', eventClass)
.promiseMap(entry => entry.subscriber(event))
await this.bus.dispatch(event)
}
/**

Loading…
Cancel
Save