import {Awaitable, 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' import {Schema} from '../schema/Schema' /** * Error thrown when a connection is used before it is ready. * @extends Error */ export class ConnectionNotReadyError extends ErrorWithContext { constructor(name = '', context: {[key: string]: any} = {}) { super(`The connection ${name} is not ready and cannot execute queries.`) this.context = context } } /** * Abstract base class for database connections. * @abstract */ @Injectable() export abstract class Connection extends AppClass { @Inject() protected bus!: EventBus constructor( /** * The name of this connection * @type string */ public readonly name: string, /** * This connection's config object */ public readonly config: any = {}, ) { super() } public abstract dialect(): SQLDialect /** * Open the connection. * @return Promise */ public abstract init(): Promise /** * Execute an SQL query and get the result. * @param {string} query * @return Promise */ public abstract query(query: string): Promise /** * Close the connection. * @return Promise */ public abstract close(): Promise /** * Get a Schema on this connection. * @param name */ public abstract schema(name?: string): Schema /** * Execute all queries logged to this connection during the closure * as a transaction in the database. * @param closure */ public abstract asTransaction(closure: () => Awaitable): Awaitable /** * Fire a QueryExecutedEvent for the given query string. * @param query * @protected */ protected async queryExecuted(query: string): Promise { const event = new QueryExecutedEvent(this.name, this, query) await this.bus.dispatch(event) } }