diff --git a/src/main/java/com/cloudhandson/vpdbackoffice/domain/protectedobject/DatabaseObjectOption.java b/src/main/java/com/cloudhandson/vpdbackoffice/domain/protectedobject/DatabaseObjectOption.java index 7922dbd..0a4a17d 100644 --- a/src/main/java/com/cloudhandson/vpdbackoffice/domain/protectedobject/DatabaseObjectOption.java +++ b/src/main/java/com/cloudhandson/vpdbackoffice/domain/protectedobject/DatabaseObjectOption.java @@ -13,8 +13,4 @@ public record DatabaseObjectOption( public String label() { return owner + "." + objectName + " (" + objectType + ")"; } - - public String defaultOrdsPath() { - return owner.toLowerCase() + "/" + objectName.toLowerCase(); - } } diff --git a/src/main/java/com/cloudhandson/vpdbackoffice/mapper/ProtectedObjectMapper.java b/src/main/java/com/cloudhandson/vpdbackoffice/mapper/ProtectedObjectMapper.java index fd9111f..36996ef 100644 --- a/src/main/java/com/cloudhandson/vpdbackoffice/mapper/ProtectedObjectMapper.java +++ b/src/main/java/com/cloudhandson/vpdbackoffice/mapper/ProtectedObjectMapper.java @@ -34,5 +34,7 @@ public interface ProtectedObjectMapper { @Param("columnName") String columnName, @Param("sensitiveYn") String sensitiveYn); + int updateOrdsPath(@Param("objectId") long objectId, @Param("ordsPath") String ordsPath); + int disableObject(@Param("objectId") long objectId); } diff --git a/src/main/java/com/cloudhandson/vpdbackoffice/service/ProtectedObjectService.java b/src/main/java/com/cloudhandson/vpdbackoffice/service/ProtectedObjectService.java index e1cfcf6..4bbb830 100644 --- a/src/main/java/com/cloudhandson/vpdbackoffice/service/ProtectedObjectService.java +++ b/src/main/java/com/cloudhandson/vpdbackoffice/service/ProtectedObjectService.java @@ -68,29 +68,8 @@ public class ProtectedObjectService { if (existing != null) { return existing; } - List columns = mapper.findDatabaseColumns(owner, objectName); - if (columns.isEmpty()) { - throw new AppException("DB 객체 컬럼을 찾을 수 없습니다: " + owner + "." + objectName); - } - long objectId = mapper.nextObjectId(); - mapper.insertObject(objectId, new ProtectedObjectCreateCommand( - owner, - objectName, - defaultOrdsPath(owner, objectName), - String.join(",", columns), - "" - )); - for (String column : columns) { - mapper.insertColumn(mapper.nextColumnId(), objectId, column, "N"); - } - auditService.record(new AuditEvent("PROTECTED_OBJECT_CREATED", null, objectId, "SUCCESS", null, null, - owner + "." + objectName)); - return mapper.findById(objectId); - } - - private String defaultOrdsPath(String owner, String objectName) { - String schemaPath = owner.equalsIgnoreCase("CB_ORDS") ? "cb-ords" : owner.toLowerCase(Locale.ROOT); - return schemaPath + "/" + objectName.toLowerCase(Locale.ROOT); + throw new AppException("테이블/뷰 관리에서 실제 ORDS Path를 먼저 등록하세요: " + + owner.toUpperCase(Locale.ROOT) + "." + objectName.toUpperCase(Locale.ROOT)); } private ProtectedObjectCreateCommand normalizeCreateCommand(ProtectedObjectCreateCommand command) { @@ -98,7 +77,7 @@ public class ProtectedObjectService { String objectName = command.objectName().trim().toUpperCase(Locale.ROOT); String ordsPath = command.ordsPath(); if (ordsPath == null || ordsPath.isBlank()) { - ordsPath = defaultOrdsPath(owner, objectName); + throw new AppException("ORDS Path는 실제 ORDS module/template 경로를 입력해야 합니다."); } String columns = command.columns(); if (columns == null || columns.isBlank()) { @@ -107,6 +86,19 @@ public class ProtectedObjectService { return new ProtectedObjectCreateCommand(owner, objectName, ordsPath.trim(), columns, command.sensitiveColumns()); } + @Transactional + public void updateOrdsPath(long objectId, String ordsPath) { + if (ordsPath == null || ordsPath.isBlank()) { + throw new AppException("ORDS Path는 필수입니다."); + } + int updated = mapper.updateOrdsPath(objectId, ordsPath.trim()); + if (updated == 0) { + throw new AppException("보호 객체를 찾을 수 없습니다."); + } + auditService.record(new AuditEvent("PROTECTED_OBJECT_ORDS_PATH_UPDATED", null, objectId, "SUCCESS", null, null, + ordsPath.trim())); + } + @Transactional public void disableObject(long objectId) { int updated = mapper.disableObject(objectId); diff --git a/src/main/java/com/cloudhandson/vpdbackoffice/web/ProtectedObjectController.java b/src/main/java/com/cloudhandson/vpdbackoffice/web/ProtectedObjectController.java index 447e492..65f2abe 100644 --- a/src/main/java/com/cloudhandson/vpdbackoffice/web/ProtectedObjectController.java +++ b/src/main/java/com/cloudhandson/vpdbackoffice/web/ProtectedObjectController.java @@ -1,6 +1,7 @@ package com.cloudhandson.vpdbackoffice.web; import com.cloudhandson.vpdbackoffice.domain.protectedobject.ProtectedObjectCreateCommand; +import com.cloudhandson.vpdbackoffice.service.AppException; import com.cloudhandson.vpdbackoffice.service.ProtectedObjectService; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; @@ -34,9 +35,28 @@ public class ProtectedObjectController { @RequestParam(required = false) String sensitiveColumns, RedirectAttributes redirectAttributes ) { - protectedObjectService.createObject( - new ProtectedObjectCreateCommand(owner, objectName, ordsPath, columns, sensitiveColumns)); - redirectAttributes.addFlashAttribute("message", "보호 객체를 추가했습니다."); + try { + protectedObjectService.createObject( + new ProtectedObjectCreateCommand(owner, objectName, ordsPath, columns, sensitiveColumns)); + redirectAttributes.addFlashAttribute("message", "보호 객체를 추가했습니다."); + } catch (AppException exception) { + redirectAttributes.addFlashAttribute("errorMessage", exception.getMessage()); + } + return "redirect:/objects"; + } + + @PostMapping("/objects/ords-path") + public String updateOrdsPath( + @RequestParam long objectId, + @RequestParam String ordsPath, + RedirectAttributes redirectAttributes + ) { + try { + protectedObjectService.updateOrdsPath(objectId, ordsPath); + redirectAttributes.addFlashAttribute("message", "ORDS Path를 수정했습니다."); + } catch (AppException exception) { + redirectAttributes.addFlashAttribute("errorMessage", exception.getMessage()); + } return "redirect:/objects"; } diff --git a/src/main/resources/mapper/ProtectedObjectMapper.xml b/src/main/resources/mapper/ProtectedObjectMapper.xml index 0518c8d..67e4fb2 100644 --- a/src/main/resources/mapper/ProtectedObjectMapper.xml +++ b/src/main/resources/mapper/ProtectedObjectMapper.xml @@ -71,6 +71,12 @@ VALUES (#{columnId}, #{objectId}, UPPER(#{columnName}), #{sensitiveYn}) + + UPDATE cb_protected_object + SET ords_path = #{ordsPath,jdbcType=VARCHAR} + WHERE object_id = #{objectId,jdbcType=NUMERIC} + + UPDATE cb_protected_object SET enabled_yn = 'N' diff --git a/src/main/resources/static/js/app.js b/src/main/resources/static/js/app.js index 747c62d..8ae8e8b 100644 --- a/src/main/resources/static/js/app.js +++ b/src/main/resources/static/js/app.js @@ -76,8 +76,8 @@ async function syncObjectCatalogSelection() { if (objectInput) { objectInput.value = selected.dataset.objectName || ''; } - if (ordsPathInput) { - ordsPathInput.value = selected.dataset.defaultPath || ''; + if (ordsPathInput && !ordsPathInput.value) { + ordsPathInput.focus(); } if (!columnsInput) { return; diff --git a/src/main/resources/templates/objects.html b/src/main/resources/templates/objects.html index d4ca353..fa55120 100644 --- a/src/main/resources/templates/objects.html +++ b/src/main/resources/templates/objects.html @@ -10,6 +10,7 @@
+

테이블/뷰 추가

@@ -23,7 +24,6 @@ th:value="${dbObject.value()}" th:data-owner="${dbObject.owner()}" th:data-object-name="${dbObject.objectName()}" - th:data-default-path="${dbObject.defaultOrdsPath()}" th:text="${dbObject.label()}"> @@ -37,7 +37,7 @@