tables transactions samples (#5496)

* transactions samples

* cleanup sample, update readme
This commit is contained in:
George Arama 2024-04-08 12:28:04 -07:00 committed by GitHub
parent da1513977a
commit abeb4e797b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 261 additions and 14 deletions

View File

@ -53,13 +53,13 @@ Two different clients are provided to interact with the various components of th
1. **`TableClient`** -
* Interacts with a specific table (which need not exist yet).
* Create, delete, query, and upsert entities within the specified table.
* Create or delete the specified table itself.
* Submit transactional batch operations.
2. **`TableServiceClient`** -
* Get and set account settings
* Query tables within the account.
* Create or delete the specified table.
### Entities
Entities are similar to rows. An entity has a **`PartitionKey`**, a **`RowKey`**, and a set of properties. A property is a name value pair, similar to a column. Every entity in a table does not need to have the same properties.
Entities are similar to rows. An entity has a set of properties, including a **`PartitionKey`** and **`RowKey`** which form the primary key of the entity. A property is a name value pair, similar to a column. Every entity in a table does not need to have the same properties.
## Examples
@ -68,7 +68,8 @@ The following sections provide several code snippets covering some of the most c
* [Creating and deleting a table](#creating-and-deleting-a-table "Creating and deleting a table")
* [Manipulating entities](#manipulating-entities "Manipulating entities")
* [Table Service Operations](#table-service-operations "Table Service Operations")
* [Table Transactions Success](#table-transactions-success "Table Transactions Success")
* [Table Transactions Error](#table-transactions-error "Table Transactions Error")
### Creating and deleting a table
In order to Create/Delete a table we need to create a TablesClient first.
@ -79,13 +80,16 @@ In order to Create/Delete a table we need to create a TablesClient first.
using namespace Azure::Data::Tables;
const std::string TableName = "sample1";
...
auto tableClient = TableClient::CreateFromConnectionString(..., TableName);
tableClient.Create();
auto tableServiceClient = TableServiceClient::CreateFromConnectionString(GetConnectionString());
// create new table
tableServiceClient.CreateTable(TableName);
```
In order to Delete a table we need to call the delete method on the previously created client.
```cpp
tableClient.Delete();
// delete existing table
tableServiceClient.DeleteTable(TableName);
```
### Manipulating entities
@ -99,22 +103,22 @@ using namespace Azure::Data::Tables;
const std::string TableName = "sample1";
...
auto tableClient = TableClient::CreateFromConnectionString(..., TableName);
tableClient.Create();
tableServiceClient.CreateTable(TableName);
```
Then we initialize and populate an entity.
```cpp
// init new entity
Models::TableEntity entity;
entity.PartitionKey = "P1";
entity.RowKey = "R1";
entity.Properties["Name"] = "Azure";
entity.Properties["Product"] = "Tables";
entity.SetPartitionKey("P1");
entity.SetRowKey("R1");
entity.Properties["Name"] = TableEntityProperty("Azure");
entity.Properties["Product"] = TableEntityProperty("Tables");
```
To create the entity on the server we call the CreateEntity method on the table client.
```cpp
tableClient.CreateEntity(entity);
tableClient.AddEntity(entity);
```
To update the entity, assume we made some changes to the entity, we call the UpdateEntity method on the table client.
@ -159,6 +163,92 @@ To get the statistics of the account we call the GetStatistics method on the tab
auto statistics = tableServiceClient.GetStatistics();
```
### Table Transactions Success
In order to get the service properties we need to create a TableServiceClient first.
```cpp
#include <azure/data/tables.hpp>
...
using namespace Azure::Data::Tables;
...
auto tableServiceClient = TableServiceClient::CreateFromConnectionString(...);
```
We create a table on which we run the transaction and get a table client.
```cpp
// create table
tableServiceClient.CreateTable(TableName);
// get table client from table service client
auto tableClient = tableServiceClient.GetTableClient(TableName);
```
N.B. Here we are obtaining the table client from the table service client using the credentials that were passed to the table service client.
We initialize and populate the entities.
```cpp
Models::TableEntity entity1;
entity1.PartitionKey = "P1";
entity1.RowKey = "R1";
entity1.Properties["Name"] = "Azure";
entity1.Properties["Product"] = "Tables";
Models::TableEntity entity2;
entity2.PartitionKey = "P2";
entity2.RowKey = "R2";
entity2.Properties["Name"] = "Azure";
entity2.Properties["Product"] = "Tables";
```
We create a transaction batch and add the operations to the transaction.
```cpp
// Create a transaction with two steps
std::vector<TransactionStep> steps;
steps.emplace_back(TransactionStep{TransactionActionType::Add, entity});
steps.emplace_back(TransactionStep{TransactionActionType::Add, entity2});
```
We then submit the transaction and check the response.
```cpp
// Check the response
if (!response.Value.Error.HasValue())
{
std::cout << "Transaction completed successfully." << std::endl;
}
else
{
std::cout << "Transaction failed with error: " << response.Value.Error.Value().Message
<< std::endl;
}
```
The output of this sample is:
```text
Transaction completed successfully.
```
### Table Transactions Error
The difference from the previous example is that we are trying to add two entities with the same PartitionKey and RowKey.
```cpp
// Create two table entities
TableEntity entity;
TableEntity entity2;
entity.SetPartitionKey("P1");
entity.SetRowKey("R1");
...
entity2.SetPartitionKey("P1");
entity2.SetRowKey("R1");
...
```
The rest of the steps are the same as in the previous example.
The output of the sample contains the error message:
```text
Transaction failed with error: 1:The batch request contains multiple changes with same row key. An entity can appear only once in a batch request.
```
## Contributing
See the [C++ Contributing Guide][sdk_contrib] for details on building,

View File

@ -18,3 +18,11 @@ create_per_service_target_build_for_sample(tables tables_entity_operations)
add_executable(tables_service_operations tables_service_operations.cpp)
target_link_libraries(tables_service_operations PRIVATE azure-data-tables get-env-helper)
create_per_service_target_build_for_sample(tables tables_service_operations)
add_executable(tables_transactions_ok tables_transactions_ok.cpp)
target_link_libraries(tables_transactions_ok PRIVATE azure-data-tables get-env-helper)
create_per_service_target_build_for_sample(tables tables_transactions_ok)
add_executable(tables_transactions_fail tables_transactions_fail.cpp)
target_link_libraries(tables_transactions_fail PRIVATE azure-data-tables get-env-helper)
create_per_service_target_build_for_sample(tables tables_transactions_fail)

View File

@ -14,3 +14,5 @@ description: Samples for the azure-data-tables client library.
- Create,list and delete tables.
- Create, merge, update, delete entities.
- List Tables, Get Statistics, Get Access Policy for service.
- Submit Transactions success
- Submit Transactions failure

View File

@ -30,7 +30,6 @@ const std::string TableName = "sample1";
int main()
{
auto tableServiceClient = TableServiceClient::CreateFromConnectionString(GetConnectionString());
auto tableClient = TableClient::CreateFromConnectionString(GetConnectionString(), TableName);
// create new table
tableServiceClient.CreateTable(TableName);

View File

@ -0,0 +1,74 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#include <azure/data/tables.hpp>
#include <cstdio>
#include <iostream>
#include <stdexcept>
#include <thread>
using namespace Azure::Data::Tables;
using namespace Azure::Data::Tables::Models;
const std::string TableName = "transactions2";
std::string GetConnectionString()
{
const static std::string ConnectionString = "";
if (!ConnectionString.empty())
{
return ConnectionString;
}
const static std::string envConnectionString = std::getenv("STANDARD_STORAGE_CONNECTION_STRING");
if (!envConnectionString.empty())
{
return envConnectionString;
}
throw std::runtime_error("Cannot find connection string.");
}
int main()
{
// Get the service client
auto tableServiceClient = TableServiceClient::CreateFromConnectionString(GetConnectionString());
// create table
tableServiceClient.CreateTable(TableName);
// get table client from table service client
auto tableClient = tableServiceClient.GetTableClient(TableName);
// Create two table entities
TableEntity entity;
TableEntity entity2;
entity.SetPartitionKey("P1");
entity.SetRowKey("R1");
entity.Properties["Name"] = TableEntityProperty("Azure");
entity.Properties["Product"] = TableEntityProperty("Tables");
entity2.SetPartitionKey("P1");
entity2.SetRowKey("R1");
entity2.Properties["Name"] = TableEntityProperty("Azure2");
entity2.Properties["Product"] = TableEntityProperty("Tables2");
// Create a transaction with two steps
std::vector<TransactionStep> steps;
steps.emplace_back(TransactionStep{TransactionActionType::Add, entity});
steps.emplace_back(TransactionStep{TransactionActionType::Add, entity2});
// Submit the transaction
auto response = tableClient.SubmitTransaction(steps);
// Check the response
if (!response.Value.Error.HasValue())
{
std::cout << "Transaction completed successfully." << std::endl;
}
else
{
std::cout << "Transaction failed with error: " << response.Value.Error.Value().Message
<< std::endl;
}
// delete existing table
tableServiceClient.DeleteTable(TableName);
return 0;
}

View File

@ -0,0 +1,74 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#include <azure/data/tables.hpp>
#include <cstdio>
#include <iostream>
#include <stdexcept>
#include <thread>
using namespace Azure::Data::Tables;
using namespace Azure::Data::Tables::Models;
const std::string TableName = "transactions";
std::string GetConnectionString()
{
const static std::string ConnectionString = "";
if (!ConnectionString.empty())
{
return ConnectionString;
}
const static std::string envConnectionString = std::getenv("STANDARD_STORAGE_CONNECTION_STRING");
if (!envConnectionString.empty())
{
return envConnectionString;
}
throw std::runtime_error("Cannot find connection string.");
}
int main()
{
// Get the service client
auto tableServiceClient = TableServiceClient::CreateFromConnectionString(GetConnectionString());
// create table
tableServiceClient.CreateTable(TableName);
// get table client from table service client
auto tableClient = tableServiceClient.GetTableClient(TableName);
// Create two table entities
TableEntity entity;
TableEntity entity2;
entity.SetPartitionKey("P1");
entity.SetRowKey("R1");
entity.Properties["Name"] = TableEntityProperty("Azure");
entity.Properties["Product"] = TableEntityProperty("Tables");
entity2.SetPartitionKey("P1");
entity2.SetRowKey("R2");
entity2.Properties["Name"] = TableEntityProperty("Azure2");
entity2.Properties["Product"] = TableEntityProperty("Tables2");
// Create a transaction with two steps
std::vector<TransactionStep> steps;
steps.emplace_back(TransactionStep{TransactionActionType::Add, entity});
steps.emplace_back(TransactionStep{TransactionActionType::Add, entity2});
// Submit the transaction
auto response = tableClient.SubmitTransaction(steps);
// Check the response
if (!response.Value.Error.HasValue())
{
std::cout << "Transaction completed successfully." << std::endl;
}
else
{
std::cout << "Transaction failed with error: " << response.Value.Error.Value().Message
<< std::endl;
}
// delete existing table
tableServiceClient.DeleteTable(TableName);
return 0;
}