diff --git a/base/commands/map/common.go b/base/commands/map/common.go index 4cc97eba..4edf5c9a 100644 --- a/base/commands/map/common.go +++ b/base/commands/map/common.go @@ -3,11 +3,15 @@ package _map import ( + "context" "fmt" "strings" "github.com/hazelcast/hazelcast-go-client" + "github.com/hazelcast/hazelcast-commandline-client/base" + "github.com/hazelcast/hazelcast-commandline-client/clc" + "github.com/hazelcast/hazelcast-commandline-client/clc/cmd" "github.com/hazelcast/hazelcast-commandline-client/internal" "github.com/hazelcast/hazelcast-commandline-client/internal/mk" "github.com/hazelcast/hazelcast-commandline-client/internal/plug" @@ -58,3 +62,13 @@ func makeKeyValueData(ec plug.ExecContext, ci *hazelcast.ClientInternal, keyStr, } return kd, vd, nil } + +func getMap(ctx context.Context, ec plug.ExecContext, sp clc.Spinner) (*hazelcast.Map, error) { + name := ec.Props().GetString(base.FlagName) + ci, err := cmd.ClientInternal(ctx, ec, sp) + if err != nil { + return nil, err + } + sp.SetText(fmt.Sprintf("Getting map %s", name)) + return ci.Client().GetMap(ctx, name) +} diff --git a/base/commands/map/map.go b/base/commands/map/map.go index 40de412f..b43256b5 100644 --- a/base/commands/map/map.go +++ b/base/commands/map/map.go @@ -4,24 +4,15 @@ package _map import ( "context" - "fmt" - - "github.com/hazelcast/hazelcast-go-client" + "github.com/hazelcast/hazelcast-commandline-client/base" "github.com/hazelcast/hazelcast-commandline-client/clc" "github.com/hazelcast/hazelcast-commandline-client/clc/paths" . "github.com/hazelcast/hazelcast-commandline-client/internal/check" "github.com/hazelcast/hazelcast-commandline-client/internal/plug" ) -const ( - mapFlagName = "name" - mapFlagShowType = "show-type" - mapPropertyName = "map" -) - -type MapCommand struct { -} +type MapCommand struct{} func (mc *MapCommand) Init(cc plug.InitContext) error { cc.SetCommandUsage("map") @@ -30,8 +21,8 @@ func (mc *MapCommand) Init(cc plug.InitContext) error { cc.SetCommandGroup(clc.GroupDDSID) help := "Map operations" cc.SetCommandHelp(help, help) - cc.AddStringFlag(mapFlagName, "n", defaultMapName, false, "map name") - cc.AddBoolFlag(mapFlagShowType, "", false, false, "add the type names to the output") + cc.AddStringFlag(base.FlagName, "n", defaultMapName, false, "map name") + cc.AddBoolFlag(base.FlagShowType, "", false, false, "add the type names to the output") if !cc.Interactive() { cc.AddStringFlag(clc.PropertySchemaDir, "", paths.Schemas(), false, "set the schema directory") } @@ -42,34 +33,6 @@ func (mc *MapCommand) Exec(context.Context, plug.ExecContext) error { return nil } -func (mc *MapCommand) Augment(ec plug.ExecContext, props *plug.Properties) error { - ctx := context.TODO() - props.SetBlocking(mapPropertyName, func() (any, error) { - mapName := ec.Props().GetString(mapFlagName) - // empty map name is allowed - ci, err := ec.ClientInternal(ctx) - if err != nil { - return nil, err - } - mv, stop, err := ec.ExecuteBlocking(ctx, func(ctx context.Context, sp clc.Spinner) (any, error) { - sp.SetText(fmt.Sprintf("Getting map %s", mapName)) - m, err := ci.Client().GetMap(ctx, mapName) - if err != nil { - return nil, err - } - return m, nil - }) - if err != nil { - return nil, err - } - stop() - return mv.(*hazelcast.Map), nil - }) - return nil -} - func init() { - cmd := &MapCommand{} - Must(plug.Registry.RegisterCommand("map", cmd)) - plug.Registry.RegisterAugmentor("20-map", cmd) + Must(plug.Registry.RegisterCommand("map", &MapCommand{})) } diff --git a/base/commands/map/map_clear.go b/base/commands/map/map_clear.go index a48daf49..baf33043 100644 --- a/base/commands/map/map_clear.go +++ b/base/commands/map/map_clear.go @@ -6,8 +6,6 @@ import ( "context" "fmt" - "github.com/hazelcast/hazelcast-go-client" - "github.com/hazelcast/hazelcast-commandline-client/errors" "github.com/hazelcast/hazelcast-commandline-client/internal/prompt" @@ -19,6 +17,8 @@ import ( type MapClearCommand struct{} +func (mc *MapClearCommand) Unwrappable() {} + func (mc *MapClearCommand) Init(cc plug.InitContext) error { cc.SetCommandUsage("clear") help := "Delete all entries of a Map" @@ -28,10 +28,6 @@ func (mc *MapClearCommand) Init(cc plug.InitContext) error { } func (mc *MapClearCommand) Exec(ctx context.Context, ec plug.ExecContext) error { - mv, err := ec.Props().GetBlocking(mapPropertyName) - if err != nil { - return err - } autoYes := ec.Props().GetBool(clc.FlagAutoYes) if !autoYes { p := prompt.New(ec.Stdin(), ec.Stdout()) @@ -44,18 +40,23 @@ func (mc *MapClearCommand) Exec(ctx context.Context, ec plug.ExecContext) error return errors.ErrUserCancelled } } - m := mv.(*hazelcast.Map) - _, stop, err := ec.ExecuteBlocking(ctx, func(ctx context.Context, sp clc.Spinner) (any, error) { + name, stop, err := ec.ExecuteBlocking(ctx, func(ctx context.Context, sp clc.Spinner) (any, error) { + m, err := getMap(ctx, ec, sp) + if err != nil { + return nil, err + } sp.SetText(fmt.Sprintf("Clearing map %s", m.Name())) if err := m.Clear(ctx); err != nil { return nil, err } - return nil, nil + return m.Name(), nil }) if err != nil { return err } stop() + msg := fmt.Sprintf("OK Cleared map: %s.", name) + ec.PrintlnUnnecessary(msg) return nil } diff --git a/base/commands/map/map_destroy.go b/base/commands/map/map_destroy.go index e4d7df35..3b286625 100644 --- a/base/commands/map/map_destroy.go +++ b/base/commands/map/map_destroy.go @@ -6,8 +6,6 @@ import ( "context" "fmt" - "github.com/hazelcast/hazelcast-go-client" - "github.com/hazelcast/hazelcast-commandline-client/clc" "github.com/hazelcast/hazelcast-commandline-client/errors" . "github.com/hazelcast/hazelcast-commandline-client/internal/check" @@ -17,6 +15,8 @@ import ( type MapDestroyCommand struct{} +func (mc *MapDestroyCommand) Unwrappable() {} + func (mc *MapDestroyCommand) Init(cc plug.InitContext) error { cc.SetCommandUsage("destroy") long := `Destroy a Map @@ -29,10 +29,6 @@ This command will delete the Map and the data in it will not be available anymor } func (mc *MapDestroyCommand) Exec(ctx context.Context, ec plug.ExecContext) error { - mv, err := ec.Props().GetBlocking(mapPropertyName) - if err != nil { - return err - } autoYes := ec.Props().GetBool(clc.FlagAutoYes) if !autoYes { p := prompt.New(ec.Stdin(), ec.Stdout()) @@ -45,18 +41,23 @@ func (mc *MapDestroyCommand) Exec(ctx context.Context, ec plug.ExecContext) erro return errors.ErrUserCancelled } } - m := mv.(*hazelcast.Map) - _, stop, err := ec.ExecuteBlocking(ctx, func(ctx context.Context, sp clc.Spinner) (any, error) { + name, stop, err := ec.ExecuteBlocking(ctx, func(ctx context.Context, sp clc.Spinner) (any, error) { + m, err := getMap(ctx, ec, sp) + if err != nil { + return nil, err + } sp.SetText(fmt.Sprintf("Destroying map %s", m.Name())) if err := m.Destroy(ctx); err != nil { return nil, err } - return nil, nil + return m.Name(), nil }) if err != nil { return err } stop() + msg := fmt.Sprintf("OK Destroyed map %s.", name) + ec.PrintlnUnnecessary(msg) return nil } diff --git a/base/commands/map/map_entry_set.go b/base/commands/map/map_entry_set.go index 2b749c7a..ed7874dc 100644 --- a/base/commands/map/map_entry_set.go +++ b/base/commands/map/map_entry_set.go @@ -6,9 +6,9 @@ import ( "context" "fmt" - "github.com/hazelcast/hazelcast-go-client" - + "github.com/hazelcast/hazelcast-commandline-client/base" "github.com/hazelcast/hazelcast-commandline-client/clc" + "github.com/hazelcast/hazelcast-commandline-client/clc/cmd" "github.com/hazelcast/hazelcast-commandline-client/internal/output" "github.com/hazelcast/hazelcast-commandline-client/internal/plug" "github.com/hazelcast/hazelcast-commandline-client/internal/proto/codec" @@ -18,6 +18,8 @@ import ( type MapEntrySetCommand struct{} +func (mc *MapEntrySetCommand) Unwrappable() {} + func (mc *MapEntrySetCommand) Init(cc plug.InitContext) error { cc.SetCommandUsage("entry-set") help := "Get all entries of a Map" @@ -26,28 +28,33 @@ func (mc *MapEntrySetCommand) Init(cc plug.InitContext) error { } func (mc *MapEntrySetCommand) Exec(ctx context.Context, ec plug.ExecContext) error { - mapName := ec.Props().GetString(mapFlagName) - showType := ec.Props().GetBool(mapFlagShowType) - ci, err := ec.ClientInternal(ctx) - if err != nil { - return err - } - req := codec.EncodeMapEntrySetRequest(mapName) - rv, stop, err := ec.ExecuteBlocking(ctx, func(ctx context.Context, sp clc.Spinner) (any, error) { + mapName := ec.Props().GetString(base.FlagName) + showType := ec.Props().GetBool(base.FlagShowType) + rowsV, stop, err := ec.ExecuteBlocking(ctx, func(ctx context.Context, sp clc.Spinner) (any, error) { + ci, err := cmd.ClientInternal(ctx, ec, sp) + if err != nil { + return nil, err + } + req := codec.EncodeMapEntrySetRequest(mapName) sp.SetText(fmt.Sprintf("Getting entries of %s", mapName)) - return ci.InvokeOnRandomTarget(ctx, req, nil) + resp, err := ci.InvokeOnRandomTarget(ctx, req, nil) + if err != nil { + return nil, err + } + pairs := codec.DecodeMapEntrySetResponse(resp) + rows := output.DecodePairs(ci, pairs, showType) + return rows, nil }) if err != nil { return err } stop() - pairs := codec.DecodeMapEntrySetResponse(rv.(*hazelcast.ClientMessage)) - rows := output.DecodePairs(ci, pairs, showType) - if len(rows) > 0 { - return ec.AddOutputRows(ctx, rows...) + rows := rowsV.([]output.Row) + if len(rows) == 0 { + ec.PrintlnUnnecessary("OK No entries found.") + return nil } - ec.PrintlnUnnecessary("No entries found.") - return nil + return ec.AddOutputRows(ctx, rows...) } func init() { diff --git a/base/commands/map/map_get.go b/base/commands/map/map_get.go index 78741f59..b52a6130 100644 --- a/base/commands/map/map_get.go +++ b/base/commands/map/map_get.go @@ -6,9 +6,9 @@ import ( "context" "fmt" - "github.com/hazelcast/hazelcast-go-client" - + "github.com/hazelcast/hazelcast-commandline-client/base" "github.com/hazelcast/hazelcast-commandline-client/clc" + "github.com/hazelcast/hazelcast-commandline-client/clc/cmd" . "github.com/hazelcast/hazelcast-commandline-client/internal/check" "github.com/hazelcast/hazelcast-commandline-client/internal/output" "github.com/hazelcast/hazelcast-commandline-client/internal/plug" @@ -18,6 +18,8 @@ import ( type MapGetCommand struct{} +func (mc *MapGetCommand) Unwrappable() {} + func (mc *MapGetCommand) Init(cc plug.InitContext) error { cc.SetCommandUsage("get") addKeyTypeFlag(cc) @@ -28,47 +30,52 @@ func (mc *MapGetCommand) Init(cc plug.InitContext) error { } func (mc *MapGetCommand) Exec(ctx context.Context, ec plug.ExecContext) error { - mapName := ec.Props().GetString(mapFlagName) - ci, err := ec.ClientInternal(ctx) - if err != nil { - return err - } + mapName := ec.Props().GetString(base.FlagName) keyStr := ec.GetStringArg(argKey) - keyData, err := makeKeyData(ec, ci, keyStr) - if err != nil { - return err - } - req := codec.EncodeMapGetRequest(mapName, keyData, 0) - rv, stop, err := ec.ExecuteBlocking(ctx, func(ctx context.Context, sp clc.Spinner) (any, error) { + showType := ec.Props().GetBool(base.FlagShowType) + rowV, stop, err := ec.ExecuteBlocking(ctx, func(ctx context.Context, sp clc.Spinner) (any, error) { + ci, err := cmd.ClientInternal(ctx, ec, sp) + if err != nil { + return nil, err + } sp.SetText(fmt.Sprintf("Getting from map %s", mapName)) - return ci.InvokeOnKey(ctx, req, keyData, nil) + keyData, err := makeKeyData(ec, ci, keyStr) + if err != nil { + return nil, err + } + req := codec.EncodeMapGetRequest(mapName, keyData, 0) + resp, err := ci.InvokeOnKey(ctx, req, keyData, nil) + if err != nil { + return nil, err + } + data := codec.DecodeMapGetResponse(resp) + vt := data.Type() + value, err := ci.DecodeData(data) + if err != nil { + ec.Logger().Info("The value for %s was not decoded, due to error: %s", keyStr, err.Error()) + value = serialization.NondecodedType(serialization.TypeToLabel(vt)) + } + row := output.Row{ + output.Column{ + Name: output.NameValue, + Type: vt, + Value: value, + }, + } + if showType { + row = append(row, output.Column{ + Name: output.NameValueType, + Type: serialization.TypeString, + Value: serialization.TypeToLabel(vt), + }) + } + return row, nil }) if err != nil { return err } stop() - raw := codec.DecodeMapGetResponse(rv.(*hazelcast.ClientMessage)) - vt := raw.Type() - value, err := ci.DecodeData(raw) - if err != nil { - ec.Logger().Info("The value for %s was not decoded, due to error: %s", keyStr, err.Error()) - value = serialization.NondecodedType(serialization.TypeToLabel(vt)) - } - row := output.Row{ - output.Column{ - Name: output.NameValue, - Type: vt, - Value: value, - }, - } - if ec.Props().GetBool(mapFlagShowType) { - row = append(row, output.Column{ - Name: output.NameValueType, - Type: serialization.TypeString, - Value: serialization.TypeToLabel(vt), - }) - } - return ec.AddOutputRows(ctx, row) + return ec.AddOutputRows(ctx, rowV.(output.Row)) } func init() { diff --git a/base/commands/map/map_it_test.go b/base/commands/map/map_it_test.go index ae5882ff..a9d36eec 100644 --- a/base/commands/map/map_it_test.go +++ b/base/commands/map/map_it_test.go @@ -154,7 +154,6 @@ func size_InteractiveTest(t *testing.T) { tcx.WithReset(func() { check.Must(m.Set(ctx, "foo", "bar")) tcx.WriteStdin([]byte(fmt.Sprintf("\\map -n %s size\n", m.Name()))) - tcx.AssertStderrContains("OK") tcx.AssertStdoutDollarWithPath("testdata/map_size_1.txt") }) }) @@ -196,14 +195,12 @@ func keySet_InteractiveTest(t *testing.T) { tcx.WithReset(func() { check.Must(m.Set(ctx, "foo", "bar")) tcx.WriteStdin([]byte(fmt.Sprintf("\\map -n %s key-set\n", m.Name()))) - tcx.AssertStderrContains("OK") tcx.AssertStdoutDollarWithPath("testdata/map_key_set.txt") }) // show type tcx.WithReset(func() { check.Must(m.Set(ctx, "foo", "bar")) tcx.WriteStdin([]byte(fmt.Sprintf("\\map -n %s key-set --show-type\n", m.Name()))) - tcx.AssertStderrContains("OK") tcx.AssertStdoutDollarWithPath("testdata/map_key_set_show_type.txt") }) }) @@ -259,13 +256,13 @@ func lock_InteractiveTest(t *testing.T) { go tcx.WithShell(context.TODO(), func(tcx it.TestContext) { tcx.WithReset(func() { tcx.WriteStdinf(fmt.Sprintf("\\map -n %s lock %s\n", m.Name(), key)) - tcx.AssertStderrContains("OK") + tcx.AssertStdoutContains("OK") contUnlock <- true }) tcx.WithReset(func() { <-contLock tcx.WriteStdinf(fmt.Sprintf("\\map -n %s unlock %s\n", m.Name(), key)) - tcx.AssertStderrContains("OK") + tcx.AssertStdoutContains("OK") contUnlock <- true }) }) @@ -334,7 +331,7 @@ func loadAll_Replacing_NonInteractiveTest(t *testing.T) { check.Must(m.PutTransient(context.Background(), "k0", "new-v0")) check.Must(m.PutTransient(context.Background(), "k1", "new-v1")) check.Must(tcx.CLC().Execute(ctx, "map", "-n", m.Name(), "load-all", "--replace")) - tcx.AssertStderrContains("OK") + tcx.AssertStdoutContains("OK") require.Equal(t, "v0", check.MustValue(m.Get(ctx, "k0"))) require.Equal(t, "v1", check.MustValue(m.Get(ctx, "k1"))) }) @@ -353,7 +350,7 @@ func loadAll_NonReplacing_NonInteractiveTest(t *testing.T) { check.Must(m.PutTransient(context.Background(), "k0", "new-v0")) check.Must(m.PutTransient(context.Background(), "k1", "new-v1")) check.Must(tcx.CLC().Execute(ctx, "map", "-n", m.Name(), "load-all")) - tcx.AssertStderrContains("OK") + tcx.AssertStdoutContains("OK") require.Equal(t, "new-v0", check.MustValue(m.Get(ctx, "k0"))) require.Equal(t, "new-v1", check.MustValue(m.Get(ctx, "k1"))) }) @@ -372,7 +369,7 @@ func loadAll_Replacing_WithKeys_NonInteractiveTest(t *testing.T) { check.Must(m.PutTransient(context.Background(), "k0", "new-v0")) check.Must(m.PutTransient(context.Background(), "k1", "new-v1")) check.Must(tcx.CLC().Execute(ctx, "map", "-n", m.Name(), "load-all", "k0", "--replace")) - tcx.AssertStderrContains("OK") + tcx.AssertStdoutContains("OK") require.Equal(t, "v0", check.MustValue(m.Get(ctx, "k0"))) require.Equal(t, "new-v1", check.MustValue(m.Get(ctx, "k1"))) }) diff --git a/base/commands/map/map_key_set.go b/base/commands/map/map_key_set.go index 27d27b7c..0c678c9c 100644 --- a/base/commands/map/map_key_set.go +++ b/base/commands/map/map_key_set.go @@ -6,11 +6,11 @@ import ( "context" "fmt" + "github.com/hazelcast/hazelcast-commandline-client/base" + "github.com/hazelcast/hazelcast-commandline-client/clc/cmd" "github.com/hazelcast/hazelcast-commandline-client/internal/output" "github.com/hazelcast/hazelcast-commandline-client/internal/serialization" - "github.com/hazelcast/hazelcast-go-client" - "github.com/hazelcast/hazelcast-commandline-client/clc" "github.com/hazelcast/hazelcast-commandline-client/internal/plug" "github.com/hazelcast/hazelcast-commandline-client/internal/proto/codec" @@ -20,6 +20,8 @@ import ( type MapKeySetCommand struct{} +func (mc *MapKeySetCommand) Unwrappable() {} + func (mc *MapKeySetCommand) Init(cc plug.InitContext) error { cc.SetCommandUsage("key-set") help := "Get all keys of a Map" @@ -28,43 +30,47 @@ func (mc *MapKeySetCommand) Init(cc plug.InitContext) error { } func (mc *MapKeySetCommand) Exec(ctx context.Context, ec plug.ExecContext) error { - mapName := ec.Props().GetString(mapFlagName) - showType := ec.Props().GetBool(mapFlagShowType) - ci, err := ec.ClientInternal(ctx) - if err != nil { - return err - } - req := codec.EncodeMapKeySetRequest(mapName) - rv, stop, err := ec.ExecuteBlocking(ctx, func(ctx context.Context, sp clc.Spinner) (any, error) { + mapName := ec.Props().GetString(base.FlagName) + showType := ec.Props().GetBool(base.FlagShowType) + rowsV, stop, err := ec.ExecuteBlocking(ctx, func(ctx context.Context, sp clc.Spinner) (any, error) { + ci, err := cmd.ClientInternal(ctx, ec, sp) + if err != nil { + return nil, err + } + req := codec.EncodeMapKeySetRequest(mapName) sp.SetText(fmt.Sprintf("Getting keys of %s", mapName)) - return ci.InvokeOnRandomTarget(ctx, req, nil) + resp, err := ci.InvokeOnRandomTarget(ctx, req, nil) + if err != nil { + return nil, err + } + data := codec.DecodeMapKeySetResponse(resp) + var rows []output.Row + for _, r := range data { + var row output.Row + t := r.Type() + v, err := ci.DecodeData(*r) + if err != nil { + v = serialization.NondecodedType(serialization.TypeToLabel(t)) + } + row = append(row, output.NewKeyColumn(t, v)) + if showType { + row = append(row, output.NewKeyTypeColumn(t)) + } + rows = append(rows, row) + } + return rows, nil }) if err != nil { return err } stop() - raw := codec.DecodeMapKeySetResponse(rv.(*hazelcast.ClientMessage)) - var rows []output.Row - for _, r := range raw { - var row output.Row - t := r.Type() - v, err := ci.DecodeData(*r) - if err != nil { - v = serialization.NondecodedType(serialization.TypeToLabel(t)) - } - row = append(row, output.NewKeyColumn(t, v)) - if showType { - row = append(row, output.NewKeyTypeColumn(t)) - } - rows = append(rows, row) - } - if len(rows) > 0 { - return ec.AddOutputRows(ctx, rows...) - } - - ec.PrintlnUnnecessary("No entries found.") + rows := rowsV.([]output.Row) + if len(rows) == 0 { + ec.PrintlnUnnecessary("OK No entries found.") + return nil - return nil + } + return ec.AddOutputRows(ctx, rows...) } func init() { diff --git a/base/commands/map/map_load_all.go b/base/commands/map/map_load_all.go index bf8cb0ed..8afd19ba 100644 --- a/base/commands/map/map_load_all.go +++ b/base/commands/map/map_load_all.go @@ -8,7 +8,9 @@ import ( "github.com/hazelcast/hazelcast-go-client" + "github.com/hazelcast/hazelcast-commandline-client/base" "github.com/hazelcast/hazelcast-commandline-client/clc" + "github.com/hazelcast/hazelcast-commandline-client/clc/cmd" . "github.com/hazelcast/hazelcast-commandline-client/internal/check" "github.com/hazelcast/hazelcast-commandline-client/internal/plug" "github.com/hazelcast/hazelcast-commandline-client/internal/proto/codec" @@ -16,6 +18,8 @@ import ( type MapLoadAllCommand struct{} +func (mc *MapLoadAllCommand) Unwrappable() {} + func (mc *MapLoadAllCommand) Init(cc plug.InitContext) error { cc.SetCommandUsage("load-all") long := `Load keys from map-store into the map @@ -30,34 +34,39 @@ If no key is given, all keys are loaded.` } func (mc *MapLoadAllCommand) Exec(ctx context.Context, ec plug.ExecContext) error { - mapName := ec.Props().GetString(mapFlagName) - ci, err := ec.ClientInternal(ctx) - if err != nil { - return err - } - var keys []hazelcast.Data - for _, keyStr := range ec.GetStringSliceArg(argKey) { - keyData, err := makeKeyData(ec, ci, keyStr) + mapName := ec.Props().GetString(base.FlagName) + _, stop, err := ec.ExecuteBlocking(ctx, func(ctx context.Context, sp clc.Spinner) (any, error) { + ci, err := cmd.ClientInternal(ctx, ec, sp) if err != nil { - return err + return nil, err + } + var keys []hazelcast.Data + for _, keyStr := range ec.GetStringSliceArg(argKey) { + keyData, err := makeKeyData(ec, ci, keyStr) + if err != nil { + return nil, err + } + keys = append(keys, keyData) + } + replace := ec.Props().GetBool(mapFlagReplace) + var req *hazelcast.ClientMessage + if len(keys) == 0 { + req = codec.EncodeMapLoadAllRequest(mapName, replace) + } else { + req = codec.EncodeMapLoadGivenKeysRequest(mapName, keys, replace) } - keys = append(keys, keyData) - } - replace := ec.Props().GetBool(mapFlagReplace) - var req *hazelcast.ClientMessage - if len(keys) == 0 { - req = codec.EncodeMapLoadAllRequest(mapName, replace) - } else { - req = codec.EncodeMapLoadGivenKeysRequest(mapName, keys, replace) - } - _, stop, err := ec.ExecuteBlocking(ctx, func(ctx context.Context, sp clc.Spinner) (any, error) { sp.SetText(fmt.Sprintf("Loading keys into the map %s", mapName)) - return ci.InvokeOnRandomTarget(ctx, req, nil) + if _, err = ci.InvokeOnRandomTarget(ctx, req, nil); err != nil { + return nil, err + } + return nil, nil }) if err != nil { return err } stop() + msg := fmt.Sprintf("OK Loaded the keys into map %s", mapName) + ec.PrintlnUnnecessary(msg) return nil } diff --git a/base/commands/map/map_lock.go b/base/commands/map/map_lock.go index 02e2c53f..4023f666 100644 --- a/base/commands/map/map_lock.go +++ b/base/commands/map/map_lock.go @@ -7,15 +7,17 @@ import ( "fmt" "time" - "github.com/hazelcast/hazelcast-go-client" - + "github.com/hazelcast/hazelcast-commandline-client/base" "github.com/hazelcast/hazelcast-commandline-client/clc" + "github.com/hazelcast/hazelcast-commandline-client/clc/cmd" . "github.com/hazelcast/hazelcast-commandline-client/internal/check" "github.com/hazelcast/hazelcast-commandline-client/internal/plug" ) type MapLock struct{} +func (mc *MapLock) Unwrappable() {} + func (mc *MapLock) Init(cc plug.InitContext) error { cc.SetCommandUsage("lock") long := `Lock a key in the given Map @@ -30,22 +32,21 @@ This command is only available in the interactive mode.` } func (mc *MapLock) Exec(ctx context.Context, ec plug.ExecContext) error { - mapName := ec.Props().GetString(mapFlagName) - ci, err := ec.ClientInternal(ctx) - if err != nil { - return err - } - mv, err := ec.Props().GetBlocking(mapPropertyName) - if err != nil { - return err - } - m := mv.(*hazelcast.Map) - keyStr := ec.GetStringArg(argKey) - keyData, err := makeKeyData(ec, ci, keyStr) - if err != nil { - return err - } + mapName := ec.Props().GetString(base.FlagName) _, stop, err := ec.ExecuteBlocking(ctx, func(ctx context.Context, sp clc.Spinner) (any, error) { + ci, err := cmd.ClientInternal(ctx, ec, sp) + if err != nil { + return nil, err + } + m, err := getMap(ctx, ec, sp) + if err != nil { + return nil, err + } + keyStr := ec.GetStringArg(argKey) + keyData, err := makeKeyData(ec, ci, keyStr) + if err != nil { + return nil, err + } sp.SetText(fmt.Sprintf("Locking key in map %s", mapName)) if ttl := GetTTL(ec); ttl != ttlUnset { return nil, m.LockWithLease(ctx, keyData, time.Duration(GetTTL(ec))) @@ -56,6 +57,8 @@ func (mc *MapLock) Exec(ctx context.Context, ec plug.ExecContext) error { return err } stop() + msg := fmt.Sprintf("OK Locked the key in map %s", mapName) + ec.PrintlnUnnecessary(msg) return nil } diff --git a/base/commands/map/map_remove.go b/base/commands/map/map_remove.go index 2261f377..059577ca 100644 --- a/base/commands/map/map_remove.go +++ b/base/commands/map/map_remove.go @@ -6,9 +6,9 @@ import ( "context" "fmt" - "github.com/hazelcast/hazelcast-go-client" - + "github.com/hazelcast/hazelcast-commandline-client/base" "github.com/hazelcast/hazelcast-commandline-client/clc" + "github.com/hazelcast/hazelcast-commandline-client/clc/cmd" . "github.com/hazelcast/hazelcast-commandline-client/internal/check" "github.com/hazelcast/hazelcast-commandline-client/internal/output" "github.com/hazelcast/hazelcast-commandline-client/internal/plug" @@ -18,6 +18,8 @@ import ( type MapRemoveCommand struct{} +func (mc *MapRemoveCommand) Unwrappable() {} + func (mc *MapRemoveCommand) Init(cc plug.InitContext) error { cc.SetCommandUsage("remove") help := "Remove a value from the given Map" @@ -28,47 +30,54 @@ func (mc *MapRemoveCommand) Init(cc plug.InitContext) error { } func (mc *MapRemoveCommand) Exec(ctx context.Context, ec plug.ExecContext) error { - mapName := ec.Props().GetString(mapFlagName) - ci, err := ec.ClientInternal(ctx) - if err != nil { - return err - } - keyStr := ec.GetStringArg(argKey) - keyData, err := makeKeyData(ec, ci, keyStr) - if err != nil { - return err - } - req := codec.EncodeMapRemoveRequest(mapName, keyData, 0) - rv, stop, err := ec.ExecuteBlocking(ctx, func(ctx context.Context, sp clc.Spinner) (any, error) { + mapName := ec.Props().GetString(base.FlagName) + showType := ec.Props().GetBool(base.FlagShowType) + rowV, stop, err := ec.ExecuteBlocking(ctx, func(ctx context.Context, sp clc.Spinner) (any, error) { + ci, err := cmd.ClientInternal(ctx, ec, sp) + if err != nil { + return nil, err + } + keyStr := ec.GetStringArg(argKey) + keyData, err := makeKeyData(ec, ci, keyStr) + if err != nil { + return nil, err + } + req := codec.EncodeMapRemoveRequest(mapName, keyData, 0) sp.SetText(fmt.Sprintf("Removing from map %s", mapName)) - return ci.InvokeOnKey(ctx, req, keyData, nil) + resp, err := ci.InvokeOnKey(ctx, req, keyData, nil) + if err != nil { + return nil, err + } + raw := codec.DecodeMapRemoveResponse(resp) + vt := raw.Type() + value, err := ci.DecodeData(raw) + if err != nil { + ec.Logger().Info("The value for %s was not decoded, due to error: %s", keyStr, err.Error()) + value = serialization.NondecodedType(serialization.TypeToLabel(vt)) + } + row := output.Row{ + output.Column{ + Name: output.NameValue, + Type: vt, + Value: value, + }, + } + if showType { + row = append(row, output.Column{ + Name: output.NameValueType, + Type: serialization.TypeString, + Value: serialization.TypeToLabel(vt), + }) + } + return row, nil }) if err != nil { return err } stop() - raw := codec.DecodeMapRemoveResponse(rv.(*hazelcast.ClientMessage)) - vt := raw.Type() - value, err := ci.DecodeData(raw) - if err != nil { - ec.Logger().Info("The value for %s was not decoded, due to error: %s", keyStr, err.Error()) - value = serialization.NondecodedType(serialization.TypeToLabel(vt)) - } - row := output.Row{ - output.Column{ - Name: output.NameValue, - Type: vt, - Value: value, - }, - } - if ec.Props().GetBool(mapFlagShowType) { - row = append(row, output.Column{ - Name: output.NameValueType, - Type: serialization.TypeString, - Value: serialization.TypeToLabel(vt), - }) - } - return ec.AddOutputRows(ctx, row) + msg := fmt.Sprintf("OK Removed the entry from map: %s.\n", mapName) + ec.PrintlnUnnecessary(msg) + return ec.AddOutputRows(ctx, rowV.(output.Row)) } func init() { diff --git a/base/commands/map/map_set.go b/base/commands/map/map_set.go index 717542de..13a1fdae 100644 --- a/base/commands/map/map_set.go +++ b/base/commands/map/map_set.go @@ -8,7 +8,9 @@ import ( "github.com/hazelcast/hazelcast-go-client" + "github.com/hazelcast/hazelcast-commandline-client/base" "github.com/hazelcast/hazelcast-commandline-client/clc" + "github.com/hazelcast/hazelcast-commandline-client/clc/cmd" . "github.com/hazelcast/hazelcast-commandline-client/internal/check" "github.com/hazelcast/hazelcast-commandline-client/internal/plug" "github.com/hazelcast/hazelcast-commandline-client/internal/proto/codec" @@ -21,6 +23,8 @@ const ( type MapSetCommand struct{} +func (mc *MapSetCommand) Unwrappable() {} + func (mc *MapSetCommand) Init(cc plug.InitContext) error { cc.SetCommandUsage("set") help := "Set a value in the given Map" @@ -35,37 +39,43 @@ func (mc *MapSetCommand) Init(cc plug.InitContext) error { } func (mc *MapSetCommand) Exec(ctx context.Context, ec plug.ExecContext) error { - mapName := ec.Props().GetString(mapFlagName) - ci, err := ec.ClientInternal(ctx) - if err != nil { - return err - } - // get the map just to ensure the corresponding proxy is created - if _, err := ec.Props().GetBlocking(mapPropertyName); err != nil { - return err - } - keyStr := ec.GetStringArg(argKey) - valueStr := ec.GetStringArg(argValue) - kd, vd, err := makeKeyValueData(ec, ci, keyStr, valueStr) - if err != nil { - return err - } - ttl := GetTTL(ec) - maxIdle := GetMaxIdle(ec) - var req *hazelcast.ClientMessage - if maxIdle >= 0 { - req = codec.EncodeMapSetWithMaxIdleRequest(mapName, kd, vd, 0, ttl, maxIdle) - } else { - req = codec.EncodeMapSetRequest(mapName, kd, vd, 0, ttl) - } + mapName := ec.Props().GetString(base.FlagName) _, stop, err := ec.ExecuteBlocking(ctx, func(ctx context.Context, sp clc.Spinner) (any, error) { + ci, err := cmd.ClientInternal(ctx, ec, sp) + if err != nil { + return nil, err + } sp.SetText(fmt.Sprintf("Setting value into map %s", mapName)) - return ci.InvokeOnKey(ctx, req, kd, nil) + _, err = getMap(ctx, ec, sp) + if err != nil { + return nil, err + } + keyStr := ec.GetStringArg(argKey) + valueStr := ec.GetStringArg(argValue) + kd, vd, err := makeKeyValueData(ec, ci, keyStr, valueStr) + if err != nil { + return nil, err + } + ttl := GetTTL(ec) + maxIdle := GetMaxIdle(ec) + var req *hazelcast.ClientMessage + if maxIdle >= 0 { + req = codec.EncodeMapSetWithMaxIdleRequest(mapName, kd, vd, 0, ttl, maxIdle) + } else { + req = codec.EncodeMapSetRequest(mapName, kd, vd, 0, ttl) + } + _, err = ci.InvokeOnKey(ctx, req, kd, nil) + if err != nil { + return nil, err + } + return nil, nil }) if err != nil { return err } stop() + msg := fmt.Sprintf("OK Set the value into the map %s", mapName) + ec.PrintlnUnnecessary(msg) return nil } diff --git a/base/commands/map/map_size.go b/base/commands/map/map_size.go index 884bf626..044bf259 100644 --- a/base/commands/map/map_size.go +++ b/base/commands/map/map_size.go @@ -6,8 +6,7 @@ import ( "context" "fmt" - "github.com/hazelcast/hazelcast-go-client" - + "github.com/hazelcast/hazelcast-commandline-client/base" "github.com/hazelcast/hazelcast-commandline-client/clc" . "github.com/hazelcast/hazelcast-commandline-client/internal/check" "github.com/hazelcast/hazelcast-commandline-client/internal/output" @@ -17,6 +16,8 @@ import ( type MapSizeCommand struct{} +func (mc *MapSizeCommand) Unwrappable() {} + func (mc *MapSizeCommand) Init(cc plug.InitContext) error { cc.SetCommandUsage("size") help := "Return the size of the given Map" @@ -25,13 +26,12 @@ func (mc *MapSizeCommand) Init(cc plug.InitContext) error { } func (mc *MapSizeCommand) Exec(ctx context.Context, ec plug.ExecContext) error { - mapName := ec.Props().GetString(mapFlagName) - mv, err := ec.Props().GetBlocking(mapPropertyName) - if err != nil { - return err - } - m := mv.(*hazelcast.Map) + mapName := ec.Props().GetString(base.FlagName) sv, stop, err := ec.ExecuteBlocking(ctx, func(ctx context.Context, sp clc.Spinner) (any, error) { + m, err := getMap(ctx, ec, sp) + if err != nil { + return nil, err + } sp.SetText(fmt.Sprintf("Getting the size of the map %s", mapName)) return m.Size(ctx) }) diff --git a/base/commands/map/map_try_lock.go b/base/commands/map/map_try_lock.go index 42686707..1d075d4f 100644 --- a/base/commands/map/map_try_lock.go +++ b/base/commands/map/map_try_lock.go @@ -7,9 +7,9 @@ import ( "fmt" "time" - "github.com/hazelcast/hazelcast-go-client" - + "github.com/hazelcast/hazelcast-commandline-client/base" "github.com/hazelcast/hazelcast-commandline-client/clc" + "github.com/hazelcast/hazelcast-commandline-client/clc/cmd" . "github.com/hazelcast/hazelcast-commandline-client/internal/check" "github.com/hazelcast/hazelcast-commandline-client/internal/output" "github.com/hazelcast/hazelcast-commandline-client/internal/plug" @@ -18,6 +18,8 @@ import ( type MapTryLock struct{} +func (mc *MapTryLock) Unwrappable() {} + func (mc *MapTryLock) Init(cc plug.InitContext) error { cc.SetCommandUsage("try-lock") long := `Try to lock a key in the given map @@ -34,23 +36,22 @@ This command is only available in the interactive mode.` } func (mc *MapTryLock) Exec(ctx context.Context, ec plug.ExecContext) error { - mapName := ec.Props().GetString(mapFlagName) - ci, err := ec.ClientInternal(ctx) - if err != nil { - return err - } - mv, err := ec.Props().GetBlocking(mapPropertyName) - if err != nil { - return err - } - m := mv.(*hazelcast.Map) - keyStr := ec.GetStringArg(argKey) - keyData, err := makeKeyData(ec, ci, keyStr) - if err != nil { - return err - } rv, stop, err := ec.ExecuteBlocking(ctx, func(ctx context.Context, sp clc.Spinner) (any, error) { + mapName := ec.Props().GetString(base.FlagName) + ci, err := cmd.ClientInternal(ctx, ec, sp) + if err != nil { + return nil, err + } sp.SetText(fmt.Sprintf("Locking key in map %s", mapName)) + m, err := getMap(ctx, ec, sp) + if err != nil { + return nil, err + } + keyStr := ec.GetStringArg(argKey) + keyData, err := makeKeyData(ec, ci, keyStr) + if err != nil { + return nil, err + } if ttl := GetTTL(ec); ttl != ttlUnset { return m.TryLockWithLease(ctx, keyData, time.Duration(GetTTL(ec))) } diff --git a/base/commands/map/map_unlock.go b/base/commands/map/map_unlock.go index a558b7e4..5ad0b4ee 100644 --- a/base/commands/map/map_unlock.go +++ b/base/commands/map/map_unlock.go @@ -6,8 +6,7 @@ import ( "context" "fmt" - "github.com/hazelcast/hazelcast-go-client" - + "github.com/hazelcast/hazelcast-commandline-client/base" "github.com/hazelcast/hazelcast-commandline-client/clc" . "github.com/hazelcast/hazelcast-commandline-client/internal/check" "github.com/hazelcast/hazelcast-commandline-client/internal/plug" @@ -15,6 +14,8 @@ import ( type MapUnlock struct{} +func (mc *MapUnlock) Unwrappable() {} + func (mc *MapUnlock) Init(cc plug.InitContext) error { cc.SetCommandUsage("unlock") long := `Unlock a key in the given Map @@ -28,29 +29,30 @@ This command is only available in the interactive mode.` } func (mc *MapUnlock) Exec(ctx context.Context, ec plug.ExecContext) error { - mapName := ec.Props().GetString(mapFlagName) - ci, err := ec.ClientInternal(ctx) - if err != nil { - return err - } - mv, err := ec.Props().GetBlocking(mapPropertyName) - if err != nil { - return err - } - m := mv.(*hazelcast.Map) - keyStr := ec.GetStringArg(argKey) - keyData, err := makeKeyData(ec, ci, keyStr) - if err != nil { - return err - } + mapName := ec.Props().GetString(base.FlagName) _, stop, err := ec.ExecuteBlocking(ctx, func(ctx context.Context, sp clc.Spinner) (any, error) { - sp.SetText(fmt.Sprintf("Locking key in map %s", mapName)) + ci, err := ec.ClientInternal(ctx) + if err != nil { + return nil, err + } + sp.SetText(fmt.Sprintf("Unlocking key in map %s", mapName)) + m, err := getMap(ctx, ec, sp) + if err != nil { + return nil, err + } + keyStr := ec.GetStringArg(argKey) + keyData, err := makeKeyData(ec, ci, keyStr) + if err != nil { + return nil, err + } return nil, m.Unlock(ctx, keyData) }) if err != nil { return err } stop() + msg := fmt.Sprintf("OK Unlocked the key in map %s", mapName) + ec.PrintlnUnnecessary(msg) return nil } diff --git a/base/commands/map/map_values.go b/base/commands/map/map_values.go index aa1cc939..5b98b67c 100644 --- a/base/commands/map/map_values.go +++ b/base/commands/map/map_values.go @@ -6,9 +6,9 @@ import ( "context" "fmt" - "github.com/hazelcast/hazelcast-go-client" - + "github.com/hazelcast/hazelcast-commandline-client/base" "github.com/hazelcast/hazelcast-commandline-client/clc" + "github.com/hazelcast/hazelcast-commandline-client/clc/cmd" . "github.com/hazelcast/hazelcast-commandline-client/internal/check" "github.com/hazelcast/hazelcast-commandline-client/internal/output" "github.com/hazelcast/hazelcast-commandline-client/internal/plug" @@ -18,6 +18,8 @@ import ( type MapValuesCommand struct{} +func (mc *MapValuesCommand) Unwrappable() {} + func (mc *MapValuesCommand) Init(cc plug.InitContext) error { cc.SetCommandUsage("values") help := "Get all values of a Map" @@ -26,41 +28,46 @@ func (mc *MapValuesCommand) Init(cc plug.InitContext) error { } func (mc *MapValuesCommand) Exec(ctx context.Context, ec plug.ExecContext) error { - mapName := ec.Props().GetString(mapFlagName) - showType := ec.Props().GetBool(mapFlagShowType) - ci, err := ec.ClientInternal(ctx) - if err != nil { - return err - } - req := codec.EncodeMapValuesRequest(mapName) - rv, stop, err := ec.ExecuteBlocking(ctx, func(ctx context.Context, sp clc.Spinner) (any, error) { + mapName := ec.Props().GetString(base.FlagName) + showType := ec.Props().GetBool(base.FlagShowType) + rowsV, stop, err := ec.ExecuteBlocking(ctx, func(ctx context.Context, sp clc.Spinner) (any, error) { + ci, err := cmd.ClientInternal(ctx, ec, sp) + if err != nil { + return nil, err + } sp.SetText(fmt.Sprintf("Getting values of %s", mapName)) - return ci.InvokeOnRandomTarget(ctx, req, nil) + req := codec.EncodeMapValuesRequest(mapName) + resp, err := ci.InvokeOnRandomTarget(ctx, req, nil) + if err != nil { + return nil, err + } + data := codec.DecodeMapValuesResponse(resp) + var rows []output.Row + for _, r := range data { + var row output.Row + t := r.Type() + v, err := ci.DecodeData(*r) + if err != nil { + v = serialization.NondecodedType(serialization.TypeToLabel(t)) + } + row = append(row, output.NewValueColumn(t, v)) + if showType { + row = append(row, output.NewValueTypeColumn(t)) + } + rows = append(rows, row) + } + return rows, nil }) if err != nil { return err } stop() - raw := codec.DecodeMapValuesResponse(rv.(*hazelcast.ClientMessage)) - var rows []output.Row - for _, r := range raw { - var row output.Row - t := r.Type() - v, err := ci.DecodeData(*r) - if err != nil { - v = serialization.NondecodedType(serialization.TypeToLabel(t)) - } - row = append(row, output.NewValueColumn(t, v)) - if showType { - row = append(row, output.NewValueTypeColumn(t)) - } - rows = append(rows, row) - } - if len(rows) > 0 { - return ec.AddOutputRows(ctx, rows...) + rows := rowsV.([]output.Row) + if len(rows) == 0 { + ec.PrintlnUnnecessary("OK the map has no values.") + return nil } - ec.PrintlnUnnecessary("No values found.") - return nil + return ec.AddOutputRows(ctx, rows...) } func init() { diff --git a/clc/ux/stage/stage.go b/clc/ux/stage/stage.go index 8c1fe91f..fa71255d 100644 --- a/clc/ux/stage/stage.go +++ b/clc/ux/stage/stage.go @@ -6,6 +6,7 @@ import ( "time" "github.com/hazelcast/hazelcast-commandline-client/clc" + hzerrors "github.com/hazelcast/hazelcast-commandline-client/errors" "github.com/hazelcast/hazelcast-commandline-client/internal" "github.com/hazelcast/hazelcast-commandline-client/internal/plug" "github.com/hazelcast/hazelcast-commandline-client/internal/str" @@ -117,7 +118,7 @@ func Execute[T any](ctx context.Context, ec plug.ExecContext, value T, sp Provid }) if err != nil { ec.PrintlnUnnecessary(fmt.Sprintf("FAIL %s: %s", stg.FailureMsg, err.Error())) - return value, err + return value, hzerrors.WrappedError{Err: err} } stop() ec.PrintlnUnnecessary(fmt.Sprintf("OK %s %s.", ss.indexText, stg.SuccessMsg))