static async Task UpdateAsync( IAmazonDynamoDB client, string tableName, Guid ownerId, Guid scoreId, int[] removeIndices, string newHash, string oldHash, DateTimeOffset now ) { var partitionKey = ScoreDatabaseUtils.ConvertToPartitionKey(ownerId); var score = ScoreDatabaseUtils.ConvertToBase64(scoreId); var updateAt = ScoreDatabaseUtils.ConvertToUnixTimeMilli(now); var request = new UpdateItemRequest() { Key = new Dictionary <string, AttributeValue>() { [DynamoDbScorePropertyNames.PartitionKey] = new AttributeValue(partitionKey), [DynamoDbScorePropertyNames.SortKey] = new AttributeValue(ScoreDatabaseConstant.ScoreIdMainPrefix + score), }, ExpressionAttributeNames = new Dictionary <string, string>() { ["#updateAt"] = DynamoDbScorePropertyNames.UpdateAt, ["#hash"] = DynamoDbScorePropertyNames.DataHash, ["#data"] = DynamoDbScorePropertyNames.Data, ["#pages"] = DynamoDbScorePropertyNames.DataPropertyNames.Pages, }, ExpressionAttributeValues = new Dictionary <string, AttributeValue>() { [":newHash"] = new AttributeValue(newHash), [":oldHash"] = new AttributeValue(oldHash), [":updateAt"] = new AttributeValue(updateAt), }, ConditionExpression = "#hash = :oldHash", UpdateExpression = $"SET #updateAt = :updateAt, #hash = :newHash REMOVE {string.Join(", ", removeIndices.Select(i=>$"#data.#pages[{i}]"))}", TableName = tableName, }; try { await client.UpdateItemAsync(request); } catch (Exception ex) { Console.WriteLine(ex.Message); throw; } }
CreateDynamoDbValue(ScoreItemDatabaseItemDataBase itemData, DateTimeOffset now) { var items = new Dictionary <string, AttributeValue>(); var partitionKey = ScoreItemDatabaseUtils.ConvertToPartitionKey(itemData.OwnerId); var score = ScoreDatabaseUtils.ConvertToBase64(itemData.ScoreId); var item = ScoreDatabaseUtils.ConvertToBase64(itemData.ItemId); var at = ScoreDatabaseUtils.ConvertToUnixTimeMilli(now); items[ScoreItemDatabasePropertyNames.OwnerId] = new AttributeValue(partitionKey); items[ScoreItemDatabasePropertyNames.ItemId] = new AttributeValue(score + item); items[ScoreItemDatabasePropertyNames.ObjName] = new AttributeValue(itemData.ObjName); items[ScoreItemDatabasePropertyNames.Size] = new AttributeValue { N = itemData.Size.ToString() }; items[ScoreItemDatabasePropertyNames.At] = new AttributeValue(at); var totalSize = itemData.Size; if (itemData is ScoreItemDatabaseItemDataImage itemDataImage) { items[ScoreItemDatabasePropertyNames.Type] = new AttributeValue(ScoreItemDatabaseConstant.TypeImage); items[ScoreItemDatabasePropertyNames.OrgName] = new AttributeValue(itemDataImage.OrgName); items[ScoreItemDatabasePropertyNames.Thumbnail] = new AttributeValue { M = new Dictionary <string, AttributeValue> { [ScoreItemDatabasePropertyNames.ThumbnailPropertyNames.ObjName] = new AttributeValue(itemDataImage.Thumbnail.ObjName), [ScoreItemDatabasePropertyNames.ThumbnailPropertyNames.Size] = new AttributeValue { N = itemDataImage.Thumbnail.Size.ToString() } } }; totalSize += itemDataImage.Thumbnail.Size; } items[ScoreItemDatabasePropertyNames.TotalSize] = new AttributeValue { N = totalSize.ToString() }; return(items, partitionKey, score, item, totalSize); }
static async Task UpdateAsync( IAmazonDynamoDB client, string tableName, Guid ownerId, Guid scoreId, Guid snapshotId, string snapshotName, DateTimeOffset now, int maxSnapshotCount ) { var partitionKey = ScoreDatabaseUtils.ConvertToPartitionKey(ownerId); var score = ScoreDatabaseUtils.ConvertToBase64(scoreId); var snapshot = ScoreDatabaseUtils.ConvertToBase64(snapshotId); var at = ScoreDatabaseUtils.ConvertToUnixTimeMilli(now); var actions = new List <TransactWriteItem>() { new TransactWriteItem() { Update = new Update() { TableName = tableName, Key = new Dictionary <string, AttributeValue>() { [DynamoDbScorePropertyNames.PartitionKey] = new AttributeValue(partitionKey), [DynamoDbScorePropertyNames.SortKey] = new AttributeValue(ScoreDatabaseConstant.ScoreIdMainPrefix + score), }, ExpressionAttributeNames = new Dictionary <string, string>() { ["#snapshotCount"] = DynamoDbScorePropertyNames.SnapshotCount, }, ExpressionAttributeValues = new Dictionary <string, AttributeValue>() { [":increment"] = new AttributeValue() { N = "1" }, [":countMax"] = new AttributeValue() { N = maxSnapshotCount.ToString(), }, }, ConditionExpression = "#snapshotCount < :countMax", UpdateExpression = "ADD #snapshotCount :increment" } }, new TransactWriteItem() { Put = new Put() { TableName = tableName, Item = new Dictionary <string, AttributeValue>() { [DynamoDbScorePropertyNames.PartitionKey] = new AttributeValue(partitionKey), [DynamoDbScorePropertyNames.SortKey] = new AttributeValue(ScoreDatabaseConstant.ScoreIdSnapPrefix + score + snapshot), [DynamoDbScorePropertyNames.CreateAt] = new AttributeValue(at), [DynamoDbScorePropertyNames.UpdateAt] = new AttributeValue(at), [DynamoDbScorePropertyNames.SnapshotName] = new AttributeValue(snapshotName), }, ExpressionAttributeNames = new Dictionary <string, string>() { ["#score"] = DynamoDbScorePropertyNames.SortKey, }, ConditionExpression = "attribute_not_exists(#score)", } } }; try { await client.TransactWriteItemsAsync(new TransactWriteItemsRequest() { TransactItems = actions, ReturnConsumedCapacity = ReturnConsumedCapacity.TOTAL }); } catch (TransactionCanceledException ex) { var updateReason = ex.CancellationReasons[0]; if (updateReason.Code == "ConditionalCheckFailed") { throw new CreatedSnapshotException(CreatedSnapshotExceptionCodes.ExceededUpperLimit, ex); } throw; } catch (Exception ex) { Console.WriteLine(ex.Message); throw; } }