플로우 외부연결 중간커밋
This commit is contained in:
@@ -8,6 +8,8 @@ import { FlowStepDataCount, FlowStepDataList } from "../types/flow";
|
||||
import { FlowDefinitionService } from "./flowDefinitionService";
|
||||
import { FlowStepService } from "./flowStepService";
|
||||
import { FlowConditionParser } from "./flowConditionParser";
|
||||
import { executeExternalQuery } from "./externalDbHelper";
|
||||
import { getPlaceholder, buildPaginationClause } from "./dbQueryBuilder";
|
||||
|
||||
export class FlowExecutionService {
|
||||
private flowDefinitionService: FlowDefinitionService;
|
||||
@@ -28,6 +30,13 @@ export class FlowExecutionService {
|
||||
throw new Error(`Flow definition not found: ${flowId}`);
|
||||
}
|
||||
|
||||
console.log("🔍 [getStepDataCount] Flow Definition:", {
|
||||
flowId,
|
||||
dbSourceType: flowDef.dbSourceType,
|
||||
dbConnectionId: flowDef.dbConnectionId,
|
||||
tableName: flowDef.tableName,
|
||||
});
|
||||
|
||||
// 2. 플로우 단계 조회
|
||||
const step = await this.flowStepService.findById(stepId);
|
||||
if (!step) {
|
||||
@@ -46,11 +55,40 @@ export class FlowExecutionService {
|
||||
step.conditionJson
|
||||
);
|
||||
|
||||
// 5. 카운트 쿼리 실행
|
||||
// 5. 카운트 쿼리 실행 (내부 또는 외부 DB)
|
||||
const query = `SELECT COUNT(*) as count FROM ${tableName} WHERE ${where}`;
|
||||
const result = await db.query(query, params);
|
||||
|
||||
return parseInt(result[0].count);
|
||||
console.log("🔍 [getStepDataCount] Query Info:", {
|
||||
tableName,
|
||||
query,
|
||||
params,
|
||||
isExternal: flowDef.dbSourceType === "external",
|
||||
connectionId: flowDef.dbConnectionId,
|
||||
});
|
||||
|
||||
let result: any;
|
||||
if (flowDef.dbSourceType === "external" && flowDef.dbConnectionId) {
|
||||
// 외부 DB 조회
|
||||
console.log(
|
||||
"✅ [getStepDataCount] Using EXTERNAL DB:",
|
||||
flowDef.dbConnectionId
|
||||
);
|
||||
const externalResult = await executeExternalQuery(
|
||||
flowDef.dbConnectionId,
|
||||
query,
|
||||
params
|
||||
);
|
||||
console.log("📦 [getStepDataCount] External result:", externalResult);
|
||||
result = externalResult.rows;
|
||||
} else {
|
||||
// 내부 DB 조회
|
||||
console.log("✅ [getStepDataCount] Using INTERNAL DB");
|
||||
result = await db.query(query, params);
|
||||
}
|
||||
|
||||
const count = parseInt(result[0].count || result[0].COUNT);
|
||||
console.log("✅ [getStepDataCount] Final count:", count);
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,47 +126,98 @@ export class FlowExecutionService {
|
||||
|
||||
const offset = (page - 1) * pageSize;
|
||||
|
||||
const isExternalDb =
|
||||
flowDef.dbSourceType === "external" && flowDef.dbConnectionId;
|
||||
|
||||
// 5. 전체 카운트
|
||||
const countQuery = `SELECT COUNT(*) as count FROM ${tableName} WHERE ${where}`;
|
||||
const countResult = await db.query(countQuery, params);
|
||||
const total = parseInt(countResult[0].count);
|
||||
let countResult: any;
|
||||
let total: number;
|
||||
|
||||
// 6. 테이블의 Primary Key 컬럼 찾기
|
||||
let orderByColumn = "";
|
||||
try {
|
||||
const pkQuery = `
|
||||
SELECT a.attname
|
||||
FROM pg_index i
|
||||
JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)
|
||||
WHERE i.indrelid = $1::regclass
|
||||
AND i.indisprimary
|
||||
LIMIT 1
|
||||
`;
|
||||
const pkResult = await db.query(pkQuery, [tableName]);
|
||||
if (pkResult.length > 0) {
|
||||
orderByColumn = pkResult[0].attname;
|
||||
}
|
||||
} catch (err) {
|
||||
// Primary Key를 찾지 못하면 ORDER BY 없이 진행
|
||||
console.warn(`Could not find primary key for table ${tableName}:`, err);
|
||||
if (isExternalDb) {
|
||||
const externalCountResult = await executeExternalQuery(
|
||||
flowDef.dbConnectionId!,
|
||||
countQuery,
|
||||
params
|
||||
);
|
||||
countResult = externalCountResult.rows;
|
||||
total = parseInt(countResult[0].count || countResult[0].COUNT);
|
||||
} else {
|
||||
countResult = await db.query(countQuery, params);
|
||||
total = parseInt(countResult[0].count);
|
||||
}
|
||||
|
||||
// 7. 데이터 조회
|
||||
const orderByClause = orderByColumn ? `ORDER BY ${orderByColumn} DESC` : "";
|
||||
const dataQuery = `
|
||||
SELECT * FROM ${tableName}
|
||||
WHERE ${where}
|
||||
${orderByClause}
|
||||
LIMIT $${params.length + 1} OFFSET $${params.length + 2}
|
||||
`;
|
||||
const dataResult = await db.query(dataQuery, [...params, pageSize, offset]);
|
||||
// 6. 데이터 조회 (DB 타입별 페이징 처리)
|
||||
let dataQuery: string;
|
||||
let dataParams: any[];
|
||||
|
||||
return {
|
||||
records: dataResult,
|
||||
total,
|
||||
page,
|
||||
pageSize,
|
||||
};
|
||||
if (isExternalDb) {
|
||||
// 외부 DB는 id 컬럼으로 정렬 (가정)
|
||||
// DB 타입에 따른 페이징 절은 빌더에서 처리하지 않고 직접 작성
|
||||
// PostgreSQL, MySQL, MSSQL, Oracle 모두 지원하도록 단순화
|
||||
dataQuery = `
|
||||
SELECT * FROM ${tableName}
|
||||
WHERE ${where}
|
||||
ORDER BY id DESC
|
||||
LIMIT ${pageSize} OFFSET ${offset}
|
||||
`;
|
||||
dataParams = params;
|
||||
|
||||
const externalDataResult = await executeExternalQuery(
|
||||
flowDef.dbConnectionId!,
|
||||
dataQuery,
|
||||
dataParams
|
||||
);
|
||||
|
||||
return {
|
||||
records: externalDataResult.rows,
|
||||
total,
|
||||
page,
|
||||
pageSize,
|
||||
};
|
||||
} else {
|
||||
// 내부 DB (PostgreSQL)
|
||||
// Primary Key 컬럼 찾기
|
||||
let orderByColumn = "";
|
||||
try {
|
||||
const pkQuery = `
|
||||
SELECT a.attname
|
||||
FROM pg_index i
|
||||
JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)
|
||||
WHERE i.indrelid = $1::regclass
|
||||
AND i.indisprimary
|
||||
LIMIT 1
|
||||
`;
|
||||
const pkResult = await db.query(pkQuery, [tableName]);
|
||||
if (pkResult.length > 0) {
|
||||
orderByColumn = pkResult[0].attname;
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn(`Could not find primary key for table ${tableName}:`, err);
|
||||
}
|
||||
|
||||
const orderByClause = orderByColumn
|
||||
? `ORDER BY ${orderByColumn} DESC`
|
||||
: "";
|
||||
dataQuery = `
|
||||
SELECT * FROM ${tableName}
|
||||
WHERE ${where}
|
||||
${orderByClause}
|
||||
LIMIT $${params.length + 1} OFFSET $${params.length + 2}
|
||||
`;
|
||||
const dataResult = await db.query(dataQuery, [
|
||||
...params,
|
||||
pageSize,
|
||||
offset,
|
||||
]);
|
||||
|
||||
return {
|
||||
records: dataResult,
|
||||
total,
|
||||
page,
|
||||
pageSize,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user