feat: add description field to document
This commit is contained in:
parent
fe6d61e1b6
commit
95d1f077cf
|
@ -0,0 +1,41 @@
|
||||||
|
package com.databasir.api;
|
||||||
|
|
||||||
|
import com.databasir.api.config.security.DatabasirUserDetails;
|
||||||
|
import com.databasir.common.JsonData;
|
||||||
|
import com.databasir.core.domain.description.data.DocumentDescriptionSaveRequest;
|
||||||
|
import com.databasir.core.domain.description.service.DocumentDescriptionService;
|
||||||
|
import com.databasir.core.domain.log.annotation.Operation;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@Validated
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class DocumentDescriptionController {
|
||||||
|
|
||||||
|
private final DocumentDescriptionService documentDescriptionService;
|
||||||
|
|
||||||
|
@PostMapping(Routes.DocumentDescription.SAVE)
|
||||||
|
@PreAuthorize("hasAnyAuthority('SYS_OWNER', 'GROUP_OWNER?groupId='+#groupId, 'GROUP_MEMBER?groupId='+#groupId)")
|
||||||
|
@Operation(module = Operation.Modules.PROJECT,
|
||||||
|
name = "更新描述",
|
||||||
|
involvedProjectId = "#projectId")
|
||||||
|
public JsonData<Void> save(@PathVariable Integer groupId,
|
||||||
|
@PathVariable Integer projectId,
|
||||||
|
@RequestBody @Valid DocumentDescriptionSaveRequest request) {
|
||||||
|
DatabasirUserDetails principal = (DatabasirUserDetails) SecurityContextHolder.getContext()
|
||||||
|
.getAuthentication()
|
||||||
|
.getPrincipal();
|
||||||
|
Integer userId = principal.getUserPojo().getId();
|
||||||
|
documentDescriptionService.save(groupId, projectId, userId, request);
|
||||||
|
return JsonData.ok();
|
||||||
|
}
|
||||||
|
}
|
|
@ -96,6 +96,13 @@ public interface Routes {
|
||||||
String DELETE = DISCUSSION_BASE + "/{discussionId}";
|
String DELETE = DISCUSSION_BASE + "/{discussionId}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface DocumentDescription {
|
||||||
|
|
||||||
|
String DISCUSSION_BASE = BASE + "/groups/{groupId}/projects/{projectId}/descriptions";
|
||||||
|
|
||||||
|
String SAVE = DISCUSSION_BASE;
|
||||||
|
}
|
||||||
|
|
||||||
interface Setting {
|
interface Setting {
|
||||||
|
|
||||||
String GET_SYS_EMAIL = BASE + "/settings/sys_email";
|
String GET_SYS_EMAIL = BASE + "/settings/sys_email";
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.databasir.core.domain.description.converter;
|
||||||
|
|
||||||
|
import com.databasir.core.domain.description.data.DocumentDescriptionSaveRequest;
|
||||||
|
import com.databasir.dao.tables.pojos.DocumentDescriptionPojo;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.Mapping;
|
||||||
|
|
||||||
|
@Mapper(componentModel = "spring")
|
||||||
|
public interface DocumentDescriptionPojoConverter {
|
||||||
|
|
||||||
|
@Mapping(target = "id", ignore = true)
|
||||||
|
@Mapping(target = "createAt", ignore = true)
|
||||||
|
@Mapping(target = "updateAt", ignore = true)
|
||||||
|
DocumentDescriptionPojo of(Integer projectId,
|
||||||
|
Integer updateBy,
|
||||||
|
DocumentDescriptionSaveRequest request);
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.databasir.core.domain.description.data;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class DocumentDescriptionSaveRequest {
|
||||||
|
|
||||||
|
private String tableName;
|
||||||
|
|
||||||
|
private String columnName;
|
||||||
|
|
||||||
|
private String content;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.databasir.core.domain.description.service;
|
||||||
|
|
||||||
|
import com.databasir.core.domain.description.converter.DocumentDescriptionPojoConverter;
|
||||||
|
import com.databasir.core.domain.description.data.DocumentDescriptionSaveRequest;
|
||||||
|
import com.databasir.dao.impl.DocumentDescriptionDao;
|
||||||
|
import com.databasir.dao.tables.pojos.DocumentDescriptionPojo;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class DocumentDescriptionService {
|
||||||
|
|
||||||
|
private final DocumentDescriptionDao documentDescriptionDao;
|
||||||
|
|
||||||
|
private final DocumentDescriptionPojoConverter documentDescriptionPojoConverter;
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void save(Integer groupId,
|
||||||
|
Integer projectId,
|
||||||
|
Integer userId,
|
||||||
|
DocumentDescriptionSaveRequest request) {
|
||||||
|
|
||||||
|
DocumentDescriptionPojo pojo = documentDescriptionPojoConverter.of(projectId, userId, request);
|
||||||
|
if (!documentDescriptionDao.exists(projectId, request.getTableName(), request.getColumnName())) {
|
||||||
|
documentDescriptionDao.insertAndReturnId(pojo);
|
||||||
|
} else {
|
||||||
|
documentDescriptionDao.update(pojo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,21 +28,25 @@ public interface DocumentResponseConverter {
|
||||||
@SuppressWarnings("checkstyle:all")
|
@SuppressWarnings("checkstyle:all")
|
||||||
DatabaseDocumentResponse.TableDocumentResponse of(TableDocumentPojo tableDocument,
|
DatabaseDocumentResponse.TableDocumentResponse of(TableDocumentPojo tableDocument,
|
||||||
Integer discussionCount,
|
Integer discussionCount,
|
||||||
|
String description,
|
||||||
List<DatabaseDocumentResponse.TableDocumentResponse.ColumnDocumentResponse> columns,
|
List<DatabaseDocumentResponse.TableDocumentResponse.ColumnDocumentResponse> columns,
|
||||||
List<TableIndexDocumentPojo> indexes,
|
List<TableIndexDocumentPojo> indexes,
|
||||||
List<TableTriggerDocumentPojo> triggers);
|
List<TableTriggerDocumentPojo> triggers);
|
||||||
|
|
||||||
DatabaseDocumentResponse.TableDocumentResponse.ColumnDocumentResponse of(TableColumnDocumentPojo pojo,
|
DatabaseDocumentResponse.TableDocumentResponse.ColumnDocumentResponse of(TableColumnDocumentPojo pojo,
|
||||||
Integer discussionCount);
|
Integer discussionCount,
|
||||||
|
String description);
|
||||||
|
|
||||||
default List<DatabaseDocumentResponse.TableDocumentResponse.ColumnDocumentResponse> of(
|
default List<DatabaseDocumentResponse.TableDocumentResponse.ColumnDocumentResponse> of(
|
||||||
List<TableColumnDocumentPojo> columns,
|
List<TableColumnDocumentPojo> columns,
|
||||||
String tableName,
|
String tableName,
|
||||||
Map<String, Integer> discussionCountMapByJoinName) {
|
Map<String, Integer> discussionCountMapByJoinName,
|
||||||
|
Map<String, String> descriptionMapByJoinName) {
|
||||||
return columns.stream()
|
return columns.stream()
|
||||||
.map(column -> {
|
.map(column -> {
|
||||||
Integer count = discussionCountMapByJoinName.get(tableName + "." + column.getName());
|
Integer count = discussionCountMapByJoinName.get(tableName + "." + column.getName());
|
||||||
return of(column, count);
|
String description = descriptionMapByJoinName.get(tableName + "." + column.getName());
|
||||||
|
return of(column, count, description);
|
||||||
})
|
})
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,14 +21,18 @@ public interface DocumentSimpleResponseConverter {
|
||||||
DatabaseDocumentSimpleResponse of(DatabaseDocumentPojo databaseDocument,
|
DatabaseDocumentSimpleResponse of(DatabaseDocumentPojo databaseDocument,
|
||||||
List<DatabaseDocumentSimpleResponse.TableData> tables);
|
List<DatabaseDocumentSimpleResponse.TableData> tables);
|
||||||
|
|
||||||
DatabaseDocumentSimpleResponse.TableData of(TableDocumentPojo tables, Integer discussionCount);
|
DatabaseDocumentSimpleResponse.TableData of(TableDocumentPojo tables,
|
||||||
|
Integer discussionCount,
|
||||||
|
String description);
|
||||||
|
|
||||||
default List<DatabaseDocumentSimpleResponse.TableData> of(List<TableDocumentPojo> tables,
|
default List<DatabaseDocumentSimpleResponse.TableData> of(List<TableDocumentPojo> tables,
|
||||||
Map<String, Integer> discussionCountMapByTableName) {
|
Map<String, Integer> discussionCountMapByTableName,
|
||||||
|
Map<String, String> descriptionMapByTableName) {
|
||||||
return tables.stream()
|
return tables.stream()
|
||||||
.map(table -> {
|
.map(table -> {
|
||||||
Integer count = discussionCountMapByTableName.get(table.getName());
|
Integer count = discussionCountMapByTableName.get(table.getName());
|
||||||
return of(table, count);
|
String description = descriptionMapByTableName.get(table.getName());
|
||||||
|
return of(table, count, description);
|
||||||
})
|
})
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,8 @@ public class DatabaseDocumentResponse {
|
||||||
|
|
||||||
private Integer discussionCount;
|
private Integer discussionCount;
|
||||||
|
|
||||||
|
private String description;
|
||||||
|
|
||||||
@Builder.Default
|
@Builder.Default
|
||||||
private List<ColumnDocumentResponse> columns = new ArrayList<>();
|
private List<ColumnDocumentResponse> columns = new ArrayList<>();
|
||||||
|
|
||||||
|
@ -76,6 +78,8 @@ public class DatabaseDocumentResponse {
|
||||||
|
|
||||||
private String comment;
|
private String comment;
|
||||||
|
|
||||||
|
private String description;
|
||||||
|
|
||||||
private Boolean isPrimaryKey;
|
private Boolean isPrimaryKey;
|
||||||
|
|
||||||
private String nullable;
|
private String nullable;
|
||||||
|
|
|
@ -37,5 +37,7 @@ public class DatabaseDocumentSimpleResponse {
|
||||||
private String comment;
|
private String comment;
|
||||||
|
|
||||||
private Integer discussionCount;
|
private Integer discussionCount;
|
||||||
|
|
||||||
|
private String description;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,8 @@ public class DocumentService {
|
||||||
|
|
||||||
private final DocumentDiscussionDao documentDiscussionDao;
|
private final DocumentDiscussionDao documentDiscussionDao;
|
||||||
|
|
||||||
|
private final DocumentDescriptionDao documentDescriptionDao;
|
||||||
|
|
||||||
private final DocumentPojoConverter documentPojoConverter;
|
private final DocumentPojoConverter documentPojoConverter;
|
||||||
|
|
||||||
private final DocumentResponseConverter documentResponseConverter;
|
private final DocumentResponseConverter documentResponseConverter;
|
||||||
|
@ -146,7 +148,15 @@ public class DocumentService {
|
||||||
documentDiscussionDao.selectTableDiscussionCount(projectId)
|
documentDiscussionDao.selectTableDiscussionCount(projectId)
|
||||||
.stream()
|
.stream()
|
||||||
.collect(Collectors.toMap(d -> d.getTableName(), d -> d.getCount(), (a, b) -> a));
|
.collect(Collectors.toMap(d -> d.getTableName(), d -> d.getCount(), (a, b) -> a));
|
||||||
var tableMetas = documentSimpleResponseConverter.of(tables, discussionCountMapByTableName);
|
Map<String, String> descriptionMapByTableName =
|
||||||
|
documentDescriptionDao.selectTableDescriptionByProjectId(projectId)
|
||||||
|
.stream()
|
||||||
|
.collect(Collectors.toMap(d -> d.getTableName(), d -> d.getContent(), (a, b) -> a));
|
||||||
|
var tableMetas = documentSimpleResponseConverter.of(
|
||||||
|
tables,
|
||||||
|
discussionCountMapByTableName,
|
||||||
|
descriptionMapByTableName
|
||||||
|
);
|
||||||
return documentSimpleResponseConverter.of(document, tableMetas);
|
return documentSimpleResponseConverter.of(document, tableMetas);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -206,19 +216,26 @@ public class DocumentService {
|
||||||
}
|
}
|
||||||
var tables =
|
var tables =
|
||||||
tableDocumentDao.selectByDatabaseDocumentIdAndIdIn(databaseDocumentId, tableIds);
|
tableDocumentDao.selectByDatabaseDocumentIdAndIdIn(databaseDocumentId, tableIds);
|
||||||
|
// column
|
||||||
var columns =
|
var columns =
|
||||||
tableColumnDocumentDao.selectByDatabaseDocumentIdAndTableIdIn(databaseDocumentId, tableIds);
|
tableColumnDocumentDao.selectByDatabaseDocumentIdAndTableIdIn(databaseDocumentId, tableIds);
|
||||||
var indexes =
|
|
||||||
tableIndexDocumentDao.selectByDatabaseDocumentIdAndIdIn(databaseDocumentId, tableIds);
|
|
||||||
var triggers =
|
|
||||||
tableTriggerDocumentDao.selectByDatabaseDocumentIdAndIdIn(databaseDocumentId, tableIds);
|
|
||||||
var discussions = documentDiscussionDao.selectAllDiscussionCount(projectId);
|
|
||||||
Map<Integer, List<TableColumnDocumentPojo>> columnsGroupByTableMetaId = columns.stream()
|
Map<Integer, List<TableColumnDocumentPojo>> columnsGroupByTableMetaId = columns.stream()
|
||||||
.collect(Collectors.groupingBy(TableColumnDocumentPojo::getTableDocumentId));
|
.collect(Collectors.groupingBy(TableColumnDocumentPojo::getTableDocumentId));
|
||||||
|
|
||||||
|
// index
|
||||||
|
var indexes =
|
||||||
|
tableIndexDocumentDao.selectByDatabaseDocumentIdAndIdIn(databaseDocumentId, tableIds);
|
||||||
Map<Integer, List<TableIndexDocumentPojo>> indexesGroupByTableMetaId = indexes.stream()
|
Map<Integer, List<TableIndexDocumentPojo>> indexesGroupByTableMetaId = indexes.stream()
|
||||||
.collect(Collectors.groupingBy(TableIndexDocumentPojo::getTableDocumentId));
|
.collect(Collectors.groupingBy(TableIndexDocumentPojo::getTableDocumentId));
|
||||||
|
|
||||||
|
// trigger
|
||||||
|
var triggers =
|
||||||
|
tableTriggerDocumentDao.selectByDatabaseDocumentIdAndIdIn(databaseDocumentId, tableIds);
|
||||||
Map<Integer, List<TableTriggerDocumentPojo>> triggersGroupByTableMetaId = triggers.stream()
|
Map<Integer, List<TableTriggerDocumentPojo>> triggersGroupByTableMetaId = triggers.stream()
|
||||||
.collect(Collectors.groupingBy(TableTriggerDocumentPojo::getTableDocumentId));
|
.collect(Collectors.groupingBy(TableTriggerDocumentPojo::getTableDocumentId));
|
||||||
|
|
||||||
|
// discussion
|
||||||
|
var discussions = documentDiscussionDao.selectAllDiscussionCount(projectId);
|
||||||
Map<String, Integer> discussionCountMapByJoinName = discussions.stream()
|
Map<String, Integer> discussionCountMapByJoinName = discussions.stream()
|
||||||
.collect(Collectors.toMap(
|
.collect(Collectors.toMap(
|
||||||
d -> String.join(".",
|
d -> String.join(".",
|
||||||
|
@ -226,6 +243,17 @@ public class DocumentService {
|
||||||
StringUtils.defaultIfBlank(d.getColumnName(), "")),
|
StringUtils.defaultIfBlank(d.getColumnName(), "")),
|
||||||
DocumentDiscussionCountPojo::getCount,
|
DocumentDiscussionCountPojo::getCount,
|
||||||
(a, b) -> a));
|
(a, b) -> a));
|
||||||
|
|
||||||
|
// description
|
||||||
|
var descriptions = documentDescriptionDao.selectByProjectId(projectId);
|
||||||
|
Map<String, String> descriptionMapByJoinName = descriptions.stream()
|
||||||
|
.collect(Collectors.toMap(
|
||||||
|
d -> String.join(".",
|
||||||
|
d.getTableName(),
|
||||||
|
StringUtils.defaultIfBlank(d.getColumnName(), "")),
|
||||||
|
DocumentDescriptionPojo::getContent,
|
||||||
|
(a, b) -> a));
|
||||||
|
|
||||||
return tables.stream()
|
return tables.stream()
|
||||||
.map(table -> {
|
.map(table -> {
|
||||||
Integer tableId = table.getId();
|
Integer tableId = table.getId();
|
||||||
|
@ -233,9 +261,14 @@ public class DocumentService {
|
||||||
var subIndexes = indexesGroupByTableMetaId.getOrDefault(tableId, Collections.emptyList());
|
var subIndexes = indexesGroupByTableMetaId.getOrDefault(tableId, Collections.emptyList());
|
||||||
var subTriggers = triggersGroupByTableMetaId.getOrDefault(tableId, Collections.emptyList());
|
var subTriggers = triggersGroupByTableMetaId.getOrDefault(tableId, Collections.emptyList());
|
||||||
var discussionCount = discussionCountMapByJoinName.get(table.getName());
|
var discussionCount = discussionCountMapByJoinName.get(table.getName());
|
||||||
|
var description= descriptionMapByJoinName.get(table.getName());
|
||||||
var columnResponses =
|
var columnResponses =
|
||||||
documentResponseConverter.of(subColumns, table.getName(), discussionCountMapByJoinName);
|
documentResponseConverter.of(
|
||||||
return documentResponseConverter.of(table, discussionCount, columnResponses, subIndexes,
|
subColumns,
|
||||||
|
table.getName(),
|
||||||
|
discussionCountMapByJoinName,
|
||||||
|
descriptionMapByJoinName);
|
||||||
|
return documentResponseConverter.of(table, discussionCount,description, columnResponses, subIndexes,
|
||||||
subTriggers);
|
subTriggers);
|
||||||
})
|
})
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
package com.databasir.dao.impl;
|
||||||
|
|
||||||
|
import com.databasir.dao.tables.pojos.DocumentDescriptionPojo;
|
||||||
|
import com.databasir.dao.tables.records.DocumentDescriptionRecord;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.jooq.Condition;
|
||||||
|
import org.jooq.DSLContext;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static com.databasir.dao.Tables.DOCUMENT_DESCRIPTION;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public class DocumentDescriptionDao extends BaseDao<DocumentDescriptionPojo> {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Getter
|
||||||
|
private DSLContext dslContext;
|
||||||
|
|
||||||
|
public DocumentDescriptionDao() {
|
||||||
|
super(DOCUMENT_DESCRIPTION, DocumentDescriptionPojo.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean exists(Integer projectId, String tableName, String columnName) {
|
||||||
|
Condition condition = DOCUMENT_DESCRIPTION.PROJECT_ID.eq(projectId)
|
||||||
|
.and(DOCUMENT_DESCRIPTION.TABLE_NAME.eq(tableName));
|
||||||
|
if (columnName == null) {
|
||||||
|
condition = condition.and(DOCUMENT_DESCRIPTION.COLUMN_NAME.isNull());
|
||||||
|
} else {
|
||||||
|
condition = condition.and(DOCUMENT_DESCRIPTION.COLUMN_NAME.eq(columnName));
|
||||||
|
}
|
||||||
|
return this.exists(condition);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(DocumentDescriptionPojo pojo) {
|
||||||
|
Condition condition = DOCUMENT_DESCRIPTION.TABLE_NAME.eq(pojo.getTableName());
|
||||||
|
if (pojo.getColumnName() == null) {
|
||||||
|
condition = condition.and(DOCUMENT_DESCRIPTION.COLUMN_NAME.isNull());
|
||||||
|
} else {
|
||||||
|
condition = condition.and(DOCUMENT_DESCRIPTION.COLUMN_NAME.eq(pojo.getColumnName()));
|
||||||
|
}
|
||||||
|
DocumentDescriptionRecord record = getDslContext().newRecord(DOCUMENT_DESCRIPTION, pojo);
|
||||||
|
getDslContext().executeUpdate(record, condition);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<DocumentDescriptionPojo> selectByProjectId(Integer projectId) {
|
||||||
|
return selectByCondition(DOCUMENT_DESCRIPTION.PROJECT_ID.eq(projectId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<DocumentDescriptionPojo> selectTableDescriptionByProjectId(Integer projectId) {
|
||||||
|
return selectByCondition(DOCUMENT_DESCRIPTION.PROJECT_ID.eq(projectId)
|
||||||
|
.and(DOCUMENT_DESCRIPTION.COLUMN_NAME.isNull()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<DocumentDescriptionPojo> selectByCondition(Condition condition) {
|
||||||
|
return this.getDslContext()
|
||||||
|
.selectFrom(DOCUMENT_DESCRIPTION).where(condition)
|
||||||
|
.fetchInto(DocumentDescriptionPojo.class);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue