/* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ using System; using System.Collections; using System.Collections.Generic; using System.Reflection; using Amazon.DynamoDBv2.Model; using Amazon.DynamoDBv2.DocumentModel; using System.Globalization; #if AWS_ASYNC_API using System.Threading.Tasks; #endif using System.Threading; namespace Amazon.DynamoDBv2.DataModel { /// /// Represents a non-generic object for writing/deleting a batch of items /// in a single DynamoDB table /// public abstract partial class BatchWrite { #region Internal/protected properties internal DynamoDBContext Context { get; set; } internal DynamoDBFlatConfig Config { get; set; } internal DocumentBatchWrite DocumentBatch { get; set; } #endregion #region Constructor internal BatchWrite(DynamoDBContext context, DynamoDBFlatConfig config) { Context = context; Config = config; } #endregion #region Protected methods /// /// Executes a server call to batch-write/delete the items requested. /// internal protected abstract void ExecuteHelper(); #if AWS_ASYNC_API /// /// Executes an asynchronous server call to batch-write/delete the items requested. /// internal protected abstract Task ExecuteHelperAsync(CancellationToken cancellationToken); #endif #endregion } /// /// Represents a strongly-typed object for writing/deleting a batch of items /// in a single DynamoDB table /// public class BatchWrite : BatchWrite { #region Public combine methods /// /// Creates a MultiTableBatchWrite object that is a combination /// of the current BatchWrite and the specified BatchWrites /// /// Other BatchWrite objects /// /// MultiTableBatchWrite consisting of the multiple BatchWrite objects: /// the current batch and the passed-in batches. /// public MultiTableBatchWrite Combine(params BatchWrite[] otherBatches) { return new MultiTableBatchWrite(this, otherBatches); } #endregion #region Public Put methods /// /// Add a number of items to be put in the current batch operation /// /// Items to put public void AddPutItems(IEnumerable values) { if (values == null) return; foreach (T item in values) { AddPutItem(item); } } /// /// Add a single item to be put in the current batch operation /// /// public void AddPutItem(T item) { if (item == null) return; ItemStorage storage = Context.ObjectToItemStorageHelper(item, StorageConfig, Config, keysOnly: false, ignoreNullValues: true); if (storage == null) return; DocumentBatch.AddDocumentToPut(storage.Document); } #endregion #region Public Delete methods /// /// Add a number of items to be deleted in the current batch operation /// /// Items to be deleted public void AddDeleteItems(IEnumerable values) { if (values == null) return; foreach (T item in values) { AddDeleteItem(item); } } /// /// Add a single item to be deleted in the current batch operation. /// /// Item to be deleted public void AddDeleteItem(T item) { if (item == null) return; ItemStorage storage = Context.ObjectToItemStorageHelper(item, StorageConfig, Config, keysOnly: true, ignoreNullValues: true); if (storage == null) return; DocumentBatch.AddItemToDelete(storage.Document); } /// /// Add a single item to be deleted in the current batch operation. /// Item is identified by its hash primary key. /// /// Hash key of the item to delete public void AddDeleteKey(object hashKey) { AddDeleteKey(hashKey, null); } /// /// Add a single item to be deleted in the current batch operation. /// Item is identified by its hash-and-range primary key. /// /// Hash key of the item to delete /// Range key of the item to delete public void AddDeleteKey(object hashKey, object rangeKey) { DocumentBatch.AddKeyToDelete(Context.MakeKey(hashKey, rangeKey, StorageConfig, Config)); } #endregion #region Constructor internal BatchWrite(DynamoDBContext context, DynamoDBFlatConfig config) : this(context, typeof(T), config) { } internal BatchWrite(DynamoDBContext context, Type valuesType, DynamoDBFlatConfig config) : base(context, config) { StorageConfig = context.StorageConfigCache.GetConfig(valuesType, config); if (StorageConfig.HasVersion) { if (!Config.SkipVersionCheck.GetValueOrDefault(false)) throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Object {0} has a versioning field, which is not supported for this operation. To ignore versioning, use the DynamoDBContextConfig.SkipVersionCheck property.", valuesType.Name)); } Table table = Context.GetTargetTable(StorageConfig, Config); DocumentBatch = table.CreateBatchWrite(); } #endregion #region Internal/protected/private members internal ItemStorageConfig StorageConfig { get; set; } /// /// Execute the batch write. /// internal protected override void ExecuteHelper() { DocumentBatch.ExecuteHelper(); } #if AWS_ASYNC_API /// /// Execute the batch write asynchronously. /// internal protected override Task ExecuteHelperAsync(CancellationToken cancellationToken) { return DocumentBatch.ExecuteHelperAsync(cancellationToken); } #endif #endregion } /// /// Class for writing/deleting a batch of items in multiple DynamoDB tables, /// using multiple strongly-typed BatchWrite objects /// public partial class MultiTableBatchWrite { #region Private members private List allBatches = new List(); #endregion #region Constructor /// /// Constructs a MultiTableBatchWrite object from a number of /// BatchWrite objects /// /// Collection of BatchWrite objects public MultiTableBatchWrite(params BatchWrite[] batches) { allBatches = new List(batches); } internal MultiTableBatchWrite(BatchWrite first, params BatchWrite[] rest) { allBatches = new List(); allBatches.Add(first); allBatches.AddRange(rest); } #endregion #region Public methods /// /// Add a BatchWrite object to the multi-table batch request /// /// BatchGet to add public void AddBatch(BatchWrite batch) { allBatches.Add(batch); } internal void ExecuteHelper() { MultiTableDocumentBatchWrite superBatch = new MultiTableDocumentBatchWrite(); foreach (var batch in allBatches) { superBatch.AddBatch(batch.DocumentBatch); } superBatch.ExecuteHelper(); } #if AWS_ASYNC_API internal Task ExecuteHelperAsync(CancellationToken cancellationToken) { MultiTableDocumentBatchWrite superBatch = new MultiTableDocumentBatchWrite(); foreach (var batch in allBatches) { superBatch.AddBatch(batch.DocumentBatch); } return superBatch.ExecuteHelperAsync(cancellationToken); } #endif #endregion } }