Skip to content

Commit

Permalink
refactor(cmd): move database management commands from immuclient to i…
Browse files Browse the repository at this point in the history
…mmuadmin. Fixes #440

Signed-off-by: Michele Meloni <[email protected]>
  • Loading branch information
mmeloni committed Aug 5, 2020
1 parent d48e6e5 commit cdecd94
Show file tree
Hide file tree
Showing 10 changed files with 237 additions and 164 deletions.
110 changes: 110 additions & 0 deletions cmd/immuadmin/command/database.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
Copyright 2019-2020 vChain, Inc.
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 immuadmin

import (
"fmt"
"github.com/codenotary/immudb/pkg/api/schema"
"github.com/spf13/cobra"
"google.golang.org/protobuf/types/known/emptypb"
)

func (cl *commandline) database(cmd *cobra.Command) {
ccmd := &cobra.Command{
Use: "database",
Short: "Issue all database commands",
Aliases: []string{"d"},
PersistentPreRunE: cl.connect,
PersistentPostRun: cl.disconnect,
ValidArgs: []string{"list", "create", "use"},
}
ccd := &cobra.Command{
Use: "list",
Short: "List all databases",
Aliases: []string{"l"},
PersistentPreRunE: cl.connect,
PersistentPostRun: cl.disconnect,
RunE: func(cmd *cobra.Command, args []string) error {
resp, err := cl.immuClient.DatabaseList(cl.context, &emptypb.Empty{})
if err != nil {
cl.quit(err)
}
var dbList string
for _, val := range resp.Databases {
if cl.options.CurrentDatabase == val.Databasename {
dbList += fmt.Sprintf("*")
}
dbList += fmt.Sprintf("%s\n", val.Databasename)

}
fmt.Fprintf(cmd.OutOrStdout(), dbList+"\n")
return nil
},
Args: cobra.ExactArgs(0),
}
cc := &cobra.Command{
Use: "create",
Short: "Create a new database",
PersistentPreRunE: cl.connect,
PersistentPostRun: cl.disconnect,
Example: "create {database_name}",
RunE: func(cmd *cobra.Command, args []string) error {
if err := cl.immuClient.CreateDatabase(cl.context, &schema.Database{
Databasename: args[0],
}); err != nil {
return err
}
fmt.Fprintf(cmd.OutOrStdout(), "database successfully created\n")
return nil
},
Args: cobra.ExactArgs(1),
}

ccu := &cobra.Command{
Use: "use command",
Short: "Select database",
Example: "use {database_name}",
PersistentPreRunE: cl.connect,
PersistentPostRun: cl.disconnect,
ValidArgs: []string{"databasename"},
RunE: func(cmd *cobra.Command, args []string) error {
resp, err := cl.immuClient.UseDatabase(cl.context, &schema.Database{
Databasename: args[0],
})
if err != nil {
cl.quit(err)
}
if err != nil {
return err
}
cl.immuClient.GetOptions().CurrentDatabase = args[0]
tokenFileName := cl.immuClient.GetOptions().TokenFileName
if err = cl.hds.WriteFileToUserHomeDir([]byte(resp.Token), tokenFileName); err != nil {
return err
}

fmt.Fprintf(cmd.OutOrStdout(), "Now using %s\n", args[0])
return nil
},
Args: cobra.MaximumNArgs(2),
}

ccmd.AddCommand(ccu)
ccmd.AddCommand(ccd)
ccmd.AddCommand(cc)
cmd.AddCommand(ccmd)
}
121 changes: 121 additions & 0 deletions cmd/immuadmin/command/database_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package immuadmin

import (
"bytes"
"context"
"github.com/codenotary/immudb/cmd/immuclient/immuclienttest"
"github.com/codenotary/immudb/pkg/client"
"github.com/codenotary/immudb/pkg/server"
"github.com/codenotary/immudb/pkg/server/servertest"
"github.com/spf13/cobra"
"google.golang.org/grpc"
"io/ioutil"
"strings"
"testing"
)

