diff --git a/api/src/main/java/com/databasir/api/DocumentDescriptionController.java b/api/src/main/java/com/databasir/api/DocumentDescriptionController.java new file mode 100644 index 0000000..6bfc88f --- /dev/null +++ b/api/src/main/java/com/databasir/api/DocumentDescriptionController.java @@ -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(); + } +} diff --git a/api/src/main/java/com/databasir/api/Routes.java b/api/src/main/java/com/databasir/api/Routes.java index 2f63a79..c33819c 100644 --- a/api/src/main/java/com/databasir/api/Routes.java +++ b/api/src/main/java/com/databasir/api/Routes.java @@ -96,6 +96,13 @@ public interface Routes { String DELETE = DISCUSSION_BASE + "/{discussionId}"; } + interface DocumentDescription { + + String DISCUSSION_BASE = BASE + "/groups/{groupId}/projects/{projectId}/descriptions"; + + String SAVE = DISCUSSION_BASE; + } + interface Setting { String GET_SYS_EMAIL = BASE + "/settings/sys_email"; diff --git a/core/src/main/java/com/databasir/core/domain/description/converter/DocumentDescriptionPojoConverter.java b/core/src/main/java/com/databasir/core/domain/description/converter/DocumentDescriptionPojoConverter.java new file mode 100644 index 0000000..e6105f2 --- /dev/null +++ b/core/src/main/java/com/databasir/core/domain/description/converter/DocumentDescriptionPojoConverter.java @@ -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); +} diff --git a/core/src/main/java/com/databasir/core/domain/description/data/DocumentDescriptionSaveRequest.java b/core/src/main/java/com/databasir/core/domain/description/data/DocumentDescriptionSaveRequest.java new file mode 100644 index 0000000..9eeb6e0 --- /dev/null +++ b/core/src/main/java/com/databasir/core/domain/description/data/DocumentDescriptionSaveRequest.java @@ -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; + +} diff --git a/core/src/main/java/com/databasir/core/domain/description/service/DocumentDescriptionService.java b/core/src/main/java/com/databasir/core/domain/description/service/DocumentDescriptionService.java new file mode 100644 index 0000000..661ed8f --- /dev/null +++ b/core/src/main/java/com/databasir/core/domain/description/service/DocumentDescriptionService.java @@ -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); + } + } +} diff --git a/core/src/main/java/com/databasir/core/domain/document/converter/DocumentResponseConverter.java b/core/src/main/java/com/databasir/core/domain/document/converter/DocumentResponseConverter.java index 9d70386..f0f3557 100644 --- a/core/src/main/java/com/databasir/core/domain/document/converter/DocumentResponseConverter.java +++ b/core/src/main/java/com/databasir/core/domain/document/converter/DocumentResponseConverter.java @@ -28,21 +28,25 @@ public interface DocumentResponseConverter { @SuppressWarnings("checkstyle:all") DatabaseDocumentResponse.TableDocumentResponse of(TableDocumentPojo tableDocument, Integer discussionCount, + String description, List<DatabaseDocumentResponse.TableDocumentResponse.ColumnDocumentResponse> columns, List<TableIndexDocumentPojo> indexes, List<TableTriggerDocumentPojo> triggers); DatabaseDocumentResponse.TableDocumentResponse.ColumnDocumentResponse of(TableColumnDocumentPojo pojo, - Integer discussionCount); + Integer discussionCount, + String description); default List<DatabaseDocumentResponse.TableDocumentResponse.ColumnDocumentResponse> of( List<TableColumnDocumentPojo> columns, String tableName, - Map<String, Integer> discussionCountMapByJoinName) { + Map<String, Integer> discussionCountMapByJoinName, + Map<String, String> descriptionMapByJoinName) { return columns.stream() .map(column -> { 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()); } diff --git a/core/src/main/java/com/databasir/core/domain/document/converter/DocumentSimpleResponseConverter.java b/core/src/main/java/com/databasir/core/domain/document/converter/DocumentSimpleResponseConverter.java index cc29ed4..8abf891 100644 --- a/core/src/main/java/com/databasir/core/domain/document/converter/DocumentSimpleResponseConverter.java +++ b/core/src/main/java/com/databasir/core/domain/document/converter/DocumentSimpleResponseConverter.java @@ -21,14 +21,18 @@ public interface DocumentSimpleResponseConverter { DatabaseDocumentSimpleResponse of(DatabaseDocumentPojo databaseDocument, 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, - Map<String, Integer> discussionCountMapByTableName) { + Map<String, Integer> discussionCountMapByTableName, + Map<String, String> descriptionMapByTableName) { return tables.stream() .map(table -> { Integer count = discussionCountMapByTableName.get(table.getName()); - return of(table, count); + String description = descriptionMapByTableName.get(table.getName()); + return of(table, count, description); }) .collect(Collectors.toList()); } diff --git a/core/src/main/java/com/databasir/core/domain/document/data/DatabaseDocumentResponse.java b/core/src/main/java/com/databasir/core/domain/document/data/DatabaseDocumentResponse.java index a0dcda6..e3cebe0 100644 --- a/core/src/main/java/com/databasir/core/domain/document/data/DatabaseDocumentResponse.java +++ b/core/src/main/java/com/databasir/core/domain/document/data/DatabaseDocumentResponse.java @@ -48,6 +48,8 @@ public class DatabaseDocumentResponse { private Integer discussionCount; + private String description; + @Builder.Default private List<ColumnDocumentResponse> columns = new ArrayList<>(); @@ -76,6 +78,8 @@ public class DatabaseDocumentResponse { private String comment; + private String description; + private Boolean isPrimaryKey; private String nullable; diff --git a/core/src/main/java/com/databasir/core/domain/document/data/DatabaseDocumentSimpleResponse.java b/core/src/main/java/com/databasir/core/domain/document/data/DatabaseDocumentSimpleResponse.java index 1be8388..38e7bfe 100644 --- a/core/src/main/java/com/databasir/core/domain/document/data/DatabaseDocumentSimpleResponse.java +++ b/core/src/main/java/com/databasir/core/domain/document/data/DatabaseDocumentSimpleResponse.java @@ -37,5 +37,7 @@ public class DatabaseDocumentSimpleResponse { private String comment; private Integer discussionCount; + + private String description; } } 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 544c689..a44e7df 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 @@ -59,6 +59,8 @@ public class DocumentService { private final DocumentDiscussionDao documentDiscussionDao; + private final DocumentDescriptionDao documentDescriptionDao; + private final DocumentPojoConverter documentPojoConverter; private final DocumentResponseConverter documentResponseConverter; @@ -146,7 +148,15 @@ public class DocumentService { documentDiscussionDao.selectTableDiscussionCount(projectId) .stream() .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); }); } @@ -206,19 +216,26 @@ public class DocumentService { } var tables = tableDocumentDao.selectByDatabaseDocumentIdAndIdIn(databaseDocumentId, tableIds); + // column var columns = 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() .collect(Collectors.groupingBy(TableColumnDocumentPojo::getTableDocumentId)); + + // index + var indexes = + tableIndexDocumentDao.selectByDatabaseDocumentIdAndIdIn(databaseDocumentId, tableIds); Map<Integer, List<TableIndexDocumentPojo>> indexesGroupByTableMetaId = indexes.stream() .collect(Collectors.groupingBy(TableIndexDocumentPojo::getTableDocumentId)); + + // trigger + var triggers = + tableTriggerDocumentDao.selectByDatabaseDocumentIdAndIdIn(databaseDocumentId, tableIds); Map<Integer, List<TableTriggerDocumentPojo>> triggersGroupByTableMetaId = triggers.stream() .collect(Collectors.groupingBy(TableTriggerDocumentPojo::getTableDocumentId)); + + // discussion + var discussions = documentDiscussionDao.selectAllDiscussionCount(projectId); Map<String, Integer> discussionCountMapByJoinName = discussions.stream() .collect(Collectors.toMap( d -> String.join(".", @@ -226,6 +243,17 @@ public class DocumentService { StringUtils.defaultIfBlank(d.getColumnName(), "")), DocumentDiscussionCountPojo::getCount, (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() .map(table -> { Integer tableId = table.getId(); @@ -233,9 +261,14 @@ public class DocumentService { var subIndexes = indexesGroupByTableMetaId.getOrDefault(tableId, Collections.emptyList()); var subTriggers = triggersGroupByTableMetaId.getOrDefault(tableId, Collections.emptyList()); var discussionCount = discussionCountMapByJoinName.get(table.getName()); + var description= descriptionMapByJoinName.get(table.getName()); var columnResponses = - documentResponseConverter.of(subColumns, table.getName(), discussionCountMapByJoinName); - return documentResponseConverter.of(table, discussionCount, columnResponses, subIndexes, + documentResponseConverter.of( + subColumns, + table.getName(), + discussionCountMapByJoinName, + descriptionMapByJoinName); + return documentResponseConverter.of(table, discussionCount,description, columnResponses, subIndexes, subTriggers); }) .collect(Collectors.toList()); diff --git a/dao/src/main/java/com/databasir/dao/impl/DocumentDescriptionDao.java b/dao/src/main/java/com/databasir/dao/impl/DocumentDescriptionDao.java new file mode 100644 index 0000000..aa95280 --- /dev/null +++ b/dao/src/main/java/com/databasir/dao/impl/DocumentDescriptionDao.java @@ -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); + } +}