import { Provider } from '@nestjs/common' ; import { createProviderToken , OgmaService } from '@ogma/nestjs-module' ; import { Pool } from 'pg' ; import { from } from 'rxjs' ; import { delay , retryWhen , scan } from 'rxjs/operators' ; import { DATABASE_FEATURE , DATABASE_MODULE_OPTIONS , DATABASE_POOL , } from './database.constants' ; import { DatabaseService } from './database.service' ; import { DatabaseModuleOptions } from './interfaces/database-options.interface' ; import { DatabaseFeatureOptions } from './interfaces/database.interface' ; export function createDatabasePoolConnection ( ) { return { provide : DATABASE_POOL , useFactory : async ( options , logger ) => { const pool = new Pool ( { ssl : options . ssl , connectionString : options . connectionUrl , } ) ; return from ( pool . connect ( ) ) . pipe ( retryWhen ( ( e ) => e . pipe ( scan ( ( errorCount , error ) => { logger . warn ( `Unable to connect to database. ${ error . message }. Retrying ${ errorCount + 1 }...` ) ; if ( errorCount + 1 > 9 ) { throw error ; } return errorCount + 1 ; } , 0 ) , delay ( 1 * 1000 ) ) ) ) . toPromise ( ) ; } , inject : [ DATABASE_MODULE_OPTIONS , createProviderToken ( 'DatabaseConnectionProvider' ) , ] , } ; } export function createDatabaseProviderToken ( tableName ) { return `${ DATABASE_FEATURE }:${ tableName }` ; } export function createDatabaseProviders ( feature ) { const token = createDatabaseProviderToken ( feature . tableName ) ; return [ { inject : [ DATABASE_POOL , createProviderToken ( DatabaseService . name ) ] , provide : token , useFactory : ( pool , ogmaService ) => { return new DatabaseService ( pool , feature , ogmaService ) ; } , } , ] ; }