Skip to content

Commit

Permalink
Add 'delete db' and 'delete doc' commands
Browse files Browse the repository at this point in the history
  • Loading branch information
flimzy committed Nov 27, 2020
1 parent 765b32e commit fbee54b
Show file tree
Hide file tree
Showing 17 changed files with 393 additions and 25 deletions.
30 changes: 15 additions & 15 deletions cmd/kouchctl/cmd/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,33 +23,33 @@ type delete struct {
}

func deleteCmd(r *root) *cobra.Command {
g := &get{
c := &delete{
root: r,
doc: getDocCmd(r),
db: getDBCmd(r),
ver: getVersionCmd(r),
doc: deleteDocCmd(r),
db: deleteDBCmd(r),
}
cmd := &cobra.Command{
Use: "delete [command]",
Aliases: []string{"del"},
Short: "Delete a resource",
Long: `Delete a resource described by the URL`,
RunE: g.RunE,
RunE: c.RunE,
}

// cmd.AddCommand(g.doc)
// cmd.AddCommand(g.db)
cmd.AddCommand(c.doc)
cmd.AddCommand(c.db)

return cmd
}

func (c *delete) RunE(cmd *cobra.Command, args []string) error {
// if c.conf.HasDoc() {
// return g.doc.RunE(cmd, args)
// }
// if c.conf.HasDB() {
// return g.db.RunE(cmd, args)
// }
// return c.ver.RunE(cmd, args)
return nil
if c.conf.HasDoc() {
return c.doc.RunE(cmd, args)
}
if c.conf.HasDB() {
return c.db.RunE(cmd, args)
}

_, err := c.client()
return err
}
57 changes: 57 additions & 0 deletions cmd/kouchctl/cmd/delete_db.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

package cmd

import (
"github.com/spf13/cobra"

"github.com/go-kivik/xkivik/v4/cmd/kouchctl/output"
)

type deleteDB struct {
*root
}

func deleteDBCmd(r *root) *cobra.Command {
c := &deleteDB{
root: r,
}
return &cobra.Command{
Use: "database [dsn]/[database]",
Aliases: []string{"db"},
Short: "Delete a database",
RunE: c.RunE,
}
}

func (c *deleteDB) RunE(cmd *cobra.Command, _ []string) error {
client, err := c.client()
if err != nil {
return err
}
db, _, err := c.conf.DBDoc()
if err != nil {
return err
}
c.log.Debugf("[delete] Will delete database: %s/%s/%s", client.DSN(), db)
return c.retry(func() error {
err := client.DestroyDB(cmd.Context(), db, c.opts())
if err != nil {
return err
}

return c.fmt.Output(output.JSONReader(map[string]interface{}{
"ok": true,
}))
})
}
51 changes: 51 additions & 0 deletions cmd/kouchctl/cmd/delete_db_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

package cmd

import (
"io/ioutil"
"net/http"
"strings"
"testing"

"gitlab.com/flimzy/testy"

"github.com/go-kivik/xkivik/v4/cmd/kouchctl/errors"
)

func Test_delete_db_RunE(t *testing.T) {
tests := testy.NewTable()

tests.Add("missing db", cmdTest{
args: []string{"delete", "database"},
status: errors.ErrUsage,
})
tests.Add("success", func(t *testing.T) interface{} {
s := testy.ServeResponse(&http.Response{
StatusCode: http.StatusOK,
Header: http.Header{
"Content-Type": []string{"application/json"},
"Server": []string{"CouchDB/2.3.1 (Erlang OTP/20)"},
},
Body: ioutil.NopCloser(strings.NewReader(`{"ok":true}`)),
})

return cmdTest{
args: []string{"delete", "db", s.URL + "/db"},
}
})

tests.Run(t, func(t *testing.T, tt cmdTest) {
tt.Test(t)
})
}
59 changes: 59 additions & 0 deletions cmd/kouchctl/cmd/delete_doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

package cmd

import (
"github.com/spf13/cobra"

"github.com/go-kivik/xkivik/v4/cmd/kouchctl/output"
)

type deleteDoc struct {
*root
}

func deleteDocCmd(r *root) *cobra.Command {
c := &deleteDoc{
root: r,
}
return &cobra.Command{
Use: "document [dsn]/[database]/[document]",
Aliases: []string{"doc"},
Short: "Delete a document",
RunE: c.RunE,
}
}

func (c *deleteDoc) RunE(cmd *cobra.Command, _ []string) error {
client, err := c.client()
if err != nil {
return err
}
db, docID, err := c.conf.DBDoc()
if err != nil {
return err
}
c.log.Debugf("[delete] Will delete document: %s/%s/%s", client.DSN(), db, docID)
return c.retry(func() error {
newRev, err := client.DB(db).Delete(cmd.Context(), docID, "", c.opts())
if err != nil {
return err
}

return c.fmt.Output(output.JSONReader(map[string]interface{}{
"ok": true,
"id": docID,
"rev": newRev,
}))
})
}
68 changes: 68 additions & 0 deletions cmd/kouchctl/cmd/delete_doc_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

package cmd

import (
"io/ioutil"
"net/http"
"strings"
"testing"

"gitlab.com/flimzy/testy"

"github.com/go-kivik/xkivik/v4/cmd/kouchctl/errors"
)

func Test_delete_doc_RunE(t *testing.T) {
tests := testy.NewTable()

tests.Add("missing document", cmdTest{
args: []string{"delete", "doc"},
status: errors.ErrUsage,
})
tests.Add("success", func(t *testing.T) interface{} {
s := testy.ServeResponse(&http.Response{
StatusCode: http.StatusOK,
Header: http.Header{
"Content-Type": []string{"application/json"},
"Server": []string{"CouchDB/2.3.1 (Erlang OTP/20)"},
"ETag": []string{`"2-eec205a9d413992850a6e32678485900`},
},
Body: ioutil.NopCloser(strings.NewReader(`{"ok":true,"id":"fe6a1fef482d660160b45165ed001740","rev":"2-eec205a9d413992850a6e32678485900"}`)),
})

return cmdTest{
args: []string{"delete", "doc", s.URL + "/db/doc", "-O", "rev=1-xxx"},
}
})
tests.Add("no rev", func(t *testing.T) interface{} {
s := testy.ServeResponse(&http.Response{
StatusCode: http.StatusConflict,
Header: http.Header{
"Content-Type": []string{"application/json"},
"Server": []string{"CouchDB/2.3.1 (Erlang OTP/20)"},
},
Body: ioutil.NopCloser(strings.NewReader(`{"error":"conflict","reason":"Document update conflict."}
`)),
})

return cmdTest{
args: []string{"delete", "doc", s.URL + "/db/doc"},
status: errors.ErrBadRequest,
}
})

tests.Run(t, func(t *testing.T, tt cmdTest) {
tt.Test(t)
})
}
42 changes: 38 additions & 4 deletions cmd/kouchctl/cmd/delete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,52 @@
package cmd

import (
"io/ioutil"
"net/http"
"strings"
"testing"

"gitlab.com/flimzy/testy"

"github.com/go-kivik/xkivik/v4/cmd/kouchctl/errors"
)

func Test_delete_RunE(t *testing.T) {
tests := testy.NewTable()

// tests.Add("missing document", cmdTest{
// args: []string{"delete"},
// status: errors.ErrUsage,
// })
tests.Add("missing resource", cmdTest{
args: []string{"delete"},
status: errors.ErrUsage,
})
tests.Add("auto delete doc", func(t *testing.T) interface{} {
s := testy.ServeResponse(&http.Response{
StatusCode: http.StatusOK,
Header: http.Header{
"Content-Type": []string{"application/json"},
"Server": []string{"CouchDB/2.3.1 (Erlang OTP/20)"},
"ETag": []string{`"2-eec205a9d413992850a6e32678485900`},
},
Body: ioutil.NopCloser(strings.NewReader(`{"ok":true,"id":"fe6a1fef482d660160b45165ed001740","rev":"2-eec205a9d413992850a6e32678485900"}`)),
})

return cmdTest{
args: []string{"delete", s.URL + "/db/doc", "-O", "rev=1-xxx"},
}
})
tests.Add("auto delete db", func(t *testing.T) interface{} {
s := testy.ServeResponse(&http.Response{
StatusCode: http.StatusOK,
Header: http.Header{
"Content-Type": []string{"application/json"},
"Server": []string{"CouchDB/2.3.1 (Erlang OTP/20)"},
},
Body: ioutil.NopCloser(strings.NewReader(`{"ok":true}`)),
})

return cmdTest{
args: []string{"delete", s.URL + "/db"},
}
})

tests.Run(t, func(t *testing.T, tt cmdTest) {
tt.Test(t)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"ok": true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"id": "doc",
"ok": true,
"rev": "2-eec205a9d413992850a6e32678485900"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
Error: no context specified
Usage:
kouchctl delete [command] [flags]
kouchctl delete [command]

Aliases:
delete, del

Available Commands:
database Delete a database
document Delete a document

Flags:
-h, --help help for delete

Global Flags:
--connect-timeout string Limits the time spent establishing a TCP connection.
--debug Enable debug output
-f, --format string Output format. One of: json[=...]|raw|yaml|go-template=...
-H, --header Output response header
--kouchconfig string Path to kouchconfig file to use for CLI requests (default "~/.kouchctl/config")
-O, --option stringToString CouchDB options, specified as key=value. May be repeated. (default [])
-o, --output string Output file/directory.
-F, --overwrite Overwrite output file
--request-timeout string The time limit for each request.
--retry int In case of transient error, retry up to this many times. A negative value retries forever.
--retry-delay string Delay between retry attempts. Disables the default exponential backoff algorithm.
--retry-timeout string When used with --retry, no more retries will be attempted after this timeout.
-v, --verbose Output bi-directional network traffic

Use "kouchctl delete [command] --help" for more information about a command.

Loading

0 comments on commit fbee54b

Please sign in to comment.