moby--moby/libnetwork/datastore/datastore.go

112 lines
2.8 KiB
Go
Raw Normal View History

package datastore
import (
"errors"
"strings"
"github.com/docker/swarm/pkg/store"
)
//DataStore exported
type DataStore interface {
// PutObject adds a new Record based on an object into the datastore
PutObject(kvObject KV) error
// PutObjectAtomic provides an atomic add and update operation for a Record
PutObjectAtomic(kvObject KV) error
// KVStore returns access to the KV Store
KVStore() store.Store
}
type datastore struct {
store store.Store
config *StoreConfiguration
}
//StoreConfiguration exported
type StoreConfiguration struct {
Addrs []string
Provider string
}
//KV Key Value interface used by objects to be part of the DataStore
type KV interface {
Key() []string
Value() []byte
Index() uint64
SetIndex(uint64)
}
//Key provides convenient method to create a Key
func Key(key ...string) string {
keychain := []string{"docker", "libnetwork"}
keychain = append(keychain, key...)
str := strings.Join(keychain, "/")
return str + "/"
}
var errNewDatastore = errors.New("Error creating new Datastore")
var errInvalidConfiguration = errors.New("Invalid Configuration passed to Datastore")
var errInvalidAtomicRequest = errors.New("Invalid Atomic Request")
// newClient used to connect to KV Store
func newClient(kv string, addrs []string) (DataStore, error) {
store, err := store.CreateStore(kv, addrs, store.Config{})
if err != nil {
return nil, err
}
ds := &datastore{store: store}
return ds, nil
}
// NewDataStore creates a new instance of LibKV data store
func NewDataStore(config *StoreConfiguration) (DataStore, error) {
if config == nil {
return nil, errInvalidConfiguration
}
return newClient(config.Provider, config.Addrs)
}
func (ds *datastore) KVStore() store.Store {
return ds.store
}
// PutObjectAtomic adds a new Record based on an object into the datastore
func (ds *datastore) PutObjectAtomic(kvObject KV) error {
if kvObject == nil {
return errors.New("kvObject is nil")
}
kvObjValue := kvObject.Value()
if kvObjValue == nil {
return errInvalidAtomicRequest
}
_, err := ds.store.AtomicPut(Key(kvObject.Key()...), []byte{}, kvObjValue, kvObject.Index())
if err != nil {
return err
}
_, index, err := ds.store.Get(Key(kvObject.Key()...))
if err != nil {
return err
}
kvObject.SetIndex(index)
return nil
}
// PutObject adds a new Record based on an object into the datastore
func (ds *datastore) PutObject(kvObject KV) error {
if kvObject == nil {
return errors.New("kvObject is nil")
}
return ds.putObjectWithKey(kvObject, kvObject.Key()...)
}
func (ds *datastore) putObjectWithKey(kvObject KV, key ...string) error {
kvObjValue := kvObject.Value()
if kvObjValue == nil {
return errors.New("Object must provide marshalled data for key : " + Key(kvObject.Key()...))
}
return ds.store.Put(Key(key...), kvObjValue)
}