Page MenuHomeSoftware Heritage

D8020.id28968.diff
No OneTemporary

D8020.id28968.diff

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,17 @@
def get_content(self, content_id):
# FIXME, only for tests
return self.storage.content_find({"sha1_git": content_id})
+
+ def search_in_swhids(self, swhid) -> List:
+ # query iff a valid swhid
+ swhid = CoreSWHID.from_string(swhid)
+ return self.get_revisions([swhid.object_id])
+
+ def search_in_metadata(self, query) -> List:
+ # validate the query language as a key expression in the utils
+ return []
+
+ def search_in_origins(self, query) -> List:
+ # use this with the get_origins method
+ # validate the query language as a key expression in the utils
+ return []
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
@@ -239,6 +239,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,66 @@
+# 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):
+ return 10
+
+
+class SearchResultConnection(BaseConnection):
+ """
+ Category is a mandatory argument, get one category per
+ query
+ different categories can be requested in one request with
+ alias in query
+ eg:
+ query mysearch {
+ ori-search: search(query: "test", category: "origin") {
+ type
+ }
+ meta-search: search(query: "test", category: "metadata") {
+ type
+ }
+ swhid-search: search(query: "test", category: "swhid") {
+ type
+ }
+ }
+ """
+
+ # client UI can have a result page with multiple tabs
+ # each category will add a new tab in the UI
+ # add more categories as needed
+ # advanced query language will be handled implicitly in
+ # metadata and origins
+
+ _node_class = SearchResult
+
+ def _get_paged_result(self):
+ query = self.kwargs.get("query")
+ category = self.kwargs.get("category")
+ # FIXME, use a search factory instead, either in this module
+ # or in a separate package
+ if category == "swhid":
+ results = archive.Archive().search_in_swhids(query)
+ elif category == "metadata":
+ results = archive.Archive().search_in_metadata(query)
+ elif category == "origin":
+ # this will return a homogeneous list of origin types
+ # still using the same SearchResult type to return result
+ # FIXME, maybe it is better to add a type OriginSearchResult
+ results = archive.Archive().search_in_origins(query)
+ return PagedResult(results=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,12 @@
"""
swhid: SWHID!
): Content
+
+ """
+ Search the archive
+ """
+ search(
+ query: String
+ category: String # Make an enum
+ ): SearchResultConnection
}

File Metadata

Mime Type
text/plain
Expires
Nov 5 2024, 3:55 PM (11 w, 14 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3228859

Event Timeline