mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
client: add KeysAPI.Delete
This commit is contained in:
parent
2f479c8721
commit
0f31f403d1
@ -65,6 +65,8 @@ type KeysAPI interface {
|
|||||||
Create(ctx context.Context, key, value string) (*Response, error)
|
Create(ctx context.Context, key, value string) (*Response, error)
|
||||||
Update(ctx context.Context, key, value string) (*Response, error)
|
Update(ctx context.Context, key, value string) (*Response, error)
|
||||||
|
|
||||||
|
Delete(ctx context.Context, key string, opts DeleteOptions) (*Response, error)
|
||||||
|
|
||||||
Get(ctx context.Context, key string) (*Response, error)
|
Get(ctx context.Context, key string) (*Response, error)
|
||||||
RGet(ctx context.Context, key string) (*Response, error)
|
RGet(ctx context.Context, key string) (*Response, error)
|
||||||
|
|
||||||
@ -76,6 +78,10 @@ type SetOptions struct {
|
|||||||
PrevExist PrevExistType
|
PrevExist PrevExistType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DeleteOptions struct {
|
||||||
|
Recursive bool
|
||||||
|
}
|
||||||
|
|
||||||
type Watcher interface {
|
type Watcher interface {
|
||||||
Next(context.Context) (*Response, error)
|
Next(context.Context) (*Response, error)
|
||||||
}
|
}
|
||||||
@ -129,6 +135,21 @@ func (k *httpKeysAPI) Update(ctx context.Context, key, val string) (*Response, e
|
|||||||
return k.Set(ctx, key, val, SetOptions{PrevExist: PrevExist})
|
return k.Set(ctx, key, val, SetOptions{PrevExist: PrevExist})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (k *httpKeysAPI) Delete(ctx context.Context, key string, opts DeleteOptions) (*Response, error) {
|
||||||
|
act := &deleteAction{
|
||||||
|
Prefix: k.prefix,
|
||||||
|
Key: key,
|
||||||
|
Options: opts,
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, body, err := k.client.Do(ctx, act)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return unmarshalHTTPResponse(resp.StatusCode, resp.Header, body)
|
||||||
|
}
|
||||||
|
|
||||||
func (k *httpKeysAPI) Get(ctx context.Context, key string) (*Response, error) {
|
func (k *httpKeysAPI) Get(ctx context.Context, key string) (*Response, error) {
|
||||||
get := &getAction{
|
get := &getAction{
|
||||||
Prefix: k.prefix,
|
Prefix: k.prefix,
|
||||||
@ -276,6 +297,28 @@ func (a *setAction) HTTPRequest(ep url.URL) *http.Request {
|
|||||||
return req
|
return req
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type deleteAction struct {
|
||||||
|
Prefix string
|
||||||
|
Key string
|
||||||
|
Value string
|
||||||
|
Options DeleteOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *deleteAction) HTTPRequest(ep url.URL) *http.Request {
|
||||||
|
u := v2KeysURL(ep, a.Prefix, a.Key)
|
||||||
|
|
||||||
|
params := u.Query()
|
||||||
|
if a.Options.Recursive {
|
||||||
|
params.Set("recursive", "true")
|
||||||
|
}
|
||||||
|
u.RawQuery = params.Encode()
|
||||||
|
|
||||||
|
req, _ := http.NewRequest("DELETE", u.String(), nil)
|
||||||
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
|
||||||
|
return req
|
||||||
|
}
|
||||||
|
|
||||||
func unmarshalHTTPResponse(code int, header http.Header, body []byte) (res *Response, err error) {
|
func unmarshalHTTPResponse(code int, header http.Header, body []byte) (res *Response, err error) {
|
||||||
switch code {
|
switch code {
|
||||||
case http.StatusOK, http.StatusCreated:
|
case http.StatusOK, http.StatusCreated:
|
||||||
|
@ -304,6 +304,92 @@ func TestSetAction(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDeleteAction(t *testing.T) {
|
||||||
|
wantHeader := http.Header(map[string][]string{
|
||||||
|
"Content-Type": []string{"application/x-www-form-urlencoded"},
|
||||||
|
})
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
act deleteAction
|
||||||
|
wantURL string
|
||||||
|
}{
|
||||||
|
// default prefix
|
||||||
|
{
|
||||||
|
act: deleteAction{
|
||||||
|
Prefix: DefaultV2KeysPrefix,
|
||||||
|
Key: "foo",
|
||||||
|
},
|
||||||
|
wantURL: "http://example.com/v2/keys/foo",
|
||||||
|
},
|
||||||
|
|
||||||
|
// non-default prefix
|
||||||
|
{
|
||||||
|
act: deleteAction{
|
||||||
|
Prefix: "/pfx",
|
||||||
|
Key: "foo",
|
||||||
|
},
|
||||||
|
wantURL: "http://example.com/pfx/foo",
|
||||||
|
},
|
||||||
|
|
||||||
|
// no prefix
|
||||||
|
{
|
||||||
|
act: deleteAction{
|
||||||
|
Key: "foo",
|
||||||
|
},
|
||||||
|
wantURL: "http://example.com/foo",
|
||||||
|
},
|
||||||
|
|
||||||
|
// Key with path separators
|
||||||
|
{
|
||||||
|
act: deleteAction{
|
||||||
|
Prefix: DefaultV2KeysPrefix,
|
||||||
|
Key: "foo/bar/baz",
|
||||||
|
},
|
||||||
|
wantURL: "http://example.com/v2/keys/foo/bar/baz",
|
||||||
|
},
|
||||||
|
|
||||||
|
// Key with leading slash, Prefix with trailing slash
|
||||||
|
{
|
||||||
|
act: deleteAction{
|
||||||
|
Prefix: "/foo/",
|
||||||
|
Key: "/bar",
|
||||||
|
},
|
||||||
|
wantURL: "http://example.com/foo/bar",
|
||||||
|
},
|
||||||
|
|
||||||
|
// Key with trailing slash
|
||||||
|
{
|
||||||
|
act: deleteAction{
|
||||||
|
Key: "/foo/",
|
||||||
|
},
|
||||||
|
wantURL: "http://example.com/foo",
|
||||||
|
},
|
||||||
|
|
||||||
|
// Recursive set to true
|
||||||
|
{
|
||||||
|
act: deleteAction{
|
||||||
|
Key: "foo",
|
||||||
|
Options: DeleteOptions{
|
||||||
|
Recursive: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantURL: "http://example.com/foo?recursive=true",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tt := range tests {
|
||||||
|
u, err := url.Parse(tt.wantURL)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("#%d: unable to use wantURL fixture: %v", i, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
got := tt.act.HTTPRequest(url.URL{Scheme: "http", Host: "example.com"})
|
||||||
|
if err := assertRequest(*got, "DELETE", u, wantHeader, nil); err != nil {
|
||||||
|
t.Errorf("#%d: %v", i, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func assertRequest(got http.Request, wantMethod string, wantURL *url.URL, wantHeader http.Header, wantBody []byte) error {
|
func assertRequest(got http.Request, wantMethod string, wantURL *url.URL, wantHeader http.Header, wantBody []byte) error {
|
||||||
if wantMethod != got.Method {
|
if wantMethod != got.Method {
|
||||||
return fmt.Errorf("want.Method=%#v got.Method=%#v", wantMethod, got.Method)
|
return fmt.Errorf("want.Method=%#v got.Method=%#v", wantMethod, got.Method)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user