A community based topic aggregation platform built on atproto
1package carstore 2 3import ( 4 "context" 5 "fmt" 6 "io" 7 8 "github.com/bluesky-social/indigo/carstore" 9 "github.com/bluesky-social/indigo/models" 10 "github.com/ipfs/go-cid" 11 "gorm.io/gorm" 12) 13 14// CarStore wraps Indigo's carstore for managing ATProto repository CAR files 15type CarStore struct { 16 cs carstore.CarStore 17} 18 19// NewCarStore creates a new CarStore instance using Indigo's implementation 20func NewCarStore(db *gorm.DB, carDirs []string) (*CarStore, error) { 21 // Initialize Indigo's carstore 22 cs, err := carstore.NewCarStore(db, carDirs) 23 if err != nil { 24 return nil, fmt.Errorf("initializing carstore: %w", err) 25 } 26 27 return &CarStore{ 28 cs: cs, 29 }, nil 30} 31 32// ImportSlice imports a CAR file slice for a user 33func (c *CarStore) ImportSlice(ctx context.Context, uid models.Uid, since *string, carData []byte) (cid.Cid, error) { 34 rootCid, _, err := c.cs.ImportSlice(ctx, uid, since, carData) 35 if err != nil { 36 return cid.Undef, fmt.Errorf("importing CAR slice for UID %d: %w", uid, err) 37 } 38 return rootCid, nil 39} 40 41// ReadUserCar reads a user's repository CAR file 42func (c *CarStore) ReadUserCar(ctx context.Context, uid models.Uid, sinceRev string, incremental bool, w io.Writer) error { 43 if err := c.cs.ReadUserCar(ctx, uid, sinceRev, incremental, w); err != nil { 44 return fmt.Errorf("reading user CAR for UID %d: %w", uid, err) 45 } 46 return nil 47} 48 49// GetUserRepoHead gets the latest repository head CID for a user 50func (c *CarStore) GetUserRepoHead(ctx context.Context, uid models.Uid) (cid.Cid, error) { 51 head, err := c.cs.GetUserRepoHead(ctx, uid) 52 if err != nil { 53 return cid.Undef, fmt.Errorf("getting repo head for UID %d: %w", uid, err) 54 } 55 return head, nil 56} 57 58// CompactUserShards performs garbage collection and compaction for a user's data 59func (c *CarStore) CompactUserShards(ctx context.Context, uid models.Uid, aggressive bool) error { 60 _, err := c.cs.CompactUserShards(ctx, uid, aggressive) 61 if err != nil { 62 return fmt.Errorf("compacting shards for UID %d: %w", uid, err) 63 } 64 return nil 65} 66 67// WipeUserData removes all data for a user 68func (c *CarStore) WipeUserData(ctx context.Context, uid models.Uid) error { 69 if err := c.cs.WipeUserData(ctx, uid); err != nil { 70 return fmt.Errorf("wiping data for UID %d: %w", uid, err) 71 } 72 return nil 73} 74 75// NewDeltaSession creates a new session for writing deltas 76func (c *CarStore) NewDeltaSession(ctx context.Context, uid models.Uid, since *string) (*carstore.DeltaSession, error) { 77 session, err := c.cs.NewDeltaSession(ctx, uid, since) 78 if err != nil { 79 return nil, fmt.Errorf("creating delta session for UID %d: %w", uid, err) 80 } 81 return session, nil 82} 83 84// ReadOnlySession creates a read-only session for reading user data 85func (c *CarStore) ReadOnlySession(uid models.Uid) (*carstore.DeltaSession, error) { 86 session, err := c.cs.ReadOnlySession(uid) 87 if err != nil { 88 return nil, fmt.Errorf("creating read-only session for UID %d: %w", uid, err) 89 } 90 return session, nil 91} 92 93// Stat returns statistics about the carstore 94func (c *CarStore) Stat(ctx context.Context, uid models.Uid) ([]carstore.UserStat, error) { 95 stats, err := c.cs.Stat(ctx, uid) 96 if err != nil { 97 return nil, fmt.Errorf("getting stats for UID %d: %w", uid, err) 98 } 99 return stats, nil 100}