/*
* 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.Generic;
using System.Threading;
#if AWS_ASYNC_API
using System.Threading.Tasks;
#endif
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.DocumentModel;
namespace Amazon.DynamoDBv2.DataModel
{
///
/// Context object for using the DataModel mode of DynamoDB.
/// Used to interact with the service, save/load objects, etc.
///
public partial class DynamoDBContext : IDynamoDBContext
{
#region Private members
private bool disposed;
private bool ownClient;
internal IAmazonDynamoDB Client { get; private set; }
private Dictionary tablesMap;
private readonly ReaderWriterLockSlim _readerWriterLockSlim = new ReaderWriterLockSlim();
internal DynamoDBContextConfig Config { get; private set; }
internal ItemStorageConfigCache StorageConfigCache { get; private set; }
#endregion
#region Public properties
///
/// This cache is a way to store Converters for objects which provides a way to expand Context
///
public Dictionary ConverterCache { get; private set; }
#endregion
#region Constructors
#if !NETSTANDARD
///
/// Constructs a DynamoDBContext object with a default AmazonDynamoDBClient
/// client and a default DynamoDBContextConfig object for configuration.
///
public DynamoDBContext()
: this(new AmazonDynamoDBClient()) { }
///
/// Constructs a DynamoDBContext object with a default AmazonDynamoDBClient
/// client and a default DynamoDBContextConfig object for configuration.
///
/// The region to configure the AmazonDynamoDBClient to use.
public DynamoDBContext(RegionEndpoint region)
: this(new AmazonDynamoDBClient(region), true, new DynamoDBContextConfig()) { }
///
/// Constructs a DynamoDBContext object with the specified configuration.
/// Uses a default AmazonDynamoDBClient as the client.
///
///
public DynamoDBContext(DynamoDBContextConfig config)
: this(new AmazonDynamoDBClient(), config) { }
///
/// Constructs a DynamoDBContext object with the specified configuration.
/// Uses a default AmazonDynamoDBClient as the client.
///
/// The region to configure the AmazonDynamoDBClient to use.
///
public DynamoDBContext(RegionEndpoint region, DynamoDBContextConfig config)
: this(new AmazonDynamoDBClient(region), true, config) { }
#endif
///
/// Constructs a DynamoDBContext object with the specified DynamoDB client.
/// Uses default DynamoDBContextConfig object for configuration.
///
/// Client to use for making calls
public DynamoDBContext(IAmazonDynamoDB client)
: this(client, false, new DynamoDBContextConfig()) { }
///
/// Constructs a DynamoDBContext object with the specified DynamoDB client
/// and configuration.
///
/// Client to use for making calls
/// Configuration to use
public DynamoDBContext(IAmazonDynamoDB client, DynamoDBContextConfig config)
: this(client, false, config) { }
private DynamoDBContext(IAmazonDynamoDB client, bool ownClient, DynamoDBContextConfig config)
{
if (client == null) throw new ArgumentNullException("client");
this.ConverterCache = new Dictionary();
this.ConverterCache.Add(typeof(S3Link), new S3Link.S3LinkConverter(this));
this.Client = client;
this.tablesMap = new Dictionary();
this.ownClient = ownClient;
this.Config = config ?? new DynamoDBContextConfig();
this.StorageConfigCache = new ItemStorageConfigCache(this);
}
#endregion
#region Dispose Pattern Implementation
///
/// Implements the Dispose pattern
///
/// Whether this object is being disposed via a call to Dispose
/// or garbage collected.
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing && Client != null)
{
if (ownClient)
{
StorageConfigCache.Dispose();
Client.Dispose();
}
Client = null;
}
this.disposed = true;
}
}
///
/// Disposes of all managed and unmanaged resources.
///
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
///
/// The destructor for the client class.
///
~DynamoDBContext()
{
this.Dispose(false);
}
#endregion
#region Factory Creates
///
/// Creates a strongly-typed BatchGet object, allowing
/// a batch-get operation against DynamoDB.
///
/// Type of objects to get
/// Empty strongly-typed BatchGet object
public BatchGet CreateBatchGet()
{
return CreateBatchGet(null);
}
///
/// Creates a strongly-typed BatchGet object, allowing
/// a batch-get operation against DynamoDB.
///
/// Type of objects to get
/// Config object which can be used to override that table used.
/// Empty strongly-typed BatchGet object
public BatchGet CreateBatchGet(DynamoDBOperationConfig operationConfig)
{
DynamoDBFlatConfig config = new DynamoDBFlatConfig(operationConfig, this.Config);
return new BatchGet(this, config);
}
///
/// Creates a MultiTableBatchGet object, composed of multiple
/// individual BatchGet objects.
///
/// Individual BatchGet objects
/// Composite MultiTableBatchGet object
public MultiTableBatchGet CreateMultiTableBatchGet(params BatchGet[] batches)
{
return new MultiTableBatchGet(batches);
}
///
/// Creates a strongly-typed BatchWrite object, allowing
/// a batch-write operation against DynamoDB.
///
/// Type of objects to write
/// Empty strongly-typed BatchWrite object
public BatchWrite CreateBatchWrite()
{
return CreateBatchWrite(null);
}
///
/// Creates a strongly-typed BatchWrite object, allowing
/// a batch-write operation against DynamoDB.
///
/// Type of objects to write
/// Config object which can be used to override that table used.
/// Empty strongly-typed BatchWrite object
public BatchWrite CreateBatchWrite(DynamoDBOperationConfig operationConfig)
{
DynamoDBFlatConfig config = new DynamoDBFlatConfig(operationConfig, this.Config);
return new BatchWrite(this, config);
}
///
/// Creates a strongly-typed BatchWrite object, allowing
/// a batch-write operation against DynamoDB.
///
/// This is intended for use only when the valuesType is not known at compile-time, for example,
/// when hooking into EF's ChangeTracker to record audit logs from EF into DynamoDB.
///
/// In scenarios when the valuesType is known at compile-time, the `BatchWrite CreateBatchWrite()`
/// method is generally preferred.
///
/// Type of objects to write
/// Empty strongly-typed BatchWrite object
public BatchWrite