func TestDatabaseList(t *testing.T) {
bs := servertest.NewBufconnServer(server.DefaultOptions().WithAuth(true).WithInMemoryStore(true))
bs.Start()

pr := &immuclienttest.PasswordReader{
Pass: []string{"immudb"},
}
hds := &immuclienttest.HomedirServiceMock{}
ctx := context.Background()
dialOptions := []grpc.DialOption{
grpc.WithContextDialer(bs.Dialer), grpc.WithInsecure(),
}
cliopt := Options().WithDialOptions(&dialOptions).WithPasswordReader(pr).
WithHomedirService(hds)
cliopt.PasswordReader = pr
cliopt.DialOptions = &dialOptions
clientb, _ := client.NewImmuClient(cliopt)
token, err := clientb.Login(ctx, []byte("immudb"), []byte("immudb"))
if err != nil {
t.Fatal(err)
}
if err = hds.WriteFileToUserHomeDir(token.Token, ""); err != nil {
t.Fatal(err)
}

cmdl := commandline{
options: cliopt,
immuClient: clientb,
passwordReader: pr,
context: ctx,
hds: hds,
}

cmd := cobra.Command{}

cmdl.database(&cmd)
b := bytes.NewBufferString("")
cmd.SetOut(b)

cmd.SetArgs([]string{"database", "list"})
err = cmd.Execute()
if err != nil {
t.Fatal(err)
}
msg, err := ioutil.ReadAll(b)
if err != nil {
t.Fatal(err)
}
if !strings.Contains(string(msg), "defaultdb") {
t.Fatal(err)
}
}

func TestDatabaseCreate(t *testing.T) {
bs := servertest.NewBufconnServer(server.DefaultOptions().WithAuth(true).WithInMemoryStore(true))
bs.Start()

pr := &immuclienttest.PasswordReader{
Pass: []string{"immudb"},
}
hds := &immuclienttest.HomedirServiceMock{}
ctx := context.Background()
dialOptions := []grpc.DialOption{
grpc.WithContextDialer(bs.Dialer), grpc.WithInsecure(),
}
cliopt := Options().WithDialOptions(&dialOptions).WithPasswordReader(pr).
WithHomedirService(hds)
cliopt.PasswordReader = pr
cliopt.DialOptions = &dialOptions
clientb, _ := client.NewImmuClient(cliopt)
token, err := clientb.Login(ctx, []byte("immudb"), []byte("immudb"))
if err != nil {
t.Fatal(err)
}
if err = hds.WriteFileToUserHomeDir(token.Token, ""); err != nil {
t.Fatal(err)
}

cmdl := commandline{
options: cliopt,
immuClient: clientb,
passwordReader: pr,
context: ctx,
hds: hds,
}

cmd := cobra.Command{}

cmdl.database(&cmd)
b := bytes.NewBufferString("")
cmd.SetOut(b)

cmd.SetArgs([]string{"database", "create", "mynewdb"})
err = cmd.Execute()
if err != nil {
t.Fatal(err)
}
msg, err := ioutil.ReadAll(b)
if err != nil {
t.Fatal(err)
}
if !strings.Contains(string(msg), "database successfully created") {
t.Fatal(string(msg))
}
}
1 change: 1 addition & 0 deletions cmd/immuadmin/command/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ func Init(rootCmd *cobra.Command, cmdName string, cfgFn *string) *cobra.Command
cl.status(rootCmd)
cl.stats(rootCmd)
cl.serverConfig(rootCmd)
cl.database(rootCmd)

os := immuos.NewStandardOS()
clb, err := newCommandlineBck(os)
Expand Down
3 changes: 0 additions & 3 deletions cmd/immuclient/cli/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,4 @@ func (cli *cli) initCommands() {
cli.Register(&command{"status", "", cli.healthCheck, nil, false})
cli.Register(&command{"history", "Fetch history for the item having the specified key", cli.history, []string{"key"}, false})
cli.Register(&command{"version", "Print version", cli.version, nil, false})

// Admin Commands
cli.Register(&command{"database", "Database operatons (help,create,list)", cli.CreateDatabase, nil, true})
}
2 changes: 1 addition & 1 deletion cmd/immuclient/cli/register_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ func TestInitCommands(t *testing.T) {
cli.commands = make(map[string]*command)
cli.commandsList = make([]*command, 0)
cli.initCommands()
assert.EqualValues(t, 26, len(cli.commands))
assert.EqualValues(t, 25, len(cli.commands))
}
14 changes: 1 addition & 13 deletions cmd/immuclient/cli/setcommands.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ limitations under the License.

package cli

import "fmt"

