1package server
2
3import (
4 "bytes"
5
6 "github.com/bluesky-social/indigo/carstore"
7 "github.com/haileyok/cocoon/internal/helpers"
8 "github.com/haileyok/cocoon/models"
9 "github.com/ipfs/go-cid"
10 cbor "github.com/ipfs/go-ipld-cbor"
11 "github.com/ipld/go-car"
12 "github.com/labstack/echo/v4"
13)
14
15func (s *Server) handleSyncGetRecord(e echo.Context) error {
16 ctx := e.Request().Context()
17 logger := s.logger.With("name", "handleSyncGetRecord")
18
19 did := e.QueryParam("did")
20 collection := e.QueryParam("collection")
21 rkey := e.QueryParam("rkey")
22
23 var urepo models.Repo
24 if err := s.db.Raw(ctx, "SELECT * FROM repos WHERE did = ?", nil, did).Scan(&urepo).Error; err != nil {
25 logger.Error("error getting repo", "error", err)
26 return helpers.ServerError(e, nil)
27 }
28
29 root, blocks, err := s.repoman.getRecordProof(ctx, urepo, collection, rkey)
30 if err != nil {
31 return err
32 }
33
34 buf := new(bytes.Buffer)
35
36 hb, err := cbor.DumpObject(&car.CarHeader{
37 Roots: []cid.Cid{root},
38 Version: 1,
39 })
40
41 if _, err := carstore.LdWrite(buf, hb); err != nil {
42 logger.Error("error writing to car", "error", err)
43 return helpers.ServerError(e, nil)
44 }
45
46 for _, blk := range blocks {
47 if _, err := carstore.LdWrite(buf, blk.Cid().Bytes(), blk.RawData()); err != nil {
48 logger.Error("error writing to car", "error", err)
49 return helpers.ServerError(e, nil)
50 }
51 }
52
53 return e.Stream(200, "application/vnd.ipld.car", bytes.NewReader(buf.Bytes()))
54}