Skip to content

Commit

Permalink
feat(cmd): add Get, Put, Delete, and interactive shell
Browse files Browse the repository at this point in the history
  • Loading branch information
ken8203 committed May 6, 2023
1 parent 697df2a commit d3329c0
Show file tree
Hide file tree
Showing 14 changed files with 867 additions and 0 deletions.
76 changes: 76 additions & 0 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package cmd

import (
"fmt"
"os"

"github.com/ken8203/tikv-cli/internal/client"
pingcaplog "github.com/pingcap/log"
"github.com/spf13/cobra"
"go.uber.org/zap"
)

var (
// Host is the PD host address.
Host string
// Port is the PD port.
Port string
// Mode is the client mode: raw/txn
Mode string
// APIVersion is the API version: v1/v1ttl/v2
APIVersion string
)

var rootCmd = &cobra.Command{
Use: "tikv-cli",
Short: "Interact with TiKV cluster through PD",
PersistentPreRun: func(cmd *cobra.Command, args []string) {

},
RunE: shellRunE,
}

func init() {
// Disable logging in tikv/client-go
pingcaplog.ReplaceGlobals(zap.NewNop(), nil)

rootCmd.PersistentFlags().StringVarP(&Host, "host", "h", "localhost", "PD host address")
rootCmd.PersistentFlags().StringVarP(&Port, "port", "p", "2379", "PD port")
rootCmd.PersistentFlags().StringVarP(&Mode, "mode", "m", "txn", "Client mode")
rootCmd.PersistentFlags().StringVarP(&APIVersion, "api-version", "a", "v2", "API version")
rootCmd.PersistentFlags().Bool("help", false, "help for tikv-cli")

rootCmd.AddCommand(versionCmd, putCmd, getCmd, deleteCmd)
}

