diff --git a/swh/graphql/backends/archive.py b/swh/graphql/backends/archive.py --- a/swh/graphql/backends/archive.py +++ b/swh/graphql/backends/archive.py @@ -3,7 +3,10 @@ # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information +from typing import List + from swh.graphql import server +from swh.model.swhids import CoreSWHID class Archive: @@ -77,3 +80,8 @@ def get_content(self, content_id): # FIXME, only for tests return self.storage.content_find({"sha1_git": content_id}) + + def lookup_swhid(self, swhid) -> List: + # query iff a valid swhid + swhid = CoreSWHID.from_string(swhid) + return self.get_revisions([swhid.object_id]) diff --git a/swh/graphql/resolvers/resolver_factory.py b/swh/graphql/resolvers/resolver_factory.py --- a/swh/graphql/resolvers/resolver_factory.py +++ b/swh/graphql/resolvers/resolver_factory.py @@ -14,6 +14,7 @@ RevisionNode, TargetRevisionNode, ) +from .search import SearchResultConnection from .snapshot import ( OriginSnapshotConnection, SnapshotNode, @@ -67,6 +68,7 @@ "revision-parents": ParentRevisionConnection, "revision-log": LogRevisionConnection, "directory-entries": DirectoryEntryConnection, + "search": SearchResultConnection, } if resolver_type not in mapping: raise AttributeError(f"Invalid connection type: {resolver_type}") diff --git a/swh/graphql/resolvers/resolvers.py b/swh/graphql/resolvers/resolvers.py --- a/swh/graphql/resolvers/resolvers.py +++ b/swh/graphql/resolvers/resolvers.py @@ -236,6 +236,14 @@ return resolver(obj, info, **kw)() +@query.field("search") +def search_resolver( + obj, info: GraphQLResolveInfo, **kw +) -> rs.search.SearchResultConnection: + resolver = get_connection_resolver("search") + return resolver(obj, info, **kw)() + + # Any other type of resolver diff --git a/swh/graphql/resolvers/search.py b/swh/graphql/resolvers/search.py new file mode 100644 --- /dev/null +++ b/swh/graphql/resolvers/search.py @@ -0,0 +1,33 @@ +# Copyright (C) 2022 The Software Heritage developers +# See the AUTHORS file at the top-level directory of this distribution +# License: GNU General Public License version 3, or any later version +# See top-level LICENSE file for more information +from swh.graphql.backends import archive +from swh.storage.interface import PagedResult + +from .base_connection import BaseConnection +from .base_node import BaseNode + + +class SearchResult(BaseNode): + # match: int + + @property + def resultType(self): + self._node.is_type_of() + + @property + def match(self): + pass + + +class SearchResultConnection(BaseConnection): + + _node_class = SearchResult + + def _get_paged_result(self): + search_term = self.kwargs.get("searchTerm") + swhid_results = archive.Archive().lookup_swhid(search_term) + # origin_results = origin_search(search_term) + # metadata_results = metadata_search(search_term) + return PagedResult(results=[*swhid_results], next_page_token=None) diff --git a/swh/graphql/schema/schema.graphql b/swh/graphql/schema/schema.graphql --- a/swh/graphql/schema/schema.graphql +++ b/swh/graphql/schema/schema.graphql @@ -805,6 +805,55 @@ status: String } +""" +Connection to search results +""" +type SearchResultConnection { + """ + List of search result edges + """ + edges: [SearchResultEdge] + + """ + List of search result objects + """ + nodes: [SearchResult] + + """ + Information for pagination + """ + pageInfo: PageInfo! + + """ + Total number of origin objects in the connection + """ + totalCount: Int +} + +type SearchResultEdge { + """ + Cursor to request the next page after the item + """ + cursor: String! + + """ + Search result object + """ + node: SearchResult +} + +union SearchResultTarget = Revision | Release | Branch | Content | Directory | Snapshot | Origin + +""" +A search result object +""" +type SearchResult { + match: Int + result: SearchResultTarget + resultType: String + metadata: String +} + """ The query root of the GraphQL interface. """ @@ -903,4 +952,11 @@ """ swhid: SWHID! ): Content + + """ + Search the archive + """ + search( + searchTerm: String + ): SearchResultConnection }