sqs-browse: added notion of workspaces in sqs-browse
Also added a tool to generate test tables
This commit is contained in:
parent
cecdbafabb
commit
30dbc4eefe
|
@ -10,8 +10,8 @@ import (
|
|||
"github.com/lmika/awstools/internal/common/ui/dispatcher"
|
||||
"github.com/lmika/awstools/internal/sqs-browse/controllers"
|
||||
"github.com/lmika/awstools/internal/sqs-browse/models"
|
||||
"github.com/lmika/awstools/internal/sqs-browse/providers/memstore"
|
||||
sqsprovider "github.com/lmika/awstools/internal/sqs-browse/providers/sqs"
|
||||
"github.com/lmika/awstools/internal/sqs-browse/providers/stormstore"
|
||||
"github.com/lmika/awstools/internal/sqs-browse/services/messages"
|
||||
"github.com/lmika/awstools/internal/sqs-browse/services/pollmessage"
|
||||
"github.com/lmika/awstools/internal/sqs-browse/ui"
|
||||
|
@ -35,7 +35,18 @@ func main() {
|
|||
|
||||
bus := events.New()
|
||||
|
||||
msgStore := memstore.NewStore()
|
||||
workspaceFile, err := os.CreateTemp("", "sqs-browse*.workspace")
|
||||
if err != nil {
|
||||
cli.Fatalf("cannot create workspace file: %v", err)
|
||||
}
|
||||
workspaceFile.Close() // We just need the filename
|
||||
|
||||
msgStore, err := stormstore.NewStore(workspaceFile.Name())
|
||||
if err != nil {
|
||||
cli.Fatalf("cannot open workspace: %v", err)
|
||||
}
|
||||
defer msgStore.Close()
|
||||
|
||||
sqsProvider := sqsprovider.NewProvider(sqsClient)
|
||||
|
||||
messageService := messages.NewService(sqsProvider)
|
||||
|
@ -59,6 +70,8 @@ func main() {
|
|||
}
|
||||
defer f.Close()
|
||||
|
||||
log.Printf("workspace file: %v", workspaceFile.Name())
|
||||
|
||||
go func() {
|
||||
if err := pollService.Poll(context.Background()); err != nil {
|
||||
log.Printf("cannot start poller: %v", err)
|
||||
|
|
4
go.mod
4
go.mod
|
@ -21,6 +21,7 @@ require (
|
|||
|
||||
require (
|
||||
github.com/alecthomas/participle/v2 v2.0.0-alpha7 // indirect
|
||||
github.com/asdine/storm v2.1.2+incompatible // indirect
|
||||
github.com/atotto/clipboard v0.1.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.10.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.6 // indirect
|
||||
|
@ -33,8 +34,10 @@ require (
|
|||
github.com/aws/aws-sdk-go-v2/service/sso v1.9.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.14.0 // indirect
|
||||
github.com/aws/smithy-go v1.11.1 // indirect
|
||||
github.com/brianvoe/gofakeit/v6 v6.15.0 // indirect
|
||||
github.com/containerd/console v1.0.3 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/juju/ansiterm v0.0.0-20210929141451-8b71cc96ebdc // indirect
|
||||
github.com/lmika/shellwords v0.0.0-20140714114018-ce258dd729fe // indirect
|
||||
|
@ -47,6 +50,7 @@ require (
|
|||
github.com/muesli/termenv v0.11.1-0.20220212125758-44cd13922739 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
go.etcd.io/bbolt v1.3.6 // indirect
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
|
||||
|
|
9
go.sum
9
go.sum
|
@ -2,6 +2,8 @@ github.com/alecthomas/participle v0.7.1 h1:2bN7reTw//5f0cugJcTOnY/NYZcWQOaajW+Bw
|
|||
github.com/alecthomas/participle/v2 v2.0.0-alpha7 h1:cK4vjj0VSgb3lN1nuKA5F7dw+1s1pWBe5bx7nNCnN+c=
|
||||
github.com/alecthomas/participle/v2 v2.0.0-alpha7/go.mod h1:NumScqsC42o9x+dGj8/YqsIfhrIQjFEOFovxotbBirA=
|
||||
github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ=
|
||||
github.com/asdine/storm v2.1.2+incompatible h1:dczuIkyqwY2LrtXPz8ixMrU/OFgZp71kbKTHGrXYt/Q=
|
||||
github.com/asdine/storm v2.1.2+incompatible/go.mod h1:RarYDc9hq1UPLImuiXK3BIWPJLdIygvV3PsInK0FbVQ=
|
||||
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
|
||||
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
|
||||
github.com/aws/aws-sdk-go-v2 v1.13.0 h1:1XIXAfxsEmbhbj5ry3D3vX+6ZcUYvIqSm4CWWEuGZCA=
|
||||
|
@ -46,6 +48,8 @@ github.com/aws/smithy-go v1.10.0 h1:gsoZQMNHnX+PaghNw4ynPsyGP7aUCqx5sY2dlPQsZ0w=
|
|||
github.com/aws/smithy-go v1.10.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
|
||||
github.com/aws/smithy-go v1.11.1 h1:IQ+lPZVkSM3FRtyaDox41R8YS6iwPMYIreejOgPW49g=
|
||||
github.com/aws/smithy-go v1.11.1/go.mod h1:3xHYmszWVx2c0kIwQeEVf9uSm4fYZt67FBJnwub1bgM=
|
||||
github.com/brianvoe/gofakeit/v6 v6.15.0 h1:lJPGJZ2/07TRGDazyTzD5b18N3y4tmmJpdhCUw18FlI=
|
||||
github.com/brianvoe/gofakeit/v6 v6.15.0/go.mod h1:Ow6qC71xtwm79anlwKRlWZW6zVq9D2XHE4QSSMP/rU8=
|
||||
github.com/calyptia/go-bubble-table v0.1.0 h1:mXpaaBlrHGH4K8v5PvM8YqBFT9jlysS1YOycU2u3gEQ=
|
||||
github.com/calyptia/go-bubble-table v0.1.0/go.mod h1:2nnweuFos+eEIIbgweXvZuX+ROOatsMwB3NHnX/vTC4=
|
||||
github.com/charmbracelet/bubbles v0.10.3 h1:fKarbRaObLn/DCsZO4Y3vKCwRUzynQD9L+gGev1E/ho=
|
||||
|
@ -66,6 +70,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
|||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
|
||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
|
@ -115,8 +121,11 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
|||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
|
||||
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
|
||||
func TestCommandController_Prompt(t *testing.T) {
|
||||
t.Run("prompt user for a command", func(t *testing.T) {
|
||||
cmd := commandctrl.NewCommandController()
|
||||
cmd := commandctrl.NewCommandController(nil)
|
||||
|
||||
ctx, uiCtx := testuictx.New(context.Background())
|
||||
err := cmd.Prompt().Execute(ctx)
|
||||
|
|
|
@ -55,7 +55,7 @@ func TestTableWriteController_Delete(t *testing.T) {
|
|||
ctx = controllers.ContextWithState(ctx, controllers.State{
|
||||
ResultSet: resultSet,
|
||||
SelectedItem: resultSet.Items[1],
|
||||
InReadWriteMode: false,
|
||||
InReadWriteMode: true,
|
||||
})
|
||||
|
||||
op := twc.Delete()
|
||||
|
@ -91,7 +91,7 @@ func TestTableWriteController_Delete(t *testing.T) {
|
|||
ctx = controllers.ContextWithState(ctx, controllers.State{
|
||||
ResultSet: resultSet,
|
||||
SelectedItem: resultSet.Items[1],
|
||||
InReadWriteMode: false,
|
||||
InReadWriteMode: true,
|
||||
})
|
||||
|
||||
op := twc.Delete()
|
||||
|
|
|
@ -2,9 +2,7 @@ package modexpr
|
|||
|
||||
import (
|
||||
"github.com/alecthomas/participle/v2"
|
||||
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
|
||||
"github.com/pkg/errors"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type astExpr struct {
|
||||
|
@ -12,19 +10,17 @@ type astExpr struct {
|
|||
}
|
||||
|
||||
type astAttribute struct {
|
||||
Name string `parser:"@Ident '='"`
|
||||
Value string `parser:"@String"`
|
||||
Names *astKeyList `parser:"@@ '='"`
|
||||
Value *astLiteralValue `parser:"@@"`
|
||||
}
|
||||
|
||||
func (a astAttribute) dynamoValue() (types.AttributeValue, error) {
|
||||
// TODO: should be based on type
|
||||
s, err := strconv.Unquote(a.Value)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "cannot unquote string")
|
||||
}
|
||||
return &types.AttributeValueMemberS{Value: s}, nil
|
||||
type astKeyList struct {
|
||||
Names []string `parser:"@Ident ('/' @Ident)*"`
|
||||
}
|
||||
|
||||
type astLiteralValue struct {
|
||||
String string `parser:"@String"`
|
||||
}
|
||||
|
||||
var parser = participle.MustBuild(&astExpr{})
|
||||
|
||||
|
|
31
internal/dynamo-browse/models/modexpr/astmods.go
Normal file
31
internal/dynamo-browse/models/modexpr/astmods.go
Normal file
|
@ -0,0 +1,31 @@
|
|||
package modexpr
|
||||
|
||||
import "github.com/lmika/awstools/internal/dynamo-browse/models"
|
||||
|
||||
func (a *astExpr) calcPatchMods(item models.Item) ([]patchMod, error) {
|
||||
patchMods := make([]patchMod, 0)
|
||||
|
||||
for _, attr := range a.Attributes {
|
||||
attrPatchMods, err := attr.calcPatchMods(item)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
patchMods = append(patchMods, attrPatchMods...)
|
||||
}
|
||||
|
||||
return patchMods, nil
|
||||
}
|
||||
|
||||
func (a *astAttribute) calcPatchMods(item models.Item) ([]patchMod, error) {
|
||||
value, err := a.Value.dynamoValue()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
patchMods := make([]patchMod, 0)
|
||||
for _, key := range a.Names.Names {
|
||||
patchMods = append(patchMods, setAttributeMod{key: key, to: value})
|
||||
}
|
||||
|
||||
return patchMods, nil
|
||||
}
|
|
@ -7,15 +7,14 @@ type ModExpr struct {
|
|||
}
|
||||
|
||||
func (me *ModExpr) Patch(item models.Item) (models.Item, error) {
|
||||
newItem := item.Clone()
|
||||
|
||||
for _, attribute := range me.ast.Attributes {
|
||||
var err error
|
||||
name := attribute.Name
|
||||
newItem[name], err = attribute.dynamoValue()
|
||||
mods, err := me.ast.calcPatchMods(item)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
newItem := item.Clone()
|
||||
for _, mod := range mods {
|
||||
mod.Apply(newItem)
|
||||
}
|
||||
|
||||
return newItem, nil
|
||||
|
|
|
@ -36,4 +36,20 @@ func TestModExpr_Patch(t *testing.T) {
|
|||
assert.Equal(t, "new value", newItem["alpha"].(*types.AttributeValueMemberS).Value)
|
||||
assert.Equal(t, "another new value", newItem["beta"].(*types.AttributeValueMemberS).Value)
|
||||
})
|
||||
|
||||
t.Run("patch with key tuple", func(t *testing.T) {
|
||||
modExpr, err := modexpr.Parse(`alpha/beta="new value"`)
|
||||
assert.NoError(t, err)
|
||||
|
||||
oldItem := models.Item{
|
||||
"old": &types.AttributeValueMemberS{Value: "before"},
|
||||
"beta": &types.AttributeValueMemberS{Value: "before beta"},
|
||||
}
|
||||
newItem, err := modExpr.Patch(oldItem)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, "before", newItem["old"].(*types.AttributeValueMemberS).Value)
|
||||
assert.Equal(t, "new value", newItem["alpha"].(*types.AttributeValueMemberS).Value)
|
||||
assert.Equal(t, "new value", newItem["beta"].(*types.AttributeValueMemberS).Value)
|
||||
})
|
||||
}
|
||||
|
|
19
internal/dynamo-browse/models/modexpr/mods.go
Normal file
19
internal/dynamo-browse/models/modexpr/mods.go
Normal file
|
@ -0,0 +1,19 @@
|
|||
package modexpr
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
|
||||
"github.com/lmika/awstools/internal/dynamo-browse/models"
|
||||
)
|
||||
|
||||
type patchMod interface {
|
||||
Apply(item models.Item)
|
||||
}
|
||||
|
||||
type setAttributeMod struct {
|
||||
key string
|
||||
to types.AttributeValue
|
||||
}
|
||||
|
||||
func (sa setAttributeMod) Apply(item models.Item) {
|
||||
item[sa.key] = sa.to
|
||||
}
|
15
internal/dynamo-browse/models/modexpr/values.go
Normal file
15
internal/dynamo-browse/models/modexpr/values.go
Normal file
|
@ -0,0 +1,15 @@
|
|||
package modexpr
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
|
||||
"github.com/pkg/errors"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func (a *astLiteralValue) dynamoValue() (types.AttributeValue, error) {
|
||||
s, err := strconv.Unquote(a.String)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "cannot unquote string")
|
||||
}
|
||||
return &types.AttributeValueMemberS{Value: s}, nil
|
||||
}
|
|
@ -155,10 +155,14 @@ func (m uiModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
// Tea events
|
||||
case tea.WindowSizeMsg:
|
||||
fixedViewsHeight := lipgloss.Height(m.headerView()) + lipgloss.Height(m.splitterView()) + lipgloss.Height(m.footerView())
|
||||
tableHeight := msg.Height / 2
|
||||
viewportHeight := msg.Height / 2 // TODO: make this dynamic
|
||||
if viewportHeight > 15 {
|
||||
viewportHeight = 15
|
||||
}
|
||||
tableHeight := msg.Height - fixedViewsHeight - viewportHeight
|
||||
|
||||
if !m.ready {
|
||||
m.viewport = viewport.New(msg.Width, msg.Height-tableHeight-fixedViewsHeight)
|
||||
m.viewport = viewport.New(msg.Width, viewportHeight)
|
||||
m.viewport.SetContent("(no message selected)")
|
||||
m.ready = true
|
||||
} else {
|
||||
|
|
|
@ -3,9 +3,9 @@ package models
|
|||
import "time"
|
||||
|
||||
type Message struct {
|
||||
ID uint64
|
||||
ExtID string
|
||||
Queue string
|
||||
ID uint64 `storm:"id,increment"`
|
||||
ExtID string `storm:"unique"`
|
||||
Queue string `storm:"index"`
|
||||
Received time.Time
|
||||
Data string
|
||||
}
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
package memstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/lmika/awstools/internal/sqs-browse/models"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Store struct {
|
||||
messages []models.Message
|
||||
|
||||
mtx *sync.Mutex
|
||||
currSeqNo uint64
|
||||
}
|
||||
|
||||
func (s *Store) Save(ctx context.Context, msg *models.Message) error {
|
||||
s.mtx.Lock()
|
||||
defer s.mtx.Unlock()
|
||||
|
||||
s.currSeqNo++
|
||||
msg.ID = s.currSeqNo
|
||||
s.messages = append(s.messages, *msg)
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewStore() *Store {
|
||||
return &Store{
|
||||
messages: make([]models.Message, 0),
|
||||
mtx: new(sync.Mutex),
|
||||
}
|
||||
}
|
30
internal/sqs-browse/providers/stormstore/memstore.go
Normal file
30
internal/sqs-browse/providers/stormstore/memstore.go
Normal file
|
@ -0,0 +1,30 @@
|
|||
package stormstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/asdine/storm"
|
||||
"github.com/lmika/awstools/internal/sqs-browse/models"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type Store struct {
|
||||
db *storm.DB
|
||||
}
|
||||
|
||||
// TODO: should probably be a workspace provider
|
||||
func NewStore(filename string) (*Store, error) {
|
||||
db, err := storm.Open(filename)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "cannot open store %v", filename)
|
||||
}
|
||||
|
||||
return &Store{db: db}, nil
|
||||
}
|
||||
|
||||
func (s *Store) Close() {
|
||||
s.db.Close()
|
||||
}
|
||||
|
||||
func (s *Store) Save(ctx context.Context, msg *models.Message) error {
|
||||
return s.db.Save(msg)
|
||||
}
|
74
test/cmd/load-test-table/main.go
Normal file
74
test/cmd/load-test-table/main.go
Normal file
|
@ -0,0 +1,74 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
"github.com/aws/aws-sdk-go-v2/config"
|
||||
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
|
||||
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
|
||||
"github.com/brianvoe/gofakeit/v6"
|
||||
"github.com/google/uuid"
|
||||
"github.com/lmika/awstools/internal/dynamo-browse/models"
|
||||
"github.com/lmika/awstools/internal/dynamo-browse/providers/dynamo"
|
||||
"github.com/lmika/awstools/internal/dynamo-browse/services/tables"
|
||||
"github.com/lmika/gopkgs/cli"
|
||||
"log"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx := context.Background()
|
||||
tableName := "awstools-test"
|
||||
totalItems := 300
|
||||
|
||||
cfg, err := config.LoadDefaultConfig(ctx)
|
||||
if err != nil {
|
||||
cli.Fatalf("cannot load AWS config: %v", err)
|
||||
}
|
||||
|
||||
dynamoClient := dynamodb.NewFromConfig(cfg,
|
||||
dynamodb.WithEndpointResolver(dynamodb.EndpointResolverFromURL("http://localhost:8000")))
|
||||
|
||||
if _, err = dynamoClient.DeleteTable(ctx, &dynamodb.DeleteTableInput{
|
||||
TableName: aws.String(tableName),
|
||||
}); err != nil {
|
||||
log.Printf("warn: cannot delete table: %v", tableName)
|
||||
}
|
||||
|
||||
if _, err = dynamoClient.CreateTable(ctx, &dynamodb.CreateTableInput{
|
||||
TableName: aws.String(tableName),
|
||||
KeySchema: []types.KeySchemaElement{
|
||||
{AttributeName: aws.String("pk"), KeyType: types.KeyTypeHash},
|
||||
{AttributeName: aws.String("sk"), KeyType: types.KeyTypeRange},
|
||||
},
|
||||
AttributeDefinitions: []types.AttributeDefinition{
|
||||
{AttributeName: aws.String("pk"), AttributeType: types.ScalarAttributeTypeS},
|
||||
{AttributeName: aws.String("sk"), AttributeType: types.ScalarAttributeTypeS},
|
||||
},
|
||||
ProvisionedThroughput: &types.ProvisionedThroughput{
|
||||
ReadCapacityUnits: aws.Int64(100),
|
||||
WriteCapacityUnits: aws.Int64(100),
|
||||
},
|
||||
}); err != nil {
|
||||
log.Fatalf("warn: cannot create table: %v", tableName)
|
||||
}
|
||||
|
||||
dynamoProvider := dynamo.NewProvider(dynamoClient)
|
||||
tableService := tables.NewService(dynamoProvider)
|
||||
|
||||
for i := 0; i < totalItems; i++ {
|
||||
key := uuid.New().String()
|
||||
if err := tableService.Put(ctx, tableName, models.Item{
|
||||
"pk": &types.AttributeValueMemberS{Value: key},
|
||||
"sk": &types.AttributeValueMemberS{Value: key},
|
||||
"name": &types.AttributeValueMemberS{Value: gofakeit.Name()},
|
||||
"address": &types.AttributeValueMemberS{Value: gofakeit.Address().Address},
|
||||
"city": &types.AttributeValueMemberS{Value: gofakeit.Address().City},
|
||||
"phone": &types.AttributeValueMemberS{Value: gofakeit.Phone()},
|
||||
"web": &types.AttributeValueMemberS{Value: gofakeit.URL()},
|
||||
}); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
}
|
||||
|
||||
log.Printf("table '%v' created with %v items", tableName, totalItems)
|
||||
}
|
Loading…
Reference in a new issue