Skip to content

Commit 67d8df8

Browse files
irina-herciudscpinheiro
authored andcommitted
use PutItem operation for key only entities
Update TransactWrite.cs use putItem operation for key only entities
1 parent c94a5d3 commit 67d8df8

File tree

3 files changed

+151
-5
lines changed

3 files changed

+151
-5
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"services": [
3+
{
4+
"serviceName": "DynamoDBv2",
5+
"type": "patch",
6+
"changeLogMessages": [
7+
"Fixed issue with TransactWrite in the DataModel where it wasn't correctly handling cases where only keys were being saved."
8+
]
9+
}
10+
]
11+
}

sdk/src/Services/DynamoDBv2/Custom/DataModel/TransactWrite.cs

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
using System;
1717
using System.Collections.Generic;
1818
using System.Globalization;
19+
using System.Linq;
1920
#if AWS_ASYNC_API
2021
using System.Threading;
2122
using System.Threading.Tasks;
@@ -134,11 +135,8 @@ public void AddSaveItem(T item)
134135
Expression conditionExpression = CreateConditionExpressionForVersion(storage);
135136
SetNewVersion(storage);
136137

137-
DocumentTransaction.AddDocumentToUpdate(storage.Document, new TransactWriteItemOperationConfig
138-
{
139-
ConditionalExpression = conditionExpression,
140-
ReturnValuesOnConditionCheckFailure = DocumentModel.ReturnValuesOnConditionCheckFailure.None
141-
});
138+
AddDocumentTransaction(storage, conditionExpression);
139+
142140
var objectItem = new DynamoDBContext.ObjectWithItemStorage
143141
{
144142
OriginalObject = item,
@@ -437,6 +435,45 @@ private Expression CreateConditionExpressionForVersion(ItemStorage storage)
437435
DocumentTransaction.TargetTable.IsEmptyStringValueEnabled);
438436
return DynamoDBContext.CreateConditionExpressionForVersion(storage, conversionConfig);
439437
}
438+
439+
440+
private void AddDocumentTransaction(ItemStorage storage, Expression conditionExpression)
441+
{
442+
var hashKeyPropertyNames = storage.Config.HashKeyPropertyNames;
443+
var rangeKeyPropertyNames = storage.Config.RangeKeyPropertyNames;
444+
445+
var attributeNames = storage.Document.Keys.ToList();
446+
447+
foreach (var keyPropertyName in hashKeyPropertyNames)
448+
{
449+
attributeNames.Remove(keyPropertyName);
450+
}
451+
452+
foreach (var rangeKeyPropertyName in rangeKeyPropertyNames)
453+
{
454+
attributeNames.Remove(rangeKeyPropertyName);
455+
}
456+
457+
// If there are no attributes left, we need to use PutItem
458+
// as UpdateItem requires at least one data attribute
459+
if (attributeNames.Any())
460+
{
461+
DocumentTransaction.AddDocumentToUpdate(storage.Document, new TransactWriteItemOperationConfig
462+
{
463+
ConditionalExpression = conditionExpression,
464+
ReturnValuesOnConditionCheckFailure = DocumentModel.ReturnValuesOnConditionCheckFailure.None
465+
});
466+
}
467+
else
468+
{
469+
470+
DocumentTransaction.AddDocumentToPut(storage.Document, new TransactWriteItemOperationConfig
471+
{
472+
ConditionalExpression = conditionExpression,
473+
ReturnValuesOnConditionCheckFailure = DocumentModel.ReturnValuesOnConditionCheckFailure.None
474+
});
475+
}
476+
}
440477

441478
private void SetNewVersion(ItemStorage storage)
442479
{

sdk/test/Services/DynamoDBv2/IntegrationTests/DataModelTests.cs

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,76 @@ public void TestContext_DisableFetchingTableMetadata_KeyWithPropertyConverter()
183183
Assert.AreEqual(employee.Name, storedEmployee.Name);
184184
}
185185

