eth-tracker/internal/db/db.go

103 lines
1.6 KiB
Go

package db
import (
"encoding/binary"
"fmt"
"log/slog"
bolt "go.etcd.io/bbolt"
)
type (
DBOpts struct {
Logg *slog.Logger
}
DB struct {
db *bolt.DB
logg *slog.Logger
}
)
const (
dbFolderName = "celo_tracker_blocks_db"
upperBoundKey = "upper"
lowerBoundKey = "lower"
)
var (
sortableOrder = binary.BigEndian
)
func New(o DBOpts) (*DB, error) {
db, err := bolt.Open(dbFolderName, 0600, nil)
if err != nil {
return nil, err
}
db.Update(func(tx *bolt.Tx) error {
_, err := tx.CreateBucketIfNotExists([]byte("blocks"))
if err != nil {
return fmt.Errorf("create bucket: %s", err)
}
return nil
})
return &DB{
db: db,
logg: o.Logg,
}, nil
}
func (d *DB) Close() error {
return d.db.Close()
}
func (d *DB) get(k string) ([]byte, error) {
var v []byte
err := d.db.View(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte("blocks"))
v = b.Get([]byte(k))
return nil
})
if err != nil {
return nil, err
}
return v, nil
}
func (d *DB) setUint64(k string, v uint64) error {
err := d.db.Update(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte("blocks"))
return b.Put([]byte(k), marshalUint64(v))
})
if err != nil {
return err
}
return nil
}
func (d *DB) setUint64AsKey(v uint64) error {
err := d.db.Update(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte("blocks"))
return b.Put(marshalUint64(v), nil)
})
if err != nil {
return err
}
return nil
}
func unmarshalUint64(b []byte) uint64 {
return sortableOrder.Uint64(b)
}
func marshalUint64(v uint64) []byte {
b := make([]byte, 8)
sortableOrder.PutUint64(b, v)
return b
}