feat(node_extern.go) add prevNode field

This commit is contained in:
Xiang Li 2014-01-01 19:50:07 +08:00
parent c49711ae2c
commit f46fdbf078
6 changed files with 69 additions and 10 deletions

View File

@ -26,7 +26,7 @@ func TestV2DeleteKey(t *testing.T) {
assert.Equal(t, resp.StatusCode, http.StatusOK) assert.Equal(t, resp.StatusCode, http.StatusOK)
body := tests.ReadBody(resp) body := tests.ReadBody(resp)
assert.Nil(t, err, "") assert.Nil(t, err, "")
assert.Equal(t, string(body), `{"action":"delete","node":{"key":"/foo/bar","modifiedIndex":3,"createdIndex":2}}`, "") assert.Equal(t, string(body), `{"action":"delete","node":{"key":"/foo/bar","modifiedIndex":3,"createdIndex":2},"prevNode":{"key":"/foo/bar","value":"XXX","modifiedIndex":2,"createdIndex":2}}`, "")
}) })
} }
@ -48,7 +48,7 @@ func TestV2DeleteEmptyDirectory(t *testing.T) {
assert.Equal(t, resp.StatusCode, http.StatusOK) assert.Equal(t, resp.StatusCode, http.StatusOK)
body := tests.ReadBody(resp) body := tests.ReadBody(resp)
assert.Nil(t, err, "") assert.Nil(t, err, "")
assert.Equal(t, string(body), `{"action":"delete","node":{"key":"/foo","dir":true,"modifiedIndex":3,"createdIndex":2}}`, "") assert.Equal(t, string(body), `{"action":"delete","node":{"key":"/foo","dir":true,"modifiedIndex":3,"createdIndex":2},"prevNode":{"key":"/foo","dir":true,"modifiedIndex":2,"createdIndex":2}}`, "")
}) })
} }
@ -70,7 +70,7 @@ func TestV2DeleteNonEmptyDirectory(t *testing.T) {
assert.Equal(t, resp.StatusCode, http.StatusOK) assert.Equal(t, resp.StatusCode, http.StatusOK)
body := tests.ReadBody(resp) body := tests.ReadBody(resp)
assert.Nil(t, err, "") assert.Nil(t, err, "")
assert.Equal(t, string(body), `{"action":"delete","node":{"key":"/foo","dir":true,"modifiedIndex":3,"createdIndex":2}}`, "") assert.Equal(t, string(body), `{"action":"delete","node":{"key":"/foo","dir":true,"modifiedIndex":3,"createdIndex":2},"prevNode":{"key":"/foo","dir":true,"modifiedIndex":2,"createdIndex":2}}`, "")
}) })
} }
@ -87,7 +87,7 @@ func TestV2DeleteDirectoryRecursiveImpliesDir(t *testing.T) {
assert.Equal(t, resp.StatusCode, http.StatusOK) assert.Equal(t, resp.StatusCode, http.StatusOK)
body := tests.ReadBody(resp) body := tests.ReadBody(resp)
assert.Nil(t, err, "") assert.Nil(t, err, "")
assert.Equal(t, string(body), `{"action":"delete","node":{"key":"/foo","dir":true,"modifiedIndex":3,"createdIndex":2}}`, "") assert.Equal(t, string(body), `{"action":"delete","node":{"key":"/foo","dir":true,"modifiedIndex":3,"createdIndex":2},"prevNode":{"key":"/foo","dir":true,"modifiedIndex":2,"createdIndex":2}}`, "")
}) })
} }

View File

