Module

x/postgres/client.ts

PostgreSQL driver for Deno
Extremely Popular
Go to Latest
File
import { Connection, ResultType } from "./connection/connection.ts";import { ConnectionOptions, ConnectionString, createParams,} from "./connection/connection_params.ts";import { Query, QueryArguments, QueryArrayResult, QueryConfig, QueryObjectConfig, QueryObjectResult, QueryResult, templateStringToQuery,} from "./query/query.ts";import { isTemplateString } from "./utils.ts";
export class QueryClient { /** * This function is meant to be replaced when being extended * * It's sole purpose is to be a common interface implementations can use * regardless of their internal structure */ _executeQuery(_query: Query, _result: ResultType): Promise<QueryResult> { throw new Error( `"${this._executeQuery.name}" hasn't been implemented for class "${this.constructor.name}"`, ); }
/** * This method allows executed queries to be retrieved as array entries. * It supports a generic interface in order to type the entries retrieved by the query * * ```ts * const {rows} = await my_client.queryArray( * "SELECT ID, NAME FROM CLIENTS" * ); // Array<unknown[]> * * const {rows} = await my_client.queryArray<[number, string]>( * "SELECT ID, NAME FROM CLIENTS" * ); // Array<[number, string]> * ``` * * It also allows you to execute prepared stamements with template strings * * ```ts * const id = 12; * // Array<[number, string]> * const {rows} = await my_client.queryArray<[number, string]>`SELECT ID, NAME FROM CLIENTS WHERE ID = ${id}`; * ``` */ queryArray<T extends Array<unknown>>( query: string, ...args: QueryArguments ): Promise<QueryArrayResult<T>>; queryArray<T extends Array<unknown>>( config: QueryConfig, ): Promise<QueryArrayResult<T>>; queryArray<T extends Array<unknown>>( strings: TemplateStringsArray, ...args: QueryArguments ): Promise<QueryArrayResult<T>>; queryArray<T extends Array<unknown> = Array<unknown>>( // deno-lint-ignore camelcase query_template_or_config: TemplateStringsArray | string | QueryConfig, ...args: QueryArguments ): Promise<QueryArrayResult<T>> { let query; if (typeof query_template_or_config === "string") { query = new Query(query_template_or_config, ...args); } else if (isTemplateString(query_template_or_config)) { query = templateStringToQuery(query_template_or_config, args); } else { query = new Query(query_template_or_config); }
return this._executeQuery( query, ResultType.ARRAY, ) as Promise<QueryArrayResult<T>>; }
/** * This method allows executed queries to be retrieved as object entries. * It supports a generic interface in order to type the entries retrieved by the query * * ```ts * const {rows} = await my_client.queryObject( * "SELECT ID, NAME FROM CLIENTS" * ); // Record<string, unknown> * * const {rows} = await my_client.queryObject<{id: number, name: string}>( * "SELECT ID, NAME FROM CLIENTS" * ); // Array<{id: number, name: string}> * ``` * * You can also map the expected results to object fields using the configuration interface. * This will be assigned in the order they were provided * * ```ts * const {rows} = await my_client.queryObject( * "SELECT ID, NAME FROM CLIENTS" * ); * * console.log(rows); // [{id: 78, name: "Frank"}, {id: 15, name: "Sarah"}] * * const {rows} = await my_client.queryObject({ * text: "SELECT ID, NAME FROM CLIENTS", * fields: ["personal_id", "complete_name"], * }); * * console.log(rows); // [{personal_id: 78, complete_name: "Frank"}, {personal_id: 15, complete_name: "Sarah"}] * ``` * * It also allows you to execute prepared stamements with template strings * * ```ts * const id = 12; * // Array<{id: number, name: string}> * const {rows} = await my_client.queryObject<{id: number, name: string}>`SELECT ID, NAME FROM CLIENTS WHERE ID = ${id}`; * ``` */ queryObject<T extends Record<string, unknown>>( query: string, ...args: QueryArguments ): Promise<QueryObjectResult<T>>; queryObject<T extends Record<string, unknown>>( config: QueryObjectConfig, ): Promise<QueryObjectResult<T>>; queryObject<T extends Record<string, unknown>>( query: TemplateStringsArray, ...args: QueryArguments ): Promise<QueryObjectResult<T>>; queryObject< T extends Record<string, unknown> = Record<string, unknown>, >( // deno-lint-ignore camelcase query_template_or_config: | string | QueryObjectConfig | TemplateStringsArray, ...args: QueryArguments ): Promise<QueryObjectResult<T>> { let query; if (typeof query_template_or_config === "string") { query = new Query(query_template_or_config, ...args); } else if (isTemplateString(query_template_or_config)) { query = templateStringToQuery(query_template_or_config, args); } else { query = new Query(query_template_or_config as QueryObjectConfig); }
return this._executeQuery( query, ResultType.OBJECT, ) as Promise<QueryObjectResult<T>>; }}
export class Client extends QueryClient { protected _connection: Connection;
constructor(config?: ConnectionOptions | ConnectionString) { super(); this._connection = new Connection(createParams(config)); }
_executeQuery(query: Query, result: ResultType): Promise<QueryResult> { return this._connection.query(query, result); }
async connect(): Promise<void> { await this._connection.startup(); }
async end(): Promise<void> { await this._connection.end(); }}
export class PoolClient extends QueryClient { protected _connection: Connection; private _releaseCallback: () => void;
constructor(connection: Connection, releaseCallback: () => void) { super(); this._connection = connection; this._releaseCallback = releaseCallback; }
_executeQuery(query: Query, result: ResultType): Promise<QueryResult> { return this._connection.query(query, result); }
async release(): Promise<void> { await this._releaseCallback(); }}