-
Notifications
You must be signed in to change notification settings - Fork 0
/
helper.go
175 lines (158 loc) · 4.28 KB
/
helper.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
package dygo
import (
"errors"
"strconv"
"strings"
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
)
// createAttributeValue creates a types.AttributeValue based on the input type.
func createAttributeValue(key interface{}) types.AttributeValue {
switch k := key.(type) {
case string:
return &types.AttributeValueMemberS{Value: k}
case int:
return &types.AttributeValueMemberN{Value: strconv.Itoa(k)}
}
return nil
}
// validate validates the given key and value.
func (i *Item) validate(key string, value any) error {
switch key {
case "PK":
return i.validatePartitionKey(value)
case "SK":
return i.validateSortKey(value)
case "Projection":
return i.validateProjecion(value)
case "GSI":
return i.validateGSI(value)
case "FilterAnd":
return i.validateFilterAnd(value)
case "FilterOr":
return i.validateFilterOr(value)
case "TableName":
return i.validateTableName(value)
}
return nil
}
// validateTableName checks if the provided table name is empty.
func (i *Item) validateTableName(value any) error {
if value == "" {
return dynamoError().method("TableName").message("table name can't be empty")
}
return nil
}
// validateFilterOr validates the filter OR condition for an Item.
func (i *Item) validateFilterOr(value any) error {
return dynamoError().method("FilterAnd").message("invalid filter OR condition")
}
// validateFilterAnd validates the filter AND condition for an Item.
func (i *Item) validateFilterAnd(value any) error {
return dynamoError().method("FilterAnd").message("invalid filter AND condition")
}
// validateGSI validates the Global Secondary Index (GSI) value.
func (i *Item) validateGSI(value any) error {
found := false
for _, gsi := range i.c.gsis {
if gsi.indexName == i.indexName {
found = true
}
}
if !found {
return dynamoError().method("GSI").message("invalid GSI name")
}
return nil
}
// validatePartitionKey checks if the provided partition key value is empty.
func (i *Item) validatePartitionKey(value any) error {
if value == "" {
return dynamoError().method("PK").message("partition key can't be empty")
}
return nil
}
// validateSortKey validates the sort key value for an Item.
func (i *Item) validateSortKey(value any) error {
msg := ""
if i.c.sortKey == "" {
msg = "sort key is not required"
}
if i.c.sortKey != "" && value == "" {
msg = "sort key can't be empty"
}
if msg != "" {
return dynamoError().method("SK").message(msg)
}
return nil
}
// validateProjecion validates the projection value for an Item.
func (i *Item) validateProjecion(value any) error {
msg := ""
if value == "" {
msg = "projection can't be empty"
return dynamoError().method("Projection").message(msg)
}
return nil
}
// isGetItemValid checks if the provided item is valid for a GetItem operation.
func (i *Item) isGetItemValid() error {
switch {
case i.c.partitionKey == "":
return errors.New("partition key name is empty")
case i.c.tableName == "":
return errors.New("table name is empty")
case i.key == nil:
return errors.New("key is empty")
case i.key != nil:
if _, ok := i.key[i.c.partitionKey]; !ok {
return errors.New("partition key is empty")
}
if i.c.sortKey != "" {
if _, ok := i.key[i.c.sortKey]; !ok {
return errors.New("sort key is empty")
}
}
if i.c.sortKey == "" {
if len(i.key) > 1 {
return errors.New("too many keys")
}
}
case i.useGSI:
return errors.New("couldn't use gsi with get item")
}
return nil
}
// stringExists checks if a given string exists in a slice of strings.
func stringExists(s []string, str string) bool {
for _, v := range s {
if v == str {
return true
}
}
return false
}
// getSplittedKey returns the first part of the key based on the provided separator.
func getSplittedKey(key string, separator string) string {
if separator != "" {
return strings.Split(key, separator)[0]
}
return key
}
// getStringValue returns the string value of the provided key.
func getStringValue(key interface{}) string {
switch k := key.(type) {
case string:
return k
case int:
return strconv.Itoa(k)
}
return ""
}
// getGsiPartitionKey returns the partition key for selected Global Secondary Index (GSI).
func getPartitionKey(i *Item) string {
for _, v := range i.c.gsis {
if v.indexName == i.indexName {
return v.partitionKey
}
}
return i.c.gsis[0].partitionKey
}