import oracledb, { Connection, PoolAttributes, Result } from 'oracledb'; // Oracle 자동 커밋 활성화 oracledb.autoCommit = true; // 연결 구성 타입 interface DbConfig extends PoolAttributes { user: string; password: string; connectString: string; } // 환경 변수에서 DB 설정 가져오기 const dbConfig: DbConfig = { user: process.env.ORACLE_USER || '', password: process.env.ORACLE_PASSWORD || '', connectString: process.env.ORACLE_CONNECTION_STRING || '' }; // DB 연결 풀 let pool: oracledb.Pool | null = null; /** * DB 연결 풀 초기화 */ async function initialize(): Promise { try { pool = await oracledb.createPool(dbConfig); console.log('Oracle DB 연결 풀이 초기화되었습니다.'); } catch (err) { console.error('Oracle DB 풀 초기화 오류:', err); throw err; } } /** * DB 연결 가져오기 */ export async function getConnection(): Promise { if (!pool) { await initialize(); } if (!pool) { throw new Error('DB 풀이 초기화되지 않았습니다.'); } return pool.getConnection(); } /** * 쿼리 실행 함수 */ export async function executeQuery( query: string, params: any[] = [], options: oracledb.ExecuteOptions = {} ): Promise> { let connection: Connection | undefined; try { connection = await getConnection(); const result = await connection.execute( query, params, { outFormat: oracledb.OUT_FORMAT_OBJECT, ...options } ); return result; } catch (err) { console.error('쿼리 실행 오류:', err); throw err; } finally { if (connection) { try { await connection.close(); } catch (err) { console.error('연결 종료 오류:', err); } } } } /** * 테이블 데이터 가져오기 함수 */ export async function getTableData(tableName: string): Promise { // SQL 인젝션 방지를 위한 테이블 이름 검증 // 알파벳, 숫자, 밑줄(_), 달러 기호($), 해시(#) 만 허용 const tableNameRegex = /^[a-zA-Z0-9_$#]+$/; if (!tableNameRegex.test(tableName)) { throw new Error('유효하지 않은 테이블 이름입니다.'); } const query = `SELECT * FROM ${tableName}`; const result = await executeQuery(query); return result.rows as T[] || []; } /** * 테이블 특정 컬럼 데이터 가져오기 함수 */ export async function getTableColumns( tableName: string, columns: string[] ): Promise { // SQL 인젝션 방지 const tableNameRegex = /^[a-zA-Z0-9_$#]+$/; if (!tableNameRegex.test(tableName)) { throw new Error('유효하지 않은 테이블 이름입니다.'); } // 컬럼명 검증 const columnNameRegex = /^[a-zA-Z0-9_$#]+$/; const validColumns = columns.filter(col => columnNameRegex.test(col)); if (validColumns.length === 0) { throw new Error('유효하지 않은 컬럼 이름입니다.'); } const columnsStr = validColumns.join(', '); const query = `SELECT ${columnsStr} FROM ${tableName}`; const result = await executeQuery(query); return result.rows as T[] || []; } /** * 풀 종료 함수 */ export async function closePool(): Promise { if (pool) { try { await pool.close(0); pool = null; console.log('Oracle DB 연결 풀이 종료되었습니다.'); } catch (err) { console.error('풀 종료 오류:', err); throw err; } } }