외부 DB 연결 끊김 오류 해결
This commit is contained in:
@@ -1,43 +1,25 @@
|
||||
import { Request, Response } from "express";
|
||||
import { pool, queryOne } from "../database/db";
|
||||
import logger from "../utils/logger";
|
||||
import { PasswordEncryption } from "../utils/passwordEncryption";
|
||||
import { DatabaseConnectorFactory } from "../database/DatabaseConnectorFactory";
|
||||
import { ExternalDbConnectionPoolService } from "../services/externalDbConnectionPoolService";
|
||||
|
||||
// 외부 DB 커넥터를 가져오는 헬퍼 함수
|
||||
// 외부 DB 커넥터를 가져오는 헬퍼 함수 (연결 풀 사용)
|
||||
export async function getExternalDbConnector(connectionId: number) {
|
||||
// 외부 DB 연결 정보 조회
|
||||
const connection = await queryOne<any>(
|
||||
`SELECT * FROM external_db_connections WHERE id = $1`,
|
||||
[connectionId]
|
||||
);
|
||||
const poolService = ExternalDbConnectionPoolService.getInstance();
|
||||
|
||||
if (!connection) {
|
||||
throw new Error(`외부 DB 연결 정보를 찾을 수 없습니다. ID: ${connectionId}`);
|
||||
}
|
||||
|
||||
// 패스워드 복호화
|
||||
const decryptedPassword = PasswordEncryption.decrypt(connection.password);
|
||||
|
||||
// DB 연결 설정
|
||||
const config = {
|
||||
host: connection.host,
|
||||
port: connection.port,
|
||||
user: connection.username,
|
||||
password: decryptedPassword,
|
||||
database: connection.database_name,
|
||||
// 연결 풀 래퍼를 반환 (executeQuery 메서드를 가진 객체)
|
||||
return {
|
||||
executeQuery: async (sql: string, params?: any[]) => {
|
||||
const result = await poolService.executeQuery(connectionId, sql, params);
|
||||
return { rows: result };
|
||||
},
|
||||
};
|
||||
|
||||
// DB 커넥터 생성
|
||||
return await DatabaseConnectorFactory.createConnector(
|
||||
connection.db_type || "mariadb",
|
||||
config,
|
||||
connectionId
|
||||
);
|
||||
}
|
||||
|
||||
// 동적 계층 구조 데이터 조회 (범용)
|
||||
export const getHierarchyData = async (req: Request, res: Response): Promise<Response> => {
|
||||
export const getHierarchyData = async (
|
||||
req: Request,
|
||||
res: Response
|
||||
): Promise<Response> => {
|
||||
try {
|
||||
const { externalDbConnectionId, hierarchyConfig } = req.body;
|
||||
|
||||
@@ -48,7 +30,9 @@ export const getHierarchyData = async (req: Request, res: Response): Promise<Res
|
||||
});
|
||||
}
|
||||
|
||||
const connector = await getExternalDbConnector(Number(externalDbConnectionId));
|
||||
const connector = await getExternalDbConnector(
|
||||
Number(externalDbConnectionId)
|
||||
);
|
||||
const config = JSON.parse(hierarchyConfig);
|
||||
|
||||
const result: any = {
|
||||
@@ -69,7 +53,7 @@ export const getHierarchyData = async (req: Request, res: Response): Promise<Res
|
||||
for (const level of config.levels) {
|
||||
const levelQuery = `SELECT * FROM ${level.tableName} LIMIT 1000`;
|
||||
const levelResult = await connector.executeQuery(levelQuery);
|
||||
|
||||
|
||||
result.levels.push({
|
||||
level: level.level,
|
||||
name: level.name,
|
||||
@@ -94,7 +78,10 @@ export const getHierarchyData = async (req: Request, res: Response): Promise<Res
|
||||
logger.info("동적 계층 구조 데이터 조회", {
|
||||
externalDbConnectionId,
|
||||
warehouseCount: result.warehouse?.length || 0,
|
||||
levelCounts: result.levels.map((l: any) => ({ level: l.level, count: l.data.length })),
|
||||
levelCounts: result.levels.map((l: any) => ({
|
||||
level: l.level,
|
||||
count: l.data.length,
|
||||
})),
|
||||
});
|
||||
|
||||
return res.json({
|
||||
@@ -112,22 +99,35 @@ export const getHierarchyData = async (req: Request, res: Response): Promise<Res
|
||||
};
|
||||
|
||||
// 특정 레벨의 하위 데이터 조회
|
||||
export const getChildrenData = async (req: Request, res: Response): Promise<Response> => {
|
||||
export const getChildrenData = async (
|
||||
req: Request,
|
||||
res: Response
|
||||
): Promise<Response> => {
|
||||
try {
|
||||
const { externalDbConnectionId, hierarchyConfig, parentLevel, parentKey } = req.body;
|
||||
const { externalDbConnectionId, hierarchyConfig, parentLevel, parentKey } =
|
||||
req.body;
|
||||
|
||||
if (!externalDbConnectionId || !hierarchyConfig || !parentLevel || !parentKey) {
|
||||
if (
|
||||
!externalDbConnectionId ||
|
||||
!hierarchyConfig ||
|
||||
!parentLevel ||
|
||||
!parentKey
|
||||
) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: "필수 파라미터가 누락되었습니다.",
|
||||
});
|
||||
}
|
||||
|
||||
const connector = await getExternalDbConnector(Number(externalDbConnectionId));
|
||||
const connector = await getExternalDbConnector(
|
||||
Number(externalDbConnectionId)
|
||||
);
|
||||
const config = JSON.parse(hierarchyConfig);
|
||||
|
||||
// 다음 레벨 찾기
|
||||
const nextLevel = config.levels?.find((l: any) => l.level === parentLevel + 1);
|
||||
const nextLevel = config.levels?.find(
|
||||
(l: any) => l.level === parentLevel + 1
|
||||
);
|
||||
|
||||
if (!nextLevel) {
|
||||
return res.json({
|
||||
@@ -168,7 +168,10 @@ export const getChildrenData = async (req: Request, res: Response): Promise<Resp
|
||||
};
|
||||
|
||||
// 창고 목록 조회 (사용자 지정 테이블) - 레거시, 호환성 유지
|
||||
export const getWarehouses = async (req: Request, res: Response): Promise<Response> => {
|
||||
export const getWarehouses = async (
|
||||
req: Request,
|
||||
res: Response
|
||||
): Promise<Response> => {
|
||||
try {
|
||||
const { externalDbConnectionId, tableName } = req.query;
|
||||
|
||||
@@ -186,7 +189,9 @@ export const getWarehouses = async (req: Request, res: Response): Promise<Respon
|
||||
});
|
||||
}
|
||||
|
||||
const connector = await getExternalDbConnector(Number(externalDbConnectionId));
|
||||
const connector = await getExternalDbConnector(
|
||||
Number(externalDbConnectionId)
|
||||
);
|
||||
|
||||
// 테이블명을 사용하여 모든 컬럼 조회
|
||||
const query = `SELECT * FROM ${tableName} LIMIT 100`;
|
||||
@@ -215,7 +220,10 @@ export const getWarehouses = async (req: Request, res: Response): Promise<Respon
|
||||
};
|
||||
|
||||
// 구역 목록 조회 (사용자 지정 테이블) - 레거시, 호환성 유지
|
||||
export const getAreas = async (req: Request, res: Response): Promise<Response> => {
|
||||
export const getAreas = async (
|
||||
req: Request,
|
||||
res: Response
|
||||
): Promise<Response> => {
|
||||
try {
|
||||
const { externalDbConnectionId, warehouseKey, tableName } = req.query;
|
||||
|
||||
@@ -226,7 +234,9 @@ export const getAreas = async (req: Request, res: Response): Promise<Response> =
|
||||
});
|
||||
}
|
||||
|
||||
const connector = await getExternalDbConnector(Number(externalDbConnectionId));
|
||||
const connector = await getExternalDbConnector(
|
||||
Number(externalDbConnectionId)
|
||||
);
|
||||
|
||||
const query = `
|
||||
SELECT * FROM ${tableName}
|
||||
@@ -258,7 +268,10 @@ export const getAreas = async (req: Request, res: Response): Promise<Response> =
|
||||
};
|
||||
|
||||
// 위치 목록 조회 (사용자 지정 테이블) - 레거시, 호환성 유지
|
||||
export const getLocations = async (req: Request, res: Response): Promise<Response> => {
|
||||
export const getLocations = async (
|
||||
req: Request,
|
||||
res: Response
|
||||
): Promise<Response> => {
|
||||
try {
|
||||
const { externalDbConnectionId, areaKey, tableName } = req.query;
|
||||
|
||||
@@ -269,7 +282,9 @@ export const getLocations = async (req: Request, res: Response): Promise<Respons
|
||||
});
|
||||
}
|
||||
|
||||
const connector = await getExternalDbConnector(Number(externalDbConnectionId));
|
||||
const connector = await getExternalDbConnector(
|
||||
Number(externalDbConnectionId)
|
||||
);
|
||||
|
||||
const query = `
|
||||
SELECT * FROM ${tableName}
|
||||
@@ -301,28 +316,38 @@ export const getLocations = async (req: Request, res: Response): Promise<Respons
|
||||
};
|
||||
|
||||
// 자재 목록 조회 (동적 컬럼 매핑 지원)
|
||||
export const getMaterials = async (req: Request, res: Response): Promise<Response> => {
|
||||
export const getMaterials = async (
|
||||
req: Request,
|
||||
res: Response
|
||||
): Promise<Response> => {
|
||||
try {
|
||||
const {
|
||||
externalDbConnectionId,
|
||||
locaKey,
|
||||
const {
|
||||
externalDbConnectionId,
|
||||
locaKey,
|
||||
tableName,
|
||||
keyColumn,
|
||||
locationKeyColumn,
|
||||
layerColumn
|
||||
layerColumn,
|
||||
} = req.query;
|
||||
|
||||
if (!externalDbConnectionId || !locaKey || !tableName || !locationKeyColumn) {
|
||||
if (
|
||||
!externalDbConnectionId ||
|
||||
!locaKey ||
|
||||
!tableName ||
|
||||
!locationKeyColumn
|
||||
) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: "필수 파라미터가 누락되었습니다.",
|
||||
});
|
||||
}
|
||||
|
||||
const connector = await getExternalDbConnector(Number(externalDbConnectionId));
|
||||
const connector = await getExternalDbConnector(
|
||||
Number(externalDbConnectionId)
|
||||
);
|
||||
|
||||
// 동적 쿼리 생성
|
||||
const orderByClause = layerColumn ? `ORDER BY ${layerColumn}` : '';
|
||||
const orderByClause = layerColumn ? `ORDER BY ${layerColumn}` : "";
|
||||
const query = `
|
||||
SELECT * FROM ${tableName}
|
||||
WHERE ${locationKeyColumn} = '${locaKey}'
|
||||
@@ -356,7 +381,10 @@ export const getMaterials = async (req: Request, res: Response): Promise<Respons
|
||||
};
|
||||
|
||||
// 자재 개수 조회 (여러 Location 일괄) - 레거시, 호환성 유지
|
||||
export const getMaterialCounts = async (req: Request, res: Response): Promise<Response> => {
|
||||
export const getMaterialCounts = async (
|
||||
req: Request,
|
||||
res: Response
|
||||
): Promise<Response> => {
|
||||
try {
|
||||
const { externalDbConnectionId, locationKeys, tableName } = req.body;
|
||||
|
||||
@@ -367,7 +395,9 @@ export const getMaterialCounts = async (req: Request, res: Response): Promise<Re
|
||||
});
|
||||
}
|
||||
|
||||
const connector = await getExternalDbConnector(Number(externalDbConnectionId));
|
||||
const connector = await getExternalDbConnector(
|
||||
Number(externalDbConnectionId)
|
||||
);
|
||||
|
||||
const keysString = locationKeys.map((key: string) => `'${key}'`).join(",");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user