etcdb/hex-db.go
2022-12-05 11:12:52 +01:00

92 lines
1.7 KiB
Go

package etcdb
import (
"encoding/hex"
"fmt"
)
type HexDB struct {
WrappedDB DB
}
var _ DB = HexDB{}
func (h HexDB) Get(key string) (value []byte, ok bool, err error) {
encodedValue, ok, err := h.WrappedDB.Get(key)
if !ok || err != nil {
return
}
value = make([]byte, hex.DecodedLen(len(encodedValue)))
_, err = hex.Decode(value, encodedValue)
if err != nil {
err = fmt.Errorf("invalid hex-encoded value: %w", err)
ok = false
}
return
}
func (h HexDB) Put(key string, value []byte) (err error) {
encodedValue := make([]byte, hex.EncodedLen(len(value)))
hex.Encode(encodedValue, value)
return h.WrappedDB.Put(key, encodedValue)
}
func (h HexDB) Del(key string) error {
return h.WrappedDB.Del(key)
}
func (h HexDB) ForEach(callback func(key string, value []byte) (cont bool)) (err error) {
forEachErr := h.WrappedDB.ForEach(func(key string, encodedValue []byte) (cont bool) {
value := make([]byte, hex.DecodedLen(len(encodedValue)))
_, err = hex.Decode(value, encodedValue)
if err != nil {
err = fmt.Errorf("invalid hex-encoded value under %q: %w", key, err)
return false
}
return callback(key, value)
})
if err == nil && forEachErr != nil {
err = forEachErr
}
return
}
func (h HexDB) Watch(rev int64) <-chan WatchEvent {
ch := make(chan WatchEvent, 1)
go func() {
defer close(ch)
inCh := h.WrappedDB.Watch(rev)
for evt := range inCh {
if len(evt.Value) == 0 {
ch <- evt
continue
}
value := make([]byte, hex.DecodedLen(len(evt.Value)))
_, err := hex.Decode(value, evt.Value)
if err != nil {
ch <- WatchEvent{
Key: evt.Key,
Err: fmt.Errorf("invalid hex-encoded value: %w", err),
}
continue
}
evt.Value = value
ch <- evt
}
}()
return ch
}