@@ -5,11 +5,14 @@ import (
55 "fmt"
66 "sync"
77
8+ "github.com/graph-gophers/graphql-go"
9+ "github.com/graph-gophers/graphql-go/relay"
810 orderedmap "github.com/wk8/go-ordered-map/v2"
911 "go.opentelemetry.io/otel/attribute"
1012
1113 "github.com/sourcegraph/scip/bindings/go/scip"
1214
15+ "github.com/sourcegraph/sourcegraph/internal/api"
1316 "github.com/sourcegraph/sourcegraph/internal/authz"
1417 "github.com/sourcegraph/sourcegraph/internal/codeintel/codenav"
1518 resolverstubs "github.com/sourcegraph/sourcegraph/internal/codeintel/resolvers"
@@ -159,6 +162,10 @@ func (r *rootResolver) CodeGraphData(ctx context.Context, opts *resolverstubs.Co
159162 return & []resolverstubs.CodeGraphDataResolver {}, nil
160163}
161164
165+ func (r * rootResolver ) CodeGraphDataByID (ctx context.Context , id graphql.ID ) (resolverstubs.CodeGraphDataResolver , error ) {
166+ return newCodeGraphDataResolverFromID (ctx , r .repoStore , r .svc , r .operations , id )
167+ }
168+
162169func preferUploadsWithLongestRoots (uploads []shared.CompletedUpload ) []shared.CompletedUpload {
163170 // Use orderedmap instead of a map to preserve the order of the uploads
164171 // and to avoid introducing non-determinism.
@@ -317,14 +324,34 @@ type codeGraphDataResolver struct {
317324
318325 // Arguments
319326 svc CodeNavService
320- upload shared. CompletedUpload
327+ upload UploadData
321328 opts * resolverstubs.CodeGraphDataOpts
322329 provenance resolverstubs.CodeGraphDataProvenance
323330
324331 // O11y
325332 operations * operations
326333}
327334
335+ // UploadData represents the subset of information of shared.CompletedUpload
336+ // that we actually care about for the purposes of the GraphQL API.
337+ //
338+ // All fields are left public for JSON marshaling/unmarshaling.
339+ type UploadData struct {
340+ UploadID int
341+ Commit string
342+ Indexer string
343+ IndexerVersion string
344+ }
345+
346+ func NewUploadData (upload shared.CompletedUpload ) UploadData {
347+ return UploadData {
348+ UploadID : upload .ID ,
349+ Commit : upload .Commit ,
350+ Indexer : upload .Indexer ,
351+ IndexerVersion : upload .IndexerVersion ,
352+ }
353+ }
354+
328355func newCodeGraphDataResolver (
329356 svc CodeNavService ,
330357 upload shared.CompletedUpload ,
@@ -337,23 +364,81 @@ func newCodeGraphDataResolver(
337364 /*document*/ nil ,
338365 /*documentRetrievalError*/ nil ,
339366 svc ,
340- upload ,
367+ NewUploadData ( upload ) ,
341368 opts ,
342369 provenance ,
343370 operations ,
344371 }
345372}
346373
374+ // CodeGraphDataID represents the serializable state needed to materialize
375+ // a CodeGraphData value from an opaque GraphQL ID.
376+ //
377+ // All fields are left public for JSON marshaling/unmarshaling.
378+ type CodeGraphDataID struct {
379+ UploadData
380+ Args * resolverstubs.CodeGraphDataArgs
381+ api.RepoID
382+ Commit api.CommitID
383+ Path string
384+ resolverstubs.CodeGraphDataProvenance
385+ }
386+
387+ func newCodeGraphDataResolverFromID (
388+ ctx context.Context ,
389+ repoStore database.RepoStore ,
390+ svc CodeNavService ,
391+ operations * operations ,
392+ rawID graphql.ID ,
393+ ) (resolverstubs.CodeGraphDataResolver , error ) {
394+ var id CodeGraphDataID
395+ if err := relay .UnmarshalSpec (rawID , & id ); err != nil {
396+ return nil , errors .Wrap (err , "malformed ID" )
397+ }
398+ repos , err := repoStore .GetByIDs (ctx , id .RepoID )
399+ if err != nil {
400+ return nil , errors .Wrap (err , "repo for CodeGraphData value no longer exists" )
401+ }
402+ opts := resolverstubs.CodeGraphDataOpts {
403+ Args : id .Args ,
404+ Repo : repos [0 ],
405+ Commit : id .Commit ,
406+ Path : id .Path ,
407+ }
408+ return & codeGraphDataResolver {
409+ sync.Once {},
410+ /*document*/ nil ,
411+ /*documentRetrievalError*/ nil ,
412+ svc ,
413+ id .UploadData ,
414+ & opts ,
415+ id .CodeGraphDataProvenance ,
416+ operations ,
417+ }, nil
418+ }
419+
347420func (c * codeGraphDataResolver ) tryRetrieveDocument (ctx context.Context ) (* scip.Document , error ) {
348421 // NOTE(id: scip-doc-optimization): In the case of pagination, if we retrieve the document ID
349422 // from the database, we can avoid performing a JOIN between codeintel_scip_document_lookup
350423 // and codeintel_scip_documents
351424 c .retrievedDocument .Do (func () {
352- c .document , c .documentRetrievalError = c .svc .SCIPDocument (ctx , c .upload .ID , c .opts .Path )
425+ c .document , c .documentRetrievalError = c .svc .SCIPDocument (ctx , c .upload .UploadID , c .opts .Path )
353426 })
354427 return c .document , c .documentRetrievalError
355428}
356429
430+ func (c * codeGraphDataResolver ) ID () graphql.ID {
431+ dataID := CodeGraphDataID {
432+ c .upload ,
433+ c .opts .Args ,
434+ c .opts .Repo .ID ,
435+ c .opts .Commit ,
436+ c .opts .Path ,
437+ c .provenance ,
438+ }
439+ return relay .MarshalID (resolverstubs .CodeGraphDataIDKind , dataID )
440+ }
441+
357442func (c * codeGraphDataResolver ) Provenance (_ context.Context ) (resolverstubs.CodeGraphDataProvenance , error ) {
358443 return c .provenance , nil
359444}
0 commit comments