1package expression 2 3import ( 4 "strings" 5) 6 7// ProjectionBuilder represents Projection Expressions in DynamoDB. 8// ProjectionBuilders are the building blocks of Builders. 9// More Information at: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ProjectionExpressions.html 10type ProjectionBuilder struct { 11 names []NameBuilder 12} 13 14// NamesList returns a ProjectionBuilder representing the list of item 15// attribute names specified by the argument NameBuilders. The resulting 16// ProjectionBuilder can be used as a part of other ProjectionBuilders or as an 17// argument to the WithProjection() method for the Builder struct. 18// 19// Example: 20// 21// // projection represents the list of names {"foo", "bar"} 22// projection := expression.NamesList(expression.Name("foo"), expression.Name("bar")) 23// 24// // Used in another Projection Expression 25// anotherProjection := expression.AddNames(projection, expression.Name("baz")) 26// // Used to make an Builder 27// builder := expression.NewBuilder().WithProjection(newProjection) 28// 29// Expression Equivalent: 30// 31// expression.NamesList(expression.Name("foo"), expression.Name("bar")) 32// "foo, bar" 33func NamesList(nameBuilder NameBuilder, namesList ...NameBuilder) ProjectionBuilder { 34 namesList = append([]NameBuilder{nameBuilder}, namesList...) 35 return ProjectionBuilder{ 36 names: namesList, 37 } 38} 39 40// NamesList returns a ProjectionBuilder representing the list of item 41// attribute names specified by the argument NameBuilders. The resulting 42// ProjectionBuilder can be used as a part of other ProjectionBuilders or as an 43// argument to the WithProjection() method for the Builder struct. 44// 45// Example: 46// 47// // projection represents the list of names {"foo", "bar"} 48// projection := expression.Name("foo").NamesList(expression.Name("bar")) 49// 50// // Used in another Projection Expression 51// anotherProjection := expression.AddNames(projection, expression.Name("baz")) 52// // Used to make an Builder 53// builder := expression.NewBuilder().WithProjection(newProjection) 54// 55// Expression Equivalent: 56// 57// expression.Name("foo").NamesList(expression.Name("bar")) 58// "foo, bar" 59func (nb NameBuilder) NamesList(namesList ...NameBuilder) ProjectionBuilder { 60 return NamesList(nb, namesList...) 61} 62 63// AddNames returns a ProjectionBuilder representing the list of item 64// attribute names equivalent to appending all of the argument item attribute 65// names to the argument ProjectionBuilder. The resulting ProjectionBuilder can 66// be used as a part of other ProjectionBuilders or as an argument to the 67// WithProjection() method for the Builder struct. 68// 69// Example: 70// 71// // projection represents the list of names {"foo", "bar", "baz", "qux"} 72// oldProj := expression.NamesList(expression.Name("foo"), expression.Name("bar")) 73// projection := expression.AddNames(oldProj, expression.Name("baz"), expression.Name("qux")) 74// 75// // Used in another Projection Expression 76// anotherProjection := expression.AddNames(projection, expression.Name("quux")) 77// // Used to make an Builder 78// builder := expression.NewBuilder().WithProjection(newProjection) 79// 80// Expression Equivalent: 81// 82// expression.AddNames(expression.NamesList(expression.Name("foo"), expression.Name("bar")), expression.Name("baz"), expression.Name("qux")) 83// "foo, bar, baz, qux" 84func AddNames(projectionBuilder ProjectionBuilder, namesList ...NameBuilder) ProjectionBuilder { 85 projectionBuilder.names = append(projectionBuilder.names, namesList...) 86 return projectionBuilder 87} 88 89// AddNames returns a ProjectionBuilder representing the list of item 90// attribute names equivalent to appending all of the argument item attribute 91// names to the argument ProjectionBuilder. The resulting ProjectionBuilder can 92// be used as a part of other ProjectionBuilders or as an argument to the 93// WithProjection() method for the Builder struct. 94// 95// Example: 96// 97// // projection represents the list of names {"foo", "bar", "baz", "qux"} 98// oldProj := expression.NamesList(expression.Name("foo"), expression.Name("bar")) 99// projection := oldProj.AddNames(expression.Name("baz"), expression.Name("qux")) 100// 101// // Used in another Projection Expression 102// anotherProjection := expression.AddNames(projection, expression.Name("quux")) 103// // Used to make an Builder 104// builder := expression.NewBuilder().WithProjection(newProjection) 105// 106// Expression Equivalent: 107// 108// expression.NamesList(expression.Name("foo"), expression.Name("bar")).AddNames(expression.Name("baz"), expression.Name("qux")) 109// "foo, bar, baz, qux" 110func (pb ProjectionBuilder) AddNames(namesList ...NameBuilder) ProjectionBuilder { 111 return AddNames(pb, namesList...) 112} 113 114// buildTree builds a tree structure of exprNodes based on the tree 115// structure of the input ProjectionBuilder's child NameBuilders. buildTree() 116// satisfies the treeBuilder interface so ProjectionBuilder can be a part of 117// Builder and Expression struct. 118func (pb ProjectionBuilder) buildTree() (exprNode, error) { 119 if len(pb.names) == 0 { 120 return exprNode{}, newUnsetParameterError("buildTree", "ProjectionBuilder") 121 } 122 123 childNodes, err := pb.buildChildNodes() 124 if err != nil { 125 return exprNode{}, err 126 } 127 ret := exprNode{ 128 children: childNodes, 129 } 130 131 ret.fmtExpr = "$c" + strings.Repeat(", $c", len(pb.names)-1) 132 133 return ret, nil 134} 135 136// buildChildNodes creates the list of the child exprNodes. 137func (pb ProjectionBuilder) buildChildNodes() ([]exprNode, error) { 138 childNodes := make([]exprNode, 0, len(pb.names)) 139 for _, name := range pb.names { 140 operand, err := name.BuildOperand() 141 if err != nil { 142 return []exprNode{}, err 143 } 144 childNodes = append(childNodes, operand.exprNode) 145 } 146 147 return childNodes, nil 148} 149