in registry/datastore/repository.go [909:1001]
func (s *repositoryStore) appendTagsDetailReferrers(ctx context.Context, r *models.Repository, tags []*models.TagDetail, artifactTypes []string) error {
if len(tags) == 0 {
return nil
}
sbjDigests := make([]string, 0, len(tags))
for _, tag := range tags {
nd, err := NewDigest(tag.Digest)
if err != nil {
return err
}
sbjDigests = append(sbjDigests, nd.HexDecode())
}
q := `SELECT
encode(m.digest, 'hex') AS digest,
COALESCE(at.media_type, cmt.media_type) AS artifact_type,
encode(ms.digest, 'hex') AS subject_digest
FROM
manifests AS m
JOIN manifests AS ms ON m.top_level_namespace_id = ms.top_level_namespace_id
AND m.subject_id = ms.id
LEFT JOIN media_types AS at ON at.id = m.artifact_media_type_id
LEFT JOIN media_types AS cmt ON cmt.id = m.configuration_media_type_id
WHERE
m.top_level_namespace_id = $1
AND m.repository_id = $2
AND m.subject_id IN (
SELECT
id
FROM
manifests
WHERE
top_level_namespace_id = $1
AND repository_id = $2
AND digest = ANY ($3))`
var rows *sql.Rows
var err error
if len(artifactTypes) > 0 {
ats, errInner := s.mediaTypeIDs(ctx, artifactTypes)
if errInner != nil {
return errInner
}
q += " AND (m.artifact_media_type_id = ANY ($4) OR m.configuration_media_type_id = ANY ($4))"
rows, err = s.db.QueryContext(ctx, q, r.NamespaceID, r.ID, sbjDigests, ats) // nolint: staticcheck // err is checked below
} else {
rows, err = s.db.QueryContext(ctx, q, r.NamespaceID, r.ID, sbjDigests)
}
if err != nil {
return err
}
defer rows.Close()
refMap := make(map[string][]models.TagReferrerDetail)
var (
dgst, sbjDgst Digest
at, sbjStr string
)
for rows.Next() {
if err = rows.Scan(&dgst, &at, &sbjDgst); err != nil {
return fmt.Errorf("scanning referrer: %w", err)
}
d, err := dgst.Parse()
if err != nil {
return err
}
sbj, err := sbjDgst.Parse()
if err != nil {
return err
}
sbjStr = sbj.String()
if refMap[sbjStr] == nil {
refMap[sbjStr] = make([]models.TagReferrerDetail, 0)
}
refMap[sbjStr] = append(refMap[sbjStr], models.TagReferrerDetail{
Digest: d.String(),
ArtifactType: at,
})
}
if err := rows.Err(); err != nil {
return fmt.Errorf("scanning referrers: %w", err)
}
for _, tag := range tags {
tag.Referrers = refMap[tag.Digest.String()]
}
return nil
}