/*
* 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
}
}