외부 db연동 구현
This commit is contained in:
@@ -18,6 +18,8 @@ import {
|
||||
GetTemplatesResponse,
|
||||
CreateTemplateRequest,
|
||||
} from "../types/report";
|
||||
import { DatabaseConnectorFactory } from "../database/DatabaseConnectorFactory";
|
||||
import { ExternalDbConnectionService } from "./externalDbConnectionService";
|
||||
|
||||
export class ReportService {
|
||||
/**
|
||||
@@ -165,6 +167,7 @@ export class ReportService {
|
||||
query_type,
|
||||
sql_query,
|
||||
parameters,
|
||||
external_connection_id,
|
||||
display_order,
|
||||
created_at,
|
||||
created_by,
|
||||
@@ -449,9 +452,10 @@ export class ReportService {
|
||||
query_type,
|
||||
sql_query,
|
||||
parameters,
|
||||
external_connection_id,
|
||||
display_order,
|
||||
created_by
|
||||
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
||||
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
|
||||
`;
|
||||
|
||||
for (const originalQuery of queriesResult.rows) {
|
||||
@@ -463,6 +467,7 @@ export class ReportService {
|
||||
originalQuery.query_type,
|
||||
originalQuery.sql_query,
|
||||
JSON.stringify(originalQuery.parameters),
|
||||
originalQuery.external_connection_id || null,
|
||||
originalQuery.display_order,
|
||||
userId,
|
||||
]);
|
||||
@@ -595,9 +600,10 @@ export class ReportService {
|
||||
query_type,
|
||||
sql_query,
|
||||
parameters,
|
||||
external_connection_id,
|
||||
display_order,
|
||||
created_by
|
||||
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
||||
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
|
||||
`;
|
||||
|
||||
for (let i = 0; i < data.queries.length; i++) {
|
||||
@@ -609,6 +615,7 @@ export class ReportService {
|
||||
q.type,
|
||||
q.sqlQuery,
|
||||
JSON.stringify(q.parameters),
|
||||
(q as any).externalConnectionId || null, // 외부 DB 연결 ID
|
||||
i,
|
||||
userId,
|
||||
]);
|
||||
@@ -620,26 +627,34 @@ export class ReportService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 쿼리 실행
|
||||
* 쿼리 실행 (내부 DB 또는 외부 DB)
|
||||
*/
|
||||
async executeQuery(
|
||||
reportId: string,
|
||||
queryId: string,
|
||||
parameters: Record<string, any>,
|
||||
sqlQuery?: string
|
||||
sqlQuery?: string,
|
||||
externalConnectionId?: number | null
|
||||
): Promise<{ fields: string[]; rows: any[] }> {
|
||||
let sql_query: string;
|
||||
let queryParameters: string[] = [];
|
||||
let connectionId: number | null = externalConnectionId ?? null;
|
||||
|
||||
// 테스트 모드 (sqlQuery 직접 전달)
|
||||
if (sqlQuery) {
|
||||
sql_query = sqlQuery;
|
||||
// 파라미터 순서 추출
|
||||
// 파라미터 순서 추출 (등장 순서대로)
|
||||
const matches = sqlQuery.match(/\$\d+/g);
|
||||
if (matches) {
|
||||
queryParameters = Array.from(new Set(matches)).sort((a, b) => {
|
||||
return parseInt(a.substring(1)) - parseInt(b.substring(1));
|
||||
});
|
||||
const seen = new Set<string>();
|
||||
const result: string[] = [];
|
||||
for (const match of matches) {
|
||||
if (!seen.has(match)) {
|
||||
seen.add(match);
|
||||
result.push(match);
|
||||
}
|
||||
}
|
||||
queryParameters = result;
|
||||
}
|
||||
} else {
|
||||
// DB에서 쿼리 조회
|
||||
@@ -656,6 +671,7 @@ export class ReportService {
|
||||
queryParameters = Array.isArray(queryResult.parameters)
|
||||
? queryResult.parameters
|
||||
: [];
|
||||
connectionId = queryResult.external_connection_id;
|
||||
}
|
||||
|
||||
// 파라미터 배열 생성 ($1, $2 순서대로)
|
||||
@@ -665,8 +681,49 @@ export class ReportService {
|
||||
}
|
||||
|
||||
try {
|
||||
// 쿼리 실행
|
||||
const result = await query(sql_query, paramArray);
|
||||
let result: any[];
|
||||
|
||||
// 외부 DB 연결이 있으면 외부 DB에서 실행
|
||||
if (connectionId) {
|
||||
// 외부 DB 연결 정보 조회
|
||||
const connectionResult =
|
||||
await ExternalDbConnectionService.getConnectionById(connectionId);
|
||||
|
||||
if (!connectionResult.success || !connectionResult.data) {
|
||||
throw new Error("외부 DB 연결 정보를 찾을 수 없습니다.");
|
||||
}
|
||||
|
||||
const connection = connectionResult.data;
|
||||
|
||||
// DatabaseConnectorFactory를 사용하여 외부 DB 쿼리 실행
|
||||
const config = {
|
||||
host: connection.host,
|
||||
port: connection.port,
|
||||
database: connection.database_name,
|
||||
user: connection.username,
|
||||
password: connection.password,
|
||||
connectionTimeout: connection.connection_timeout || 30000,
|
||||
queryTimeout: connection.query_timeout || 30000,
|
||||
};
|
||||
|
||||
const connector = await DatabaseConnectorFactory.createConnector(
|
||||
connection.db_type,
|
||||
config,
|
||||
connectionId
|
||||
);
|
||||
|
||||
await connector.connect();
|
||||
|
||||
try {
|
||||
const queryResult = await connector.executeQuery(sql_query);
|
||||
result = queryResult.rows || [];
|
||||
} finally {
|
||||
await connector.disconnect();
|
||||
}
|
||||
} else {
|
||||
// 내부 DB에서 실행
|
||||
result = await query(sql_query, paramArray);
|
||||
}
|
||||
|
||||
// 필드명 추출
|
||||
const fields = result.length > 0 ? Object.keys(result[0]) : [];
|
||||
|
||||
Reference in New Issue
Block a user