this repo has no description
1package db 2 3import ( 4 "database/sql" 5 "fmt" 6 "strings" 7 8 "github.com/bluesky-social/indigo/atproto/syntax" 9 "tangled.org/core/api/tangled" 10 "tangled.org/core/appview/models" 11) 12 13// FindReferences resolves refLinks to Issue/PR/IssueComment/PullComment ATURIs. 14// It will ignore missing refLinks. 15func FindReferences(e Execer, refLinks []models.ReferenceLink) ([]syntax.ATURI, error) { 16 var ( 17 issueRefs []models.ReferenceLink 18 pullRefs []models.ReferenceLink 19 ) 20 for _, ref := range refLinks { 21 switch ref.Kind { 22 case models.RefKindIssue: 23 issueRefs = append(issueRefs, ref) 24 case models.RefKindPull: 25 pullRefs = append(pullRefs, ref) 26 } 27 } 28 issueUris, err := findIssueReferences(e, issueRefs) 29 if err != nil { 30 return nil, err 31 } 32 pullUris, err := findPullReferences(e, pullRefs) 33 if err != nil { 34 return nil, err 35 } 36 37 return append(issueUris, pullUris...), nil 38} 39 40func findIssueReferences(e Execer, refLinks []models.ReferenceLink) ([]syntax.ATURI, error) { 41 if len(refLinks) == 0 { 42 return nil, nil 43 } 44 vals := make([]string, len(refLinks)) 45 args := make([]any, 0, len(refLinks)*4) 46 for i, ref := range refLinks { 47 vals[i] = "(?, ?, ?, ?)" 48 args = append(args, ref.Handle, ref.Repo, ref.SubjectId, ref.CommentId) 49 } 50 query := fmt.Sprintf( 51 `with input(owner_did, name, issue_id, comment_id) as ( 52 values %s 53 ) 54 select 55 i.did, i.rkey, 56 c.did, c.rkey 57 from input inp 58 join repos r 59 on r.did = inp.owner_did 60 and r.name = inp.name 61 join issues i 62 on i.repo_at = r.at_uri 63 and i.issue_id = inp.issue_id 64 left join issue_comments c 65 on inp.comment_id is not null 66 and c.issue_at = i.at_uri 67 and c.id = inp.comment_id 68 `, 69 strings.Join(vals, ","), 70 ) 71 rows, err := e.Query(query, args...) 72 if err != nil { 73 return nil, err 74 } 75 defer rows.Close() 76 77 var uris []syntax.ATURI 78 79 for rows.Next() { 80 // Scan rows 81 var issueOwner, issueRkey string 82 var commentOwner, commentRkey sql.NullString 83 var uri syntax.ATURI 84 if err := rows.Scan(&issueOwner, &issueRkey, &commentOwner, &commentRkey); err != nil { 85 return nil, err 86 } 87 if commentOwner.Valid && commentRkey.Valid { 88 uri = syntax.ATURI(fmt.Sprintf( 89 "at://%s/%s/%s", 90 commentOwner.String, 91 tangled.RepoIssueCommentNSID, 92 commentRkey.String, 93 )) 94 } else { 95 uri = syntax.ATURI(fmt.Sprintf( 96 "at://%s/%s/%s", 97 issueOwner, 98 tangled.RepoIssueNSID, 99 issueRkey, 100 )) 101 } 102 uris = append(uris, uri) 103 } 104 return uris, nil 105} 106 107func findPullReferences(e Execer, refLinks []models.ReferenceLink) ([]syntax.ATURI, error) { 108 if len(refLinks) == 0 { 109 return nil, nil 110 } 111 vals := make([]string, len(refLinks)) 112 args := make([]any, 0, len(refLinks)*4) 113 for i, ref := range refLinks { 114 vals[i] = "(?, ?, ?, ?)" 115 args = append(args, ref.Handle, ref.Repo, ref.SubjectId, ref.CommentId) 116 } 117 query := fmt.Sprintf( 118 `with input(owner_did, name, pull_id, comment_id) as ( 119 values %s 120 ) 121 select 122 p.owner_did, p.rkey, 123 c.owner_did, c.rkey 124 from input inp 125 join repos r 126 on r.did = inp.owner_did 127 and r.name = inp.name 128 join pulls p 129 on p.repo_at = r.at_uri 130 and p.pull_id = inp.pull_id 131 left join pull_comments c 132 on inp.comment_id is not null 133 and c.repo_at = r.at_uri and c.pull_id = p.pull_id 134 and c.id = inp.comment_id 135 `, 136 strings.Join(vals, ","), 137 ) 138 rows, err := e.Query(query, args...) 139 if err != nil { 140 return nil, err 141 } 142 defer rows.Close() 143 144 var uris []syntax.ATURI 145 146 for rows.Next() { 147 // Scan rows 148 var pullOwner, pullRkey string 149 var commentOwner, commentRkey sql.NullString 150 var uri syntax.ATURI 151 if err := rows.Scan(&pullOwner, &pullRkey, &commentOwner, &commentRkey); err != nil { 152 return nil, err 153 } 154 if commentOwner.Valid && commentRkey.Valid { 155 uri = syntax.ATURI(fmt.Sprintf( 156 "at://%s/%s/%s", 157 commentOwner.String, 158 tangled.RepoPullCommentNSID, 159 commentRkey.String, 160 )) 161 } else { 162 uri = syntax.ATURI(fmt.Sprintf( 163 "at://%s/%s/%s", 164 pullOwner, 165 tangled.RepoPullNSID, 166 pullRkey, 167 )) 168 } 169 uris = append(uris, uri) 170 } 171 return uris, nil 172}