Issues (1008)

dynamodb/client_xapi_item.go (2 issues)

Severity
1
package dynamodb
2
3
import (
4
	"context"
5
	"fmt"
6
7
	SDK "github.com/aws/aws-sdk-go-v2/service/dynamodb"
8
	"github.com/evalphobia/aws-sdk-go-v2-wrapper/errors"
9
	"github.com/evalphobia/aws-sdk-go-v2-wrapper/private/pointers"
10
)
11
12
// XGetSingleItem gets single item.
13
func (svc *DynamoDB) XGetSingleItem(ctx context.Context, in XGetSingleItemRequest) (map[string]AttributeValue, error) {
14
	req, err := in.ToRequest()
15
	if err != nil {
16
		return nil, err
17
	}
18
19
	result, err := svc.GetItem(ctx, req)
20
	switch {
21
	case err != nil,
22
		result == nil:
23
		return nil, err
24
	}
25
26
	return result.Item, nil
27
}
28
29
type XGetSingleItemRequest struct {
0 ignored issues
show
exported type XGetSingleItemRequest should have comment or be unexported
Loading history...
30
	TableName string
31
32
	HashKeyName  string
33
	HashKeyValue interface{}
34
35
	RangeKeyName  string
36
	RangeKeyValue interface{}
37
}
38
39
func (in XGetSingleItemRequest) ToRequest() (GetItemRequest, error) {
0 ignored issues
show
exported method XGetSingleItemRequest.ToRequest should have comment or be unexported
Loading history...
40
	r := GetItemRequest{
41
		TableName: in.TableName,
42
		Key:       make(map[string]AttributeValue),
43
	}
44
45
	v, err := RawMarshal(in.HashKeyValue, defaultStructTag)
46
	if err != nil {
47
		return r, err
48
	}
49
	if v != nil {
50
		r.Key[in.HashKeyName] = newAttributeValue(*v)
51
	}
52
53
	if in.RangeKeyName != "" {
54
		v, err := RawMarshal(in.RangeKeyValue, defaultStructTag)
55
		if err != nil {
56
			return r, err
57
		}
58
		if v != nil {
59
			r.Key[in.RangeKeyName] = newAttributeValue(*v)
60
		}
61
	}
62
63
	return r, nil
64
}
65
66
// XBatchDeleteItems deletes multiple items using 'BatchWriteItems'.
67
func (svc *DynamoDB) XBatchDeleteItems(ctx context.Context, req XBatchDeleteItemRequest) error {
68
	tableName := req.TableName
69
	hashKey := req.HashKey
70
	rangeKey := req.RangeKey
71
72
	var errs errors.ErrorList
73
	itemChunks := req.ToChunks()
74
	for _, items := range itemChunks {
75
		writeReq := make([]WriteRequest, len(items))
76
		for i, v := range items {
77
			av, err := RawMarshal(v.HashKeyValue, defaultStructTag)
78
			if err != nil {
79
				return err
80
			}
81
82
			delKeys := map[string]AttributeValue{
83
				hashKey: newAttributeValue(*av),
84
			}
85
86
			if rangeKey != "" {
87
				av, err := RawMarshal(v.RangeKeyValue, defaultStructTag)
88
				if err != nil {
89
					return err
90
				}
91
				delKeys[rangeKey] = newAttributeValue(*av)
92
			}
93
			writeReq[i] = WriteRequest{
94
				DeleteKeys: delKeys,
95
			}
96
		}
97
98
		_, err := svc.BatchWriteItem(ctx, BatchWriteItemRequest{
99
			RequestItems: map[string][]WriteRequest{
100
				tableName: writeReq,
101
			},
102
		})
103
		if err != nil {
104
			errs = append(errs, err)
105
		}
106
	}
107
	if len(errs) != 0 {
108
		return errs
109
	}
110
	return nil
111
}
112
113
// XBatchDeleteItemRequest is parameters of 'XBatchDeleteItems'.
114
type XBatchDeleteItemRequest struct {
115
	TableName string
116
	HashKey   string
117
	RangeKey  string
118
	Items     []XBatchDeleteItem
119
}
120
121
// ToChunks makes a slice of 25 items slices to avoid the limitation of 'BatchWriteItem'.
122
func (r XBatchDeleteItemRequest) ToChunks() [][]XBatchDeleteItem {
123
	const ddbSize = 25
124
	var parts [][]XBatchDeleteItem
125
126
	items := r.Items
127
	maxSize := len(items)
128
129
	for i := 0; i < maxSize; i += ddbSize {
130
		end := i + ddbSize
131
		if end > maxSize {
132
			end = maxSize
133
		}
134
135
		parts = append(parts, items[i:end])
136
	}
137
	return parts
138
}
139
140
// XBatchDeleteItem contains key values to delete and used in 'XBatchDeleteItemRequest'.
141
type XBatchDeleteItem struct {
142
	HashKeyValue  interface{}
143
	RangeKeyValue interface{}
144
}
145
146
// XForceDeleteAll deletes all data in the table.
147
// This performs scan all item and delete it via 'BatchWriteItem'.
148
// For big tables, consider using 'DeleteTable' instead.
149
func (svc *DynamoDB) XForceDeleteAll(ctx context.Context, tableName string) error {
150
	descResp, err := svc.DescribeTable(ctx, DescribeTableRequest{
151
		TableName: tableName,
152
	})
153
	switch {
154
	case err != nil:
155
		return err
156
	case descResp == nil:
157
		return fmt.Errorf("Unexpected response from `DescribeTable` | [%s]", tableName)
158
	}
159
160
	schema := descResp.Table.KeySchema
161
	hashKey := schema[0].AttributeName
162
	rangeKey := ""
163
	if len(schema) > 1 {
164
		rangeKey = schema[1].AttributeName
165
	}
166
167
	for {
168
		result, err := svc.RawScan(ctx, &SDK.ScanInput{
169
			TableName: pointers.String(tableName),
170
		})
171
		switch {
172
		case err != nil:
173
			return err
174
		case result == nil:
175
			return fmt.Errorf("Unexpected response from `Scan` | [%s]", tableName)
176
		case *result.Count == 0:
177
			return nil
178
		}
179
180
		items := make([]XBatchDeleteItem, len(result.Items))
181
		for i, v := range result.Items {
182
			item := XBatchDeleteItem{
183
				HashKeyValue: newAttributeValue(v[hashKey]).GetValue(),
184
			}
185
			if rangeKey != "" {
186
				item.RangeKeyValue = newAttributeValue(v[rangeKey]).GetValue()
187
			}
188
			items[i] = item
189
		}
190
191
		r := XBatchDeleteItemRequest{
192
			TableName: tableName,
193
			HashKey:   hashKey,
194
			RangeKey:  rangeKey,
195
			Items:     items,
196
		}
197
		if err := svc.XBatchDeleteItems(ctx, r); err != nil {
198
			return err
199
		}
200
	}
201
}
202