Passed
Push — master ( 2f1af3...a8e5e6 )
by eval
03:46 queued 02:09
created

dynamodb.XCondition.KeyCondition   C

Complexity

Conditions 10

Size

Total Lines 22
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 21
nop 0
dl 0
loc 22
rs 5.9999
c 0
b 0
f 0

How to fix   Complexity   

Complexity

Complex classes like dynamodb.XCondition.KeyCondition often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
package dynamodb
2
3
import (
4
	"errors"
5
6
	"github.com/aws/aws-sdk-go-v2/service/dynamodb/expression"
7
)
8
9
// XConditions is to build Expression Condition for Query/Scan/Update operation.
10
type XConditions struct {
11
	KeyConditions []XCondition
12
	Conditions    []XCondition
13
	Filters       []XCondition
14
	Projections   []string
15
}
16
17
func (x XConditions) hasValue() bool {
18
	switch {
19
	case len(x.KeyConditions) != 0,
20
		len(x.Conditions) != 0,
21
		len(x.Filters) != 0,
22
		len(x.Projections) != 0:
23
		return true
24
	}
25
	return false
26
}
27
28
func (x XConditions) Build() (expression.Expression, error) {
0 ignored issues
show
introduced by
exported method XConditions.Build should have comment or be unexported
Loading history...
29
	b := expression.NewBuilder()
30
31
	if len(x.KeyConditions) != 0 {
32
		kc, err := x.KeyConditions[0].KeyCondition()
33
		if err != nil {
34
			return expression.Expression{}, err
35
		}
36
		// for multiple key conditions
37
		if len(x.KeyConditions) > 1 {
38
			for _, v := range x.KeyConditions[1:] {
39
				kc2, err := v.KeyCondition()
40
				if err != nil {
41
					return expression.Expression{}, err
42
				}
43
				kc = kc.And(kc2)
44
			}
45
		}
46
		b = b.WithKeyCondition(kc)
47
	}
48
49
	if len(x.Conditions) != 0 {
50
		cond, err := x.Conditions[0].Condition()
51
		if err != nil {
52
			return expression.Expression{}, err
53
		}
54
55
		// for multiple conditions
56
		if len(x.Conditions) > 1 {
57
			for _, v := range x.Conditions[1:] {
58
				cond2, err := v.Condition()
59
				if err != nil {
60
					return expression.Expression{}, err
61
				}
62
				if v.IsNOT {
63
					cond2 = cond2.Not()
64
				}
65
66
				switch {
67
				case v.IsOR:
68
					cond = cond.Or(cond2)
69
				default:
70
					cond = cond.And(cond2)
71
				}
72
			}
73
		}
74
		b = b.WithCondition(cond)
75
	}
76
77
	if len(x.Filters) != 0 {
78
		filt, err := x.Filters[0].Condition()
79
		if err != nil {
80
			return expression.Expression{}, err
81
		}
82
83
		// for multiple conditions
84
		if len(x.Filters) > 1 {
85
			for _, v := range x.Filters[1:] {
86
				filt2, err := v.Condition()
87
				if err != nil {
88
					return expression.Expression{}, err
89
				}
90
				if v.IsNOT {
91
					filt2 = filt2.Not()
92
				}
93
94
				switch {
95
				case v.IsOR:
96
					filt = filt.Or(filt2)
97
				default:
98
					filt = filt.And(filt2)
99
				}
100
			}
101
		}
102
		b = b.WithFilter(filt)
103
	}
104
105
	if len(x.Projections) != 0 {
106
		list := make([]expression.NameBuilder, len(x.Projections))
107
		for i, v := range x.Projections {
108
			list[i] = expression.Name(v)
109
		}
110
		b = b.WithProjection(expression.ProjectionBuilder{}.AddNames(list...))
111
	}
112
113
	return b.Build()
114
}
115
116
// XCondition contains single condition parameters.
117
type XCondition struct {
118
	Name     string
119
	Value    string
120
	Operator ComparisonOperator
121
122
	// optional
123
	IsOR  bool
124
	IsNOT bool
125
	// - 'BETWEEN': higher value.
126
	// - 'IN': all of values afre used besides XCondition.Value.
127
	OtherValues []string
128
}
129
130
func (x XCondition) KeyCondition() (expression.KeyConditionBuilder, error) {
0 ignored issues
show
introduced by
exported method XCondition.KeyCondition should have comment or be unexported
Loading history...
131
	e := expression.Key(x.Name)
132
	switch x.Operator {
133
	case ComparisonOperatorEq:
134
		return e.Equal(expression.Value(x.Value)), nil
135
	case ComparisonOperatorLe:
136
		return e.LessThanEqual(expression.Value(x.Value)), nil
137
	case ComparisonOperatorLt:
138
		return e.LessThan(expression.Value(x.Value)), nil
139
	case ComparisonOperatorGe:
140
		return e.GreaterThanEqual(expression.Value(x.Value)), nil
141
	case ComparisonOperatorGt:
142
		return e.GreaterThan(expression.Value(x.Value)), nil
143
	case ComparisonOperatorBeginsWith:
144
		return e.BeginsWith(x.Value), nil
145
	case ComparisonOperatorBetween:
146
		if len(x.OtherValues) == 0 {
147
			return expression.KeyConditionBuilder{}, errors.New("Condition 'BETWEEN' must set 'OtherValues[0]'")
148
		}
149
		return e.Between(expression.Value(x.Value), expression.Value(x.OtherValues[0])), nil
150
	default:
151
		return e.Equal(expression.Value(x.Value)), nil
152
	}
153
}
154
155
func (x XCondition) Condition() (expression.ConditionBuilder, error) {
0 ignored issues
show
introduced by
exported method XCondition.Condition should have comment or be unexported
Loading history...
156
	e := expression.Name(x.Name)
157
	switch x.Operator {
158
	case ComparisonOperatorEq:
159
		return e.Equal(expression.Value(x.Value)), nil
160
	case ComparisonOperatorLe:
161
		return e.LessThanEqual(expression.Value(x.Value)), nil
162
	case ComparisonOperatorLt:
163
		return e.LessThan(expression.Value(x.Value)), nil
164
	case ComparisonOperatorGe:
165
		return e.GreaterThanEqual(expression.Value(x.Value)), nil
166
	case ComparisonOperatorGt:
167
		return e.GreaterThan(expression.Value(x.Value)), nil
168
	case ComparisonOperatorBeginsWith:
169
		return e.BeginsWith(x.Value), nil
170
	case ComparisonOperatorBetween:
171
		if len(x.OtherValues) == 0 {
172
			return expression.ConditionBuilder{}, errors.New("Condition 'BETWEEN' must set 'OtherValues[0]'")
173
		}
174
		return e.Between(expression.Value(x.Value), expression.Value(x.OtherValues[0])), nil
175
	case ComparisonOperatorIn:
176
		list := make([]expression.OperandBuilder, len(x.OtherValues))
177
		for i, v := range x.OtherValues {
178
			list[i] = expression.Value(v)
179
		}
180
		return e.In(expression.Value(x.Value), list...), nil
181
	case ComparisonOperatorNe:
182
		return e.NotEqual(expression.Value(x.Value)), nil
183
	case ComparisonOperatorContains:
184
		return e.Contains(x.Value), nil
185
	case ComparisonOperatorAttrExists:
186
		return e.AttributeExists(), nil
187
	case ComparisonOperatorAttrNotExists:
188
		return e.AttributeNotExists(), nil
189
	case ComparisonOperatorAttrType:
190
		return e.AttributeType(expression.DynamoDBAttributeType(x.Value)), nil
191
	default:
192
		return e.Equal(expression.Value(x.Value)), nil
193
	}
194
}
195