sqs-browse: fixed assumption regarding table keys

This commit is contained in:
Leon Mika 2022-03-25 08:13:43 +11:00
parent 30dbc4eefe
commit 3428bd2a8a
10 changed files with 160 additions and 48 deletions

View file

@ -7,6 +7,7 @@ import (
)
type TableProvider interface {
DescribeTable(ctx context.Context, tableName string) (*models.TableInfo, error)
ScanItems(ctx context.Context, tableName string) ([]models.Item, error)
DeleteItem(ctx context.Context, tableName string, key map[string]types.AttributeValue) error
PutItem(ctx context.Context, name string, item models.Item) error

View file

@ -2,7 +2,6 @@ package tables
import (
"context"
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
"github.com/lmika/awstools/internal/dynamo-browse/models"
"github.com/pkg/errors"
"sort"
@ -18,24 +17,34 @@ func NewService(provider TableProvider) *Service {
}
}
func (s *Service) Scan(ctx context.Context, table string) (*models.ResultSet, error) {
results, err := s.provider.ScanItems(ctx, table)
if err != nil {
return nil, errors.Wrapf(err, "unable to scan table %v", table)
}
func (s *Service) Describe(ctx context.Context, table string) (*models.TableInfo, error) {
return s.provider.DescribeTable(ctx, table)
}
// TODO: need to get PKs and SKs from table
pk, sk := "pk", "sk"
func (s *Service) Scan(ctx context.Context, tableInfo *models.TableInfo) (*models.ResultSet, error) {
results, err := s.provider.ScanItems(ctx, tableInfo.Name)
if err != nil {
return nil, errors.Wrapf(err, "unable to scan table %v", tableInfo.Name)
}
// Get the columns
seenColumns := make(map[string]int)
seenColumns[pk] = 0
seenColumns[sk] = 1
seenColumns[tableInfo.Keys.PartitionKey] = 0
if tableInfo.Keys.SortKey != "" {
seenColumns[tableInfo.Keys.SortKey] = 1
}
for _, definedAttribute := range tableInfo.DefinedAttributes {
if _, seen := seenColumns[definedAttribute]; !seen {
seenColumns[definedAttribute] = len(seenColumns)
}
}
otherColsRank := len(seenColumns)
for _, result := range results {
for k := range result {
if _, isSeen := seenColumns[k]; !isSeen {
seenColumns[k] = 2
seenColumns[k] = otherColsRank
}
}
}
@ -51,23 +60,19 @@ func (s *Service) Scan(ctx context.Context, table string) (*models.ResultSet, er
return seenColumns[columns[i]] < seenColumns[columns[j]]
})
models.Sort(results, pk, sk)
models.Sort(results, tableInfo)
return &models.ResultSet{
Table: table,
TableInfo: tableInfo,
Columns: columns,
Items: results,
}, nil
}
func (s *Service) Put(ctx context.Context, tableName string, item models.Item) error {
return s.provider.PutItem(ctx, tableName, item)
func (s *Service) Put(ctx context.Context, tableInfo *models.TableInfo, item models.Item) error {
return s.provider.PutItem(ctx, tableInfo.Name, item)
}
func (s *Service) Delete(ctx context.Context, name string, item models.Item) error {
// TODO: do not hardcode keys
return s.provider.DeleteItem(ctx, name, map[string]types.AttributeValue{
"pk": item["pk"],
"sk": item["sk"],
})
func (s *Service) Delete(ctx context.Context, tableInfo *models.TableInfo, item models.Item) error {
return s.provider.DeleteItem(ctx, tableInfo.Name, item.KeyValue(tableInfo))
}

View file

@ -9,6 +9,28 @@ import (
"testing"
)
func TestService_Describe(t *testing.T) {
tableName := "service-describe-table"
client, cleanupFn := testdynamo.SetupTestTable(t, tableName, testData)
defer cleanupFn()
provider := dynamo.NewProvider(client)
t.Run("return details of the table", func(t *testing.T) {
ctx := context.Background()
service := tables.NewService(provider)
ti, err := service.Describe(ctx, tableName)
assert.NoError(t, err)
// Hash first, then range, then columns in alphabetic order
assert.Equal(t, ti.Name, tableName)
assert.Equal(t, "pk", ti.Keys.PartitionKey, "pk")
assert.Equal(t, "sk", ti.Keys.SortKey, "sk")
assert.Equal(t, []string{"pk", "sk"}, ti.DefinedAttributes)
})
}
func TestService_Scan(t *testing.T) {
tableName := "service-scan-test-table"
@ -20,11 +42,14 @@ func TestService_Scan(t *testing.T) {
ctx := context.Background()
service := tables.NewService(provider)
rs, err := service.Scan(ctx, tableName)
ti, err := service.Describe(ctx, tableName)
assert.NoError(t, err)
rs, err := service.Scan(ctx, ti)
assert.NoError(t, err)
// Hash first, then range, then columns in alphabetic order
assert.Equal(t, rs.Table, tableName)
assert.Equal(t, rs.TableInfo, ti)
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]))