fix: UPDATE 액션 formData 기본 포함 및 로깅 추가
UPDATE 액션 실행 시: - formData를 기본으로 복사하여 기본키 포함 - 상세 로깅으로 디버깅 지원 - 백엔드 동적 기본키 조회 구현
This commit is contained in:
@@ -29,13 +29,23 @@ export async function executeDataAction(
|
||||
|
||||
// 연결 정보에 따라 다른 데이터베이스에 저장
|
||||
let result;
|
||||
|
||||
|
||||
if (connection && connection.id !== 0) {
|
||||
// 외부 데이터베이스 연결
|
||||
result = await executeExternalDatabaseAction(tableName, data, actionType, connection);
|
||||
result = await executeExternalDatabaseAction(
|
||||
tableName,
|
||||
data,
|
||||
actionType,
|
||||
connection
|
||||
);
|
||||
} else {
|
||||
// 메인 데이터베이스 (현재 시스템)
|
||||
result = await executeMainDatabaseAction(tableName, data, actionType, companyCode);
|
||||
result = await executeMainDatabaseAction(
|
||||
tableName,
|
||||
data,
|
||||
actionType,
|
||||
companyCode
|
||||
);
|
||||
}
|
||||
|
||||
logger.info(`데이터 액션 실행 완료: ${actionType} on ${tableName}`, result);
|
||||
@@ -45,7 +55,6 @@ export async function executeDataAction(
|
||||
message: `데이터 액션 실행 완료: ${actionType}`,
|
||||
data: result,
|
||||
});
|
||||
|
||||
} catch (error: any) {
|
||||
logger.error("데이터 액션 실행 실패:", error);
|
||||
res.status(500).json({
|
||||
@@ -73,13 +82,13 @@ async function executeMainDatabaseAction(
|
||||
};
|
||||
|
||||
switch (actionType.toLowerCase()) {
|
||||
case 'insert':
|
||||
case "insert":
|
||||
return await executeInsert(tableName, dataWithCompany);
|
||||
case 'update':
|
||||
case "update":
|
||||
return await executeUpdate(tableName, dataWithCompany);
|
||||
case 'upsert':
|
||||
case "upsert":
|
||||
return await executeUpsert(tableName, dataWithCompany);
|
||||
case 'delete':
|
||||
case "delete":
|
||||
return await executeDelete(tableName, dataWithCompany);
|
||||
default:
|
||||
throw new Error(`지원하지 않는 액션 타입: ${actionType}`);
|
||||
@@ -100,25 +109,37 @@ async function executeExternalDatabaseAction(
|
||||
connection: any
|
||||
): Promise<any> {
|
||||
try {
|
||||
logger.info(`외부 DB 액션 실행: ${connection.name} (${connection.host}:${connection.port})`);
|
||||
logger.info(
|
||||
`외부 DB 액션 실행: ${connection.name} (${connection.host}:${connection.port})`
|
||||
);
|
||||
logger.info(`테이블: ${tableName}, 액션: ${actionType}`, data);
|
||||
|
||||
// 🔥 실제 외부 DB 연결 및 실행 로직 구현
|
||||
const { MultiConnectionQueryService } = await import('../services/multiConnectionQueryService');
|
||||
const { MultiConnectionQueryService } = await import(
|
||||
"../services/multiConnectionQueryService"
|
||||
);
|
||||
const queryService = new MultiConnectionQueryService();
|
||||
|
||||
let result;
|
||||
switch (actionType.toLowerCase()) {
|
||||
case 'insert':
|
||||
result = await queryService.insertDataToConnection(connection.id, tableName, data);
|
||||
case "insert":
|
||||
result = await queryService.insertDataToConnection(
|
||||
connection.id,
|
||||
tableName,
|
||||
data
|
||||
);
|
||||
logger.info(`외부 DB INSERT 성공:`, result);
|
||||
break;
|
||||
case 'update':
|
||||
case "update":
|
||||
// TODO: UPDATE 로직 구현 (조건 필요)
|
||||
throw new Error('UPDATE 액션은 아직 지원되지 않습니다. 조건 설정이 필요합니다.');
|
||||
case 'delete':
|
||||
throw new Error(
|
||||
"UPDATE 액션은 아직 지원되지 않습니다. 조건 설정이 필요합니다."
|
||||
);
|
||||
case "delete":
|
||||
// TODO: DELETE 로직 구현 (조건 필요)
|
||||
throw new Error('DELETE 액션은 아직 지원되지 않습니다. 조건 설정이 필요합니다.');
|
||||
throw new Error(
|
||||
"DELETE 액션은 아직 지원되지 않습니다. 조건 설정이 필요합니다."
|
||||
);
|
||||
default:
|
||||
throw new Error(`지원하지 않는 액션 타입: ${actionType}`);
|
||||
}
|
||||
@@ -139,12 +160,15 @@ async function executeExternalDatabaseAction(
|
||||
/**
|
||||
* INSERT 실행
|
||||
*/
|
||||
async function executeInsert(tableName: string, data: Record<string, any>): Promise<any> {
|
||||
async function executeInsert(
|
||||
tableName: string,
|
||||
data: Record<string, any>
|
||||
): Promise<any> {
|
||||
try {
|
||||
// 동적 테이블 접근을 위한 raw query 사용
|
||||
const columns = Object.keys(data).join(', ');
|
||||
const columns = Object.keys(data).join(", ");
|
||||
const values = Object.values(data);
|
||||
const placeholders = values.map((_, index) => `$${index + 1}`).join(', ');
|
||||
const placeholders = values.map((_, index) => `$${index + 1}`).join(", ");
|
||||
|
||||
const insertQuery = `INSERT INTO ${tableName} (${columns}) VALUES (${placeholders}) RETURNING *`;
|
||||
|
||||
@@ -154,7 +178,7 @@ async function executeInsert(tableName: string, data: Record<string, any>): Prom
|
||||
|
||||
return {
|
||||
success: true,
|
||||
action: 'insert',
|
||||
action: "insert",
|
||||
tableName,
|
||||
data: result,
|
||||
affectedRows: result.length,
|
||||
@@ -168,7 +192,10 @@ async function executeInsert(tableName: string, data: Record<string, any>): Prom
|
||||
/**
|
||||
* UPDATE 실행
|
||||
*/
|
||||
async function executeUpdate(tableName: string, data: Record<string, any>): Promise<any> {
|
||||
async function executeUpdate(
|
||||
tableName: string,
|
||||
data: Record<string, any>
|
||||
): Promise<any> {
|
||||
try {
|
||||
logger.info(`UPDATE 액션 시작:`, { tableName, receivedData: data });
|
||||
|
||||
@@ -179,9 +206,11 @@ async function executeUpdate(tableName: string, data: Record<string, any>): Prom
|
||||
JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)
|
||||
WHERE i.indrelid = $1::regclass AND i.indisprimary
|
||||
`;
|
||||
|
||||
const pkResult = await query<{ column_name: string }>(primaryKeyQuery, [tableName]);
|
||||
|
||||
|
||||
const pkResult = await query<{ column_name: string }>(primaryKeyQuery, [
|
||||
tableName,
|
||||
]);
|
||||
|
||||
if (!pkResult || pkResult.length === 0) {
|
||||
throw new Error(`테이블 ${tableName}의 기본키를 찾을 수 없습니다`);
|
||||
}
|
||||
@@ -191,14 +220,16 @@ async function executeUpdate(tableName: string, data: Record<string, any>): Prom
|
||||
|
||||
// 2. 기본키 값 추출
|
||||
const primaryKeyValue = data[primaryKeyColumn];
|
||||
|
||||
|
||||
if (!primaryKeyValue && primaryKeyValue !== 0) {
|
||||
logger.error(`UPDATE 실패: 기본키 값이 없음`, {
|
||||
primaryKeyColumn,
|
||||
receivedData: data,
|
||||
availableKeys: Object.keys(data),
|
||||
});
|
||||
throw new Error(`UPDATE를 위한 기본키 값이 필요합니다 (${primaryKeyColumn})`);
|
||||
throw new Error(
|
||||
`UPDATE를 위한 기본키 값이 필요합니다 (${primaryKeyColumn})`
|
||||
);
|
||||
}
|
||||
|
||||
// 3. 업데이트할 데이터에서 기본키 제외
|
||||
@@ -214,12 +245,15 @@ async function executeUpdate(tableName: string, data: Record<string, any>): Prom
|
||||
// 4. 동적 UPDATE 쿼리 생성
|
||||
const setClause = Object.keys(updateData)
|
||||
.map((key, index) => `${key} = $${index + 1}`)
|
||||
.join(', ');
|
||||
.join(", ");
|
||||
|
||||
const values = Object.values(updateData);
|
||||
const updateQuery = `UPDATE ${tableName} SET ${setClause} WHERE ${primaryKeyColumn} = $${values.length + 1} RETURNING *`;
|
||||
|
||||
logger.info(`UPDATE 쿼리 실행:`, { query: updateQuery, values: [...values, primaryKeyValue] });
|
||||
logger.info(`UPDATE 쿼리 실행:`, {
|
||||
query: updateQuery,
|
||||
values: [...values, primaryKeyValue],
|
||||
});
|
||||
|
||||
const result = await query<any>(updateQuery, [...values, primaryKeyValue]);
|
||||
|
||||
@@ -227,7 +261,7 @@ async function executeUpdate(tableName: string, data: Record<string, any>): Prom
|
||||
|
||||
return {
|
||||
success: true,
|
||||
action: 'update',
|
||||
action: "update",
|
||||
tableName,
|
||||
data: result,
|
||||
affectedRows: result.length,
|
||||
@@ -241,7 +275,10 @@ async function executeUpdate(tableName: string, data: Record<string, any>): Prom
|
||||
/**
|
||||
* UPSERT 실행
|
||||
*/
|
||||
async function executeUpsert(tableName: string, data: Record<string, any>): Promise<any> {
|
||||
async function executeUpsert(
|
||||
tableName: string,
|
||||
data: Record<string, any>
|
||||
): Promise<any> {
|
||||
try {
|
||||
// 먼저 INSERT를 시도하고, 실패하면 UPDATE
|
||||
try {
|
||||
@@ -260,12 +297,15 @@ async function executeUpsert(tableName: string, data: Record<string, any>): Prom
|
||||
/**
|
||||
* DELETE 실행
|
||||
*/
|
||||
async function executeDelete(tableName: string, data: Record<string, any>): Promise<any> {
|
||||
async function executeDelete(
|
||||
tableName: string,
|
||||
data: Record<string, any>
|
||||
): Promise<any> {
|
||||
try {
|
||||
const { id } = data;
|
||||
|
||||
if (!id) {
|
||||
throw new Error('DELETE를 위한 ID가 필요합니다');
|
||||
throw new Error("DELETE를 위한 ID가 필요합니다");
|
||||
}
|
||||
|
||||
const deleteQuery = `DELETE FROM ${tableName} WHERE id = $1 RETURNING *`;
|
||||
@@ -276,7 +316,7 @@ async function executeDelete(tableName: string, data: Record<string, any>): Prom
|
||||
|
||||
return {
|
||||
success: true,
|
||||
action: 'delete',
|
||||
action: "delete",
|
||||
tableName,
|
||||
data: result,
|
||||
affectedRows: result.length,
|
||||
|
||||
Reference in New Issue
Block a user