Add query executed event; forward model events to global event bus
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
61731c4ebd
commit
c264d45927
@ -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),
|
||||
|
67
src/orm/connection/event/QueryExecutedEvent.ts
Normal file
67
src/orm/connection/event/QueryExecutedEvent.ts
Normal file
@ -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…
Reference in New Issue
Block a user