186+
187+
/// <summary>
188+
/// Tests that disabling fetching table metadata works with a key that has a property converter.
189+
/// </summary>
190+
[TestMethod]
191+
[TestCategory("DynamoDBv2")]
192+
public void TestTransactWrite_AddSaveItem_DocumentTransaction()
193+
{
194+
TableCache.Clear();
195+
CleanupTables();
196+
TableCache.Clear();
197+
198+
CreateContext(DynamoDBEntryConversion.V2, true, true);
199+
200+
{
201+
202+
var hashRangeOnly = new AnnotatedRangeTable
203+
{
204+
Name = "Bob",
205+
Age = 10
206+
};
207+
208+
var transactWrite = Context.CreateTransactWrite<AnnotatedRangeTable>();
209+
transactWrite.AddSaveItem(hashRangeOnly);
210+
transactWrite.Execute();
211+
212+
var storedHashOnly = Context.Load<AnnotatedRangeTable>(hashRangeOnly.Name, hashRangeOnly.Age);
213+
Assert.IsNotNull(storedHashOnly);
214+
Assert.AreEqual(hashRangeOnly.Name, storedHashOnly.Name);
215+
}
216+
217+
{
218+
var hashRangeOnly = new IgnoreAnnotatedRangeTable
219+
{
220+
Name = "Bob",
221+
Age = 10,
222+
IgnoreAttribute = 100
223+
};
224+
225+
var transactWrite = Context.CreateTransactWrite<IgnoreAnnotatedRangeTable>();
226+
transactWrite.AddSaveItem(hashRangeOnly);
227+
transactWrite.Execute();
228+
229+
var storedHashOnly = Context.Load<IgnoreAnnotatedRangeTable>(hashRangeOnly.Name, hashRangeOnly.Age);
230+
Assert.IsNotNull(storedHashOnly);
231+
Assert.AreEqual(hashRangeOnly.Name, storedHashOnly.Name);
232+
Assert.AreEqual(hashRangeOnly.Age, storedHashOnly.Age);
233+
}
234+
235+
{
236+
var hashRangeOnly = new AnnotatedRangeTable2
237+
{
238+
Name = "Bob",
239+
Age = 10,
240+
NotAnnotatedAttribute = 100
241+
};
242+
243+
var transactWrite = Context.CreateTransactWrite<AnnotatedRangeTable2>();
244+
transactWrite.AddSaveItem(hashRangeOnly);
245+
transactWrite.Execute();
246+
247+
var storedHashOnly = Context.Load<AnnotatedRangeTable2>(hashRangeOnly.Name, hashRangeOnly.Age);
248+
Assert.IsNotNull(storedHashOnly);
249+
Assert.AreEqual(hashRangeOnly.Name, storedHashOnly.Name);
250+
Assert.AreEqual(hashRangeOnly.Age, storedHashOnly.Age);
251+
Assert.AreEqual(hashRangeOnly.NotAnnotatedAttribute, storedHashOnly.NotAnnotatedAttribute);
252+
}
253+
254+
}
255+
186256
/// <summary>
187257
/// Tests that the DynamoDB operations can retrieve <see cref="DateTime"/> attributes in UTC and local timezone.
188258
/// </summary>
@@ -2039,6 +2109,34 @@ public class PropertyConverterEmployee
20392109
public Status Name { get; set; }
20402110
}
20412111

2112+
[DynamoDBTable("HashRangeTable")]
2113+
public class AnnotatedRangeTable
2114+
{
2115+
// Hash key
2116+
[DynamoDBHashKey]
2117+
public string Name { get; set; }
2118+
2119+
// Range key
2120+
[DynamoDBRangeKey]
2121+
internal int Age { get; set; }
2122+
}
2123+
2124+
[DynamoDBTable("HashRangeTable")]
2125+
public class IgnoreAnnotatedRangeTable : AnnotatedRangeTable
2126+
{
2127+
[DynamoDBIgnore]
2128+
internal int IgnoreAttribute { get; set; }
2129+
}
2130+
2131+
2132+
[DynamoDBTable("HashRangeTable")]
2133+
public class AnnotatedRangeTable2 : AnnotatedRangeTable
2134+
{
2135+
internal int NotAnnotatedAttribute { get; set; }
2136+
}
2137+
2138+
2139+
20422140
public class DateTimeUtcConverter : IPropertyConverter
20432141
{
20442142
public DynamoDBEntry ToEntry(object value) => (DateTime)value;

0 commit comments

Comments
 (0)