MCPcopy Create free account
hub / github.com/rilldata/rill / QueryResolver

Method QueryResolver

runtime/server/query_resolver.go:18–103  ·  view source on GitHub ↗

QueryResolver enables superusers and project admins to query a resolver within a project

(ctx context.Context, req *runtimev1.QueryResolverRequest)

Source from the content-addressed store, hash-verified

16
17// QueryResolver enables superusers and project admins to query a resolver within a project
18func (s *Server) QueryResolver(ctx context.Context, req *runtimev1.QueryResolverRequest) (*runtimev1.QueryResolverResponse, error) {
19 // Validate permissions
20 claims := auth.GetClaims(ctx, req.InstanceId)
21 switch req.Resolver {
22 case "metrics", "metrics_sql":
23 // As a special case, we allow metrics resolvers for users with ReadMetrics permission (i.e. all users)
24 if !claims.Can(runtime.ReadMetrics) {
25 return nil, status.Error(codes.PermissionDenied, "not allowed to query metrics")
26 }
27 default:
28 // Other resolvers require ReadResolvers permission (i.e. project admin)
29 if !claims.Can(runtime.ReadResolvers) {
30 return nil, status.Error(codes.PermissionDenied, "only project admins can query resolvers")
31 }
32 }
33
34 // Resolver should exist
35 initializer, ok := runtime.ResolverInitializers[req.Resolver]
36 if !ok {
37 return nil, status.Errorf(codes.NotFound, "no resolver found of type %q", req.Resolver)
38 }
39
40 // Inject limit into the props.
41 // Note: Not all resolvers support `limit` being passed here, but it's better than nothing.
42 // In case the resolver does not apply the limit, we fall back to applying it when reading the results later in this handler.
43 props := req.ResolverProperties.AsMap()
44 if req.Limit != 0 {
45 props["limit"] = req.Limit
46 }
47
48 // Initialize the resolver
49 resolver, err := initializer(ctx, &runtime.ResolverOptions{
50 Runtime: s.runtime,
51 InstanceID: req.InstanceId,
52 Properties: props,
53 Args: req.ResolverArgs.AsMap(),
54 Claims: claims,
55 ForExport: false,
56 })
57 if err != nil {
58 return nil, mapGRPCErrorWithFallback(err, codes.InvalidArgument)
59 }
60 defer resolver.Close()
61
62 // Query the resolver
63 res, err := resolver.ResolveInteractive(ctx)
64 if err != nil {
65 return nil, mapGRPCErrorWithFallback(err, codes.InvalidArgument)
66 }
67 defer res.Close()
68
69 data := make([]*structpb.Struct, 0)
70 count := 0
71 for {
72 // Break if we've reached the limit (when limit > 0)
73 if req.Limit > 0 && count >= int(req.Limit) {
74 break
75 }

Callers 1

Calls 12

GetClaimsFunction · 0.92
ToStructFunction · 0.92
mapGRPCErrorWithFallbackFunction · 0.85
CanMethod · 0.80
ErrorfMethod · 0.65
CloseMethod · 0.65
ResolveInteractiveMethod · 0.65
NextMethod · 0.65
SchemaMethod · 0.65
MetaMethod · 0.65
ErrorMethod · 0.45
AsMapMethod · 0.45

Tested by 1