199 lines
5.1 KiB
Go
199 lines
5.1 KiB
Go
package controllers
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
|
|
tea "github.com/charmbracelet/bubbletea"
|
|
"github.com/lmika/awstools/internal/common/ui/events"
|
|
"github.com/lmika/awstools/internal/dynamo-browse/models"
|
|
"github.com/lmika/awstools/internal/dynamo-browse/services/tables"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
type TableWriteController struct {
|
|
state *State
|
|
tableService *tables.Service
|
|
tableReadControllers *TableReadController
|
|
}
|
|
|
|
func NewTableWriteController(state *State, tableService *tables.Service, tableReadControllers *TableReadController) *TableWriteController {
|
|
return &TableWriteController{
|
|
state: state,
|
|
tableService: tableService,
|
|
tableReadControllers: tableReadControllers,
|
|
}
|
|
}
|
|
|
|
func (twc *TableWriteController) ToggleMark(idx int) tea.Cmd {
|
|
return func() tea.Msg {
|
|
twc.state.withResultSet(func(resultSet *models.ResultSet) {
|
|
resultSet.SetMark(idx, !resultSet.Marked(idx))
|
|
})
|
|
|
|
return ResultSetUpdated{}
|
|
}
|
|
}
|
|
|
|
func (twc *TableWriteController) NewItem() tea.Cmd {
|
|
return func() tea.Msg {
|
|
// Work out which keys we need to prompt for
|
|
rs := twc.state.ResultSet()
|
|
|
|
keyPrompts := &promptSequence{
|
|
prompts: []string{rs.TableInfo.Keys.PartitionKey + ": "},
|
|
}
|
|
if rs.TableInfo.Keys.SortKey != "" {
|
|
keyPrompts.prompts = append(keyPrompts.prompts, rs.TableInfo.Keys.SortKey+": ")
|
|
}
|
|
keyPrompts.onAllDone = func(values []string) tea.Msg {
|
|
twc.state.withResultSet(func(set *models.ResultSet) {
|
|
newItem := models.Item{}
|
|
|
|
// TODO: deal with keys of different type
|
|
newItem[rs.TableInfo.Keys.PartitionKey] = &types.AttributeValueMemberS{Value: values[0]}
|
|
if len(values) == 2 {
|
|
newItem[rs.TableInfo.Keys.SortKey] = &types.AttributeValueMemberS{Value: values[1]}
|
|
}
|
|
|
|
set.AddNewItem(newItem, models.ItemAttribute{
|
|
New: true,
|
|
Dirty: true,
|
|
})
|
|
})
|
|
return NewResultSet{twc.state.ResultSet()}
|
|
}
|
|
|
|
return keyPrompts.next()
|
|
}
|
|
}
|
|
|
|
func (twc *TableWriteController) SetStringValue(idx int, key string) tea.Cmd {
|
|
return func() tea.Msg {
|
|
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}
|
|
set.SetDirty(idx, true)
|
|
})
|
|
return ResultSetUpdated{}
|
|
}
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|
|
func (twc *TableWriteController) PutItem(idx int) tea.Cmd {
|
|
return func() tea.Msg {
|
|
resultSet := twc.state.ResultSet()
|
|
if !resultSet.IsDirty(idx) {
|
|
return events.Error(errors.New("item is not dirty"))
|
|
}
|
|
|
|
return events.PromptForInputMsg{
|
|
Prompt: "put item? ",
|
|
OnDone: func(value string) tea.Cmd {
|
|
return func() tea.Msg {
|
|
if value != "y" {
|
|
return nil
|
|
}
|
|
|
|
if err := twc.tableService.PutItemAt(context.Background(), resultSet, idx); err != nil {
|
|
return events.Error(err)
|
|
}
|
|
return ResultSetUpdated{}
|
|
}
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|
|
func (twc *TableWriteController) TouchItem(idx int) tea.Cmd {
|
|
return func() tea.Msg {
|
|
resultSet := twc.state.ResultSet()
|
|
if resultSet.IsDirty(idx) {
|
|
return events.Error(errors.New("cannot touch dirty items"))
|
|
}
|
|
|
|
return events.PromptForInputMsg{
|
|
Prompt: "touch item? ",
|
|
OnDone: func(value string) tea.Cmd {
|
|
return func() tea.Msg {
|
|
if value != "y" {
|
|
return nil
|
|
}
|
|
|
|
if err := twc.tableService.PutItemAt(context.Background(), resultSet, idx); err != nil {
|
|
return events.Error(err)
|
|
}
|
|
return ResultSetUpdated{}
|
|
}
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|
|
func (twc *TableWriteController) NoisyTouchItem(idx int) tea.Cmd {
|
|
return func() tea.Msg {
|
|
resultSet := twc.state.ResultSet()
|
|
if resultSet.IsDirty(idx) {
|
|
return events.Error(errors.New("cannot noisy touch dirty items"))
|
|
}
|
|
|
|
return events.PromptForInputMsg{
|
|
Prompt: "noisy touch item? ",
|
|
OnDone: func(value string) tea.Cmd {
|
|
return func() tea.Msg {
|
|
ctx := context.Background()
|
|
|
|
if value != "y" {
|
|
return nil
|
|
}
|
|
|
|
item := resultSet.Items()[0]
|
|
if err := twc.tableService.Delete(ctx, resultSet.TableInfo, []models.Item{item}); err != nil {
|
|
return events.Error(err)
|
|
}
|
|
|
|
if err := twc.tableService.Put(ctx, resultSet.TableInfo, item); err != nil {
|
|
return events.Error(err)
|
|
}
|
|
|
|
return twc.tableReadControllers.doScan(ctx, resultSet)
|
|
}
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|
|
func (twc *TableWriteController) DeleteMarked() tea.Cmd {
|
|
return func() tea.Msg {
|
|
resultSet := twc.state.ResultSet()
|
|
markedItems := resultSet.MarkedItems()
|
|
|
|
if len(markedItems) == 0 {
|
|
return events.StatusMsg("no marked items")
|
|
}
|
|
|
|
return events.PromptForInputMsg{
|
|
Prompt: fmt.Sprintf("delete %d items? ", len(markedItems)),
|
|
OnDone: func(value string) tea.Cmd {
|
|
if value != "y" {
|
|
return events.SetStatus("operation aborted")
|
|
}
|
|
|
|
return func() tea.Msg {
|
|
ctx := context.Background()
|
|
if err := twc.tableService.Delete(ctx, resultSet.TableInfo, markedItems); err != nil {
|
|
return events.Error(err)
|
|
}
|
|
|
|
return twc.tableReadControllers.doScan(ctx, resultSet)
|
|
}
|
|
},
|
|
}
|
|
}
|
|
}
|