119 lines
2.5 KiB
Go
119 lines
2.5 KiB
Go
package badger
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
"unsafe"
|
|
|
|
"git.loyso.art/frx/eway/internal/entity"
|
|
badger "github.com/dgraph-io/badger/v4"
|
|
)
|
|
|
|
var (
|
|
categorySequenceIDKey = []byte("!!cat_seq!!")
|
|
queueSequenceIDKey = []byte("!!que_seq!!")
|
|
)
|
|
|
|
type client struct {
|
|
db *badger.DB
|
|
nextCategoryIDSeq *badger.Sequence
|
|
nextQueueIDSeq *badger.Sequence
|
|
}
|
|
|
|
func NewClient(db *badger.DB) (*client, error) {
|
|
categorySeqGen, err := db.GetSequence(categorySequenceIDKey, 10)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("getting sequence for categories: %w", err)
|
|
}
|
|
queueSeqGen, err := db.GetSequence(queueSequenceIDKey, 10)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("getting sequence for queues: %w", err)
|
|
}
|
|
|
|
return &client{
|
|
db: db,
|
|
nextCategoryIDSeq: categorySeqGen,
|
|
nextQueueIDSeq: queueSeqGen,
|
|
}, nil
|
|
}
|
|
|
|
// Close closes the underlying sequences in the client. Should be called right before
|
|
// underlying *badger.DB closed.
|
|
func (c *client) Close() error {
|
|
err := c.nextCategoryIDSeq.Release()
|
|
if err != nil {
|
|
return fmt.Errorf("releasing next_category_sequence: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (c *client) Category() entity.CategoryRepository {
|
|
return newCategoryClient(c.db, c.nextCategoryIDSeq)
|
|
}
|
|
|
|
func (c *client) GoodsItem() entity.GoodsItemRepository {
|
|
return newGoodsItemClient(c.db)
|
|
}
|
|
|
|
func (c *client) QueueClient() entity.MessageQueue {
|
|
nc := c.Table("queues")
|
|
return newQueueClient(nc, c.nextQueueIDSeq)
|
|
}
|
|
|
|
func (c *client) Table(name string) namedClient {
|
|
tableBytes := unsafe.Slice(unsafe.StringData("!!"+name+"!!"), len(name)+4)
|
|
return namedClient{
|
|
table: tableBytes,
|
|
db: c.db,
|
|
}
|
|
}
|
|
|
|
type namedClient struct {
|
|
table []byte
|
|
db *badger.DB
|
|
}
|
|
|
|
type putOpt func(*badger.Entry)
|
|
|
|
func withTTL(duration time.Duration) putOpt {
|
|
return func(e *badger.Entry) {
|
|
e.WithTTL(duration)
|
|
}
|
|
}
|
|
|
|
func (c *namedClient) Put(key, value []byte, opts ...putOpt) error {
|
|
return c.db.Update(func(txn *badger.Txn) error {
|
|
tableKey := c.makeKey(key)
|
|
entry := badger.NewEntry(tableKey, value)
|
|
for _, opt := range opts {
|
|
opt(entry)
|
|
}
|
|
|
|
return txn.SetEntry(entry)
|
|
})
|
|
}
|
|
|
|
func (c *namedClient) Get(key []byte) ([]byte, error) {
|
|
var out []byte
|
|
err := c.db.View(func(txn *badger.Txn) error {
|
|
item, err := txn.Get(c.makeKey(key))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
out = make([]byte, item.ValueSize())
|
|
out, err = item.ValueCopy(out)
|
|
return err
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return out, nil
|
|
}
|
|
|
|
func (c *namedClient) makeKey(key []byte) (out []byte) {
|
|
return append(c.table, key...)
|
|
}
|