clientv3: withOption for Gets

This commit is contained in:
Anthony Romano 2016-02-08 13:11:55 -08:00
parent 2be7f7c2fb
commit 8dcd24bd64
4 changed files with 42 additions and 47 deletions

View File

@ -57,7 +57,7 @@ func TestKVPut(t *testing.T) {
if _, err := kv.Put(tt.key, tt.val, tt.leaseID); err != nil { if _, err := kv.Put(tt.key, tt.val, tt.leaseID); err != nil {
t.Fatalf("#%d: couldn't put %q (%v)", i, tt.key, err) t.Fatalf("#%d: couldn't put %q (%v)", i, tt.key, err)
} }
resp, err := kv.Get(tt.key, 0) resp, err := kv.Get(tt.key)
if err != nil { if err != nil {
t.Fatalf("#%d: couldn't get key (%v)", i, err) t.Fatalf("#%d: couldn't get key (%v)", i, err)
} }
@ -87,7 +87,7 @@ func TestKVRange(t *testing.T) {
t.Fatalf("#%d: couldn't put %q (%v)", i, key, err) t.Fatalf("#%d: couldn't put %q (%v)", i, key, err)
} }
} }
resp, err := kv.Get(keySet[0], 0) resp, err := kv.Get(keySet[0])
if err != nil { if err != nil {
t.Fatalf("couldn't get key (%v)", err) t.Fatalf("couldn't get key (%v)", err)
} }
@ -169,7 +169,11 @@ func TestKVRange(t *testing.T) {
} }
for i, tt := range tests { for i, tt := range tests {
resp, err := kv.Range(tt.begin, tt.end, 0, tt.rev, tt.sortOption) opts := []clientv3.OpOption{clientv3.WithRange(tt.end), clientv3.WithRev(tt.rev)}
if tt.sortOption != nil {
opts = append(opts, clientv3.WithSort(tt.sortOption.Target, tt.sortOption.Order))
}
resp, err := kv.Get(tt.begin, opts...)
if err != nil { if err != nil {
t.Fatalf("#%d: couldn't range (%v)", i, err) t.Fatalf("#%d: couldn't range (%v)", i, err)
} }
@ -213,7 +217,7 @@ func TestKVDeleteRange(t *testing.T) {
if dresp.Header.Revision != tt.delRev { if dresp.Header.Revision != tt.delRev {
t.Fatalf("#%d: dresp.Header.Revision got %d, want %d", i, dresp.Header.Revision, tt.delRev) t.Fatalf("#%d: dresp.Header.Revision got %d, want %d", i, dresp.Header.Revision, tt.delRev)
} }
resp, err := kv.Range(tt.key, tt.end, 0, 0, nil) resp, err := kv.Get(tt.key, clientv3.WithRange(tt.end))
if err != nil { if err != nil {
t.Fatalf("#%d: couldn't get key (%v)", i, err) t.Fatalf("#%d: couldn't get key (%v)", i, err)
} }
@ -245,7 +249,7 @@ func TestKVDelete(t *testing.T) {
if resp.Header.Revision != 3 { if resp.Header.Revision != 3 {
t.Fatalf("resp.Header.Revision got %d, want %d", resp.Header.Revision, 3) t.Fatalf("resp.Header.Revision got %d, want %d", resp.Header.Revision, 3)
} }
gresp, err := kv.Get("foo", 0) gresp, err := kv.Get("foo")
if err != nil { if err != nil {
t.Fatalf("couldn't get key (%v)", err) t.Fatalf("couldn't get key (%v)", err)
} }
@ -311,7 +315,7 @@ func TestKVGetRetry(t *testing.T) {
donec := make(chan struct{}) donec := make(chan struct{})
go func() { go func() {
// Get will fail, but reconnect will trigger // Get will fail, but reconnect will trigger
gresp, gerr := kv.Get("foo", 0) gresp, gerr := kv.Get("foo")
if gerr != nil { if gerr != nil {
t.Fatal(gerr) t.Fatal(gerr)
} }
@ -359,7 +363,7 @@ func TestKVPutFailGetRetry(t *testing.T) {
donec := make(chan struct{}) donec := make(chan struct{})
go func() { go func() {
// Get will fail, but reconnect will trigger // Get will fail, but reconnect will trigger
gresp, gerr := kv.Get("foo", 0) gresp, gerr := kv.Get("foo")
if gerr != nil { if gerr != nil {
t.Fatal(gerr) t.Fatal(gerr)
} }

View File

@ -57,7 +57,7 @@ func TestTxnWriteFail(t *testing.T) {
donec <- struct{}{} donec <- struct{}{}
// and ensure the put didn't take // and ensure the put didn't take
gresp, gerr := kv.Get("foo", 0) gresp, gerr := kv.Get("foo")
if gerr != nil { if gerr != nil {
t.Fatal(gerr) t.Fatal(gerr)
} }
@ -92,7 +92,7 @@ func TestTxnReadRetry(t *testing.T) {
donec := make(chan struct{}) donec := make(chan struct{})
go func() { go func() {
_, err := kv.Txn().Then(clientv3.OpGet("foo", 0)).Commit() _, err := kv.Txn().Then(clientv3.OpGet("foo")).Commit()
if err != nil { if err != nil {
t.Fatalf("expected response, got error %v", err) t.Fatalf("expected response, got error %v", err)
} }
@ -122,7 +122,7 @@ func TestTxnSuccess(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
resp, err := kv.Get("foo", 0) resp, err := kv.Get("foo")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -25,7 +25,6 @@ import (
type ( type (
PutResponse pb.PutResponse PutResponse pb.PutResponse
RangeResponse pb.RangeResponse
GetResponse pb.RangeResponse GetResponse pb.RangeResponse
DeleteRangeResponse pb.DeleteRangeResponse DeleteRangeResponse pb.DeleteRangeResponse
DeleteResponse pb.DeleteRangeResponse DeleteResponse pb.DeleteRangeResponse
@ -39,14 +38,14 @@ type KV interface {
// To get a string of bytes, do string([]byte(0x10, 0x20)). // To get a string of bytes, do string([]byte(0x10, 0x20)).
Put(key, val string, leaseID lease.LeaseID) (*PutResponse, error) Put(key, val string, leaseID lease.LeaseID) (*PutResponse, error)
// Range gets the keys [key, end) in the range at rev. // Get retrieves keys.
// If rev <=0, range gets the keys at currentRev. // By default, Get will return the value for "key", if any.
// Limit limits the number of keys returned. // When passed WithRange(end), Get will return the keys in the range [key, end).
// If the required rev is compacted, ErrCompacted will be returned. // When passed WithRev(rev) with rev > 0, Get retrieves keys at the given revision;
Range(key, end string, limit, rev int64, sort *SortOption) (*RangeResponse, error) // if the required revision is compacted, the request will fail with ErrCompacted .
// When passed WithLimit(limit), the number of returned keys is bounded by limit.
// Get is like Range. A shortcut for ranging single key like [key, key+1). // When passed WithSort(), the keys will be sorted.
Get(key string, rev int64) (*GetResponse, error) Get(key string, opts ...OpOption) (*GetResponse, error)
// DeleteRange deletes the given range [key, end). // DeleteRange deletes the given range [key, end).
DeleteRange(key, end string) (*DeleteRangeResponse, error) DeleteRange(key, end string) (*DeleteRangeResponse, error)
@ -89,16 +88,8 @@ func (kv *kv) Put(key, val string, leaseID lease.LeaseID) (*PutResponse, error)
return (*PutResponse)(r.GetResponsePut()), nil return (*PutResponse)(r.GetResponsePut()), nil
} }
func (kv *kv) Range(key, end string, limit, rev int64, sort *SortOption) (*RangeResponse, error) { func (kv *kv) Get(key string, opts ...OpOption) (*GetResponse, error) {
r, err := kv.do(OpRange(key, end, limit, rev, sort)) r, err := kv.do(OpGet(key, opts...))
if err != nil {
return nil, err
}
return (*RangeResponse)(r.GetResponseRange()), nil
}
func (kv *kv) Get(key string, rev int64) (*GetResponse, error) {
r, err := kv.do(OpGet(key, rev))
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -68,25 +68,12 @@ func (op Op) isWrite() bool {
return op.t != tRange return op.t != tRange
} }
func OpRange(key, end string, limit, rev int64, sort *SortOption) Op { func OpGet(key string, opts ...OpOption) Op {
return Op{ ret := Op{t: tRange, key: []byte(key)}
t: tRange, for _, opt := range opts {
key: []byte(key), opt(&ret)
end: []byte(end),
limit: limit,
rev: rev,
sort: sort,
}
}
func OpGet(key string, rev int64) Op {
return Op{
t: tRange,
key: []byte(key),
rev: rev,
} }
return ret
} }
func OpDeleteRange(key, end string) Op { func OpDeleteRange(key, end string) Op {
@ -113,3 +100,16 @@ func OpPut(key, val string, leaseID lease.LeaseID) Op {
leaseID: leaseID, leaseID: leaseID,
} }
} }
type OpOption func(*Op)
func WithLimit(n int64) OpOption { return func(op *Op) { op.limit = n } }
func WithRev(rev int64) OpOption { return func(op *Op) { op.rev = rev } }
func WithSort(tgt SortTarget, order SortOrder) OpOption {
return func(op *Op) {
op.sort = &SortOption{tgt, order}
}
}
func WithRange(endKey string) OpOption {
return func(op *Op) { op.end = []byte(endKey) }
}