This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / spindle / db / repos.go
3.0 kB 128 lines
1package db 2 3import ( 4 "database/sql" 5 6 "github.com/bluesky-social/indigo/atproto/syntax" 7) 8 9type Repo struct { 10 Knot string 11 Owner syntax.DID 12 Rkey syntax.RecordKey 13 RepoDid syntax.DID 14 CreatedAt string 15} 16 17func (d *DB) AddRepo(repo Repo) error { 18 var createdAt sql.NullString 19 if repo.CreatedAt != "" { 20 createdAt = sql.NullString{String: repo.CreatedAt, Valid: true} 21 } 22 _, err := d.Exec( 23 `insert into repos (knot, owner, rkey, repo_did, created_at) 24 values (?, ?, ?, ?, ?) 25 on conflict(owner, rkey) do update set 26 knot = excluded.knot, 27 repo_did = excluded.repo_did, 28 created_at = coalesce(excluded.created_at, repos.created_at)`, 29 repo.Knot, repo.Owner.String(), repo.Rkey.String(), repo.RepoDid.String(), createdAt, 30 ) 31 return err 32} 33 34func (d *DB) CollapseRepoSiblings(owner, repoDid syntax.DID) (int64, error) { 35 res, err := d.Exec( 36 `delete from repos 37 where owner = ? 38 and repo_did = ? 39 and created_at is not null 40 and created_at < ( 41 select max(created_at) from repos 42 where owner = ? and repo_did = ? and created_at is not null 43 )`, 44 owner.String(), repoDid.String(), owner.String(), repoDid.String(), 45 ) 46 if err != nil { 47 return 0, err 48 } 49 return res.RowsAffected() 50} 51 52func (d *DB) Knots() ([]string, error) { 53 rows, err := d.Query(`select distinct knot from repos`) 54 if err != nil { 55 return nil, err 56 } 57 defer rows.Close() 58 59 var knots []string 60 for rows.Next() { 61 var knot string 62 if err := rows.Scan(&knot); err != nil { 63 return nil, err 64 } 65 knots = append(knots, knot) 66 } 67 68 if err := rows.Err(); err != nil { 69 return nil, err 70 } 71 72 return knots, nil 73} 74 75func scanRepo(row interface{ Scan(...any) error }) (*Repo, error) { 76 var knot, owner, rkey, repoDid string 77 if err := row.Scan(&knot, &owner, &rkey, &repoDid); err != nil { 78 return nil, err 79 } 80 return &Repo{ 81 Knot: knot, 82 Owner: syntax.DID(owner), 83 Rkey: syntax.RecordKey(rkey), 84 RepoDid: syntax.DID(repoDid), 85 }, nil 86} 87 88func (d *DB) GetRepoByDid(repoDid syntax.DID) (*Repo, error) { 89 return scanRepo(d.QueryRow( 90 `select knot, owner, rkey, coalesce(repo_did, '') from repos where repo_did = ?`, 91 repoDid.String(), 92 )) 93} 94 95func (d *DB) GetRepoByOwnerRkey(owner syntax.DID, rkey syntax.RecordKey) (*Repo, error) { 96 return scanRepo(d.QueryRow( 97 `select knot, owner, rkey, coalesce(repo_did, '') from repos where owner = ? and rkey = ?`, 98 owner.String(), rkey.String(), 99 )) 100} 101 102func (d *DB) AllRepos() ([]Repo, error) { 103 rows, err := d.Query(`select knot, owner, rkey, coalesce(repo_did, '') from repos`) 104 if err != nil { 105 return nil, err 106 } 107 defer rows.Close() 108 109 var repos []Repo 110 for rows.Next() { 111 r, err := scanRepo(rows) 112 if err != nil { 113 return nil, err 114 } 115 repos = append(repos, *r) 116 } 117 118 if err := rows.Err(); err != nil { 119 return nil, err 120 } 121 122 return repos, nil 123} 124 125func (d *DB) DeleteRepoByOwnerRkey(owner syntax.DID, rkey syntax.RecordKey) error { 126 _, err := d.Exec(`delete from repos where owner = ? and rkey = ?`, owner.String(), rkey.String()) 127 return err 128}