1
0
Fork 0
mirror of https://git.sr.ht/~ashkeel/strimertul synced 2024-09-18 01:50:50 +00:00
strimertul/database/driver.pebble.go

100 lines
2.3 KiB
Go
Raw Normal View History

2022-11-30 18:15:47 +00:00
package database
2022-02-08 14:13:45 +00:00
import (
"fmt"
"io"
"os"
"path/filepath"
"go.uber.org/zap"
2022-02-08 14:13:45 +00:00
"github.com/cockroachdb/pebble"
kv "github.com/strimertul/kilovolt/v9"
2022-02-08 14:13:45 +00:00
pebble_driver "github.com/strimertul/kv-pebble"
)
type PebbleDatabase struct {
2022-11-30 18:15:47 +00:00
db *pebble.DB
hub *kv.Hub
logger *zap.Logger
}
// NewPebble creates a new database driver instance with an underlying Pebble database
2022-11-30 18:15:47 +00:00
func NewPebble(directory string, logger *zap.Logger) (*PebbleDatabase, error) {
2022-11-16 11:23:54 +00:00
db, err := pebble.Open(directory, &pebble.Options{})
if err != nil {
return nil, fmt.Errorf("could not open DB: %w", err)
2022-11-16 11:23:54 +00:00
}
2022-02-08 14:13:45 +00:00
// Create file for autodetect
err = os.WriteFile(filepath.Join(directory, "stul-driver"), []byte("pebble"), 0o644)
2022-11-16 11:23:54 +00:00
if err != nil {
return nil, fmt.Errorf("could not write driver file: %w", err)
2022-02-08 14:13:45 +00:00
}
p := &PebbleDatabase{
2022-11-30 18:15:47 +00:00
db: db,
hub: nil,
logger: logger,
}
2022-02-08 14:13:45 +00:00
return p, nil
2022-02-08 14:13:45 +00:00
}
func (p *PebbleDatabase) Hub() *kv.Hub {
if p.hub == nil {
2022-11-30 18:15:47 +00:00
p.hub, _ = kv.NewHub(pebble_driver.NewPebbleBackend(p.db, true), kv.HubOptions{}, p.logger)
2022-11-16 11:23:54 +00:00
}
return p.hub
}
2022-11-16 11:23:54 +00:00
func (p *PebbleDatabase) Close() error {
err := p.db.Close()
2022-11-16 11:23:54 +00:00
if err != nil {
return fmt.Errorf("Could not close database: %w", err)
2022-11-16 11:23:54 +00:00
}
return nil
2022-02-08 14:13:45 +00:00
}
func (p *PebbleDatabase) Import(entries map[string]string) error {
batch := p.db.NewBatch()
for key, value := range entries {
err := batch.Set([]byte(key), []byte(value), &pebble.WriteOptions{})
if err != nil {
return err
}
2022-02-08 14:13:45 +00:00
}
return batch.Commit(&pebble.WriteOptions{})
2022-02-08 14:13:45 +00:00
}
func (p *PebbleDatabase) Export(file io.Writer) error {
return p.Backup(file)
}
2022-11-16 11:23:54 +00:00
func (p *PebbleDatabase) Restore(file io.Reader) error {
2022-02-08 14:13:45 +00:00
in := make(map[string]string)
err := json.NewDecoder(file).Decode(&in)
2022-02-08 14:13:45 +00:00
if err != nil {
2022-11-16 11:23:54 +00:00
return fmt.Errorf("Could not decode backup: %w", err)
2022-02-08 14:13:45 +00:00
}
b := p.db.NewBatch()
2022-02-08 14:13:45 +00:00
for k, v := range in {
err = b.Set([]byte(k), []byte(v), nil)
if err != nil {
2022-11-16 11:23:54 +00:00
return fmt.Errorf("Could not set key %s: %w", k, err)
2022-02-08 14:13:45 +00:00
}
}
return b.Commit(&pebble.WriteOptions{Sync: true})
2022-11-16 11:23:54 +00:00
}
func (p *PebbleDatabase) Backup(file io.Writer) error {
iter := p.db.NewSnapshot().NewIter(&pebble.IterOptions{})
2022-11-16 11:23:54 +00:00
out := make(map[string]string)
for iter.First(); iter.Valid(); iter.Next() {
out[string(iter.Key())] = string(iter.Value())
}
return json.NewEncoder(file).Encode(out)
2022-02-08 14:13:45 +00:00
}