Added set-n command to set number attributes
Also added the ability to set subattribes of maps
This commit is contained in:
parent
ed577dc53e
commit
e35855f05c
64
internal/dynamo-browse/controllers/attrpath.go
Normal file
64
internal/dynamo-browse/controllers/attrpath.go
Normal file
|
@ -0,0 +1,64 @@
|
|||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
|
||||
"github.com/lmika/awstools/internal/dynamo-browse/models"
|
||||
"github.com/pkg/errors"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type attrPath []string
|
||||
|
||||
func newAttrPath(expr string) attrPath {
|
||||
return strings.Split(expr, ".")
|
||||
}
|
||||
|
||||
func (ap attrPath) follow(item models.Item) (types.AttributeValue, error) {
|
||||
var step types.AttributeValue
|
||||
for i, seg := range ap {
|
||||
if i == 0 {
|
||||
step = item[seg]
|
||||
continue
|
||||
}
|
||||
|
||||
switch s := step.(type) {
|
||||
case *types.AttributeValueMemberM:
|
||||
step = s.Value[seg]
|
||||
default:
|
||||
return nil, errors.Errorf("seg %v expected to be a map", i)
|
||||
}
|
||||
}
|
||||
return step, nil
|
||||
}
|
||||
|
||||
func (ap attrPath) setAt(item models.Item, newValue types.AttributeValue) error {
|
||||
if len(ap) == 1 {
|
||||
item[ap[0]] = newValue
|
||||
return nil
|
||||
}
|
||||
|
||||
var step types.AttributeValue
|
||||
for i, seg := range ap[:len(ap)-1] {
|
||||
if i == 0 {
|
||||
step = item[seg]
|
||||
continue
|
||||
}
|
||||
|
||||
switch s := step.(type) {
|
||||
case *types.AttributeValueMemberM:
|
||||
step = s.Value[seg]
|
||||
default:
|
||||
return errors.Errorf("seg %v expected to be a map", i)
|
||||
}
|
||||
}
|
||||
|
||||
lastSeg := ap[len(ap)-1]
|
||||
switch s := step.(type) {
|
||||
case *types.AttributeValueMemberM:
|
||||
s.Value[lastSeg] = newValue
|
||||
default:
|
||||
return errors.Errorf("last seg expected to be a map, but was %T", lastSeg)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -37,6 +37,13 @@ func (s *State) withResultSet(rs func(*models.ResultSet)) {
|
|||
rs(s.resultSet)
|
||||
}
|
||||
|
||||
func (s *State) withResultSetReturningError(rs func(*models.ResultSet) error) (err error) {
|
||||
s.withResultSet(func(set *models.ResultSet) {
|
||||
err = rs(set)
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *State) setResultSetAndFilter(resultSet *models.ResultSet, filter string) {
|
||||
s.mutex.Lock()
|
||||
defer s.mutex.Unlock()
|
||||
|
|
|
@ -70,7 +70,7 @@ func TestTableReadController_ExportCSV(t *testing.T) {
|
|||
|
||||
provider := dynamo.NewProvider(client)
|
||||
service := tables.NewService(provider)
|
||||
readController := controllers.NewTableReadController(controllers.NewState(), service, "alpha-table")
|
||||
readController := controllers.NewTableReadController(controllers.NewState(), service, "bravo-table")
|
||||
|
||||
t.Run("should export result set to CSV file", func(t *testing.T) {
|
||||
tempFile := tempFile(t)
|
||||
|
@ -83,9 +83,9 @@ func TestTableReadController_ExportCSV(t *testing.T) {
|
|||
|
||||
assert.Equal(t, string(bts), strings.Join([]string{
|
||||
"pk,sk,alpha,beta,gamma\n",
|
||||
"abc,111,This is some value,,\n",
|
||||
"abc,222,This is another some value,1231,\n",
|
||||
"bbb,131,,2468,foobar\n",
|
||||
"foo,bar,This is some value,,\n",
|
||||
}, ""))
|
||||
})
|
||||
|
||||
|
@ -106,7 +106,7 @@ func TestTableReadController_Query(t *testing.T) {
|
|||
|
||||
provider := dynamo.NewProvider(client)
|
||||
service := tables.NewService(provider)
|
||||
readController := controllers.NewTableReadController(controllers.NewState(), service, "alpha-table")
|
||||
readController := controllers.NewTableReadController(controllers.NewState(), service, "bravo-table")
|
||||
|
||||
t.Run("should run scan with filter based on user query", func(t *testing.T) {
|
||||
tempFile := tempFile(t)
|
||||
|
@ -120,7 +120,6 @@ func TestTableReadController_Query(t *testing.T) {
|
|||
|
||||
assert.Equal(t, string(bts), strings.Join([]string{
|
||||
"pk,sk,alpha,beta\n",
|
||||
"abc,111,This is some value,\n",
|
||||
"abc,222,This is another some value,1231\n",
|
||||
}, ""))
|
||||
})
|
||||
|
@ -213,6 +212,11 @@ var testData = []testdynamo.TestData{
|
|||
"pk": "abc",
|
||||
"sk": "111",
|
||||
"alpha": "This is some value",
|
||||
"age": 23,
|
||||
"address": map[string]any{
|
||||
"no": 123,
|
||||
"street": "Fake st.",
|
||||
},
|
||||
},
|
||||
{
|
||||
"pk": "abc",
|
||||
|
|
|
@ -70,15 +70,67 @@ func (twc *TableWriteController) NewItem() tea.Cmd {
|
|||
|
||||
func (twc *TableWriteController) SetStringValue(idx int, key string) tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
// Verify that the expression is valid
|
||||
apPath := newAttrPath(key)
|
||||
|
||||
if err := twc.state.withResultSetReturningError(func(set *models.ResultSet) error {
|
||||
_, err := apPath.follow(set.Items()[idx])
|
||||
return err
|
||||
}); err != nil {
|
||||
return events.Error(err)
|
||||
}
|
||||
|
||||
return events.PromptForInputMsg{
|
||||
Prompt: "string value: ",
|
||||
OnDone: func(value string) tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
twc.state.withResultSet(func(set *models.ResultSet) {
|
||||
set.Items()[idx][key] = &types.AttributeValueMemberS{Value: value}
|
||||
if err := twc.state.withResultSetReturningError(func(set *models.ResultSet) error {
|
||||
err := apPath.setAt(set.Items()[idx], &types.AttributeValueMemberS{Value: value})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
set.SetDirty(idx, true)
|
||||
set.RefreshColumns()
|
||||
})
|
||||
return nil
|
||||
}); err != nil {
|
||||
return events.Error(err)
|
||||
}
|
||||
return ResultSetUpdated{}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (twc *TableWriteController) SetNumberValue(idx int, key string) tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
// Verify that the expression is valid
|
||||
apPath := newAttrPath(key)
|
||||
|
||||
if err := twc.state.withResultSetReturningError(func(set *models.ResultSet) error {
|
||||
_, err := apPath.follow(set.Items()[idx])
|
||||
return err
|
||||
}); err != nil {
|
||||
return events.Error(err)
|
||||
}
|
||||
|
||||
return events.PromptForInputMsg{
|
||||
Prompt: "number value: ",
|
||||
OnDone: func(value string) tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
if err := twc.state.withResultSetReturningError(func(set *models.ResultSet) error {
|
||||
err := apPath.setAt(set.Items()[idx], &types.AttributeValueMemberN{Value: value})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
set.SetDirty(idx, true)
|
||||
set.RefreshColumns()
|
||||
return nil
|
||||
}); err != nil {
|
||||
return events.Error(err)
|
||||
}
|
||||
return ResultSetUpdated{}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package controllers_test
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
|
||||
"github.com/lmika/awstools/internal/dynamo-browse/controllers"
|
||||
"github.com/lmika/awstools/internal/dynamo-browse/providers/dynamo"
|
||||
"github.com/lmika/awstools/internal/dynamo-browse/services/tables"
|
||||
|
@ -9,177 +10,6 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
func TestTableWriteController_ToggleReadWrite(t *testing.T) {
|
||||
t.Skip("needs to be updated")
|
||||
|
||||
/*
|
||||
twc, _, closeFn := setupController(t)
|
||||
t.Cleanup(closeFn)
|
||||
|
||||
t.Run("should enabling read write if disabled", func(t *testing.T) {
|
||||
ctx, uiCtx := testuictx.New(context.Background())
|
||||
ctx = controllers.ContextWithState(ctx, controllers.State{
|
||||
InReadWriteMode: false,
|
||||
})
|
||||
|
||||
err := twc.ToggleReadWrite().Execute(ctx)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Contains(t, uiCtx.Messages, controllers.SetReadWrite{NewValue: true})
|
||||
})
|
||||
|
||||
t.Run("should disable read write if enabled", func(t *testing.T) {
|
||||
ctx, uiCtx := testuictx.New(context.Background())
|
||||
ctx = controllers.ContextWithState(ctx, controllers.State{
|
||||
InReadWriteMode: true,
|
||||
})
|
||||
|
||||
err := twc.ToggleReadWrite().Execute(ctx)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Contains(t, uiCtx.Messages, controllers.SetReadWrite{NewValue: false})
|
||||
})
|
||||
*/
|
||||
}
|
||||
|
||||
func TestTableWriteController_Delete(t *testing.T) {
|
||||
/*
|
||||
t.Run("should delete selected item if in read/write mode is inactive", func(t *testing.T) {
|
||||
twc, ctrls, closeFn := setupController(t)
|
||||
t.Cleanup(closeFn)
|
||||
|
||||
ti, err := ctrls.tableService.Describe(context.Background(), ctrls.tableName)
|
||||
assert.NoError(t, err)
|
||||
|
||||
resultSet, err := ctrls.tableService.Scan(context.Background(), ti)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, resultSet.Items, 3)
|
||||
|
||||
ctx, uiCtx := testuictx.New(context.Background())
|
||||
ctx = controllers.ContextWithState(ctx, controllers.State{
|
||||
ResultSet: resultSet,
|
||||
SelectedItem: resultSet.Items[1],
|
||||
InReadWriteMode: true,
|
||||
})
|
||||
|
||||
op := twc.Delete()
|
||||
|
||||
// Should prompt first
|
||||
err = op.Execute(ctx)
|
||||
assert.NoError(t, err)
|
||||
|
||||
_ = uiCtx
|
||||
|
||||
*/
|
||||
/*
|
||||
promptRequest, ok := uiCtx.Messages[0].(events.PromptForInput)
|
||||
assert.True(t, ok)
|
||||
|
||||
// After prompt, continue to delete
|
||||
err = promptRequest.OnDone.Execute(uimodels.WithPromptValue(ctx, "y"))
|
||||
assert.NoError(t, err)
|
||||
|
||||
afterResultSet, err := ctrls.tableService.Scan(context.Background(), ti)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, afterResultSet.Items, 2)
|
||||
assert.Contains(t, afterResultSet.Items, resultSet.Items[0])
|
||||
assert.NotContains(t, afterResultSet.Items, resultSet.Items[1])
|
||||
assert.Contains(t, afterResultSet.Items, resultSet.Items[2])
|
||||
*/
|
||||
/*
|
||||
})
|
||||
|
||||
t.Run("should not delete selected item if prompt is not y", func(t *testing.T) {
|
||||
twc, ctrls, closeFn := setupController(t)
|
||||
t.Cleanup(closeFn)
|
||||
|
||||
ti, err := ctrls.tableService.Describe(context.Background(), ctrls.tableName)
|
||||
assert.NoError(t, err)
|
||||
|
||||
resultSet, err := ctrls.tableService.Scan(context.Background(), ti)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, resultSet.Items, 3)
|
||||
|
||||
ctx, uiCtx := testuictx.New(context.Background())
|
||||
ctx = controllers.ContextWithState(ctx, controllers.State{
|
||||
ResultSet: resultSet,
|
||||
SelectedItem: resultSet.Items[1],
|
||||
InReadWriteMode: true,
|
||||
})
|
||||
|
||||
op := twc.Delete()
|
||||
|
||||
// Should prompt first
|
||||
err = op.Execute(ctx)
|
||||
assert.NoError(t, err)
|
||||
_ = uiCtx
|
||||
*/
|
||||
/*
|
||||
promptRequest, ok := uiCtx.Messages[0].(events.PromptForInput)
|
||||
assert.True(t, ok)
|
||||
|
||||
// After prompt, continue to delete
|
||||
err = promptRequest.OnDone.Execute(uimodels.WithPromptValue(ctx, "n"))
|
||||
assert.Error(t, err)
|
||||
|
||||
afterResultSet, err := ctrls.tableService.Scan(context.Background(), ti)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, afterResultSet.Items, 3)
|
||||
assert.Contains(t, afterResultSet.Items, resultSet.Items[0])
|
||||
assert.Contains(t, afterResultSet.Items, resultSet.Items[1])
|
||||
assert.Contains(t, afterResultSet.Items, resultSet.Items[2])
|
||||
*/
|
||||
/*
|
||||
})
|
||||
|
||||
t.Run("should not delete if read/write mode is inactive", func(t *testing.T) {
|
||||
tableWriteController, ctrls, closeFn := setupController(t)
|
||||
t.Cleanup(closeFn)
|
||||
|
||||
ti, err := ctrls.tableService.Describe(context.Background(), ctrls.tableName)
|
||||
assert.NoError(t, err)
|
||||
|
||||
resultSet, err := ctrls.tableService.Scan(context.Background(), ti)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, resultSet.Items, 3)
|
||||
|
||||
ctx, _ := testuictx.New(context.Background())
|
||||
ctx = controllers.ContextWithState(ctx, controllers.State{
|
||||
ResultSet: resultSet,
|
||||
SelectedItem: resultSet.Items[1],
|
||||
InReadWriteMode: false,
|
||||
})
|
||||
|
||||
op := tableWriteController.Delete()
|
||||
|
||||
err = op.Execute(ctx)
|
||||
assert.Error(t, err)
|
||||
})
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
type controller struct {
|
||||
tableName string
|
||||
tableService *tables.Service
|
||||
}
|
||||
|
||||
func setupController(t *testing.T) (*controllers.TableWriteController, controller, func()) {
|
||||
tableName := "table-write-controller-table"
|
||||
|
||||
client, cleanupFn := testdynamo.SetupTestTable(t, tableName, testData)
|
||||
provider := dynamo.NewProvider(client)
|
||||
tableService := tables.NewService(provider)
|
||||
tableReadController := controllers.NewTableReadController(tableService, tableName)
|
||||
tableWriteController := controllers.NewTableWriteController(tableService, tableReadController)
|
||||
return tableWriteController, controller{
|
||||
tableName: tableName,
|
||||
tableService: tableService,
|
||||
}, cleanupFn
|
||||
}
|
||||
*/
|
||||
|
||||
func TestTableWriteController_NewItem(t *testing.T) {
|
||||
t.Run("should add an item with pk and sk set at the end of the result set", func(t *testing.T) {
|
||||
client, cleanupFn := testdynamo.SetupTestTable(t, testData)
|
||||
|
@ -218,7 +48,7 @@ func TestTableWriteController_SetStringValue(t *testing.T) {
|
|||
provider := dynamo.NewProvider(client)
|
||||
service := tables.NewService(provider)
|
||||
|
||||
t.Run("should add a new empty item at the end of the result set", func(t *testing.T) {
|
||||
t.Run("should change the value of a string field if already present", func(t *testing.T) {
|
||||
state := controllers.NewState()
|
||||
readController := controllers.NewTableReadController(state, service, "alpha-table")
|
||||
writeController := controllers.NewTableWriteController(state, service, readController)
|
||||
|
@ -235,8 +65,73 @@ func TestTableWriteController_SetStringValue(t *testing.T) {
|
|||
assert.True(t, state.ResultSet().IsDirty(0))
|
||||
})
|
||||
|
||||
t.Run("should prevent duplicate partition,sort keys", func(t *testing.T) {
|
||||
t.Skip("TODO")
|
||||
t.Run("should change the value of a string field within a map if already present", func(t *testing.T) {
|
||||
state := controllers.NewState()
|
||||
readController := controllers.NewTableReadController(state, service, "alpha-table")
|
||||
writeController := controllers.NewTableWriteController(state, service, readController)
|
||||
|
||||
invokeCommand(t, readController.Init())
|
||||
|
||||
beforeAddress := state.ResultSet().Items()[0]["address"].(*types.AttributeValueMemberM)
|
||||
beforeStreet := beforeAddress.Value["street"].(*types.AttributeValueMemberS).Value
|
||||
|
||||
assert.Equal(t, "Fake st.", beforeStreet)
|
||||
assert.False(t, state.ResultSet().IsDirty(0))
|
||||
|
||||
invokeCommandWithPrompt(t, writeController.SetStringValue(0, "address.street"), "Fiction rd.")
|
||||
|
||||
afterAddress := state.ResultSet().Items()[0]["address"].(*types.AttributeValueMemberM)
|
||||
afterStreet := afterAddress.Value["street"].(*types.AttributeValueMemberS).Value
|
||||
|
||||
assert.Equal(t, "Fiction rd.", afterStreet)
|
||||
assert.True(t, state.ResultSet().IsDirty(0))
|
||||
})
|
||||
}
|
||||
|
||||
func TestTableWriteController_SetNumberValue(t *testing.T) {
|
||||
client, cleanupFn := testdynamo.SetupTestTable(t, testData)
|
||||
defer cleanupFn()
|
||||
|
||||
provider := dynamo.NewProvider(client)
|
||||
service := tables.NewService(provider)
|
||||
|
||||
t.Run("should change the value of a number field if already present", func(t *testing.T) {
|
||||
state := controllers.NewState()
|
||||
readController := controllers.NewTableReadController(state, service, "alpha-table")
|
||||
writeController := controllers.NewTableWriteController(state, service, readController)
|
||||
|
||||
invokeCommand(t, readController.Init())
|
||||
before, _ := state.ResultSet().Items()[0].AttributeValueAsString("age")
|
||||
assert.Equal(t, "23", before)
|
||||
assert.False(t, state.ResultSet().IsDirty(0))
|
||||
|
||||
invokeCommandWithPrompt(t, writeController.SetNumberValue(0, "age"), "46")
|
||||
|
||||
after, _ := state.ResultSet().Items()[0].AttributeValueAsString("age")
|
||||
assert.Equal(t, "46", after)
|
||||
assert.True(t, state.ResultSet().IsDirty(0))
|
||||
})
|
||||
|
||||
t.Run("should change the value of a number field within a map if already present", func(t *testing.T) {
|
||||
state := controllers.NewState()
|
||||
readController := controllers.NewTableReadController(state, service, "alpha-table")
|
||||
writeController := controllers.NewTableWriteController(state, service, readController)
|
||||
|
||||
invokeCommand(t, readController.Init())
|
||||
|
||||
beforeAddress := state.ResultSet().Items()[0]["address"].(*types.AttributeValueMemberM)
|
||||
beforeStreet := beforeAddress.Value["no"].(*types.AttributeValueMemberN).Value
|
||||
|
||||
assert.Equal(t, "123", beforeStreet)
|
||||
assert.False(t, state.ResultSet().IsDirty(0))
|
||||
|
||||
invokeCommandWithPrompt(t, writeController.SetNumberValue(0, "address.no"), "456")
|
||||
|
||||
afterAddress := state.ResultSet().Items()[0]["address"].(*types.AttributeValueMemberM)
|
||||
afterStreet := afterAddress.Value["no"].(*types.AttributeValueMemberN).Value
|
||||
|
||||
assert.Equal(t, "456", afterStreet)
|
||||
assert.True(t, state.ResultSet().IsDirty(0))
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ func TestModExpr_Query(t *testing.T) {
|
|||
modExpr, err := queryexpr.Parse(`pk="prefix"`)
|
||||
assert.NoError(t, err)
|
||||
|
||||
plan, err := modExpr.BuildQuery(tableInfo)
|
||||
plan, err := modExpr.Plan(tableInfo)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.False(t, plan.CanQuery)
|
||||
|
@ -36,7 +36,7 @@ func TestModExpr_Query(t *testing.T) {
|
|||
modExpr, err := queryexpr.Parse(`pk^="prefix"`) // TODO: fix this so that '^ =' is invalid
|
||||
assert.NoError(t, err)
|
||||
|
||||
plan, err := modExpr.BuildQuery(tableInfo)
|
||||
plan, err := modExpr.Plan(tableInfo)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.False(t, plan.CanQuery)
|
||||
|
|
|
@ -20,7 +20,7 @@ func TestProvider_ScanItems(t *testing.T) {
|
|||
t.Run("should return scanned items from the table", func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
items, err := provider.ScanItems(ctx, tableName, 100)
|
||||
items, err := provider.ScanItems(ctx, tableName, nil, 100)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, items, 3)
|
||||
|
||||
|
@ -32,7 +32,7 @@ func TestProvider_ScanItems(t *testing.T) {
|
|||
t.Run("should return error if table name does not exist", func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
items, err := provider.ScanItems(ctx, "does-not-exist", 100)
|
||||
items, err := provider.ScanItems(ctx, "does-not-exist", nil, 100)
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, items)
|
||||
})
|
||||
|
@ -53,7 +53,7 @@ func TestProvider_DeleteItem(t *testing.T) {
|
|||
"sk": &types.AttributeValueMemberS{Value: "222"},
|
||||
})
|
||||
|
||||
items, err := provider.ScanItems(ctx, tableName, 100)
|
||||
items, err := provider.ScanItems(ctx, tableName, nil, 100)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, items, 2)
|
||||
|
||||
|
@ -75,7 +75,7 @@ func TestProvider_DeleteItem(t *testing.T) {
|
|||
"sk": &types.AttributeValueMemberS{Value: "999"},
|
||||
})
|
||||
|
||||
items, err := provider.ScanItems(ctx, tableName, 100)
|
||||
items, err := provider.ScanItems(ctx, tableName, nil, 100)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, items, 3)
|
||||
|
||||
|
@ -91,7 +91,7 @@ func TestProvider_DeleteItem(t *testing.T) {
|
|||
|
||||
ctx := context.Background()
|
||||
|
||||
items, err := provider.ScanItems(ctx, "does-not-exist", 100)
|
||||
items, err := provider.ScanItems(ctx, "does-not-exist", nil, 100)
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, items)
|
||||
})
|
||||
|
|
|
@ -51,7 +51,7 @@ func TestService_Scan(t *testing.T) {
|
|||
|
||||
// Hash first, then range, then columns in alphabetic order
|
||||
assert.Equal(t, rs.TableInfo, ti)
|
||||
assert.Equal(t, rs.Columns, []string{"pk", "sk", "alpha", "beta", "gamma"})
|
||||
assert.Equal(t, rs.Columns(), []string{"pk", "sk", "alpha", "beta", "gamma"})
|
||||
//assert.Equal(t, rs.Items[0], testdynamo.TestRecordAsItem(t, testData[1]))
|
||||
//assert.Equal(t, rs.Items[1], testdynamo.TestRecordAsItem(t, testData[0]))
|
||||
//assert.Equal(t, rs.Items[2], testdynamo.TestRecordAsItem(t, testData[2]))
|
||||
|
|
|
@ -62,6 +62,12 @@ func NewModel(rc *controllers.TableReadController, wc *controllers.TableWriteCon
|
|||
}
|
||||
return wc.SetStringValue(dtv.SelectedItemIndex(), args[0])
|
||||
},
|
||||
"set-n": func(args []string) tea.Cmd {
|
||||
if len(args) == 0 {
|
||||
return events.SetError(errors.New("expected field"))
|
||||
}
|
||||
return wc.SetNumberValue(dtv.SelectedItemIndex(), args[0])
|
||||
},
|
||||
|
||||
"put": func(args []string) tea.Cmd {
|
||||
return wc.PutItem(dtv.SelectedItemIndex())
|
||||
|
@ -75,8 +81,7 @@ func NewModel(rc *controllers.TableReadController, wc *controllers.TableWriteCon
|
|||
},
|
||||
})
|
||||
|
||||
//root := layout.FullScreen(tableSelect)
|
||||
root := layout.FullScreen(dialogPrompt)
|
||||
root := layout.FullScreen(tableSelect)
|
||||
|
||||
return Model{
|
||||
tableReadController: rc,
|
||||
|
|
|
@ -14,7 +14,7 @@ func New(model layout.ResizingModel) *Model {
|
|||
compositor: layout.NewCompositor(model),
|
||||
}
|
||||
// TEMP
|
||||
m.compositor.SetOverlay(&dialogModel{}, 5, 5, 30, 12)
|
||||
//m.compositor.SetOverlay(&dialogModel{}, 5, 5, 30, 12)
|
||||
return m
|
||||
}
|
||||
|
||||
|
|
|
@ -60,11 +60,13 @@ func SetupTestTable(t *testing.T, testData []TestData) (*dynamodb.Client, func()
|
|||
}
|
||||
}
|
||||
|
||||
return dynamoClient, func() {
|
||||
t.Cleanup(func() {
|
||||
for _, table := range testData {
|
||||
dynamoClient.DeleteTable(ctx, &dynamodb.DeleteTableInput{
|
||||
TableName: aws.String(table.TableName),
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return dynamoClient, func() {}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue