mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
Merge pull request #4483 from heyitsanthony/clientv3-op-opts
clientv3: optionize put and delete
This commit is contained in:
commit
fcf94f3a59
@ -55,7 +55,7 @@ func TestKVPut(t *testing.T) {
|
||||
}
|
||||
|
||||
for i, tt := range tests {
|
||||
if _, err := kv.Put(ctx, tt.key, tt.val, tt.leaseID); err != nil {
|
||||
if _, err := kv.Put(ctx, tt.key, tt.val, clientv3.WithLease(tt.leaseID)); err != nil {
|
||||
t.Fatalf("#%d: couldn't put %q (%v)", i, tt.key, err)
|
||||
}
|
||||
resp, err := kv.Get(ctx, tt.key)
|
||||
@ -85,7 +85,7 @@ func TestKVRange(t *testing.T) {
|
||||
|
||||
keySet := []string{"a", "b", "c", "c", "c", "foo", "foo/abc", "fop"}
|
||||
for i, key := range keySet {
|
||||
if _, err := kv.Put(ctx, key, "", lease.NoLease); err != nil {
|
||||
if _, err := kv.Put(ctx, key, ""); err != nil {
|
||||
t.Fatalf("#%d: couldn't put %q (%v)", i, key, err)
|
||||
}
|
||||
}
|
||||
@ -199,7 +199,7 @@ func TestKVDeleteRange(t *testing.T) {
|
||||
|
||||
keySet := []string{"a", "b", "c", "c", "c", "d", "e", "f"}
|
||||
for i, key := range keySet {
|
||||
if _, err := kv.Put(ctx, key, "", lease.NoLease); err != nil {
|
||||
if _, err := kv.Put(ctx, key, ""); err != nil {
|
||||
t.Fatalf("#%d: couldn't put %q (%v)", i, key, err)
|
||||
}
|
||||
}
|
||||
@ -213,7 +213,7 @@ func TestKVDeleteRange(t *testing.T) {
|
||||
}
|
||||
|
||||
for i, tt := range tests {
|
||||
dresp, err := kv.DeleteRange(ctx, tt.key, tt.end)
|
||||
dresp, err := kv.Delete(ctx, tt.key, clientv3.WithRange(tt.end))
|
||||
if err != nil {
|
||||
t.Fatalf("#%d: couldn't delete range (%v)", i, err)
|
||||
}
|
||||
@ -239,7 +239,7 @@ func TestKVDelete(t *testing.T) {
|
||||
kv := clientv3.NewKV(clus.RandClient())
|
||||
ctx := context.TODO()
|
||||
|
||||
presp, err := kv.Put(ctx, "foo", "", lease.NoLease)
|
||||
presp, err := kv.Put(ctx, "foo", "")
|
||||
if err != nil {
|
||||
t.Fatalf("couldn't put 'foo' (%v)", err)
|
||||
}
|
||||
@ -272,7 +272,7 @@ func TestKVCompact(t *testing.T) {
|
||||
ctx := context.TODO()
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
if _, err := kv.Put(ctx, "foo", "bar", lease.NoLease); err != nil {
|
||||
if _, err := kv.Put(ctx, "foo", "bar"); err != nil {
|
||||
t.Fatalf("couldn't put 'foo' (%v)", err)
|
||||
}
|
||||
}
|
||||
@ -311,7 +311,7 @@ func TestKVGetRetry(t *testing.T) {
|
||||
kv := clientv3.NewKV(clus.Client(0))
|
||||
ctx := context.TODO()
|
||||
|
||||
if _, err := kv.Put(ctx, "foo", "bar", 0); err != nil {
|
||||
if _, err := kv.Put(ctx, "foo", "bar"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@ -363,7 +363,7 @@ func TestKVPutFailGetRetry(t *testing.T) {
|
||||
clus.Members[0].Stop(t)
|
||||
<-clus.Members[0].StopNotify()
|
||||
|
||||
_, err := kv.Put(ctx, "foo", "bar", 0)
|
||||
_, err := kv.Put(ctx, "foo", "bar")
|
||||
if err == nil {
|
||||
t.Fatalf("got success on disconnected put, wanted error")
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ func TestLeaseCreate(t *testing.T) {
|
||||
t.Errorf("failed to create lease %v", err)
|
||||
}
|
||||
|
||||
_, err = kv.Put(context.TODO(), "foo", "bar", lease.LeaseID(resp.ID))
|
||||
_, err = kv.Put(context.TODO(), "foo", "bar", clientv3.WithLease(lease.LeaseID(resp.ID)))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create key with lease %v", err)
|
||||
}
|
||||
@ -69,7 +69,7 @@ func TestLeaseRevoke(t *testing.T) {
|
||||
t.Errorf("failed to revoke lease %v", err)
|
||||
}
|
||||
|
||||
_, err = kv.Put(context.TODO(), "foo", "bar", lease.LeaseID(resp.ID))
|
||||
_, err = kv.Put(context.TODO(), "foo", "bar", clientv3.WithLease(lease.LeaseID(resp.ID)))
|
||||
if err != v3rpc.ErrLeaseNotFound {
|
||||
t.Fatalf("err = %v, want %v", err, v3rpc.ErrLeaseNotFound)
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ func TestTxnWriteFail(t *testing.T) {
|
||||
|
||||
donec := make(chan struct{})
|
||||
go func() {
|
||||
resp, err := kv.Txn(ctx).Then(clientv3.OpPut("foo", "bar", 0)).Commit()
|
||||
resp, err := kv.Txn(ctx).Then(clientv3.OpPut("foo", "bar")).Commit()
|
||||
if err == nil {
|
||||
t.Fatalf("expected error, got response %v", resp)
|
||||
}
|
||||
@ -123,7 +123,7 @@ func TestTxnSuccess(t *testing.T) {
|
||||
kv := clientv3.NewKV(clus.Client(0))
|
||||
ctx := context.TODO()
|
||||
|
||||
_, err := kv.Txn(ctx).Then(clientv3.OpPut("foo", "bar", 0)).Commit()
|
||||
_, err := kv.Txn(ctx).Then(clientv3.OpPut("foo", "bar")).Commit()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ func testWatchMultiWatcher(t *testing.T, wctx *watchctx) {
|
||||
for i := 0; i < numKeyUpdates; i++ {
|
||||
for _, k := range keys {
|
||||
v := fmt.Sprintf("%s-%d", k, i)
|
||||
if _, err := wctx.kv.Put(ctx, k, v, 0); err != nil {
|
||||
if _, err := wctx.kv.Put(ctx, k, v); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
@ -221,7 +221,7 @@ func testWatchCancelRunning(t *testing.T, wctx *watchctx) {
|
||||
if wctx.ch = wctx.w.Watch(ctx, "a", 0); wctx.ch == nil {
|
||||
t.Fatalf("expected non-nil watcher channel")
|
||||
}
|
||||
if _, err := wctx.kv.Put(ctx, "a", "a", 0); err != nil {
|
||||
if _, err := wctx.kv.Put(ctx, "a", "a"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cancel()
|
||||
@ -246,7 +246,7 @@ func testWatchCancelRunning(t *testing.T, wctx *watchctx) {
|
||||
}
|
||||
|
||||
func putAndWatch(t *testing.T, wctx *watchctx, key, val string) {
|
||||
if _, err := wctx.kv.Put(context.TODO(), key, val, 0); err != nil {
|
||||
if _, err := wctx.kv.Put(context.TODO(), key, val); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
select {
|
||||
|
@ -20,15 +20,13 @@ import (
|
||||
"github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
|
||||
"github.com/coreos/etcd/Godeps/_workspace/src/google.golang.org/grpc"
|
||||
pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
|
||||
"github.com/coreos/etcd/lease"
|
||||
)
|
||||
|
||||
type (
|
||||
PutResponse pb.PutResponse
|
||||
GetResponse pb.RangeResponse
|
||||
DeleteRangeResponse pb.DeleteRangeResponse
|
||||
DeleteResponse pb.DeleteRangeResponse
|
||||
TxnResponse pb.TxnResponse
|
||||
PutResponse pb.PutResponse
|
||||
GetResponse pb.RangeResponse
|
||||
DeleteResponse pb.DeleteRangeResponse
|
||||
TxnResponse pb.TxnResponse
|
||||
)
|
||||
|
||||
type KV interface {
|
||||
@ -36,7 +34,7 @@ type KV interface {
|
||||
// Note that key,value can be plain bytes array and string is
|
||||
// an immutable representation of that bytes array.
|
||||
// To get a string of bytes, do string([]byte(0x10, 0x20)).
|
||||
Put(ctx context.Context, key, val string, leaseID lease.LeaseID) (*PutResponse, error)
|
||||
Put(ctx context.Context, key, val string, opts ...OpOption) (*PutResponse, error)
|
||||
|
||||
// Get retrieves keys.
|
||||
// By default, Get will return the value for "key", if any.
|
||||
@ -47,11 +45,8 @@ type KV interface {
|
||||
// When passed WithSort(), the keys will be sorted.
|
||||
Get(ctx context.Context, key string, opts ...OpOption) (*GetResponse, error)
|
||||
|
||||
// DeleteRange deletes the given range [key, end).
|
||||
DeleteRange(ctx context.Context, key, end string) (*DeleteRangeResponse, error)
|
||||
|
||||
// Delete is like DeleteRange. A shortcut for deleting single key like [key, key+1).
|
||||
Delete(ctx context.Context, key string) (*DeleteResponse, error)
|
||||
// Delete deletes a key, or optionallly using WithRange(end), [key, end).
|
||||
Delete(ctx context.Context, key string, opts ...OpOption) (*DeleteResponse, error)
|
||||
|
||||
// Compact compacts etcd KV history before the given rev.
|
||||
Compact(ctx context.Context, rev int64) error
|
||||
@ -80,8 +75,8 @@ func NewKV(c *Client) KV {
|
||||
}
|
||||
}
|
||||
|
||||
func (kv *kv) Put(ctx context.Context, key, val string, leaseID lease.LeaseID) (*PutResponse, error) {
|
||||
r, err := kv.do(ctx, OpPut(key, val, leaseID))
|
||||
func (kv *kv) Put(ctx context.Context, key, val string, opts ...OpOption) (*PutResponse, error) {
|
||||
r, err := kv.do(ctx, OpPut(key, val, opts...))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -96,16 +91,8 @@ func (kv *kv) Get(ctx context.Context, key string, opts ...OpOption) (*GetRespon
|
||||
return (*GetResponse)(r.GetResponseRange()), nil
|
||||
}
|
||||
|
||||
func (kv *kv) DeleteRange(ctx context.Context, key, end string) (*DeleteRangeResponse, error) {
|
||||
r, err := kv.do(ctx, OpDeleteRange(key, end))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return (*DeleteRangeResponse)(r.GetResponseDeleteRange()), nil
|
||||
}
|
||||
|
||||
func (kv *kv) Delete(ctx context.Context, key string) (*DeleteResponse, error) {
|
||||
r, err := kv.do(ctx, OpDelete(key))
|
||||
func (kv *kv) Delete(ctx context.Context, key string, opts ...OpOption) (*DeleteResponse, error) {
|
||||
r, err := kv.do(ctx, OpDelete(key, opts...))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -70,39 +70,53 @@ func (op Op) isWrite() bool {
|
||||
|
||||
func OpGet(key string, opts ...OpOption) Op {
|
||||
ret := Op{t: tRange, key: []byte(key)}
|
||||
for _, opt := range opts {
|
||||
opt(&ret)
|
||||
ret.applyOpts(opts)
|
||||
return ret
|
||||
}
|
||||
|
||||
func OpDelete(key string, opts ...OpOption) Op {
|
||||
ret := Op{t: tDeleteRange, key: []byte(key)}
|
||||
ret.applyOpts(opts)
|
||||
switch {
|
||||
case ret.leaseID != 0:
|
||||
panic("unexpected lease in delete")
|
||||
case ret.limit != 0:
|
||||
panic("unexpected limit in delete")
|
||||
case ret.rev != 0:
|
||||
panic("unexpected revision in delete")
|
||||
case ret.sort != nil:
|
||||
panic("unexpected sort in delete")
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func OpDeleteRange(key, end string) Op {
|
||||
return Op{
|
||||
t: tDeleteRange,
|
||||
key: []byte(key),
|
||||
end: []byte(end),
|
||||
func OpPut(key, val string, opts ...OpOption) Op {
|
||||
ret := Op{t: tPut, key: []byte(key), val: []byte(val)}
|
||||
ret.applyOpts(opts)
|
||||
switch {
|
||||
case ret.end != nil:
|
||||
panic("unexpected range in put")
|
||||
case ret.limit != 0:
|
||||
panic("unexpected limit in put")
|
||||
case ret.rev != 0:
|
||||
panic("unexpected revision in put")
|
||||
case ret.sort != nil:
|
||||
panic("unexpected sort in put")
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func OpDelete(key string) Op {
|
||||
return Op{
|
||||
t: tDeleteRange,
|
||||
key: []byte(key),
|
||||
}
|
||||
}
|
||||
|
||||
func OpPut(key, val string, leaseID lease.LeaseID) Op {
|
||||
return Op{
|
||||
t: tPut,
|
||||
key: []byte(key),
|
||||
|
||||
val: []byte(val),
|
||||
leaseID: leaseID,
|
||||
func (op *Op) applyOpts(opts []OpOption) {
|
||||
for _, opt := range opts {
|
||||
opt(op)
|
||||
}
|
||||
}
|
||||
|
||||
type OpOption func(*Op)
|
||||
|
||||
func WithLease(leaseID lease.LeaseID) OpOption {
|
||||
return func(op *Op) { op.leaseID = leaseID }
|
||||
}
|
||||
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 {
|
||||
|
@ -34,7 +34,7 @@ func TestTxnPanics(t *testing.T) {
|
||||
}
|
||||
|
||||
cmp := Compare(CreatedRevision("foo"), "=", 0)
|
||||
op := OpPut("foo", "bar", 0)
|
||||
op := OpPut("foo", "bar")
|
||||
|
||||
tests := []struct {
|
||||
f func()
|
||||
|
Loading…
x
Reference in New Issue
Block a user