dynamo-query: added delete attribute command

This commit is contained in:
Leon Mika 2022-07-14 21:15:31 +10:00
parent e35855f05c
commit c00b99a2eb
4 changed files with 112 additions and 0 deletions

View file

@ -31,6 +31,38 @@ func (ap attrPath) follow(item models.Item) (types.AttributeValue, error) {
return step, nil
}
func (ap attrPath) deleteAt(item models.Item) error {
if len(ap) == 1 {
delete(item, ap[0])
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:
delete(s.Value, lastSeg)
default:
return errors.Errorf("last seg expected to be a map, but was %T", lastSeg)
}
return nil
}
func (ap attrPath) setAt(item models.Item, newValue types.AttributeValue) error {
if len(ap) == 1 {
item[ap[0]] = newValue

View file

@ -138,6 +138,35 @@ func (twc *TableWriteController) SetNumberValue(idx int, key string) tea.Cmd {
}
}
func (twc *TableWriteController) DeleteAttribute(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)
}
if err := twc.state.withResultSetReturningError(func(set *models.ResultSet) error {
err := apPath.deleteAt(set.Items()[idx])
if err != nil {
return err
}
set.SetDirty(idx, true)
set.RefreshColumns()
return nil
}); err != nil {
return events.Error(err)
}
return ResultSetUpdated{}
}
}
func (twc *TableWriteController) PutItem(idx int) tea.Cmd {
return func() tea.Msg {
resultSet := twc.state.ResultSet()

View file

@ -135,6 +135,51 @@ func TestTableWriteController_SetNumberValue(t *testing.T) {
})
}
func TestTableWriteController_DeleteAttribute(t *testing.T) {
client, cleanupFn := testdynamo.SetupTestTable(t, testData)
defer cleanupFn()
provider := dynamo.NewProvider(client)
service := tables.NewService(provider)
t.Run("should delete top level attribute", 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))
invokeCommand(t, writeController.DeleteAttribute(0, "age"))
_, hasAge := state.ResultSet().Items()[0]["age"]
assert.False(t, hasAge)
})
t.Run("should delete attribute of map", 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))
invokeCommand(t, writeController.DeleteAttribute(0, "address.no"))
afterAddress := state.ResultSet().Items()[0]["address"].(*types.AttributeValueMemberM)
_, hasStreet := afterAddress.Value["no"]
assert.False(t, hasStreet)
})
}
func TestTableWriteController_PutItem(t *testing.T) {
t.Run("should put the selected item if dirty", func(t *testing.T) {
client, cleanupFn := testdynamo.SetupTestTable(t, testData)

View file

@ -68,6 +68,12 @@ func NewModel(rc *controllers.TableReadController, wc *controllers.TableWriteCon
}
return wc.SetNumberValue(dtv.SelectedItemIndex(), args[0])
},
"del-attr": func(args []string) tea.Cmd {
if len(args) == 0 {
return events.SetError(errors.New("expected field"))
}
return wc.DeleteAttribute(dtv.SelectedItemIndex(), args[0])
},
"put": func(args []string) tea.Cmd {
return wc.PutItem(dtv.SelectedItemIndex())