1
0
Fork 0
mirror of https://github.com/diamondburned/arikawa.git synced 2025-09-04 12:47:54 +00:00
arikawa/state/store/kvstore/kvdriver/basic.go
diamondburned ba5ee814a8
WIP ifaces
2021-11-16 19:38:42 -08:00

81 lines
2.4 KiB
Go

package kvdriver
import "strings"
// BasicDatabase defines a flat key-value database API. It is useful for
// key-value databases that don't support nesting, such as BadgerDB. Most users
// should use WrapBasicDatabase to wrap the BasicDatabase and create a full
// Database.
type BasicDatabase interface {
// Get works the same as Database.
Get(key string, v interface{}) error
// Set works the same as Database.
Set(key string, v interface{}) error
// Each iterates over each key. The database must allow calling Get inside
// the fn callback.
Each(fn func(k string) error) error
// EachIsOrdered works the same as Database.
EachIsOrdered() bool
}
type wrappedBasicDatabase struct {
BasicDatabase
// Delimiter is the default delimiter byte to use. The given keys will be
// sanitized of this delimiter. The default is a null byte.
delimiter string
// state
prefix string
}
var _ Database = (*wrappedBasicDatabase)(nil)
// WrapBasicDatabase wraps the given basic database to provide an emulated
// nested database. If no delimiter is given, then a single null byte is used.
func WrapBasicDatabase(basic BasicDatabase, delimiter ...byte) Database {
return wrapBasicDatabase(basic, delimiter)
}
func wrapBasicDatabase(basic BasicDatabase, delimiter []byte) wrappedBasicDatabase {
if len(delimiter) == 0 {
delimiter = []byte{0}
}
return wrappedBasicDatabase{
BasicDatabase: basic,
delimiter: string(delimiter),
}
}
func (b wrappedBasicDatabase) EachIsOrdered() bool {
return b.BasicDatabase.EachIsOrdered()
}
// Bucket returns a copy of wrappedBasicDatabase with a new prefix.
func (b wrappedBasicDatabase) Bucket(keys ...string) (Database, error) {
b.prefix += strings.Join(keys, b.delimiter) + b.delimiter
return b, nil
}
// Get gets the given key into v.
func (b wrappedBasicDatabase) Get(key string, v interface{}) error {
return b.BasicDatabase.Get(b.prefix+key, v)
}
// Sets sets the given key into v.
func (b wrappedBasicDatabase) Set(key string, v interface{}) error {
return b.BasicDatabase.Set(b.prefix+key, v)
}
// Each wraps around the BasicDatabase by using its key-only Each API.
func (b wrappedBasicDatabase) Each(tmp interface{}, fn func(k string) error) error {
return b.BasicDatabase.Each(func(k string) error {
key := strings.TrimPrefix(k, b.prefix)
if strings.Contains(key, b.delimiter) {
// Skip, since is nested bucket.
return nil
}
return b.BasicDatabase.Get(k, tmp)
})
}