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 {QueryResult} from '../types'
|
||||||
import {SQLDialect} from '../dialect/SQLDialect'
|
import {SQLDialect} from '../dialect/SQLDialect'
|
||||||
import {AppClass} from '../../lifecycle/AppClass'
|
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.
|
* 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 base class for database connections.
|
||||||
* @abstract
|
* @abstract
|
||||||
*/
|
*/
|
||||||
|
@Injectable()
|
||||||
export abstract class Connection extends AppClass {
|
export abstract class Connection extends AppClass {
|
||||||
|
@Inject()
|
||||||
|
protected bus!: EventBus
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
/**
|
/**
|
||||||
@ -64,4 +70,14 @@ export abstract class Connection extends AppClass {
|
|||||||
// public abstract tables(database_name: string): Promise<Collection<Table>>
|
// public abstract tables(database_name: string): Promise<Collection<Table>>
|
||||||
|
|
||||||
// public abstract table(database_name: string, table_name: string): Promise<Table | undefined>
|
// 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 {
|
try {
|
||||||
const result = await this.client.query(query)
|
const result = await this.client.query(query)
|
||||||
|
await this.queryExecuted(query)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
rows: collect(result.rows),
|
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 {ModelUpdatedEvent} from './events/ModelUpdatedEvent'
|
||||||
import {ModelCreatingEvent} from './events/ModelCreatingEvent'
|
import {ModelCreatingEvent} from './events/ModelCreatingEvent'
|
||||||
import {ModelCreatedEvent} from './events/ModelCreatedEvent'
|
import {ModelCreatedEvent} from './events/ModelCreatedEvent'
|
||||||
|
import {EventBus} from '../../event/EventBus'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base for classes that are mapped to tables in a database.
|
* Base for classes that are mapped to tables in a database.
|
||||||
*/
|
*/
|
||||||
export abstract class Model<T extends Model<T>> extends AppClass implements Bus {
|
export abstract class Model<T extends Model<T>> extends AppClass implements Bus {
|
||||||
@Inject()
|
@Inject()
|
||||||
protected readonly logging!: Logging;
|
protected readonly logging!: Logging
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
protected readonly bus!: EventBus
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the connection this model should run through.
|
* 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>
|
const eventClass: StaticClass<typeof event, typeof event> = event.constructor as StaticClass<Dispatchable, Dispatchable>
|
||||||
await this.modelEventBusSubscribers.where('event', '=', eventClass)
|
await this.modelEventBusSubscribers.where('event', '=', eventClass)
|
||||||
.promiseMap(entry => entry.subscriber(event))
|
.promiseMap(entry => entry.subscriber(event))
|
||||||
|
|
||||||
|
await this.bus.dispatch(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user