vendor: update all dependencies to latest versions
This commit is contained in:
parent
911d121bb9
commit
b017fcfe9a
3048 changed files with 537057 additions and 189681 deletions
496
vendor/github.com/aws/aws-sdk-go/service/dynamodb/api.go
generated
vendored
496
vendor/github.com/aws/aws-sdk-go/service/dynamodb/api.go
generated
vendored
|
@ -17,19 +17,18 @@ const opBatchGetItem = "BatchGetItem"
|
|||
|
||||
// BatchGetItemRequest generates a "aws/request.Request" representing the
|
||||
// client's request for the BatchGetItem operation. The "output" return
|
||||
// value can be used to capture response data after the request's "Send" method
|
||||
// is called.
|
||||
// value will be populated with the request's response once the request complets
|
||||
// successfuly.
|
||||
//
|
||||
// See BatchGetItem for usage and error information.
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// Creating a request object using this method should be used when you want to inject
|
||||
// custom logic into the request's lifecycle using a custom handler, or if you want to
|
||||
// access properties on the request object before or after sending the request. If
|
||||
// you just want the service response, call the BatchGetItem method directly
|
||||
// instead.
|
||||
// See BatchGetItem for more information on using the BatchGetItem
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
// Note: You must call the "Send" method on the returned request object in order
|
||||
// to execute the request.
|
||||
//
|
||||
// // Example sending a request using the BatchGetItemRequest method.
|
||||
// req, resp := client.BatchGetItemRequest(params)
|
||||
|
@ -213,19 +212,18 @@ const opBatchWriteItem = "BatchWriteItem"
|
|||
|
||||
// BatchWriteItemRequest generates a "aws/request.Request" representing the
|
||||
// client's request for the BatchWriteItem operation. The "output" return
|
||||
// value can be used to capture response data after the request's "Send" method
|
||||
// is called.
|
||||
// value will be populated with the request's response once the request complets
|
||||
// successfuly.
|
||||
//
|
||||
// See BatchWriteItem for usage and error information.
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// Creating a request object using this method should be used when you want to inject
|
||||
// custom logic into the request's lifecycle using a custom handler, or if you want to
|
||||
// access properties on the request object before or after sending the request. If
|
||||
// you just want the service response, call the BatchWriteItem method directly
|
||||
// instead.
|
||||
// See BatchWriteItem for more information on using the BatchWriteItem
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
// Note: You must call the "Send" method on the returned request object in order
|
||||
// to execute the request.
|
||||
//
|
||||
// // Example sending a request using the BatchWriteItemRequest method.
|
||||
// req, resp := client.BatchWriteItemRequest(params)
|
||||
|
@ -377,19 +375,18 @@ const opCreateTable = "CreateTable"
|
|||
|
||||
// CreateTableRequest generates a "aws/request.Request" representing the
|
||||
// client's request for the CreateTable operation. The "output" return
|
||||
// value can be used to capture response data after the request's "Send" method
|
||||
// is called.
|
||||
// value will be populated with the request's response once the request complets
|
||||
// successfuly.
|
||||
//
|
||||
// See CreateTable for usage and error information.
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// Creating a request object using this method should be used when you want to inject
|
||||
// custom logic into the request's lifecycle using a custom handler, or if you want to
|
||||
// access properties on the request object before or after sending the request. If
|
||||
// you just want the service response, call the CreateTable method directly
|
||||
// instead.
|
||||
// See CreateTable for more information on using the CreateTable
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
// Note: You must call the "Send" method on the returned request object in order
|
||||
// to execute the request.
|
||||
//
|
||||
// // Example sending a request using the CreateTableRequest method.
|
||||
// req, resp := client.CreateTableRequest(params)
|
||||
|
@ -486,19 +483,18 @@ const opDeleteItem = "DeleteItem"
|
|||
|
||||
// DeleteItemRequest generates a "aws/request.Request" representing the
|
||||
// client's request for the DeleteItem operation. The "output" return
|
||||
// value can be used to capture response data after the request's "Send" method
|
||||
// is called.
|
||||
// value will be populated with the request's response once the request complets
|
||||
// successfuly.
|
||||
//
|
||||
// See DeleteItem for usage and error information.
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// Creating a request object using this method should be used when you want to inject
|
||||
// custom logic into the request's lifecycle using a custom handler, or if you want to
|
||||
// access properties on the request object before or after sending the request. If
|
||||
// you just want the service response, call the DeleteItem method directly
|
||||
// instead.
|
||||
// See DeleteItem for more information on using the DeleteItem
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
// Note: You must call the "Send" method on the returned request object in order
|
||||
// to execute the request.
|
||||
//
|
||||
// // Example sending a request using the DeleteItemRequest method.
|
||||
// req, resp := client.DeleteItemRequest(params)
|
||||
|
@ -598,19 +594,18 @@ const opDeleteTable = "DeleteTable"
|
|||
|
||||
// DeleteTableRequest generates a "aws/request.Request" representing the
|
||||
// client's request for the DeleteTable operation. The "output" return
|
||||
// value can be used to capture response data after the request's "Send" method
|
||||
// is called.
|
||||
// value will be populated with the request's response once the request complets
|
||||
// successfuly.
|
||||
//
|
||||
// See DeleteTable for usage and error information.
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// Creating a request object using this method should be used when you want to inject
|
||||
// custom logic into the request's lifecycle using a custom handler, or if you want to
|
||||
// access properties on the request object before or after sending the request. If
|
||||
// you just want the service response, call the DeleteTable method directly
|
||||
// instead.
|
||||
// See DeleteTable for more information on using the DeleteTable
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
// Note: You must call the "Send" method on the returned request object in order
|
||||
// to execute the request.
|
||||
//
|
||||
// // Example sending a request using the DeleteTableRequest method.
|
||||
// req, resp := client.DeleteTableRequest(params)
|
||||
|
@ -714,19 +709,18 @@ const opDescribeLimits = "DescribeLimits"
|
|||
|
||||
// DescribeLimitsRequest generates a "aws/request.Request" representing the
|
||||
// client's request for the DescribeLimits operation. The "output" return
|
||||
// value can be used to capture response data after the request's "Send" method
|
||||
// is called.
|
||||
// value will be populated with the request's response once the request complets
|
||||
// successfuly.
|
||||
//
|
||||
// See DescribeLimits for usage and error information.
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// Creating a request object using this method should be used when you want to inject
|
||||
// custom logic into the request's lifecycle using a custom handler, or if you want to
|
||||
// access properties on the request object before or after sending the request. If
|
||||
// you just want the service response, call the DescribeLimits method directly
|
||||
// instead.
|
||||
// See DescribeLimits for more information on using the DescribeLimits
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
// Note: You must call the "Send" method on the returned request object in order
|
||||
// to execute the request.
|
||||
//
|
||||
// // Example sending a request using the DescribeLimitsRequest method.
|
||||
// req, resp := client.DescribeLimitsRequest(params)
|
||||
|
@ -850,19 +844,18 @@ const opDescribeTable = "DescribeTable"
|
|||
|
||||
// DescribeTableRequest generates a "aws/request.Request" representing the
|
||||
// client's request for the DescribeTable operation. The "output" return
|
||||
// value can be used to capture response data after the request's "Send" method
|
||||
// is called.
|
||||
// value will be populated with the request's response once the request complets
|
||||
// successfuly.
|
||||
//
|
||||
// See DescribeTable for usage and error information.
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// Creating a request object using this method should be used when you want to inject
|
||||
// custom logic into the request's lifecycle using a custom handler, or if you want to
|
||||
// access properties on the request object before or after sending the request. If
|
||||
// you just want the service response, call the DescribeTable method directly
|
||||
// instead.
|
||||
// See DescribeTable for more information on using the DescribeTable
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
// Note: You must call the "Send" method on the returned request object in order
|
||||
// to execute the request.
|
||||
//
|
||||
// // Example sending a request using the DescribeTableRequest method.
|
||||
// req, resp := client.DescribeTableRequest(params)
|
||||
|
@ -942,19 +935,18 @@ const opDescribeTimeToLive = "DescribeTimeToLive"
|
|||
|
||||
// DescribeTimeToLiveRequest generates a "aws/request.Request" representing the
|
||||
// client's request for the DescribeTimeToLive operation. The "output" return
|
||||
// value can be used to capture response data after the request's "Send" method
|
||||
// is called.
|
||||
// value will be populated with the request's response once the request complets
|
||||
// successfuly.
|
||||
//
|
||||
// See DescribeTimeToLive for usage and error information.
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// Creating a request object using this method should be used when you want to inject
|
||||
// custom logic into the request's lifecycle using a custom handler, or if you want to
|
||||
// access properties on the request object before or after sending the request. If
|
||||
// you just want the service response, call the DescribeTimeToLive method directly
|
||||
// instead.
|
||||
// See DescribeTimeToLive for more information on using the DescribeTimeToLive
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
// Note: You must call the "Send" method on the returned request object in order
|
||||
// to execute the request.
|
||||
//
|
||||
// // Example sending a request using the DescribeTimeToLiveRequest method.
|
||||
// req, resp := client.DescribeTimeToLiveRequest(params)
|
||||
|
@ -1026,19 +1018,18 @@ const opGetItem = "GetItem"
|
|||
|
||||
// GetItemRequest generates a "aws/request.Request" representing the
|
||||
// client's request for the GetItem operation. The "output" return
|
||||
// value can be used to capture response data after the request's "Send" method
|
||||
// is called.
|
||||
// value will be populated with the request's response once the request complets
|
||||
// successfuly.
|
||||
//
|
||||
// See GetItem for usage and error information.
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// Creating a request object using this method should be used when you want to inject
|
||||
// custom logic into the request's lifecycle using a custom handler, or if you want to
|
||||
// access properties on the request object before or after sending the request. If
|
||||
// you just want the service response, call the GetItem method directly
|
||||
// instead.
|
||||
// See GetItem for more information on using the GetItem
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
// Note: You must call the "Send" method on the returned request object in order
|
||||
// to execute the request.
|
||||
//
|
||||
// // Example sending a request using the GetItemRequest method.
|
||||
// req, resp := client.GetItemRequest(params)
|
||||
|
@ -1125,19 +1116,18 @@ const opListTables = "ListTables"
|
|||
|
||||
// ListTablesRequest generates a "aws/request.Request" representing the
|
||||
// client's request for the ListTables operation. The "output" return
|
||||
// value can be used to capture response data after the request's "Send" method
|
||||
// is called.
|
||||
// value will be populated with the request's response once the request complets
|
||||
// successfuly.
|
||||
//
|
||||
// See ListTables for usage and error information.
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// Creating a request object using this method should be used when you want to inject
|
||||
// custom logic into the request's lifecycle using a custom handler, or if you want to
|
||||
// access properties on the request object before or after sending the request. If
|
||||
// you just want the service response, call the ListTables method directly
|
||||
// instead.
|
||||
// See ListTables for more information on using the ListTables
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
// Note: You must call the "Send" method on the returned request object in order
|
||||
// to execute the request.
|
||||
//
|
||||
// // Example sending a request using the ListTablesRequest method.
|
||||
// req, resp := client.ListTablesRequest(params)
|
||||
|
@ -1263,19 +1253,18 @@ const opListTagsOfResource = "ListTagsOfResource"
|
|||
|
||||
// ListTagsOfResourceRequest generates a "aws/request.Request" representing the
|
||||
// client's request for the ListTagsOfResource operation. The "output" return
|
||||
// value can be used to capture response data after the request's "Send" method
|
||||
// is called.
|
||||
// value will be populated with the request's response once the request complets
|
||||
// successfuly.
|
||||
//
|
||||
// See ListTagsOfResource for usage and error information.
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// Creating a request object using this method should be used when you want to inject
|
||||
// custom logic into the request's lifecycle using a custom handler, or if you want to
|
||||
// access properties on the request object before or after sending the request. If
|
||||
// you just want the service response, call the ListTagsOfResource method directly
|
||||
// instead.
|
||||
// See ListTagsOfResource for more information on using the ListTagsOfResource
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
// Note: You must call the "Send" method on the returned request object in order
|
||||
// to execute the request.
|
||||
//
|
||||
// // Example sending a request using the ListTagsOfResourceRequest method.
|
||||
// req, resp := client.ListTagsOfResourceRequest(params)
|
||||
|
@ -1351,19 +1340,18 @@ const opPutItem = "PutItem"
|
|||
|
||||
// PutItemRequest generates a "aws/request.Request" representing the
|
||||
// client's request for the PutItem operation. The "output" return
|
||||
// value can be used to capture response data after the request's "Send" method
|
||||
// is called.
|
||||
// value will be populated with the request's response once the request complets
|
||||
// successfuly.
|
||||
//
|
||||
// See PutItem for usage and error information.
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// Creating a request object using this method should be used when you want to inject
|
||||
// custom logic into the request's lifecycle using a custom handler, or if you want to
|
||||
// access properties on the request object before or after sending the request. If
|
||||
// you just want the service response, call the PutItem method directly
|
||||
// instead.
|
||||
// See PutItem for more information on using the PutItem
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
// Note: You must call the "Send" method on the returned request object in order
|
||||
// to execute the request.
|
||||
//
|
||||
// // Example sending a request using the PutItemRequest method.
|
||||
// req, resp := client.PutItemRequest(params)
|
||||
|
@ -1397,10 +1385,31 @@ func (c *DynamoDB) PutItemRequest(input *PutItemInput) (req *request.Request, ou
|
|||
// table, the new item completely replaces the existing item. You can perform
|
||||
// a conditional put operation (add a new item if one with the specified primary
|
||||
// key doesn't exist), or replace an existing item if it has certain attribute
|
||||
// values.
|
||||
// values. You can return the item's attribute values in the same operation,
|
||||
// using the ReturnValues parameter.
|
||||
//
|
||||
// In addition to putting an item, you can also return the item's attribute
|
||||
// values in the same operation, using the ReturnValues parameter.
|
||||
// This topic provides general information about the PutItem API.
|
||||
//
|
||||
// For information on how to call the PutItem API using the AWS SDK in specific
|
||||
// languages, see the following:
|
||||
//
|
||||
// PutItem in the AWS Command Line Interface (http://docs.aws.amazon.com/goto/aws-cli/dynamodb-2012-08-10/PutItem)
|
||||
//
|
||||
// PutItem in the AWS SDK for .NET (http://docs.aws.amazon.com/goto/DotNetSDKV3/dynamodb-2012-08-10/PutItem)
|
||||
//
|
||||
// PutItem in the AWS SDK for C++ (http://docs.aws.amazon.com/goto/SdkForCpp/dynamodb-2012-08-10/PutItem)
|
||||
//
|
||||
// PutItem in the AWS SDK for Go (http://docs.aws.amazon.com/goto/SdkForGoV1/dynamodb-2012-08-10/PutItem)
|
||||
//
|
||||
// PutItem in the AWS SDK for Java (http://docs.aws.amazon.com/goto/SdkForJava/dynamodb-2012-08-10/PutItem)
|
||||
//
|
||||
// PutItem in the AWS SDK for JavaScript (http://docs.aws.amazon.com/goto/AWSJavaScriptSDK/dynamodb-2012-08-10/PutItem)
|
||||
//
|
||||
// PutItem in the AWS SDK for PHP V3 (http://docs.aws.amazon.com/goto/SdkForPHPV3/dynamodb-2012-08-10/PutItem)
|
||||
//
|
||||
// PutItem in the AWS SDK for Python (http://docs.aws.amazon.com/goto/boto3/dynamodb-2012-08-10/PutItem)
|
||||
//
|
||||
// PutItem in the AWS SDK for Ruby V2 (http://docs.aws.amazon.com/goto/SdkForRubyV2/dynamodb-2012-08-10/PutItem)
|
||||
//
|
||||
// When you add an item, the primary key attribute(s) are the only required
|
||||
// attributes. Attribute values cannot be null. String and Binary type attributes
|
||||
|
@ -1472,19 +1481,18 @@ const opQuery = "Query"
|
|||
|
||||
// QueryRequest generates a "aws/request.Request" representing the
|
||||
// client's request for the Query operation. The "output" return
|
||||
// value can be used to capture response data after the request's "Send" method
|
||||
// is called.
|
||||
// value will be populated with the request's response once the request complets
|
||||
// successfuly.
|
||||
//
|
||||
// See Query for usage and error information.
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// Creating a request object using this method should be used when you want to inject
|
||||
// custom logic into the request's lifecycle using a custom handler, or if you want to
|
||||
// access properties on the request object before or after sending the request. If
|
||||
// you just want the service response, call the Query method directly
|
||||
// instead.
|
||||
// See Query for more information on using the Query
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
// Note: You must call the "Send" method on the returned request object in order
|
||||
// to execute the request.
|
||||
//
|
||||
// // Example sending a request using the QueryRequest method.
|
||||
// req, resp := client.QueryRequest(params)
|
||||
|
@ -1519,26 +1527,48 @@ func (c *DynamoDB) QueryRequest(input *QueryInput) (req *request.Request, output
|
|||
|
||||
// Query API operation for Amazon DynamoDB.
|
||||
//
|
||||
// A Query operation uses the primary key of a table or a secondary index to
|
||||
// directly access items from that table or index.
|
||||
// The Query operation finds items based on primary key values. You can query
|
||||
// any table or secondary index that has a composite primary key (a partition
|
||||
// key and a sort key).
|
||||
//
|
||||
// Use the KeyConditionExpression parameter to provide a specific value for
|
||||
// the partition key. The Query operation will return all of the items from
|
||||
// the table or index with that partition key value. You can optionally narrow
|
||||
// the scope of the Query operation by specifying a sort key value and a comparison
|
||||
// operator in KeyConditionExpression. You can use the ScanIndexForward parameter
|
||||
// to get results in forward or reverse order, by sort key.
|
||||
// operator in KeyConditionExpression. To further refine the Query results,
|
||||
// you can optionally provide a FilterExpression. A FilterExpression determines
|
||||
// which items within the results should be returned to you. All of the other
|
||||
// results are discarded.
|
||||
//
|
||||
// Queries that do not return results consume the minimum number of read capacity
|
||||
// units for that type of read operation.
|
||||
// A Query operation always returns a result set. If no matching items are found,
|
||||
// the result set will be empty. Queries that do not return results consume
|
||||
// the minimum number of read capacity units for that type of read operation.
|
||||
//
|
||||
// If the total number of items meeting the query criteria exceeds the result
|
||||
// set size limit of 1 MB, the query stops and results are returned to the user
|
||||
// with the LastEvaluatedKey element to continue the query in a subsequent operation.
|
||||
// Unlike a Scan operation, a Query operation never returns both an empty result
|
||||
// set and a LastEvaluatedKey value. LastEvaluatedKey is only provided if you
|
||||
// have used the Limit parameter, or if the result set exceeds 1 MB (prior to
|
||||
// applying a filter).
|
||||
// DynamoDB calculates the number of read capacity units consumed based on item
|
||||
// size, not on the amount of data that is returned to an application. The number
|
||||
// of capacity units consumed will be the same whether you request all of the
|
||||
// attributes (the default behavior) or just some of them (using a projection
|
||||
// expression). The number will also be the same whether or not you use a FilterExpression.
|
||||
//
|
||||
// Query results are always sorted by the sort key value. If the data type of
|
||||
// the sort key is Number, the results are returned in numeric order; otherwise,
|
||||
// the results are returned in order of UTF-8 bytes. By default, the sort order
|
||||
// is ascending. To reverse the order, set the ScanIndexForward parameter to
|
||||
// false.
|
||||
//
|
||||
// A single Query operation will read up to the maximum number of items set
|
||||
// (if using the Limit parameter) or a maximum of 1 MB of data and then apply
|
||||
// any filtering to the results using FilterExpression. If LastEvaluatedKey
|
||||
// is present in the response, you will need to paginate the result set. For
|
||||
// more information, see Paginating the Results (http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.html#Query.Pagination)
|
||||
// in the Amazon DynamoDB Developer Guide.
|
||||
//
|
||||
// FilterExpression is applied after a Query finishes, but before the results
|
||||
// are returned. A FilterExpression cannot contain partition key or sort key
|
||||
// attributes. You need to specify those attributes in the KeyConditionExpression.
|
||||
//
|
||||
// A Query operation can return an empty result set and a LastEvaluatedKey if
|
||||
// all the items read for the page of results are filtered out.
|
||||
//
|
||||
// You can query a table, a local secondary index, or a global secondary index.
|
||||
// For a query on a table or on a local secondary index, you can set the ConsistentRead
|
||||
|
@ -1645,19 +1675,18 @@ const opScan = "Scan"
|
|||
|
||||
// ScanRequest generates a "aws/request.Request" representing the
|
||||
// client's request for the Scan operation. The "output" return
|
||||
// value can be used to capture response data after the request's "Send" method
|
||||
// is called.
|
||||
// value will be populated with the request's response once the request complets
|
||||
// successfuly.
|
||||
//
|
||||
// See Scan for usage and error information.
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// Creating a request object using this method should be used when you want to inject
|
||||
// custom logic into the request's lifecycle using a custom handler, or if you want to
|
||||
// access properties on the request object before or after sending the request. If
|
||||
// you just want the service response, call the Scan method directly
|
||||
// instead.
|
||||
// See Scan for more information on using the Scan
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
// Note: You must call the "Send" method on the returned request object in order
|
||||
// to execute the request.
|
||||
//
|
||||
// // Example sending a request using the ScanRequest method.
|
||||
// req, resp := client.ScanRequest(params)
|
||||
|
@ -1702,16 +1731,23 @@ func (c *DynamoDB) ScanRequest(input *ScanInput) (req *request.Request, output *
|
|||
// the number of items exceeding the limit. A scan can result in no table data
|
||||
// meeting the filter criteria.
|
||||
//
|
||||
// By default, Scan operations proceed sequentially; however, for faster performance
|
||||
// on a large table or secondary index, applications can request a parallel
|
||||
// Scan operation by providing the Segment and TotalSegments parameters. For
|
||||
// more information, see Parallel Scan (http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html#QueryAndScanParallelScan)
|
||||
// A single Scan operation will read up to the maximum number of items set (if
|
||||
// using the Limit parameter) or a maximum of 1 MB of data and then apply any
|
||||
// filtering to the results using FilterExpression. If LastEvaluatedKey is present
|
||||
// in the response, you will need to paginate the result set. For more information,
|
||||
// see Paginating the Results (http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Scan.html#Scan.Pagination)
|
||||
// in the Amazon DynamoDB Developer Guide.
|
||||
//
|
||||
// By default, Scan uses eventually consistent reads when accessing the data
|
||||
// in a table; therefore, the result set might not include the changes to data
|
||||
// in the table immediately before the operation began. If you need a consistent
|
||||
// copy of the data, as of the time that the Scan begins, you can set the ConsistentRead
|
||||
// Scan operations proceed sequentially; however, for faster performance on
|
||||
// a large table or secondary index, applications can request a parallel Scan
|
||||
// operation by providing the Segment and TotalSegments parameters. For more
|
||||
// information, see Parallel Scan (http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Scan.html#Scan.ParallelScan)
|
||||
// in the Amazon DynamoDB Developer Guide.
|
||||
//
|
||||
// Scan uses eventually consistent reads when accessing the data in a table;
|
||||
// therefore, the result set might not include the changes to data in the table
|
||||
// immediately before the operation began. If you need a consistent copy of
|
||||
// the data, as of the time that the Scan begins, you can set the ConsistentRead
|
||||
// parameter to true.
|
||||
//
|
||||
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
|
||||
|
@ -1813,19 +1849,18 @@ const opTagResource = "TagResource"
|
|||
|
||||
// TagResourceRequest generates a "aws/request.Request" representing the
|
||||
// client's request for the TagResource operation. The "output" return
|
||||
// value can be used to capture response data after the request's "Send" method
|
||||
// is called.
|
||||
// value will be populated with the request's response once the request complets
|
||||
// successfuly.
|
||||
//
|
||||
// See TagResource for usage and error information.
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// Creating a request object using this method should be used when you want to inject
|
||||
// custom logic into the request's lifecycle using a custom handler, or if you want to
|
||||
// access properties on the request object before or after sending the request. If
|
||||
// you just want the service response, call the TagResource method directly
|
||||
// instead.
|
||||
// See TagResource for more information on using the TagResource
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
// Note: You must call the "Send" method on the returned request object in order
|
||||
// to execute the request.
|
||||
//
|
||||
// // Example sending a request using the TagResourceRequest method.
|
||||
// req, resp := client.TagResourceRequest(params)
|
||||
|
@ -1920,19 +1955,18 @@ const opUntagResource = "UntagResource"
|
|||
|
||||
// UntagResourceRequest generates a "aws/request.Request" representing the
|
||||
// client's request for the UntagResource operation. The "output" return
|
||||
// value can be used to capture response data after the request's "Send" method
|
||||
// is called.
|
||||
// value will be populated with the request's response once the request complets
|
||||
// successfuly.
|
||||
//
|
||||
// See UntagResource for usage and error information.
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// Creating a request object using this method should be used when you want to inject
|
||||
// custom logic into the request's lifecycle using a custom handler, or if you want to
|
||||
// access properties on the request object before or after sending the request. If
|
||||
// you just want the service response, call the UntagResource method directly
|
||||
// instead.
|
||||
// See UntagResource for more information on using the UntagResource
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
// Note: You must call the "Send" method on the returned request object in order
|
||||
// to execute the request.
|
||||
//
|
||||
// // Example sending a request using the UntagResourceRequest method.
|
||||
// req, resp := client.UntagResourceRequest(params)
|
||||
|
@ -2025,19 +2059,18 @@ const opUpdateItem = "UpdateItem"
|
|||
|
||||
// UpdateItemRequest generates a "aws/request.Request" representing the
|
||||
// client's request for the UpdateItem operation. The "output" return
|
||||
// value can be used to capture response data after the request's "Send" method
|
||||
// is called.
|
||||
// value will be populated with the request's response once the request complets
|
||||
// successfuly.
|
||||
//
|
||||
// See UpdateItem for usage and error information.
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// Creating a request object using this method should be used when you want to inject
|
||||
// custom logic into the request's lifecycle using a custom handler, or if you want to
|
||||
// access properties on the request object before or after sending the request. If
|
||||
// you just want the service response, call the UpdateItem method directly
|
||||
// instead.
|
||||
// See UpdateItem for more information on using the UpdateItem
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
// Note: You must call the "Send" method on the returned request object in order
|
||||
// to execute the request.
|
||||
//
|
||||
// // Example sending a request using the UpdateItemRequest method.
|
||||
// req, resp := client.UpdateItemRequest(params)
|
||||
|
@ -2131,19 +2164,18 @@ const opUpdateTable = "UpdateTable"
|
|||
|
||||
// UpdateTableRequest generates a "aws/request.Request" representing the
|
||||
// client's request for the UpdateTable operation. The "output" return
|
||||
// value can be used to capture response data after the request's "Send" method
|
||||
// is called.
|
||||
// value will be populated with the request's response once the request complets
|
||||
// successfuly.
|
||||
//
|
||||
// See UpdateTable for usage and error information.
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// Creating a request object using this method should be used when you want to inject
|
||||
// custom logic into the request's lifecycle using a custom handler, or if you want to
|
||||
// access properties on the request object before or after sending the request. If
|
||||
// you just want the service response, call the UpdateTable method directly
|
||||
// instead.
|
||||
// See UpdateTable for more information on using the UpdateTable
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
// Note: You must call the "Send" method on the returned request object in order
|
||||
// to execute the request.
|
||||
//
|
||||
// // Example sending a request using the UpdateTableRequest method.
|
||||
// req, resp := client.UpdateTableRequest(params)
|
||||
|
@ -2247,19 +2279,18 @@ const opUpdateTimeToLive = "UpdateTimeToLive"
|
|||
|
||||
// UpdateTimeToLiveRequest generates a "aws/request.Request" representing the
|
||||
// client's request for the UpdateTimeToLive operation. The "output" return
|
||||
// value can be used to capture response data after the request's "Send" method
|
||||
// is called.
|
||||
// value will be populated with the request's response once the request complets
|
||||
// successfuly.
|
||||
//
|
||||
// See UpdateTimeToLive for usage and error information.
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// Creating a request object using this method should be used when you want to inject
|
||||
// custom logic into the request's lifecycle using a custom handler, or if you want to
|
||||
// access properties on the request object before or after sending the request. If
|
||||
// you just want the service response, call the UpdateTimeToLive method directly
|
||||
// instead.
|
||||
// See UpdateTimeToLive for more information on using the UpdateTimeToLive
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
// Note: You must call the "Send" method on the returned request object in order
|
||||
// to execute the request.
|
||||
//
|
||||
// // Example sending a request using the UpdateTimeToLiveRequest method.
|
||||
// req, resp := client.UpdateTimeToLiveRequest(params)
|
||||
|
@ -2288,11 +2319,11 @@ func (c *DynamoDB) UpdateTimeToLiveRequest(input *UpdateTimeToLiveInput) (req *r
|
|||
|
||||
// UpdateTimeToLive API operation for Amazon DynamoDB.
|
||||
//
|
||||
// Specify the lifetime of individual table items. The database automatically
|
||||
// removes the item at the expiration of the item. The UpdateTimeToLive method
|
||||
// will enable or disable TTL for the specified table. A successful UpdateTimeToLive
|
||||
// call returns the current TimeToLiveSpecification; it may take up to one hour
|
||||
// for the change to fully process.
|
||||
// The UpdateTimeToLive method will enable or disable TTL for the specified
|
||||
// table. A successful UpdateTimeToLive call returns the current TimeToLiveSpecification;
|
||||
// it may take up to one hour for the change to fully process. Any additional
|
||||
// UpdateTimeToLive calls for the same table during this one hour duration result
|
||||
// in a ValidationException.
|
||||
//
|
||||
// TTL compares the current time in epoch time format to the time stored in
|
||||
// the TTL attribute of an item. If the epoch time value stored in the attribute
|
||||
|
@ -2908,8 +2939,8 @@ type BatchWriteItemInput struct {
|
|||
// * DeleteRequest - Perform a DeleteItem operation on the specified item.
|
||||
// The item to be deleted is identified by a Key subelement:
|
||||
//
|
||||
// Key - A map of primary key attribute values that uniquely identify the !
|
||||
// item. Each entry in this map consists of an attribute name and an attribute
|
||||
// Key - A map of primary key attribute values that uniquely identify the item.
|
||||
// Each entry in this map consists of an attribute name and an attribute
|
||||
// value. For each primary key, you must provide all of the key attributes.
|
||||
// For example, with a simple primary key, you only need to provide a value
|
||||
// for the partition key. For a composite primary key, you must provide values
|
||||
|
@ -3786,7 +3817,7 @@ type DeleteItemInput struct {
|
|||
// in the Amazon DynamoDB Developer Guide.
|
||||
ConditionalOperator *string `type:"string" enum:"ConditionalOperator"`
|
||||
|
||||
// This is a legacy parameter. Use ConditionExpresssion instead. For more information,
|
||||
// This is a legacy parameter. Use ConditionExpression instead. For more information,
|
||||
// see Expected (http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.Expected.html)
|
||||
// in the Amazon DynamoDB Developer Guide.
|
||||
Expected map[string]*ExpectedAttributeValue `type:"map"`
|
||||
|
@ -5953,7 +5984,7 @@ type PutItemInput struct {
|
|||
// in the Amazon DynamoDB Developer Guide.
|
||||
ConditionalOperator *string `type:"string" enum:"ConditionalOperator"`
|
||||
|
||||
// This is a legacy parameter. Use ConditionExpresssion instead. For more information,
|
||||
// This is a legacy parameter. Use ConditionExpression instead. For more information,
|
||||
// see Expected (http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.Expected.html)
|
||||
// in the Amazon DynamoDB Developer Guide.
|
||||
Expected map[string]*ExpectedAttributeValue `type:"map"`
|
||||
|
@ -8050,7 +8081,7 @@ type UpdateItemInput struct {
|
|||
// in the Amazon DynamoDB Developer Guide.
|
||||
ConditionalOperator *string `type:"string" enum:"ConditionalOperator"`
|
||||
|
||||
// This is a legacy parameter. Use ConditionExpresssion instead. For more information,
|
||||
// This is a legacy parameter. Use ConditionExpression instead. For more information,
|
||||
// see Expected (http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.Expected.html)
|
||||
// in the Amazon DynamoDB Developer Guide.
|
||||
Expected map[string]*ExpectedAttributeValue `type:"map"`
|
||||
|
@ -8148,9 +8179,8 @@ type UpdateItemInput struct {
|
|||
// (the default), no statistics are returned.
|
||||
ReturnItemCollectionMetrics *string `type:"string" enum:"ReturnItemCollectionMetrics"`
|
||||
|
||||
// Use ReturnValues if you want to get the item attributes as they appeared
|
||||
// either before or after they were updated. For UpdateItem, the valid values
|
||||
// are:
|
||||
// Use ReturnValues if you want to get the item attributes as they appear before
|
||||
// or after they are updated. For UpdateItem, the valid values are:
|
||||
//
|
||||
// * NONE - If ReturnValues is not specified, or if its value is NONE, then
|
||||
// nothing is returned. (This setting is the default for ReturnValues.)
|
||||
|
@ -8169,9 +8199,9 @@ type UpdateItemInput struct {
|
|||
//
|
||||
// There is no additional cost associated with requesting a return value aside
|
||||
// from the small network and processing overhead of receiving a larger response.
|
||||
// No Read Capacity Units are consumed.
|
||||
// No read capacity units are consumed.
|
||||
//
|
||||
// Values returned are strongly consistent
|
||||
// The values returned are strongly consistent.
|
||||
ReturnValues *string `type:"string" enum:"ReturnValue"`
|
||||
|
||||
// The name of the table containing the item to update.
|
||||
|
@ -8361,9 +8391,11 @@ func (s *UpdateItemInput) SetUpdateExpression(v string) *UpdateItemInput {
|
|||
type UpdateItemOutput struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
// A map of attribute values as they appeared before the UpdateItem operation.
|
||||
// This map only appears if ReturnValues was specified as something other than
|
||||
// NONE in the request. Each element represents one attribute.
|
||||
// A map of attribute values as they appear before or after the UpdateItem operation,
|
||||
// as determined by the ReturnValues parameter.
|
||||
//
|
||||
// The Attributes map is only present if ReturnValues was specified as something
|
||||
// other than NONE in the request. Each element represents one attribute.
|
||||
Attributes map[string]*AttributeValue `type:"map"`
|
||||
|
||||
// The capacity units consumed by the UpdateItem operation. The data returned
|
||||
|
|
64
vendor/github.com/aws/aws-sdk-go/service/dynamodb/doc.go
generated
vendored
64
vendor/github.com/aws/aws-sdk-go/service/dynamodb/doc.go
generated
vendored
|
@ -29,69 +29,17 @@
|
|||
//
|
||||
// Using the Client
|
||||
//
|
||||
// To use the client for Amazon DynamoDB you will first need
|
||||
// to create a new instance of it.
|
||||
// To Amazon DynamoDB with the SDK use the New function to create
|
||||
// a new service client. With that client you can make API requests to the service.
|
||||
// These clients are safe to use concurrently.
|
||||
//
|
||||
// When creating a client for an AWS service you'll first need to have a Session
|
||||
// already created. The Session provides configuration that can be shared
|
||||
// between multiple service clients. Additional configuration can be applied to
|
||||
// the Session and service's client when they are constructed. The aws package's
|
||||
// Config type contains several fields such as Region for the AWS Region the
|
||||
// client should make API requests too. The optional Config value can be provided
|
||||
// as the variadic argument for Sessions and client creation.
|
||||
//
|
||||
// Once the service's client is created you can use it to make API requests the
|
||||
// AWS service. These clients are safe to use concurrently.
|
||||
//
|
||||
// // Create a session to share configuration, and load external configuration.
|
||||
// sess := session.Must(session.NewSession())
|
||||
//
|
||||
// // Create the service's client with the session.
|
||||
// svc := dynamodb.New(sess)
|
||||
//
|
||||
// See the SDK's documentation for more information on how to use service clients.
|
||||
// See the SDK's documentation for more information on how to use the SDK.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/
|
||||
//
|
||||
// See aws package's Config type for more information on configuration options.
|
||||
// See aws.Config documentation for more information on configuring SDK clients.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config
|
||||
//
|
||||
// See the Amazon DynamoDB client DynamoDB for more
|
||||
// information on creating the service's client.
|
||||
// information on creating client for this service.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/service/dynamodb/#New
|
||||
//
|
||||
// Once the client is created you can make an API request to the service.
|
||||
// Each API method takes a input parameter, and returns the service response
|
||||
// and an error.
|
||||
//
|
||||
// The API method will document which error codes the service can be returned
|
||||
// by the operation if the service models the API operation's errors. These
|
||||
// errors will also be available as const strings prefixed with "ErrCode".
|
||||
//
|
||||
// result, err := svc.BatchGetItem(params)
|
||||
// if err != nil {
|
||||
// // Cast err to awserr.Error to handle specific error codes.
|
||||
// aerr, ok := err.(awserr.Error)
|
||||
// if ok && aerr.Code() == <error code to check for> {
|
||||
// // Specific error code handling
|
||||
// }
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// fmt.Println("BatchGetItem result:")
|
||||
// fmt.Println(result)
|
||||
//
|
||||
// Using the Client with Context
|
||||
//
|
||||
// The service's client also provides methods to make API requests with a Context
|
||||
// value. This allows you to control the timeout, and cancellation of pending
|
||||
// requests. These methods also take request Option as variadic parameter to apply
|
||||
// additional configuration to the API request.
|
||||
//
|
||||
// ctx := context.Background()
|
||||
//
|
||||
// result, err := svc.BatchGetItemWithContext(ctx, params)
|
||||
//
|
||||
// See the request package documentation for more information on using Context pattern
|
||||
// with the SDK.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/aws/request/
|
||||
package dynamodb
|
||||
|
|
109
vendor/github.com/aws/aws-sdk-go/service/dynamodb/doc_custom.go
generated
vendored
109
vendor/github.com/aws/aws-sdk-go/service/dynamodb/doc_custom.go
generated
vendored
|
@ -1,84 +1,27 @@
|
|||
// AttributeValue Marshaling and Unmarshaling Helpers
|
||||
//
|
||||
// Utility helpers to marshal and unmarshal AttributeValue to and
|
||||
// from Go types can be found in the dynamodbattribute sub package. This package
|
||||
// provides has specialized functions for the common ways of working with
|
||||
// AttributeValues. Such as map[string]*AttributeValue, []*AttributeValue, and
|
||||
// directly with *AttributeValue. This is helpful for marshaling Go types for API
|
||||
// operations such as PutItem, and unmarshaling Query and Scan APIs' responses.
|
||||
//
|
||||
// See the dynamodbattribute package documentation for more information.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/service/dynamodb/dynamodbattribute/
|
||||
//
|
||||
// AttributeValue Marshaling
|
||||
//
|
||||
// To marshal a Go type to an AttributeValue you can use the Marshal
|
||||
// functions in the dynamodbattribute package. There are specialized versions
|
||||
// of these functions for collections of AttributeValue, such as maps and lists.
|
||||
//
|
||||
// The following example uses MarshalMap to convert the Record Go type to a
|
||||
// dynamodb.AttributeValue type and use the value to make a PutItem API request.
|
||||
//
|
||||
// type Record struct {
|
||||
// ID string
|
||||
// URLs []string
|
||||
// }
|
||||
//
|
||||
// //...
|
||||
//
|
||||
// r := Record{
|
||||
// ID: "ABC123",
|
||||
// URLs: []string{
|
||||
// "https://example.com/first/link",
|
||||
// "https://example.com/second/url",
|
||||
// },
|
||||
// }
|
||||
// av, err := dynamodbattribute.MarshalMap(r)
|
||||
// if err != nil {
|
||||
// panic(fmt.Sprintf("failed to DynamoDB marshal Record, %v", err))
|
||||
// }
|
||||
//
|
||||
// _, err = svc.PutItem(&dynamodb.PutItemInput{
|
||||
// TableName: aws.String(myTableName),
|
||||
// Item: av,
|
||||
// })
|
||||
// if err != nil {
|
||||
// panic(fmt.Sprintf("failed to put Record to DynamoDB, %v", err))
|
||||
// }
|
||||
//
|
||||
// AttributeValue Unmarshaling
|
||||
//
|
||||
// To unmarshal a dynamodb.AttributeValue to a Go type you can use the Unmarshal
|
||||
// functions in the dynamodbattribute package. There are specialized versions
|
||||
// of these functions for collections of AttributeValue, such as maps and lists.
|
||||
//
|
||||
// The following example will unmarshal the DynamoDB's Scan API operation. The
|
||||
// Items returned by the operation will be unmarshaled into the slice of Records
|
||||
// Go type.
|
||||
//
|
||||
// type Record struct {
|
||||
// ID string
|
||||
// URLs []string
|
||||
// }
|
||||
//
|
||||
// //...
|
||||
//
|
||||
// var records []Record
|
||||
//
|
||||
// // Use the ScanPages method to perform the scan with pagination. Use
|
||||
// // just Scan method to make the API call without pagination.
|
||||
// err := svc.ScanPages(&dynamodb.ScanInput{
|
||||
// TableName: aws.String(myTableName),
|
||||
// }, func(page *dynamodb.ScanOutput, last bool) bool {
|
||||
// recs := []Record{}
|
||||
//
|
||||
// err := dynamodbattribute.UnmarshalListOfMaps(page.Items, &recs)
|
||||
// if err != nil {
|
||||
// panic(fmt.Sprintf("failed to unmarshal Dynamodb Scan Items, %v", err))
|
||||
// }
|
||||
//
|
||||
// records = append(records, recs...)
|
||||
//
|
||||
// return true // keep paging
|
||||
// })
|
||||
/*
|
||||
AttributeValue Marshaling and Unmarshaling Helpers
|
||||
|
||||
Utility helpers to marshal and unmarshal AttributeValue to and
|
||||
from Go types can be found in the dynamodbattribute sub package. This package
|
||||
provides has specialized functions for the common ways of working with
|
||||
AttributeValues. Such as map[string]*AttributeValue, []*AttributeValue, and
|
||||
directly with *AttributeValue. This is helpful for marshaling Go types for API
|
||||
operations such as PutItem, and unmarshaling Query and Scan APIs' responses.
|
||||
|
||||
See the dynamodbattribute package documentation for more information.
|
||||
https://docs.aws.amazon.com/sdk-for-go/api/service/dynamodb/dynamodbattribute/
|
||||
|
||||
Expression Builders
|
||||
|
||||
The expression package provides utility types and functions to build DynamoDB
|
||||
expression for type safe construction of API ExpressionAttributeNames, and
|
||||
ExpressionAttribute Values.
|
||||
|
||||
The package represents the various DynamoDB Expressions as structs named
|
||||
accordingly. For example, ConditionBuilder represents a DynamoDB Condition
|
||||
Expression, an UpdateBuilder represents a DynamoDB Update Expression, and so on.
|
||||
|
||||
See the expression package documentation for more information.
|
||||
https://docs.aws.amazon.com/sdk-for-go/api/service/dynamodb/expression/
|
||||
*/
|
||||
package dynamodb
|
||||
|
|
11
vendor/github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute/decode.go
generated
vendored
11
vendor/github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute/decode.go
generated
vendored
|
@ -153,6 +153,7 @@ var stringInterfaceMapType = reflect.TypeOf(map[string]interface{}(nil))
|
|||
var byteSliceType = reflect.TypeOf([]byte(nil))
|
||||
var byteSliceSlicetype = reflect.TypeOf([][]byte(nil))
|
||||
var numberType = reflect.TypeOf(Number(""))
|
||||
var timeType = reflect.TypeOf(time.Time{})
|
||||
|
||||
func (d *Decoder) decode(av *dynamodb.AttributeValue, v reflect.Value, fieldTag tag) error {
|
||||
var u Unmarshaler
|
||||
|
@ -338,12 +339,12 @@ func (d *Decoder) decodeNumber(n *string, v reflect.Value, fieldTag tag) error {
|
|||
}
|
||||
v.SetFloat(i)
|
||||
default:
|
||||
if _, ok := v.Interface().(time.Time); ok && fieldTag.AsUnixTime {
|
||||
if v.Type().ConvertibleTo(timeType) && fieldTag.AsUnixTime {
|
||||
t, err := decodeUnixTime(*n)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v.Set(reflect.ValueOf(t))
|
||||
v.Set(reflect.ValueOf(t).Convert(v.Type()))
|
||||
return nil
|
||||
}
|
||||
return &UnmarshalTypeError{Value: "number", Type: v.Type()}
|
||||
|
@ -502,12 +503,12 @@ func (d *Decoder) decodeString(s *string, v reflect.Value, fieldTag tag) error {
|
|||
|
||||
// To maintain backwards compatibility with ConvertFrom family of methods which
|
||||
// converted strings to time.Time structs
|
||||
if _, ok := v.Interface().(time.Time); ok {
|
||||
if v.Type().ConvertibleTo(timeType) {
|
||||
t, err := time.Parse(time.RFC3339, *s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v.Set(reflect.ValueOf(t))
|
||||
v.Set(reflect.ValueOf(t).Convert(v.Type()))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -564,7 +565,7 @@ func decodeUnixTime(n string) (time.Time, error) {
|
|||
v, err := strconv.ParseInt(n, 10, 64)
|
||||
if err != nil {
|
||||
return time.Time{}, &UnmarshalError{
|
||||
Err: err, Value: n, Type: reflect.TypeOf(time.Time{}),
|
||||
Err: err, Value: n, Type: timeType,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
119
vendor/github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute/decode_test.go
generated
vendored
119
vendor/github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute/decode_test.go
generated
vendored
|
@ -10,7 +10,6 @@ import (
|
|||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/service/dynamodb"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestUnmarshalErrorTypes(t *testing.T) {
|
||||
|
@ -390,12 +389,22 @@ func TestUnmarshalUnmashaler(t *testing.T) {
|
|||
}
|
||||
|
||||
err := Unmarshal(av, u)
|
||||
assert.NoError(t, err)
|
||||
if err != nil {
|
||||
t.Errorf("expect no error, got %v", err)
|
||||
}
|
||||
|
||||
assert.Equal(t, "value", u.Value)
|
||||
assert.Equal(t, 123, u.Value2)
|
||||
assert.Equal(t, true, u.Value3)
|
||||
assert.Equal(t, testDate, u.Value4)
|
||||
if e, a := "value", u.Value; e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if e, a := 123, u.Value2; e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if e, a := true, u.Value3; e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if e, a := testDate, u.Value4; e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeUseNumber(t *testing.T) {
|
||||
|
@ -412,13 +421,20 @@ func TestDecodeUseNumber(t *testing.T) {
|
|||
d.UseNumber = true
|
||||
})
|
||||
err := decoder.Decode(av, &u)
|
||||
assert.NoError(t, err)
|
||||
if err != nil {
|
||||
t.Errorf("expect no error, got %v", err)
|
||||
}
|
||||
|
||||
assert.Equal(t, "value", u["abc"])
|
||||
n, ok := u["def"].(Number)
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, "123", n.String())
|
||||
assert.Equal(t, true, u["ghi"])
|
||||
if e, a := "value", u["abc"]; e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
n := u["def"].(Number)
|
||||
if e, a := "123", n.String(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if e, a := true, u["ghi"]; e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeUseNumberNumberSet(t *testing.T) {
|
||||
|
@ -437,13 +453,18 @@ func TestDecodeUseNumberNumberSet(t *testing.T) {
|
|||
d.UseNumber = true
|
||||
})
|
||||
err := decoder.Decode(av, &u)
|
||||
assert.NoError(t, err)
|
||||
if err != nil {
|
||||
t.Errorf("expect no error, got %v", err)
|
||||
}
|
||||
|
||||
ns, ok := u["ns"].([]Number)
|
||||
assert.True(t, ok)
|
||||
ns := u["ns"].([]Number)
|
||||
|
||||
assert.Equal(t, "123", ns[0].String())
|
||||
assert.Equal(t, "321", ns[1].String())
|
||||
if e, a := "123", ns[0].String(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if e, a := "321", ns[1].String(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeEmbeddedPointerStruct(t *testing.T) {
|
||||
|
@ -471,12 +492,20 @@ func TestDecodeEmbeddedPointerStruct(t *testing.T) {
|
|||
decoder := NewDecoder()
|
||||
a := A{}
|
||||
err := decoder.Decode(av, &a)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 321, a.Aint)
|
||||
if err != nil {
|
||||
t.Errorf("expect no error, got %v", err)
|
||||
}
|
||||
if e, a := 321, a.Aint; e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
// Embedded pointer struct can be created automatically.
|
||||
assert.Equal(t, 123, a.Bint)
|
||||
if e, a := 123, a.Bint; e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
// But not for absent fields.
|
||||
assert.Nil(t, a.C)
|
||||
if a.C != nil {
|
||||
t.Errorf("expect nil, got %v", a.C)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeBooleanOverlay(t *testing.T) {
|
||||
|
@ -491,8 +520,12 @@ func TestDecodeBooleanOverlay(t *testing.T) {
|
|||
var v BooleanOverlay
|
||||
|
||||
err := decoder.Decode(av, &v)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, BooleanOverlay(true), v)
|
||||
if err != nil {
|
||||
t.Errorf("expect no error, got %v", err)
|
||||
}
|
||||
if e, a := BooleanOverlay(true), v; e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeUnixTime(t *testing.T) {
|
||||
|
@ -524,6 +557,42 @@ func TestDecodeUnixTime(t *testing.T) {
|
|||
actual := A{}
|
||||
|
||||
err := Unmarshal(input, &actual)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, expect, actual)
|
||||
if err != nil {
|
||||
t.Errorf("expect no error, got %v", err)
|
||||
}
|
||||
if e, a := expect, actual; e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeAliasedUnixTime(t *testing.T) {
|
||||
type A struct {
|
||||
Normal AliasedTime
|
||||
Tagged AliasedTime `dynamodbav:",unixtime"`
|
||||
}
|
||||
|
||||
expect := A{
|
||||
Normal: AliasedTime(time.Unix(123, 0).UTC()),
|
||||
Tagged: AliasedTime(time.Unix(456, 0)),
|
||||
}
|
||||
|
||||
input := &dynamodb.AttributeValue{
|
||||
M: map[string]*dynamodb.AttributeValue{
|
||||
"Normal": {
|
||||
S: aws.String("1970-01-01T00:02:03Z"),
|
||||
},
|
||||
"Tagged": {
|
||||
N: aws.String("456"),
|
||||
},
|
||||
},
|
||||
}
|
||||
actual := A{}
|
||||
|
||||
err := Unmarshal(input, &actual)
|
||||
if err != nil {
|
||||
t.Errorf("expect no error, got %v", err)
|
||||
}
|
||||
if expect != actual {
|
||||
t.Errorf("expect %v, got %v", expect, actual)
|
||||
}
|
||||
}
|
||||
|
|
2
vendor/github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute/doc.go
generated
vendored
2
vendor/github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute/doc.go
generated
vendored
|
@ -34,7 +34,7 @@
|
|||
// panic(fmt.Sprintf("failed to DynamoDB marshal Record, %v", err))
|
||||
// }
|
||||
//
|
||||
// _, err := r.svc.PutItem(&dynamodb.PutItemInput{
|
||||
// _, err = svc.PutItem(&dynamodb.PutItemInput{
|
||||
// TableName: aws.String(myTableName),
|
||||
// Item: av,
|
||||
// })
|
||||
|
|
4
vendor/github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute/encode.go
generated
vendored
4
vendor/github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute/encode.go
generated
vendored
|
@ -285,7 +285,9 @@ func (e *Encoder) encode(av *dynamodb.AttributeValue, v reflect.Value, fieldTag
|
|||
func (e *Encoder) encodeStruct(av *dynamodb.AttributeValue, v reflect.Value, fieldTag tag) error {
|
||||
// To maintain backwards compatibility with ConvertTo family of methods which
|
||||
// converted time.Time structs to strings
|
||||
if t, ok := v.Interface().(time.Time); ok {
|
||||
if v.Type().ConvertibleTo(timeType) {
|
||||
var t time.Time
|
||||
t = v.Convert(timeType).Interface().(time.Time)
|
||||
if fieldTag.AsUnixTime {
|
||||
return UnixTime(t).MarshalDynamoDBAttributeValue(av)
|
||||
}
|
||||
|
|
94
vendor/github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute/encode_test.go
generated
vendored
94
vendor/github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute/encode_test.go
generated
vendored
|
@ -2,13 +2,13 @@ package dynamodbattribute
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/service/dynamodb"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestMarshalErrorTypes(t *testing.T) {
|
||||
|
@ -73,9 +73,13 @@ func TestMarshalMashaler(t *testing.T) {
|
|||
}
|
||||
|
||||
actual, err := Marshal(m)
|
||||
assert.NoError(t, err)
|
||||
if err != nil {
|
||||
t.Errorf("expect nil, got %v", err)
|
||||
}
|
||||
|
||||
assert.Equal(t, expect, actual)
|
||||
if e, a := expect, actual; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
type testOmitEmptyElemListStruct struct {
|
||||
|
@ -99,8 +103,12 @@ func TestMarshalListOmitEmptyElem(t *testing.T) {
|
|||
m := testOmitEmptyElemListStruct{Values: []string{"abc", "", "123"}}
|
||||
|
||||
actual, err := Marshal(m)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, expect, actual)
|
||||
if err != nil {
|
||||
t.Errorf("expect nil, got %v", err)
|
||||
}
|
||||
if e, a := expect, actual; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMarshalMapOmitEmptyElem(t *testing.T) {
|
||||
|
@ -121,8 +129,12 @@ func TestMarshalMapOmitEmptyElem(t *testing.T) {
|
|||
}}
|
||||
|
||||
actual, err := Marshal(m)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, expect, actual)
|
||||
if err != nil {
|
||||
t.Errorf("expect nil, got %v", err)
|
||||
}
|
||||
if e, a := expect, actual; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
type testOmitEmptyScalar struct {
|
||||
|
@ -141,8 +153,12 @@ func TestMarshalOmitEmpty(t *testing.T) {
|
|||
m := testOmitEmptyScalar{IntPtrSetZero: aws.Int(0)}
|
||||
|
||||
actual, err := Marshal(m)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, expect, actual)
|
||||
if err != nil {
|
||||
t.Errorf("expect nil, got %v", err)
|
||||
}
|
||||
if e, a := expect, actual; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncodeEmbeddedPointerStruct(t *testing.T) {
|
||||
|
@ -158,12 +174,20 @@ func TestEncodeEmbeddedPointerStruct(t *testing.T) {
|
|||
*C
|
||||
}
|
||||
a := A{Aint: 321, B: &B{123}}
|
||||
assert.Equal(t, 321, a.Aint)
|
||||
assert.Equal(t, 123, a.Bint)
|
||||
assert.Nil(t, a.C)
|
||||
if e, a := 321, a.Aint; e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if e, a := 123, a.Bint; e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if a.C != nil {
|
||||
t.Errorf("expect nil, got %v", a.C)
|
||||
}
|
||||
|
||||
actual, err := Marshal(a)
|
||||
assert.NoError(t, err)
|
||||
if err != nil {
|
||||
t.Errorf("expect nil, got %v", err)
|
||||
}
|
||||
expect := &dynamodb.AttributeValue{
|
||||
M: map[string]*dynamodb.AttributeValue{
|
||||
"Aint": {
|
||||
|
@ -174,7 +198,9 @@ func TestEncodeEmbeddedPointerStruct(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}
|
||||
assert.Equal(t, expect, actual)
|
||||
if e, a := expect, actual; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncodeUnixTime(t *testing.T) {
|
||||
|
@ -191,7 +217,9 @@ func TestEncodeUnixTime(t *testing.T) {
|
|||
}
|
||||
|
||||
actual, err := Marshal(a)
|
||||
assert.NoError(t, err)
|
||||
if err != nil {
|
||||
t.Errorf("expect nil, got %v", err)
|
||||
}
|
||||
expect := &dynamodb.AttributeValue{
|
||||
M: map[string]*dynamodb.AttributeValue{
|
||||
"Normal": {
|
||||
|
@ -205,5 +233,39 @@ func TestEncodeUnixTime(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}
|
||||
assert.Equal(t, expect, actual)
|
||||
if e, a := expect, actual; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
type AliasedTime time.Time
|
||||
|
||||
func TestEncodeAliasedUnixTime(t *testing.T) {
|
||||
type A struct {
|
||||
Normal AliasedTime
|
||||
Tagged AliasedTime `dynamodbav:",unixtime"`
|
||||
}
|
||||
|
||||
a := A{
|
||||
Normal: AliasedTime(time.Unix(123, 0).UTC()),
|
||||
Tagged: AliasedTime(time.Unix(456, 0)),
|
||||
}
|
||||
|
||||
actual, err := Marshal(a)
|
||||
if err != nil {
|
||||
t.Errorf("expect no err, got %v", err)
|
||||
}
|
||||
expect := &dynamodb.AttributeValue{
|
||||
M: map[string]*dynamodb.AttributeValue{
|
||||
"Normal": {
|
||||
S: aws.String("1970-01-01T00:02:03Z"),
|
||||
},
|
||||
"Tagged": {
|
||||
N: aws.String("456"),
|
||||
},
|
||||
},
|
||||
}
|
||||
if e, a := expect, actual; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
|
18
vendor/github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute/field_test.go
generated
vendored
18
vendor/github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute/field_test.go
generated
vendored
|
@ -3,8 +3,6 @@ package dynamodbattribute
|
|||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type testUnionValues struct {
|
||||
|
@ -77,9 +75,13 @@ func TestUnionStructFields(t *testing.T) {
|
|||
fields := unionStructFields(v.Type(), MarshalOptions{SupportJSONTags: true})
|
||||
for j, f := range fields {
|
||||
expected := c.expect[j]
|
||||
assert.Equal(t, expected.Name, f.Name, "case %d, field %d", i, j)
|
||||
if e, a := expected.Name, f.Name; e != a {
|
||||
t.Errorf("%d:%d expect %v, got %v", i, j, e, f)
|
||||
}
|
||||
actual := v.FieldByIndex(f.Index).Interface()
|
||||
assert.EqualValues(t, expected.Value, actual, "case %d, field %d", i, j)
|
||||
if e, a := expected.Value, actual; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%d:%d expect %v, got %v", i, j, e, f)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -102,9 +104,13 @@ func TestFieldByName(t *testing.T) {
|
|||
|
||||
for _, c := range cases {
|
||||
f, ok := fieldByName(fields, c.Name)
|
||||
assert.Equal(t, c.Found, ok)
|
||||
if e, a := c.Found, ok; e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if ok {
|
||||
assert.Equal(t, c.FieldName, f.Name)
|
||||
if e, a := c.FieldName, f.Name; e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
13
vendor/github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute/shared_test.go
generated
vendored
13
vendor/github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute/shared_test.go
generated
vendored
|
@ -7,7 +7,6 @@ import (
|
|||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/dynamodb"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type testBinarySetStruct struct {
|
||||
|
@ -376,14 +375,18 @@ func assertConvertTest(t *testing.T, i int, actual, expected interface{}, err, e
|
|||
i++
|
||||
if expectedErr != nil {
|
||||
if err != nil {
|
||||
assert.Equal(t, expectedErr, err, "case %d", i)
|
||||
if e, a := expectedErr, err; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("case %d expect %v, got %v", i, e, a)
|
||||
}
|
||||
} else {
|
||||
assert.Fail(t, "", "case %d, expected error, %v", i)
|
||||
t.Fatalf("case %d, expected error, %v", i, expectedErr)
|
||||
}
|
||||
} else if err != nil {
|
||||
assert.Fail(t, "", "case %d, expect no error, got %v", i, err)
|
||||
t.Fatalf("case %d, expect no error, got %v", i, err)
|
||||
} else {
|
||||
assert.Equal(t, ptrToValue(expected), ptrToValue(actual), "case %d", i)
|
||||
if e, a := ptrToValue(expected), ptrToValue(actual); !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("case %d, expect %v, got %v", i, e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
6
vendor/github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute/tag_test.go
generated
vendored
6
vendor/github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute/tag_test.go
generated
vendored
|
@ -3,8 +3,6 @@ package dynamodbattribute
|
|||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestTagParse(t *testing.T) {
|
||||
|
@ -42,6 +40,8 @@ func TestTagParse(t *testing.T) {
|
|||
if c.av {
|
||||
actual.parseAVTag(c.in)
|
||||
}
|
||||
assert.Equal(t, c.expect, actual, "case %d", i+1)
|
||||
if e, a := c.expect, actual; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("case %d, expect %v, got %v", i, e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
2
vendor/github.com/aws/aws-sdk-go/service/dynamodb/dynamodbiface/interface.go
generated
vendored
2
vendor/github.com/aws/aws-sdk-go/service/dynamodb/dynamodbiface/interface.go
generated
vendored
|
@ -21,7 +21,7 @@ import (
|
|||
//
|
||||
// The best way to use this interface is so the SDK's service client's calls
|
||||
// can be stubbed out for unit testing your code with the SDK without needing
|
||||
// to inject custom request handlers into the the SDK's request pipeline.
|
||||
// to inject custom request handlers into the SDK's request pipeline.
|
||||
//
|
||||
// // myFunc uses an SDK service client to make a request to
|
||||
// // Amazon DynamoDB.
|
||||
|
|
1577
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/condition.go
generated
vendored
Normal file
1577
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/condition.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
1615
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/condition_test.go
generated
vendored
Normal file
1615
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/condition_test.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
48
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/doc.go
generated
vendored
Normal file
48
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
Package expression provides types and functions to create Amazon DynamoDB
|
||||
Expression strings, ExpressionAttributeNames maps, and ExpressionAttributeValues
|
||||
maps.
|
||||
|
||||
Using the Package
|
||||
|
||||
The package represents the various DynamoDB Expressions as structs named
|
||||
accordingly. For example, ConditionBuilder represents a DynamoDB Condition
|
||||
Expression, an UpdateBuilder represents a DynamoDB Update Expression, and so on.
|
||||
The following example shows a sample ConditionExpression and how to build an
|
||||
equilvalent ConditionBuilder
|
||||
|
||||
// Let :a be an ExpressionAttributeValue representing the string "No One You
|
||||
// Know"
|
||||
condExpr := "Artist = :a"
|
||||
condBuilder := expression.Name("Artist").Equal(expression.Value("No One You Know"))
|
||||
|
||||
In order to retrieve the formatted DynamoDB Expression strings, call the getter
|
||||
methods on the Expression struct. To create the Expression struct, call the
|
||||
Build() method on the Builder struct. Because some input structs, such as
|
||||
QueryInput, can have multiple DynamoDB Expressions, multiple structs
|
||||
representing various DynamoDB Expressions can be added to the Builder struct.
|
||||
The following example shows a generic usage of the whole package.
|
||||
|
||||
filt := expression.Name("Artist").Equal(expression.Value("No One You Know"))
|
||||
proj := expression.NamesList(expression.Name("SongTitle"), expression.Name("AlbumTitle"))
|
||||
expr, err := expression.NewBuilder().WithFilter(filt).WithProjection(proj).Build()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
input := &dynamodb.ScanInput{
|
||||
ExpressionAttributeNames: expr.Names(),
|
||||
ExpressionAttributeValues: expr.Values(),
|
||||
FilterExpression: expr.Filter(),
|
||||
ProjectionExpression: expr.Projection(),
|
||||
TableName: aws.String("Music"),
|
||||
}
|
||||
|
||||
The ExpressionAttributeNames and ExpressionAttributeValues member of the input
|
||||
struct must always be assigned when using the Expression struct because all item
|
||||
attribute names and values are aliased. That means that if the
|
||||
ExpressionAttributeNames and ExpressionAttributeValues member is not assigned
|
||||
with the corresponding Names() and Values() methods, the DynamoDB operation will
|
||||
run into a logic error.
|
||||
*/
|
||||
package expression
|
59
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/error.go
generated
vendored
Normal file
59
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/error.go
generated
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
package expression
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// InvalidParameterError is returned if invalid parameters are encountered. This
|
||||
// error specifically refers to situations where parameters are non-empty but
|
||||
// have an invalid syntax/format. The error message includes the function
|
||||
// that returned the error originally and the parameter type that was deemed
|
||||
// invalid.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // err is of type InvalidParameterError
|
||||
// _, err := expression.Name("foo..bar").BuildOperand()
|
||||
type InvalidParameterError struct {
|
||||
parameterType string
|
||||
functionName string
|
||||
}
|
||||
|
||||
func (ipe InvalidParameterError) Error() string {
|
||||
return fmt.Sprintf("%s error: invalid parameter: %s", ipe.functionName, ipe.parameterType)
|
||||
}
|
||||
|
||||
func newInvalidParameterError(funcName, paramType string) InvalidParameterError {
|
||||
return InvalidParameterError{
|
||||
parameterType: paramType,
|
||||
functionName: funcName,
|
||||
}
|
||||
}
|
||||
|
||||
// UnsetParameterError is returned if parameters are empty and uninitialized.
|
||||
// This error is returned if opaque structs (ConditionBuilder, NameBuilder,
|
||||
// Builder, etc) are initialized outside of functions in the package, since all
|
||||
// structs in the package are designed to be initialized with functions.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // err is of type UnsetParameterError
|
||||
// _, err := expression.Builder{}.Build()
|
||||
// _, err := expression.NewBuilder().
|
||||
// WithCondition(expression.ConditionBuilder{}).
|
||||
// Build()
|
||||
type UnsetParameterError struct {
|
||||
parameterType string
|
||||
functionName string
|
||||
}
|
||||
|
||||
func (upe UnsetParameterError) Error() string {
|
||||
return fmt.Sprintf("%s error: unset parameter: %s", upe.functionName, upe.parameterType)
|
||||
}
|
||||
|
||||
func newUnsetParameterError(funcName, paramType string) UnsetParameterError {
|
||||
return UnsetParameterError{
|
||||
parameterType: paramType,
|
||||
functionName: funcName,
|
||||
}
|
||||
}
|
51
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/error_test.go
generated
vendored
Normal file
51
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/error_test.go
generated
vendored
Normal file
|
@ -0,0 +1,51 @@
|
|||
// +build go1.7
|
||||
|
||||
package expression
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestInvalidParameterError(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
input InvalidParameterError
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "invalid error",
|
||||
input: newInvalidParameterError("func", "param"),
|
||||
expected: "func error: invalid parameter: param",
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
actual := c.input.Error()
|
||||
if e, a := c.expected, actual; e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnsetParameterError(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
input UnsetParameterError
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "unset error",
|
||||
input: newUnsetParameterError("func", "param"),
|
||||
expected: "func error: unset parameter: param",
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
actual := c.input.Error()
|
||||
if e, a := c.expected, actual; e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
315
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/examples_test.go
generated
vendored
Normal file
315
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/examples_test.go
generated
vendored
Normal file
|
@ -0,0 +1,315 @@
|
|||
package expression_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/dynamodb"
|
||||
"github.com/aws/aws-sdk-go/service/dynamodb/expression"
|
||||
)
|
||||
|
||||
// Using Projection Expression
|
||||
//
|
||||
// This example queries items in the Music table. The table has a partition key and
|
||||
// sort key (Artist and SongTitle), but this query only specifies the partition key
|
||||
// value. It returns song titles by the artist named "No One You Know".
|
||||
func ExampleBuilder_WithProjection() {
|
||||
svc := dynamodb.New(session.New())
|
||||
|
||||
// Construct the Key condition builder
|
||||
keyCond := expression.Key("Artist").Equal(expression.Value("No One You Know"))
|
||||
|
||||
// Create the project expression builder with a names list.
|
||||
proj := expression.NamesList(expression.Name("SongTitle"))
|
||||
|
||||
// Combine the key condition, and projection together as a DynamoDB expression
|
||||
// builder.
|
||||
expr, err := expression.NewBuilder().
|
||||
WithKeyCondition(keyCond).
|
||||
WithProjection(proj).
|
||||
Build()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
// Use the built expression to populate the DynamoDB Query's API input
|
||||
// parameters.
|
||||
input := &dynamodb.QueryInput{
|
||||
ExpressionAttributeValues: expr.Values(),
|
||||
KeyConditionExpression: expr.KeyCondition(),
|
||||
ProjectionExpression: expr.Projection(),
|
||||
TableName: aws.String("Music"),
|
||||
}
|
||||
|
||||
result, err := svc.Query(input)
|
||||
if err != nil {
|
||||
if aerr, ok := err.(awserr.Error); ok {
|
||||
switch aerr.Code() {
|
||||
case dynamodb.ErrCodeProvisionedThroughputExceededException:
|
||||
fmt.Println(dynamodb.ErrCodeProvisionedThroughputExceededException, aerr.Error())
|
||||
case dynamodb.ErrCodeResourceNotFoundException:
|
||||
fmt.Println(dynamodb.ErrCodeResourceNotFoundException, aerr.Error())
|
||||
case dynamodb.ErrCodeInternalServerError:
|
||||
fmt.Println(dynamodb.ErrCodeInternalServerError, aerr.Error())
|
||||
default:
|
||||
fmt.Println(aerr.Error())
|
||||
}
|
||||
} else {
|
||||
// Print the error, cast err to awserr.Error to get the Code and
|
||||
// Message from an error.
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(result)
|
||||
}
|
||||
|
||||
// Using Key Condition Expression
|
||||
//
|
||||
// This example queries items in the Music table. The table has a partition key and
|
||||
// sort key (Artist and SongTitle), but this query only specifies the partition key
|
||||
// value. It returns song titles by the artist named "No One You Know".
|
||||
func ExampleBuilder_WithKeyCondition() {
|
||||
svc := dynamodb.New(session.New())
|
||||
|
||||
// Construct the Key condition builder
|
||||
keyCond := expression.Key("Artist").Equal(expression.Value("No One You Know"))
|
||||
|
||||
// Create the project expression builder with a names list.
|
||||
proj := expression.NamesList(expression.Name("SongTitle"))
|
||||
|
||||
// Combine the key condition, and projection together as a DynamoDB expression
|
||||
// builder.
|
||||
expr, err := expression.NewBuilder().
|
||||
WithKeyCondition(keyCond).
|
||||
WithProjection(proj).
|
||||
Build()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
// Use the built expression to populate the DynamoDB Query's API input
|
||||
// parameters.
|
||||
input := &dynamodb.QueryInput{
|
||||
ExpressionAttributeValues: expr.Values(),
|
||||
KeyConditionExpression: expr.KeyCondition(),
|
||||
ProjectionExpression: expr.Projection(),
|
||||
TableName: aws.String("Music"),
|
||||
}
|
||||
|
||||
result, err := svc.Query(input)
|
||||
if err != nil {
|
||||
if aerr, ok := err.(awserr.Error); ok {
|
||||
switch aerr.Code() {
|
||||
case dynamodb.ErrCodeProvisionedThroughputExceededException:
|
||||
fmt.Println(dynamodb.ErrCodeProvisionedThroughputExceededException, aerr.Error())
|
||||
case dynamodb.ErrCodeResourceNotFoundException:
|
||||
fmt.Println(dynamodb.ErrCodeResourceNotFoundException, aerr.Error())
|
||||
case dynamodb.ErrCodeInternalServerError:
|
||||
fmt.Println(dynamodb.ErrCodeInternalServerError, aerr.Error())
|
||||
default:
|
||||
fmt.Println(aerr.Error())
|
||||
}
|
||||
} else {
|
||||
// Print the error, cast err to awserr.Error to get the Code and
|
||||
// Message from an error.
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(result)
|
||||
}
|
||||
|
||||
// Using Filter Expression
|
||||
//
|
||||
// This example scans the entire Music table, and then narrows the results to songs
|
||||
// by the artist "No One You Know". For each item, only the album title and song title
|
||||
// are returned.
|
||||
func ExampleBuilder_WithFilter() {
|
||||
svc := dynamodb.New(session.New())
|
||||
|
||||
// Construct the filter builder with a name and value.
|
||||
filt := expression.Name("Artist").Equal(expression.Value("No One You Know"))
|
||||
|
||||
// Create the names list projection of names to project.
|
||||
proj := expression.NamesList(
|
||||
expression.Name("AlbumTitle"),
|
||||
expression.Name("SongTitle"),
|
||||
)
|
||||
|
||||
// Using the filter and projections create a DynamoDB expression from the two.
|
||||
expr, err := expression.NewBuilder().
|
||||
WithFilter(filt).
|
||||
WithProjection(proj).
|
||||
Build()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
// Use the built expression to populate the DynamoDB Scan API input parameters.
|
||||
input := &dynamodb.ScanInput{
|
||||
ExpressionAttributeNames: expr.Names(),
|
||||
ExpressionAttributeValues: expr.Values(),
|
||||
FilterExpression: expr.Filter(),
|
||||
ProjectionExpression: expr.Projection(),
|
||||
TableName: aws.String("Music"),
|
||||
}
|
||||
|
||||
result, err := svc.Scan(input)
|
||||
if err != nil {
|
||||
if aerr, ok := err.(awserr.Error); ok {
|
||||
switch aerr.Code() {
|
||||
case dynamodb.ErrCodeProvisionedThroughputExceededException:
|
||||
fmt.Println(dynamodb.ErrCodeProvisionedThroughputExceededException, aerr.Error())
|
||||
case dynamodb.ErrCodeResourceNotFoundException:
|
||||
fmt.Println(dynamodb.ErrCodeResourceNotFoundException, aerr.Error())
|
||||
case dynamodb.ErrCodeInternalServerError:
|
||||
fmt.Println(dynamodb.ErrCodeInternalServerError, aerr.Error())
|
||||
default:
|
||||
fmt.Println(aerr.Error())
|
||||
}
|
||||
} else {
|
||||
// Print the error, cast err to awserr.Error to get the Code and
|
||||
// Message from an error.
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(result)
|
||||
}
|
||||
|
||||
// Using Update Expression
|
||||
//
|
||||
// This example updates an item in the Music table. It adds a new attribute (Year) and
|
||||
// modifies the AlbumTitle attribute. All of the attributes in the item, as they appear
|
||||
// after the update, are returned in the response.
|
||||
func ExampleBuilder_WithUpdate() {
|
||||
svc := dynamodb.New(session.New())
|
||||
|
||||
// Create an update to set two fields in the table.
|
||||
update := expression.Set(
|
||||
expression.Name("Year"),
|
||||
expression.Value(2015),
|
||||
).Set(
|
||||
expression.Name("AlbumTitle"),
|
||||
expression.Value("Louder Than Ever"),
|
||||
)
|
||||
|
||||
// Create the DynamoDB expression from the Update.
|
||||
expr, err := expression.NewBuilder().
|
||||
WithUpdate(update).
|
||||
Build()
|
||||
|
||||
// Use the built expression to populate the DynamoDB UpdateItem API
|
||||
// input parameters.
|
||||
input := &dynamodb.UpdateItemInput{
|
||||
ExpressionAttributeNames: expr.Names(),
|
||||
ExpressionAttributeValues: expr.Values(),
|
||||
Key: map[string]*dynamodb.AttributeValue{
|
||||
"Artist": {
|
||||
S: aws.String("Acme Band"),
|
||||
},
|
||||
"SongTitle": {
|
||||
S: aws.String("Happy Day"),
|
||||
},
|
||||
},
|
||||
ReturnValues: aws.String("ALL_NEW"),
|
||||
TableName: aws.String("Music"),
|
||||
UpdateExpression: expr.Update(),
|
||||
}
|
||||
|
||||
result, err := svc.UpdateItem(input)
|
||||
if err != nil {
|
||||
if aerr, ok := err.(awserr.Error); ok {
|
||||
switch aerr.Code() {
|
||||
case dynamodb.ErrCodeConditionalCheckFailedException:
|
||||
fmt.Println(dynamodb.ErrCodeConditionalCheckFailedException, aerr.Error())
|
||||
case dynamodb.ErrCodeProvisionedThroughputExceededException:
|
||||
fmt.Println(dynamodb.ErrCodeProvisionedThroughputExceededException, aerr.Error())
|
||||
case dynamodb.ErrCodeResourceNotFoundException:
|
||||
fmt.Println(dynamodb.ErrCodeResourceNotFoundException, aerr.Error())
|
||||
case dynamodb.ErrCodeItemCollectionSizeLimitExceededException:
|
||||
fmt.Println(dynamodb.ErrCodeItemCollectionSizeLimitExceededException, aerr.Error())
|
||||
case dynamodb.ErrCodeInternalServerError:
|
||||
fmt.Println(dynamodb.ErrCodeInternalServerError, aerr.Error())
|
||||
default:
|
||||
fmt.Println(aerr.Error())
|
||||
}
|
||||
} else {
|
||||
// Print the error, cast err to awserr.Error to get the Code and
|
||||
// Message from an error.
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(result)
|
||||
}
|
||||
|
||||
// Using Condition Expression
|
||||
//
|
||||
// This example deletes an item from the Music table if the rating is lower than
|
||||
// 7.
|
||||
func ExampleBuilder_WithCondition() {
|
||||
svc := dynamodb.New(session.New())
|
||||
|
||||
// Create a condition where the Rating field must be less than 7.
|
||||
cond := expression.Name("Rating").LessThan(expression.Value(7))
|
||||
|
||||
// Create a DynamoDB expression from the condition.
|
||||
expr, err := expression.NewBuilder().
|
||||
WithCondition(cond).
|
||||
Build()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
// Use the built expression to populate the DeleteItem API operation with the
|
||||
// condition expression.
|
||||
input := &dynamodb.DeleteItemInput{
|
||||
Key: map[string]*dynamodb.AttributeValue{
|
||||
"Artist": {
|
||||
S: aws.String("No One You Know"),
|
||||
},
|
||||
"SongTitle": {
|
||||
S: aws.String("Scared of My Shadow"),
|
||||
},
|
||||
},
|
||||
ExpressionAttributeNames: expr.Names(),
|
||||
ExpressionAttributeValues: expr.Values(),
|
||||
ConditionExpression: expr.Condition(),
|
||||
TableName: aws.String("Music"),
|
||||
}
|
||||
|
||||
result, err := svc.DeleteItem(input)
|
||||
if err != nil {
|
||||
if aerr, ok := err.(awserr.Error); ok {
|
||||
switch aerr.Code() {
|
||||
case dynamodb.ErrCodeConditionalCheckFailedException:
|
||||
fmt.Println(dynamodb.ErrCodeConditionalCheckFailedException, aerr.Error())
|
||||
case dynamodb.ErrCodeProvisionedThroughputExceededException:
|
||||
fmt.Println(dynamodb.ErrCodeProvisionedThroughputExceededException, aerr.Error())
|
||||
case dynamodb.ErrCodeResourceNotFoundException:
|
||||
fmt.Println(dynamodb.ErrCodeResourceNotFoundException, aerr.Error())
|
||||
case dynamodb.ErrCodeItemCollectionSizeLimitExceededException:
|
||||
fmt.Println(dynamodb.ErrCodeItemCollectionSizeLimitExceededException, aerr.Error())
|
||||
case dynamodb.ErrCodeInternalServerError:
|
||||
fmt.Println(dynamodb.ErrCodeInternalServerError, aerr.Error())
|
||||
default:
|
||||
fmt.Println(aerr.Error())
|
||||
}
|
||||
} else {
|
||||
// Print the error, cast err to awserr.Error to get the Code and
|
||||
// Message from an error.
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(result)
|
||||
}
|
635
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/expression.go
generated
vendored
Normal file
635
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/expression.go
generated
vendored
Normal file
|
@ -0,0 +1,635 @@
|
|||
package expression
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/dynamodb"
|
||||
)
|
||||
|
||||
// expressionType specifies the type of Expression. Declaring this type is used
|
||||
// to eliminate magic strings
|
||||
type expressionType string
|
||||
|
||||
const (
|
||||
projection expressionType = "projection"
|
||||
keyCondition = "keyCondition"
|
||||
condition = "condition"
|
||||
filter = "filter"
|
||||
update = "update"
|
||||
)
|
||||
|
||||
// Implement the Sort interface
|
||||
type typeList []expressionType
|
||||
|
||||
func (l typeList) Len() int {
|
||||
return len(l)
|
||||
}
|
||||
|
||||
func (l typeList) Less(i, j int) bool {
|
||||
return string(l[i]) < string(l[j])
|
||||
}
|
||||
|
||||
func (l typeList) Swap(i, j int) {
|
||||
l[i], l[j] = l[j], l[i]
|
||||
}
|
||||
|
||||
// Builder represents the struct that builds the Expression struct. Methods such
|
||||
// as WithProjection() and WithCondition() can add different kinds of DynamoDB
|
||||
// Expressions to the Builder. The method Build() creates an Expression struct
|
||||
// with the specified types of DynamoDB Expressions.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// keyCond := expression.Key("someKey").Equal(expression.Value("someValue"))
|
||||
// proj := expression.NamesList(expression.Name("aName"), expression.Name("anotherName"), expression.Name("oneOtherName"))
|
||||
//
|
||||
// builder := expression.NewBuilder().WithKeyCondition(keyCond).WithProjection(proj)
|
||||
// expression := builder.Build()
|
||||
//
|
||||
// queryInput := dynamodb.QueryInput{
|
||||
// KeyConditionExpression: expression.KeyCondition(),
|
||||
// ProjectionExpression: expression.Projection(),
|
||||
// ExpressionAttributeNames: expression.Names(),
|
||||
// ExpressionAttributeValues: expression.Values(),
|
||||
// TableName: aws.String("SomeTable"),
|
||||
// }
|
||||
type Builder struct {
|
||||
expressionMap map[expressionType]treeBuilder
|
||||
}
|
||||
|
||||
// NewBuilder returns an empty Builder struct. Methods such as WithProjection()
|
||||
// and WithCondition() can add different kinds of DynamoDB Expressions to the
|
||||
// Builder. The method Build() creates an Expression struct with the specified
|
||||
// types of DynamoDB Expressions.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// keyCond := expression.Key("someKey").Equal(expression.Value("someValue"))
|
||||
// proj := expression.NamesList(expression.Name("aName"), expression.Name("anotherName"), expression.Name("oneOtherName"))
|
||||
// builder := expression.NewBuilder().WithKeyCondition(keyCond).WithProjection(proj)
|
||||
func NewBuilder() Builder {
|
||||
return Builder{}
|
||||
}
|
||||
|
||||
// Build builds an Expression struct representing multiple types of DynamoDB
|
||||
// Expressions. Getter methods on the resulting Expression struct returns the
|
||||
// DynamoDB Expression strings as well as the maps that correspond to
|
||||
// ExpressionAttributeNames and ExpressionAttributeValues. Calling Build() on an
|
||||
// empty Builder returns the typed error EmptyParameterError.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // keyCond represents the Key Condition Expression
|
||||
// keyCond := expression.Key("someKey").Equal(expression.Value("someValue"))
|
||||
// // proj represents the Projection Expression
|
||||
// proj := expression.NamesList(expression.Name("aName"), expression.Name("anotherName"), expression.Name("oneOtherName"))
|
||||
//
|
||||
// // Add keyCond and proj to builder as a Key Condition and Projection
|
||||
// // respectively
|
||||
// builder := expression.NewBuilder().WithKeyCondition(keyCond).WithProjection(proj)
|
||||
// expression := builder.Build()
|
||||
//
|
||||
// queryInput := dynamodb.QueryInput{
|
||||
// KeyConditionExpression: expression.KeyCondition(),
|
||||
// ProjectionExpression: expression.Projection(),
|
||||
// ExpressionAttributeNames: expression.Names(),
|
||||
// ExpressionAttributeValues: expression.Values(),
|
||||
// TableName: aws.String("SomeTable"),
|
||||
// }
|
||||
func (b Builder) Build() (Expression, error) {
|
||||
if b.expressionMap == nil {
|
||||
return Expression{}, newUnsetParameterError("Build", "Builder")
|
||||
}
|
||||
|
||||
aliasList, expressionMap, err := b.buildChildTrees()
|
||||
if err != nil {
|
||||
return Expression{}, err
|
||||
}
|
||||
|
||||
expression := Expression{
|
||||
expressionMap: expressionMap,
|
||||
}
|
||||
|
||||
if len(aliasList.namesList) != 0 {
|
||||
namesMap := map[string]*string{}
|
||||
for ind, val := range aliasList.namesList {
|
||||
namesMap[fmt.Sprintf("#%v", ind)] = aws.String(val)
|
||||
}
|
||||
expression.namesMap = namesMap
|
||||
}
|
||||
|
||||
if len(aliasList.valuesList) != 0 {
|
||||
valuesMap := map[string]*dynamodb.AttributeValue{}
|
||||
for i := 0; i < len(aliasList.valuesList); i++ {
|
||||
valuesMap[fmt.Sprintf(":%v", i)] = &aliasList.valuesList[i]
|
||||
}
|
||||
expression.valuesMap = valuesMap
|
||||
}
|
||||
|
||||
return expression, nil
|
||||
}
|
||||
|
||||
// buildChildTrees compiles the list of treeBuilders that are the children of
|
||||
// the argument Builder. The returned aliasList represents all the alias tokens
|
||||
// used in the expression strings. The returned map[string]string maps the type
|
||||
// of expression (i.e. "condition", "update") to the appropriate expression
|
||||
// string.
|
||||
func (b Builder) buildChildTrees() (aliasList, map[expressionType]string, error) {
|
||||
aList := aliasList{}
|
||||
formattedExpressions := map[expressionType]string{}
|
||||
keys := typeList{}
|
||||
|
||||
for expressionType := range b.expressionMap {
|
||||
keys = append(keys, expressionType)
|
||||
}
|
||||
|
||||
sort.Sort(keys)
|
||||
|
||||
for _, key := range keys {
|
||||
node, err := b.expressionMap[key].buildTree()
|
||||
if err != nil {
|
||||
return aliasList{}, nil, err
|
||||
}
|
||||
formattedExpression, err := node.buildExpressionString(&aList)
|
||||
if err != nil {
|
||||
return aliasList{}, nil, err
|
||||
}
|
||||
formattedExpressions[key] = formattedExpression
|
||||
}
|
||||
|
||||
return aList, formattedExpressions, nil
|
||||
}
|
||||
|
||||
// WithCondition method adds the argument ConditionBuilder as a Condition
|
||||
// Expression to the argument Builder. If the argument Builder already has a
|
||||
// ConditionBuilder representing a Condition Expression, WithCondition()
|
||||
// overwrites the existing ConditionBuilder.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // let builder be an existing Builder{} and cond be an existing
|
||||
// // ConditionBuilder{}
|
||||
// builder = builder.WithCondition(cond)
|
||||
//
|
||||
// // add other DynamoDB Expressions to the builder. let proj be an already
|
||||
// // existing ProjectionBuilder
|
||||
// builder = builder.WithProjection(proj)
|
||||
// // create an Expression struct
|
||||
// expression := builder.Build()
|
||||
func (b Builder) WithCondition(conditionBuilder ConditionBuilder) Builder {
|
||||
if b.expressionMap == nil {
|
||||
b.expressionMap = map[expressionType]treeBuilder{}
|
||||
}
|
||||
b.expressionMap[condition] = conditionBuilder
|
||||
return b
|
||||
}
|
||||
|
||||
// WithProjection method adds the argument ProjectionBuilder as a Projection
|
||||
// Expression to the argument Builder. If the argument Builder already has a
|
||||
// ProjectionBuilder representing a Projection Expression, WithProjection()
|
||||
// overwrites the existing ProjectionBuilder.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // let builder be an existing Builder{} and proj be an existing
|
||||
// // ProjectionBuilder{}
|
||||
// builder = builder.WithProjection(proj)
|
||||
//
|
||||
// // add other DynamoDB Expressions to the builder. let cond be an already
|
||||
// // existing ConditionBuilder
|
||||
// builder = builder.WithCondition(cond)
|
||||
// // create an Expression struct
|
||||
// expression := builder.Build()
|
||||
func (b Builder) WithProjection(projectionBuilder ProjectionBuilder) Builder {
|
||||
if b.expressionMap == nil {
|
||||
b.expressionMap = map[expressionType]treeBuilder{}
|
||||
}
|
||||
b.expressionMap[projection] = projectionBuilder
|
||||
return b
|
||||
}
|
||||
|
||||
// WithKeyCondition method adds the argument KeyConditionBuilder as a Key
|
||||
// Condition Expression to the argument Builder. If the argument Builder already
|
||||
// has a KeyConditionBuilder representing a Key Condition Expression,
|
||||
// WithKeyCondition() overwrites the existing KeyConditionBuilder.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // let builder be an existing Builder{} and keyCond be an existing
|
||||
// // KeyConditionBuilder{}
|
||||
// builder = builder.WithKeyCondition(keyCond)
|
||||
//
|
||||
// // add other DynamoDB Expressions to the builder. let cond be an already
|
||||
// // existing ConditionBuilder
|
||||
// builder = builder.WithCondition(cond)
|
||||
// // create an Expression struct
|
||||
// expression := builder.Build()
|
||||
func (b Builder) WithKeyCondition(keyConditionBuilder KeyConditionBuilder) Builder {
|
||||
if b.expressionMap == nil {
|
||||
b.expressionMap = map[expressionType]treeBuilder{}
|
||||
}
|
||||
b.expressionMap[keyCondition] = keyConditionBuilder
|
||||
return b
|
||||
}
|
||||
|
||||
// WithFilter method adds the argument ConditionBuilder as a Filter Expression
|
||||
// to the argument Builder. If the argument Builder already has a
|
||||
// ConditionBuilder representing a Filter Expression, WithFilter()
|
||||
// overwrites the existing ConditionBuilder.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // let builder be an existing Builder{} and filt be an existing
|
||||
// // ConditionBuilder{}
|
||||
// builder = builder.WithFilter(filt)
|
||||
//
|
||||
// // add other DynamoDB Expressions to the builder. let cond be an already
|
||||
// // existing ConditionBuilder
|
||||
// builder = builder.WithCondition(cond)
|
||||
// // create an Expression struct
|
||||
// expression := builder.Build()
|
||||
func (b Builder) WithFilter(filterBuilder ConditionBuilder) Builder {
|
||||
if b.expressionMap == nil {
|
||||
b.expressionMap = map[expressionType]treeBuilder{}
|
||||
}
|
||||
b.expressionMap[filter] = filterBuilder
|
||||
return b
|
||||
}
|
||||
|
||||
// WithUpdate method adds the argument UpdateBuilder as an Update Expression
|
||||
// to the argument Builder. If the argument Builder already has a UpdateBuilder
|
||||
// representing a Update Expression, WithUpdate() overwrites the existing
|
||||
// UpdateBuilder.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // let builder be an existing Builder{} and update be an existing
|
||||
// // UpdateBuilder{}
|
||||
// builder = builder.WithUpdate(update)
|
||||
//
|
||||
// // add other DynamoDB Expressions to the builder. let cond be an already
|
||||
// // existing ConditionBuilder
|
||||
// builder = builder.WithCondition(cond)
|
||||
// // create an Expression struct
|
||||
// expression := builder.Build()
|
||||
func (b Builder) WithUpdate(updateBuilder UpdateBuilder) Builder {
|
||||
if b.expressionMap == nil {
|
||||
b.expressionMap = map[expressionType]treeBuilder{}
|
||||
}
|
||||
b.expressionMap[update] = updateBuilder
|
||||
return b
|
||||
}
|
||||
|
||||
// Expression represents a collection of DynamoDB Expressions. The getter
|
||||
// methods of the Expression struct retrieves the formatted DynamoDB
|
||||
// Expressions, ExpressionAttributeNames, and ExpressionAttributeValues.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // keyCond represents the Key Condition Expression
|
||||
// keyCond := expression.Key("someKey").Equal(expression.Value("someValue"))
|
||||
// // proj represents the Projection Expression
|
||||
// proj := expression.NamesList(expression.Name("aName"), expression.Name("anotherName"), expression.Name("oneOtherName"))
|
||||
//
|
||||
// // Add keyCond and proj to builder as a Key Condition and Projection
|
||||
// // respectively
|
||||
// builder := expression.NewBuilder().WithKeyCondition(keyCond).WithProjection(proj)
|
||||
// expression := builder.Build()
|
||||
//
|
||||
// queryInput := dynamodb.QueryInput{
|
||||
// KeyConditionExpression: expression.KeyCondition(),
|
||||
// ProjectionExpression: expression.Projection(),
|
||||
// ExpressionAttributeNames: expression.Names(),
|
||||
// ExpressionAttributeValues: expression.Values(),
|
||||
// TableName: aws.String("SomeTable"),
|
||||
// }
|
||||
type Expression struct {
|
||||
expressionMap map[expressionType]string
|
||||
namesMap map[string]*string
|
||||
valuesMap map[string]*dynamodb.AttributeValue
|
||||
}
|
||||
|
||||
// treeBuilder interface is fulfilled by builder structs that represent
|
||||
// different types of Expressions.
|
||||
type treeBuilder interface {
|
||||
// buildTree creates the tree structure of exprNodes. The tree structure
|
||||
// of exprNodes are traversed in order to build the string representing
|
||||
// different types of Expressions as well as the maps that represent
|
||||
// ExpressionAttributeNames and ExpressionAttributeValues.
|
||||
buildTree() (exprNode, error)
|
||||
}
|
||||
|
||||
// Condition returns the *string corresponding to the Condition Expression
|
||||
// of the argument Expression. This method is used to satisfy the members of
|
||||
// DynamoDB input structs. If the Expression does not have a condition
|
||||
// expression this method returns nil.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // let expression be an instance of Expression{}
|
||||
//
|
||||
// deleteInput := dynamodb.DeleteItemInput{
|
||||
// ConditionExpression: expression.Condition(),
|
||||
// ExpressionAttributeNames: expression.Names(),
|
||||
// ExpressionAttributeValues: expression.Values(),
|
||||
// Key: map[string]*dynamodb.AttributeValue{
|
||||
// "PartitionKey": &dynamodb.AttributeValue{
|
||||
// S: aws.String("SomeKey"),
|
||||
// },
|
||||
// },
|
||||
// TableName: aws.String("SomeTable"),
|
||||
// }
|
||||
func (e Expression) Condition() *string {
|
||||
return e.returnExpression(condition)
|
||||
}
|
||||
|
||||
// Filter returns the *string corresponding to the Filter Expression of the
|
||||
// argument Expression. This method is used to satisfy the members of DynamoDB
|
||||
// input structs. If the Expression does not have a filter expression this
|
||||
// method returns nil.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // let expression be an instance of Expression{}
|
||||
//
|
||||
// queryInput := dynamodb.QueryInput{
|
||||
// KeyConditionExpression: expression.KeyCondition(),
|
||||
// FilterExpression: expression.Filter(),
|
||||
// ExpressionAttributeNames: expression.Names(),
|
||||
// ExpressionAttributeValues: expression.Values(),
|
||||
// TableName: aws.String("SomeTable"),
|
||||
// }
|
||||
func (e Expression) Filter() *string {
|
||||
return e.returnExpression(filter)
|
||||
}
|
||||
|
||||
// Projection returns the *string corresponding to the Projection Expression
|
||||
// of the argument Expression. This method is used to satisfy the members of
|
||||
// DynamoDB input structs. If the Expression does not have a projection
|
||||
// expression this method returns nil.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // let expression be an instance of Expression{}
|
||||
//
|
||||
// queryInput := dynamodb.QueryInput{
|
||||
// KeyConditionExpression: expression.KeyCondition(),
|
||||
// ProjectionExpression: expression.Projection(),
|
||||
// ExpressionAttributeNames: expression.Names(),
|
||||
// ExpressionAttributeValues: expression.Values(),
|
||||
// TableName: aws.String("SomeTable"),
|
||||
// }
|
||||
func (e Expression) Projection() *string {
|
||||
return e.returnExpression(projection)
|
||||
}
|
||||
|
||||
// KeyCondition returns the *string corresponding to the Key Condition
|
||||
// Expression of the argument Expression. This method is used to satisfy the
|
||||
// members of DynamoDB input structs. If the argument Expression does not have a
|
||||
// KeyConditionExpression, KeyCondition() returns nil.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // let expression be an instance of Expression{}
|
||||
//
|
||||
// queryInput := dynamodb.QueryInput{
|
||||
// KeyConditionExpression: expression.KeyCondition(),
|
||||
// ProjectionExpression: expression.Projection(),
|
||||
// ExpressionAttributeNames: expression.Names(),
|
||||
// ExpressionAttributeValues: expression.Values(),
|
||||
// TableName: aws.String("SomeTable"),
|
||||
// }
|
||||
func (e Expression) KeyCondition() *string {
|
||||
return e.returnExpression(keyCondition)
|
||||
}
|
||||
|
||||
// Update returns the *string corresponding to the Update Expression of the
|
||||
// argument Expression. This method is used to satisfy the members of DynamoDB
|
||||
// input structs. If the argument Expression does not have a UpdateExpression,
|
||||
// Update() returns nil.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // let expression be an instance of Expression{}
|
||||
//
|
||||
// updateInput := dynamodb.UpdateInput{
|
||||
// Key: map[string]*dynamodb.AttributeValue{
|
||||
// "PartitionKey": {
|
||||
// S: aws.String("someKey"),
|
||||
// },
|
||||
// },
|
||||
// UpdateExpression: expression.Update(),
|
||||
// ExpressionAttributeNames: expression.Names(),
|
||||
// ExpressionAttributeValues: expression.Values(),
|
||||
// TableName: aws.String("SomeTable"),
|
||||
// }
|
||||
func (e Expression) Update() *string {
|
||||
return e.returnExpression(update)
|
||||
}
|
||||
|
||||
// Names returns the map[string]*string corresponding to the
|
||||
// ExpressionAttributeNames of the argument Expression. This method is used to
|
||||
// satisfy the members of DynamoDB input structs. If Expression does not use
|
||||
// ExpressionAttributeNames, this method returns nil. The
|
||||
// ExpressionAttributeNames and ExpressionAttributeValues member of the input
|
||||
// struct must always be assigned when using the Expression struct since all
|
||||
// item attribute names and values are aliased. That means that if the
|
||||
// ExpressionAttributeNames and ExpressionAttributeValues member is not assigned
|
||||
// with the corresponding Names() and Values() methods, the DynamoDB operation
|
||||
// will run into a logic error.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // let expression be an instance of Expression{}
|
||||
//
|
||||
// queryInput := dynamodb.QueryInput{
|
||||
// KeyConditionExpression: expression.KeyCondition(),
|
||||
// ProjectionExpression: expression.Projection(),
|
||||
// ExpressionAttributeNames: expression.Names(),
|
||||
// ExpressionAttributeValues: expression.Values(),
|
||||
// TableName: aws.String("SomeTable"),
|
||||
// }
|
||||
func (e Expression) Names() map[string]*string {
|
||||
return e.namesMap
|
||||
}
|
||||
|
||||
// Values returns the map[string]*dynamodb.AttributeValue corresponding to
|
||||
// the ExpressionAttributeValues of the argument Expression. This method is used
|
||||
// to satisfy the members of DynamoDB input structs. If Expression does not use
|
||||
// ExpressionAttributeValues, this method returns nil. The
|
||||
// ExpressionAttributeNames and ExpressionAttributeValues member of the input
|
||||
// struct must always be assigned when using the Expression struct since all
|
||||
// item attribute names and values are aliased. That means that if the
|
||||
// ExpressionAttributeNames and ExpressionAttributeValues member is not assigned
|
||||
// with the corresponding Names() and Values() methods, the DynamoDB operation
|
||||
// will run into a logic error.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // let expression be an instance of Expression{}
|
||||
//
|
||||
// queryInput := dynamodb.QueryInput{
|
||||
// KeyConditionExpression: expression.KeyCondition(),
|
||||
// ProjectionExpression: expression.Projection(),
|
||||
// ExpressionAttributeNames: expression.Names(),
|
||||
// ExpressionAttributeValues: expression.Values(),
|
||||
// TableName: aws.String("SomeTable"),
|
||||
// }
|
||||
func (e Expression) Values() map[string]*dynamodb.AttributeValue {
|
||||
return e.valuesMap
|
||||
}
|
||||
|
||||
// returnExpression returns *string corresponding to the type of Expression
|
||||
// string specified by the expressionType. If there is no corresponding
|
||||
// expression available in Expression, the method returns nil
|
||||
func (e Expression) returnExpression(expressionType expressionType) *string {
|
||||
if e.expressionMap == nil {
|
||||
return nil
|
||||
}
|
||||
return aws.String(e.expressionMap[expressionType])
|
||||
}
|
||||
|
||||
// exprNode are the generic nodes that represents both Operands and
|
||||
// Conditions. The purpose of exprNode is to be able to call an generic
|
||||
// recursive function on the top level exprNode to be able to determine a root
|
||||
// node in order to deduplicate name aliases.
|
||||
// fmtExpr is a string that has escaped characters to refer to
|
||||
// names/values/children which needs to be aliased at runtime in order to avoid
|
||||
// duplicate values. The rules are as follows:
|
||||
// $n: Indicates that an alias of a name needs to be inserted. The
|
||||
// corresponding name to be alias is in the []names slice.
|
||||
// $v: Indicates that an alias of a value needs to be inserted. The
|
||||
// corresponding value to be alias is in the []values slice.
|
||||
// $c: Indicates that the fmtExpr of a child exprNode needs to be inserted.
|
||||
// The corresponding child node is in the []children slice.
|
||||
type exprNode struct {
|
||||
names []string
|
||||
values []dynamodb.AttributeValue
|
||||
children []exprNode
|
||||
fmtExpr string
|
||||
}
|
||||
|
||||
// aliasList keeps track of all the names we need to alias in the nested
|
||||
// struct of conditions and operands. This allows each alias to be unique.
|
||||
// aliasList is passed in as a pointer when buildChildTrees is called in
|
||||
// order to deduplicate all names within the tree strcuture of the exprNodes.
|
||||
type aliasList struct {
|
||||
namesList []string
|
||||
valuesList []dynamodb.AttributeValue
|
||||
}
|
||||
|
||||
// buildExpressionString returns a string with aliasing for names/values
|
||||
// specified by aliasList. The string corresponds to the expression that the
|
||||
// exprNode tree represents.
|
||||
func (en exprNode) buildExpressionString(aliasList *aliasList) (string, error) {
|
||||
// Since each exprNode contains a slice of names, values, and children that
|
||||
// correspond to the escaped characters, we an index to traverse the slices
|
||||
index := struct {
|
||||
name, value, children int
|
||||
}{}
|
||||
|
||||
formattedExpression := en.fmtExpr
|
||||
|
||||
for i := 0; i < len(formattedExpression); {
|
||||
if formattedExpression[i] != '$' {
|
||||
i++
|
||||
continue
|
||||
}
|
||||
|
||||
if i == len(formattedExpression)-1 {
|
||||
return "", fmt.Errorf("buildexprNode error: invalid escape character")
|
||||
}
|
||||
|
||||
var alias string
|
||||
var err error
|
||||
// if an escaped character is found, substitute it with the proper alias
|
||||
// TODO consider AST instead of string in the future
|
||||
switch formattedExpression[i+1] {
|
||||
case 'n':
|
||||
alias, err = substitutePath(index.name, en, aliasList)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
index.name++
|
||||
|
||||
case 'v':
|
||||
alias, err = substituteValue(index.value, en, aliasList)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
index.value++
|
||||
|
||||
case 'c':
|
||||
alias, err = substituteChild(index.children, en, aliasList)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
index.children++
|
||||
|
||||
default:
|
||||
return "", fmt.Errorf("buildexprNode error: invalid escape rune %#v", formattedExpression[i+1])
|
||||
}
|
||||
formattedExpression = formattedExpression[:i] + alias + formattedExpression[i+2:]
|
||||
i += len(alias)
|
||||
}
|
||||
|
||||
return formattedExpression, nil
|
||||
}
|
||||
|
||||
// substitutePath substitutes the escaped character $n with the appropriate
|
||||
// alias.
|
||||
func substitutePath(index int, node exprNode, aliasList *aliasList) (string, error) {
|
||||
if index >= len(node.names) {
|
||||
return "", fmt.Errorf("substitutePath error: exprNode []names out of range")
|
||||
}
|
||||
str, err := aliasList.aliasPath(node.names[index])
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return str, nil
|
||||
}
|
||||
|
||||
// substituteValue substitutes the escaped character $v with the appropriate
|
||||
// alias.
|
||||
func substituteValue(index int, node exprNode, aliasList *aliasList) (string, error) {
|
||||
if index >= len(node.values) {
|
||||
return "", fmt.Errorf("substituteValue error: exprNode []values out of range")
|
||||
}
|
||||
str, err := aliasList.aliasValue(node.values[index])
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return str, nil
|
||||
}
|
||||
|
||||
// substituteChild substitutes the escaped character $c with the appropriate
|
||||
// alias.
|
||||
func substituteChild(index int, node exprNode, aliasList *aliasList) (string, error) {
|
||||
if index >= len(node.children) {
|
||||
return "", fmt.Errorf("substituteChild error: exprNode []children out of range")
|
||||
}
|
||||
return node.children[index].buildExpressionString(aliasList)
|
||||
}
|
||||
|
||||
// aliasValue returns the corresponding alias to the dav value argument. Since
|
||||
// values are not deduplicated as of now, all values are just appended to the
|
||||
// aliasList and given the index as the alias.
|
||||
func (al *aliasList) aliasValue(dav dynamodb.AttributeValue) (string, error) {
|
||||
al.valuesList = append(al.valuesList, dav)
|
||||
return fmt.Sprintf(":%d", len(al.valuesList)-1), nil
|
||||
}
|
||||
|
||||
// aliasPath returns the corresponding alias to the argument string. The
|
||||
// argument is checked against all existing aliasList names in order to avoid
|
||||
// duplicate strings getting two different aliases.
|
||||
func (al *aliasList) aliasPath(nm string) (string, error) {
|
||||
for ind, name := range al.namesList {
|
||||
if nm == name {
|
||||
return fmt.Sprintf("#%d", ind), nil
|
||||
}
|
||||
}
|
||||
al.namesList = append(al.namesList, nm)
|
||||
return fmt.Sprintf("#%d", len(al.namesList)-1), nil
|
||||
}
|
1082
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/expression_test.go
generated
vendored
Normal file
1082
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/expression_test.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
557
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/key_condition.go
generated
vendored
Normal file
557
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/key_condition.go
generated
vendored
Normal file
|
@ -0,0 +1,557 @@
|
|||
package expression
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// keyConditionMode specifies the types of the struct KeyConditionBuilder,
|
||||
// representing the different types of KeyConditions (i.e. And, Or, Between, ...)
|
||||
type keyConditionMode int
|
||||
|
||||
const (
|
||||
// unsetKeyCond catches errors for unset KeyConditionBuilder structs
|
||||
unsetKeyCond keyConditionMode = iota
|
||||
// equalKeyCond represents the Equals KeyCondition
|
||||
equalKeyCond
|
||||
// lessThanKeyCond represents the Less Than KeyCondition
|
||||
lessThanKeyCond
|
||||
// lessThanEqualKeyCond represents the Less Than Or Equal To KeyCondition
|
||||
lessThanEqualKeyCond
|
||||
// greaterThanKeyCond represents the Greater Than KeyCondition
|
||||
greaterThanKeyCond
|
||||
// greaterThanEqualKeyCond represents the Greater Than Or Equal To KeyCondition
|
||||
greaterThanEqualKeyCond
|
||||
// andKeyCond represents the Logical And KeyCondition
|
||||
andKeyCond
|
||||
// betweenKeyCond represents the Between KeyCondition
|
||||
betweenKeyCond
|
||||
// beginsWithKeyCond represents the Begins With KeyCondition
|
||||
beginsWithKeyCond
|
||||
)
|
||||
|
||||
// KeyConditionBuilder represents Key Condition Expressions in DynamoDB.
|
||||
// KeyConditionBuilders are the building blocks of Expressions.
|
||||
// More Information at: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.html#Query.KeyConditionExpressions
|
||||
type KeyConditionBuilder struct {
|
||||
operandList []OperandBuilder
|
||||
keyConditionList []KeyConditionBuilder
|
||||
mode keyConditionMode
|
||||
}
|
||||
|
||||
// KeyEqual returns a KeyConditionBuilder representing the equality clause
|
||||
// of the two argument OperandBuilders. The resulting KeyConditionBuilder can be
|
||||
// used as a part of other Key Condition Expressions or as an argument to the
|
||||
// WithKeyCondition() method for the Builder struct.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // keyCondition represents the equal clause of the key "foo" and the
|
||||
// // value 5
|
||||
// keyCondition := expression.KeyEqual(expression.Key("foo"), expression.Value(5))
|
||||
//
|
||||
// // Used in another Key Condition Expression
|
||||
// anotherKeyCondition := expression.Key("partitionKey").Equal(expression.Value("aValue")).And(keyCondition)
|
||||
// // Used to make an Builder
|
||||
// builder := expression.NewBuilder().WithKeyCondition(keyCondition)
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.KeyEqual(expression.Key("foo"), expression.Value(5))
|
||||
// // Let :five be an ExpressionAttributeValue representing the value 5
|
||||
// "foo = :five"
|
||||
func KeyEqual(keyBuilder KeyBuilder, valueBuilder ValueBuilder) KeyConditionBuilder {
|
||||
return KeyConditionBuilder{
|
||||
operandList: []OperandBuilder{keyBuilder, valueBuilder},
|
||||
mode: equalKeyCond,
|
||||
}
|
||||
}
|
||||
|
||||
// Equal returns a KeyConditionBuilder representing the equality clause of
|
||||
// the two argument OperandBuilders. The resulting KeyConditionBuilder can be
|
||||
// used as a part of other Key Condition Expressions or as an argument to the
|
||||
// WithKeyCondition() method for the Builder struct.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // keyCondition represents the equal clause of the key "foo" and the
|
||||
// // value 5
|
||||
// keyCondition := expression.Key("foo").Equal(expression.Value(5))
|
||||
//
|
||||
// // Used in another Key Condition Expression
|
||||
// anotherKeyCondition := expression.Key("partitionKey").Equal(expression.Value("aValue")).And(keyCondition)
|
||||
// // Used to make an Builder
|
||||
// builder := expression.NewBuilder().WithKeyCondition(keyCondition)
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.Key("foo").Equal(expression.Value(5))
|
||||
// // Let :five be an ExpressionAttributeValue representing the value 5
|
||||
// "foo = :five"
|
||||
func (kb KeyBuilder) Equal(valueBuilder ValueBuilder) KeyConditionBuilder {
|
||||
return KeyEqual(kb, valueBuilder)
|
||||
}
|
||||
|
||||
// KeyLessThan returns a KeyConditionBuilder representing the less than
|
||||
// clause of the two argument OperandBuilders. The resulting KeyConditionBuilder
|
||||
// can be used as a part of other Key Condition Expressions.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // keyCondition represents the less than clause of the key "foo" and the
|
||||
// // value 5
|
||||
// keyCondition := expression.KeyLessThan(expression.Key("foo"), expression.Value(5))
|
||||
//
|
||||
// // Used in another Key Condition Expression
|
||||
// anotherKeyCondition := expression.Key("partitionKey").Equal(expression.Value("aValue")).And(keyCondition)
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.KeyLessThan(expression.Key("foo"), expression.Value(5))
|
||||
// // Let :five be an ExpressionAttributeValue representing the value 5
|
||||
// "foo < :five"
|
||||
func KeyLessThan(keyBuilder KeyBuilder, valueBuilder ValueBuilder) KeyConditionBuilder {
|
||||
return KeyConditionBuilder{
|
||||
operandList: []OperandBuilder{keyBuilder, valueBuilder},
|
||||
mode: lessThanKeyCond,
|
||||
}
|
||||
}
|
||||
|
||||
// LessThan returns a KeyConditionBuilder representing the less than clause
|
||||
// of the two argument OperandBuilders. The resulting KeyConditionBuilder can be
|
||||
// used as a part of other Key Condition Expressions.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // keyCondition represents the less than clause of the key "foo" and the
|
||||
// // value 5
|
||||
// keyCondition := expression.Key("foo").LessThan(expression.Value(5))
|
||||
//
|
||||
// // Used in another Key Condition Expression
|
||||
// anotherKeyCondition := expression.Key("partitionKey").Equal(expression.Value("aValue")).And(keyCondition)
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.Key("foo").LessThan(expression.Value(5))
|
||||
// // Let :five be an ExpressionAttributeValue representing the value 5
|
||||
// "foo < :five"
|
||||
func (kb KeyBuilder) LessThan(valueBuilder ValueBuilder) KeyConditionBuilder {
|
||||
return KeyLessThan(kb, valueBuilder)
|
||||
}
|
||||
|
||||
// KeyLessThanEqual returns a KeyConditionBuilder representing the less than
|
||||
// equal to clause of the two argument OperandBuilders. The resulting
|
||||
// KeyConditionBuilder can be used as a part of other Key Condition Expressions.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // keyCondition represents the less than equal to clause of the key
|
||||
// // "foo" and the value 5
|
||||
// keyCondition := expression.KeyLessThanEqual(expression.Key("foo"), expression.Value(5))
|
||||
//
|
||||
// // Used in another Key Condition Expression
|
||||
// anotherKeyCondition := expression.Key("partitionKey").Equal(expression.Value("aValue")).And(keyCondition)
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.KeyLessThanEqual(expression.Key("foo"), expression.Value(5))
|
||||
// // Let :five be an ExpressionAttributeValue representing the value 5
|
||||
// "foo <= :five"
|
||||
func KeyLessThanEqual(keyBuilder KeyBuilder, valueBuilder ValueBuilder) KeyConditionBuilder {
|
||||
return KeyConditionBuilder{
|
||||
operandList: []OperandBuilder{keyBuilder, valueBuilder},
|
||||
mode: lessThanEqualKeyCond,
|
||||
}
|
||||
}
|
||||
|
||||
// LessThanEqual returns a KeyConditionBuilder representing the less than
|
||||
// equal to clause of the two argument OperandBuilders. The resulting
|
||||
// KeyConditionBuilder can be used as a part of other Key Condition Expressions.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // keyCondition represents the less than equal to clause of the key
|
||||
// // "foo" and the value 5
|
||||
// keyCondition := expression.Key("foo").LessThanEqual(expression.Value(5))
|
||||
//
|
||||
// // Used in another Key Condition Expression
|
||||
// anotherKeyCondition := expression.Key("partitionKey").Equal(expression.Value("aValue")).And(keyCondition)
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.Key("foo").LessThanEqual(expression.Value(5))
|
||||
// // Let :five be an ExpressionAttributeValue representing the value 5
|
||||
// "foo <= :five"
|
||||
func (kb KeyBuilder) LessThanEqual(valueBuilder ValueBuilder) KeyConditionBuilder {
|
||||
return KeyLessThanEqual(kb, valueBuilder)
|
||||
}
|
||||
|
||||
// KeyGreaterThan returns a KeyConditionBuilder representing the greater
|
||||
// than clause of the two argument OperandBuilders. The resulting
|
||||
// KeyConditionBuilder can be used as a part of other Key Condition Expressions.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // keyCondition represents the greater than clause of the key "foo" and
|
||||
// // the value 5
|
||||
// keyCondition := expression.KeyGreaterThan(expression.Key("foo"), expression.Value(5))
|
||||
//
|
||||
// // Used in another Key Condition Expression
|
||||
// anotherKeyCondition := expression.Key("partitionKey").Equal(expression.Value("aValue")).And(keyCondition)
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.KeyGreaterThan(expression.Key("foo"), expression.Value(5))
|
||||
// // Let :five be an ExpressionAttributeValue representing the value 5
|
||||
// "foo > :five"
|
||||
func KeyGreaterThan(keyBuilder KeyBuilder, valueBuilder ValueBuilder) KeyConditionBuilder {
|
||||
return KeyConditionBuilder{
|
||||
operandList: []OperandBuilder{keyBuilder, valueBuilder},
|
||||
mode: greaterThanKeyCond,
|
||||
}
|
||||
}
|
||||
|
||||
// GreaterThan returns a KeyConditionBuilder representing the greater than
|
||||
// clause of the two argument OperandBuilders. The resulting KeyConditionBuilder
|
||||
// can be used as a part of other Key Condition Expressions.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // key condition represents the greater than clause of the key "foo" and
|
||||
// // the value 5
|
||||
// keyCondition := expression.Key("foo").GreaterThan(expression.Value(5))
|
||||
//
|
||||
// // Used in another Key Condition Expression
|
||||
// anotherKeyCondition := expression.Key("partitionKey").Equal(expression.Value("aValue")).And(keyCondition)
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.Key("foo").GreaterThan(expression.Value(5))
|
||||
// // Let :five be an ExpressionAttributeValue representing the value 5
|
||||
// "foo > :five"
|
||||
func (kb KeyBuilder) GreaterThan(valueBuilder ValueBuilder) KeyConditionBuilder {
|
||||
return KeyGreaterThan(kb, valueBuilder)
|
||||
}
|
||||
|
||||
// KeyGreaterThanEqual returns a KeyConditionBuilder representing the
|
||||
// greater than equal to clause of the two argument OperandBuilders. The
|
||||
// resulting KeyConditionBuilder can be used as a part of other Key Condition
|
||||
// Expressions.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // keyCondition represents the greater than equal to clause of the key
|
||||
// // "foo" and the value 5
|
||||
// keyCondition := expression.KeyGreaterThanEqual(expression.Key("foo"), expression.Value(5))
|
||||
//
|
||||
// // Used in another Key Condition Expression
|
||||
// anotherKeyCondition := expression.Key("partitionKey").Equal(expression.Value("aValue")).And(keyCondition)
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.KeyGreaterThanEqual(expression.Key("foo"), expression.Value(5))
|
||||
// // Let :five be an ExpressionAttributeValue representing the value 5
|
||||
// "foo >= :five"
|
||||
func KeyGreaterThanEqual(keyBuilder KeyBuilder, valueBuilder ValueBuilder) KeyConditionBuilder {
|
||||
return KeyConditionBuilder{
|
||||
operandList: []OperandBuilder{keyBuilder, valueBuilder},
|
||||
mode: greaterThanEqualKeyCond,
|
||||
}
|
||||
}
|
||||
|
||||
// GreaterThanEqual returns a KeyConditionBuilder representing the greater
|
||||
// than equal to clause of the two argument OperandBuilders. The resulting
|
||||
// KeyConditionBuilder can be used as a part of other Key Condition Expressions.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // keyCondition represents the greater than equal to clause of the key
|
||||
// // "foo" and the value 5
|
||||
// keyCondition := expression.Key("foo").GreaterThanEqual(expression.Value(5))
|
||||
//
|
||||
// // Used in another Key Condition Expression
|
||||
// anotherKeyCondition := expression.Key("partitionKey").Equal(expression.Value("aValue")).And(keyCondition)
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.Key("foo").GreaterThanEqual(expression.Value(5))
|
||||
// // Let :five be an ExpressionAttributeValue representing the value 5
|
||||
// "foo >= :five"
|
||||
func (kb KeyBuilder) GreaterThanEqual(valueBuilder ValueBuilder) KeyConditionBuilder {
|
||||
return KeyGreaterThanEqual(kb, valueBuilder)
|
||||
}
|
||||
|
||||
// KeyAnd returns a KeyConditionBuilder representing the logical AND clause
|
||||
// of the two argument KeyConditionBuilders. The resulting KeyConditionBuilder
|
||||
// can be used as an argument to the WithKeyCondition() method for the Builder
|
||||
// struct.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // keyCondition represents the key condition where the partition key
|
||||
// // "TeamName" is equal to value "Wildcats" and sort key "Number" is equal
|
||||
// // to value 1
|
||||
// keyCondition := expression.KeyAnd(expression.Key("TeamName").Equal(expression.Value("Wildcats")), expression.Key("Number").Equal(expression.Value(1)))
|
||||
//
|
||||
// // Used to make an Builder
|
||||
// builder := expression.NewBuilder().WithKeyCondition(keyCondition)
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.KeyAnd(expression.Key("TeamName").Equal(expression.Value("Wildcats")), expression.Key("Number").Equal(expression.Value(1)))
|
||||
// // Let #NUMBER, :teamName, and :one be ExpressionAttributeName and
|
||||
// // ExpressionAttributeValues representing the item attribute "Number",
|
||||
// // the value "Wildcats", and the value 1
|
||||
// "(TeamName = :teamName) AND (#NUMBER = :one)"
|
||||
func KeyAnd(left, right KeyConditionBuilder) KeyConditionBuilder {
|
||||
if left.mode != equalKeyCond {
|
||||
return KeyConditionBuilder{
|
||||
mode: andKeyCond,
|
||||
}
|
||||
}
|
||||
if right.mode == andKeyCond {
|
||||
return KeyConditionBuilder{
|
||||
mode: andKeyCond,
|
||||
}
|
||||
}
|
||||
return KeyConditionBuilder{
|
||||
keyConditionList: []KeyConditionBuilder{left, right},
|
||||
mode: andKeyCond,
|
||||
}
|
||||
}
|
||||
|
||||
// And returns a KeyConditionBuilder representing the logical AND clause of
|
||||
// the two argument KeyConditionBuilders. The resulting KeyConditionBuilder can
|
||||
// be used as an argument to the WithKeyCondition() method for the Builder
|
||||
// struct.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // keyCondition represents the key condition where the partition key
|
||||
// // "TeamName" is equal to value "Wildcats" and sort key "Number" is equal
|
||||
// // to value 1
|
||||
// keyCondition := expression.Key("TeamName").Equal(expression.Value("Wildcats")).And(expression.Key("Number").Equal(expression.Value(1)))
|
||||
//
|
||||
// // Used to make an Builder
|
||||
// builder := expression.NewBuilder().WithKeyCondition(keyCondition)
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.Key("TeamName").Equal(expression.Value("Wildcats")).And(expression.Key("Number").Equal(expression.Value(1)))
|
||||
// // Let #NUMBER, :teamName, and :one be ExpressionAttributeName and
|
||||
// // ExpressionAttributeValues representing the item attribute "Number",
|
||||
// // the value "Wildcats", and the value 1
|
||||
// "(TeamName = :teamName) AND (#NUMBER = :one)"
|
||||
func (kcb KeyConditionBuilder) And(right KeyConditionBuilder) KeyConditionBuilder {
|
||||
return KeyAnd(kcb, right)
|
||||
}
|
||||
|
||||
// KeyBetween returns a KeyConditionBuilder representing the result of the
|
||||
// BETWEEN function in DynamoDB Key Condition Expressions. The resulting
|
||||
// KeyConditionBuilder can be used as a part of other Key Condition Expressions.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // keyCondition represents the boolean key condition of whether the value
|
||||
// // of the key "foo" is between values 5 and 10
|
||||
// keyCondition := expression.KeyBetween(expression.Key("foo"), expression.Value(5), expression.Value(10))
|
||||
//
|
||||
// // Used in another Key Condition Expression
|
||||
// anotherKeyCondition := expression.Key("partitionKey").Equal(expression.Value("aValue")).And(keyCondition)
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.KeyBetween(expression.Key("foo"), expression.Value(5), expression.Value(10))
|
||||
// // Let :five and :ten be ExpressionAttributeValues representing the
|
||||
// // values 5 and 10 respectively
|
||||
// "foo BETWEEN :five AND :ten"
|
||||
func KeyBetween(keyBuilder KeyBuilder, lower, upper ValueBuilder) KeyConditionBuilder {
|
||||
return KeyConditionBuilder{
|
||||
operandList: []OperandBuilder{keyBuilder, lower, upper},
|
||||
mode: betweenKeyCond,
|
||||
}
|
||||
}
|
||||
|
||||
// Between returns a KeyConditionBuilder representing the result of the
|
||||
// BETWEEN function in DynamoDB Key Condition Expressions. The resulting
|
||||
// KeyConditionBuilder can be used as a part of other Key Condition Expressions.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // keyCondition represents the boolean key condition of whether the value
|
||||
// // of the key "foo" is between values 5 and 10
|
||||
// keyCondition := expression.Key("foo").Between(expression.Value(5), expression.Value(10))
|
||||
//
|
||||
// // Used in another Key Condition Expression
|
||||
// anotherKeyCondition := expression.Key("partitionKey").Equal(expression.Value("aValue")).And(keyCondition)
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.Key("foo").Between(expression.Value(5), expression.Value(10))
|
||||
// // Let :five and :ten be ExpressionAttributeValues representing the
|
||||
// // values 5 and 10 respectively
|
||||
// "foo BETWEEN :five AND :ten"
|
||||
func (kb KeyBuilder) Between(lower, upper ValueBuilder) KeyConditionBuilder {
|
||||
return KeyBetween(kb, lower, upper)
|
||||
}
|
||||
|
||||
// KeyBeginsWith returns a KeyConditionBuilder representing the result of
|
||||
// the begins_with function in DynamoDB Key Condition Expressions. The resulting
|
||||
// KeyConditionBuilder can be used as a part of other Key Condition Expressions.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // keyCondition represents the boolean key condition of whether the value
|
||||
// // of the key "foo" is begins with the prefix "bar"
|
||||
// keyCondition := expression.KeyBeginsWith(expression.Key("foo"), "bar")
|
||||
//
|
||||
// // Used in another Key Condition Expression
|
||||
// anotherKeyCondition := expression.Key("partitionKey").Equal(expression.Value("aValue")).And(keyCondition)
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.KeyBeginsWith(expression.Key("foo"), "bar")
|
||||
// // Let :bar be an ExpressionAttributeValue representing the value "bar"
|
||||
// "begins_with(foo, :bar)"
|
||||
func KeyBeginsWith(keyBuilder KeyBuilder, prefix string) KeyConditionBuilder {
|
||||
valueBuilder := ValueBuilder{
|
||||
value: prefix,
|
||||
}
|
||||
return KeyConditionBuilder{
|
||||
operandList: []OperandBuilder{keyBuilder, valueBuilder},
|
||||
mode: beginsWithKeyCond,
|
||||
}
|
||||
}
|
||||
|
||||
// BeginsWith returns a KeyConditionBuilder representing the result of the
|
||||
// begins_with function in DynamoDB Key Condition Expressions. The resulting
|
||||
// KeyConditionBuilder can be used as a part of other Key Condition Expressions.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // keyCondition represents the boolean key condition of whether the value
|
||||
// // of the key "foo" is begins with the prefix "bar"
|
||||
// keyCondition := expression.Key("foo").BeginsWith("bar")
|
||||
//
|
||||
// // Used in another Key Condition Expression
|
||||
// anotherKeyCondition := expression.Key("partitionKey").Equal(expression.Value("aValue")).And(keyCondition)
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.Key("foo").BeginsWith("bar")
|
||||
// // Let :bar be an ExpressionAttributeValue representing the value "bar"
|
||||
// "begins_with(foo, :bar)"
|
||||
func (kb KeyBuilder) BeginsWith(prefix string) KeyConditionBuilder {
|
||||
return KeyBeginsWith(kb, prefix)
|
||||
}
|
||||
|
||||
// buildTree builds a tree structure of exprNodes based on the tree
|
||||
// structure of the input KeyConditionBuilder's child KeyConditions/Operands.
|
||||
// buildTree() satisfies the treeBuilder interface so KeyConditionBuilder can be
|
||||
// a part of Expression struct.
|
||||
func (kcb KeyConditionBuilder) buildTree() (exprNode, error) {
|
||||
childNodes, err := kcb.buildChildNodes()
|
||||
if err != nil {
|
||||
return exprNode{}, err
|
||||
}
|
||||
ret := exprNode{
|
||||
children: childNodes,
|
||||
}
|
||||
|
||||
switch kcb.mode {
|
||||
case equalKeyCond, lessThanKeyCond, lessThanEqualKeyCond, greaterThanKeyCond, greaterThanEqualKeyCond:
|
||||
return compareBuildKeyCondition(kcb.mode, ret)
|
||||
case andKeyCond:
|
||||
return andBuildKeyCondition(kcb, ret)
|
||||
case betweenKeyCond:
|
||||
return betweenBuildKeyCondition(ret)
|
||||
case beginsWithKeyCond:
|
||||
return beginsWithBuildKeyCondition(ret)
|
||||
case unsetKeyCond:
|
||||
return exprNode{}, newUnsetParameterError("buildTree", "KeyConditionBuilder")
|
||||
default:
|
||||
return exprNode{}, fmt.Errorf("buildKeyCondition error: unsupported mode: %v", kcb.mode)
|
||||
}
|
||||
}
|
||||
|
||||
// compareBuildKeyCondition is the function to make exprNodes from Compare
|
||||
// KeyConditionBuilders. compareBuildKeyCondition is only called by the
|
||||
// buildKeyCondition method. This function assumes that the argument
|
||||
// KeyConditionBuilder has the right format.
|
||||
func compareBuildKeyCondition(keyConditionMode keyConditionMode, node exprNode) (exprNode, error) {
|
||||
// Create a string with special characters that can be substituted later: $c
|
||||
switch keyConditionMode {
|
||||
case equalKeyCond:
|
||||
node.fmtExpr = "$c = $c"
|
||||
case lessThanKeyCond:
|
||||
node.fmtExpr = "$c < $c"
|
||||
case lessThanEqualKeyCond:
|
||||
node.fmtExpr = "$c <= $c"
|
||||
case greaterThanKeyCond:
|
||||
node.fmtExpr = "$c > $c"
|
||||
case greaterThanEqualKeyCond:
|
||||
node.fmtExpr = "$c >= $c"
|
||||
default:
|
||||
return exprNode{}, fmt.Errorf("build compare key condition error: unsupported mode: %v", keyConditionMode)
|
||||
}
|
||||
|
||||
return node, nil
|
||||
}
|
||||
|
||||
// andBuildKeyCondition is the function to make exprNodes from And
|
||||
// KeyConditionBuilders. andBuildKeyCondition is only called by the
|
||||
// buildKeyCondition method. This function assumes that the argument
|
||||
// KeyConditionBuilder has the right format.
|
||||
func andBuildKeyCondition(keyConditionBuilder KeyConditionBuilder, node exprNode) (exprNode, error) {
|
||||
if len(keyConditionBuilder.keyConditionList) == 0 && len(keyConditionBuilder.operandList) == 0 {
|
||||
return exprNode{}, newInvalidParameterError("andBuildKeyCondition", "KeyConditionBuilder")
|
||||
}
|
||||
// create a string with escaped characters to substitute them with proper
|
||||
// aliases during runtime
|
||||
node.fmtExpr = "($c) AND ($c)"
|
||||
|
||||
return node, nil
|
||||
}
|
||||
|
||||
// betweenBuildKeyCondition is the function to make exprNodes from Between
|
||||
// KeyConditionBuilders. betweenBuildKeyCondition is only called by the
|
||||
// buildKeyCondition method. This function assumes that the argument
|
||||
// KeyConditionBuilder has the right format.
|
||||
func betweenBuildKeyCondition(node exprNode) (exprNode, error) {
|
||||
// Create a string with special characters that can be substituted later: $c
|
||||
node.fmtExpr = "$c BETWEEN $c AND $c"
|
||||
|
||||
return node, nil
|
||||
}
|
||||
|
||||
// beginsWithBuildKeyCondition is the function to make exprNodes from
|
||||
// BeginsWith KeyConditionBuilders. beginsWithBuildKeyCondition is only
|
||||
// called by the buildKeyCondition method. This function assumes that the argument
|
||||
// KeyConditionBuilder has the right format.
|
||||
func beginsWithBuildKeyCondition(node exprNode) (exprNode, error) {
|
||||
// Create a string with special characters that can be substituted later: $c
|
||||
node.fmtExpr = "begins_with ($c, $c)"
|
||||
|
||||
return node, nil
|
||||
}
|
||||
|
||||
// buildChildNodes creates the list of the child exprNodes. This avoids
|
||||
// duplication of code amongst the various buildConditions.
|
||||
func (kcb KeyConditionBuilder) buildChildNodes() ([]exprNode, error) {
|
||||
childNodes := make([]exprNode, 0, len(kcb.keyConditionList)+len(kcb.operandList))
|
||||
for _, keyCondition := range kcb.keyConditionList {
|
||||
node, err := keyCondition.buildTree()
|
||||
if err != nil {
|
||||
return []exprNode{}, err
|
||||
}
|
||||
childNodes = append(childNodes, node)
|
||||
}
|
||||
for _, operand := range kcb.operandList {
|
||||
ope, err := operand.BuildOperand()
|
||||
if err != nil {
|
||||
return []exprNode{}, err
|
||||
}
|
||||
childNodes = append(childNodes, ope.exprNode)
|
||||
}
|
||||
|
||||
return childNodes, nil
|
||||
}
|
446
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/key_condition_test.go
generated
vendored
Normal file
446
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/key_condition_test.go
generated
vendored
Normal file
|
@ -0,0 +1,446 @@
|
|||
// +build go1.7
|
||||
|
||||
package expression
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/dynamodb"
|
||||
)
|
||||
|
||||
// keyCondErrorMode will help with error cases and checking error types
|
||||
type keyCondErrorMode string
|
||||
|
||||
const (
|
||||
noKeyConditionError keyCondErrorMode = ""
|
||||
// unsetKeyCondition error will occur when buildTree() is called on an empty
|
||||
// KeyConditionBuilder
|
||||
unsetKeyCondition = "unset parameter: KeyConditionBuilder"
|
||||
// invalidKeyConditionOperand error will occur when an invalid OperandBuilder is used as
|
||||
// an argument
|
||||
invalidKeyConditionOperand = "BuildOperand error"
|
||||
// invalidAndFormat error will occur when the first key condition is not an equal
|
||||
// clause or if the second key condition is an and condition.
|
||||
invalidAndFormat = "invalid parameter: KeyConditionBuilder"
|
||||
)
|
||||
|
||||
func TestKeyCompare(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
input KeyConditionBuilder
|
||||
expectedNode exprNode
|
||||
err keyCondErrorMode
|
||||
}{
|
||||
{
|
||||
name: "key equal",
|
||||
input: Key("foo").Equal(Value(5)),
|
||||
expectedNode: exprNode{
|
||||
children: []exprNode{
|
||||
{
|
||||
names: []string{"foo"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
{
|
||||
values: []dynamodb.AttributeValue{
|
||||
{
|
||||
N: aws.String("5"),
|
||||
},
|
||||
},
|
||||
fmtExpr: "$v",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c = $c",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "key less than",
|
||||
input: Key("foo").LessThan(Value(5)),
|
||||
expectedNode: exprNode{
|
||||
children: []exprNode{
|
||||
{
|
||||
names: []string{"foo"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
{
|
||||
values: []dynamodb.AttributeValue{
|
||||
{
|
||||
N: aws.String("5"),
|
||||
},
|
||||
},
|
||||
fmtExpr: "$v",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c < $c",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "key less than equal",
|
||||
input: Key("foo").LessThanEqual(Value(5)),
|
||||
expectedNode: exprNode{
|
||||
children: []exprNode{
|
||||
{
|
||||
names: []string{"foo"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
{
|
||||
values: []dynamodb.AttributeValue{
|
||||
{
|
||||
N: aws.String("5"),
|
||||
},
|
||||
},
|
||||
fmtExpr: "$v",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c <= $c",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "key greater than",
|
||||
input: Key("foo").GreaterThan(Value(5)),
|
||||
expectedNode: exprNode{
|
||||
children: []exprNode{
|
||||
{
|
||||
names: []string{"foo"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
{
|
||||
values: []dynamodb.AttributeValue{
|
||||
{
|
||||
N: aws.String("5"),
|
||||
},
|
||||
},
|
||||
fmtExpr: "$v",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c > $c",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "key greater than equal",
|
||||
input: Key("foo").GreaterThanEqual(Value(5)),
|
||||
expectedNode: exprNode{
|
||||
children: []exprNode{
|
||||
{
|
||||
names: []string{"foo"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
{
|
||||
values: []dynamodb.AttributeValue{
|
||||
{
|
||||
N: aws.String("5"),
|
||||
},
|
||||
},
|
||||
fmtExpr: "$v",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c >= $c",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "unset KeyConditionBuilder",
|
||||
input: KeyConditionBuilder{},
|
||||
err: unsetKeyCondition,
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
actual, err := c.input.buildTree()
|
||||
if c.err != noKeyConditionError {
|
||||
if err == nil {
|
||||
t.Errorf("expect error %q, got no error", c.err)
|
||||
} else {
|
||||
if e, a := string(c.err), err.Error(); !strings.Contains(a, e) {
|
||||
t.Errorf("expect %q error message to be in %q", e, a)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Errorf("expect no error, got unexpected Error %q", err)
|
||||
}
|
||||
|
||||
if e, a := c.expectedNode, actual; !reflect.DeepEqual(a, e) {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestKeyBetween(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
input KeyConditionBuilder
|
||||
expectedNode exprNode
|
||||
err keyCondErrorMode
|
||||
}{
|
||||
{
|
||||
name: "key between",
|
||||
input: Key("foo").Between(Value(5), Value(10)),
|
||||
expectedNode: exprNode{
|
||||
children: []exprNode{
|
||||
{
|
||||
names: []string{"foo"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
{
|
||||
values: []dynamodb.AttributeValue{
|
||||
{
|
||||
N: aws.String("5"),
|
||||
},
|
||||
},
|
||||
fmtExpr: "$v",
|
||||
},
|
||||
{
|
||||
values: []dynamodb.AttributeValue{
|
||||
{
|
||||
N: aws.String("10"),
|
||||
},
|
||||
},
|
||||
fmtExpr: "$v",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c BETWEEN $c AND $c",
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
actual, err := c.input.buildTree()
|
||||
if c.err != noKeyConditionError {
|
||||
if err == nil {
|
||||
t.Errorf("expect error %q, got no error", c.err)
|
||||
} else {
|
||||
if e, a := string(c.err), err.Error(); !strings.Contains(a, e) {
|
||||
t.Errorf("expect %q error message to be in %q", e, a)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Errorf("expect no error, got unexpected Error %q", err)
|
||||
}
|
||||
|
||||
if e, a := c.expectedNode, actual; !reflect.DeepEqual(a, e) {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestKeyBeginsWith(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
input KeyConditionBuilder
|
||||
expectedNode exprNode
|
||||
err keyCondErrorMode
|
||||
}{
|
||||
{
|
||||
name: "key begins with",
|
||||
input: Key("foo").BeginsWith("bar"),
|
||||
expectedNode: exprNode{
|
||||
children: []exprNode{
|
||||
{
|
||||
names: []string{"foo"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
{
|
||||
values: []dynamodb.AttributeValue{
|
||||
{
|
||||
S: aws.String("bar"),
|
||||
},
|
||||
},
|
||||
fmtExpr: "$v",
|
||||
},
|
||||
},
|
||||
fmtExpr: "begins_with ($c, $c)",
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
actual, err := c.input.buildTree()
|
||||
if c.err != noKeyConditionError {
|
||||
if err == nil {
|
||||
t.Errorf("expect error %q, got no error", c.err)
|
||||
} else {
|
||||
if e, a := string(c.err), err.Error(); !strings.Contains(a, e) {
|
||||
t.Errorf("expect %q error message to be in %q", e, a)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Errorf("expect no error, got unexpected Error %q", err)
|
||||
}
|
||||
|
||||
if e, a := c.expectedNode, actual; !reflect.DeepEqual(a, e) {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestKeyAnd(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
input KeyConditionBuilder
|
||||
expectedNode exprNode
|
||||
err keyCondErrorMode
|
||||
}{
|
||||
{
|
||||
name: "key and",
|
||||
input: Key("foo").Equal(Value(5)).And(Key("bar").BeginsWith("baz")),
|
||||
expectedNode: exprNode{
|
||||
children: []exprNode{
|
||||
{
|
||||
children: []exprNode{
|
||||
{
|
||||
names: []string{"foo"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
{
|
||||
values: []dynamodb.AttributeValue{
|
||||
{
|
||||
N: aws.String("5"),
|
||||
},
|
||||
},
|
||||
fmtExpr: "$v",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c = $c",
|
||||
},
|
||||
{
|
||||
children: []exprNode{
|
||||
{
|
||||
names: []string{"bar"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
{
|
||||
values: []dynamodb.AttributeValue{
|
||||
{
|
||||
S: aws.String("baz"),
|
||||
},
|
||||
},
|
||||
fmtExpr: "$v",
|
||||
},
|
||||
},
|
||||
fmtExpr: "begins_with ($c, $c)",
|
||||
},
|
||||
},
|
||||
fmtExpr: "($c) AND ($c)",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "first condition is not equal",
|
||||
input: Key("foo").LessThan(Value(5)).And(Key("bar").BeginsWith("baz")),
|
||||
err: invalidAndFormat,
|
||||
},
|
||||
{
|
||||
name: "second condition is and",
|
||||
input: Key("foo").Equal(Value(5)).And(Key("bar").Equal(Value(1)).And(Key("baz").BeginsWith("yar"))),
|
||||
err: invalidAndFormat,
|
||||
},
|
||||
{
|
||||
name: "operand error",
|
||||
input: Key("").Equal(Value("yikes")),
|
||||
err: invalidKeyConditionOperand,
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
actual, err := c.input.buildTree()
|
||||
if c.err != noKeyConditionError {
|
||||
if err == nil {
|
||||
t.Errorf("expect error %q, got no error", c.err)
|
||||
} else {
|
||||
if e, a := string(c.err), err.Error(); !strings.Contains(a, e) {
|
||||
t.Errorf("expect %q error message to be in %q", e, a)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Errorf("expect no error, got unexpected Error %q", err)
|
||||
}
|
||||
|
||||
if e, a := c.expectedNode, actual; !reflect.DeepEqual(a, e) {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestKeyConditionBuildChildNodes(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
input KeyConditionBuilder
|
||||
expected []exprNode
|
||||
err keyCondErrorMode
|
||||
}{
|
||||
{
|
||||
name: "build child nodes",
|
||||
input: Key("foo").Equal(Value("bar")).And(Key("baz").LessThan(Value(10))),
|
||||
expected: []exprNode{
|
||||
{
|
||||
children: []exprNode{
|
||||
{
|
||||
names: []string{"foo"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
{
|
||||
values: []dynamodb.AttributeValue{
|
||||
{
|
||||
S: aws.String("bar"),
|
||||
},
|
||||
},
|
||||
fmtExpr: "$v",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c = $c",
|
||||
},
|
||||
{
|
||||
children: []exprNode{
|
||||
{
|
||||
names: []string{"baz"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
{
|
||||
values: []dynamodb.AttributeValue{
|
||||
{
|
||||
N: aws.String("10"),
|
||||
},
|
||||
},
|
||||
fmtExpr: "$v",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c < $c",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
actual, err := c.input.buildChildNodes()
|
||||
if c.err != noKeyConditionError {
|
||||
if err == nil {
|
||||
t.Errorf("expect error %q, got no error", c.err)
|
||||
} else {
|
||||
if e, a := string(c.err), err.Error(); !strings.Contains(a, e) {
|
||||
t.Errorf("expect %q error message to be in %q", e, a)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Errorf("expect no error, got unexpected Error %q", err)
|
||||
}
|
||||
|
||||
if e, a := c.expected, actual; !reflect.DeepEqual(a, e) {
|
||||
t.Errorf("expect %#v, got %#v", e, a)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
620
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/operand.go
generated
vendored
Normal file
620
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/operand.go
generated
vendored
Normal file
|
@ -0,0 +1,620 @@
|
|||
package expression
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/aws/aws-sdk-go/service/dynamodb"
|
||||
"github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute"
|
||||
)
|
||||
|
||||
// ValueBuilder represents an item attribute value operand and implements the
|
||||
// OperandBuilder interface. Methods and functions in the package take
|
||||
// ValueBuilder as an argument and establishes relationships between operands.
|
||||
// ValueBuilder should only be initialized using the function Value().
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Create a ValueBuilder representing the string "aValue"
|
||||
// valueBuilder := expression.Value("aValue")
|
||||
type ValueBuilder struct {
|
||||
value interface{}
|
||||
}
|
||||
|
||||
// NameBuilder represents a name of a top level item attribute or a nested
|
||||
// attribute. Since NameBuilder represents a DynamoDB Operand, it implements the
|
||||
// OperandBuilder interface. Methods and functions in the package take
|
||||
// NameBuilder as an argument and establishes relationships between operands.
|
||||
// NameBuilder should only be initialized using the function Name().
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Create a NameBuilder representing the item attribute "aName"
|
||||
// nameBuilder := expression.Name("aName")
|
||||
type NameBuilder struct {
|
||||
name string
|
||||
}
|
||||
|
||||
// SizeBuilder represents the output of the function size ("someName"), which
|
||||
// evaluates to the size of the item attribute defined by "someName". Since
|
||||
// SizeBuilder represents an operand, SizeBuilder implements the OperandBuilder
|
||||
// interface. Methods and functions in the package take SizeBuilder as an
|
||||
// argument and establishes relationships between operands. SizeBuilder should
|
||||
// only be initialized using the function Size().
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Create a SizeBuilder representing the size of the item attribute
|
||||
// // "aName"
|
||||
// sizeBuilder := expression.Name("aName").Size()
|
||||
type SizeBuilder struct {
|
||||
nameBuilder NameBuilder
|
||||
}
|
||||
|
||||
// KeyBuilder represents either the partition key or the sort key, both of which
|
||||
// are top level attributes to some item in DynamoDB. Since KeyBuilder
|
||||
// represents an operand, KeyBuilder implements the OperandBuilder interface.
|
||||
// Methods and functions in the package take KeyBuilder as an argument and
|
||||
// establishes relationships between operands. However, KeyBuilder should only
|
||||
// be used to describe Key Condition Expressions. KeyBuilder should only be
|
||||
// initialized using the function Key().
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Create a KeyBuilder representing the item key "aKey"
|
||||
// keyBuilder := expression.Key("aKey")
|
||||
type KeyBuilder struct {
|
||||
key string
|
||||
}
|
||||
|
||||
// setValueMode specifies the type of SetValueBuilder. The default value is
|
||||
// unsetValue so that an UnsetParameterError when BuildOperand() is called on an
|
||||
// empty SetValueBuilder.
|
||||
type setValueMode int
|
||||
|
||||
const (
|
||||
unsetValue setValueMode = iota
|
||||
plusValueMode
|
||||
minusValueMode
|
||||
listAppendValueMode
|
||||
ifNotExistsValueMode
|
||||
)
|
||||
|
||||
// SetValueBuilder represents the outcome of operator functions supported by the
|
||||
// DynamoDB Set operation. The operator functions are the following:
|
||||
// Plus() // Represents the "+" operator
|
||||
// Minus() // Represents the "-" operator
|
||||
// ListAppend()
|
||||
// IfNotExists()
|
||||
// For documentation on the above functions,
|
||||
// see: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.SET
|
||||
// Since SetValueBuilder represents an operand, it implements the OperandBuilder
|
||||
// interface. SetValueBuilder structs are used as arguments to the Set()
|
||||
// function. SetValueBuilders should only initialize a SetValueBuilder using the
|
||||
// functions listed above.
|
||||
type SetValueBuilder struct {
|
||||
leftOperand OperandBuilder
|
||||
rightOperand OperandBuilder
|
||||
mode setValueMode
|
||||
}
|
||||
|
||||
// Operand represents an item attribute name or value in DynamoDB. The
|
||||
// relationship between Operands specified by various builders such as
|
||||
// ConditionBuilders and UpdateBuilders for example is processed internally to
|
||||
// write Condition Expressions and Update Expressions respectively.
|
||||
type Operand struct {
|
||||
exprNode exprNode
|
||||
}
|
||||
|
||||
// OperandBuilder represents the idea of Operand which are building blocks to
|
||||
// DynamoDB Expressions. Package methods and functions can establish
|
||||
// relationships between operands, representing DynamoDB Expressions. The method
|
||||
// BuildOperand() is called recursively when the Build() method on the type
|
||||
// Builder is called. BuildOperand() should never be called externally.
|
||||
// OperandBuilder and BuildOperand() are exported to allow package functions to
|
||||
// take an interface as an argument.
|
||||
type OperandBuilder interface {
|
||||
BuildOperand() (Operand, error)
|
||||
}
|
||||
|
||||
// Name creates a NameBuilder. The argument should represent the desired item
|
||||
// attribute. It is possible to reference nested item attributes by using
|
||||
// square brackets for lists and dots for maps. For documentation on specifying
|
||||
// item attributes,
|
||||
// see: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.Attributes.html
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Specify a top-level attribute
|
||||
// name := expression.Name("TopLevel")
|
||||
// // Specify a nested attribute
|
||||
// nested := expression.Name("Record[6].SongList")
|
||||
// // Use Name() to create a condition expression
|
||||
// condition := expression.Name("foo").Equal(expression.Name("bar"))
|
||||
func Name(name string) NameBuilder {
|
||||
return NameBuilder{
|
||||
name: name,
|
||||
}
|
||||
}
|
||||
|
||||
// Value creates a ValueBuilder. The argument should represent the desired item
|
||||
// attribute. The value is marshalled using the dynamodbattribute package by the
|
||||
// Build() method for type Builder.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Use Value() to create a condition expression
|
||||
// condition := expression.Name("foo").Equal(expression.Value(10))
|
||||
func Value(value interface{}) ValueBuilder {
|
||||
return ValueBuilder{
|
||||
value: value,
|
||||
}
|
||||
}
|
||||
|
||||
// Size creates a SizeBuilder representing the size of the item attribute
|
||||
// specified by the argument NameBuilder. Size() is only valid for certain types
|
||||
// of item attributes. For documentation,
|
||||
// see: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html
|
||||
// SizeBuilder is only a valid operand in Condition Expressions and Filter
|
||||
// Expressions.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Use Size() to create a condition expression
|
||||
// condition := expression.Name("foo").Size().Equal(expression.Value(10))
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.Name("aName").Size()
|
||||
// "size (aName)"
|
||||
func (nb NameBuilder) Size() SizeBuilder {
|
||||
return SizeBuilder{
|
||||
nameBuilder: nb,
|
||||
}
|
||||
}
|
||||
|
||||
// Size creates a SizeBuilder representing the size of the item attribute
|
||||
// specified by the argument NameBuilder. Size() is only valid for certain types
|
||||
// of item attributes. For documentation,
|
||||
// see: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html
|
||||
// SizeBuilder is only a valid operand in Condition Expressions and Filter
|
||||
// Expressions.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Use Size() to create a condition expression
|
||||
// condition := expression.Size(expression.Name("foo")).Equal(expression.Value(10))
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.Size(expression.Name("aName"))
|
||||
// "size (aName)"
|
||||
func Size(nameBuilder NameBuilder) SizeBuilder {
|
||||
return nameBuilder.Size()
|
||||
}
|
||||
|
||||
// Key creates a KeyBuilder. The argument should represent the desired partition
|
||||
// key or sort key value. KeyBuilders should only be used to specify
|
||||
// relationships for Key Condition Expressions. When referring to the partition
|
||||
// key or sort key in any other Expression, use Name().
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Use Key() to create a key condition expression
|
||||
// keyCondition := expression.Key("foo").Equal(expression.Value("bar"))
|
||||
func Key(key string) KeyBuilder {
|
||||
return KeyBuilder{
|
||||
key: key,
|
||||
}
|
||||
}
|
||||
|
||||
// Plus creates a SetValueBuilder to be used in as an argument to Set(). The
|
||||
// arguments can either be NameBuilders or ValueBuilders. Plus() only supports
|
||||
// DynamoDB Number types, so the ValueBuilder must be a Number and the
|
||||
// NameBuilder must specify an item attribute of type Number.
|
||||
// More information: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.SET.IncrementAndDecrement
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Use Plus() to set the value of the item attribute "someName" to 5 + 10
|
||||
// update, err := expression.Set(expression.Name("someName"), expression.Plus(expression.Value(5), expression.Value(10)))
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.Plus(expression.Value(5), expression.Value(10))
|
||||
// // let :five and :ten be ExpressionAttributeValues for the values 5 and
|
||||
// // 10 respectively.
|
||||
// ":five + :ten"
|
||||
func Plus(leftOperand, rightOperand OperandBuilder) SetValueBuilder {
|
||||
return SetValueBuilder{
|
||||
leftOperand: leftOperand,
|
||||
rightOperand: rightOperand,
|
||||
mode: plusValueMode,
|
||||
}
|
||||
}
|
||||
|
||||
// Plus creates a SetValueBuilder to be used in as an argument to Set(). The
|
||||
// arguments can either be NameBuilders or ValueBuilders. Plus() only supports
|
||||
// DynamoDB Number types, so the ValueBuilder must be a Number and the
|
||||
// NameBuilder must specify an item attribute of type Number.
|
||||
// More information: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.SET.IncrementAndDecrement
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Use Plus() to set the value of the item attribute "someName" to the
|
||||
// // numeric value of item attribute "aName" incremented by 10
|
||||
// update, err := expression.Set(expression.Name("someName"), expression.Name("aName").Plus(expression.Value(10)))
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.Name("aName").Plus(expression.Value(10))
|
||||
// // let :ten be ExpressionAttributeValues representing the value 10
|
||||
// "aName + :ten"
|
||||
func (nb NameBuilder) Plus(rightOperand OperandBuilder) SetValueBuilder {
|
||||
return Plus(nb, rightOperand)
|
||||
}
|
||||
|
||||
// Plus creates a SetValueBuilder to be used in as an argument to Set(). The
|
||||
// arguments can either be NameBuilders or ValueBuilders. Plus() only supports
|
||||
// DynamoDB Number types, so the ValueBuilder must be a Number and the
|
||||
// NameBuilder must specify an item attribute of type Number.
|
||||
// More information: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.SET.IncrementAndDecrement
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Use Plus() to set the value of the item attribute "someName" to 5 + 10
|
||||
// update, err := expression.Set(expression.Name("someName"), expression.Value(5).Plus(expression.Value(10)))
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.Value(5).Plus(expression.Value(10))
|
||||
// // let :five and :ten be ExpressionAttributeValues representing the value
|
||||
// // 5 and 10 respectively
|
||||
// ":five + :ten"
|
||||
func (vb ValueBuilder) Plus(rightOperand OperandBuilder) SetValueBuilder {
|
||||
return Plus(vb, rightOperand)
|
||||
}
|
||||
|
||||
// Minus creates a SetValueBuilder to be used in as an argument to Set(). The
|
||||
// arguments can either be NameBuilders or ValueBuilders. Minus() only supports
|
||||
// DynamoDB Number types, so the ValueBuilder must be a Number and the
|
||||
// NameBuilder must specify an item attribute of type Number.
|
||||
// More information: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.SET.IncrementAndDecrement
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Use Minus() to set the value of item attribute "someName" to 5 - 10
|
||||
// update, err := expression.Set(expression.Name("someName"), expression.Minus(expression.Value(5), expression.Value(10)))
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.Minus(expression.Value(5), expression.Value(10))
|
||||
// // let :five and :ten be ExpressionAttributeValues for the values 5 and
|
||||
// // 10 respectively.
|
||||
// ":five - :ten"
|
||||
func Minus(leftOperand, rightOperand OperandBuilder) SetValueBuilder {
|
||||
return SetValueBuilder{
|
||||
leftOperand: leftOperand,
|
||||
rightOperand: rightOperand,
|
||||
mode: minusValueMode,
|
||||
}
|
||||
}
|
||||
|
||||
// Minus creates a SetValueBuilder to be used in as an argument to Set(). The
|
||||
// arguments can either be NameBuilders or ValueBuilders. Minus() only supports
|
||||
// DynamoDB Number types, so the ValueBuilder must be a Number and the
|
||||
// NameBuilder must specify an item attribute of type Number.
|
||||
// More information: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.SET.IncrementAndDecrement
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Use Minus() to set the value of item attribute "someName" to the
|
||||
// // numeric value of "aName" decremented by 10
|
||||
// update, err := expression.Set(expression.Name("someName"), expression.Name("aName").Minus(expression.Value(10)))
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.Name("aName").Minus(expression.Value(10)))
|
||||
// // let :ten be ExpressionAttributeValues represent the value 10
|
||||
// "aName - :ten"
|
||||
func (nb NameBuilder) Minus(rightOperand OperandBuilder) SetValueBuilder {
|
||||
return Minus(nb, rightOperand)
|
||||
}
|
||||
|
||||
// Minus creates a SetValueBuilder to be used in as an argument to Set(). The
|
||||
// arguments can either be NameBuilders or ValueBuilders. Minus() only supports
|
||||
// DynamoDB Number types, so the ValueBuilder must be a Number and the
|
||||
// NameBuilder must specify an item attribute of type Number.
|
||||
// More information: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.SET.IncrementAndDecrement
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Use Minus() to set the value of item attribute "someName" to 5 - 10
|
||||
// update, err := expression.Set(expression.Name("someName"), expression.Value(5).Minus(expression.Value(10)))
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.Value(5).Minus(expression.Value(10))
|
||||
// // let :five and :ten be ExpressionAttributeValues for the values 5 and
|
||||
// // 10 respectively.
|
||||
// ":five - :ten"
|
||||
func (vb ValueBuilder) Minus(rightOperand OperandBuilder) SetValueBuilder {
|
||||
return Minus(vb, rightOperand)
|
||||
}
|
||||
|
||||
// ListAppend creates a SetValueBuilder to be used in as an argument to Set().
|
||||
// The arguments can either be NameBuilders or ValueBuilders. ListAppend() only
|
||||
// supports DynamoDB List types, so the ValueBuilder must be a List and the
|
||||
// NameBuilder must specify an item attribute of type List.
|
||||
// More information: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.SET.UpdatingListElements
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Use ListAppend() to set item attribute "someName" to the item
|
||||
// // attribute "nameOfList" with "some" and "list" appended to it
|
||||
// update, err := expression.Set(expression.Name("someName"), expression.ListAppend(expression.Name("nameOfList"), expression.Value([]string{"some", "list"})))
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.ListAppend(expression.Name("nameOfList"), expression.Value([]string{"some", "list"})
|
||||
// // let :list be a ExpressionAttributeValue representing the list
|
||||
// // containing "some" and "list".
|
||||
// "list_append (nameOfList, :list)"
|
||||
func ListAppend(leftOperand, rightOperand OperandBuilder) SetValueBuilder {
|
||||
return SetValueBuilder{
|
||||
leftOperand: leftOperand,
|
||||
rightOperand: rightOperand,
|
||||
mode: listAppendValueMode,
|
||||
}
|
||||
}
|
||||
|
||||
// ListAppend creates a SetValueBuilder to be used in as an argument to Set().
|
||||
// The arguments can either be NameBuilders or ValueBuilders. ListAppend() only
|
||||
// supports DynamoDB List types, so the ValueBuilder must be a List and the
|
||||
// NameBuilder must specify an item attribute of type List.
|
||||
// More information: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.SET.UpdatingListElements
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Use ListAppend() to set item attribute "someName" to the item
|
||||
// // attribute "nameOfList" with "some" and "list" appended to it
|
||||
// update, err := expression.Set(expression.Name("someName"), expression.Name("nameOfList").ListAppend(expression.Value([]string{"some", "list"})))
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.Name("nameOfList").ListAppend(expression.Value([]string{"some", "list"})
|
||||
// // let :list be a ExpressionAttributeValue representing the list
|
||||
// // containing "some" and "list".
|
||||
// "list_append (nameOfList, :list)"
|
||||
func (nb NameBuilder) ListAppend(rightOperand OperandBuilder) SetValueBuilder {
|
||||
return ListAppend(nb, rightOperand)
|
||||
}
|
||||
|
||||
// ListAppend creates a SetValueBuilder to be used in as an argument to Set().
|
||||
// The arguments can either be NameBuilders or ValueBuilders. ListAppend() only
|
||||
// supports DynamoDB List types, so the ValueBuilder must be a List and the
|
||||
// NameBuilder must specify an item attribute of type List.
|
||||
// More information: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.SET.UpdatingListElements
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Use ListAppend() to set item attribute "someName" to a string list
|
||||
// // equal to {"a", "list", "some", "list"}
|
||||
// update, err := expression.Set(expression.Name("someName"), expression.Value([]string{"a", "list"}).ListAppend(expression.Value([]string{"some", "list"})))
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.Name([]string{"a", "list"}).ListAppend(expression.Value([]string{"some", "list"})
|
||||
// // let :list1 and :list2 be a ExpressionAttributeValue representing the
|
||||
// // list {"a", "list"} and {"some", "list"} respectively
|
||||
// "list_append (:list1, :list2)"
|
||||
func (vb ValueBuilder) ListAppend(rightOperand OperandBuilder) SetValueBuilder {
|
||||
return ListAppend(vb, rightOperand)
|
||||
}
|
||||
|
||||
// IfNotExists creates a SetValueBuilder to be used in as an argument to Set().
|
||||
// The first argument must be a NameBuilder representing the name where the new
|
||||
// item attribute is created. The second argument can either be a NameBuilder or
|
||||
// a ValueBuilder. In the case that it is a NameBuilder, the value of the item
|
||||
// attribute at the name specified becomes the value of the new item attribute.
|
||||
// More information: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.SET.PreventingAttributeOverwrites
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Use IfNotExists() to set item attribute "someName" to value 5 if
|
||||
// // "someName" does not exist yet. (Prevents overwrite)
|
||||
// update, err := expression.Set(expression.Name("someName"), expression.IfNotExists(expression.Name("someName"), expression.Value(5)))
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.IfNotExists(expression.Name("someName"), expression.Value(5))
|
||||
// // let :five be a ExpressionAttributeValue representing the value 5
|
||||
// "if_not_exists (someName, :five)"
|
||||
func IfNotExists(name NameBuilder, setValue OperandBuilder) SetValueBuilder {
|
||||
return SetValueBuilder{
|
||||
leftOperand: name,
|
||||
rightOperand: setValue,
|
||||
mode: ifNotExistsValueMode,
|
||||
}
|
||||
}
|
||||
|
||||
// IfNotExists creates a SetValueBuilder to be used in as an argument to Set().
|
||||
// The first argument must be a NameBuilder representing the name where the new
|
||||
// item attribute is created. The second argument can either be a NameBuilder or
|
||||
// a ValueBuilder. In the case that it is a NameBuilder, the value of the item
|
||||
// attribute at the name specified becomes the value of the new item attribute.
|
||||
// More information: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.SET.PreventingAttributeOverwrites
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Use IfNotExists() to set item attribute "someName" to value 5 if
|
||||
// // "someName" does not exist yet. (Prevents overwrite)
|
||||
// update, err := expression.Set(expression.Name("someName"), expression.Name("someName").IfNotExists(expression.Value(5)))
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.Name("someName").IfNotExists(expression.Value(5))
|
||||
// // let :five be a ExpressionAttributeValue representing the value 5
|
||||
// "if_not_exists (someName, :five)"
|
||||
func (nb NameBuilder) IfNotExists(rightOperand OperandBuilder) SetValueBuilder {
|
||||
return IfNotExists(nb, rightOperand)
|
||||
}
|
||||
|
||||
// BuildOperand creates an Operand struct which are building blocks to DynamoDB
|
||||
// Expressions. Package methods and functions can establish relationships
|
||||
// between operands, representing DynamoDB Expressions. The method
|
||||
// BuildOperand() is called recursively when the Build() method on the type
|
||||
// Builder is called. BuildOperand() should never be called externally.
|
||||
// BuildOperand() aliases all strings to avoid stepping over DynamoDB's reserved
|
||||
// words.
|
||||
// More information on reserved words at http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html
|
||||
func (nb NameBuilder) BuildOperand() (Operand, error) {
|
||||
if nb.name == "" {
|
||||
return Operand{}, newUnsetParameterError("BuildOperand", "NameBuilder")
|
||||
}
|
||||
|
||||
node := exprNode{
|
||||
names: []string{},
|
||||
}
|
||||
|
||||
nameSplit := strings.Split(nb.name, ".")
|
||||
fmtNames := make([]string, 0, len(nameSplit))
|
||||
|
||||
for _, word := range nameSplit {
|
||||
var substr string
|
||||
if word == "" {
|
||||
return Operand{}, newInvalidParameterError("BuildOperand", "NameBuilder")
|
||||
}
|
||||
|
||||
if word[len(word)-1] == ']' {
|
||||
for j, char := range word {
|
||||
if char == '[' {
|
||||
substr = word[j:]
|
||||
word = word[:j]
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if word == "" {
|
||||
return Operand{}, newInvalidParameterError("BuildOperand", "NameBuilder")
|
||||
}
|
||||
|
||||
// Create a string with special characters that can be substituted later: $p
|
||||
node.names = append(node.names, word)
|
||||
fmtNames = append(fmtNames, "$n"+substr)
|
||||
}
|
||||
node.fmtExpr = strings.Join(fmtNames, ".")
|
||||
return Operand{
|
||||
exprNode: node,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// BuildOperand creates an Operand struct which are building blocks to DynamoDB
|
||||
// Expressions. Package methods and functions can establish relationships
|
||||
// between operands, representing DynamoDB Expressions. The method
|
||||
// BuildOperand() is called recursively when the Build() method on the type
|
||||
// Builder is called. BuildOperand() should never be called externally.
|
||||
// BuildOperand() aliases all strings to avoid stepping over DynamoDB's reserved
|
||||
// words.
|
||||
// More information on reserved words at http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html
|
||||
func (vb ValueBuilder) BuildOperand() (Operand, error) {
|
||||
expr, err := dynamodbattribute.Marshal(vb.value)
|
||||
if err != nil {
|
||||
return Operand{}, newInvalidParameterError("BuildOperand", "ValueBuilder")
|
||||
}
|
||||
|
||||
// Create a string with special characters that can be substituted later: $v
|
||||
operand := Operand{
|
||||
exprNode: exprNode{
|
||||
values: []dynamodb.AttributeValue{*expr},
|
||||
fmtExpr: "$v",
|
||||
},
|
||||
}
|
||||
return operand, nil
|
||||
}
|
||||
|
||||
// BuildOperand creates an Operand struct which are building blocks to DynamoDB
|
||||
// Expressions. Package methods and functions can establish relationships
|
||||
// between operands, representing DynamoDB Expressions. The method
|
||||
// BuildOperand() is called recursively when the Build() method on the type
|
||||
// Builder is called. BuildOperand() should never be called externally.
|
||||
// BuildOperand() aliases all strings to avoid stepping over DynamoDB's reserved
|
||||
// words.
|
||||
// More information on reserved words at http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html
|
||||
func (sb SizeBuilder) BuildOperand() (Operand, error) {
|
||||
operand, err := sb.nameBuilder.BuildOperand()
|
||||
operand.exprNode.fmtExpr = "size (" + operand.exprNode.fmtExpr + ")"
|
||||
|
||||
return operand, err
|
||||
}
|
||||
|
||||
// BuildOperand creates an Operand struct which are building blocks to DynamoDB
|
||||
// Expressions. Package methods and functions can establish relationships
|
||||
// between operands, representing DynamoDB Expressions. The method
|
||||
// BuildOperand() is called recursively when the Build() method on the type
|
||||
// Builder is called. BuildOperand() should never be called externally.
|
||||
// BuildOperand() aliases all strings to avoid stepping over DynamoDB's reserved
|
||||
// words.
|
||||
// More information on reserved words at http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html
|
||||
func (kb KeyBuilder) BuildOperand() (Operand, error) {
|
||||
if kb.key == "" {
|
||||
return Operand{}, newUnsetParameterError("BuildOperand", "KeyBuilder")
|
||||
}
|
||||
|
||||
ret := Operand{
|
||||
exprNode: exprNode{
|
||||
names: []string{kb.key},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// BuildOperand creates an Operand struct which are building blocks to DynamoDB
|
||||
// Expressions. Package methods and functions can establish relationships
|
||||
// between operands, representing DynamoDB Expressions. The method
|
||||
// BuildOperand() is called recursively when the Build() method on the type
|
||||
// Builder is called. BuildOperand() should never be called externally.
|
||||
// BuildOperand() aliases all strings to avoid stepping over DynamoDB's reserved
|
||||
// words.
|
||||
// More information on reserved words at http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html
|
||||
func (svb SetValueBuilder) BuildOperand() (Operand, error) {
|
||||
if svb.mode == unsetValue {
|
||||
return Operand{}, newUnsetParameterError("BuildOperand", "SetValueBuilder")
|
||||
}
|
||||
|
||||
left, err := svb.leftOperand.BuildOperand()
|
||||
if err != nil {
|
||||
return Operand{}, err
|
||||
}
|
||||
leftNode := left.exprNode
|
||||
|
||||
right, err := svb.rightOperand.BuildOperand()
|
||||
if err != nil {
|
||||
return Operand{}, err
|
||||
}
|
||||
rightNode := right.exprNode
|
||||
|
||||
node := exprNode{
|
||||
children: []exprNode{leftNode, rightNode},
|
||||
}
|
||||
|
||||
switch svb.mode {
|
||||
case plusValueMode:
|
||||
node.fmtExpr = "$c + $c"
|
||||
case minusValueMode:
|
||||
node.fmtExpr = "$c - $c"
|
||||
case listAppendValueMode:
|
||||
node.fmtExpr = "list_append($c, $c)"
|
||||
case ifNotExistsValueMode:
|
||||
node.fmtExpr = "if_not_exists($c, $c)"
|
||||
default:
|
||||
return Operand{}, fmt.Errorf("build operand error: unsupported mode: %v", svb.mode)
|
||||
}
|
||||
|
||||
return Operand{
|
||||
exprNode: node,
|
||||
}, nil
|
||||
}
|
144
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/operand_test.go
generated
vendored
Normal file
144
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/operand_test.go
generated
vendored
Normal file
|
@ -0,0 +1,144 @@
|
|||
// +build go1.7
|
||||
|
||||
package expression
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/dynamodb"
|
||||
)
|
||||
|
||||
// opeErrorMode will help with error cases and checking error types
|
||||
type opeErrorMode string
|
||||
|
||||
const (
|
||||
noOperandError opeErrorMode = ""
|
||||
// unsetName error will occur if an empty string is passed into NameBuilder
|
||||
unsetName = "unset parameter: NameBuilder"
|
||||
// invalidName error will occur if a nested name has an empty intermediary
|
||||
// attribute name (i.e. foo.bar..baz)
|
||||
invalidName = "invalid parameter: NameBuilder"
|
||||
// unsetKey error will occur if an empty string is passed into KeyBuilder
|
||||
unsetKey = "unset parameter: KeyBuilder"
|
||||
)
|
||||
|
||||
func TestBuildOperand(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
input OperandBuilder
|
||||
expected exprNode
|
||||
err opeErrorMode
|
||||
}{
|
||||
{
|
||||
name: "basic name",
|
||||
input: Name("foo"),
|
||||
expected: exprNode{
|
||||
names: []string{"foo"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "duplicate name name",
|
||||
input: Name("foo.foo"),
|
||||
expected: exprNode{
|
||||
names: []string{"foo", "foo"},
|
||||
fmtExpr: "$n.$n",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "basic value",
|
||||
input: Value(5),
|
||||
expected: exprNode{
|
||||
values: []dynamodb.AttributeValue{
|
||||
{
|
||||
N: aws.String("5"),
|
||||
},
|
||||
},
|
||||
fmtExpr: "$v",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "nested name",
|
||||
input: Name("foo.bar"),
|
||||
expected: exprNode{
|
||||
names: []string{"foo", "bar"},
|
||||
fmtExpr: "$n.$n",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "nested name with index",
|
||||
input: Name("foo.bar[0].baz"),
|
||||
expected: exprNode{
|
||||
names: []string{"foo", "bar", "baz"},
|
||||
fmtExpr: "$n.$n[0].$n",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "basic size",
|
||||
input: Name("foo").Size(),
|
||||
expected: exprNode{
|
||||
names: []string{"foo"},
|
||||
fmtExpr: "size ($n)",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "key",
|
||||
input: Key("foo"),
|
||||
expected: exprNode{
|
||||
names: []string{"foo"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "unset key error",
|
||||
input: Key(""),
|
||||
expected: exprNode{},
|
||||
err: unsetKey,
|
||||
},
|
||||
{
|
||||
name: "empty name error",
|
||||
input: Name(""),
|
||||
expected: exprNode{},
|
||||
err: unsetName,
|
||||
},
|
||||
{
|
||||
name: "invalid name",
|
||||
input: Name("foo..bar"),
|
||||
expected: exprNode{},
|
||||
err: invalidName,
|
||||
},
|
||||
{
|
||||
name: "invalid index",
|
||||
input: Name("[foo]"),
|
||||
expected: exprNode{},
|
||||
err: invalidName,
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
operand, err := c.input.BuildOperand()
|
||||
|
||||
if c.err != noOperandError {
|
||||
if err == nil {
|
||||
t.Errorf("expect error %q, got no error", c.err)
|
||||
} else {
|
||||
if e, a := string(c.err), err.Error(); !strings.Contains(a, e) {
|
||||
t.Errorf("expect %q error message to be in %q", e, a)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Errorf("expect no error, got unexpected Error %q", err)
|
||||
}
|
||||
|
||||
if e, a := c.expected, operand.exprNode; !reflect.DeepEqual(a, e) {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
148
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/projection.go
generated
vendored
Normal file
148
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/projection.go
generated
vendored
Normal file
|
@ -0,0 +1,148 @@
|
|||
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(newProjection)
|
||||
//
|
||||
// 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
|
||||
}
|
215
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/projection_test.go
generated
vendored
Normal file
215
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/projection_test.go
generated
vendored
Normal file
|
@ -0,0 +1,215 @@
|
|||
// +build go1.7
|
||||
|
||||
package expression
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// projErrorMode will help with error cases and checking error types
|
||||
type projErrorMode string
|
||||
|
||||
const (
|
||||
noProjError projErrorMode = ""
|
||||
// invalidProjectionOperand error will occur when an invalid OperandBuilder is
|
||||
// used as an argument
|
||||
invalidProjectionOperand = "BuildOperand error"
|
||||
// unsetProjection error will occur if the argument ProjectionBuilder is unset
|
||||
unsetProjection = "unset parameter: ProjectionBuilder"
|
||||
)
|
||||
|
||||
func TestProjectionBuilder(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
input ProjectionBuilder
|
||||
expectedNode exprNode
|
||||
err projErrorMode
|
||||
}{
|
||||
{
|
||||
name: "names list function call",
|
||||
input: NamesList(Name("foo"), Name("bar")),
|
||||
expectedNode: exprNode{
|
||||
children: []exprNode{
|
||||
{
|
||||
names: []string{"foo"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
{
|
||||
names: []string{"bar"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c, $c",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "names list method call",
|
||||
input: Name("foo").NamesList(Name("bar")),
|
||||
expectedNode: exprNode{
|
||||
children: []exprNode{
|
||||
{
|
||||
names: []string{"foo"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
{
|
||||
names: []string{"bar"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c, $c",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "add name",
|
||||
input: Name("foo").NamesList(Name("bar")).AddNames(Name("baz"), Name("qux")),
|
||||
expectedNode: exprNode{
|
||||
children: []exprNode{
|
||||
{
|
||||
names: []string{"foo"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
{
|
||||
names: []string{"bar"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
{
|
||||
names: []string{"baz"},
|
||||
fmtExpr: "$n",
|
||||
}, {
|
||||
names: []string{"qux"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c, $c, $c, $c",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid operand",
|
||||
input: NamesList(Name("")),
|
||||
err: invalidProjectionOperand,
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
actual, err := c.input.buildTree()
|
||||
if c.err != noProjError {
|
||||
if err == nil {
|
||||
t.Errorf("expect error %q, got no error", c.err)
|
||||
} else {
|
||||
if e, a := string(c.err), err.Error(); !strings.Contains(a, e) {
|
||||
t.Errorf("expect %q error message to be in %q", e, a)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Errorf("expect no error, got unexpected Error %q", err)
|
||||
}
|
||||
if e, a := c.expectedNode, actual; !reflect.DeepEqual(a, e) {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildProjection(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
input ProjectionBuilder
|
||||
expected string
|
||||
err projErrorMode
|
||||
}{
|
||||
{
|
||||
name: "build projection 3",
|
||||
input: NamesList(Name("foo"), Name("bar"), Name("baz")),
|
||||
expected: "$c, $c, $c",
|
||||
},
|
||||
{
|
||||
name: "build projection 5",
|
||||
input: NamesList(Name("foo"), Name("bar"), Name("baz")).AddNames(Name("qux"), Name("quux")),
|
||||
expected: "$c, $c, $c, $c, $c",
|
||||
},
|
||||
{
|
||||
name: "empty ProjectionBuilder",
|
||||
input: ProjectionBuilder{},
|
||||
err: unsetProjection,
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
actual, err := c.input.buildTree()
|
||||
if c.err != noProjError {
|
||||
if err == nil {
|
||||
t.Errorf("expect error %q, got no error", c.err)
|
||||
} else {
|
||||
if e, a := string(c.err), err.Error(); !strings.Contains(a, e) {
|
||||
t.Errorf("expect %q error message to be in %q", e, a)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Errorf("expect no error, got unexpected Error %q", err)
|
||||
}
|
||||
if e, a := c.expected, actual.fmtExpr; !reflect.DeepEqual(a, e) {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildProjectionChildNodes(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
input ProjectionBuilder
|
||||
expected []exprNode
|
||||
err projErrorMode
|
||||
}{
|
||||
{
|
||||
name: "build child nodes",
|
||||
input: NamesList(Name("foo"), Name("bar"), Name("baz")),
|
||||
expected: []exprNode{
|
||||
{
|
||||
names: []string{"foo"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
{
|
||||
names: []string{"bar"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
{
|
||||
names: []string{"baz"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "operand error",
|
||||
input: NamesList(Name("")),
|
||||
err: invalidProjectionOperand,
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
actual, err := c.input.buildTree()
|
||||
if c.err != noProjError {
|
||||
if err == nil {
|
||||
t.Errorf("expect error %q, got no error", c.err)
|
||||
} else {
|
||||
if e, a := string(c.err), err.Error(); !strings.Contains(a, e) {
|
||||
t.Errorf("expect %q error message to be in %q", e, a)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Errorf("expect no error, got unexpected Error %q", err)
|
||||
}
|
||||
if e, a := c.expected, actual.children; !reflect.DeepEqual(a, e) {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
391
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/update.go
generated
vendored
Normal file
391
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/update.go
generated
vendored
Normal file
|
@ -0,0 +1,391 @@
|
|||
package expression
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// operationMode specifies the types of update operations that the
|
||||
// updateBuilder is going to represent. The const is in a string to use the
|
||||
// const value as a map key and as a string when creating the formatted
|
||||
// expression for the exprNodes.
|
||||
type operationMode string
|
||||
|
||||
const (
|
||||
setOperation operationMode = "SET"
|
||||
removeOperation = "REMOVE"
|
||||
addOperation = "ADD"
|
||||
deleteOperation = "DELETE"
|
||||
)
|
||||
|
||||
// Implementing the Sort interface
|
||||
type modeList []operationMode
|
||||
|
||||
func (ml modeList) Len() int {
|
||||
return len(ml)
|
||||
}
|
||||
|
||||
func (ml modeList) Less(i, j int) bool {
|
||||
return string(ml[i]) < string(ml[j])
|
||||
}
|
||||
|
||||
func (ml modeList) Swap(i, j int) {
|
||||
ml[i], ml[j] = ml[j], ml[i]
|
||||
}
|
||||
|
||||
// UpdateBuilder represents Update Expressions in DynamoDB. UpdateBuilders
|
||||
// are the building blocks of the Builder struct. Note that there are different
|
||||
// update operations in DynamoDB and an UpdateBuilder can represent multiple
|
||||
// update operations.
|
||||
// More Information at: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html
|
||||
type UpdateBuilder struct {
|
||||
operationList map[operationMode][]operationBuilder
|
||||
}
|
||||
|
||||
// operationBuilder represents specific update actions (SET, REMOVE, ADD,
|
||||
// DELETE). The mode specifies what type of update action the
|
||||
// operationBuilder represents.
|
||||
type operationBuilder struct {
|
||||
name NameBuilder
|
||||
value OperandBuilder
|
||||
mode operationMode
|
||||
}
|
||||
|
||||
// buildOperation builds an exprNode from an operationBuilder. buildOperation
|
||||
// is called recursively by buildTree in order to create a tree structure
|
||||
// of exprNodes representing the parent/child relationships between
|
||||
// UpdateBuilders and operationBuilders.
|
||||
func (ob operationBuilder) buildOperation() (exprNode, error) {
|
||||
pathChild, err := ob.name.BuildOperand()
|
||||
if err != nil {
|
||||
return exprNode{}, err
|
||||
}
|
||||
|
||||
node := exprNode{
|
||||
children: []exprNode{pathChild.exprNode},
|
||||
fmtExpr: "$c",
|
||||
}
|
||||
|
||||
if ob.mode == removeOperation {
|
||||
return node, nil
|
||||
}
|
||||
|
||||
valueChild, err := ob.value.BuildOperand()
|
||||
if err != nil {
|
||||
return exprNode{}, err
|
||||
}
|
||||
node.children = append(node.children, valueChild.exprNode)
|
||||
|
||||
switch ob.mode {
|
||||
case setOperation:
|
||||
node.fmtExpr += " = $c"
|
||||
case addOperation, deleteOperation:
|
||||
node.fmtExpr += " $c"
|
||||
default:
|
||||
return exprNode{}, fmt.Errorf("build update error: build operation error: unsupported mode: %v", ob.mode)
|
||||
}
|
||||
|
||||
return node, nil
|
||||
}
|
||||
|
||||
// Delete returns an UpdateBuilder representing one Delete operation for
|
||||
// DynamoDB Update Expressions. The argument name should specify the item
|
||||
// attribute and the argument value should specify the value to be deleted. The
|
||||
// resulting UpdateBuilder can be used as an argument to the WithUpdate() method
|
||||
// for the Builder struct.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // update represents the delete operation to delete the string value
|
||||
// // "subsetToDelete" from the item attribute "pathToList"
|
||||
// update := expression.Delete(expression.Name("pathToList"), expression.Value("subsetToDelete"))
|
||||
//
|
||||
// // Adding more update methods
|
||||
// anotherUpdate := update.Remove(expression.Name("someName"))
|
||||
// // Creating a Builder
|
||||
// builder := Update(update)
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.Delete(expression.Name("pathToList"), expression.Value("subsetToDelete"))
|
||||
// // let :del be an ExpressionAttributeValue representing the value
|
||||
// // "subsetToDelete"
|
||||
// "DELETE pathToList :del"
|
||||
func Delete(name NameBuilder, value ValueBuilder) UpdateBuilder {
|
||||
emptyUpdateBuilder := UpdateBuilder{}
|
||||
return emptyUpdateBuilder.Delete(name, value)
|
||||
}
|
||||
|
||||
// Delete adds a Delete operation to the argument UpdateBuilder. The
|
||||
// argument name should specify the item attribute and the argument value should
|
||||
// specify the value to be deleted. The resulting UpdateBuilder can be used as
|
||||
// an argument to the WithUpdate() method for the Builder struct.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Let update represent an already existing update expression. Delete()
|
||||
// // adds the operation to delete the value "subsetToDelete" from the item
|
||||
// // attribute "pathToList"
|
||||
// update := update.Delete(expression.Name("pathToList"), expression.Value("subsetToDelete"))
|
||||
//
|
||||
// // Adding more update methods
|
||||
// anotherUpdate := update.Remove(expression.Name("someName"))
|
||||
// // Creating a Builder
|
||||
// builder := Update(update)
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// Delete(expression.Name("pathToList"), expression.Value("subsetToDelete"))
|
||||
// // let :del be an ExpressionAttributeValue representing the value
|
||||
// // "subsetToDelete"
|
||||
// "DELETE pathToList :del"
|
||||
func (ub UpdateBuilder) Delete(name NameBuilder, value ValueBuilder) UpdateBuilder {
|
||||
if ub.operationList == nil {
|
||||
ub.operationList = map[operationMode][]operationBuilder{}
|
||||
}
|
||||
ub.operationList[deleteOperation] = append(ub.operationList[deleteOperation], operationBuilder{
|
||||
name: name,
|
||||
value: value,
|
||||
mode: deleteOperation,
|
||||
})
|
||||
return ub
|
||||
}
|
||||
|
||||
// Add returns an UpdateBuilder representing the Add operation for DynamoDB
|
||||
// Update Expressions. The argument name should specify the item attribute and
|
||||
// the argument value should specify the value to be added. The resulting
|
||||
// UpdateBuilder can be used as an argument to the WithUpdate() method for the
|
||||
// Builder struct.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // update represents the add operation to add the value 5 to the item
|
||||
// // attribute "aPath"
|
||||
// update := expression.Add(expression.Name("aPath"), expression.Value(5))
|
||||
//
|
||||
// // Adding more update methods
|
||||
// anotherUpdate := update.Remove(expression.Name("someName"))
|
||||
// // Creating a Builder
|
||||
// builder := Update(update)
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.Add(expression.Name("aPath"), expression.Value(5))
|
||||
// // Let :five be an ExpressionAttributeValue representing the value 5
|
||||
// "ADD aPath :5"
|
||||
func Add(name NameBuilder, value ValueBuilder) UpdateBuilder {
|
||||
emptyUpdateBuilder := UpdateBuilder{}
|
||||
return emptyUpdateBuilder.Add(name, value)
|
||||
}
|
||||
|
||||
// Add adds an Add operation to the argument UpdateBuilder. The argument
|
||||
// name should specify the item attribute and the argument value should specify
|
||||
// the value to be added. The resulting UpdateBuilder can be used as an argument
|
||||
// to the WithUpdate() method for the Builder struct.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Let update represent an already existing update expression. Add() adds
|
||||
// // the operation to add the value 5 to the item attribute "aPath"
|
||||
// update := update.Add(expression.Name("aPath"), expression.Value(5))
|
||||
//
|
||||
// // Adding more update methods
|
||||
// anotherUpdate := update.Remove(expression.Name("someName"))
|
||||
// // Creating a Builder
|
||||
// builder := Update(update)
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// Add(expression.Name("aPath"), expression.Value(5))
|
||||
// // Let :five be an ExpressionAttributeValue representing the value 5
|
||||
// "ADD aPath :5"
|
||||
func (ub UpdateBuilder) Add(name NameBuilder, value ValueBuilder) UpdateBuilder {
|
||||
if ub.operationList == nil {
|
||||
ub.operationList = map[operationMode][]operationBuilder{}
|
||||
}
|
||||
ub.operationList[addOperation] = append(ub.operationList[addOperation], operationBuilder{
|
||||
name: name,
|
||||
value: value,
|
||||
mode: addOperation,
|
||||
})
|
||||
return ub
|
||||
}
|
||||
|
||||
// Remove returns an UpdateBuilder representing the Remove operation for
|
||||
// DynamoDB Update Expressions. The argument name should specify the item
|
||||
// attribute to delete. The resulting UpdateBuilder can be used as an argument
|
||||
// to the WithUpdate() method for the Builder struct.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // update represents the remove operation to remove the item attribute
|
||||
// // "itemToRemove"
|
||||
// update := expression.Remove(expression.Name("itemToRemove"))
|
||||
//
|
||||
// // Adding more update methods
|
||||
// anotherUpdate := update.Remove(expression.Name("someName"))
|
||||
// // Creating a Builder
|
||||
// builder := Update(update)
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.Remove(expression.Name("itemToRemove"))
|
||||
// "REMOVE itemToRemove"
|
||||
func Remove(name NameBuilder) UpdateBuilder {
|
||||
emptyUpdateBuilder := UpdateBuilder{}
|
||||
return emptyUpdateBuilder.Remove(name)
|
||||
}
|
||||
|
||||
// Remove adds a Remove operation to the argument UpdateBuilder. The
|
||||
// argument name should specify the item attribute to delete. The resulting
|
||||
// UpdateBuilder can be used as an argument to the WithUpdate() method for the
|
||||
// Builder struct.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Let update represent an already existing update expression. Remove()
|
||||
// // adds the operation to remove the item attribute "itemToRemove"
|
||||
// update := update.Remove(expression.Name("itemToRemove"))
|
||||
//
|
||||
// // Adding more update methods
|
||||
// anotherUpdate := update.Remove(expression.Name("someName"))
|
||||
// // Creating a Builder
|
||||
// builder := Update(update)
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// Remove(expression.Name("itemToRemove"))
|
||||
// "REMOVE itemToRemove"
|
||||
func (ub UpdateBuilder) Remove(name NameBuilder) UpdateBuilder {
|
||||
if ub.operationList == nil {
|
||||
ub.operationList = map[operationMode][]operationBuilder{}
|
||||
}
|
||||
ub.operationList[removeOperation] = append(ub.operationList[removeOperation], operationBuilder{
|
||||
name: name,
|
||||
mode: removeOperation,
|
||||
})
|
||||
return ub
|
||||
}
|
||||
|
||||
// Set returns an UpdateBuilder representing the Set operation for DynamoDB
|
||||
// Update Expressions. The argument name should specify the item attribute to
|
||||
// modify. The argument OperandBuilder should specify the value to modify the
|
||||
// the item attribute to. The resulting UpdateBuilder can be used as an argument
|
||||
// to the WithUpdate() method for the Builder struct.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // update represents the set operation to set the item attribute
|
||||
// // "itemToSet" to the value "setValue" if the item attribute does not
|
||||
// // exist yet. (conditional write)
|
||||
// update := expression.Set(expression.Name("itemToSet"), expression.IfNotExists(expression.Name("itemToSet"), expression.Value("setValue")))
|
||||
//
|
||||
// // Adding more update methods
|
||||
// anotherUpdate := update.Remove(expression.Name("someName"))
|
||||
// // Creating a Builder
|
||||
// builder := Update(update)
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// expression.Set(expression.Name("itemToSet"), expression.IfNotExists(expression.Name("itemToSet"), expression.Value("setValue")))
|
||||
// // Let :val be an ExpressionAttributeValue representing the value
|
||||
// // "setValue"
|
||||
// "SET itemToSet = :val"
|
||||
func Set(name NameBuilder, operandBuilder OperandBuilder) UpdateBuilder {
|
||||
emptyUpdateBuilder := UpdateBuilder{}
|
||||
return emptyUpdateBuilder.Set(name, operandBuilder)
|
||||
}
|
||||
|
||||
// Set adds a Set operation to the argument UpdateBuilder. The argument name
|
||||
// should specify the item attribute to modify. The argument OperandBuilder
|
||||
// should specify the value to modify the the item attribute to. The resulting
|
||||
// UpdateBuilder can be used as an argument to the WithUpdate() method for the
|
||||
// Builder struct.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Let update represent an already existing update expression. Set() adds
|
||||
// // the operation to to set the item attribute "itemToSet" to the value
|
||||
// // "setValue" if the item attribute does not exist yet. (conditional
|
||||
// // write)
|
||||
// update := update.Set(expression.Name("itemToSet"), expression.IfNotExists(expression.Name("itemToSet"), expression.Value("setValue")))
|
||||
//
|
||||
// // Adding more update methods
|
||||
// anotherUpdate := update.Remove(expression.Name("someName"))
|
||||
// // Creating a Builder
|
||||
// builder := Update(update)
|
||||
//
|
||||
// Expression Equivalent:
|
||||
//
|
||||
// Set(expression.Name("itemToSet"), expression.IfNotExists(expression.Name("itemToSet"), expression.Value("setValue")))
|
||||
// // Let :val be an ExpressionAttributeValue representing the value
|
||||
// // "setValue"
|
||||
// "SET itemToSet = :val"
|
||||
func (ub UpdateBuilder) Set(name NameBuilder, operandBuilder OperandBuilder) UpdateBuilder {
|
||||
if ub.operationList == nil {
|
||||
ub.operationList = map[operationMode][]operationBuilder{}
|
||||
}
|
||||
ub.operationList[setOperation] = append(ub.operationList[setOperation], operationBuilder{
|
||||
name: name,
|
||||
value: operandBuilder,
|
||||
mode: setOperation,
|
||||
})
|
||||
return ub
|
||||
}
|
||||
|
||||
// buildTree builds a tree structure of exprNodes based on the tree
|
||||
// structure of the input UpdateBuilder's child UpdateBuilders/Operands.
|
||||
// buildTree() satisfies the TreeBuilder interface so ProjectionBuilder can be a
|
||||
// part of Expression struct.
|
||||
func (ub UpdateBuilder) buildTree() (exprNode, error) {
|
||||
if ub.operationList == nil {
|
||||
return exprNode{}, newUnsetParameterError("buildTree", "UpdateBuilder")
|
||||
}
|
||||
ret := exprNode{
|
||||
children: []exprNode{},
|
||||
}
|
||||
|
||||
modes := modeList{}
|
||||
|
||||
for mode := range ub.operationList {
|
||||
modes = append(modes, mode)
|
||||
}
|
||||
|
||||
sort.Sort(modes)
|
||||
|
||||
for _, key := range modes {
|
||||
ret.fmtExpr += string(key) + " $c\n"
|
||||
|
||||
childNode, err := buildChildNodes(ub.operationList[key])
|
||||
if err != nil {
|
||||
return exprNode{}, err
|
||||
}
|
||||
|
||||
ret.children = append(ret.children, childNode)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// buildChildNodes creates the list of the child exprNodes.
|
||||
func buildChildNodes(operationBuilderList []operationBuilder) (exprNode, error) {
|
||||
if len(operationBuilderList) == 0 {
|
||||
return exprNode{}, fmt.Errorf("buildChildNodes error: operationBuilder list is empty")
|
||||
}
|
||||
|
||||
node := exprNode{
|
||||
children: make([]exprNode, 0, len(operationBuilderList)),
|
||||
fmtExpr: "$c" + strings.Repeat(", $c", len(operationBuilderList)-1),
|
||||
}
|
||||
|
||||
for _, val := range operationBuilderList {
|
||||
valNode, err := val.buildOperation()
|
||||
if err != nil {
|
||||
return exprNode{}, err
|
||||
}
|
||||
node.children = append(node.children, valNode)
|
||||
}
|
||||
|
||||
return node, nil
|
||||
}
|
771
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/update_test.go
generated
vendored
Normal file
771
vendor/github.com/aws/aws-sdk-go/service/dynamodb/expression/update_test.go
generated
vendored
Normal file
|
@ -0,0 +1,771 @@
|
|||
// +build go1.7
|
||||
|
||||
package expression
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/dynamodb"
|
||||
)
|
||||
|
||||
// updateErrorMode will help with error cases and checking error types
|
||||
type updateErrorMode string
|
||||
|
||||
const (
|
||||
noUpdateError updateErrorMode = ""
|
||||
invalidUpdateOperand = "BuildOperand error"
|
||||
unsetSetValue = "unset parameter: SetValueBuilder"
|
||||
unsetUpdate = "unset parameter: UpdateBuilder"
|
||||
emptyOperationBuilderList = "operationBuilder list is empty"
|
||||
)
|
||||
|
||||
func TestBuildOperation(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
input operationBuilder
|
||||
expected exprNode
|
||||
err updateErrorMode
|
||||
}{
|
||||
{
|
||||
name: "set operation",
|
||||
input: operationBuilder{
|
||||
name: Name("foo"),
|
||||
value: Value(5),
|
||||
mode: setOperation,
|
||||
},
|
||||
expected: exprNode{
|
||||
children: []exprNode{
|
||||
{
|
||||
names: []string{"foo"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
{
|
||||
values: []dynamodb.AttributeValue{
|
||||
{
|
||||
N: aws.String("5"),
|
||||
},
|
||||
},
|
||||
fmtExpr: "$v",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c = $c",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "add operation",
|
||||
input: operationBuilder{
|
||||
name: Name("foo"),
|
||||
value: Value(5),
|
||||
mode: addOperation,
|
||||
},
|
||||
expected: exprNode{
|
||||
children: []exprNode{
|
||||
{
|
||||
names: []string{"foo"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
{
|
||||
values: []dynamodb.AttributeValue{
|
||||
{
|
||||
N: aws.String("5"),
|
||||
},
|
||||
},
|
||||
fmtExpr: "$v",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c $c",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "remove operation",
|
||||
input: operationBuilder{
|
||||
name: Name("foo"),
|
||||
mode: removeOperation,
|
||||
},
|
||||
expected: exprNode{
|
||||
children: []exprNode{
|
||||
{
|
||||
names: []string{"foo"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid operand",
|
||||
input: operationBuilder{
|
||||
name: Name(""),
|
||||
mode: removeOperation,
|
||||
},
|
||||
err: invalidUpdateOperand,
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
actual, err := c.input.buildOperation()
|
||||
if c.err != noUpdateError {
|
||||
if err == nil {
|
||||
t.Errorf("expect error %q, got no error", c.err)
|
||||
} else {
|
||||
if e, a := string(c.err), err.Error(); !strings.Contains(a, e) {
|
||||
t.Errorf("expect %q error message to be in %q", e, a)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Errorf("expect no error, got unexpected Error %q", err)
|
||||
}
|
||||
|
||||
if e, a := c.expected, actual; !reflect.DeepEqual(a, e) {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateTree(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
input UpdateBuilder
|
||||
expectedNode exprNode
|
||||
err updateErrorMode
|
||||
}{
|
||||
{
|
||||
name: "set update",
|
||||
input: Set(Name("foo"), Value(5)),
|
||||
expectedNode: exprNode{
|
||||
children: []exprNode{
|
||||
{
|
||||
children: []exprNode{
|
||||
{
|
||||
children: []exprNode{
|
||||
{
|
||||
names: []string{"foo"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
{
|
||||
values: []dynamodb.AttributeValue{
|
||||
{
|
||||
N: aws.String("5"),
|
||||
},
|
||||
},
|
||||
fmtExpr: "$v",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c = $c",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c",
|
||||
},
|
||||
},
|
||||
fmtExpr: "SET $c\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "remove update",
|
||||
input: Remove(Name("foo")),
|
||||
expectedNode: exprNode{
|
||||
children: []exprNode{
|
||||
{
|
||||
children: []exprNode{
|
||||
{
|
||||
children: []exprNode{
|
||||
{
|
||||
names: []string{"foo"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c",
|
||||
},
|
||||
},
|
||||
fmtExpr: "REMOVE $c\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "add update",
|
||||
input: Add(Name("foo"), Value(5)),
|
||||
expectedNode: exprNode{
|
||||
children: []exprNode{
|
||||
{
|
||||
children: []exprNode{
|
||||
{
|
||||
children: []exprNode{
|
||||
{
|
||||
names: []string{"foo"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
{
|
||||
values: []dynamodb.AttributeValue{
|
||||
{
|
||||
N: aws.String("5"),
|
||||
},
|
||||
},
|
||||
fmtExpr: "$v",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c $c",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c",
|
||||
},
|
||||
},
|
||||
fmtExpr: "ADD $c\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "delete update",
|
||||
input: Delete(Name("foo"), Value(5)),
|
||||
expectedNode: exprNode{
|
||||
children: []exprNode{
|
||||
{
|
||||
children: []exprNode{
|
||||
{
|
||||
children: []exprNode{
|
||||
{
|
||||
names: []string{"foo"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
{
|
||||
values: []dynamodb.AttributeValue{
|
||||
{
|
||||
N: aws.String("5"),
|
||||
},
|
||||
},
|
||||
fmtExpr: "$v",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c $c",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c",
|
||||
},
|
||||
},
|
||||
fmtExpr: "DELETE $c\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "multiple sets",
|
||||
input: Set(Name("foo"), Value(5)).Set(Name("bar"), Value(6)).Set(Name("baz"), Name("qux")),
|
||||
expectedNode: exprNode{
|
||||
fmtExpr: "SET $c\n",
|
||||
children: []exprNode{
|
||||
{
|
||||
fmtExpr: "$c, $c, $c",
|
||||
children: []exprNode{
|
||||
{
|
||||
fmtExpr: "$c = $c",
|
||||
children: []exprNode{
|
||||
{
|
||||
fmtExpr: "$n",
|
||||
names: []string{"foo"},
|
||||
},
|
||||
{
|
||||
fmtExpr: "$v",
|
||||
values: []dynamodb.AttributeValue{
|
||||
{
|
||||
N: aws.String("5"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
fmtExpr: "$c = $c",
|
||||
children: []exprNode{
|
||||
{
|
||||
fmtExpr: "$n",
|
||||
names: []string{"bar"},
|
||||
},
|
||||
{
|
||||
fmtExpr: "$v",
|
||||
values: []dynamodb.AttributeValue{
|
||||
{
|
||||
N: aws.String("6"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
fmtExpr: "$c = $c",
|
||||
children: []exprNode{
|
||||
{
|
||||
fmtExpr: "$n",
|
||||
names: []string{"baz"},
|
||||
},
|
||||
{
|
||||
fmtExpr: "$n",
|
||||
names: []string{"qux"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "compound update",
|
||||
input: Add(Name("foo"), Value(5)).Set(Name("foo"), Value(5)).Delete(Name("foo"), Value(5)).Remove(Name("foo")),
|
||||
expectedNode: exprNode{
|
||||
children: []exprNode{
|
||||
{
|
||||
children: []exprNode{
|
||||
{
|
||||
children: []exprNode{
|
||||
{
|
||||
names: []string{"foo"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
{
|
||||
values: []dynamodb.AttributeValue{
|
||||
{
|
||||
N: aws.String("5"),
|
||||
},
|
||||
},
|
||||
fmtExpr: "$v",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c $c",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c",
|
||||
},
|
||||
{
|
||||
children: []exprNode{
|
||||
{
|
||||
children: []exprNode{
|
||||
{
|
||||
names: []string{"foo"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
{
|
||||
values: []dynamodb.AttributeValue{
|
||||
{
|
||||
N: aws.String("5"),
|
||||
},
|
||||
},
|
||||
fmtExpr: "$v",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c $c",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c",
|
||||
},
|
||||
{
|
||||
children: []exprNode{
|
||||
{
|
||||
children: []exprNode{
|
||||
{
|
||||
names: []string{"foo"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c",
|
||||
},
|
||||
{
|
||||
children: []exprNode{
|
||||
{
|
||||
children: []exprNode{
|
||||
{
|
||||
names: []string{"foo"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
{
|
||||
values: []dynamodb.AttributeValue{
|
||||
{
|
||||
N: aws.String("5"),
|
||||
},
|
||||
},
|
||||
fmtExpr: "$v",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c = $c",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c",
|
||||
},
|
||||
},
|
||||
fmtExpr: "ADD $c\nDELETE $c\nREMOVE $c\nSET $c\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "empty UpdateBuilder",
|
||||
input: UpdateBuilder{},
|
||||
err: unsetUpdate,
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
actual, err := c.input.buildTree()
|
||||
if c.err != noUpdateError {
|
||||
if err == nil {
|
||||
t.Errorf("expect error %q, got no error", c.err)
|
||||
} else {
|
||||
if e, a := string(c.err), err.Error(); !strings.Contains(a, e) {
|
||||
t.Errorf("expect %q error message to be in %q", e, a)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Errorf("expect no error, got unexpected Error %q", err)
|
||||
}
|
||||
|
||||
if e, a := c.expectedNode, actual; !reflect.DeepEqual(a, e) {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetValueBuilder(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
input SetValueBuilder
|
||||
expected exprNode
|
||||
err updateErrorMode
|
||||
}{
|
||||
{
|
||||
name: "name plus name",
|
||||
input: Name("foo").Plus(Name("bar")),
|
||||
expected: exprNode{
|
||||
children: []exprNode{
|
||||
{
|
||||
names: []string{"foo"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
{
|
||||
names: []string{"bar"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c + $c",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "name minus name",
|
||||
input: Name("foo").Minus(Name("bar")),
|
||||
expected: exprNode{
|
||||
children: []exprNode{
|
||||
{
|
||||
names: []string{"foo"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
{
|
||||
names: []string{"bar"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c - $c",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "list append name and name",
|
||||
input: Name("foo").ListAppend(Name("bar")),
|
||||
expected: exprNode{
|
||||
children: []exprNode{
|
||||
{
|
||||
names: []string{"foo"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
{
|
||||
names: []string{"bar"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
},
|
||||
fmtExpr: "list_append($c, $c)",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "if not exists name and name",
|
||||
input: Name("foo").IfNotExists(Name("bar")),
|
||||
expected: exprNode{
|
||||
children: []exprNode{
|
||||
{
|
||||
names: []string{"foo"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
{
|
||||
names: []string{"bar"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
},
|
||||
fmtExpr: "if_not_exists($c, $c)",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "value plus name",
|
||||
input: Value(5).Plus(Name("bar")),
|
||||
expected: exprNode{
|
||||
children: []exprNode{
|
||||
{
|
||||
values: []dynamodb.AttributeValue{
|
||||
{
|
||||
N: aws.String("5"),
|
||||
},
|
||||
},
|
||||
fmtExpr: "$v",
|
||||
},
|
||||
{
|
||||
names: []string{"bar"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c + $c",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "value minus name",
|
||||
input: Value(5).Minus(Name("bar")),
|
||||
expected: exprNode{
|
||||
children: []exprNode{
|
||||
{
|
||||
values: []dynamodb.AttributeValue{
|
||||
{
|
||||
N: aws.String("5"),
|
||||
},
|
||||
},
|
||||
fmtExpr: "$v",
|
||||
},
|
||||
{
|
||||
names: []string{"bar"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
},
|
||||
fmtExpr: "$c - $c",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "list append list and name",
|
||||
input: Value([]int{1, 2, 3}).ListAppend(Name("bar")),
|
||||
expected: exprNode{
|
||||
children: []exprNode{
|
||||
{
|
||||
values: []dynamodb.AttributeValue{
|
||||
{
|
||||
L: []*dynamodb.AttributeValue{
|
||||
{
|
||||
N: aws.String("1"),
|
||||
},
|
||||
{
|
||||
N: aws.String("2"),
|
||||
},
|
||||
{
|
||||
N: aws.String("3"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
fmtExpr: "$v",
|
||||
},
|
||||
{
|
||||
names: []string{"bar"},
|
||||
fmtExpr: "$n",
|
||||
},
|
||||
},
|
||||
fmtExpr: "list_append($c, $c)",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "unset SetValueBuilder",
|
||||
input: SetValueBuilder{},
|
||||
err: unsetSetValue,
|
||||
},
|
||||
{
|
||||
name: "invalid operand error",
|
||||
input: Name("").Plus(Name("foo")),
|
||||
err: invalidUpdateOperand,
|
||||
},
|
||||
{
|
||||
name: "invalid operand error",
|
||||
input: Name("foo").Plus(Name("")),
|
||||
err: invalidUpdateOperand,
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
actual, err := c.input.BuildOperand()
|
||||
if c.err != noUpdateError {
|
||||
if err == nil {
|
||||
t.Errorf("expect error %q, got no error", c.err)
|
||||
} else {
|
||||
if e, a := string(c.err), err.Error(); !strings.Contains(a, e) {
|
||||
t.Errorf("expect %q error message to be in %q", e, a)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Errorf("expect no error, got unexpected Error %q", err)
|
||||
}
|
||||
|
||||
if e, a := c.expected, actual.exprNode; !reflect.DeepEqual(a, e) {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateBuildChildNodes(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
input []operationBuilder
|
||||
expected exprNode
|
||||
err updateErrorMode
|
||||
}{
|
||||
{
|
||||
name: "set operand builder",
|
||||
input: []operationBuilder{
|
||||
{
|
||||
mode: setOperation,
|
||||
name: NameBuilder{
|
||||
name: "foo",
|
||||
},
|
||||
value: ValueBuilder{
|
||||
value: 5,
|
||||
},
|
||||
},
|
||||
{
|
||||
mode: setOperation,
|
||||
name: NameBuilder{
|
||||
name: "bar",
|
||||
},
|
||||
value: ValueBuilder{
|
||||
value: 6,
|
||||
},
|
||||
},
|
||||
{
|
||||
mode: setOperation,
|
||||
name: NameBuilder{
|
||||
name: "baz",
|
||||
},
|
||||
value: ValueBuilder{
|
||||
value: 7,
|
||||
},
|
||||
},
|
||||
{
|
||||
mode: setOperation,
|
||||
name: NameBuilder{
|
||||
name: "qux",
|
||||
},
|
||||
value: ValueBuilder{
|
||||
value: 8,
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: exprNode{
|
||||
fmtExpr: "$c, $c, $c, $c",
|
||||
children: []exprNode{
|
||||
{
|
||||
fmtExpr: "$c = $c",
|
||||
children: []exprNode{
|
||||
{
|
||||
fmtExpr: "$n",
|
||||
names: []string{"foo"},
|
||||
},
|
||||
{
|
||||
fmtExpr: "$v",
|
||||
values: []dynamodb.AttributeValue{
|
||||
{
|
||||
N: aws.String("5"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
fmtExpr: "$c = $c",
|
||||
children: []exprNode{
|
||||
{
|
||||
fmtExpr: "$n",
|
||||
names: []string{"bar"},
|
||||
},
|
||||
{
|
||||
fmtExpr: "$v",
|
||||
values: []dynamodb.AttributeValue{
|
||||
{
|
||||
N: aws.String("6"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
fmtExpr: "$c = $c",
|
||||
children: []exprNode{
|
||||
{
|
||||
fmtExpr: "$n",
|
||||
names: []string{"baz"},
|
||||
},
|
||||
{
|
||||
fmtExpr: "$v",
|
||||
values: []dynamodb.AttributeValue{
|
||||
{
|
||||
N: aws.String("7"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
fmtExpr: "$c = $c",
|
||||
children: []exprNode{
|
||||
{
|
||||
fmtExpr: "$n",
|
||||
names: []string{"qux"},
|
||||
},
|
||||
{
|
||||
fmtExpr: "$v",
|
||||
values: []dynamodb.AttributeValue{
|
||||
{
|
||||
N: aws.String("8"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "empty operationBuilder list",
|
||||
input: []operationBuilder{},
|
||||
err: emptyOperationBuilderList,
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
actual, err := buildChildNodes(c.input)
|
||||
if c.err != noUpdateError {
|
||||
if err == nil {
|
||||
t.Errorf("expect error %q, got no error", c.err)
|
||||
} else {
|
||||
if e, a := string(c.err), err.Error(); !strings.Contains(a, e) {
|
||||
t.Errorf("expect %q error message to be in %q", e, a)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Errorf("expect no error, got unexpected Error %q", err)
|
||||
}
|
||||
|
||||
if e, a := c.expected, actual; !reflect.DeepEqual(a, e) {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
4
vendor/github.com/aws/aws-sdk-go/service/dynamodb/waiters.go
generated
vendored
4
vendor/github.com/aws/aws-sdk-go/service/dynamodb/waiters.go
generated
vendored
|
@ -11,7 +11,7 @@ import (
|
|||
|
||||
// WaitUntilTableExists uses the DynamoDB API operation
|
||||
// DescribeTable to wait for a condition to be met before returning.
|
||||
// If the condition is not meet within the max attempt window an error will
|
||||
// If the condition is not met within the max attempt window, an error will
|
||||
// be returned.
|
||||
func (c *DynamoDB) WaitUntilTableExists(input *DescribeTableInput) error {
|
||||
return c.WaitUntilTableExistsWithContext(aws.BackgroundContext(), input)
|
||||
|
@ -62,7 +62,7 @@ func (c *DynamoDB) WaitUntilTableExistsWithContext(ctx aws.Context, input *Descr
|
|||
|
||||
// WaitUntilTableNotExists uses the DynamoDB API operation
|
||||
// DescribeTable to wait for a condition to be met before returning.
|
||||
// If the condition is not meet within the max attempt window an error will
|
||||
// If the condition is not met within the max attempt window, an error will
|
||||
// be returned.
|
||||
func (c *DynamoDB) WaitUntilTableNotExists(input *DescribeTableInput) error {
|
||||
return c.WaitUntilTableNotExistsWithContext(aws.BackgroundContext(), input)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue