Skip to content

Commit 534a0de

Browse files
authored
Merge branch 'main' into renovate/actions-setup-go-6.x
2 parents 4013d2e + 18101ab commit 534a0de

File tree

10 files changed

+1207
-158
lines changed

10 files changed

+1207
-158
lines changed

adapter/dynamodb_transcoder.go

Lines changed: 53 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"encoding/json"
55

66
"github.com/bootjp/elastickv/kv"
7+
"github.com/bootjp/elastickv/store"
78
"github.com/cockroachdb/errors"
89
)
910

@@ -14,7 +15,8 @@ func newDynamoDBTranscoder() *dynamodbTranscoder { // create new transcoder
1415
}
1516

1617
type attributeValue struct {
17-
S string `json:"S"`
18+
S string `json:"S,omitempty"`
19+
L []attributeValue `json:"L,omitempty"`
1820
}
1921

2022
type putItemInput struct {
@@ -43,16 +45,8 @@ func (t *dynamodbTranscoder) PutItemToRequest(b []byte) (*kv.OperationGroup[kv.O
4345
if !ok {
4446
return nil, errors.New("missing value attribute")
4547
}
46-
return &kv.OperationGroup[kv.OP]{
47-
IsTxn: false,
48-
Elems: []*kv.Elem[kv.OP]{
49-
{
50-
Op: kv.Put,
51-
Key: []byte(keyAttr.S),
52-
Value: []byte(valAttr.S),
53-
},
54-
},
55-
}, nil
48+
49+
return t.valueAttrToOps([]byte(keyAttr.S), valAttr)
5650
}
5751

5852
func (t *dynamodbTranscoder) TransactWriteItemsToRequest(b []byte) (*kv.OperationGroup[kv.OP], error) {
@@ -74,15 +68,58 @@ func (t *dynamodbTranscoder) TransactWriteItemsToRequest(b []byte) (*kv.Operatio
7468
if !ok {
7569
return nil, errors.New("missing value attribute")
7670
}
77-
elems = append(elems, &kv.Elem[kv.OP]{
78-
Op: kv.Put,
79-
Key: []byte(keyAttr.S),
80-
Value: []byte(valAttr.S),
81-
})
71+
72+
ops, err := t.valueAttrToOps([]byte(keyAttr.S), valAttr)
73+
if err != nil {
74+
return nil, err
75+
}
76+
elems = append(elems, ops.Elems...)
8277
}
8378

8479
return &kv.OperationGroup[kv.OP]{
8580
IsTxn: true,
8681
Elems: elems,
8782
}, nil
8883
}
84+
85+
func (t *dynamodbTranscoder) valueAttrToOps(key []byte, val attributeValue) (*kv.OperationGroup[kv.OP], error) {
86+
// List handling: only lists of scalar strings are supported.
87+
if len(val.L) > 0 {
88+
var elems []*kv.Elem[kv.OP]
89+
for i, item := range val.L {
90+
if len(item.L) > 0 {
91+
return nil, errors.New("nested lists are not supported")
92+
}
93+
elems = append(elems, &kv.Elem[kv.OP]{
94+
Op: kv.Put,
95+
Key: store.ListItemKey(key, int64(i)),
96+
Value: []byte(item.S),
97+
})
98+
}
99+
meta := store.ListMeta{
100+
Head: 0,
101+
Tail: int64(len(val.L)),
102+
Len: int64(len(val.L)),
103+
}
104+
b, err := store.MarshalListMeta(meta)
105+
if err != nil {
106+
return nil, errors.WithStack(err)
107+
}
108+
elems = append(elems, &kv.Elem[kv.OP]{Op: kv.Put, Key: store.ListMetaKey(key), Value: b})
109+
110+
return &kv.OperationGroup[kv.OP]{IsTxn: true, Elems: elems}, nil
111+
}
112+
113+
// Default: simple string (allow empty string). Reject only when both S and L are absent.
114+
if val.S == "" && len(val.L) == 0 {
115+
return nil, errors.New("unsupported attribute type (only S or L of S)")
116+
}
117+
return &kv.OperationGroup[kv.OP]{
118+
IsTxn: false,
119+
Elems: []*kv.Elem[kv.OP]{{
120+
Op: kv.Put,
121+
Key: key,
122+
Value: []byte(val.S),
123+
}},
124+
}, nil
125+
}

0 commit comments

Comments
 (0)