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
1617type attributeValue struct {
17- S string `json:"S"`
18+ S string `json:"S,omitempty"`
19+ L []attributeValue `json:"L,omitempty"`
1820}
1921
2022type 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
5852func (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