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
|
package expression
import (
"strings"
)
// ProjectionBuilder represents Projection Expressions in DynamoDB.
// ProjectionBuilders are the building blocks of Builders.
// More Information at: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ProjectionExpressions.html
type ProjectionBuilder struct {
names []NameBuilder
}
// NamesList returns a ProjectionBuilder representing the list of item
// attribute names specified by the argument NameBuilders. The resulting
// ProjectionBuilder can be used as a part of other ProjectionBuilders or as an
// argument to the WithProjection() method for the Builder struct.
//
// Example:
//
// // projection represents the list of names {"foo", "bar"}
// projection := expression.NamesList(expression.Name("foo"), expression.Name("bar"))
//
// // Used in another Projection Expression
// anotherProjection := expression.AddNames(projection, expression.Name("baz"))
//
// // Used to make an Builder
// builder := expression.NewBuilder().WithProjection(anotherProjection)
//
// Expression Equivalent:
//
// expression.NamesList(expression.Name("foo"), expression.Name("bar"))
// "foo, bar"
func NamesList(nameBuilder NameBuilder, namesList ...NameBuilder) ProjectionBuilder {
namesList = append([]NameBuilder{nameBuilder}, namesList...)
return ProjectionBuilder{
names: namesList,
}
}
// NamesList returns a ProjectionBuilder representing the list of item
// attribute names specified by the argument NameBuilders. The resulting
// ProjectionBuilder can be used as a part of other ProjectionBuilders or as an
// argument to the WithProjection() method for the Builder struct.
//
// Example:
//
// // projection represents the list of names {"foo", "bar"}
// projection := expression.Name("foo").NamesList(expression.Name("bar"))
//
// // Used in another Projection Expression
// anotherProjection := expression.AddNames(projection, expression.Name("baz"))
// // Used to make an Builder
// builder := expression.NewBuilder().WithProjection(newProjection)
//
// Expression Equivalent:
//
// expression.Name("foo").NamesList(expression.Name("bar"))
// "foo, bar"
func (nb NameBuilder) NamesList(namesList ...NameBuilder) ProjectionBuilder {
return NamesList(nb, namesList...)
}
// AddNames returns a ProjectionBuilder representing the list of item
// attribute names equivalent to appending all of the argument item attribute
// names to the argument ProjectionBuilder. The resulting ProjectionBuilder can
// be used as a part of other ProjectionBuilders or as an argument to the
// WithProjection() method for the Builder struct.
//
// Example:
//
// // projection represents the list of names {"foo", "bar", "baz", "qux"}
// oldProj := expression.NamesList(expression.Name("foo"), expression.Name("bar"))
// projection := expression.AddNames(oldProj, expression.Name("baz"), expression.Name("qux"))
//
// // Used in another Projection Expression
// anotherProjection := expression.AddNames(projection, expression.Name("quux"))
// // Used to make an Builder
// builder := expression.NewBuilder().WithProjection(newProjection)
//
// Expression Equivalent:
//
// expression.AddNames(expression.NamesList(expression.Name("foo"), expression.Name("bar")), expression.Name("baz"), expression.Name("qux"))
// "foo, bar, baz, qux"
func AddNames(projectionBuilder ProjectionBuilder, namesList ...NameBuilder) ProjectionBuilder {
projectionBuilder.names = append(projectionBuilder.names, namesList...)
return projectionBuilder
}
// AddNames returns a ProjectionBuilder representing the list of item
// attribute names equivalent to appending all of the argument item attribute
// names to the argument ProjectionBuilder. The resulting ProjectionBuilder can
// be used as a part of other ProjectionBuilders or as an argument to the
// WithProjection() method for the Builder struct.
//
// Example:
//
// // projection represents the list of names {"foo", "bar", "baz", "qux"}
// oldProj := expression.NamesList(expression.Name("foo"), expression.Name("bar"))
// projection := oldProj.AddNames(expression.Name("baz"), expression.Name("qux"))
//
// // Used in another Projection Expression
// anotherProjection := expression.AddNames(projection, expression.Name("quux"))
// // Used to make an Builder
// builder := expression.NewBuilder().WithProjection(newProjection)
//
// Expression Equivalent:
//
// expression.NamesList(expression.Name("foo"), expression.Name("bar")).AddNames(expression.Name("baz"), expression.Name("qux"))
// "foo, bar, baz, qux"
func (pb ProjectionBuilder) AddNames(namesList ...NameBuilder) ProjectionBuilder {
return AddNames(pb, namesList...)
}
// buildTree builds a tree structure of exprNodes based on the tree
// structure of the input ProjectionBuilder's child NameBuilders. buildTree()
// satisfies the treeBuilder interface so ProjectionBuilder can be a part of
// Builder and Expression struct.
func (pb ProjectionBuilder) buildTree() (exprNode, error) {
if len(pb.names) == 0 {
return exprNode{}, newUnsetParameterError("buildTree", "ProjectionBuilder")
}
childNodes, err := pb.buildChildNodes()
if err != nil {
return exprNode{}, err
}
ret := exprNode{
children: childNodes,
}
ret.fmtExpr = "$c" + strings.Repeat(", $c", len(pb.names)-1)
return ret, nil
}
// buildChildNodes creates the list of the child exprNodes.
func (pb ProjectionBuilder) buildChildNodes() ([]exprNode, error) {
childNodes := make([]exprNode, 0, len(pb.names))
for _, name := range pb.names {
operand, err := name.BuildOperand()
if err != nil {
return []exprNode{}, err
}
childNodes = append(childNodes, operand.exprNode)
}
return childNodes, nil
}
|