179 lines
3.6 KiB
Go
179 lines
3.6 KiB
Go
package ramkv
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"sync"
|
|
"time"
|
|
|
|
"src.dualinventive.com/go/lib/kv/rediskv"
|
|
)
|
|
|
|
// ErrNotFound is returned when a value is not found
|
|
var ErrNotFound = rediskv.ErrNotFound
|
|
|
|
// Ramkv stores the values that is set or retrieved in RAM
|
|
type Ramkv struct {
|
|
lock sync.RWMutex
|
|
storage map[string]map[string]string
|
|
}
|
|
|
|
// New creates a Ram key value instance
|
|
func New() (*Ramkv, error) {
|
|
return &Ramkv{
|
|
storage: make(map[string]map[string]string),
|
|
}, nil
|
|
}
|
|
|
|
// Close closes the RAM KV
|
|
func (r *Ramkv) Close() error {
|
|
return nil
|
|
}
|
|
|
|
// Get returns the value from the requested key.
|
|
func (r *Ramkv) Get(key string) (string, error) {
|
|
r.lock.RLock()
|
|
value, found := r.storage[key]
|
|
r.lock.RUnlock()
|
|
if found && value != nil {
|
|
value, err := json.Marshal(value)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return string(value), nil
|
|
}
|
|
return "", ErrNotFound
|
|
}
|
|
|
|
// Set stores the value with the given key
|
|
func (r *Ramkv) Set(key string, value interface{}) error {
|
|
r.lock.Lock()
|
|
if r.storage[key] == nil {
|
|
r.storage[key] = make(map[string]string)
|
|
}
|
|
r.lock.Unlock()
|
|
|
|
if strValue, ok := value.(string); ok {
|
|
var jsonValue map[string]string
|
|
err := json.Unmarshal([]byte(strValue), &jsonValue)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
r.lock.Lock()
|
|
r.storage[key] = jsonValue
|
|
r.lock.Unlock()
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// SetExp stores the value with the given key with expiration, not implemented for now
|
|
func (r *Ramkv) SetExp(key string, value interface{}, expiration time.Duration) error {
|
|
return errors.New("not implemented")
|
|
}
|
|
|
|
//Exists return whether the key is existing or not
|
|
func (r *Ramkv) Exists(key string) (bool, error) {
|
|
_, ok := r.storage[key]
|
|
return ok, nil
|
|
}
|
|
|
|
// Del removes the value with the given key
|
|
func (r *Ramkv) Del(key string) (bool, error) {
|
|
r.lock.Lock()
|
|
_, ok := r.storage[key]
|
|
delete(r.storage, key)
|
|
r.lock.Unlock()
|
|
return ok, nil
|
|
}
|
|
|
|
// Keys returns a list of all keys, pattern is ignored
|
|
func (r *Ramkv) Keys(pattern string) ([]string, error) { //nolint: unparam
|
|
var keys []string
|
|
|
|
r.lock.RLock()
|
|
for k := range r.storage {
|
|
keys = append(keys, k)
|
|
}
|
|
r.lock.RUnlock()
|
|
|
|
return keys, nil
|
|
}
|
|
|
|
// HKeys returns all keys in a hash
|
|
func (r *Ramkv) HKeys(key string) ([]string, error) {
|
|
var keys []string
|
|
|
|
r.lock.RLock()
|
|
s, ok := r.storage[key]
|
|
r.lock.RUnlock()
|
|
if !ok {
|
|
return nil, ErrNotFound
|
|
}
|
|
|
|
for k := range s {
|
|
keys = append(keys, k)
|
|
}
|
|
|
|
return keys, nil
|
|
}
|
|
|
|
// HGetAll returns all key-values in a hash as a map
|
|
func (r *Ramkv) HGetAll(key string) (map[string]string, error) {
|
|
r.lock.RLock()
|
|
s, ok := r.storage[key]
|
|
r.lock.RUnlock()
|
|
if !ok {
|
|
return nil, ErrNotFound
|
|
}
|
|
return s, nil
|
|
}
|
|
|
|
// HGet retrieve the value from the given field in the given key
|
|
func (r *Ramkv) HGet(key, field string) (string, error) {
|
|
r.lock.RLock()
|
|
if r.storage[key] == nil {
|
|
r.lock.RUnlock()
|
|
return "", ErrNotFound
|
|
}
|
|
|
|
value, found := r.storage[key][field]
|
|
r.lock.RUnlock()
|
|
if found {
|
|
return value, nil
|
|
}
|
|
return "", ErrNotFound
|
|
}
|
|
|
|
// HSet sets the value in the given field in the given key
|
|
func (r *Ramkv) HSet(key, field string, value interface{}) error {
|
|
r.lock.Lock()
|
|
if r.storage[key] == nil {
|
|
r.storage[key] = make(map[string]string)
|
|
}
|
|
if s, ok := value.(string); ok {
|
|
r.storage[key][field] = s
|
|
r.lock.Unlock()
|
|
return nil
|
|
}
|
|
|
|
ret, err := json.Marshal(value)
|
|
if err != nil {
|
|
r.lock.Unlock()
|
|
return err
|
|
}
|
|
r.storage[key][field] = string(ret)
|
|
r.lock.Unlock()
|
|
return nil
|
|
}
|
|
|
|
// HDel removes the value in the given field in the given key
|
|
func (r *Ramkv) HDel(key, field string) error {
|
|
r.lock.Lock()
|
|
if r.storage[key] != nil {
|
|
delete(r.storage[key], field)
|
|
}
|
|
r.lock.Unlock()
|
|
return nil
|
|
}
|