diff --git a/sdk/tables/assets.json b/sdk/tables/assets.json index d2c3b4fe9..8d744db5e 100644 --- a/sdk/tables/assets.json +++ b/sdk/tables/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "cpp", "TagPrefix": "cpp/tables", - "Tag": "cpp/tables_7a2150038f" + "Tag": "cpp/tables_cb42be8953" } diff --git a/sdk/tables/azure-data-tables/inc/azure/data/tables/tables_clients.hpp b/sdk/tables/azure-data-tables/inc/azure/data/tables/tables_clients.hpp index 150b3751a..518c77059 100644 --- a/sdk/tables/azure-data-tables/inc/azure/data/tables/tables_clients.hpp +++ b/sdk/tables/azure-data-tables/inc/azure/data/tables/tables_clients.hpp @@ -376,6 +376,7 @@ namespace Azure { namespace Data { namespace Tables { std::string PrepDeleteEntity(std::string const& changesetId, Models::TableEntity entity); std::string PrepMergeEntity(std::string const& changesetId, Models::TableEntity entity); std::string PrepUpdateEntity(std::string const& changesetId, Models::TableEntity entity); + std::string PrepInsertEntity(std::string const& changesetId, Models::TableEntity entity); std::shared_ptr m_pipeline; Core::Url m_url; std::string m_tableName; diff --git a/sdk/tables/azure-data-tables/src/tables_clients.cpp b/sdk/tables/azure-data-tables/src/tables_clients.cpp index d9251cd9d..8b2b905f8 100644 --- a/sdk/tables/azure-data-tables/src/tables_clients.cpp +++ b/sdk/tables/azure-data-tables/src/tables_clients.cpp @@ -1017,6 +1017,8 @@ std::string TableClient::PreparePayload( accumulator += PrepMergeEntity(changesetId, step.Entity); break; case Models::TransactionActionType::InsertReplace: + accumulator += PrepInsertEntity(changesetId, step.Entity); + break; case Models::TransactionActionType::UpdateReplace: accumulator += PrepUpdateEntity(changesetId, step.Entity); break; @@ -1111,3 +1113,32 @@ std::string TableClient::PrepUpdateEntity( returnValue += Serializers::UpdateEntity(entity); return returnValue; } + +std::string TableClient::PrepInsertEntity( + std::string const& changesetId, + Models::TableEntity entity) +{ + std::string payload = Serializers::UpdateEntity(entity); + std::string returnValue = "--" + changesetId + "\n"; + returnValue += "Content-Type: application/http\n"; + returnValue += "Content-Transfer-Encoding: binary\n\n"; + + returnValue += "PATCH " + m_url.GetAbsoluteUrl() + "/" + m_tableName + PartitionKeyFragment + + entity.GetPartitionKey().Value + RowKeyFragment + entity.GetRowKey().Value + ClosingFragment + + " HTTP/1.1\n"; + returnValue += "Content-Type: application/json\n"; + returnValue += "Content-Length: " + std::to_string(payload.length()); + returnValue += "Accept: application/json;odata=minimalmetadata\n"; + returnValue += "Prefer: return-no-content\n"; + returnValue += "DataServiceVersion: 3.0;\n"; + if (!entity.GetETag().Value.empty()) + { + returnValue += "If-Match: " + entity.GetETag().Value; + } + else + { + returnValue += "If-Match: *"; + } + returnValue += "\n\n"; + return returnValue; +} diff --git a/sdk/tables/azure-data-tables/test/ut/table_client_test.cpp b/sdk/tables/azure-data-tables/test/ut/table_client_test.cpp index a91f7e0f5..917b71454 100644 --- a/sdk/tables/azure-data-tables/test/ut/table_client_test.cpp +++ b/sdk/tables/azure-data-tables/test/ut/table_client_test.cpp @@ -723,6 +723,40 @@ namespace Azure { namespace Data { namespace Test { EXPECT_FALSE(response.Value.Error.HasValue()); } + TEST_P(TablesClientTest, TransactionInsertReplace) + { + if (GetParam() != AuthType::ConnectionString) + { + SkipTest(); + return; + } + + Azure::Data::Tables::Models::TableEntity entity; + Azure::Data::Tables::Models::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("Tables3"); + auto createResponse = m_tableServiceClient->CreateTable(m_tableName); + std::vector steps; + + steps.emplace_back(Azure::Data::Tables::Models::TransactionStep{ + Azure::Data::Tables::Models::TransactionActionType::InsertReplace, entity}); + auto response = m_tableClient->SubmitTransaction(steps); + + steps.clear(); + // replace entity + steps.emplace_back(Azure::Data::Tables::Models::TransactionStep{ + Azure::Data::Tables::Models::TransactionActionType::InsertReplace, entity2}); + response = m_tableClient->SubmitTransaction(steps); + + EXPECT_FALSE(response.Value.Error.HasValue()); + } + namespace { static std::string GetSuffix(const testing::TestParamInfo& info) { diff --git a/sdk/tables/azure-data-tables/test/ut/transactions_test.cpp b/sdk/tables/azure-data-tables/test/ut/transactions_test.cpp index 67ec368c7..e787dbe41 100644 --- a/sdk/tables/azure-data-tables/test/ut/transactions_test.cpp +++ b/sdk/tables/azure-data-tables/test/ut/transactions_test.cpp @@ -149,7 +149,7 @@ namespace Azure { namespace Data { namespace Test { case Models::TransactionActionType::InsertReplace: EXPECT_EQ( lines[4], - "PUT " + url + "/" + tableName + "(PartitionKey='" + partitionKey + "',RowKey='" + "PATCH " + url + "/" + tableName + "(PartitionKey='" + partitionKey + "',RowKey='" + rowKey + "') HTTP/1.1"); break; }