summaryrefslogtreecommitdiff
path: root/lib/oracle/db.ts
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-05-26 04:25:47 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-05-26 04:25:47 +0000
commit1c1c1019b6af72771358d387a2ae70ca965cd9f9 (patch)
tree6b1204684e7b52cf7d40de37b9c58decc4fac38b /lib/oracle/db.ts
parent0547ab2fe1701d84753d0e078bba718a79b07a0c (diff)
(김준회) 아이템 리스트를 자재그룹으로 변경하고 PLM 인터페이스 처리
Diffstat (limited to 'lib/oracle/db.ts')
-rw-r--r--lib/oracle/db.ts148
1 files changed, 148 insertions, 0 deletions
diff --git a/lib/oracle/db.ts b/lib/oracle/db.ts
new file mode 100644
index 00000000..57a5cd49
--- /dev/null
+++ b/lib/oracle/db.ts
@@ -0,0 +1,148 @@
+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<void> {
+ 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<Connection> {
+ if (!pool) {
+ await initialize();
+ }
+
+ if (!pool) {
+ throw new Error('DB 풀이 초기화되지 않았습니다.');
+ }
+
+ return pool.getConnection();
+}
+
+/**
+ * 쿼리 실행 함수
+ */
+export async function executeQuery<T = any>(
+ query: string,
+ params: any[] = [],
+ options: oracledb.ExecuteOptions = {}
+): Promise<Result<T>> {
+ let connection: Connection | undefined;
+
+ try {
+ connection = await getConnection();
+
+ const result = await connection.execute<T>(
+ 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<T = any>(tableName: string): Promise<T[]> {
+ // SQL 인젝션 방지를 위한 테이블 이름 검증
+ // 알파벳, 숫자, 밑줄(_), 달러 기호($), 해시(#) 만 허용
+ const tableNameRegex = /^[a-zA-Z0-9_$#]+$/;
+
+ if (!tableNameRegex.test(tableName)) {
+ throw new Error('유효하지 않은 테이블 이름입니다.');
+ }
+
+ const query = `SELECT * FROM ${tableName}`;
+ const result = await executeQuery<T>(query);
+
+ return result.rows as T[] || [];
+}
+
+/**
+ * 테이블 특정 컬럼 데이터 가져오기 함수
+ */
+export async function getTableColumns<T = any>(
+ tableName: string,
+ columns: string[]
+): Promise<T[]> {
+ // 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<T>(query);
+ return result.rows as T[] || [];
+}
+
+/**
+ * 풀 종료 함수
+ */
+export async function closePool(): Promise<void> {
+ if (pool) {
+ try {
+ await pool.close(0);
+ pool = null;
+ console.log('Oracle DB 연결 풀이 종료되었습니다.');
+ } catch (err) {
+ console.error('풀 종료 오류:', err);
+ throw err;
+ }
+ }
+} \ No newline at end of file