@ -14,6 +14,7 @@ const (
type Event struct { type Event struct {
Action string `json:"action"` Action string `json:"action"`
Node *NodeExtern `json:"node,omitempty"` Node *NodeExtern `json:"node,omitempty"`
PrevNode *NodeExtern `json:"prevNode,omitempty"`
} }
func newEvent(action string, key string, modifiedIndex, createdIndex uint64) *Event { func newEvent(action string, key string, modifiedIndex, createdIndex uint64) *Event {

View File

@ -231,9 +231,9 @@ func (n *node) Remove(dir, recursive bool, callback func(path string)) *etcdErr.
return nil return nil
} }
func (n *node) Repr(recurisive, sorted bool) NodeExtern { func (n *node) Repr(recurisive, sorted bool) *NodeExtern {
if n.IsDir() { if n.IsDir() {
node := NodeExtern{ node := &NodeExtern{
Key: n.Path, Key: n.Path,
Dir: true, Dir: true,
ModifiedIndex: n.ModifiedIndex, ModifiedIndex: n.ModifiedIndex,
@ -272,7 +272,7 @@ func (n *node) Repr(recurisive, sorted bool) NodeExtern {
return node return node
} }
node := NodeExtern{ node := &NodeExtern{
Key: n.Path, Key: n.Path,
Value: n.Value, Value: n.Value,
ModifiedIndex: n.ModifiedIndex, ModifiedIndex: n.ModifiedIndex,

View File

@ -20,7 +20,7 @@ type NodeExtern struct {
CreatedIndex uint64 `json:"createdIndex,omitempty"` CreatedIndex uint64 `json:"createdIndex,omitempty"`
} }
type NodeExterns []NodeExtern type NodeExterns []*NodeExtern
// interfaces for sorting // interfaces for sorting
func (ns NodeExterns) Len() int { func (ns NodeExterns) Len() int {

View File

@ -225,6 +225,7 @@ func (s *store) CompareAndSwap(nodePath string, prevValue string, prevIndex uint
s.CurrentIndex++ s.CurrentIndex++
e := newEvent(CompareAndSwap, nodePath, s.CurrentIndex, n.CreatedIndex) e := newEvent(CompareAndSwap, nodePath, s.CurrentIndex, n.CreatedIndex)
e.PrevNode = n.Repr(false, false)
eNode := e.Node eNode := e.Node
eNode.PrevValue = n.Value eNode.PrevValue = n.Value
@ -267,6 +268,7 @@ func (s *store) Delete(nodePath string, dir, recursive bool) (*Event, error) {
nextIndex := s.CurrentIndex + 1 nextIndex := s.CurrentIndex + 1
e := newEvent(Delete, nodePath, nextIndex, n.CreatedIndex) e := newEvent(Delete, nodePath, nextIndex, n.CreatedIndex)
e.PrevNode = n.Repr(false, false)
eNode := e.Node eNode := e.Node
if n.IsDir() { if n.IsDir() {
@ -326,6 +328,7 @@ func (s *store) CompareAndDelete(nodePath string, prevValue string, prevIndex ui
s.CurrentIndex++ s.CurrentIndex++
e := newEvent(CompareAndDelete, nodePath, s.CurrentIndex, n.CreatedIndex) e := newEvent(CompareAndDelete, nodePath, s.CurrentIndex, n.CreatedIndex)
e.PrevNode = n.Repr(false, false)
callback := func(path string) { // notify function callback := func(path string) { // notify function
// notify the watchers with deleted set true // notify the watchers with deleted set true
@ -412,6 +415,7 @@ func (s *store) Update(nodePath string, newValue string, expireTime time.Time) (
} }
e := newEvent(Update, nodePath, nextIndex, n.CreatedIndex) e := newEvent(Update, nodePath, nextIndex, n.CreatedIndex)
e.PrevNode = n.Repr(false, false)
eNode := e.Node eNode := e.Node
if n.IsDir() && len(newValue) != 0 { if n.IsDir() && len(newValue) != 0 {
@ -482,6 +486,7 @@ func (s *store) internalCreate(nodePath string, dir bool, value string, unique,
if n.IsDir() { if n.IsDir() {
return nil, etcdErr.NewError(etcdErr.EcodeNotFile, nodePath, currIndex) return nil, etcdErr.NewError(etcdErr.EcodeNotFile, nodePath, currIndex)
} }
e.PrevNode = n.Repr(false, false)
eNode.PrevValue, _ = n.Read() eNode.PrevValue, _ = n.Read()
n.Remove(false, false, nil) n.Remove(false, false, nil)
@ -557,6 +562,7 @@ func (s *store) DeleteExpiredKeys(cutoff time.Time) {
s.CurrentIndex++ s.CurrentIndex++
e := newEvent(Expire, node.Path, s.CurrentIndex, node.CreatedIndex) e := newEvent(Expire, node.Path, s.CurrentIndex, node.CreatedIndex)
e.PrevNode = node.Repr(false, false)
callback := func(path string) { // notify function callback := func(path string) { // notify function
// notify the watchers with deleted set true // notify the watchers with deleted set true

View File

@ -112,6 +112,11 @@ func TestSet(t *testing.T) {
assert.Nil(t, e.Node.Expiration, "") assert.Nil(t, e.Node.Expiration, "")
assert.Equal(t, e.Node.TTL, 0, "") assert.Equal(t, e.Node.TTL, 0, "")
assert.Equal(t, e.Node.ModifiedIndex, uint64(2), "") assert.Equal(t, e.Node.ModifiedIndex, uint64(2), "")
// check prevNode
assert.NotNil(t, e.PrevNode, "")
assert.Equal(t, e.PrevNode.Key, "/foo", "")
assert.Equal(t, e.PrevNode.Value, "", "")
assert.Equal(t, e.PrevNode.ModifiedIndex, uint64(1), "")
// Set /dir as a directory // Set /dir as a directory
e, err = s.Set("/dir", true, "", Permanent) e, err = s.Set("/dir", true, "", Permanent)
@ -199,6 +204,12 @@ func TestStoreUpdateValue(t *testing.T) {
assert.Equal(t, e.Node.Value, "baz", "") assert.Equal(t, e.Node.Value, "baz", "")
assert.Equal(t, e.Node.TTL, 0, "") assert.Equal(t, e.Node.TTL, 0, "")
assert.Equal(t, e.Node.ModifiedIndex, uint64(2), "") assert.Equal(t, e.Node.ModifiedIndex, uint64(2), "")
// check prevNode
assert.Equal(t, e.PrevNode.Key, "/foo", "")
assert.Equal(t, e.PrevNode.Value, "bar", "")
assert.Equal(t, e.PrevNode.TTL, 0, "")
assert.Equal(t, e.PrevNode.ModifiedIndex, uint64(1), "")
e, _ = s.Get("/foo", false, false) e, _ = s.Get("/foo", false, false)
assert.Equal(t, e.Node.Value, "baz", "") assert.Equal(t, e.Node.Value, "baz", "")
@ -212,6 +223,12 @@ func TestStoreUpdateValue(t *testing.T) {
assert.Equal(t, e.Node.Value, "", "") assert.Equal(t, e.Node.Value, "", "")
assert.Equal(t, e.Node.TTL, 0, "") assert.Equal(t, e.Node.TTL, 0, "")
assert.Equal(t, e.Node.ModifiedIndex, uint64(3), "") assert.Equal(t, e.Node.ModifiedIndex, uint64(3), "")
// check prevNode
assert.Equal(t, e.PrevNode.Key, "/foo", "")
assert.Equal(t, e.PrevNode.Value, "baz", "")
assert.Equal(t, e.PrevNode.TTL, 0, "")
assert.Equal(t, e.PrevNode.ModifiedIndex, uint64(2), "")
e, _ = s.Get("/foo", false, false) e, _ = s.Get("/foo", false, false)
assert.Equal(t, e.Node.Value, "", "") assert.Equal(t, e.Node.Value, "", "")
} }
@ -278,6 +295,10 @@ func TestStoreDeleteValue(t *testing.T) {
e, err := s.Delete("/foo", false, false) e, err := s.Delete("/foo", false, false)
assert.Nil(t, err, "") assert.Nil(t, err, "")
assert.Equal(t, e.Action, "delete", "") assert.Equal(t, e.Action, "delete", "")
// check pervNode
assert.NotNil(t, e.PrevNode, "")
assert.Equal(t, e.PrevNode.Key, "/foo", "")
assert.Equal(t, e.PrevNode.Value, "bar", "")
} }
// Ensure that the store can delete a directory if recursive is specified. // Ensure that the store can delete a directory if recursive is specified.
@ -290,6 +311,10 @@ func TestStoreDeleteDiretory(t *testing.T) {
e, err := s.Delete("/foo", true, false) e, err := s.Delete("/foo", true, false)
assert.Nil(t, err, "") assert.Nil(t, err, "")
assert.Equal(t, e.Action, "delete", "") assert.Equal(t, e.Action, "delete", "")
// check pervNode
assert.NotNil(t, e.PrevNode, "")
assert.Equal(t, e.PrevNode.Key, "/foo", "")
assert.Equal(t, e.PrevNode.Dir, true, "")
// create directory /foo and directory /foo/bar // create directory /foo and directory /foo/bar
s.Create("/foo/bar", true, "", false, Permanent) s.Create("/foo/bar", true, "", false, Permanent)
@ -346,6 +371,13 @@ func TestStoreCompareAndDeletePrevValue(t *testing.T) {
assert.Nil(t, err, "") assert.Nil(t, err, "")
assert.Equal(t, e.Action, "compareAndDelete", "") assert.Equal(t, e.Action, "compareAndDelete", "")
assert.Equal(t, e.Node.Key, "/foo", "") assert.Equal(t, e.Node.Key, "/foo", "")
// check pervNode
assert.NotNil(t, e.PrevNode, "")
assert.Equal(t, e.PrevNode.Key, "/foo", "")
assert.Equal(t, e.PrevNode.Value, "bar", "")
assert.Equal(t, e.PrevNode.ModifiedIndex, uint64(1), "")
assert.Equal(t, e.PrevNode.CreatedIndex, uint64(1), "")
} }
func TestStoreCompareAndDeletePrevValueFailsIfNotMatch(t *testing.T) { func TestStoreCompareAndDeletePrevValueFailsIfNotMatch(t *testing.T) {
@ -366,6 +398,12 @@ func TestStoreCompareAndDeletePrevIndex(t *testing.T) {
e, err := s.CompareAndDelete("/foo", "", 1) e, err := s.CompareAndDelete("/foo", "", 1)
assert.Nil(t, err, "") assert.Nil(t, err, "")
assert.Equal(t, e.Action, "compareAndDelete", "") assert.Equal(t, e.Action, "compareAndDelete", "")
// check pervNode
assert.NotNil(t, e.PrevNode, "")
assert.Equal(t, e.PrevNode.Key, "/foo", "")
assert.Equal(t, e.PrevNode.Value, "bar", "")
assert.Equal(t, e.PrevNode.ModifiedIndex, uint64(1), "")
assert.Equal(t, e.PrevNode.CreatedIndex, uint64(1), "")
} }
func TestStoreCompareAndDeletePrevIndexFailsIfNotMatch(t *testing.T) { func TestStoreCompareAndDeletePrevIndexFailsIfNotMatch(t *testing.T) {
@ -400,6 +438,13 @@ func TestStoreCompareAndSwapPrevValue(t *testing.T) {
assert.Equal(t, e.Action, "compareAndSwap", "") assert.Equal(t, e.Action, "compareAndSwap", "")
assert.Equal(t, e.Node.PrevValue, "bar", "") assert.Equal(t, e.Node.PrevValue, "bar", "")
assert.Equal(t, e.Node.Value, "baz", "") assert.Equal(t, e.Node.Value, "baz", "")
// check pervNode
assert.NotNil(t, e.PrevNode, "")
assert.Equal(t, e.PrevNode.Key, "/foo", "")
assert.Equal(t, e.PrevNode.Value, "bar", "")
assert.Equal(t, e.PrevNode.ModifiedIndex, uint64(1), "")
assert.Equal(t, e.PrevNode.CreatedIndex, uint64(1), "")
e, _ = s.Get("/foo", false, false) e, _ = s.Get("/foo", false, false)
assert.Equal(t, e.Node.Value, "baz", "") assert.Equal(t, e.Node.Value, "baz", "")
} }
@ -426,6 +471,13 @@ func TestStoreCompareAndSwapPrevIndex(t *testing.T) {
assert.Equal(t, e.Action, "compareAndSwap", "") assert.Equal(t, e.Action, "compareAndSwap", "")
assert.Equal(t, e.Node.PrevValue, "bar", "") assert.Equal(t, e.Node.PrevValue, "bar", "")
assert.Equal(t, e.Node.Value, "baz", "") assert.Equal(t, e.Node.Value, "baz", "")
// check pervNode
assert.NotNil(t, e.PrevNode, "")
assert.Equal(t, e.PrevNode.Key, "/foo", "")
assert.Equal(t, e.PrevNode.Value, "bar", "")
assert.Equal(t, e.PrevNode.ModifiedIndex, uint64(1), "")
assert.Equal(t, e.PrevNode.CreatedIndex, uint64(1), "")
e, _ = s.Get("/foo", false, false) e, _ = s.Get("/foo", false, false)
assert.Equal(t, e.Node.Value, "baz", "") assert.Equal(t, e.Node.Value, "baz", "")
} }