mirror of
https://github.com/garethgeorge/backrest.git
synced 2026-05-12 07:41:27 +00:00
73 lines
1.6 KiB
Go
73 lines
1.6 KiB
Go
package cache
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
v1 "github.com/garethgeorge/backrest/gen/go/v1"
|
|
"github.com/garethgeorge/backrest/internal/oplog/serializationutil"
|
|
"go.etcd.io/bbolt"
|
|
"google.golang.org/protobuf/proto"
|
|
)
|
|
|
|
var (
|
|
bucketRepoStats = []byte("repo_stats")
|
|
)
|
|
|
|
var (
|
|
ErrNotFound = errors.New("not found")
|
|
)
|
|
|
|
type Cache struct {
|
|
db *bbolt.DB
|
|
}
|
|
|
|
func NewCache(databasePath string) (*Cache, error) {
|
|
db, err := bbolt.Open(databasePath, 0600, nil)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("open database: %w", err)
|
|
}
|
|
|
|
if err := db.Update(func(tx *bbolt.Tx) error {
|
|
for _, bucket := range [][]byte{bucketRepoStats} {
|
|
_, err := tx.CreateBucketIfNotExists(bucket)
|
|
return err
|
|
}
|
|
return nil
|
|
}); err != nil {
|
|
return nil, fmt.Errorf("create bucket: %w", err)
|
|
}
|
|
|
|
return &Cache{db: db}, nil
|
|
}
|
|
|
|
func (c *Cache) Close() error {
|
|
return c.db.Close()
|
|
}
|
|
|
|
func (c *Cache) SetRepoStats(repoId string, stats *v1.RepoStats) error {
|
|
return c.db.Update(func(tx *bbolt.Tx) error {
|
|
b := tx.Bucket(bucketRepoStats)
|
|
statsBytes, err := proto.Marshal(stats)
|
|
if err != nil {
|
|
return fmt.Errorf("marshal stats: %w", err)
|
|
}
|
|
return b.Put(serializationutil.BytesToKey([]byte(repoId)), statsBytes)
|
|
})
|
|
}
|
|
|
|
func (c *Cache) GetRepoStats(repoId string) (*v1.RepoStats, error) {
|
|
var stats v1.RepoStats
|
|
if err := c.db.View(func(tx *bbolt.Tx) error {
|
|
b := tx.Bucket(bucketRepoStats)
|
|
statsBytes := b.Get(serializationutil.BytesToKey([]byte(repoId)))
|
|
if statsBytes == nil {
|
|
return ErrNotFound
|
|
}
|
|
return proto.Unmarshal(statsBytes, &stats)
|
|
}); err != nil {
|
|
return nil, err
|
|
}
|
|
return &stats, nil
|
|
}
|