UNPKG

@starbemtech/star-db-query-builder

Version:

A query builder to be used with mysql or postgres

116 lines (99 loc) 3.02 kB
import { Pool, PoolConfig } from 'pg' import promiseRetry from 'promise-retry' import { IDatabaseClient } from './IDatabaseClient' import { RetryOptions } from '../default/types' import { monitor, MonitorEvents } from '../monitor/monitor' const transientErrorCodes = new Set(['ECONNRESET', 'ETIMEDOUT', 'ECONNREFUSED']) function isTransientError(error: any): boolean { return error && error.code && transientErrorCodes.has(error.code) } async function ensureUnaccentExtension(pool: Pool): Promise<void> { try { const checkResult = await pool.query(` SELECT 1 FROM pg_extension WHERE extname = 'unaccent' `) if (checkResult.rows.length === 0) { await pool.query('CREATE EXTENSION IF NOT EXISTS unaccent') monitor.emit(MonitorEvents.CONNECTION_CREATED, { clientType: 'pg', extension: 'unaccent', status: 'installed', }) console.info( '@starbemtech/star-db-query-builder: Extensão unaccent instalada com sucesso.' ) } } catch (error) { monitor.emit(MonitorEvents.QUERY_ERROR, { clientType: 'pg', action: 'install_unaccent', error, }) throw new Error( `@starbemtech/star-db-query-builder: Não foi possível instalar a extensão unaccent: ${error}` ) } } export const createPgClient = async ( pool: Pool, retryOptions?: RetryOptions, poolConfig?: PoolConfig ): Promise<IDatabaseClient> => { await ensureUnaccentExtension(pool) monitor.emit(MonitorEvents.CONNECTION_CREATED, { clientType: 'pg', poolOptions: poolConfig, }) return { clientType: 'pg', query: async <T>(sql: string, params?: any[]): Promise<T> => { return promiseRetry(async (retry, attempt) => { const startTime = Date.now() try { monitor.emit(MonitorEvents.QUERY_START, { clientType: 'pg', sql, params, attempt, }) const { rows } = await pool.query(sql, params) const elapsedTime = Date.now() - startTime monitor.emit(MonitorEvents.QUERY_END, { clientType: 'pg', sql, params, attempt, elapsedTime, }) return rows as unknown as T } catch (error) { const elapsedTime = Date.now() - startTime monitor.emit(MonitorEvents.QUERY_ERROR, { clientType: 'pg', sql, params, attempt, elapsedTime, error, }) if (isTransientError(error)) { console.warn( `Postgres query attempt ${attempt} failed, retrying...`, error ) monitor.emit(MonitorEvents.RETRY_ATTEMPT, { clientType: 'pg', sql, params, attempt, error, }) return retry(error) } throw error } }, retryOptions) }, } }