mirror of
https://github.com/vran-dev/databasir.git
synced 2025-08-08 17:32:14 +08:00
refactor diff api (#138)
* ref: migrate diff logic to list api * feat: update frontend resources * fix: checkstyle
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
package com.databasir.core.domain.document.comparator;
|
||||
|
||||
import com.databasir.core.diff.data.DiffType;
|
||||
import lombok.Data;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Data
|
||||
@RequiredArgsConstructor
|
||||
public class DiffResult {
|
||||
|
||||
private final String id;
|
||||
|
||||
private final DiffType diffType;
|
||||
|
||||
}
|
@@ -0,0 +1,188 @@
|
||||
package com.databasir.core.domain.document.comparator;
|
||||
|
||||
import com.databasir.core.diff.data.DiffType;
|
||||
import com.databasir.core.meta.data.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
public class DocumentDiffs {
|
||||
|
||||
public static List<TableDiffResult> tableDiff(DatabaseMeta original, DatabaseMeta current) {
|
||||
return tableDiff(original.getTables(), current.getTables());
|
||||
}
|
||||
|
||||
public static List<TableDiffResult> tableDiff(List<TableMeta> original, List<TableMeta> current) {
|
||||
Map<String, TableMeta> originalTablesMap = toMap(original, TableMeta::getName);
|
||||
Map<String, TableMeta> currentTablesMap = toMap(current, TableMeta::getName);
|
||||
var added = added(originalTablesMap, currentTablesMap)
|
||||
.stream()
|
||||
.map(curr -> {
|
||||
TableDiffResult result = new TableDiffResult(curr.getName(), DiffType.ADDED);
|
||||
List<DiffResult> columnDiffs =
|
||||
doDiff(Collections.emptyList(), curr.getColumns(), ColumnMeta::getName);
|
||||
List<DiffResult> indexDiffs =
|
||||
doDiff(Collections.emptyList(), curr.getIndexes(), IndexMeta::getName);
|
||||
List<DiffResult> triggerDiffs =
|
||||
doDiff(Collections.emptyList(), curr.getTriggers(), TriggerMeta::getName);
|
||||
List<DiffResult> fkDiffs =
|
||||
doDiff(Collections.emptyList(),
|
||||
curr.getForeignKeys(),
|
||||
fk -> fk.getFkTableName() + "." + fk.getFkColumnName() + "." + fk.getKeySeq());
|
||||
result.setColumnDiffResults(columnDiffs);
|
||||
result.setIndexDiffResults(indexDiffs);
|
||||
result.setTriggerDiffResults(triggerDiffs);
|
||||
result.setForeignKeyDiffResults(fkDiffs);
|
||||
return result;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
var removed = removed(originalTablesMap, currentTablesMap)
|
||||
.stream()
|
||||
.map(old -> {
|
||||
TableDiffResult result = new TableDiffResult(old.getName(), DiffType.REMOVED);
|
||||
List<DiffResult> columnDiffs =
|
||||
doDiff(old.getColumns(), Collections.emptyList(), ColumnMeta::getName);
|
||||
List<DiffResult> indexDiffs =
|
||||
doDiff(old.getIndexes(), Collections.emptyList(), IndexMeta::getName);
|
||||
List<DiffResult> triggerDiffs =
|
||||
doDiff(old.getTriggers(), Collections.emptyList(), TriggerMeta::getName);
|
||||
List<DiffResult> fkDiffs =
|
||||
doDiff(old.getForeignKeys(),
|
||||
Collections.emptyList(),
|
||||
fk -> fk.getFkTableName() + "." + fk.getFkColumnName() + "." + fk.getKeySeq());
|
||||
result.setColumnDiffResults(columnDiffs);
|
||||
result.setIndexDiffResults(indexDiffs);
|
||||
result.setTriggerDiffResults(triggerDiffs);
|
||||
result.setForeignKeyDiffResults(fkDiffs);
|
||||
return result;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
List<TableDiffResult> sameOrModified = currentTablesMap.entrySet()
|
||||
.stream()
|
||||
.filter(entry -> originalTablesMap.containsKey(entry.getKey()))
|
||||
.map(entry -> {
|
||||
String tableName = entry.getKey();
|
||||
TableMeta currentTable = entry.getValue();
|
||||
TableMeta originalTable = originalTablesMap.get(tableName);
|
||||
|
||||
List<DiffResult> columnDiffs =
|
||||
doDiff(originalTable.getColumns(), currentTable.getColumns(), ColumnMeta::getName);
|
||||
List<DiffResult> indexDiffs =
|
||||
doDiff(originalTable.getIndexes(), currentTable.getIndexes(), IndexMeta::getName);
|
||||
List<DiffResult> triggerDiffs =
|
||||
doDiff(originalTable.getTriggers(), currentTable.getTriggers(), TriggerMeta::getName);
|
||||
List<DiffResult> fkDiffs =
|
||||
doDiff(originalTable.getForeignKeys(),
|
||||
currentTable.getForeignKeys(),
|
||||
fk -> fk.getFkTableName() + "." + fk.getFkColumnName() + "." + fk.getKeySeq());
|
||||
|
||||
DiffType diffType = Objects.equals(currentTable, originalTable) ? DiffType.NONE : DiffType.MODIFIED;
|
||||
TableDiffResult diffResult = new TableDiffResult(tableName, diffType);
|
||||
diffResult.setColumnDiffResults(columnDiffs);
|
||||
diffResult.setIndexDiffResults(indexDiffs);
|
||||
diffResult.setTriggerDiffResults(triggerDiffs);
|
||||
diffResult.setForeignKeyDiffResults(fkDiffs);
|
||||
return diffResult;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<TableDiffResult> all = new ArrayList<>(16);
|
||||
all.addAll(sameOrModified);
|
||||
all.addAll(added);
|
||||
all.addAll(removed);
|
||||
return all;
|
||||
}
|
||||
|
||||
private static <T> List<DiffResult> doDiff(List<T> original, List<T> current, Function<T, String> idMapping) {
|
||||
Map<String, T> originalColumnMap = toMap(original, idMapping);
|
||||
Map<String, T> currentColumnMap = toMap(current, idMapping);
|
||||
BiFunction<T, DiffType, DiffResult> mapping = (meta, diffType) -> {
|
||||
return new DiffResult(idMapping.apply(meta), diffType);
|
||||
};
|
||||
List<DiffResult> added = added(originalColumnMap, currentColumnMap)
|
||||
.stream()
|
||||
.map(col -> mapping.apply(col, DiffType.ADDED))
|
||||
.collect(Collectors.toList());
|
||||
List<DiffResult> removed = removed(originalColumnMap, currentColumnMap)
|
||||
.stream()
|
||||
.map(col -> mapping.apply(col, DiffType.REMOVED))
|
||||
.collect(Collectors.toList());
|
||||
List<DiffResult> modified = modified(originalColumnMap, currentColumnMap)
|
||||
.stream()
|
||||
.map(col -> mapping.apply(col, DiffType.MODIFIED))
|
||||
.collect(Collectors.toList());
|
||||
List<DiffResult> same = same(originalColumnMap, currentColumnMap)
|
||||
.stream()
|
||||
.map(col -> mapping.apply(col, DiffType.NONE))
|
||||
.collect(Collectors.toList());
|
||||
List<DiffResult> columnResults = new ArrayList<>();
|
||||
columnResults.addAll(same);
|
||||
columnResults.addAll(added);
|
||||
columnResults.addAll(modified);
|
||||
columnResults.addAll(removed);
|
||||
return columnResults;
|
||||
}
|
||||
|
||||
private static <T> Map<String, T> toMap(List<T> content, Function<T, String> idMapping) {
|
||||
return content
|
||||
.stream()
|
||||
.collect(Collectors.toMap(idMapping, Function.identity(), (a, b) -> {
|
||||
log.warn("Duplicate key, origin = {}, current = {}", a, b);
|
||||
return a;
|
||||
}));
|
||||
}
|
||||
|
||||
private static <T> List<T> added(Map<String, T> originalMapById,
|
||||
Map<String, T> currentMapById) {
|
||||
return currentMapById.entrySet()
|
||||
.stream()
|
||||
.filter(entry -> !originalMapById.containsKey(entry.getKey()))
|
||||
.map(Map.Entry::getValue)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static <T> List<T> removed(Map<String, T> originalMapById,
|
||||
Map<String, T> currentMapById) {
|
||||
return originalMapById.entrySet()
|
||||
.stream()
|
||||
.filter(entry -> !currentMapById.containsKey(entry.getKey()))
|
||||
.map(Map.Entry::getValue)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static <T> List<T> modified(Map<String, T> originalMapById,
|
||||
Map<String, T> currentMapById) {
|
||||
return modified(originalMapById, currentMapById, Objects::equals);
|
||||
}
|
||||
|
||||
private static <T> List<T> modified(Map<String, T> originalMapById,
|
||||
Map<String, T> currentMapById,
|
||||
BiFunction<T, T, Boolean> sameFunction) {
|
||||
return currentMapById.entrySet()
|
||||
.stream()
|
||||
.filter(entry -> originalMapById.containsKey(entry.getKey()))
|
||||
.filter(entry -> !sameFunction.apply(entry.getValue(), originalMapById.get(entry.getKey())))
|
||||
.map(Map.Entry::getValue)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static <T> List<T> same(Map<String, T> originalMapById,
|
||||
Map<String, T> currentMapById) {
|
||||
return same(originalMapById, currentMapById, Objects::equals);
|
||||
}
|
||||
|
||||
private static <T> List<T> same(Map<String, T> originalMapById,
|
||||
Map<String, T> currentMapById,
|
||||
BiFunction<T, T, Boolean> sameFunction) {
|
||||
return currentMapById.entrySet()
|
||||
.stream()
|
||||
.filter(entry -> originalMapById.containsKey(entry.getKey()))
|
||||
.filter(entry -> sameFunction.apply(entry.getValue(), originalMapById.get(entry.getKey())))
|
||||
.map(Map.Entry::getValue)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
@@ -0,0 +1,25 @@
|
||||
package com.databasir.core.domain.document.comparator;
|
||||
|
||||
import com.databasir.core.diff.data.DiffType;
|
||||
import lombok.Data;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
@Data
|
||||
@RequiredArgsConstructor
|
||||
public class TableDiffResult {
|
||||
|
||||
private final String id;
|
||||
|
||||
private final DiffType diffType;
|
||||
|
||||
private Collection<DiffResult> columnDiffResults = Collections.emptyList();
|
||||
|
||||
private Collection<DiffResult> indexDiffResults = Collections.emptyList();
|
||||
|
||||
private Collection<DiffResult> triggerDiffResults = Collections.emptyList();
|
||||
|
||||
private Collection<DiffResult> foreignKeyDiffResults = Collections.emptyList();
|
||||
}
|
@@ -1,5 +1,6 @@
|
||||
package com.databasir.core.domain.document.converter;
|
||||
|
||||
import com.databasir.core.domain.document.data.TableDocumentResponse;
|
||||
import com.databasir.core.infrastructure.converter.JsonConverter;
|
||||
import com.databasir.core.meta.data.ColumnMeta;
|
||||
import com.databasir.core.meta.data.DatabaseMeta;
|
||||
@@ -64,6 +65,10 @@ public interface DatabaseMetaConverter {
|
||||
@Mapping(target = "columnNames", source = "pojo.columnNameArray")
|
||||
IndexMeta of(TableIndexDocumentPojo pojo);
|
||||
|
||||
List<TableMeta> of(List<TableDocumentResponse> table);
|
||||
|
||||
TableMeta of(TableDocumentResponse table);
|
||||
|
||||
default <R> Map<Integer, List<R>> groupBy(List<R> content, Function<R, Integer> idMapping) {
|
||||
return content.stream()
|
||||
.collect(Collectors.groupingBy(idMapping));
|
||||
|
@@ -1,10 +1,7 @@
|
||||
package com.databasir.core.domain.document.converter;
|
||||
|
||||
import com.databasir.core.infrastructure.converter.JsonConverter;
|
||||
import com.databasir.core.meta.data.ColumnMeta;
|
||||
import com.databasir.core.meta.data.ForeignKeyMeta;
|
||||
import com.databasir.core.meta.data.IndexMeta;
|
||||
import com.databasir.core.meta.data.TriggerMeta;
|
||||
import com.databasir.core.meta.data.*;
|
||||
import com.databasir.dao.tables.pojos.*;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
@@ -20,7 +17,7 @@ public interface DocumentPojoConverter {
|
||||
@Mapping(target = "schemaName", source = "meta.schemaName")
|
||||
@Mapping(target = "isArchive", constant = "false")
|
||||
DatabaseDocumentPojo toDatabasePojo(Integer projectId,
|
||||
com.databasir.core.meta.data.DatabaseMeta meta,
|
||||
DatabaseMeta meta,
|
||||
Long version);
|
||||
|
||||
TableDocumentPojo toTablePojo(Integer databaseDocumentId,
|
||||
|
@@ -1,5 +1,6 @@
|
||||
package com.databasir.core.domain.document.converter;
|
||||
|
||||
import com.databasir.core.diff.data.DiffType;
|
||||
import com.databasir.core.domain.document.data.DatabaseDocumentSimpleResponse;
|
||||
import com.databasir.core.infrastructure.converter.JsonConverter;
|
||||
import com.databasir.dao.tables.pojos.DatabaseDocumentPojo;
|
||||
@@ -19,7 +20,8 @@ public interface DocumentSimpleResponseConverter {
|
||||
@Mapping(target = "createAt", source = "databaseDocument.createAt")
|
||||
@Mapping(target = "documentVersion", source = "databaseDocument.version")
|
||||
DatabaseDocumentSimpleResponse of(DatabaseDocumentPojo databaseDocument,
|
||||
List<DatabaseDocumentSimpleResponse.TableData> tables);
|
||||
List<DatabaseDocumentSimpleResponse.TableData> tables,
|
||||
DiffType diffType);
|
||||
|
||||
DatabaseDocumentSimpleResponse.TableData of(TableDocumentPojo tables,
|
||||
Integer discussionCount,
|
||||
|
@@ -1,5 +1,6 @@
|
||||
package com.databasir.core.domain.document.data;
|
||||
|
||||
import com.databasir.core.diff.data.DiffType;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
@@ -32,4 +33,6 @@ public class DatabaseDocumentResponse {
|
||||
|
||||
private LocalDateTime createAt;
|
||||
|
||||
private DiffType diffType;
|
||||
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
package com.databasir.core.domain.document.data;
|
||||
|
||||
import com.databasir.core.diff.data.DiffType;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
@@ -25,8 +26,10 @@ public class DatabaseDocumentSimpleResponse {
|
||||
|
||||
private LocalDateTime createAt;
|
||||
|
||||
private DiffType diffType;
|
||||
|
||||
@Data
|
||||
public static class TableData {
|
||||
public static class TableData implements DiffAble<TableData> {
|
||||
|
||||
private Integer id;
|
||||
|
||||
@@ -39,5 +42,9 @@ public class DatabaseDocumentSimpleResponse {
|
||||
private Integer discussionCount;
|
||||
|
||||
private String description;
|
||||
|
||||
private DiffType diffType;
|
||||
|
||||
private TableData original;
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,11 @@
|
||||
package com.databasir.core.domain.document.data;
|
||||
|
||||
import com.databasir.core.diff.data.DiffType;
|
||||
|
||||
public interface DiffAble<T> {
|
||||
|
||||
void setDiffType(DiffType diffType);
|
||||
|
||||
void setOriginal(T t);
|
||||
}
|
||||
|
@@ -0,0 +1,16 @@
|
||||
package com.databasir.core.domain.document.data;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
@Data
|
||||
public class TableDocumentRequest {
|
||||
|
||||
private Collection<Integer> tableIds = Collections.emptyList();
|
||||
|
||||
private Long originalVersion;
|
||||
|
||||
private Long currentVersion;
|
||||
}
|
@@ -1,5 +1,6 @@
|
||||
package com.databasir.core.domain.document.data;
|
||||
|
||||
import com.databasir.core.diff.data.DiffType;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
@@ -13,7 +14,7 @@ import java.util.List;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public class TableDocumentResponse {
|
||||
public class TableDocumentResponse implements DiffAble<TableDocumentResponse> {
|
||||
|
||||
private Integer id;
|
||||
|
||||
@@ -41,11 +42,15 @@ public class TableDocumentResponse {
|
||||
|
||||
private LocalDateTime createAt;
|
||||
|
||||
private DiffType diffType;
|
||||
|
||||
private TableDocumentResponse original;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public static class ColumnDocumentResponse {
|
||||
public static class ColumnDocumentResponse implements DiffAble<ColumnDocumentResponse> {
|
||||
private Integer id;
|
||||
|
||||
private String name;
|
||||
@@ -71,13 +76,17 @@ public class TableDocumentResponse {
|
||||
private Integer discussionCount;
|
||||
|
||||
private LocalDateTime createAt;
|
||||
|
||||
private DiffType diffType;
|
||||
|
||||
private ColumnDocumentResponse original;
|
||||
}
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public static class IndexDocumentResponse {
|
||||
public static class IndexDocumentResponse implements DiffAble<IndexDocumentResponse> {
|
||||
|
||||
private Integer id;
|
||||
|
||||
@@ -89,13 +98,17 @@ public class TableDocumentResponse {
|
||||
private List<String> columnNames = new ArrayList<>();
|
||||
|
||||
private LocalDateTime createAt;
|
||||
|
||||
private DiffType diffType;
|
||||
|
||||
private IndexDocumentResponse original;
|
||||
}
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public static class ForeignKeyDocumentResponse {
|
||||
public static class ForeignKeyDocumentResponse implements DiffAble<ForeignKeyDocumentResponse> {
|
||||
|
||||
private Integer id;
|
||||
|
||||
@@ -105,6 +118,8 @@ public class TableDocumentResponse {
|
||||
|
||||
private String fkColumnName;
|
||||
|
||||
private Integer keySeq;
|
||||
|
||||
private String pkName;
|
||||
|
||||
private String pkTableName;
|
||||
@@ -116,13 +131,17 @@ public class TableDocumentResponse {
|
||||
private String deleteRule;
|
||||
|
||||
private LocalDateTime createAt;
|
||||
|
||||
private DiffType diffType;
|
||||
|
||||
private ForeignKeyDocumentResponse original;
|
||||
}
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public static class TriggerDocumentResponse {
|
||||
public static class TriggerDocumentResponse implements DiffAble<TriggerDocumentResponse> {
|
||||
|
||||
private Integer id;
|
||||
|
||||
@@ -137,5 +156,9 @@ public class TableDocumentResponse {
|
||||
private String triggerCreateAt;
|
||||
|
||||
private LocalDateTime createAt;
|
||||
|
||||
private DiffType diffType;
|
||||
|
||||
private TriggerDocumentResponse original;
|
||||
}
|
||||
}
|
@@ -7,8 +7,12 @@ import com.databasir.core.diff.Diffs;
|
||||
import com.databasir.core.diff.data.DiffType;
|
||||
import com.databasir.core.diff.data.RootDiff;
|
||||
import com.databasir.core.domain.DomainErrors;
|
||||
import com.databasir.core.domain.document.comparator.DiffResult;
|
||||
import com.databasir.core.domain.document.comparator.DocumentDiffs;
|
||||
import com.databasir.core.domain.document.comparator.TableDiffResult;
|
||||
import com.databasir.core.domain.document.converter.*;
|
||||
import com.databasir.core.domain.document.data.*;
|
||||
import com.databasir.core.domain.document.data.TableDocumentResponse.ForeignKeyDocumentResponse;
|
||||
import com.databasir.core.domain.document.event.DocumentUpdated;
|
||||
import com.databasir.core.domain.document.generator.DocumentFileGenerator;
|
||||
import com.databasir.core.domain.document.generator.DocumentFileType;
|
||||
@@ -16,6 +20,7 @@ import com.databasir.core.infrastructure.connection.DatabaseConnectionService;
|
||||
import com.databasir.core.infrastructure.converter.JsonConverter;
|
||||
import com.databasir.core.infrastructure.event.EventPublisher;
|
||||
import com.databasir.core.meta.data.DatabaseMeta;
|
||||
import com.databasir.core.meta.data.TableMeta;
|
||||
import com.databasir.dao.impl.*;
|
||||
import com.databasir.dao.tables.pojos.*;
|
||||
import com.databasir.dao.value.DocumentDiscussionCountPojo;
|
||||
@@ -32,12 +37,12 @@ import org.springframework.util.CollectionUtils;
|
||||
import java.io.OutputStream;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
@@ -51,8 +56,6 @@ public class DocumentService {
|
||||
|
||||
private final DataSourcePropertyDao dataSourcePropertyDao;
|
||||
|
||||
private final SysKeyDao sysKeyDao;
|
||||
|
||||
private final DatabaseConnectionService databaseConnectionService;
|
||||
|
||||
private final DatabaseDocumentDao databaseDocumentDao;
|
||||
@@ -199,13 +202,16 @@ public class DocumentService {
|
||||
projectId, meta.getDatabaseName(), version);
|
||||
}
|
||||
|
||||
public Optional<DatabaseDocumentSimpleResponse> getSimpleOneByProjectId(Integer projectId, Long version) {
|
||||
public Optional<DatabaseDocumentSimpleResponse> getSimpleOneByProjectId(Integer projectId,
|
||||
Long version,
|
||||
Long originalVersion) {
|
||||
Optional<DatabaseDocumentPojo> documentOption;
|
||||
if (version == null) {
|
||||
documentOption = databaseDocumentDao.selectNotArchivedByProjectId(projectId);
|
||||
} else {
|
||||
documentOption = databaseDocumentDao.selectOptionalByProjectIdAndVersion(projectId, version);
|
||||
}
|
||||
|
||||
return documentOption.map(document -> {
|
||||
Integer id = document.getId();
|
||||
var tables = tableDocumentDao.selectByDatabaseDocumentId(id);
|
||||
@@ -213,7 +219,7 @@ public class DocumentService {
|
||||
documentDiscussionDao.selectTableDiscussionCount(projectId)
|
||||
.stream()
|
||||
.collect(Collectors.toMap(d -> d.getTableName(), d -> d.getCount(), (a, b) -> a));
|
||||
Map<String, String> descriptionMapByTableName =
|
||||
var descriptionMapByTableName =
|
||||
documentDescriptionDao.selectTableDescriptionByProjectId(projectId)
|
||||
.stream()
|
||||
.collect(Collectors.toMap(d -> d.getTableName(), d -> d.getContent(), (a, b) -> a));
|
||||
@@ -222,10 +228,70 @@ public class DocumentService {
|
||||
discussionCountMapByTableName,
|
||||
descriptionMapByTableName
|
||||
);
|
||||
return documentSimpleResponseConverter.of(document, tableMetas);
|
||||
|
||||
// if original version is not null mean version diff enabled
|
||||
if (originalVersion != null) {
|
||||
var originalDocument =
|
||||
databaseDocumentDao.selectOptionalByProjectIdAndVersion(projectId, originalVersion)
|
||||
.orElseThrow(DomainErrors.DOCUMENT_VERSION_IS_INVALID::exception);
|
||||
var originalTables = tableDocumentDao.selectByDatabaseDocumentId(originalDocument.getId());
|
||||
var originalTableMetas = documentSimpleResponseConverter.of(
|
||||
originalTables,
|
||||
discussionCountMapByTableName,
|
||||
descriptionMapByTableName
|
||||
);
|
||||
var originalMap = originalTableMetas.stream()
|
||||
.collect(Collectors.toMap(t -> t.getName(), Function.identity(), (a, b) -> a));
|
||||
var currentMap = tableMetas.stream()
|
||||
.collect(Collectors.toMap(t -> t.getName(), Function.identity(), (a, b) -> a));
|
||||
List<TableDiffResult> diffResults = tableDiffs(projectId, originalVersion, version);
|
||||
|
||||
List<DatabaseDocumentSimpleResponse.TableData> result = new ArrayList<>();
|
||||
for (TableDiffResult diffResult : diffResults) {
|
||||
var cur = currentMap.get(diffResult.getId());
|
||||
var org = originalMap.get(diffResult.getId());
|
||||
if (diffResult.getDiffType() == DiffType.ADDED) {
|
||||
cur.setDiffType(DiffType.ADDED);
|
||||
result.add(cur);
|
||||
} else if (diffResult.getDiffType() == DiffType.MODIFIED) {
|
||||
cur.setDiffType(DiffType.MODIFIED);
|
||||
cur.setOriginal(org);
|
||||
result.add(cur);
|
||||
} else if (diffResult.getDiffType() == DiffType.REMOVED) {
|
||||
org.setDiffType(DiffType.REMOVED);
|
||||
result.add(org);
|
||||
} else {
|
||||
cur.setDiffType(DiffType.NONE);
|
||||
result.add(cur);
|
||||
}
|
||||
}
|
||||
result.sort(Comparator.comparing(DatabaseDocumentSimpleResponse.TableData::getName));
|
||||
DiffType diffType = result.stream()
|
||||
.anyMatch(t -> t.getDiffType() == DiffType.MODIFIED) ? DiffType.MODIFIED : DiffType.NONE;
|
||||
return documentSimpleResponseConverter.of(document, result, diffType);
|
||||
} else {
|
||||
tableMetas.sort(Comparator.comparing(DatabaseDocumentSimpleResponse.TableData::getName));
|
||||
return documentSimpleResponseConverter.of(document, tableMetas, DiffType.NONE);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public List<TableDiffResult> tableDiffs(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 DocumentDiffs.tableDiff(originalMeta, currMeta);
|
||||
}
|
||||
|
||||
public Optional<DatabaseDocumentResponse> getOneByProjectId(Integer projectId, Long version) {
|
||||
|
||||
Optional<DatabaseDocumentPojo> documentOption;
|
||||
@@ -252,11 +318,11 @@ public class DocumentService {
|
||||
var tableDocumentResponseList = tables.stream()
|
||||
.map(table -> {
|
||||
Integer tableId = table.getId();
|
||||
var subColumns = columnsGroupByTableMetaId.getOrDefault(tableId, Collections.emptyList());
|
||||
var subIndexes = indexesGroupByTableMetaId.getOrDefault(tableId, Collections.emptyList());
|
||||
var subTriggers = triggersGroupByTableMetaId.getOrDefault(tableId, Collections.emptyList());
|
||||
var subColumns = columnsGroupByTableMetaId.getOrDefault(tableId, emptyList());
|
||||
var subIndexes = indexesGroupByTableMetaId.getOrDefault(tableId, emptyList());
|
||||
var subTriggers = triggersGroupByTableMetaId.getOrDefault(tableId, emptyList());
|
||||
var subForeignKeys =
|
||||
foreignKeysGroupByTableMetaId.getOrDefault(tableId, Collections.emptyList());
|
||||
foreignKeysGroupByTableMetaId.getOrDefault(tableId, emptyList());
|
||||
return documentResponseConverter.of(
|
||||
table,
|
||||
subColumns,
|
||||
@@ -284,10 +350,10 @@ public class DocumentService {
|
||||
|
||||
public List<TableDocumentResponse> getTableDetails(Integer projectId,
|
||||
Integer databaseDocumentId,
|
||||
List<Integer> tableIds) {
|
||||
Collection<Integer> tableIds) {
|
||||
// maybe deleted
|
||||
if (CollectionUtils.isEmpty(tableIds) || !projectDao.existsById(projectId)) {
|
||||
return Collections.emptyList();
|
||||
return emptyList();
|
||||
}
|
||||
var tables =
|
||||
tableDocumentDao.selectByDatabaseDocumentIdAndIdIn(databaseDocumentId, tableIds);
|
||||
@@ -338,10 +404,10 @@ public class DocumentService {
|
||||
return tables.stream()
|
||||
.map(table -> {
|
||||
Integer tableId = table.getId();
|
||||
var subColumns = columnsGroupByTableMetaId.getOrDefault(tableId, Collections.emptyList());
|
||||
var subIndexes = indexesGroupByTableMetaId.getOrDefault(tableId, Collections.emptyList());
|
||||
var subForeignKeys = foreignKeysGroupByTableMetaId.getOrDefault(tableId, Collections.emptyList());
|
||||
var subTriggers = triggersGroupByTableMetaId.getOrDefault(tableId, Collections.emptyList());
|
||||
var subColumns = columnsGroupByTableMetaId.getOrDefault(tableId, emptyList());
|
||||
var subIndexes = indexesGroupByTableMetaId.getOrDefault(tableId, emptyList());
|
||||
var subForeignKeys = foreignKeysGroupByTableMetaId.getOrDefault(tableId, emptyList());
|
||||
var subTriggers = triggersGroupByTableMetaId.getOrDefault(tableId, emptyList());
|
||||
var discussionCount = discussionCountMapByJoinName.get(table.getName());
|
||||
var description = descriptionMapByJoinName.get(table.getName());
|
||||
var columnResponses = documentResponseConverter.of(
|
||||
@@ -362,6 +428,87 @@ public class DocumentService {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<TableDocumentResponse> getTableDetails(Integer projectId,
|
||||
Integer databaseDocumentId,
|
||||
TableDocumentRequest request) {
|
||||
// maybe deleted
|
||||
if (CollectionUtils.isEmpty(request.getTableIds()) || !projectDao.existsById(projectId)) {
|
||||
return emptyList();
|
||||
}
|
||||
var current = this.getTableDetails(projectId, databaseDocumentId, request.getTableIds());
|
||||
if (request.getOriginalVersion() != null) {
|
||||
DatabaseDocumentPojo doc =
|
||||
databaseDocumentDao.selectOptionalByProjectIdAndVersion(projectId, request.getOriginalVersion())
|
||||
.orElseThrow(DomainErrors.DOCUMENT_VERSION_IS_INVALID::exception);
|
||||
List<String> tableNames = current.stream().map(t -> t.getName()).distinct().collect(Collectors.toList());
|
||||
List<Integer> originalTableIds =
|
||||
tableDocumentDao.selectTableIdsByDatabaseDocumentIdAndTableNameIn(doc.getId(), tableNames);
|
||||
var original = this.getTableDetails(projectId, doc.getId(), originalTableIds);
|
||||
Map<String, TableDocumentResponse> currentMapByName = current.stream()
|
||||
.collect(Collectors.toMap(TableDocumentResponse::getName, Function.identity(), (a, b) -> a));
|
||||
Map<String, TableDocumentResponse> originalMapByName = original.stream()
|
||||
.collect(Collectors.toMap(TableDocumentResponse::getName, Function.identity(), (a, b) -> a));
|
||||
List<TableMeta> currentMeta = databaseMetaConverter.of(current);
|
||||
List<TableMeta> originalMeta = databaseMetaConverter.of(original);
|
||||
List<TableDiffResult> diffs = DocumentDiffs.tableDiff(originalMeta, currentMeta);
|
||||
return diffs.stream()
|
||||
.map(diff -> {
|
||||
if (diff.getDiffType() == DiffType.ADDED) {
|
||||
TableDocumentResponse c = currentMapByName.get(diff.getId());
|
||||
c.setDiffType(DiffType.ADDED);
|
||||
var cols =
|
||||
diff(diff.getColumnDiffResults(), emptyList(), c.getColumns(), i -> i.getName());
|
||||
c.setColumns(cols);
|
||||
var indexes =
|
||||
diff(diff.getIndexDiffResults(), emptyList(), c.getIndexes(), i -> i.getName());
|
||||
c.setIndexes(indexes);
|
||||
var foreignKeys = foreignKeyDiff(diff.getForeignKeyDiffResults(),
|
||||
emptyList(), c.getForeignKeys());
|
||||
c.setForeignKeys(foreignKeys);
|
||||
var triggers =
|
||||
diff(diff.getTriggerDiffResults(), emptyList(), c.getTriggers(), t -> t.getName());
|
||||
c.setTriggers(triggers);
|
||||
return c;
|
||||
}
|
||||
if (diff.getDiffType() == DiffType.REMOVED) {
|
||||
TableDocumentResponse t = originalMapByName.get(diff.getId());
|
||||
t.setDiffType(DiffType.REMOVED);
|
||||
return t;
|
||||
}
|
||||
if (diff.getDiffType() == DiffType.MODIFIED) {
|
||||
TableDocumentResponse c = currentMapByName.get(diff.getId());
|
||||
TableDocumentResponse o = originalMapByName.get(diff.getId());
|
||||
c.setDiffType(DiffType.MODIFIED);
|
||||
c.setOriginal(o);
|
||||
var cols =
|
||||
diff(diff.getColumnDiffResults(), o.getColumns(), c.getColumns(),
|
||||
col -> col.getName());
|
||||
c.setColumns(cols);
|
||||
var indexes =
|
||||
diff(diff.getIndexDiffResults(), o.getIndexes(), c.getIndexes(), i -> i.getName());
|
||||
c.setIndexes(indexes);
|
||||
var foreignKeys = foreignKeyDiff(diff.getForeignKeyDiffResults(),
|
||||
o.getForeignKeys(), c.getForeignKeys());
|
||||
c.setForeignKeys(foreignKeys);
|
||||
var triggers =
|
||||
diff(diff.getTriggerDiffResults(), o.getTriggers(), c.getTriggers(),
|
||||
t -> t.getName());
|
||||
c.setTriggers(triggers);
|
||||
return c;
|
||||
}
|
||||
TableDocumentResponse t = currentMapByName.get(diff.getId());
|
||||
t.setDiffType(DiffType.NONE);
|
||||
return t;
|
||||
})
|
||||
.sorted(Comparator.comparing(TableDocumentResponse::getName))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
} else {
|
||||
current.sort(Comparator.comparing(TableDocumentResponse::getName));
|
||||
return current;
|
||||
}
|
||||
}
|
||||
|
||||
public void export(Integer projectId,
|
||||
Long version,
|
||||
DocumentFileType type,
|
||||
@@ -379,22 +526,6 @@ public class DocumentService {
|
||||
});
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public List<TableResponse> getTableAndColumns(Integer projectId, Long version) {
|
||||
Optional<DatabaseDocumentPojo> documentOption;
|
||||
if (version == null) {
|
||||
@@ -403,7 +534,7 @@ public class DocumentService {
|
||||
documentOption = databaseDocumentDao.selectOptionalByProjectIdAndVersion(projectId, version);
|
||||
}
|
||||
if (documentOption.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
return emptyList();
|
||||
} else {
|
||||
DatabaseDocumentPojo databaseDoc = documentOption.get();
|
||||
var tables = tableDocumentDao.selectByDatabaseDocumentId(databaseDoc.getId());
|
||||
@@ -413,4 +544,46 @@ public class DocumentService {
|
||||
return tableResponseConverter.from(tables, columnMapByTableId);
|
||||
}
|
||||
}
|
||||
|
||||
private <T extends DiffAble> List<T> diff(Collection<DiffResult> diffs,
|
||||
Collection<T> original,
|
||||
Collection<T> current,
|
||||
Function<T, String> idMapping) {
|
||||
var currentMapByName = current.stream()
|
||||
.collect(Collectors.toMap(idMapping, Function.identity(), (a, b) -> a));
|
||||
var originalMapByName = original.stream()
|
||||
.collect(Collectors.toMap(idMapping, Function.identity(), (a, b) -> a));
|
||||
return diffs.stream().map(diff -> {
|
||||
if (diff.getDiffType() == DiffType.ADDED) {
|
||||
var t = currentMapByName.get(diff.getId());
|
||||
t.setDiffType(DiffType.ADDED);
|
||||
return t;
|
||||
}
|
||||
if (diff.getDiffType() == DiffType.REMOVED) {
|
||||
var t = originalMapByName.get(diff.getId());
|
||||
t.setDiffType(DiffType.REMOVED);
|
||||
return t;
|
||||
}
|
||||
if (diff.getDiffType() == DiffType.MODIFIED) {
|
||||
var c = currentMapByName.get(diff.getId());
|
||||
var o = originalMapByName.get(diff.getId());
|
||||
c.setDiffType(DiffType.MODIFIED);
|
||||
c.setOriginal(o);
|
||||
return c;
|
||||
}
|
||||
var t = currentMapByName.get(diff.getId());
|
||||
t.setDiffType(DiffType.NONE);
|
||||
return t;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<ForeignKeyDocumentResponse> foreignKeyDiff(Collection<DiffResult> diffs,
|
||||
Collection<ForeignKeyDocumentResponse> original,
|
||||
Collection<ForeignKeyDocumentResponse> current) {
|
||||
Function<ForeignKeyDocumentResponse, String> idMapping = fk -> {
|
||||
return fk.getFkTableName() + "." + fk.getFkColumnName() + "." + fk.getKeySeq();
|
||||
};
|
||||
return diff(diffs, original, current, idMapping);
|
||||
}
|
||||
}
|
||||
|
@@ -61,7 +61,7 @@ public class SystemStartedEventSubscriber {
|
||||
DocumentTemplatePropertyPojo pojo = new DocumentTemplatePropertyPojo();
|
||||
pojo.setType(type);
|
||||
pojo.setKey(key);
|
||||
pojo.setDefaultValue(fieldChineseMap.get(key));
|
||||
pojo.setDefaultValue(fieldChineseMap.getOrDefault(key, def));
|
||||
return pojo;
|
||||
};
|
||||
// table field name;
|
||||
|
Reference in New Issue
Block a user