github.com/aavshr/aws-sdk-go@v1.41.3/service/dynamodb/expression/operand.go (about) 1 package expression 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/aavshr/aws-sdk-go/service/dynamodb" 8 "github.com/aavshr/aws-sdk-go/service/dynamodb/dynamodbattribute" 9 ) 10 11 // ValueBuilder represents an item attribute value operand and implements the 12 // OperandBuilder interface. Methods and functions in the package take 13 // ValueBuilder as an argument and establishes relationships between operands. 14 // ValueBuilder should only be initialized using the function Value(). 15 // 16 // Example: 17 // 18 // // Create a ValueBuilder representing the string "aValue" 19 // valueBuilder := expression.Value("aValue") 20 type ValueBuilder struct { 21 value interface{} 22 } 23 24 // NameBuilder represents a name of a top level item attribute or a nested 25 // attribute. Since NameBuilder represents a DynamoDB Operand, it implements the 26 // OperandBuilder interface. Methods and functions in the package take 27 // NameBuilder as an argument and establishes relationships between operands. 28 // NameBuilder should only be initialized using the function Name(). 29 // 30 // Example: 31 // 32 // // Create a NameBuilder representing the item attribute "aName" 33 // nameBuilder := expression.Name("aName") 34 type NameBuilder struct { 35 name string 36 } 37 38 // SizeBuilder represents the output of the function size ("someName"), which 39 // evaluates to the size of the item attribute defined by "someName". Since 40 // SizeBuilder represents an operand, SizeBuilder implements the OperandBuilder 41 // interface. Methods and functions in the package take SizeBuilder as an 42 // argument and establishes relationships between operands. SizeBuilder should 43 // only be initialized using the function Size(). 44 // 45 // Example: 46 // 47 // // Create a SizeBuilder representing the size of the item attribute 48 // // "aName" 49 // sizeBuilder := expression.Name("aName").Size() 50 type SizeBuilder struct { 51 nameBuilder NameBuilder 52 } 53 54 // KeyBuilder represents either the partition key or the sort key, both of which 55 // are top level attributes to some item in DynamoDB. Since KeyBuilder 56 // represents an operand, KeyBuilder implements the OperandBuilder interface. 57 // Methods and functions in the package take KeyBuilder as an argument and 58 // establishes relationships between operands. However, KeyBuilder should only 59 // be used to describe Key Condition Expressions. KeyBuilder should only be 60 // initialized using the function Key(). 61 // 62 // Example: 63 // 64 // // Create a KeyBuilder representing the item key "aKey" 65 // keyBuilder := expression.Key("aKey") 66 type KeyBuilder struct { 67 key string 68 } 69 70 // setValueMode specifies the type of SetValueBuilder. The default value is 71 // unsetValue so that an UnsetParameterError when BuildOperand() is called on an 72 // empty SetValueBuilder. 73 type setValueMode int 74 75 const ( 76 unsetValue setValueMode = iota 77 plusValueMode 78 minusValueMode 79 listAppendValueMode 80 ifNotExistsValueMode 81 ) 82 83 // SetValueBuilder represents the outcome of operator functions supported by the 84 // DynamoDB Set operation. The operator functions are the following: 85 // Plus() // Represents the "+" operator 86 // Minus() // Represents the "-" operator 87 // ListAppend() 88 // IfNotExists() 89 // For documentation on the above functions, 90 // see: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.SET 91 // Since SetValueBuilder represents an operand, it implements the OperandBuilder 92 // interface. SetValueBuilder structs are used as arguments to the Set() 93 // function. SetValueBuilders should only initialize a SetValueBuilder using the 94 // functions listed above. 95 type SetValueBuilder struct { 96 leftOperand OperandBuilder 97 rightOperand OperandBuilder 98 mode setValueMode 99 } 100 101 // Operand represents an item attribute name or value in DynamoDB. The 102 // relationship between Operands specified by various builders such as 103 // ConditionBuilders and UpdateBuilders for example is processed internally to 104 // write Condition Expressions and Update Expressions respectively. 105 type Operand struct { 106 exprNode exprNode 107 } 108 109 // OperandBuilder represents the idea of Operand which are building blocks to 110 // DynamoDB Expressions. Package methods and functions can establish 111 // relationships between operands, representing DynamoDB Expressions. The method 112 // BuildOperand() is called recursively when the Build() method on the type 113 // Builder is called. BuildOperand() should never be called externally. 114 // OperandBuilder and BuildOperand() are exported to allow package functions to 115 // take an interface as an argument. 116 type OperandBuilder interface { 117 BuildOperand() (Operand, error) 118 } 119 120 // Name creates a NameBuilder. The argument should represent the desired item 121 // attribute. It is possible to reference nested item attributes by using 122 // square brackets for lists and dots for maps. For documentation on specifying 123 // item attributes, 124 // see: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.Attributes.html 125 // 126 // Example: 127 // 128 // // Specify a top-level attribute 129 // name := expression.Name("TopLevel") 130 // // Specify a nested attribute 131 // nested := expression.Name("Record[6].SongList") 132 // // Use Name() to create a condition expression 133 // condition := expression.Name("foo").Equal(expression.Name("bar")) 134 func Name(name string) NameBuilder { 135 return NameBuilder{ 136 name: name, 137 } 138 } 139 140 // Value creates a ValueBuilder and sets its value to the argument. The value 141 // will be marshalled using the dynamodbattribute package, unless it is of 142 // type dynamodb.AttributeValue, where it will be used directly. 143 // 144 // Empty slices and maps will be converted to NULL dynamodb.AttributeValue 145 // values. If an empty value is required, pass a dynamodb.AttributeValue, e.g.: 146 // emptyList := (&dynamodb.AttributeValue{}).SetL([]*dynamodb.AttributeValue{}) 147 // 148 // Example: 149 // 150 // // Use Value() to create a condition expression 151 // condition := expression.Name("foo").Equal(expression.Value(10)) 152 // // Use Value() to set the value of a set expression. 153 // update := Set(expression.Name("greets"), expression.Value((&dynamodb.AttributeValue{}).SetS("hello"))) 154 func Value(value interface{}) ValueBuilder { 155 return ValueBuilder{ 156 value: value, 157 } 158 } 159 160 // Size creates a SizeBuilder representing the size of the item attribute 161 // specified by the argument NameBuilder. Size() is only valid for certain types 162 // of item attributes. For documentation, 163 // see: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html 164 // SizeBuilder is only a valid operand in Condition Expressions and Filter 165 // Expressions. 166 // 167 // Example: 168 // 169 // // Use Size() to create a condition expression 170 // condition := expression.Name("foo").Size().Equal(expression.Value(10)) 171 // 172 // Expression Equivalent: 173 // 174 // expression.Name("aName").Size() 175 // "size (aName)" 176 func (nb NameBuilder) Size() SizeBuilder { 177 return SizeBuilder{ 178 nameBuilder: nb, 179 } 180 } 181 182 // Size creates a SizeBuilder representing the size of the item attribute 183 // specified by the argument NameBuilder. Size() is only valid for certain types 184 // of item attributes. For documentation, 185 // see: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html 186 // SizeBuilder is only a valid operand in Condition Expressions and Filter 187 // Expressions. 188 // 189 // Example: 190 // 191 // // Use Size() to create a condition expression 192 // condition := expression.Size(expression.Name("foo")).Equal(expression.Value(10)) 193 // 194 // Expression Equivalent: 195 // 196 // expression.Size(expression.Name("aName")) 197 // "size (aName)" 198 func Size(nameBuilder NameBuilder) SizeBuilder { 199 return nameBuilder.Size() 200 } 201 202 // Key creates a KeyBuilder. The argument should represent the desired partition 203 // key or sort key value. KeyBuilders should only be used to specify 204 // relationships for Key Condition Expressions. When referring to the partition 205 // key or sort key in any other Expression, use Name(). 206 // 207 // Example: 208 // 209 // // Use Key() to create a key condition expression 210 // keyCondition := expression.Key("foo").Equal(expression.Value("bar")) 211 func Key(key string) KeyBuilder { 212 return KeyBuilder{ 213 key: key, 214 } 215 } 216 217 // Plus creates a SetValueBuilder to be used in as an argument to Set(). The 218 // arguments can either be NameBuilders or ValueBuilders. Plus() only supports 219 // DynamoDB Number types, so the ValueBuilder must be a Number and the 220 // NameBuilder must specify an item attribute of type Number. 221 // More information: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.SET.IncrementAndDecrement 222 // 223 // Example: 224 // 225 // // Use Plus() to set the value of the item attribute "someName" to 5 + 10 226 // update, err := expression.Set(expression.Name("someName"), expression.Plus(expression.Value(5), expression.Value(10))) 227 // 228 // Expression Equivalent: 229 // 230 // expression.Plus(expression.Value(5), expression.Value(10)) 231 // // let :five and :ten be ExpressionAttributeValues for the values 5 and 232 // // 10 respectively. 233 // ":five + :ten" 234 func Plus(leftOperand, rightOperand OperandBuilder) SetValueBuilder { 235 return SetValueBuilder{ 236 leftOperand: leftOperand, 237 rightOperand: rightOperand, 238 mode: plusValueMode, 239 } 240 } 241 242 // Plus creates a SetValueBuilder to be used in as an argument to Set(). The 243 // arguments can either be NameBuilders or ValueBuilders. Plus() only supports 244 // DynamoDB Number types, so the ValueBuilder must be a Number and the 245 // NameBuilder must specify an item attribute of type Number. 246 // More information: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.SET.IncrementAndDecrement 247 // 248 // Example: 249 // 250 // // Use Plus() to set the value of the item attribute "someName" to the 251 // // numeric value of item attribute "aName" incremented by 10 252 // update, err := expression.Set(expression.Name("someName"), expression.Name("aName").Plus(expression.Value(10))) 253 // 254 // Expression Equivalent: 255 // 256 // expression.Name("aName").Plus(expression.Value(10)) 257 // // let :ten be ExpressionAttributeValues representing the value 10 258 // "aName + :ten" 259 func (nb NameBuilder) Plus(rightOperand OperandBuilder) SetValueBuilder { 260 return Plus(nb, rightOperand) 261 } 262 263 // Plus creates a SetValueBuilder to be used in as an argument to Set(). The 264 // arguments can either be NameBuilders or ValueBuilders. Plus() only supports 265 // DynamoDB Number types, so the ValueBuilder must be a Number and the 266 // NameBuilder must specify an item attribute of type Number. 267 // More information: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.SET.IncrementAndDecrement 268 // 269 // Example: 270 // 271 // // Use Plus() to set the value of the item attribute "someName" to 5 + 10 272 // update, err := expression.Set(expression.Name("someName"), expression.Value(5).Plus(expression.Value(10))) 273 // 274 // Expression Equivalent: 275 // 276 // expression.Value(5).Plus(expression.Value(10)) 277 // // let :five and :ten be ExpressionAttributeValues representing the value 278 // // 5 and 10 respectively 279 // ":five + :ten" 280 func (vb ValueBuilder) Plus(rightOperand OperandBuilder) SetValueBuilder { 281 return Plus(vb, rightOperand) 282 } 283 284 // Minus creates a SetValueBuilder to be used in as an argument to Set(). The 285 // arguments can either be NameBuilders or ValueBuilders. Minus() only supports 286 // DynamoDB Number types, so the ValueBuilder must be a Number and the 287 // NameBuilder must specify an item attribute of type Number. 288 // More information: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.SET.IncrementAndDecrement 289 // 290 // Example: 291 // 292 // // Use Minus() to set the value of item attribute "someName" to 5 - 10 293 // update, err := expression.Set(expression.Name("someName"), expression.Minus(expression.Value(5), expression.Value(10))) 294 // 295 // Expression Equivalent: 296 // 297 // expression.Minus(expression.Value(5), expression.Value(10)) 298 // // let :five and :ten be ExpressionAttributeValues for the values 5 and 299 // // 10 respectively. 300 // ":five - :ten" 301 func Minus(leftOperand, rightOperand OperandBuilder) SetValueBuilder { 302 return SetValueBuilder{ 303 leftOperand: leftOperand, 304 rightOperand: rightOperand, 305 mode: minusValueMode, 306 } 307 } 308 309 // Minus creates a SetValueBuilder to be used in as an argument to Set(). The 310 // arguments can either be NameBuilders or ValueBuilders. Minus() only supports 311 // DynamoDB Number types, so the ValueBuilder must be a Number and the 312 // NameBuilder must specify an item attribute of type Number. 313 // More information: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.SET.IncrementAndDecrement 314 // 315 // Example: 316 // 317 // // Use Minus() to set the value of item attribute "someName" to the 318 // // numeric value of "aName" decremented by 10 319 // update, err := expression.Set(expression.Name("someName"), expression.Name("aName").Minus(expression.Value(10))) 320 // 321 // Expression Equivalent: 322 // 323 // expression.Name("aName").Minus(expression.Value(10))) 324 // // let :ten be ExpressionAttributeValues represent the value 10 325 // "aName - :ten" 326 func (nb NameBuilder) Minus(rightOperand OperandBuilder) SetValueBuilder { 327 return Minus(nb, rightOperand) 328 } 329 330 // Minus creates a SetValueBuilder to be used in as an argument to Set(). The 331 // arguments can either be NameBuilders or ValueBuilders. Minus() only supports 332 // DynamoDB Number types, so the ValueBuilder must be a Number and the 333 // NameBuilder must specify an item attribute of type Number. 334 // More information: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.SET.IncrementAndDecrement 335 // 336 // Example: 337 // 338 // // Use Minus() to set the value of item attribute "someName" to 5 - 10 339 // update, err := expression.Set(expression.Name("someName"), expression.Value(5).Minus(expression.Value(10))) 340 // 341 // Expression Equivalent: 342 // 343 // expression.Value(5).Minus(expression.Value(10)) 344 // // let :five and :ten be ExpressionAttributeValues for the values 5 and 345 // // 10 respectively. 346 // ":five - :ten" 347 func (vb ValueBuilder) Minus(rightOperand OperandBuilder) SetValueBuilder { 348 return Minus(vb, rightOperand) 349 } 350 351 // ListAppend creates a SetValueBuilder to be used in as an argument to Set(). 352 // The arguments can either be NameBuilders or ValueBuilders. ListAppend() only 353 // supports DynamoDB List types, so the ValueBuilder must be a List and the 354 // NameBuilder must specify an item attribute of type List. 355 // More information: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.SET.UpdatingListElements 356 // 357 // Example: 358 // 359 // // Use ListAppend() to set item attribute "someName" to the item 360 // // attribute "nameOfList" with "some" and "list" appended to it 361 // update, err := expression.Set(expression.Name("someName"), expression.ListAppend(expression.Name("nameOfList"), expression.Value([]string{"some", "list"}))) 362 // 363 // Expression Equivalent: 364 // 365 // expression.ListAppend(expression.Name("nameOfList"), expression.Value([]string{"some", "list"}) 366 // // let :list be a ExpressionAttributeValue representing the list 367 // // containing "some" and "list". 368 // "list_append (nameOfList, :list)" 369 func ListAppend(leftOperand, rightOperand OperandBuilder) SetValueBuilder { 370 return SetValueBuilder{ 371 leftOperand: leftOperand, 372 rightOperand: rightOperand, 373 mode: listAppendValueMode, 374 } 375 } 376 377 // ListAppend creates a SetValueBuilder to be used in as an argument to Set(). 378 // The arguments can either be NameBuilders or ValueBuilders. ListAppend() only 379 // supports DynamoDB List types, so the ValueBuilder must be a List and the 380 // NameBuilder must specify an item attribute of type List. 381 // More information: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.SET.UpdatingListElements 382 // 383 // Example: 384 // 385 // // Use ListAppend() to set item attribute "someName" to the item 386 // // attribute "nameOfList" with "some" and "list" appended to it 387 // update, err := expression.Set(expression.Name("someName"), expression.Name("nameOfList").ListAppend(expression.Value([]string{"some", "list"}))) 388 // 389 // Expression Equivalent: 390 // 391 // expression.Name("nameOfList").ListAppend(expression.Value([]string{"some", "list"}) 392 // // let :list be a ExpressionAttributeValue representing the list 393 // // containing "some" and "list". 394 // "list_append (nameOfList, :list)" 395 func (nb NameBuilder) ListAppend(rightOperand OperandBuilder) SetValueBuilder { 396 return ListAppend(nb, rightOperand) 397 } 398 399 // ListAppend creates a SetValueBuilder to be used in as an argument to Set(). 400 // The arguments can either be NameBuilders or ValueBuilders. ListAppend() only 401 // supports DynamoDB List types, so the ValueBuilder must be a List and the 402 // NameBuilder must specify an item attribute of type List. 403 // More information: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.SET.UpdatingListElements 404 // 405 // Example: 406 // 407 // // Use ListAppend() to set item attribute "someName" to a string list 408 // // equal to {"a", "list", "some", "list"} 409 // update, err := expression.Set(expression.Name("someName"), expression.Value([]string{"a", "list"}).ListAppend(expression.Value([]string{"some", "list"}))) 410 // 411 // Expression Equivalent: 412 // 413 // expression.Name([]string{"a", "list"}).ListAppend(expression.Value([]string{"some", "list"}) 414 // // let :list1 and :list2 be a ExpressionAttributeValue representing the 415 // // list {"a", "list"} and {"some", "list"} respectively 416 // "list_append (:list1, :list2)" 417 func (vb ValueBuilder) ListAppend(rightOperand OperandBuilder) SetValueBuilder { 418 return ListAppend(vb, rightOperand) 419 } 420 421 // IfNotExists creates a SetValueBuilder to be used in as an argument to Set(). 422 // The first argument must be a NameBuilder representing the name where the new 423 // item attribute is created. The second argument can either be a NameBuilder or 424 // a ValueBuilder. In the case that it is a NameBuilder, the value of the item 425 // attribute at the name specified becomes the value of the new item attribute. 426 // More information: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.SET.PreventingAttributeOverwrites 427 // 428 // Example: 429 // 430 // // Use IfNotExists() to set item attribute "someName" to value 5 if 431 // // "someName" does not exist yet. (Prevents overwrite) 432 // update, err := expression.Set(expression.Name("someName"), expression.IfNotExists(expression.Name("someName"), expression.Value(5))) 433 // 434 // Expression Equivalent: 435 // 436 // expression.IfNotExists(expression.Name("someName"), expression.Value(5)) 437 // // let :five be a ExpressionAttributeValue representing the value 5 438 // "if_not_exists (someName, :five)" 439 func IfNotExists(name NameBuilder, setValue OperandBuilder) SetValueBuilder { 440 return SetValueBuilder{ 441 leftOperand: name, 442 rightOperand: setValue, 443 mode: ifNotExistsValueMode, 444 } 445 } 446 447 // IfNotExists creates a SetValueBuilder to be used in as an argument to Set(). 448 // The first argument must be a NameBuilder representing the name where the new 449 // item attribute is created. The second argument can either be a NameBuilder or 450 // a ValueBuilder. In the case that it is a NameBuilder, the value of the item 451 // attribute at the name specified becomes the value of the new item attribute. 452 // More information: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.SET.PreventingAttributeOverwrites 453 // 454 // Example: 455 // 456 // // Use IfNotExists() to set item attribute "someName" to value 5 if 457 // // "someName" does not exist yet. (Prevents overwrite) 458 // update, err := expression.Set(expression.Name("someName"), expression.Name("someName").IfNotExists(expression.Value(5))) 459 // 460 // Expression Equivalent: 461 // 462 // expression.Name("someName").IfNotExists(expression.Value(5)) 463 // // let :five be a ExpressionAttributeValue representing the value 5 464 // "if_not_exists (someName, :five)" 465 func (nb NameBuilder) IfNotExists(rightOperand OperandBuilder) SetValueBuilder { 466 return IfNotExists(nb, rightOperand) 467 } 468 469 // BuildOperand creates an Operand struct which are building blocks to DynamoDB 470 // Expressions. Package methods and functions can establish relationships 471 // between operands, representing DynamoDB Expressions. The method 472 // BuildOperand() is called recursively when the Build() method on the type 473 // Builder is called. BuildOperand() should never be called externally. 474 // BuildOperand() aliases all strings to avoid stepping over DynamoDB's reserved 475 // words. 476 // More information on reserved words at http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html 477 func (nb NameBuilder) BuildOperand() (Operand, error) { 478 if nb.name == "" { 479 return Operand{}, newUnsetParameterError("BuildOperand", "NameBuilder") 480 } 481 482 node := exprNode{ 483 names: []string{}, 484 } 485 486 nameSplit := strings.Split(nb.name, ".") 487 fmtNames := make([]string, 0, len(nameSplit)) 488 489 for _, word := range nameSplit { 490 var substr string 491 if word == "" { 492 return Operand{}, newInvalidParameterError("BuildOperand", "NameBuilder") 493 } 494 495 if word[len(word)-1] == ']' { 496 for j, char := range word { 497 if char == '[' { 498 substr = word[j:] 499 word = word[:j] 500 break 501 } 502 } 503 } 504 505 if word == "" { 506 return Operand{}, newInvalidParameterError("BuildOperand", "NameBuilder") 507 } 508 509 // Create a string with special characters that can be substituted later: $p 510 node.names = append(node.names, word) 511 fmtNames = append(fmtNames, "$n"+substr) 512 } 513 node.fmtExpr = strings.Join(fmtNames, ".") 514 return Operand{ 515 exprNode: node, 516 }, nil 517 } 518 519 // BuildOperand creates an Operand struct which are building blocks to DynamoDB 520 // Expressions. Package methods and functions can establish relationships 521 // between operands, representing DynamoDB Expressions. The method 522 // BuildOperand() is called recursively when the Build() method on the type 523 // Builder is called. BuildOperand() should never be called externally. 524 // BuildOperand() aliases all strings to avoid stepping over DynamoDB's reserved 525 // words. 526 // More information on reserved words at http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html 527 func (vb ValueBuilder) BuildOperand() (Operand, error) { 528 var ( 529 expr *dynamodb.AttributeValue 530 err error 531 ) 532 533 switch v := vb.value.(type) { 534 case *dynamodb.AttributeValue: 535 expr = v 536 case dynamodb.AttributeValue: 537 expr = &v 538 default: 539 expr, err = dynamodbattribute.Marshal(vb.value) 540 if err != nil { 541 return Operand{}, newInvalidParameterError("BuildOperand", "ValueBuilder") 542 } 543 } 544 545 // Create a string with special characters that can be substituted later: $v 546 operand := Operand{ 547 exprNode: exprNode{ 548 values: []dynamodb.AttributeValue{*expr}, 549 fmtExpr: "$v", 550 }, 551 } 552 return operand, nil 553 } 554 555 // BuildOperand creates an Operand struct which are building blocks to DynamoDB 556 // Expressions. Package methods and functions can establish relationships 557 // between operands, representing DynamoDB Expressions. The method 558 // BuildOperand() is called recursively when the Build() method on the type 559 // Builder is called. BuildOperand() should never be called externally. 560 // BuildOperand() aliases all strings to avoid stepping over DynamoDB's reserved 561 // words. 562 // More information on reserved words at http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html 563 func (sb SizeBuilder) BuildOperand() (Operand, error) { 564 operand, err := sb.nameBuilder.BuildOperand() 565 operand.exprNode.fmtExpr = "size (" + operand.exprNode.fmtExpr + ")" 566 567 return operand, err 568 } 569 570 // BuildOperand creates an Operand struct which are building blocks to DynamoDB 571 // Expressions. Package methods and functions can establish relationships 572 // between operands, representing DynamoDB Expressions. The method 573 // BuildOperand() is called recursively when the Build() method on the type 574 // Builder is called. BuildOperand() should never be called externally. 575 // BuildOperand() aliases all strings to avoid stepping over DynamoDB's reserved 576 // words. 577 // More information on reserved words at http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html 578 func (kb KeyBuilder) BuildOperand() (Operand, error) { 579 if kb.key == "" { 580 return Operand{}, newUnsetParameterError("BuildOperand", "KeyBuilder") 581 } 582 583 ret := Operand{ 584 exprNode: exprNode{ 585 names: []string{kb.key}, 586 fmtExpr: "$n", 587 }, 588 } 589 590 return ret, nil 591 } 592 593 // BuildOperand creates an Operand struct which are building blocks to DynamoDB 594 // Expressions. Package methods and functions can establish relationships 595 // between operands, representing DynamoDB Expressions. The method 596 // BuildOperand() is called recursively when the Build() method on the type 597 // Builder is called. BuildOperand() should never be called externally. 598 // BuildOperand() aliases all strings to avoid stepping over DynamoDB's reserved 599 // words. 600 // More information on reserved words at http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html 601 func (svb SetValueBuilder) BuildOperand() (Operand, error) { 602 if svb.mode == unsetValue { 603 return Operand{}, newUnsetParameterError("BuildOperand", "SetValueBuilder") 604 } 605 606 left, err := svb.leftOperand.BuildOperand() 607 if err != nil { 608 return Operand{}, err 609 } 610 leftNode := left.exprNode 611 612 right, err := svb.rightOperand.BuildOperand() 613 if err != nil { 614 return Operand{}, err 615 } 616 rightNode := right.exprNode 617 618 node := exprNode{ 619 children: []exprNode{leftNode, rightNode}, 620 } 621 622 switch svb.mode { 623 case plusValueMode: 624 node.fmtExpr = "$c + $c" 625 case minusValueMode: 626 node.fmtExpr = "$c - $c" 627 case listAppendValueMode: 628 node.fmtExpr = "list_append($c, $c)" 629 case ifNotExistsValueMode: 630 node.fmtExpr = "if_not_exists($c, $c)" 631 default: 632 return Operand{}, fmt.Errorf("build operand error: unsupported mode: %v", svb.mode) 633 } 634 635 return Operand{ 636 exprNode: node, 637 }, nil 638 }