func (cli *cli) rawSafeSet(args []string) (string, error) {
return cli.immucl.RawSafeSet(args)
}
Expand All @@ -37,17 +35,7 @@ func (cli *cli) zAdd(args []string) (string, error) {
func (cli *cli) safeZAdd(args []string) (string, error) {
return cli.immucl.SafeZAdd(args)
}
func (cli *cli) CreateDatabase(args []string) (string, error) {
if len(args) < 1 {
return "", fmt.Errorf("wrong number of parameters")
}
if args[0] == "list" {
return cli.immucl.DatabaseList(args)
} else if args[0] == "create" {
return cli.immucl.CreateDatabase(args[1:])
}
return "", fmt.Errorf("wrong number of arguments")
}

func (cli *cli) UseDatabase(args []string) (string, error) {
return cli.immucl.UseDatabase(args)
}
34 changes: 0 additions & 34 deletions cmd/immuclient/cli/setcommands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,37 +135,3 @@ func TestSafeZAdd(t *testing.T) {
t.Fatalf("SafeZAdd failed: %s", msg)
}
}

func TestCreateDatabase(t *testing.T) {
options := server.DefaultOptions().WithAuth(true).WithInMemoryStore(true)
bs := servertest.NewBufconnServer(options)
bs.Start()
ic := test.NewClientTest(&test.PasswordReader{
Pass: []string{"immudb"},
}, &test.HomedirServiceMock{})
ic.Connect(bs.Dialer)
ic.Login("immudb")

cli := new(cli)
cli.immucl = ic.Imc
msg, err := cli.CreateDatabase([]string{"create", "newdb"})
if err != nil {
t.Fatal("CreateDatabase fail", err)
}
if !strings.Contains(msg, "database successfully created") {
t.Fatalf("CreateDatabase failed: %s", msg)
}

msg, err = cli.CreateDatabase([]string{"list"})
if err != nil {
t.Fatal("DatabaseList fail", err)
}

msg, err = cli.UseDatabase([]string{"newdb"})
if err != nil {
t.Fatal("UseDatabase fail", err)
}
if !strings.Contains(msg, "newdb") {
t.Fatalf("UseDatabase failed: %s", msg)
}
}
2 changes: 1 addition & 1 deletion cmd/immuclient/command/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ IMPORTANT: All get and safeget functions return base64-encoded keys and values,
cl.status(cmd)
cl.auditmode(cmd)
cl.interactiveCli(cmd)
cl.database(cmd)
cl.user(cmd)
cl.use(cmd)
// man file generator
cmd.AddCommand(man.Generate(cmd, "immuclient", "./cmd/docs/man/immuclient"))
Expand Down
47 changes: 2 additions & 45 deletions cmd/immuclient/command/misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,55 +208,12 @@ func (cl *commandline) user(cmd *cobra.Command) {
ccmd.AddCommand(userPermission)
cmd.AddCommand(ccmd)
}
func (cl *commandline) database(cmd *cobra.Command) {
ccmd := &cobra.Command{
Use: "database",
Short: "Issue all database commands",
Aliases: []string{"d"},
PersistentPreRunE: cl.connect,
PersistentPostRun: cl.disconnect,
ValidArgs: []string{"list", "create"},
}
ccd := &cobra.Command{
Use: "list",
Aliases: []string{"d"},
PersistentPreRunE: cl.connect,
PersistentPostRun: cl.disconnect,
RunE: func(cmd *cobra.Command, args []string) error {
resp, err := cl.immucl.DatabaseList(args)
if err != nil {
cl.quit(err)
}
fmt.Fprintf(cmd.OutOrStdout(), resp+"\n")
return nil
},
Args: cobra.ExactArgs(0),
}
cc := &cobra.Command{
Use: "create",
PersistentPreRunE: cl.connect,
PersistentPostRun: cl.disconnect,
Example: "create database_name",
RunE: func(cmd *cobra.Command, args []string) error {
resp, err := cl.immucl.CreateDatabase(args)
if err != nil {
cl.quit(err)
}
fmt.Fprintf(cmd.OutOrStdout(), resp+"\n")
return nil
},
Args: cobra.ExactArgs(1),
}
ccmd.AddCommand(ccd)
ccmd.AddCommand(cc)

cmd.AddCommand(ccmd)

}
func (cl *commandline) use(cmd *cobra.Command) {
ccmd := &cobra.Command{
Use: "use command",
Short: "select database",
Short: "Select database",
Example: "use {database_name}",
PersistentPreRunE: cl.connect,
PersistentPostRun: cl.disconnect,
ValidArgs: []string{"databasename"},
Expand Down
Loading

0 comments on commit cdecd94

Please sign in to comment.