diff --git a/store/command_factory.go b/store/command_factory.go index 99f2affed..eeab8803b 100644 --- a/store/command_factory.go +++ b/store/command_factory.go @@ -21,6 +21,7 @@ type CommandFactory interface { CreateUpdateCommand(key string, value string, expireTime time.Time) raft.Command CreateDeleteCommand(key string, recursive bool) raft.Command CreateCompareAndSwapCommand(key string, value string, prevValue string, prevIndex uint64, expireTime time.Time) raft.Command + CreateCompareAndDeleteCommand(key string, prevValue string, prevIndex uint64) raft.Command CreateSyncCommand(now time.Time) raft.Command } diff --git a/store/event.go b/store/event.go index f7a846717..aca446393 100644 --- a/store/event.go +++ b/store/event.go @@ -5,14 +5,14 @@ import ( ) const ( - Get = "get" - Create = "create" - Set = "set" - Update = "update" - Delete = "delete" - CompareAndSwap = "compareAndSwap" + Get = "get" + Create = "create" + Set = "set" + Update = "update" + Delete = "delete" + CompareAndSwap = "compareAndSwap" CompareAndDelete = "compareAndDelete" - Expire = "expire" + Expire = "expire" ) type Event struct { diff --git a/store/store.go b/store/store.go index eb88f5c82..bda244813 100644 --- a/store/store.go +++ b/store/store.go @@ -50,6 +50,7 @@ type Store interface { CompareAndSwap(nodePath string, prevValue string, prevIndex uint64, value string, expireTime time.Time) (*Event, error) Delete(nodePath string, recursive bool) (*Event, error) + CompareAndDelete(nodePath string, prevValue string, prevIndex uint64) (*Event, error) Watch(prefix string, recursive bool, sinceIndex uint64) (<-chan *Event, error) Save() ([]byte, error) Recovery(state []byte) error diff --git a/store/v2/command_factory.go b/store/v2/command_factory.go index 70b03cded..6f3707929 100644 --- a/store/v2/command_factory.go +++ b/store/v2/command_factory.go @@ -72,6 +72,15 @@ func (f *CommandFactory) CreateCompareAndSwapCommand(key string, value string, p } } +// CreateCompareAndDeleteCommand creates a version 2 command to conditionally delete a key from the store. +func (f *CommandFactory) CreateCompareAndDeleteCommand(key string, prevValue string, prevIndex uint64) raft.Command { + return &CompareAndDeleteCommand{ + Key: key, + PrevValue: prevValue, + PrevIndex: prevIndex, + } +} + func (f *CommandFactory) CreateSyncCommand(now time.Time) raft.Command { return &SyncCommand{ Time: time.Now(), diff --git a/store/v2/compare_and_delete_command.go b/store/v2/compare_and_delete_command.go new file mode 100644 index 000000000..8a518c5a6 --- /dev/null +++ b/store/v2/compare_and_delete_command.go @@ -0,0 +1,37 @@ +package v2 + +import ( + "github.com/coreos/etcd/log" + "github.com/coreos/etcd/store" + "github.com/coreos/raft" +) + +func init() { + raft.RegisterCommand(&CompareAndDeleteCommand{}) +} + +// The CompareAndDelete performs a conditional delete on a key in the store. +type CompareAndDeleteCommand struct { + Key string `json:"key"` + PrevValue string `json:"prevValue"` + PrevIndex uint64 `json:"prevIndex"` +} + +// The name of the compareAndDelete command in the log +func (c *CompareAndDeleteCommand) CommandName() string { + return "etcd:compareAndDelete" +} + +// Set the key-value pair if the current value of the key equals to the given prevValue +func (c *CompareAndDeleteCommand) Apply(server raft.Server) (interface{}, error) { + s, _ := server.StateMachine().(store.Store) + + e, err := s.CompareAndDelete(c.Key, c.PrevValue, c.PrevIndex) + + if err != nil { + log.Debug(err) + return nil, err + } + + return e, nil +}