mirror of
https://github.com/vran-dev/databasir.git
synced 2025-08-09 02:20:51 +08:00
Redesign document history model (#39)
* feat: jooq model generate * refactor: redesign document history model * fix: checkstyle * feat: add batch query table api * fix: checkstyle * feat: update frontend resources
This commit is contained in:
@@ -1,20 +0,0 @@
|
||||
package com.databasir.core.domain.document.converter;
|
||||
|
||||
import com.databasir.core.domain.document.data.DatabaseDocumentResponse;
|
||||
import com.databasir.core.infrastructure.converter.JsonConverter;
|
||||
import com.databasir.dao.tables.pojos.DatabaseDocumentHistoryPojo;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.ReportingPolicy;
|
||||
|
||||
@Mapper(componentModel = "spring", uses = JsonConverter.class, unmappedTargetPolicy = ReportingPolicy.IGNORE)
|
||||
public interface DocumentHistoryPojoConverter {
|
||||
|
||||
@Mapping(target = "databaseDocumentObject", source = "databaseMetaObject")
|
||||
@Mapping(target = "id", ignore = true)
|
||||
@Mapping(target = "createAt", ignore = true)
|
||||
DatabaseDocumentHistoryPojo of(DatabaseDocumentResponse databaseMetaObject,
|
||||
Integer projectId,
|
||||
Integer databaseDocumentId,
|
||||
Long version);
|
||||
}
|
@@ -16,16 +16,11 @@ import java.util.stream.Collectors;
|
||||
public interface DocumentPojoConverter extends BaseConverter {
|
||||
|
||||
@Mapping(target = "databaseName", source = "meta.databaseName")
|
||||
@Mapping(target = "isArchive", constant = "false")
|
||||
DatabaseDocumentPojo toDatabasePojo(Integer projectId,
|
||||
com.databasir.core.meta.data.DatabaseMeta meta,
|
||||
Long version);
|
||||
|
||||
@Mapping(target = "databaseName", source = "meta.databaseName")
|
||||
DatabaseDocumentPojo toDatabasePojo(Integer projectId,
|
||||
com.databasir.core.meta.data.DatabaseMeta meta,
|
||||
Integer id,
|
||||
Long version);
|
||||
|
||||
@Mapping(target = "comment", qualifiedBy = NullToEmpty.class)
|
||||
TableDocumentPojo toTablePojo(Integer databaseDocumentId,
|
||||
com.databasir.core.meta.data.TableMeta meta);
|
||||
|
@@ -0,0 +1,21 @@
|
||||
package com.databasir.core.domain.document.converter;
|
||||
|
||||
import com.databasir.core.domain.document.data.DatabaseDocumentSimpleResponse;
|
||||
import com.databasir.core.infrastructure.converter.JsonConverter;
|
||||
import com.databasir.dao.tables.pojos.DatabaseDocumentPojo;
|
||||
import com.databasir.dao.tables.pojos.TableDocumentPojo;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.ReportingPolicy;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper(componentModel = "spring", uses = JsonConverter.class, unmappedTargetPolicy = ReportingPolicy.WARN)
|
||||
public interface DocumentSimpleResponseConverter {
|
||||
|
||||
@Mapping(target = "id", source = "databaseDocument.id")
|
||||
@Mapping(target = "createAt", source = "databaseDocument.createAt")
|
||||
@Mapping(target = "documentVersion", source = "databaseDocument.version")
|
||||
DatabaseDocumentSimpleResponse of(DatabaseDocumentPojo databaseDocument,
|
||||
List<TableDocumentPojo> tables);
|
||||
}
|
@@ -0,0 +1,37 @@
|
||||
package com.databasir.core.domain.document.data;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class DatabaseDocumentSimpleResponse {
|
||||
|
||||
private Integer id;
|
||||
|
||||
private String databaseName;
|
||||
|
||||
private String productName;
|
||||
|
||||
private String productVersion;
|
||||
|
||||
private Integer documentVersion;
|
||||
|
||||
private List<TableData> tables = new ArrayList<>();
|
||||
|
||||
private LocalDateTime createAt;
|
||||
|
||||
@Data
|
||||
public static class TableData {
|
||||
|
||||
private Integer id;
|
||||
|
||||
private String name;
|
||||
|
||||
private String type;
|
||||
|
||||
private String comment;
|
||||
}
|
||||
}
|
@@ -13,6 +13,8 @@ import java.time.LocalDateTime;
|
||||
@Builder
|
||||
public class DatabaseDocumentVersionResponse {
|
||||
|
||||
private Integer databaseDocumentId;
|
||||
|
||||
private Long version;
|
||||
|
||||
private LocalDateTime createAt;
|
||||
|
@@ -3,10 +3,11 @@ package com.databasir.core.domain.document.service;
|
||||
import com.databasir.core.Databasir;
|
||||
import com.databasir.core.DatabasirConfig;
|
||||
import com.databasir.core.domain.DomainErrors;
|
||||
import com.databasir.core.domain.document.converter.DocumentHistoryPojoConverter;
|
||||
import com.databasir.core.domain.document.converter.DocumentPojoConverter;
|
||||
import com.databasir.core.domain.document.converter.DocumentResponseConverter;
|
||||
import com.databasir.core.domain.document.converter.DocumentSimpleResponseConverter;
|
||||
import com.databasir.core.domain.document.data.DatabaseDocumentResponse;
|
||||
import com.databasir.core.domain.document.data.DatabaseDocumentSimpleResponse;
|
||||
import com.databasir.core.domain.document.data.DatabaseDocumentVersionResponse;
|
||||
import com.databasir.core.infrastructure.connection.DatabaseConnectionService;
|
||||
import com.databasir.core.infrastructure.converter.JsonConverter;
|
||||
@@ -20,6 +21,7 @@ import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.util.*;
|
||||
@@ -53,30 +55,28 @@ public class DocumentService {
|
||||
|
||||
private final TableTriggerDocumentDao tableTriggerDocumentDao;
|
||||
|
||||
private final DatabaseDocumentHistoryDao databaseDocumentHistoryDao;
|
||||
|
||||
private final DocumentPojoConverter documentPojoConverter;
|
||||
|
||||
private final DocumentResponseConverter documentResponseConverter;
|
||||
|
||||
private final DocumentHistoryPojoConverter documentHistoryPojoConverter;
|
||||
private final DocumentSimpleResponseConverter documentSimpleResponseConverter;
|
||||
|
||||
private final JsonConverter jsonConverter;
|
||||
|
||||
@Transactional
|
||||
public void syncByProjectId(Integer projectId) {
|
||||
ProjectPojo project = projectDao.selectOptionalById(projectId)
|
||||
projectDao.selectOptionalById(projectId)
|
||||
.orElseThrow(DomainErrors.PROJECT_NOT_FOUND::exception);
|
||||
DatabaseMeta meta = retrieveDatabaseMeta(projectId);
|
||||
Optional<DatabaseDocumentPojo> historyDocumentOpt = databaseDocumentDao.selectOptionalByProjectId(projectId);
|
||||
if (historyDocumentOpt.isPresent()) {
|
||||
DatabaseDocumentPojo historyDocument = historyDocumentOpt.get();
|
||||
Integer previousDocumentId = historyDocument.getId();
|
||||
saveAsHistory(historyDocument);
|
||||
deleteDeprecatedDocument(previousDocumentId);
|
||||
saveNewDocument(meta, historyDocument.getVersion() + 1, historyDocument.getProjectId(), previousDocumentId);
|
||||
Optional<DatabaseDocumentPojo> latestDocumentOpt = databaseDocumentDao.selectNotArchivedByProjectId(projectId);
|
||||
if (latestDocumentOpt.isPresent()) {
|
||||
DatabaseDocumentPojo latestDocument = latestDocumentOpt.get();
|
||||
Integer previousDocumentId = latestDocument.getId();
|
||||
// archive old version
|
||||
databaseDocumentDao.updateIsArchiveById(previousDocumentId, true);
|
||||
saveNewDocument(meta, latestDocument.getVersion() + 1, latestDocument.getProjectId());
|
||||
} else {
|
||||
saveNewDocument(meta, 1L, projectId, null);
|
||||
saveNewDocument(meta, 1L, projectId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,42 +93,12 @@ public class DocumentService {
|
||||
.orElseThrow(DomainErrors.DATABASE_META_NOT_FOUND::exception);
|
||||
}
|
||||
|
||||
private void saveAsHistory(DatabaseDocumentPojo databaseDocument) {
|
||||
// save history
|
||||
Integer projectId = databaseDocument.getProjectId();
|
||||
Integer databaseMetaId = databaseDocument.getId();
|
||||
DatabaseDocumentResponse databaseDocumentResponse = getOneByProjectId(projectId, null).orElse(null);
|
||||
Long currVersion = databaseDocument.getVersion();
|
||||
DatabaseDocumentHistoryPojo documentHistoryPojo =
|
||||
documentHistoryPojoConverter.of(databaseDocumentResponse, projectId, databaseMetaId, currVersion);
|
||||
databaseDocumentHistoryDao.insertAndReturnId(documentHistoryPojo);
|
||||
log.info("save old meta info to history success");
|
||||
}
|
||||
|
||||
private void deleteDeprecatedDocument(Integer databaseDocumentId) {
|
||||
// delete old meta info
|
||||
tableDocumentDao.deleteByDatabaseDocumentId(databaseDocumentId);
|
||||
tableColumnDocumentDao.deleteByDatabaseDocumentId(databaseDocumentId);
|
||||
tableIndexDocumentDao.deleteByDatabaseMetaId(databaseDocumentId);
|
||||
tableTriggerDocumentDao.deleteByDatabaseDocumentId(databaseDocumentId);
|
||||
log.info("delete old meta info success");
|
||||
}
|
||||
|
||||
private void saveNewDocument(DatabaseMeta meta,
|
||||
Long version,
|
||||
Integer projectId,
|
||||
Integer databaseDocumentId) {
|
||||
Integer projectId) {
|
||||
|
||||
Integer currentDatabaseDocumentId = databaseDocumentId;
|
||||
if (databaseDocumentId == null) {
|
||||
var pojo = documentPojoConverter.toDatabasePojo(projectId, meta, 1L);
|
||||
currentDatabaseDocumentId = databaseDocumentDao.insertAndReturnId(pojo);
|
||||
} else {
|
||||
var pojo = documentPojoConverter.toDatabasePojo(projectId, meta, databaseDocumentId, version);
|
||||
databaseDocumentDao.update(pojo);
|
||||
}
|
||||
|
||||
final Integer docId = currentDatabaseDocumentId;
|
||||
var pojo = documentPojoConverter.toDatabasePojo(projectId, meta, version);
|
||||
final Integer docId = databaseDocumentDao.insertAndReturnId(pojo);
|
||||
meta.getTables().forEach(table -> {
|
||||
TableDocumentPojo tableMeta =
|
||||
documentPojoConverter.toTablePojo(docId, table);
|
||||
@@ -143,55 +113,106 @@ public class DocumentService {
|
||||
documentPojoConverter.toTriggerPojo(docId, tableMetaId, table.getTriggers());
|
||||
tableTriggerDocumentDao.batchInsert(tableTriggerMetas);
|
||||
});
|
||||
log.info("save new meta info success");
|
||||
log.info("save new version document success: projectId = {}, name = {}, version = {}",
|
||||
projectId, meta.getDatabaseName(), version);
|
||||
}
|
||||
|
||||
public Optional<DatabaseDocumentResponse> getOneByProjectId(Integer projectId, Long version) {
|
||||
public Optional<DatabaseDocumentSimpleResponse> getSimpleOneByProjectId(Integer projectId, Long version) {
|
||||
if (version == null) {
|
||||
return databaseDocumentDao.selectOptionalByProjectId(projectId)
|
||||
return databaseDocumentDao.selectNotArchivedByProjectId(projectId)
|
||||
.map(document -> {
|
||||
Integer id = document.getId();
|
||||
var tables = tableDocumentDao.selectByDatabaseDocumentId(id);
|
||||
var columns = tableColumnDocumentDao.selectByDatabaseDocumentId(id);
|
||||
var indexes = tableIndexDocumentDao.selectByDatabaseMetaId(id);
|
||||
var triggers = tableTriggerDocumentDao.selectByDatabaseDocumentId(id);
|
||||
Map<Integer, List<TableColumnDocumentPojo>> columnsGroupByTableMetaId = columns.stream()
|
||||
.collect(Collectors.groupingBy(TableColumnDocumentPojo::getTableDocumentId));
|
||||
Map<Integer, List<TableIndexDocumentPojo>> indexesGroupByTableMetaId = indexes.stream()
|
||||
.collect(Collectors.groupingBy(TableIndexDocumentPojo::getTableDocumentId));
|
||||
Map<Integer, List<TableTriggerDocumentPojo>> triggersGroupByTableMetaId = triggers.stream()
|
||||
.collect(Collectors.groupingBy(TableTriggerDocumentPojo::getTableDocumentId));
|
||||
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());
|
||||
return documentResponseConverter.of(table, subColumns, subIndexes, subTriggers);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
return documentResponseConverter.of(document, tableDocumentResponseList);
|
||||
return documentSimpleResponseConverter.of(document, tables);
|
||||
});
|
||||
} else {
|
||||
return databaseDocumentHistoryDao.selectOptionalByProjectIdAndVersion(projectId, version)
|
||||
.map(obj -> jsonConverter.of(obj.getDatabaseDocumentObject()));
|
||||
return databaseDocumentDao.selectOptionalByProjectIdAndVersion(projectId, version)
|
||||
.map(document -> {
|
||||
Integer id = document.getId();
|
||||
var tables = tableDocumentDao.selectByDatabaseDocumentId(id);
|
||||
return documentSimpleResponseConverter.of(document, tables);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public Page<DatabaseDocumentVersionResponse> getVersionsBySchemaSourceId(Integer projectId, Pageable page) {
|
||||
return databaseDocumentDao.selectOptionalByProjectId(projectId)
|
||||
.map(schemaMeta ->
|
||||
databaseDocumentHistoryDao.selectVersionPageByDatabaseDocumentId(page, schemaMeta.getId())
|
||||
public Optional<DatabaseDocumentResponse> getOneByProjectId(Integer projectId, Long version) {
|
||||
|
||||
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);
|
||||
var columns = tableColumnDocumentDao.selectByDatabaseDocumentId(id);
|
||||
var indexes = tableIndexDocumentDao.selectByDatabaseMetaId(id);
|
||||
var triggers = tableTriggerDocumentDao.selectByDatabaseDocumentId(id);
|
||||
Map<Integer, List<TableColumnDocumentPojo>> columnsGroupByTableMetaId = columns.stream()
|
||||
.collect(Collectors.groupingBy(TableColumnDocumentPojo::getTableDocumentId));
|
||||
Map<Integer, List<TableIndexDocumentPojo>> indexesGroupByTableMetaId = indexes.stream()
|
||||
.collect(Collectors.groupingBy(TableIndexDocumentPojo::getTableDocumentId));
|
||||
Map<Integer, List<TableTriggerDocumentPojo>> triggersGroupByTableMetaId = triggers.stream()
|
||||
.collect(Collectors.groupingBy(TableTriggerDocumentPojo::getTableDocumentId));
|
||||
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());
|
||||
return documentResponseConverter.of(table, subColumns, subIndexes, subTriggers);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
return documentResponseConverter.of(document, tableDocumentResponseList);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public Page<DatabaseDocumentVersionResponse> getVersionsByProjectId(Integer projectId, Pageable page) {
|
||||
return databaseDocumentDao.selectNotArchivedByProjectId(projectId)
|
||||
.map(databaseDocument ->
|
||||
databaseDocumentDao.selectVersionPageByProjectId(page, projectId)
|
||||
.map(history -> DatabaseDocumentVersionResponse.builder()
|
||||
.databaseDocumentId(history.getId())
|
||||
.version(history.getVersion())
|
||||
.createAt(history.getCreateAt())
|
||||
.build()))
|
||||
.orElseGet(Page::empty);
|
||||
}
|
||||
|
||||
public List<DatabaseDocumentResponse.TableDocumentResponse> getTableDetails(Integer projectId,
|
||||
Integer databaseDocumentId,
|
||||
List<Integer> tableIds) {
|
||||
// maybe deleted
|
||||
if (CollectionUtils.isEmpty(tableIds) || !projectDao.existsById(projectId)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
var tables =
|
||||
tableDocumentDao.selectByDatabaseDocumentIdAndIdIn(databaseDocumentId, tableIds);
|
||||
var columns =
|
||||
tableColumnDocumentDao.selectByDatabaseDocumentIdAndTableIdIn(databaseDocumentId, tableIds);
|
||||
var indexes =
|
||||
tableIndexDocumentDao.selectByDatabaseDocumentIdAndIdIn(databaseDocumentId, tableIds);
|
||||
var triggers =
|
||||
tableTriggerDocumentDao.selectByDatabaseDocumentIdAndIdIn(databaseDocumentId, tableIds);
|
||||
Map<Integer, List<TableColumnDocumentPojo>> columnsGroupByTableMetaId = columns.stream()
|
||||
.collect(Collectors.groupingBy(TableColumnDocumentPojo::getTableDocumentId));
|
||||
Map<Integer, List<TableIndexDocumentPojo>> indexesGroupByTableMetaId = indexes.stream()
|
||||
.collect(Collectors.groupingBy(TableIndexDocumentPojo::getTableDocumentId));
|
||||
Map<Integer, List<TableTriggerDocumentPojo>> triggersGroupByTableMetaId = triggers.stream()
|
||||
.collect(Collectors.groupingBy(TableTriggerDocumentPojo::getTableDocumentId));
|
||||
return 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());
|
||||
return documentResponseConverter.of(table, subColumns, subIndexes, subTriggers);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public Optional<String> toMarkdown(Integer projectId, Long version) {
|
||||
return getOneByProjectId(projectId, version)
|
||||
.map(doc -> {
|
||||
|
@@ -4,11 +4,19 @@ import com.databasir.core.domain.group.data.GroupCreateRequest;
|
||||
import com.databasir.core.domain.group.data.GroupUpdateRequest;
|
||||
import com.databasir.dao.tables.pojos.GroupPojo;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
|
||||
@Mapper(componentModel = "spring")
|
||||
public interface GroupPojoConverter {
|
||||
|
||||
@Mapping(target = "id", ignore = true)
|
||||
@Mapping(target = "deleted", ignore = true)
|
||||
@Mapping(target = "createAt", ignore = true)
|
||||
@Mapping(target = "updateAt", ignore = true)
|
||||
GroupPojo of(GroupCreateRequest groupCreateRequest);
|
||||
|
||||
@Mapping(target = "deleted", ignore = true)
|
||||
@Mapping(target = "createAt", ignore = true)
|
||||
@Mapping(target = "updateAt", ignore = true)
|
||||
GroupPojo of(GroupUpdateRequest groupUpdateRequest);
|
||||
}
|
||||
|
Reference in New Issue
Block a user