Adrian Witaszak
06/19/2024, 8:59 AMConditional Expressions
? Example below uses attribute_not_exists
. I noticed similar issue earlier when i worked on the update functionality and i was also not able to unit test it as usual.
override fun insert(evTrip: EvTrip, agreement: Agreement): Either<DeduplicationStoreError, Unit> = either {
val partitionKey = evTrip.contractId
val sortKey = evTrip.sortKey()
val ttl = evTrip.startTimestamp.plusDaysToMillis(TTL_DELAY_DAYS)
val record = DeduplicationRecord(evTrip, agreement, partitionKey, sortKey, ttl)
catch({
putItem(
TableName = tableName,
ConditionExpression = "attribute_not_exists($sortKeyAttr)",
Item = Item().with(lens of record),
)
}) { t -> raise(InsertEvTripFailed(evTrip.tripId, t.message)) }
}
and test
@Test
fun `insert existing evTrip and returns left`() {
sut().run {
insert(evTrip, agreement)
table[evTrip.contractId, evTrip.sortKey()] shouldNotBe null // Inserted
insert(evTrip, agreement) shouldBeLeft InsertEvTripFailed(evTrip.tripId, "") // Fails here as it was inserted it again
}
}
dave
06/19/2024, 9:18 AMAdrian Witaszak
06/19/2024, 10:05 AMAdrian Witaszak
06/19/2024, 11:40 AMConditionExpression = "attribute_not_exists(#key1)",
ExpressionAttributeNames = mapOf("#key1" to sortKeyAttr.name),
Andrew O'Hara
06/19/2024, 12:16 PMAdrian Witaszak
06/19/2024, 12:18 PMAndrew O'Hara
06/19/2024, 12:18 PMAndrew O'Hara
06/19/2024, 12:19 PMAdrian Witaszak
06/19/2024, 12:19 PMoverride fun insert(evTrip: EvTrip, agreement: Agreement): Either<DeduplicationStoreError, Unit> {
val partitionKey = evTrip.contractId
val sortKey = evTrip.sortKey()
val ttl = evTrip.startTimestamp.plusDaysToMillis(TTL_DELAY_DAYS)
val record = DeduplicationRecord(evTrip, agreement, partitionKey, sortKey, ttl)
return putItem(
TableName = tableName,
ConditionExpression = "attribute_not_exists(#key1)",
ExpressionAttributeNames = mapOf("#key1" to sortKeyAttr.name),
Item = Item().with(lens of record),
)
.toEither()
.mapLeft { e -> InsertEvTripFailed(evTrip.tripId, e.message) }
.map {} // throw away result
}
and the test:
@Test
fun `insert existing evTrip and returns left`() {
sut().run {
table[evTrip.contractId, evTrip.sortKey()] shouldBe null
insert(evTrip, agreement)
table[evTrip.contractId, evTrip.sortKey()] shouldNotBe null
insert(evTrip, agreement).shouldBeLeftOf<InsertEvTripFailed>()
}
}
Adrian Witaszak
06/19/2024, 12:19 PMAndrew O'Hara
06/19/2024, 12:20 PMAdrian Witaszak
06/19/2024, 12:21 PMAdrian Witaszak
06/19/2024, 12:22 PMConditionExpression
makes test to fail so it is neededAdrian Witaszak
06/19/2024, 12:22 PMAndrew O'Hara
06/19/2024, 12:23 PMAndrew O'Hara
06/19/2024, 12:23 PMAdrian Witaszak
06/19/2024, 12:24 PMAndrew O'Hara
06/19/2024, 12:25 PMAdrian Witaszak
06/19/2024, 12:26 PMConditionExpression = "attribute_not_exists",
worksAndrew O'Hara
06/19/2024, 12:27 PMAndrew O'Hara
06/19/2024, 12:28 PMAdrian Witaszak
06/19/2024, 12:28 PM"attribute_not_exists($sortKeyAttr)"
Andrew O'Hara
06/19/2024, 12:29 PMAdrian Witaszak
06/19/2024, 12:30 PMAdrian Witaszak
06/19/2024, 12:41 PMAdrian Witaszak
06/21/2024, 8:36 AMattribute_not_exists
on its own...
{
"__type": "com.amazon.coral.validate#ValidationException",
"message": "Invalid ConditionExpression: Syntax error; token: \"<EOF>\", near: \"attribute_not_exists\""
}
so ended up adding the sortKey back attribute_not_exists($sortKeyAttr)