From e416006793c003967a45d36910ad7c5406f33e5f Mon Sep 17 00:00:00 2001 From: vran Date: Sun, 15 May 2022 23:31:31 +0800 Subject: [PATCH] feat: add global search api --- .../main/java/com/databasir/api/Routes.java | 4 ++ .../com/databasir/api/SearchController.java | 27 ++++++++++ .../core/domain/search/SearchService.java | 33 ++++++++++++ .../converter/SearchResponseConverter.java | 16 ++++++ .../domain/search/data/SearchResponse.java | 51 +++++++++++++++++++ .../java/com/databasir/dao/impl/GroupDao.java | 8 +++ .../com/databasir/dao/impl/ProjectDao.java | 28 +++++++++- .../databasir/dao/value/ProjectQueryPojo.java | 21 ++++++++ 8 files changed, 186 insertions(+), 2 deletions(-) create mode 100644 api/src/main/java/com/databasir/api/SearchController.java create mode 100644 core/src/main/java/com/databasir/core/domain/search/SearchService.java create mode 100644 core/src/main/java/com/databasir/core/domain/search/converter/SearchResponseConverter.java create mode 100644 core/src/main/java/com/databasir/core/domain/search/data/SearchResponse.java create mode 100644 dao/src/main/java/com/databasir/dao/value/ProjectQueryPojo.java diff --git a/api/src/main/java/com/databasir/api/Routes.java b/api/src/main/java/com/databasir/api/Routes.java index 1d380f3..ca5731b 100644 --- a/api/src/main/java/com/databasir/api/Routes.java +++ b/api/src/main/java/com/databasir/api/Routes.java @@ -182,4 +182,8 @@ public interface Routes { String GET_SQL_MOCK_DATA = BASE + "/groups/{groupId}/projects/{projectId}/mock_data/sql"; } + + interface Search { + String SEARCH = BASE + "/search"; + } } \ No newline at end of file diff --git a/api/src/main/java/com/databasir/api/SearchController.java b/api/src/main/java/com/databasir/api/SearchController.java new file mode 100644 index 0000000..1cb9a1f --- /dev/null +++ b/api/src/main/java/com/databasir/api/SearchController.java @@ -0,0 +1,27 @@ +package com.databasir.api; + +import com.databasir.common.JsonData; +import com.databasir.core.domain.search.SearchService; +import com.databasir.core.domain.search.data.SearchResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@Validated +@Tag(name = "SearchController", description = "全局搜索 API") +public class SearchController { + + private final SearchService searchService; + + @GetMapping(Routes.Search.SEARCH) + @Operation(summary = "搜索") + public JsonData search(@RequestParam(name = "query") String keyword) { + return JsonData.ok(searchService.search(keyword)); + } +} diff --git a/core/src/main/java/com/databasir/core/domain/search/SearchService.java b/core/src/main/java/com/databasir/core/domain/search/SearchService.java new file mode 100644 index 0000000..3e9414e --- /dev/null +++ b/core/src/main/java/com/databasir/core/domain/search/SearchService.java @@ -0,0 +1,33 @@ +package com.databasir.core.domain.search; + +import com.databasir.core.domain.search.converter.SearchResponseConverter; +import com.databasir.core.domain.search.data.SearchResponse; +import com.databasir.dao.impl.GroupDao; +import com.databasir.dao.impl.ProjectDao; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class SearchService { + + private final ProjectDao projectDao; + + private final GroupDao groupDao; + + private final SearchResponseConverter searchResponseConverter; + + public SearchResponse search(String query) { + var groupPojoList = groupDao.selectByName(query); + var groupResults = searchResponseConverter.toGroupResults(groupPojoList); + var projectList = projectDao.selectByProjectNameOrDatabaseOrSchemaOrGroup(query); + var projectResults = searchResponseConverter.toProjectResults(projectList); + + // build response + SearchResponse response = new SearchResponse(); + response.setGroups(groupResults); + response.setProjects(projectResults); + // TODO support Table search + return response; + } +} diff --git a/core/src/main/java/com/databasir/core/domain/search/converter/SearchResponseConverter.java b/core/src/main/java/com/databasir/core/domain/search/converter/SearchResponseConverter.java new file mode 100644 index 0000000..942082a --- /dev/null +++ b/core/src/main/java/com/databasir/core/domain/search/converter/SearchResponseConverter.java @@ -0,0 +1,16 @@ +package com.databasir.core.domain.search.converter; + +import com.databasir.core.domain.search.data.SearchResponse; +import com.databasir.dao.tables.pojos.GroupPojo; +import com.databasir.dao.value.ProjectQueryPojo; +import org.mapstruct.Mapper; + +import java.util.List; + +@Mapper(componentModel = "spring") +public interface SearchResponseConverter { + + List toGroupResults(List groups); + + List toProjectResults(List projects); +} diff --git a/core/src/main/java/com/databasir/core/domain/search/data/SearchResponse.java b/core/src/main/java/com/databasir/core/domain/search/data/SearchResponse.java new file mode 100644 index 0000000..0eea330 --- /dev/null +++ b/core/src/main/java/com/databasir/core/domain/search/data/SearchResponse.java @@ -0,0 +1,51 @@ +package com.databasir.core.domain.search.data; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Collections; +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class SearchResponse { + + @Builder.Default + private List groups = Collections.emptyList(); + + @Builder.Default + private List projects = Collections.emptyList(); + + @Data + public static class GroupSearchResult { + + private Integer id; + + private String name; + + private String description; + } + + @Data + public static class ProjectSearchResult { + + private Integer projectId; + + private Integer groupId; + + private String groupName; + + private String projectName; + + private String projectDescription; + + private String databaseName; + + private String schemaName; + + } +} diff --git a/dao/src/main/java/com/databasir/dao/impl/GroupDao.java b/dao/src/main/java/com/databasir/dao/impl/GroupDao.java index 685819e..c9985fd 100644 --- a/dao/src/main/java/com/databasir/dao/impl/GroupDao.java +++ b/dao/src/main/java/com/databasir/dao/impl/GroupDao.java @@ -69,4 +69,12 @@ public class GroupDao extends BaseDao { .where(GROUP.ID.in(ids)) .fetchInto(GroupPojo.class); } + + public List selectByName(String nameContains) { + return getDslContext() + .select(GROUP.fields()).from(GROUP) + .where(GROUP.NAME.contains(nameContains)) + .and(GROUP.DELETED.eq(false)) + .fetchInto(GroupPojo.class); + } } \ No newline at end of file diff --git a/dao/src/main/java/com/databasir/dao/impl/ProjectDao.java b/dao/src/main/java/com/databasir/dao/impl/ProjectDao.java index ca83bd7..bcdf419 100644 --- a/dao/src/main/java/com/databasir/dao/impl/ProjectDao.java +++ b/dao/src/main/java/com/databasir/dao/impl/ProjectDao.java @@ -2,6 +2,7 @@ package com.databasir.dao.impl; import com.databasir.dao.tables.pojos.ProjectPojo; import com.databasir.dao.value.GroupProjectCountPojo; +import com.databasir.dao.value.ProjectQueryPojo; import lombok.Getter; import org.jooq.Condition; import org.jooq.DSLContext; @@ -19,8 +20,7 @@ import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; -import static com.databasir.dao.Tables.DATA_SOURCE; -import static com.databasir.dao.Tables.PROJECT; +import static com.databasir.dao.Tables.*; @Repository public class ProjectDao extends BaseDao { @@ -126,4 +126,28 @@ public class ProjectDao extends BaseDao { .where(PROJECT.ID.in(projectIds)) .fetchMap(PROJECT.ID, PROJECT.GROUP_ID); } + + public List selectByProjectNameOrDatabaseOrSchemaOrGroup(String query) { + return getDslContext() + .select( + PROJECT.ID.as("project_id"), + PROJECT.NAME.as("project_name"), + PROJECT.DESCRIPTION.as("project_description"), + DATA_SOURCE.DATABASE_NAME, + DATA_SOURCE.SCHEMA_NAME, + GROUP.NAME.as("group_name"), + GROUP.ID.as("group_id") + ) + .from(PROJECT) + .leftJoin(DATA_SOURCE).on(DATA_SOURCE.PROJECT_ID.eq(PROJECT.ID)) + .leftJoin(GROUP).on(GROUP.ID.eq(PROJECT.GROUP_ID)) + .where(PROJECT.DELETED.eq(false) + .and(GROUP.DELETED.eq(false)) + .and(PROJECT.NAME.contains(query) + .or(DATA_SOURCE.DATABASE_NAME.contains(query)) + .or(DATA_SOURCE.SCHEMA_NAME.contains(query)) + .or(GROUP.NAME.contains(query))) + ) + .fetchInto(ProjectQueryPojo.class); + } } diff --git a/dao/src/main/java/com/databasir/dao/value/ProjectQueryPojo.java b/dao/src/main/java/com/databasir/dao/value/ProjectQueryPojo.java new file mode 100644 index 0000000..edc4a5b --- /dev/null +++ b/dao/src/main/java/com/databasir/dao/value/ProjectQueryPojo.java @@ -0,0 +1,21 @@ +package com.databasir.dao.value; + +import lombok.Data; + +@Data +public class ProjectQueryPojo { + + private Integer projectId; + + private Integer groupId; + + private String groupName; + + private String projectName; + + private String projectDescription; + + private String databaseName; + + private String schemaName; +}