UNPKG

pg-tx

Version:

Transaction wrapper for node-postgres

205 lines (176 loc) 5.3 kB
import { Notification, PoolClient, QueryArrayConfig, QueryArrayResult, QueryConfig, QueryResult, QueryResultRow, Submittable } from 'pg' import { NoticeMessage } from 'pg-protocol/dist/messages' import stream from 'stream' /* eslint @typescript-eslint/ban-types: 0 */ /* eslint @typescript-eslint/no-explicit-any: 0 */ /* eslint node/no-unpublished-import: 0 */ /* eslint @typescript-eslint/explicit-module-boundary-types: 0 */ export class ProxyClient implements PoolClient { released = false private releaseCheck() { if (this.released) { throw new Error( `Transaction client already released, see more: https://tinyurl.com/py2upfcw` ) } } public constructor(private readonly client: PoolClient) {} // EventEmitter implementation addListener( event: string | symbol, listener: (...args: any[]) => void ): this { this.releaseCheck() return this.client.addListener(event, listener) as this } once(event: string | symbol, listener: (...args: any[]) => void): this { this.releaseCheck() return this.client.once(event, listener) as this } removeListener( event: string | symbol, listener: (...args: any[]) => void ): this { this.releaseCheck() return this.client.removeListener(event, listener) as this } off(event: string | symbol, listener: (...args: any[]) => void): this { this.releaseCheck() return this.client.off(event, listener) as this } removeAllListeners(event?: string | symbol): this { this.releaseCheck() return this.client.removeAllListeners(event) as this } setMaxListeners(n: number): this { this.releaseCheck() return this.client.setMaxListeners(n) as this } getMaxListeners(): number { this.releaseCheck() return this.client.getMaxListeners() } listeners(event: string | symbol): Function[] { this.releaseCheck() return this.client.listeners(event) } rawListeners(event: string | symbol): Function[] { this.releaseCheck() return this.client.rawListeners(event) } emit(event: string | symbol, ...args: any[]): boolean { this.releaseCheck() return this.client.emit(event, args) } listenerCount(event: string | symbol): number { this.releaseCheck() return this.client.listenerCount(event) } prependListener( event: string | symbol, listener: (...args: any[]) => void ): this { this.releaseCheck() return this.client.prependListener(event, listener) as this } prependOnceListener( event: string | symbol, listener: (...args: any[]) => void ): this { this.releaseCheck() return this.client.prependOnceListener(event, listener) as this } eventNames(): Array<string | symbol> { this.releaseCheck() return this.client.eventNames() } // ClientBase implementation connect(): Promise<void> connect(callback: (err: Error) => void): void connect(_?: any): any { throw new Error(`proxy client cannot connect`) } query<T extends Submittable>(queryStream: T): T // tslint:disable:no-unnecessary-generics query<R extends any[] = any[], I extends any[] = any[]>( queryConfig: QueryArrayConfig<I>, values?: I ): Promise<QueryArrayResult<R>> query<R extends QueryResultRow = any, I extends any[] = any[]>( queryConfig: QueryConfig<I> ): Promise<QueryResult<R>> query<R extends QueryResultRow = any, I extends any[] = any[]>( queryTextOrConfig: string | QueryConfig<I>, values?: I ): Promise<QueryResult<R>> query<R extends any[] = any[], I extends any[] = any[]>( queryConfig: QueryArrayConfig<I>, callback: (err: Error, result: QueryArrayResult<R>) => void ): void query<R extends QueryResultRow = any, I extends any[] = any[]>( queryTextOrConfig: string | QueryConfig<I>, callback: (err: Error, result: QueryResult<R>) => void ): void query<R extends QueryResultRow = any>( queryText: string, values: any[], callback: (err: Error, result: QueryResult<R>) => void ): void query(param1: any, param2?: any, param3?: any): any { // TODO check query texts to filter out transaction queries this.releaseCheck() return this.client.query(param1, param2, param3) } copyFrom(queryText: string): stream.Writable { this.releaseCheck() return this.client.copyFrom(queryText) } copyTo(queryText: string): stream.Readable { this.releaseCheck() return this.client.copyTo(queryText) } pauseDrain(): void { this.releaseCheck() return this.client.pauseDrain() } resumeDrain(): void { this.releaseCheck() return this.client.resumeDrain() } escapeIdentifier(str: string): string { this.releaseCheck() return this.client.escapeIdentifier(str) } escapeLiteral(str: string): string { this.releaseCheck() return this.client.escapeLiteral(str) } on(event: 'drain', listener: () => void): this on(event: 'error', listener: (err: Error) => void): this on(event: 'notice', listener: (notice: NoticeMessage) => void): this on(event: 'notification', listener: (message: Notification) => void): this // tslint:disable-next-line unified-signatures on(event: 'end', listener: () => void): this on(param1: any, param2: any): any { this.releaseCheck() return this.client.on(param1, param2) } // PoolClient implementation release(err?: Error | boolean): void { this.releaseCheck() this.proxyRelease() this.client.release(err) } proxyRelease() { this.released = true } }