From b38b498926265675cf6b82c937f19e78148eb851 Mon Sep 17 00:00:00 2001 From: vran Date: Sat, 19 Mar 2022 14:35:39 +0800 Subject: [PATCH] feat:add databasir diff api --- .../com/databasir/api/DocumentController.java | 8 +++ .../main/java/com/databasir/api/Routes.java | 2 + .../databasir/core/domain/DomainErrors.java | 1 + .../document/service/DocumentService.java | 16 ++++++ .../diff/processor/TableDiffProcessor.java | 50 ++++++++++++++++--- 5 files changed, 70 insertions(+), 7 deletions(-) diff --git a/api/src/main/java/com/databasir/api/DocumentController.java b/api/src/main/java/com/databasir/api/DocumentController.java index 52f78e2..a050d39 100644 --- a/api/src/main/java/com/databasir/api/DocumentController.java +++ b/api/src/main/java/com/databasir/api/DocumentController.java @@ -1,6 +1,7 @@ package com.databasir.api; import com.databasir.common.JsonData; +import com.databasir.core.diff.data.RootDiff; import com.databasir.core.domain.document.data.DatabaseDocumentResponse; import com.databasir.core.domain.document.data.DatabaseDocumentSimpleResponse; import com.databasir.core.domain.document.data.DatabaseDocumentVersionResponse; @@ -39,6 +40,13 @@ public class DocumentController { return JsonData.ok(); } + @GetMapping(Routes.Document.DIFF) + public JsonData diff(@PathVariable Integer projectId, + @RequestParam(name = "originalVersion") Long originalVersion, + @RequestParam(required = false) Long currentVersion) { + return JsonData.ok(documentService.diff(projectId, originalVersion, currentVersion)); + } + @GetMapping(Routes.Document.GET_ONE) public JsonData getByProjectId(@PathVariable Integer projectId, @RequestParam(required = false) Long version) { diff --git a/api/src/main/java/com/databasir/api/Routes.java b/api/src/main/java/com/databasir/api/Routes.java index c33819c..b700e66 100644 --- a/api/src/main/java/com/databasir/api/Routes.java +++ b/api/src/main/java/com/databasir/api/Routes.java @@ -82,6 +82,8 @@ public interface Routes { String GET_TABLE_DETAIL = BASE + "/projects/{projectId}/documents/{documentId}/table_documents"; + String DIFF = BASE + "/projects/{projectId}/diff_documents"; + String EXPORT = BASE + "/projects/{projectId}/document_files"; } diff --git a/core/src/main/java/com/databasir/core/domain/DomainErrors.java b/core/src/main/java/com/databasir/core/domain/DomainErrors.java index 4056d4a..d8142de 100644 --- a/core/src/main/java/com/databasir/core/domain/DomainErrors.java +++ b/core/src/main/java/com/databasir/core/domain/DomainErrors.java @@ -32,6 +32,7 @@ public enum DomainErrors implements DatabasirErrors { MUST_NOT_MODIFY_SYSTEM_DEFAULT_DATABASE_TYPE("A_10017", "禁止修改系统默认数据库类型"), DOWNLOAD_DRIVER_ERROR("A_10018", "驱动下载失败"), INVALID_DATABASE_TYPE_URL_PATTERN("A_10019", "不合法的 url pattern"), + DOCUMENT_VERSION_IS_INVALID("A_10020", "文档版本不合法"), ; private final String errCode; diff --git a/core/src/main/java/com/databasir/core/domain/document/service/DocumentService.java b/core/src/main/java/com/databasir/core/domain/document/service/DocumentService.java index c7f1dd2..571259b 100644 --- a/core/src/main/java/com/databasir/core/domain/document/service/DocumentService.java +++ b/core/src/main/java/com/databasir/core/domain/document/service/DocumentService.java @@ -349,4 +349,20 @@ public class DocumentService { .ifPresent(generator -> generator.generate(context, out)); }); } + + public RootDiff diff(Integer projectId, Long originalVersion, Long currentVersion) { + var original = databaseDocumentDao.selectOptionalByProjectIdAndVersion(projectId, originalVersion) + .orElseThrow(DomainErrors.DOCUMENT_VERSION_IS_INVALID::exception); + DatabaseDocumentPojo current; + if (currentVersion == null) { + current = databaseDocumentDao.selectNotArchivedByProjectId(projectId) + .orElseThrow(DomainErrors.DOCUMENT_VERSION_IS_INVALID::exception); + } else { + current = databaseDocumentDao.selectOptionalByProjectIdAndVersion(projectId, currentVersion) + .orElseThrow(DomainErrors.DOCUMENT_VERSION_IS_INVALID::exception); + } + DatabaseMeta currMeta = retrieveOriginalDatabaseMeta(current); + DatabaseMeta originalMeta = retrieveOriginalDatabaseMeta(original); + return Diffs.diff(originalMeta, currMeta); + } } diff --git a/plugin/src/main/java/com/databasir/core/diff/processor/TableDiffProcessor.java b/plugin/src/main/java/com/databasir/core/diff/processor/TableDiffProcessor.java index b991041..2612de6 100644 --- a/plugin/src/main/java/com/databasir/core/diff/processor/TableDiffProcessor.java +++ b/plugin/src/main/java/com/databasir/core/diff/processor/TableDiffProcessor.java @@ -19,18 +19,26 @@ public class TableDiffProcessor implements DiffProcessor { private final ForeignKeyDiffProcessor foreignKeyDiffProcessor = new ForeignKeyDiffProcessor(); + private static final TableMeta EMPTY = new TableMeta(); + @Override public FieldDiff process(String fieldName, List original, List current) { // diff tables field Map originalMap = toMap(original, TableMeta::getName); Map currentMap = toMap(current, TableMeta::getName); - List tables = new ArrayList<>(32); - // removed - List removedFields = originalRemovedField(originalMap, currentMap); - tables.addAll(removedFields); + List tables = new ArrayList<>(); + List added = added(originalMap, currentMap); + List removed = removed(originalMap, currentMap); // added - List addedFields = currentAddedField(originalMap, currentMap); + List addedFields = added.stream() + .map(table -> diffTableField(EMPTY, table)) + .collect(Collectors.toList()); tables.addAll(addedFields); + // removed + List removedFields = removed.stream() + .map(table -> diffTableField(table, EMPTY)) + .collect(Collectors.toList()); + tables.addAll(removedFields); // modified List modified = originalMap.entrySet() .stream() @@ -61,6 +69,24 @@ public class TableDiffProcessor implements DiffProcessor { return tablesField; } + private List added(Map originalMap, + Map currentMap) { + return currentMap.entrySet() + .stream() + .filter(entry -> !originalMap.containsKey(entry.getKey())) + .map(Map.Entry::getValue) + .collect(Collectors.toList()); + } + + private List removed(Map originalMap, + Map currentMap) { + return originalMap.entrySet() + .stream() + .filter(entry -> !currentMap.containsKey(entry.getKey())) + .map(Map.Entry::getValue) + .collect(Collectors.toList()); + } + private FieldDiff diffTableField(TableMeta original, TableMeta current) { FieldDiff columns = columnDiffProcessor.process("columns", original.getColumns(), current.getColumns()); @@ -78,9 +104,19 @@ public class TableDiffProcessor implements DiffProcessor { fields.add(foreignKeys); fields.add(triggers); fields.addAll(otherFields); + DiffType diffType; + if (original == EMPTY) { + diffType = DiffType.ADDED; + } else if (current == EMPTY) { + diffType = DiffType.REMOVED; + } else { + diffType = DiffType.MODIFIED; + } return FieldDiff.builder() - .diffType(DiffType.MODIFIED) - .fieldName(original.getName()) + .diffType(diffType) + .fieldName(original == EMPTY ? current.getName() : original.getName()) + .original(current == EMPTY ? original : null) + .current(original == EMPTY ? current : null) .fields(fields) .build(); }