2022-11-17 15:28:20 -05:00
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
/**
* Before running this C++ code example, set up your development environment, including your credentials.
*
* For more information, see the following documentation topic:
*
* https://docs.aws.amazon.com/sdk-for-cpp/v1/developer-guide/getting-started.html
*
* For information on the structure of the code examples and how to build and run the examples, see
* https://docs.aws.amazon.com/sdk-for-cpp/v1/developer-guide/getting-started-code-examples.html.
*
* Purpose
*
* Demonstrates using the AWS SDK for C++ to create an Amazon DynamoDB table and
* to perform a series of operations on the table using PartiQL batch statements.
*
* 1. Create a table with partition: year, and sort: title. (CreateTable)
* 2. Add multiple movies using "Insert" statements. (BatchExecuteStatement)
* 3. Get the data for multiple movies using "Select" statements. (BatchExecuteStatement)
* 4. Update the data for multiple movies using "Update" statements. (BatchExecuteStatement)
* 5. Get the updated data for multiple movies using "Select" statements. (BatchExecuteStatement)
* 6. Delete multiple movies using "Delete" statements. (BatchExecuteStatement)
* 7. Delete the table. (DeleteTable)
*/
# include "dynamodb_samples.h"
# include <iostream>
# include <iomanip>
# include <aws/core/Aws.h>
# include <aws/dynamodb/DynamoDBClient.h>
# include <aws/dynamodb/model/ExecuteStatementRequest.h>
# include <aws/dynamodb/model/BatchExecuteStatementRequest.h>
# include <array>
// snippet-start:[cpp.example_code.dynamodb.Scenario_PartiQL_Batch]
//! Scenario to modify and query a DynamoDB table using PartiQL batch statements.
/*!
\sa partiqlBatchExecuteScenario()
2022-12-20 11:23:09 -05:00
\param clientConfiguration: AWS client configuration.
2022-11-17 15:28:20 -05:00
\return bool: Function succeeded.
*/
bool AwsDoc : : DynamoDB : : partiqlBatchExecuteScenario (
const Aws : : Client : : ClientConfiguration & clientConfiguration ) {
// snippet-start:[cpp.example_code.dynamodb.BatchExecuteStatement.Insert]
// 2. Add multiple movies using "Insert" statements. (BatchExecuteStatement)
Aws : : DynamoDB : : DynamoDBClient dynamoClient ( clientConfiguration ) ;
std : : vector < Aws : : String > titles ;
std : : vector < float > ratings ;
std : : vector < int > years ;
std : : vector < Aws : : String > plots ;
Aws : : String doAgain = " n " ;
do {
Aws : : String aTitle = askQuestion (
" Enter the title of a movie you want to add to the table: " ) ;
titles . push_back ( aTitle ) ;
int aYear = askQuestionForInt ( " What year was it released? " ) ;
years . push_back ( aYear ) ;
float aRating = askQuestionForFloatRange (
" On a scale of 1 - 10, how do you rate it? " ,
1 , 10 ) ;
ratings . push_back ( aRating ) ;
Aws : : String aPlot = askQuestion ( " Summarize the plot for me: " ) ;
plots . push_back ( aPlot ) ;
doAgain = askQuestion ( Aws : : String ( " Would you like to add more movies? (y/n) " ) ) ;
} while ( doAgain = = " y " ) ;
std : : cout < < " Adding " < < titles . size ( )
< < ( titles . size ( ) = = 1 ? " movie " : " movies " )
< < " to the table using a batch \" INSERT \" statement. " < < std : : endl ;
{
Aws : : Vector < Aws : : DynamoDB : : Model : : BatchStatementRequest > statements (
titles . size ( ) ) ;
std : : stringstream sqlStream ;
sqlStream < < " INSERT INTO \" " < < MOVIE_TABLE_NAME < < " \" VALUE {' "
< < TITLE_KEY < < " ': ?, ' " < < YEAR_KEY < < " ': ?, ' "
< < INFO_KEY < < " ': ?} " ;
std : : string sql ( sqlStream . str ( ) ) ;
for ( size_t i = 0 ; i < statements . size ( ) ; + + i ) {
statements [ i ] . SetStatement ( sql ) ;
Aws : : Vector < Aws : : DynamoDB : : Model : : AttributeValue > attributes ;
attributes . push_back (
Aws : : DynamoDB : : Model : : AttributeValue ( ) . SetS ( titles [ i ] ) ) ;
attributes . push_back ( Aws : : DynamoDB : : Model : : AttributeValue ( ) . SetN ( years [ i ] ) ) ;
// Create attribute for the info map.
Aws : : DynamoDB : : Model : : AttributeValue infoMapAttribute ;
std : : shared_ptr < Aws : : DynamoDB : : Model : : AttributeValue > ratingAttribute = Aws : : MakeShared < Aws : : DynamoDB : : Model : : AttributeValue > (
ALLOCATION_TAG . c_str ( ) ) ;
ratingAttribute - > SetN ( ratings [ i ] ) ;
infoMapAttribute . AddMEntry ( RATING_KEY , ratingAttribute ) ;
2022-12-20 11:23:09 -05:00
std : : shared_ptr < Aws : : DynamoDB : : Model : : AttributeValue > plotAttribute = Aws : : MakeShared < Aws : : DynamoDB : : Model : : AttributeValue > (
2022-11-17 15:28:20 -05:00
ALLOCATION_TAG . c_str ( ) ) ;
2022-12-20 11:23:09 -05:00
plotAttribute - > SetS ( plots [ i ] ) ;
infoMapAttribute . AddMEntry ( PLOT_KEY , plotAttribute ) ;
2022-11-17 15:28:20 -05:00
attributes . push_back ( infoMapAttribute ) ;
statements [ i ] . SetParameters ( attributes ) ;
}
Aws : : DynamoDB : : Model : : BatchExecuteStatementRequest request ;
request . SetStatements ( statements ) ;
Aws : : DynamoDB : : Model : : BatchExecuteStatementOutcome outcome = dynamoClient . BatchExecuteStatement (
request ) ;
if ( ! outcome . IsSuccess ( ) ) {
std : : cerr < < " Failed to add the movies: " < < outcome . GetError ( ) . GetMessage ( )
< < std : : endl ;
return false ;
}
}
// snippet-end:[cpp.example_code.dynamodb.BatchExecuteStatement.Insert]
std : : cout < < " Retrieving the movie data with a batch \" SELECT \" statement. "
< < std : : endl ;
// snippet-start:[cpp.example_code.dynamodb.BatchExecuteStatement.Select]
// 3. Get the data for multiple movies using "Select" statements. (BatchExecuteStatement)
{
Aws : : Vector < Aws : : DynamoDB : : Model : : BatchStatementRequest > statements (
titles . size ( ) ) ;
std : : stringstream sqlStream ;
sqlStream < < " SELECT * FROM \" " < < MOVIE_TABLE_NAME < < " \" WHERE "
< < TITLE_KEY < < " =? and " < < YEAR_KEY < < " =? " ;
std : : string sql ( sqlStream . str ( ) ) ;
for ( size_t i = 0 ; i < statements . size ( ) ; + + i ) {
statements [ i ] . SetStatement ( sql ) ;
Aws : : Vector < Aws : : DynamoDB : : Model : : AttributeValue > attributes ;
attributes . push_back (
Aws : : DynamoDB : : Model : : AttributeValue ( ) . SetS ( titles [ i ] ) ) ;
attributes . push_back ( Aws : : DynamoDB : : Model : : AttributeValue ( ) . SetN ( years [ i ] ) ) ;
statements [ i ] . SetParameters ( attributes ) ;
}
Aws : : DynamoDB : : Model : : BatchExecuteStatementRequest request ;
request . SetStatements ( statements ) ;
Aws : : DynamoDB : : Model : : BatchExecuteStatementOutcome outcome = dynamoClient . BatchExecuteStatement (
request ) ;
if ( outcome . IsSuccess ( ) ) {
const Aws : : DynamoDB : : Model : : BatchExecuteStatementResult & result = outcome . GetResult ( ) ;
const Aws : : Vector < Aws : : DynamoDB : : Model : : BatchStatementResponse > & responses = result . GetResponses ( ) ;
for ( const Aws : : DynamoDB : : Model : : BatchStatementResponse & response : responses ) {
const Aws : : Map < Aws : : String , Aws : : DynamoDB : : Model : : AttributeValue > & item = response . GetItem ( ) ;
printMovieInfo ( item ) ;
}
}
else {
std : : cerr < < " Failed to retrieve the movie information: "
< < outcome . GetError ( ) . GetMessage ( ) < < std : : endl ;
return false ;
}
}
// snippet-end:[cpp.example_code.dynamodb.BatchExecuteStatement.Select]
// snippet-start:[cpp.example_code.dynamodb.BatchExecuteStatement.Update]
// 4. Update the data for multiple movies using "Update" statements. (BatchExecuteStatement)
for ( size_t i = 0 ; i < titles . size ( ) ; + + i ) {
ratings [ i ] = askQuestionForFloatRange (
Aws : : String ( " \n Let's update your the movie, \" " ) + titles [ i ] +
" . \n You rated it " + std : : to_string ( ratings [ i ] )
+ " , what new rating would you give it? " , 1 , 10 ) ;
}
std : : cout < < " Updating the movie with a batch \" UPDATE \" statement. " < < std : : endl ;
{
Aws : : Vector < Aws : : DynamoDB : : Model : : BatchStatementRequest > statements (
titles . size ( ) ) ;
std : : stringstream sqlStream ;
sqlStream < < " UPDATE \" " < < MOVIE_TABLE_NAME < < " \" SET "
< < INFO_KEY < < " . " < < RATING_KEY < < " =? WHERE "
< < TITLE_KEY < < " =? AND " < < YEAR_KEY < < " =? " ;
std : : string sql ( sqlStream . str ( ) ) ;
for ( size_t i = 0 ; i < statements . size ( ) ; + + i ) {
statements [ i ] . SetStatement ( sql ) ;
Aws : : Vector < Aws : : DynamoDB : : Model : : AttributeValue > attributes ;
attributes . push_back (
Aws : : DynamoDB : : Model : : AttributeValue ( ) . SetN ( ratings [ i ] ) ) ;
attributes . push_back (
Aws : : DynamoDB : : Model : : AttributeValue ( ) . SetS ( titles [ i ] ) ) ;
attributes . push_back ( Aws : : DynamoDB : : Model : : AttributeValue ( ) . SetN ( years [ i ] ) ) ;
statements [ i ] . SetParameters ( attributes ) ;
}
Aws : : DynamoDB : : Model : : BatchExecuteStatementRequest request ;
request . SetStatements ( statements ) ;
Aws : : DynamoDB : : Model : : BatchExecuteStatementOutcome outcome = dynamoClient . BatchExecuteStatement (
request ) ;
if ( ! outcome . IsSuccess ( ) ) {
std : : cerr < < " Failed to update movie information: "
< < outcome . GetError ( ) . GetMessage ( ) < < std : : endl ;
return false ;
}
}
// snippet-end:[cpp.example_code.dynamodb.BatchExecuteStatement.Update]
std : : cout < < " Retrieving the updated movie data with a batch \" SELECT \" statement. "
< < std : : endl ;
// 5. Get the updated data for multiple movies using "Select" statements. (BatchExecuteStatement)
{
Aws : : Vector < Aws : : DynamoDB : : Model : : BatchStatementRequest > statements (
titles . size ( ) ) ;
std : : stringstream sqlStream ;
sqlStream < < " SELECT * FROM \" " < < MOVIE_TABLE_NAME < < " \" WHERE "
< < TITLE_KEY < < " =? and " < < YEAR_KEY < < " =? " ;
std : : string sql ( sqlStream . str ( ) ) ;
for ( size_t i = 0 ; i < statements . size ( ) ; + + i ) {
statements [ i ] . SetStatement ( sql ) ;
Aws : : Vector < Aws : : DynamoDB : : Model : : AttributeValue > attributes ;
attributes . push_back (
Aws : : DynamoDB : : Model : : AttributeValue ( ) . SetS ( titles [ i ] ) ) ;
attributes . push_back ( Aws : : DynamoDB : : Model : : AttributeValue ( ) . SetN ( years [ i ] ) ) ;
statements [ i ] . SetParameters ( attributes ) ;
}
Aws : : DynamoDB : : Model : : BatchExecuteStatementRequest request ;
request . SetStatements ( statements ) ;
Aws : : DynamoDB : : Model : : BatchExecuteStatementOutcome outcome = dynamoClient . BatchExecuteStatement (
request ) ;
if ( outcome . IsSuccess ( ) ) {
const Aws : : DynamoDB : : Model : : BatchExecuteStatementResult & result = outcome . GetResult ( ) ;
const Aws : : Vector < Aws : : DynamoDB : : Model : : BatchStatementResponse > & responses = result . GetResponses ( ) ;
for ( const Aws : : DynamoDB : : Model : : BatchStatementResponse & response : responses ) {
const Aws : : Map < Aws : : String , Aws : : DynamoDB : : Model : : AttributeValue > & item = response . GetItem ( ) ;
printMovieInfo ( item ) ;
}
}
else {
std : : cerr < < " Failed to retrieve the movies information: "
< < outcome . GetError ( ) . GetMessage ( ) < < std : : endl ;
return false ;
}
}
std : : cout < < " Deleting the movie data with a batch \" DELETE \" statement. "
< < std : : endl ;
// snippet-start:[cpp.example_code.dynamodb.BatchExecuteStatement.Delete]
// 6. Delete multiple movies using "Delete" statements. (BatchExecuteStatement)
{
Aws : : Vector < Aws : : DynamoDB : : Model : : BatchStatementRequest > statements (
titles . size ( ) ) ;
std : : stringstream sqlStream ;
sqlStream < < " DELETE FROM \" " < < MOVIE_TABLE_NAME < < " \" WHERE "
< < TITLE_KEY < < " =? and " < < YEAR_KEY < < " =? " ;
std : : string sql ( sqlStream . str ( ) ) ;
for ( size_t i = 0 ; i < statements . size ( ) ; + + i ) {
statements [ i ] . SetStatement ( sql ) ;
Aws : : Vector < Aws : : DynamoDB : : Model : : AttributeValue > attributes ;
attributes . push_back (
Aws : : DynamoDB : : Model : : AttributeValue ( ) . SetS ( titles [ i ] ) ) ;
attributes . push_back ( Aws : : DynamoDB : : Model : : AttributeValue ( ) . SetN ( years [ i ] ) ) ;
statements [ i ] . SetParameters ( attributes ) ;
}
Aws : : DynamoDB : : Model : : BatchExecuteStatementRequest request ;
request . SetStatements ( statements ) ;
Aws : : DynamoDB : : Model : : BatchExecuteStatementOutcome outcome = dynamoClient . BatchExecuteStatement (
request ) ;
if ( ! outcome . IsSuccess ( ) ) {
std : : cerr < < " Failed to delete the movies: "
< < outcome . GetError ( ) . GetMessage ( ) < < std : : endl ;
return false ;
}
}
// snippet-end:[cpp.example_code.dynamodb.BatchExecuteStatement.Delete]
return true ;
}
// snippet-end:[cpp.example_code.dynamodb.Scenario_PartiQL_Batch]
# ifndef TESTING_BUILD
int main ( int argc , char * * argv ) {
( void ) argc ; // Suppress unused warning.
( void ) argv ; // Suppress unused warning.
Aws : : SDKOptions options ;
InitAPI ( options ) ;
{
std : : cout < < std : : setfill ( ' * ' )
2022-12-20 11:23:09 -05:00
< < std : : setw ( AwsDoc : : DynamoDB : : ASTERISK_FILL_WIDTH ) < < " "
2022-11-17 15:28:20 -05:00
< < std : : endl ;
std : : cout
< < " Welcome to the Amazon DynamoDB PartiQL batch statements demo. "
< < std : : endl ;
std : : cout < < std : : setfill ( ' * ' )
2022-12-20 11:23:09 -05:00
< < std : : setw ( AwsDoc : : DynamoDB : : ASTERISK_FILL_WIDTH ) < < " "
2022-11-17 15:28:20 -05:00
< < std : : endl ;
// snippet-start:[cpp.example_code.dynamodb.Scenario_PartiQL_Batch.main]
Aws : : Client : : ClientConfiguration clientConfig ;
// 1. Create a table. (CreateTable)
2022-12-20 11:23:09 -05:00
if ( AwsDoc : : DynamoDB : : createMoviesDynamoDBTable ( clientConfig ) ) {
2022-11-17 15:28:20 -05:00
AwsDoc : : DynamoDB : : partiqlBatchExecuteScenario ( clientConfig ) ;
// 7. Delete the table. (DeleteTable)
2022-12-20 11:23:09 -05:00
AwsDoc : : DynamoDB : : deleteMoviesDynamoDBTable ( clientConfig ) ;
2022-11-17 15:28:20 -05:00
}
// snippet-end:[cpp.example_code.dynamodb.Scenario_PartiQL_Batch.main]
}
return 0 ;
}
# endif // TESTING_BUILD