dynamo-query: added delete attribute command
This commit is contained in:
parent
e35855f05c
commit
c00b99a2eb
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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())
|
||||
|
|
Loading…
Reference in a new issue