92 lines
1.7 KiB
Go
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
|
|
}
|