func Execute() {
if err := rootCmd.Execute(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}

// newClient creates a tikv client.
func newClient() (client.Client, error) {
var v client.APIVersion
switch APIVersion {
case "v1":
v = client.APIVersion1
case "v1ttl":
v = client.APIVersion1TTL
case "v2":
v = client.APIVersion2
default:
v = client.APIVersion2
}

c, err := client.New([]string{addr(Host, Port)}, client.Mode(Mode), v)
if err != nil {
return nil, err
}
return c, nil
}

func addr(host, port string) string {
return host + ":" + port
}
24 changes: 24 additions & 0 deletions cmd/delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package cmd

import (
"fmt"

"github.com/spf13/cobra"
)

var deleteCmd = &cobra.Command{
Use: "delete",
Aliases: []string{"del"},
Short: "Delete a key",
RunE: deleteRunE,
}

func deleteRunE(cmd *cobra.Command, args []string) error {
client, err := newClient()
if err != nil {
return fmt.Errorf("new client: %v", err)
}
defer client.Close(cmd.Context())

return client.Delete(cmd.Context(), []byte(args[0]))
}
39 changes: 39 additions & 0 deletions cmd/get.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package cmd

import (
"errors"
"fmt"
"os"

"github.com/spf13/cobra"
tikverror "github.com/tikv/client-go/v2/error"
)

var getCmd = &cobra.Command{
Use: "get",
Short: "Get a key",
RunE: getRunE,
}

func getRunE(cmd *cobra.Command, args []string) error {
client, err := newClient()
if err != nil {
return fmt.Errorf("new client: %v", err)
}
defer client.Close(cmd.Context())

value, err := client.Get(cmd.Context(), []byte(args[0]))
if err != nil {
if errors.Is(err, tikverror.ErrNotExist) {
fmt.Fprintf(os.Stdout, "key [%s] not exist\n", args[0])
return nil
}

return fmt.Errorf("get: %w", err)
}

if _, err := fmt.Fprintln(os.Stdout, string(value)); err != nil {
return err
}
return nil
}
23 changes: 23 additions & 0 deletions cmd/put.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package cmd

import (
"fmt"

"github.com/spf13/cobra"
)

var putCmd = &cobra.Command{
Use: "put",
Short: "Put a key",
RunE: putRunE,
}

func putRunE(cmd *cobra.Command, args []string) error {
client, err := newClient()
if err != nil {
return fmt.Errorf("new client: %v", err)
}
defer client.Close(cmd.Context())

return client.Put(cmd.Context(), []byte(args[0]), []byte(args[1]))
}
69 changes: 69 additions & 0 deletions cmd/shell.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package cmd

import (
"context"
"errors"
"fmt"
"os"
"strings"

"github.com/ken8203/tikv-cli/internal/terminal"
"github.com/spf13/cobra"
tikverror "github.com/tikv/client-go/v2/error"
)

// shellRunE is the entry of shell command.
func shellRunE(cmd *cobra.Command, args []string) error {
client, err := newClient()
if err != nil {
return fmt.Errorf("new client: %v", err)
}
defer client.Close(cmd.Context())

executeFn := func(ctx context.Context, command string) {
fields := strings.Fields(command)
if len(fields) == 0 {
return
}

switch strings.ToLower(fields[0]) {
case "put":
if len(fields) != 3 {
fmt.Fprintln(os.Stdout, "(error) ERR wrong number of arguments for 'put' command")
break
}

if err := client.Put(ctx, []byte(fields[1]), []byte(fields[2])); err != nil {
fmt.Fprintln(os.Stdout, err.Error())
}
case "get":
if len(fields) != 2 {
fmt.Fprintln(os.Stdout, "(error) ERR wrong number of arguments for 'get' command")
break
}

value, err := client.Get(ctx, []byte(fields[1]))
if err != nil {
if errors.Is(err, tikverror.ErrNotExist) {
fmt.Fprintln(os.Stdout, "(nil)")
break
}
fmt.Fprintln(os.Stdout, err.Error())
}

fmt.Fprintln(os.Stdout, string(value))
case "delete":
if len(fields) != 2 {
fmt.Fprintln(os.Stdout, "(error) ERR wrong number of arguments for 'delete' command")
break
}

if err := client.Delete(ctx, []byte(fields[1])); err != nil {
fmt.Fprintln(os.Stdout, err.Error())
}
}
}

return terminal.New(addr(Host, Port), executeFn).
Prompt(cmd.Context())
}
19 changes: 19 additions & 0 deletions cmd/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package cmd

import (
"os"

"github.com/spf13/cobra"
)

// Version can be set the version info from the -ldflags when building
var Version string

var versionCmd = &cobra.Command{
Use: "version",
Short: "Print the version number of tikv-cli",
RunE: func(_ *cobra.Command, _ []string) error {
_, err := os.Stdout.Write([]byte("tikv-cli " + Version))
return err
},
}
52 changes: 52 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,55 @@
module github.com/ken8203/tikv-cli

go 1.20

require (
github.com/pingcap/kvproto v0.0.0-20230403051650-e166ae588106
github.com/pingcap/log v1.1.1-0.20221110025148-ca232912c9f3
github.com/spf13/cobra v1.7.0
github.com/tikv/client-go/v2 v2.0.7
go.uber.org/zap v1.24.0
)

require (
github.com/benbjohnson/clock v1.3.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/coreos/go-semver v0.3.0 // indirect
github.com/coreos/go-systemd/v22 v22.3.2 // indirect
github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 // indirect
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 // indirect
github.com/elastic/gosigar v0.14.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/pingcap/errors v0.11.5-0.20211224045212-9687c2b0f87c // indirect
github.com/pingcap/failpoint v0.0.0-20220801062533-2eaa32854a6c // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_golang v1.14.0 // indirect
github.com/prometheus/client_model v0.3.0 // indirect
github.com/prometheus/common v0.39.0 // indirect
github.com/prometheus/procfs v0.9.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/tiancaiamao/gp v0.0.0-20221230034425-4025bc8a4d4a // indirect
github.com/tikv/pd/client v0.0.0-20230329114254-1948c247c2b1 // indirect
github.com/twmb/murmur3 v1.1.3 // indirect
go.etcd.io/etcd/api/v3 v3.5.2 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.2 // indirect
go.etcd.io/etcd/client/v3 v3.5.2 // indirect
go.uber.org/atomic v1.10.0 // indirect
go.uber.org/multierr v1.9.0 // indirect
golang.org/x/net v0.8.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.6.0 // indirect
golang.org/x/text v0.8.0 // indirect
google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633 // indirect
google.golang.org/grpc v1.54.0 // indirect
google.golang.org/protobuf v1.30.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
)
Loading

0 comments on commit d3329c0

Please sign in to comment.