Skip to content

Commit

Permalink
etcdserver, clientv3: add "!=" to txn
Browse files Browse the repository at this point in the history
adding != to compare is a requested functionality from a etcd user

FIX etcd-io#6719
  • Loading branch information
fanminshi committed Nov 9, 2016
1 parent c9cc1ef commit c2fd42b
Show file tree
Hide file tree
Showing 12 changed files with 438 additions and 408 deletions.
4 changes: 2 additions & 2 deletions Documentation/dev-guide/api_reference_v3.md
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ Empty field.
| Field | Description | Type |
| ----- | ----------- | ---- |
| key | key is the first key to delete in the range. | bytes |
| range_end | range_end is the key following the last key to delete for the range [key, range_end). If range_end is not given, the range is defined to contain only the key argument. If range_end is '\0', the range is all keys greater than or equal to the key argument. | bytes |
| range_end | range_end is the key following the last key to delete for the range [key, range_end). If range_end is not given, the range is defined to contain only the key argument. If range_end is one bit larger than the given key, then the range is all the all keys with the prefix (the given key). If range_end is '\0', the range is all keys greater than or equal to the key argument. | bytes |
| prev_kv | If prev_kv is set, etcd gets the previous key-value pairs before deleting it. The previous key-value pairs will be returned in the delte response. | bool |


Expand Down Expand Up @@ -762,7 +762,7 @@ From google paxosdb paper: Our implementation hinges around a powerful primitive
| Field | Description | Type |
| ----- | ----------- | ---- |
| key | key is the key to register for watching. | bytes |
| range_end | range_end is the end of the range [key, range_end) to watch. If range_end is not given, only the key argument is watched. If range_end is equal to '\0', all keys greater than or equal to the key argument are watched. | bytes |
| range_end | range_end is the end of the range [key, range_end) to watch. If range_end is not given, only the key argument is watched. If range_end is equal to '\0', all keys greater than or equal to the key argument are watched. If the range_end is one bit larger than the given key, then all keys with the prefix (the given key) will be watched. | bytes |
| start_revision | start_revision is an optional revision to watch from (inclusive). No start_revision is "now". | int64 |
| progress_notify | progress_notify is set so that the etcd server will periodically send a WatchResponse with no events to the new watcher if there are no recent events. It is useful when clients wish to recover a disconnected watcher starting from a recent known revision. The etcd server may decide how often it will send notifications based on current load. | bool |
| filters | filter out put event. filter out delete event. filters filter the events at server side before it sends back to the watcher. | (slice of) FilterType |
Expand Down
5 changes: 3 additions & 2 deletions Documentation/dev-guide/apispec/swagger/rpc.swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -978,7 +978,8 @@
"enum": [
"EQUAL",
"GREATER",
"LESS"
"LESS",
"NOT_EQUAL"
],
"default": "EQUAL"
},
Expand Down Expand Up @@ -1518,7 +1519,7 @@
"range_end": {
"type": "string",
"format": "byte",
"description": "range_end is the key following the last key to delete for the range [key, range_end).\nIf range_end is not given, the range is defined to contain only the key argument.\nIf range_end is '\\0', the range is all keys greater than or equal to the key argument."
"description": "range_end is the key following the last key to delete for the range [key, range_end).\nIf range_end is not given, the range is defined to contain only the key argument.\nIf range_end is one bit larger than the given key, then the range is all\nthe all keys with the prefix (the given key).\nIf range_end is '\\0', the range is all keys greater than or equal to the key argument."
}
}
},
Expand Down
2 changes: 2 additions & 0 deletions clientv3/compare.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ func Compare(cmp Cmp, result string, v interface{}) Cmp {
switch result {
case "=":
r = pb.Compare_EQUAL
case "!=":
r = pb.Compare_NOT_EQUAL
case ">":
r = pb.Compare_GREATER
case "<":
Expand Down
34 changes: 26 additions & 8 deletions e2e/ctl_v3_txn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ func txnTestSuccess(cx ctlCtx) {
cx.t.Fatalf("txnTestSuccess ctlV3Put error (%v)", err)
}
rqs := []txnRequests{
{
compare: []string{`value("key1") != "value2"`, `value("key2") != "value1"`},
ifSucess: []string{"get key1", "get key2"},
results: []string{"SUCCESS", "key1", "value1", "key2", "value2"},
},
{
compare: []string{`version("key1") = "1"`, `version("key2") = "1"`},
ifSucess: []string{"get key1", "get key2", `put "key \"with\" space" "value \x23"`},
Expand All @@ -60,14 +65,27 @@ func txnTestSuccess(cx ctlCtx) {
}

func txnTestFail(cx ctlCtx) {
rqs := txnRequests{
compare: []string{`version("key") < "0"`},
ifSucess: []string{`put key "success"`},
ifFail: []string{`put key "fail"`},
results: []string{"FAILURE", "OK"},
}
if err := ctlV3Txn(cx, rqs); err != nil {
cx.t.Fatal(err)
if err := ctlV3Put(cx, "key1", "value1", ""); err != nil {
cx.t.Fatalf("txnTestSuccess ctlV3Put error (%v)", err)
}
rqs := []txnRequests{
{
compare: []string{`version("key") < "0"`},
ifSucess: []string{`put key "success"`},
ifFail: []string{`put key "fail"`},
results: []string{"FAILURE", "OK"},
},
{
compare: []string{`value("key1") != "value1"`},
ifSucess: []string{`put key1 "success"`},
ifFail: []string{`put key1 "fail"`},
results: []string{"FAILURE", "OK"},
},
}
for _, rq := range rqs {
if err := ctlV3Txn(cx, rq); err != nil {
cx.t.Fatal(err)
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions etcdserver/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,10 @@ func (a *applierV3backend) applyCompare(c *pb.Compare) (int64, bool) {
if result != 0 {
return rev, false
}
case pb.Compare_NOT_EQUAL:
if result == 0 {
return rev, false
}
case pb.Compare_GREATER:
if result != 1 {
return rev, false
Expand Down
90 changes: 44 additions & 46 deletions etcdserver/etcdserverpb/etcdserver.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit c2fd42b

Please sign in to comment.