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 ctx := e.Request().Context()
18
19 repo := e.QueryParam("repo")
20 collection := e.QueryParam("collection")
21 rkey := e.QueryParam("rkey")
22 cidstr := e.QueryParam("cid")
23
24 params := []any{repo, collection, rkey}
25 cidquery := ""
26
27 if cidstr != "" {
28 c, err := syntax.ParseCID(cidstr)
29 if err != nil {
30 return err
31 }
32 params = append(params, c.String())
33 cidquery = " AND cid = ?"
34 }
35
36 var record models.Record
37 if err := s.db.Raw(ctx, "SELECT * FROM records WHERE did = ? AND nsid = ? AND rkey = ?"+cidquery, nil, params...).Scan(&record).Error; err != nil {
38 // TODO: handle error nicely
39 return err
40 }
41
42 val, err := atdata.UnmarshalCBOR(record.Value)
43 if err != nil {
44 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?
45 }
46
47 return e.JSON(200, ComAtprotoRepoGetRecordResponse{
48 Uri: "at://" + record.Did + "/" + record.Nsid + "/" + record.Rkey,
49 Cid: record.Cid,
50 Value: val,
51 })
52}