1package server
2
3import (
4 "github.com/bluesky-social/indigo/atproto/atdata"
5 "github.com/bluesky-social/indigo/atproto/syntax"
6 "github.com/haileyok/cocoon/models"
7 "github.com/labstack/echo/v4"
8)
9
10type ComAtprotoRepoGetRecordResponse struct {
11 Uri string `json:"uri"`
12 Cid string `json:"cid"`
13 Value map[string]any `json:"value"`
14}
15
16func (s *Server) handleRepoGetRecord(e echo.Context) error {
17 repo := e.QueryParam("repo")
18 collection := e.QueryParam("collection")
19 rkey := e.QueryParam("rkey")
20 cidstr := e.QueryParam("cid")
21
22 params := []any{repo, collection, rkey}
23 cidquery := ""
24
25 if cidstr != "" {
26 c, err := syntax.ParseCID(cidstr)
27 if err != nil {
28 return err
29 }
30 params = append(params, c.String())
31 cidquery = " AND cid = ?"
32 }
33
34 var record models.Record
35 if err := s.db.Raw("SELECT * FROM records WHERE did = ? AND nsid = ? AND rkey = ?"+cidquery, nil, params...).Scan(&record).Error; err != nil {
36 // TODO: handle error nicely
37 return err
38 }
39
40 val, err := atdata.UnmarshalCBOR(record.Value)
41 if err != nil {
42 return s.handleProxy(e) // TODO: this should be getting handled like...if we don't find it in the db. why doesn't it throw error up there?
43 }
44
45 return e.JSON(200, ComAtprotoRepoGetRecordResponse{
46 Uri: "at://" + record.Did + "/" + record.Nsid + "/" + record.Rkey,
47 Cid: record.Cid,
48 Value: val,
49 })
50}