UNPKG

pg-promise

Version:
729 lines (557 loc) 24.7 kB
/* * Copyright (c) 2015-present, Vitaly Tomilov * * See the LICENSE file at the top-level directory of this distribution * for licensing information. * * Removal or modification of this copyright notice is prohibited. */ import * as pg from './pg-subset'; import * as pgMinify from 'pg-minify'; import * as spexLib from 'spex'; // internal namespace for "txMode" property: declare namespace _txMode { // Transaction Isolation Level; // API: https://vitaly-t.github.io/pg-promise/txMode.html#.isolationLevel enum isolationLevel { none = 0, serializable = 1, repeatableRead = 2, readCommitted = 3 } // TransactionMode class; // API: https://vitaly-t.github.io/pg-promise/txMode.TransactionMode.html class TransactionMode { constructor(options?: { tiLevel?: isolationLevel, readOnly?: boolean, deferrable?: boolean }) begin(cap?: boolean): string } } // Main protocol of the library; // API: https://vitaly-t.github.io/pg-promise/module-pg-promise.html declare namespace pgPromise { interface ISpex { batch: typeof spexLib.batch page: typeof spexLib.page sequence: typeof spexLib.sequence errors: { BatchError: spexLib.errors.BatchError, PageError: spexLib.errors.PageError, SequenceError: spexLib.errors.SequenceError } } interface IQueryFileOptions { debug?: boolean minify?: boolean | 'after' compress?: boolean params?: any noWarnings?: boolean } interface IFormattingOptions { capSQL?: boolean partial?: boolean def?: any } interface ILostContext<C extends pg.IClient = pg.IClient> { cn: string dc: any start: Date client: C } interface IConnectionOptions<C extends pg.IClient = pg.IClient> { direct?: boolean onLost?(err: any, e: ILostContext<C>): void } interface IPreparedStatement { name?: string text?: string | QueryFile values?: any[] binary?: boolean rowMode?: 'array' | null | void rows?: number types?: pg.ITypes } interface IParameterizedQuery { text?: string | QueryFile values?: any[] binary?: boolean rowMode?: void | 'array' types?: pg.ITypes; } interface IPreparedParsed { name: string text: string values: any[] binary: boolean rowMode: void | 'array' rows: number } interface IParameterizedParsed { text: string values: any[] binary: boolean rowMode: void | 'array' } interface IColumnDescriptor<T> { source: T name: string value: any exists: boolean } interface IColumnConfig<T> { name: string prop?: string mod?: FormattingFilter cast?: string cnd?: boolean def?: any init?(col: IColumnDescriptor<T>): any skip?(col: IColumnDescriptor<T>): boolean } interface IColumnSetOptions { table?: string | ITable | TableName inherit?: boolean duplicate?: 'error' | 'skip' | 'replace' } interface ITable { schema?: string table: string } type FormattingFilter = '^' | '~' | '#' | ':raw' | ':alias' | ':name' | ':json' | ':csv' | ':list' | ':value'; type QueryColumns<T> = Column<T> | ColumnSet<T> | Array<string | IColumnConfig<T> | Column<T>>; type QueryParam = string | QueryFile | IPreparedStatement | IParameterizedQuery | PreparedStatement | ParameterizedQuery | ((values?: any) => QueryParam); type ValidSchema = string | string[] | null | void; // helpers.TableName class; // API: https://vitaly-t.github.io/pg-promise/helpers.TableName.html class TableName { constructor(table: string | ITable) // these are all read-only: readonly name: string; readonly table: string; readonly schema: string; toString(): string } // helpers.Column class; // API: https://vitaly-t.github.io/pg-promise/helpers.Column.html class Column<T = unknown> { constructor(col: string | IColumnConfig<T>); // these are all read-only: readonly name: string; readonly prop: string; readonly mod: FormattingFilter; readonly cast: string; readonly cnd: boolean; readonly def: any; readonly castText: string; readonly escapedName: string; readonly variable: string; readonly init: (col: IColumnDescriptor<T>) => any readonly skip: (col: IColumnDescriptor<T>) => boolean toString(level?: number): string } // helpers.Column class; // API: https://vitaly-t.github.io/pg-promise/helpers.ColumnSet.html class ColumnSet<T = unknown> { constructor(columns: Column<T>, options?: IColumnSetOptions) constructor(columns: Array<string | IColumnConfig<T> | Column<T>>, options?: IColumnSetOptions) constructor(columns: object, options?: IColumnSetOptions) readonly columns: Column<T>[]; readonly names: string; readonly table: TableName; readonly variables: string; assign(source?: { source?: object, prefix?: string }): string assignColumns(options?: { from?: string, to?: string, skip?: string | string[] | ((c: Column<T>) => boolean) }): string extend<K extends string>(columns: K[], opts?: { skip?: boolean }): ColumnSet<T & Record<K, unknown>> extend<S>(columns: Column<S> | ColumnSet<S> | Array<IColumnConfig<S> | Column<S>>, opts?: { skip?: boolean }): ColumnSet<T & S> merge<K extends string>(columns: K[]): ColumnSet<T & Record<K, unknown>> merge<S>(columns: Column<S> | ColumnSet<S> | Array<IColumnConfig<S> | Column<S>>): ColumnSet<T & S> prepare(obj: object): object toString(level?: number): string } const minify: typeof pgMinify; // Query Result Mask; // API: https://vitaly-t.github.io/pg-promise/global.html#queryResult enum queryResult { one = 1, many = 2, none = 4, any = 6 } // PreparedStatement class; // API: https://vitaly-t.github.io/pg-promise/PreparedStatement.html class PreparedStatement { constructor(options?: IPreparedStatement) // standard properties: name: string; text: string | QueryFile; values: any[]; // advanced properties: binary: boolean; rowMode: void | 'array'; rows: number; types: pg.ITypes; parse(): IPreparedParsed | errors.PreparedStatementError toString(level?: number): string } // ParameterizedQuery class; // API: https://vitaly-t.github.io/pg-promise/ParameterizedQuery.html class ParameterizedQuery { constructor(options?: string | QueryFile | IParameterizedQuery) // standard properties: text: string | QueryFile; values: any[]; // advanced properties: binary: boolean; rowMode: void | 'array'; types: pg.ITypes; parse(): IParameterizedParsed | errors.ParameterizedQueryError toString(level?: number): string } // QueryFile class; // API: https://vitaly-t.github.io/pg-promise/QueryFile.html class QueryFile { constructor(file: string, options?: IQueryFileOptions) readonly error: Error; readonly file: string; readonly options: any; prepare(): void toString(level?: number): string } const txMode: typeof _txMode; const utils: IUtils; const as: IFormatting; // Database full protocol; // API: https://vitaly-t.github.io/pg-promise/Database.html // // We export this interface only to be able to help IntelliSense cast extension types correctly, // which doesn't always work, depending on the version of IntelliSense being used. interface IDatabase<Ext, C extends pg.IClient = pg.IClient> extends IBaseProtocol<Ext> { connect(options?: IConnectionOptions<C>): Promise<IConnected<Ext, C>> ///////////////////////////////////////////////////////////////////////////// // Hidden, read-only properties, for integrating with third-party libraries: readonly $config: ILibConfig<Ext, C> readonly $cn: string | pg.IConnectionParameters<C> readonly $dc: any readonly $pool: pg.IPool } interface IResultExt<T = unknown> extends pg.IResult<T> { // Property 'duration' exists only in the following context: // - for single-query events 'receive' // - for method Database.result duration?: number } // Post-initialization interface; // API: https://vitaly-t.github.io/pg-promise/module-pg-promise.html interface IMain<Ext = {}, C extends pg.IClient = pg.IClient> { <T = Ext, C extends pg.IClient = pg.IClient>(cn: string | pg.IConnectionParameters<C>, dc?: any): IDatabase<T, C> & T readonly PreparedStatement: typeof PreparedStatement readonly ParameterizedQuery: typeof ParameterizedQuery readonly QueryFile: typeof QueryFile readonly queryResult: typeof queryResult readonly minify: typeof pgMinify readonly spex: ISpex readonly errors: typeof errors readonly utils: IUtils readonly txMode: typeof txMode readonly helpers: IHelpers readonly as: IFormatting readonly pg: typeof pg end(): void } // Additional methods available inside tasks + transactions; // API: https://vitaly-t.github.io/pg-promise/Task.html interface ITask<Ext> extends IBaseProtocol<Ext>, ISpex { readonly ctx: ITaskContext } interface ITaskIfOptions<Ext = {}> { cnd?: boolean | ((t: ITask<Ext> & Ext) => boolean) tag?: any } interface ITxIfOptions<Ext = {}> extends ITaskIfOptions<Ext> { mode?: _txMode.TransactionMode | null reusable?: boolean | ((t: ITask<Ext> & Ext) => boolean) } // Base database protocol // API: https://vitaly-t.github.io/pg-promise/Database.html interface IBaseProtocol<Ext> { // API: https://vitaly-t.github.io/pg-promise/Database.html#query query<T = any>(query: QueryParam, values?: any, qrm?: queryResult): Promise<T> // result-specific methods; // API: https://vitaly-t.github.io/pg-promise/Database.html#none none(query: QueryParam, values?: any): Promise<null> // API: https://vitaly-t.github.io/pg-promise/Database.html#one one<T = any>(query: QueryParam, values?: any, cb?: (value: any) => T, thisArg?: any): Promise<T> // API: https://vitaly-t.github.io/pg-promise/Database.html#oneOrNone oneOrNone<T = any>(query: QueryParam, values?: any, cb?: (value: any) => T, thisArg?: any): Promise<T | null> // API: https://vitaly-t.github.io/pg-promise/Database.html#many many<T = any>(query: QueryParam, values?: any): Promise<T[]> // API: https://vitaly-t.github.io/pg-promise/Database.html#manyOrNone manyOrNone<T = any>(query: QueryParam, values?: any): Promise<T[]> // API: https://vitaly-t.github.io/pg-promise/Database.html#any any<T = any>(query: QueryParam, values?: any): Promise<T[]> // API: https://vitaly-t.github.io/pg-promise/Database.html#result result<T, R = IResultExt<T>>(query: QueryParam, values?: any, cb?: (value: IResultExt<T>) => R, thisArg?: any): Promise<R> // API: https://vitaly-t.github.io/pg-promise/Database.html#multiResult multiResult(query: QueryParam, values?: any): Promise<pg.IResult[]> // API: https://vitaly-t.github.io/pg-promise/Database.html#multi multi<T = any>(query: QueryParam, values?: any): Promise<Array<T[]>> // API: https://vitaly-t.github.io/pg-promise/Database.html#stream stream(qs: NodeJS.ReadableStream, init: (stream: NodeJS.ReadableStream) => void): Promise<{ processed: number, duration: number }> // API: https://vitaly-t.github.io/pg-promise/Database.html#func func<T = any>(funcName: string, values?: any, qrm?: queryResult): Promise<T> // API: https://vitaly-t.github.io/pg-promise/Database.html#proc proc<T = any>(procName: string, values?: any, cb?: (value: any) => T, thisArg?: any): Promise<T | null> // API: https://vitaly-t.github.io/pg-promise/Database.html#map map<T = any>(query: QueryParam, values: any, cb: (row: any, index: number, data: any[]) => T, thisArg?: any): Promise<T[]> // API: https://vitaly-t.github.io/pg-promise/Database.html#each each<T = any>(query: QueryParam, values: any, cb: (row: any, index: number, data: any[]) => void, thisArg?: any): Promise<T[]> // Tasks; // API: https://vitaly-t.github.io/pg-promise/Database.html#task task<T>(cb: (t: ITask<Ext> & Ext) => T | Promise<T>): Promise<T> task<T>(tag: string | number, cb: (t: ITask<Ext> & Ext) => T | Promise<T>): Promise<T> task<T>(options: { tag?: any }, cb: (t: ITask<Ext> & Ext) => T | Promise<T>): Promise<T> // Conditional Tasks; // API: https://vitaly-t.github.io/pg-promise/Database.html#taskIf taskIf<T>(cb: (t: ITask<Ext> & Ext) => T | Promise<T>): Promise<T> taskIf<T>(tag: string | number, cb: (t: ITask<Ext> & Ext) => T | Promise<T>): Promise<T> taskIf<T>(options: ITaskIfOptions<Ext>, cb: (t: ITask<Ext> & Ext) => T | Promise<T>): Promise<T> // Transactions; // API: https://vitaly-t.github.io/pg-promise/Database.html#tx tx<T>(cb: (t: ITask<Ext> & Ext) => T | Promise<T>): Promise<T> tx<T>(tag: string | number, cb: (t: ITask<Ext> & Ext) => T | Promise<T>): Promise<T> tx<T>(options: { tag?: any, mode?: _txMode.TransactionMode | null }, cb: (t: ITask<Ext> & Ext) => T | Promise<T>): Promise<T> // Conditional Transactions; // API: https://vitaly-t.github.io/pg-promise/Database.html#txIf txIf<T>(cb: (t: ITask<Ext> & Ext) => T | Promise<T>): Promise<T> txIf<T>(tag: string | number, cb: (t: ITask<Ext> & Ext) => T | Promise<T>): Promise<T> txIf<T>(options: ITxIfOptions<Ext>, cb: (t: ITask<Ext> & Ext) => T | Promise<T>): Promise<T> } // Database object in connected state; // API: https://vitaly-t.github.io/pg-promise/Database.html#connect interface IConnected<Ext, C extends pg.IClient> extends IBaseProtocol<Ext>, ISpex { readonly client: C // Note that for normal connections (working with the pool), method `done` accepts `kill` // flag to terminate the connection within the pool, so it can be auto-recreated; // And in this case the method returns nothing / void. // But for direct connections (connect({direct: true})), `kill` flag is ignored, because // the connection is always closed physically, which may take time, and so in this case // the method returns a Promise to indicate when the connection finished closing. done(kill?: boolean): void | Promise<void>; // Repeated calls are not allowed and will throw an error. } // Event context extension for tasks + transactions; // See: https://vitaly-t.github.io/pg-promise/global.html#TaskContext interface ITaskContext { // these are set at the beginning of each task/transaction: readonly context: any readonly parent: ITaskContext | null readonly connected: boolean readonly inTransaction: boolean readonly level: number readonly useCount: number readonly isTX: boolean readonly start: Date readonly tag: any readonly dc: any // these are set at the end of each task/transaction: readonly finish?: Date readonly duration?: number readonly success?: boolean readonly result?: any // this exists only inside transactions (isTX = true): readonly txLevel?: number // Version of PostgreSQL Server to which we are connected; // This property is not available with Native Bindings! readonly serverVersion: string } // Generic Event Context interface; // See: https://vitaly-t.github.io/pg-promise/global.html#EventContext interface IEventContext<C extends pg.IClient = pg.IClient> { client: C cn: any dc: any query: any params: any, values: any, queryFilePath?: string, ctx: ITaskContext } // Errors namespace // API: https://vitaly-t.github.io/pg-promise/errors.html namespace errors { // QueryResultError interface; // API: https://vitaly-t.github.io/pg-promise/errors.QueryResultError.html class QueryResultError extends Error { // standard error properties: name: string; message: string; stack: string; // extended properties: result: pg.IResult; received: number; code: queryResultErrorCode; query: string; values: any; // API: https://vitaly-t.github.io/pg-promise/errors.QueryResultError.html#toString toString(): string } // QueryFileError interface; // API: https://vitaly-t.github.io/pg-promise/errors.QueryFileError.html class QueryFileError extends Error { // standard error properties: name: string; message: string; stack: string; // extended properties: file: string; options: IQueryFileOptions; error: pgMinify.SQLParsingError; toString(level?: number): string } // PreparedStatementError interface; // API: https://vitaly-t.github.io/pg-promise/errors.PreparedStatementError.html class PreparedStatementError extends Error { // standard error properties: name: string; message: string; stack: string; // extended properties: error: QueryFileError; toString(level?: number): string } // ParameterizedQueryError interface; // API: https://vitaly-t.github.io/pg-promise/errors.ParameterizedQueryError.html class ParameterizedQueryError extends Error { // standard error properties: name: string; message: string; stack: string; // extended properties: error: QueryFileError; toString(level?: number): string } // Query Result Error Code; // API: https://vitaly-t.github.io/pg-promise/errors.html#.queryResultErrorCode enum queryResultErrorCode { noData = 0, notEmpty = 1, multiple = 2 } } // Library's Initialization Options // API: https://vitaly-t.github.io/pg-promise/module-pg-promise.html interface IInitOptions<Ext = {}, C extends pg.IClient = pg.IClient> { noWarnings?: boolean pgFormatting?: boolean pgNative?: boolean capSQL?: boolean schema?: ValidSchema | ((dc: any) => ValidSchema) connect?(e: { client: C, dc: any, useCount: number }): void disconnect?(e: { client: C, dc: any }): void query?(e: IEventContext<C>): void // NOTE: The result is undefined when data comes from QueryStream, i.e. via method Database.stream receive?(e: { data: any[], result: IResultExt | void, ctx: IEventContext<C> }): void task?(e: IEventContext<C>): void transact?(e: IEventContext<C>): void error?(err: any, e: IEventContext<C>): void extend?(obj: IDatabase<Ext, C> & Ext, dc: any): void } // API: https://vitaly-t.github.io/pg-promise/Database.html#$config interface ILibConfig<Ext, C extends pg.IClient = pg.IClient> { version: string promise: IGenericPromise options: IInitOptions<Ext, C> pgp: IMain<Ext, C> $npm: any } // Custom-Type Formatting object // API: https://github.com/vitaly-t/pg-promise#custom-type-formatting interface ICTFObject { toPostgres(a: any): any } // Query formatting namespace; // API: https://vitaly-t.github.io/pg-promise/formatting.html interface IFormatting { ctf: { toPostgres: symbol, rawType: symbol } alias(name: string | (() => string)): string array(arr: any[] | (() => any[]), options?: { capSQL?: boolean }): string bool(value: any | (() => any)): string buffer(obj: object | (() => object), raw?: boolean): string csv(values: any | (() => any)): string date(d: Date | (() => Date), raw?: boolean): string format(query: string | QueryFile | ICTFObject, values?: any, options?: IFormattingOptions): string func(func: (cc: any) => any, raw?: boolean, cc?: any): string json(data: any | (() => any), raw?: boolean): string name(name: any | (() => any)): string number(value: number | bigint | (() => number | bigint)): string text(value: any | (() => any), raw?: boolean): string value(value: any | (() => any)): string } interface ITaskArguments<T> extends IArguments { options: { tag?: any, cnd?: any, mode?: _txMode.TransactionMode | null } & T cb(): any } // General-purpose functions // API: https://vitaly-t.github.io/pg-promise/utils.html interface IUtils { camelize(text: string): string camelizeVar(text: string): string enumSql(dir: string, options?: { recursive?: boolean, ignoreErrors?: boolean }, cb?: (file: string, name: string, path: string) => any): any taskArgs<T = {}>(args: IArguments): ITaskArguments<T> } // Query Formatting Helpers // API: https://vitaly-t.github.io/pg-promise/helpers.html interface IHelpers { concat(queries: Array<string | QueryFile | { query: string | QueryFile, values?: any, options?: IFormattingOptions }>): string insert(data: object | object[], columns?: QueryColumns<any> | null, table?: string | ITable | TableName): string update(data: object | object[], columns?: QueryColumns<any> | null, table?: string | ITable | TableName, options?: { tableAlias?: string, valueAlias?: string, emptyUpdate?: any }): any values(data: object | object[], columns?: QueryColumns<any> | null): string sets(data: object, columns?: QueryColumns<any> | null): string Column: typeof Column ColumnSet: typeof ColumnSet TableName: typeof TableName _TN(path: TemplateStringsArray, ...args: Array<any>): ITable _TN(path: string): ITable } interface IGenericPromise { (cb: (resolve: (value?: any) => void, reject: (reason?: any) => void) => void): Promise<any> resolve(value?: any): void reject(reason?: any): void all(iterable: any): Promise<any> } } // Default library interface (before initialization) // API: https://vitaly-t.github.io/pg-promise/module-pg-promise.html declare function pgPromise<Ext = {}, C extends pg.IClient = pg.IClient>(options?: pgPromise.IInitOptions<Ext, C>): pgPromise.IMain<Ext, C> export = pgPromise;