this repo has no description
1package server 2 3import ( 4 "bytes" 5 "context" 6 "io" 7 "slices" 8 "strings" 9 10 "github.com/bluesky-social/indigo/atproto/syntax" 11 "github.com/bluesky-social/indigo/repo" 12 "github.com/haileyok/cocoon/internal/helpers" 13 "github.com/haileyok/cocoon/models" 14 blocks "github.com/ipfs/go-block-format" 15 "github.com/ipfs/go-cid" 16 "github.com/ipld/go-car" 17 "github.com/labstack/echo/v4" 18) 19 20func (s *Server) handleRepoImportRepo(e echo.Context) error { 21 ctx := e.Request().Context() 22 23 urepo := e.Get("repo").(*models.RepoActor) 24 25 b, err := io.ReadAll(e.Request().Body) 26 if err != nil { 27 s.logger.Error("could not read bytes in import request", "error", err) 28 return helpers.ServerError(e, nil) 29 } 30 31 bs := s.getBlockstore(urepo.Repo.Did) 32 33 cs, err := car.NewCarReader(bytes.NewReader(b)) 34 if err != nil { 35 s.logger.Error("could not read car in import request", "error", err) 36 return helpers.ServerError(e, nil) 37 } 38 39 orderedBlocks := []blocks.Block{} 40 currBlock, err := cs.Next() 41 if err != nil { 42 s.logger.Error("could not get first block from car", "error", err) 43 return helpers.ServerError(e, nil) 44 } 45 currBlockCt := 1 46 47 for currBlock != nil { 48 s.logger.Info("someone is importing their repo", "block", currBlockCt) 49 orderedBlocks = append(orderedBlocks, currBlock) 50 next, _ := cs.Next() 51 currBlock = next 52 currBlockCt++ 53 } 54 55 slices.Reverse(orderedBlocks) 56 57 if err := bs.PutMany(context.TODO(), orderedBlocks); err != nil { 58 s.logger.Error("could not insert blocks", "error", err) 59 return helpers.ServerError(e, nil) 60 } 61 62 r, err := repo.OpenRepo(context.TODO(), bs, cs.Header.Roots[0]) 63 if err != nil { 64 s.logger.Error("could not open repo", "error", err) 65 return helpers.ServerError(e, nil) 66 } 67 68 tx := s.db.BeginDangerously(ctx) 69 70 clock := syntax.NewTIDClock(0) 71 72 if err := r.ForEach(context.TODO(), "", func(key string, cid cid.Cid) error { 73 pts := strings.Split(key, "/") 74 nsid := pts[0] 75 rkey := pts[1] 76 cidStr := cid.String() 77 b, err := bs.Get(context.TODO(), cid) 78 if err != nil { 79 s.logger.Error("record bytes don't exist in blockstore", "error", err) 80 return helpers.ServerError(e, nil) 81 } 82 83 rec := models.Record{ 84 Did: urepo.Repo.Did, 85 CreatedAt: clock.Next().String(), 86 Nsid: nsid, 87 Rkey: rkey, 88 Cid: cidStr, 89 Value: b.RawData(), 90 } 91 92 if err := tx.Save(rec).Error; err != nil { 93 return err 94 } 95 96 return nil 97 }); err != nil { 98 tx.Rollback() 99 s.logger.Error("record bytes don't exist in blockstore", "error", err) 100 return helpers.ServerError(e, nil) 101 } 102 103 tx.Commit() 104 105 root, rev, err := r.Commit(context.TODO(), urepo.SignFor) 106 if err != nil { 107 s.logger.Error("error committing", "error", err) 108 return helpers.ServerError(e, nil) 109 } 110 111 if err := s.UpdateRepo(context.TODO(), urepo.Repo.Did, root, rev); err != nil { 112 s.logger.Error("error updating repo after commit", "error", err) 113 return helpers.ServerError(e, nil) 114 } 115 116 return nil 117}