func encodeTransactWriteItemsInput()

in dax/internal/client/request.go [589:856]


func encodeTransactWriteItemsInput(
	ctx context.Context,
	input *dynamodb.TransactWriteItemsInput,
	keySchema *lru.Lru, attrNamesListToId *lru.Lru, writer *cbor.Writer,
	extractedKeys []map[string]types.AttributeValue,
) error {
	if input == nil {
		return smithy.NewErrParamRequired("input cannot be nil")
	}
	var err error
	if err = ValidateOpTransactWriteItemsInput(input); err != nil {
		return err
	}
	if err = encodeServiceAndMethod(transactWriteItems_N1160037738_1_Id, writer); err != nil {
		return err
	}

	var operationsBuf, tableNamesBuf, keysBuf, valuesBuf, conditionExpressionsBuf,
		updateExpressionsBuf, rvOnConditionCheckFailureBuf bytes.Buffer
	operationWriter := cbor.NewWriter(&operationsBuf)
	tableNamesWriter := cbor.NewWriter(&tableNamesBuf)
	keysWriter := cbor.NewWriter(&keysBuf)
	valuesWriter := cbor.NewWriter(&valuesBuf)
	conditionExpressionsWriter := cbor.NewWriter(&conditionExpressionsBuf)
	updateExpressionsWriter := cbor.NewWriter(&updateExpressionsBuf)
	rvOnConditionCheckFailureWriter := cbor.NewWriter(&rvOnConditionCheckFailureBuf)

	l := len(input.TransactItems)

	if err = operationWriter.WriteArrayHeader(l); err != nil {
		return err
	}
	if err = tableNamesWriter.WriteArrayHeader(l); err != nil {
		return err
	}
	if err = keysWriter.WriteArrayHeader(l); err != nil {
		return err
	}
	if err = valuesWriter.WriteArrayHeader(l); err != nil {
		return err
	}
	if err = conditionExpressionsWriter.WriteArrayHeader(l); err != nil {
		return err
	}
	if err = updateExpressionsWriter.WriteArrayHeader(l); err != nil {
		return err
	}
	if err = rvOnConditionCheckFailureWriter.WriteArrayHeader(l); err != nil {
		return err
	}

	defer func() {
		operationWriter.Close()
		tableNamesWriter.Close()
		keysWriter.Close()
		valuesWriter.Close()
		conditionExpressionsWriter.Close()
		updateExpressionsWriter.Close()
		rvOnConditionCheckFailureWriter.Close()
	}()

	tableKeySet := make(map[string]bool)
	for i, twi := range input.TransactItems {
		var operation int
		var tableName *string
		var key map[string]types.AttributeValue
		var item map[string]types.AttributeValue
		var isItem bool = false
		var conditionExpression *string
		var updateExpression *string
		var expressionAttributeNames map[string]string
		var expressionAttributeValues map[string]types.AttributeValue
		var rvOnConditionCheckFailure types.ReturnValuesOnConditionCheckFailure
		opCount := 0
		if check := twi.ConditionCheck; check != nil {
			opCount++
			operation = checkOperation
			conditionExpression = check.ConditionExpression
			expressionAttributeNames = check.ExpressionAttributeNames
			expressionAttributeValues = check.ExpressionAttributeValues
			tableName = check.TableName
			key = check.Key
			rvOnConditionCheckFailure = check.ReturnValuesOnConditionCheckFailure
		}
		if delete := twi.Delete; delete != nil {
			opCount++
			operation = deleteOperation
			conditionExpression = delete.ConditionExpression
			expressionAttributeNames = delete.ExpressionAttributeNames
			expressionAttributeValues = delete.ExpressionAttributeValues
			tableName = delete.TableName
			key = delete.Key
			rvOnConditionCheckFailure = delete.ReturnValuesOnConditionCheckFailure
		}
		if put := twi.Put; put != nil {
			opCount++
			operation = putOperation
			conditionExpression = put.ConditionExpression
			expressionAttributeNames = put.ExpressionAttributeNames
			expressionAttributeValues = put.ExpressionAttributeValues
			tableName = put.TableName
			item = put.Item
			isItem = true
			rvOnConditionCheckFailure = put.ReturnValuesOnConditionCheckFailure
		}
		if update := twi.Update; update != nil {
			opCount++
			operation = partialUpdateOperation
			conditionExpression = update.ConditionExpression
			expressionAttributeNames = update.ExpressionAttributeNames
			expressionAttributeValues = update.ExpressionAttributeValues
			tableName = update.TableName
			key = update.Key
			updateExpression = update.UpdateExpression
			rvOnConditionCheckFailure = update.ReturnValuesOnConditionCheckFailure
		}

		if opCount == 0 {
			return smithy.NewErrParamRequired("Invalid Request: TransactWriteItemsInput should contain Delete or Put or Update request")
		}
		if opCount > 1 {
			return smithy.NewErrParamRequired("TransactItems can only contain one of ConditionalCheck, Put, Update or Delete")
		}

		if err := operationWriter.WriteInt(operation); err != nil {
			return err
		}
		if err := tableNamesWriter.WriteBytes([]byte(*tableName)); err != nil {
			return err
		}

		keydef, err := getKeySchema(ctx, keySchema, *tableName)
		if err != nil {
			return nil
		}

		// Check if duplicate [key, tableName] pair exists
		var keyBytes []byte
		if isItem {
			keyBytes, err = cbor.GetEncodedItemKey(item, keydef)
		} else {
			keyBytes, err = cbor.GetEncodedItemKey(key, keydef)
		}
		if err != nil {
			return err
		}
		keysWriter.WriteBytes(keyBytes)
		keyBytes = append(keyBytes, []byte(*tableName)...)
		tableKey := string(keyBytes)
		_, ok := tableKeySet[tableKey]
		if ok {
			return smithy.NewErrParamRequired("Transaction request cannot include multiple operations on one item")
		} else {
			tableKeySet[tableKey] = true
		}

		switch operation {
		case checkOperation, deleteOperation, partialUpdateOperation:
			if err := valuesWriter.WriteNull(); err != nil {
				return err
			}
		case putOperation:
			if err := encodeNonKeyAttributes(ctx, item, keydef, attrNamesListToId, valuesWriter); err != nil {
				return err
			}
			key = map[string]types.AttributeValue{}
			for _, attrDef := range keydef {
				key[*attrDef.AttributeName] = item[*attrDef.AttributeName]
			}
		}

		extractedKeys[i] = key

		encoded, err := parseExpressions(conditionExpression, updateExpression, nil, expressionAttributeNames, expressionAttributeValues)
		if err != nil {
			return err
		}
		if parsedConditionExpr := encoded[parser.ConditionExpr]; parsedConditionExpr != nil {
			if err := conditionExpressionsWriter.WriteBytes(parsedConditionExpr); err != nil {
				return err
			}
		} else {
			if err := conditionExpressionsWriter.WriteNull(); err != nil {
				return err
			}
		}

		if parsedUpdateExpr := encoded[parser.UpdateExpr]; parsedUpdateExpr != nil {
			if err := updateExpressionsWriter.WriteBytes(parsedUpdateExpr); err != nil {
				return err
			}
		} else {
			if err := updateExpressionsWriter.WriteNull(); err != nil {
				return err
			}
		}

		if rvOnConditionCheckFailure == types.ReturnValuesOnConditionCheckFailureAllOld {
			if err := rvOnConditionCheckFailureWriter.WriteInt(returnValueOnConditionCheckFailureAllOld); err != nil {
				return err
			}
		} else {
			if err := rvOnConditionCheckFailureWriter.WriteInt(returnValueOnConditionCheckFailureNone); err != nil {
				return err
			}
		}
	}

	if err := operationWriter.Flush(); err != nil {
		return err
	}
	if err := writer.Write(operationsBuf.Bytes()); err != nil {
		return err
	}
	if err := tableNamesWriter.Flush(); err != nil {
		return err
	}
	if err := writer.Write(tableNamesBuf.Bytes()); err != nil {
		return err
	}
	if err := keysWriter.Flush(); err != nil {
		return err
	}
	if err := writer.Write(keysBuf.Bytes()); err != nil {
		return err
	}
	if err := valuesWriter.Flush(); err != nil {
		return err
	}
	if err := writer.Write(valuesBuf.Bytes()); err != nil {
		return err
	}
	// Write null for returnValues
	if err := writer.WriteNull(); err != nil {
		return err
	}
	if err := rvOnConditionCheckFailureWriter.Flush(); err != nil {
		return err
	}
	if err := writer.Write(rvOnConditionCheckFailureBuf.Bytes()); err != nil {
		return err
	}
	if err := conditionExpressionsWriter.Flush(); err != nil {
		return err
	}
	if err := writer.Write(conditionExpressionsBuf.Bytes()); err != nil {
		return err
	}
	if err := updateExpressionsWriter.Flush(); err != nil {
		return err
	}
	if err := writer.Write(updateExpressionsBuf.Bytes()); err != nil {
		return err
	}

	if input.ClientRequestToken == nil {
		id, err := uuid.NewV4()
		if err != nil {
			return err
		}
		input.ClientRequestToken = aws.String(id.String())
	}
	return encodeItemOperationOptionalParamsWithToken(
		types.ReturnValueNone,
		input.ReturnConsumedCapacity,
		input.ReturnItemCollectionMetrics,
		nil, nil, nil, nil, nil, nil, input.ClientRequestToken, writer)
}