import { Injectable, Logger } from '@nestjs/common'; import { OracleDBService } from 'src/db/db.service'; import * as oracledb from 'oracledb'; import { InsertRegionsDto, UpdateRegionDto } from './region.dto'; import { BadRequestException } from 'src/exceptions/badRequest.exception'; import { InternalServerException } from 'src/exceptions/internalServerError.exception'; @Injectable() export class RegionService { private readonly logger = new Logger(RegionService.name); constructor(private readonly oracleDBService: OracleDBService) { } async insertRegions(body: InsertRegionsDto) { let connection; try { connection = await this.oracleDBService.getConnection(); if (!connection) { throw new InternalServerException(); } const result = await connection.execute( `BEGIN USCIB_Managed_Pkg.InsertNewRegion(:p_region,:p_name,:p_cursor); END;`, { p_region: { val: body.p_region, type: oracledb.DB_TYPE_VARCHAR, }, p_name: { val: body.p_name, type: oracledb.DB_TYPE_VARCHAR, }, p_cursor: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT, }, }, { outFormat: oracledb.OUT_FORMAT_OBJECT, }, ); await connection.commit(); const fres = await result.outBinds.p_cursor.getRows(); if (fres[0].ERRORMESG) { this.logger.warn(fres[0].ERRORMESG); throw new BadRequestException(fres[0].ERRORMESG) } return fres; } catch (error) { if (error instanceof BadRequestException) { this.logger.warn(error.message); throw error; } this.logger.error('insertRegions failed', error.stack || error); throw new InternalServerException(); } finally { if (connection) { try { await connection.close(); } catch (closeErr) { this.logger.error('Failed to close DB connection', closeErr); } } } } async updateRegions(body: UpdateRegionDto) { let connection; try { connection = await this.oracleDBService.getConnection(); if (!connection) { throw new InternalServerException(); } const result = await connection.execute( `BEGIN USCIB_Managed_Pkg.UpdateRegion(:p_regionID,:p_name,:p_cursor); END;`, { p_regionID: { val: body.p_regionID, type: oracledb.DB_TYPE_NUMBER, }, p_name: { val: body.p_name, type: oracledb.DB_TYPE_VARCHAR, }, p_cursor: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT, }, }, { outFormat: oracledb.OUT_FORMAT_OBJECT, }, ); await connection.commit(); const fres = await result.outBinds.p_cursor.getRows(); if (fres[0].ERRORMESG) { this.logger.warn(fres[0].ERRORMESG); throw new BadRequestException(fres[0].ERRORMESG) } return fres; } catch (error) { if (error instanceof BadRequestException) { this.logger.warn(error.message); throw error; } this.logger.error('updateRegions failed', error.stack || error); throw new InternalServerException(); } finally { if (connection) { try { await connection.close(); } catch (closeErr) { this.logger.error('Failed to close DB connection', closeErr); } } } } async getRegions() { let connection; let rows = []; try { connection = await this.oracleDBService.getConnection(); if (!connection) { throw new InternalServerException() } const result = await connection.execute( `BEGIN USCIB_Managed_Pkg.GetRegions(:p_cursor); END;`, { p_cursor: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT, }, }, { outFormat: oracledb.OUT_FORMAT_OBJECT, }, ); if (result.outBinds && result.outBinds.p_cursor) { const cursor = result.outBinds.p_cursor; let rowsBatch; do { rowsBatch = await cursor.getRows(100); rows = rows.concat(rowsBatch); } while (rowsBatch.length > 0); await cursor.close(); } else { throw new BadRequestException(); } return rows; } catch (error) { if (error instanceof BadRequestException) { this.logger.warn(error.message); throw error; } else if (error.message === "NJS-107: invalid cursor") { this.logger.warn(error.message); throw new BadRequestException(); } this.logger.error('GETBASICFEERATES failed', error.stack || error); throw new InternalServerException(); } finally { if (connection) { try { await connection.close(); } catch (closeErr) { this.logger.error('Failed to close DB connection', closeErr); } } } } }