1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package clientv3
16
17 import (
18 "context"
19
20 pb "go.etcd.io/etcd/api/v3/etcdserverpb"
21
22 "google.golang.org/grpc"
23 )
24
25 type (
26 CompactResponse pb.CompactionResponse
27 PutResponse pb.PutResponse
28 GetResponse pb.RangeResponse
29 DeleteResponse pb.DeleteRangeResponse
30 TxnResponse pb.TxnResponse
31 )
32
33 type KV interface {
34
35
36
37
38 Put(ctx context.Context, key, val string, opts ...OpOption) (*PutResponse, error)
39
40
41
42
43
44
45
46
47
48 Get(ctx context.Context, key string, opts ...OpOption) (*GetResponse, error)
49
50
51 Delete(ctx context.Context, key string, opts ...OpOption) (*DeleteResponse, error)
52
53
54 Compact(ctx context.Context, rev int64, opts ...CompactOption) (*CompactResponse, error)
55
56
57
58
59
60
61 Do(ctx context.Context, op Op) (OpResponse, error)
62
63
64 Txn(ctx context.Context) Txn
65 }
66
67 type OpResponse struct {
68 put *PutResponse
69 get *GetResponse
70 del *DeleteResponse
71 txn *TxnResponse
72 }
73
74 func (op OpResponse) Put() *PutResponse { return op.put }
75 func (op OpResponse) Get() *GetResponse { return op.get }
76 func (op OpResponse) Del() *DeleteResponse { return op.del }
77 func (op OpResponse) Txn() *TxnResponse { return op.txn }
78
79 func (resp *PutResponse) OpResponse() OpResponse {
80 return OpResponse{put: resp}
81 }
82 func (resp *GetResponse) OpResponse() OpResponse {
83 return OpResponse{get: resp}
84 }
85 func (resp *DeleteResponse) OpResponse() OpResponse {
86 return OpResponse{del: resp}
87 }
88 func (resp *TxnResponse) OpResponse() OpResponse {
89 return OpResponse{txn: resp}
90 }
91
92 type kv struct {
93 remote pb.KVClient
94 callOpts []grpc.CallOption
95 }
96
97 func NewKV(c *Client) KV {
98 api := &kv{remote: RetryKVClient(c)}
99 if c != nil {
100 api.callOpts = c.callOpts
101 }
102 return api
103 }
104
105 func NewKVFromKVClient(remote pb.KVClient, c *Client) KV {
106 api := &kv{remote: remote}
107 if c != nil {
108 api.callOpts = c.callOpts
109 }
110 return api
111 }
112
113 func (kv *kv) Put(ctx context.Context, key, val string, opts ...OpOption) (*PutResponse, error) {
114 r, err := kv.Do(ctx, OpPut(key, val, opts...))
115 return r.put, toErr(ctx, err)
116 }
117
118 func (kv *kv) Get(ctx context.Context, key string, opts ...OpOption) (*GetResponse, error) {
119 r, err := kv.Do(ctx, OpGet(key, opts...))
120 return r.get, toErr(ctx, err)
121 }
122
123 func (kv *kv) Delete(ctx context.Context, key string, opts ...OpOption) (*DeleteResponse, error) {
124 r, err := kv.Do(ctx, OpDelete(key, opts...))
125 return r.del, toErr(ctx, err)
126 }
127
128 func (kv *kv) Compact(ctx context.Context, rev int64, opts ...CompactOption) (*CompactResponse, error) {
129 resp, err := kv.remote.Compact(ctx, OpCompact(rev, opts...).toRequest(), kv.callOpts...)
130 if err != nil {
131 return nil, toErr(ctx, err)
132 }
133 return (*CompactResponse)(resp), err
134 }
135
136 func (kv *kv) Txn(ctx context.Context) Txn {
137 return &txn{
138 kv: kv,
139 ctx: ctx,
140 callOpts: kv.callOpts,
141 }
142 }
143
144 func (kv *kv) Do(ctx context.Context, op Op) (OpResponse, error) {
145 var err error
146 switch op.t {
147 case tRange:
148 var resp *pb.RangeResponse
149 resp, err = kv.remote.Range(ctx, op.toRangeRequest(), kv.callOpts...)
150 if err == nil {
151 return OpResponse{get: (*GetResponse)(resp)}, nil
152 }
153 case tPut:
154 var resp *pb.PutResponse
155 r := &pb.PutRequest{Key: op.key, Value: op.val, Lease: int64(op.leaseID), PrevKv: op.prevKV, IgnoreValue: op.ignoreValue, IgnoreLease: op.ignoreLease}
156 resp, err = kv.remote.Put(ctx, r, kv.callOpts...)
157 if err == nil {
158 return OpResponse{put: (*PutResponse)(resp)}, nil
159 }
160 case tDeleteRange:
161 var resp *pb.DeleteRangeResponse
162 r := &pb.DeleteRangeRequest{Key: op.key, RangeEnd: op.end, PrevKv: op.prevKV}
163 resp, err = kv.remote.DeleteRange(ctx, r, kv.callOpts...)
164 if err == nil {
165 return OpResponse{del: (*DeleteResponse)(resp)}, nil
166 }
167 case tTxn:
168 var resp *pb.TxnResponse
169 resp, err = kv.remote.Txn(ctx, op.toTxnRequest(), kv.callOpts...)
170 if err == nil {
171 return OpResponse{txn: (*TxnResponse)(resp)}, nil
172 }
173 default:
174 panic("Unknown op")
175 }
176 return OpResponse{}, toErr(ctx, err)
177 }
178
View as plain text