Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PartiQL #256

Merged
merged 18 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion src/EfficientDynamoDb/DynamoDbContext/DynamoDbLowLevelContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@
using EfficientDynamoDb.Exceptions;
using EfficientDynamoDb.Internal;
using EfficientDynamoDb.Internal.Extensions;
using EfficientDynamoDb.Internal.Operations.BatchExecuteStatement;
using EfficientDynamoDb.Internal.Operations.BatchGetItem;
using EfficientDynamoDb.Internal.Operations.BatchWriteItem;
using EfficientDynamoDb.Internal.Operations.DeleteItem;
using EfficientDynamoDb.Internal.Operations.DescribeTable;
using EfficientDynamoDb.Internal.Operations.ExecuteStatement;
using EfficientDynamoDb.Internal.Operations.ExecuteTransaction;
using EfficientDynamoDb.Internal.Operations.GetItem;
using EfficientDynamoDb.Internal.Operations.PutItem;
using EfficientDynamoDb.Internal.Operations.Query;
Expand All @@ -19,11 +22,14 @@
using EfficientDynamoDb.Internal.Operations.TransactWriteItems;
using EfficientDynamoDb.Internal.Operations.UpdateItem;
using EfficientDynamoDb.Internal.Reader;
using EfficientDynamoDb.Operations.BatchExecuteStatement;
using EfficientDynamoDb.Operations.BatchGetItem;
using EfficientDynamoDb.Operations.BatchWriteItem;
using EfficientDynamoDb.Operations.DeleteItem;
using EfficientDynamoDb.Operations.DescribeTable;
using EfficientDynamoDb.Operations.DescribeTable.Models.Enums;
using EfficientDynamoDb.Operations.ExecuteStatement;
using EfficientDynamoDb.Operations.ExecuteTransaction;
using EfficientDynamoDb.Operations.GetItem;
using EfficientDynamoDb.Operations.PutItem;
using EfficientDynamoDb.Operations.Query;
Expand Down Expand Up @@ -145,7 +151,31 @@ public async Task<TransactWriteItemsResponse> TransactWriteItemsAsync(TransactWr

return TransactWriteItemsResponseParser.Parse(result);
}


public async Task<ExecuteStatementResponse> ExecuteStatementAsync(ExecuteStatementRequest request, CancellationToken cancellationToken = default)
{
var httpContent = new ExecuteStatementRequestHttpContent(request);
using var response = await Api.SendAsync(Config, httpContent, cancellationToken).ConfigureAwait(false);
var result = await ReadDocumentAsync(response, QueryParsingOptions.Instance, cancellationToken).ConfigureAwait(false);
return ExecuteStatementResponseParser.Parse(result!);
}

public async Task<BatchExecuteStatementResponse> BatchExecuteStatementAsync(BatchExecuteStatementRequest request, CancellationToken cancellationToken = default)
{
var httpContent = new BatchExecuteStatementRequestHttpContent(request);
using var response = await Api.SendAsync(Config, httpContent, cancellationToken).ConfigureAwait(false);
var result = await ReadDocumentAsync(response, QueryParsingOptions.Instance, cancellationToken).ConfigureAwait(false);
return BatchExecuteStatementResponseParser.Parse(result!);
}

public async Task<ExecuteTransactionResponse> ExecuteTransactionAsync(ExecuteTransactionRequest request, CancellationToken cancellationToken = default)
{
var httpContent = new ExecuteTransactionRequestHttpContent(request);
using var response = await Api.SendAsync(Config, httpContent, cancellationToken).ConfigureAwait(false);
var result = await ReadDocumentAsync(response, QueryParsingOptions.Instance, cancellationToken).ConfigureAwait(false);
return ExecuteTransactionResponseParser.Parse(result!);
}

public T ToObject<T>(Document document) where T : class => document.ToObject<T>(Config.Metadata);

public Document ToDocument<T>(T entity) where T : class => entity.ToDocument(Config.Metadata);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
using System.Threading;
using System.Threading.Tasks;
using EfficientDynamoDb.DocumentModel;
using EfficientDynamoDb.Operations.BatchExecuteStatement;
using EfficientDynamoDb.Operations.BatchGetItem;
using EfficientDynamoDb.Operations.BatchWriteItem;
using EfficientDynamoDb.Operations.DeleteItem;
using EfficientDynamoDb.Operations.ExecuteStatement;
using EfficientDynamoDb.Operations.ExecuteTransaction;
using EfficientDynamoDb.Operations.GetItem;
using EfficientDynamoDb.Operations.PutItem;
using EfficientDynamoDb.Operations.Query;
Expand Down Expand Up @@ -35,7 +38,13 @@ public interface IDynamoDbLowLevelContext
Task<DeleteItemResponse> DeleteItemAsync(DeleteItemRequest request, CancellationToken cancellationToken = default);

Task<TransactWriteItemsResponse> TransactWriteItemsAsync(TransactWriteItemsRequest request, CancellationToken cancellationToken = default);


Task<ExecuteStatementResponse> ExecuteStatementAsync(ExecuteStatementRequest request, CancellationToken cancellationToken = default);

Task<BatchExecuteStatementResponse> BatchExecuteStatementAsync(BatchExecuteStatementRequest request, CancellationToken cancellationToken = default);

Task<ExecuteTransactionResponse> ExecuteTransactionAsync(ExecuteTransactionRequest request, CancellationToken cancellationToken = default);
ChrixApp marked this conversation as resolved.
Show resolved Hide resolved

T ToObject<T>(Document document) where T : class;

Document ToDocument<T>(T entity) where T : class;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using EfficientDynamoDb.Converters;
using EfficientDynamoDb.Internal.Extensions;
using EfficientDynamoDb.Internal.Operations.Shared;
using EfficientDynamoDb.Operations.BatchExecuteStatement;
using EfficientDynamoDb.Operations.Shared;
using System.Threading.Tasks;

namespace EfficientDynamoDb.Internal.Operations.BatchExecuteStatement
{
internal class BatchExecuteStatementRequestHttpContent : DynamoDbHttpContent
{
private readonly BatchExecuteStatementRequest _request;

public BatchExecuteStatementRequestHttpContent(BatchExecuteStatementRequest request) : base("DynamoDB_20120810.BatchExecuteStatement")
{
_request = request;
}

protected override ValueTask WriteDataAsync(DdbWriter writer)
{
var json = writer.JsonWriter;
json.WriteStartObject();

json.WritePropertyName("Statements");
json.WriteStartArray();
foreach (var statementRequest in _request.Statements)
{
json.WriteStartObject();

json.WriteString("Statement", statementRequest.Statement);

json.WritePropertyName("Parameters");
json.WriteStartArray();
foreach (var parameter in statementRequest.Parameters)
{
parameter.Write(json);
}
json.WriteEndArray();

if (statementRequest.ConsistentRead)
json.WriteBoolean("ConsistentRead", true);

if (statementRequest.ReturnValuesOnConditionCheckFailure != ReturnValuesOnConditionCheckFailure.None)
json.WriteReturnValuesOnConditionCheckFailure(statementRequest.ReturnValuesOnConditionCheckFailure);

json.WriteEndObject();
}
json.WriteEndArray();

if (_request.ReturnConsumedCapacity != ReturnConsumedCapacity.None)
json.WriteReturnConsumedCapacity(_request.ReturnConsumedCapacity);

json.WriteEndObject();

return default;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using EfficientDynamoDb.DocumentModel;
using EfficientDynamoDb.Internal.Operations.Shared;
using EfficientDynamoDb.Operations.BatchExecuteStatement;
using System;
using System.Collections.Generic;

namespace EfficientDynamoDb.Internal.Operations.BatchExecuteStatement
{
internal static class BatchExecuteStatementResponseParser
{
public static BatchExecuteStatementResponse Parse(Document response)
{
var responsesArray = response.TryGetValue("Responses", out var responsesAttribute)
? (IReadOnlyList<AttributeValue>)responsesAttribute.AsListAttribute().Items
: Array.Empty<AttributeValue>();

var items = new Document[responsesArray.Count];
for (var i = 0; i < responsesArray.Count; i++)
items[i] = responsesArray[i].AsDocument()["Item"].AsDocument();
ChrixApp marked this conversation as resolved.
Show resolved Hide resolved

return new BatchExecuteStatementResponse
{
Responses = items,
ConsumedCapacity = CapacityParser.ParseFullConsumedCapacities(response)
};
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using EfficientDynamoDb.Converters;
using EfficientDynamoDb.Internal.Extensions;
using EfficientDynamoDb.Internal.Operations.Shared;
using EfficientDynamoDb.Operations.ExecuteStatement;
using EfficientDynamoDb.Operations.Shared;
using System.Threading.Tasks;

namespace EfficientDynamoDb.Internal.Operations.ExecuteStatement
{
internal class ExecuteStatementRequestHttpContent : DynamoDbHttpContent
{
private readonly ExecuteStatementRequest _request;

public ExecuteStatementRequestHttpContent(ExecuteStatementRequest executeStatementRequest) : base("DynamoDB_20120810.ExecuteStatement")
{
_request = executeStatementRequest;
}

protected override ValueTask WriteDataAsync(DdbWriter writer)
{
var json = writer.JsonWriter;
json.WriteStartObject();

json.WritePropertyName("Statement");
json.WriteStringValue(_request.Statement);

json.WritePropertyName("Parameters");
json.WriteStartArray();
foreach (var parameter in _request.Parameters)
{
parameter.Write(json);
}
json.WriteEndArray();
ChrixApp marked this conversation as resolved.
Show resolved Hide resolved

if (_request.ConsistentRead)
json.WriteBoolean("ConsistentRead", true);

if (_request.Limit.HasValue)
json.WriteNumber("Limit", _request.Limit.Value);

if (_request.NextToken != null)
json.WriteString("NextToken", _request.NextToken);

if (_request.ReturnConsumedCapacity != ReturnConsumedCapacity.None)
json.WriteReturnConsumedCapacity(_request.ReturnConsumedCapacity);

if (_request.ReturnItemCollectionMetrics != ReturnItemCollectionMetrics.None)
json.WriteReturnItemCollectionMetrics(_request.ReturnItemCollectionMetrics);

if (_request.ReturnValuesOnConditionCheckFailure != ReturnValuesOnConditionCheckFailure.None)
json.WriteReturnValuesOnConditionCheckFailure(_request.ReturnValuesOnConditionCheckFailure);

json.WriteEndObject();
return default;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using EfficientDynamoDb.DocumentModel;
using EfficientDynamoDb.Internal.Operations.Shared;
using EfficientDynamoDb.Operations.ExecuteStatement;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;

namespace EfficientDynamoDb.Internal.Operations.ExecuteStatement
{
internal static class ExecuteStatementResponseParser
{
public static ExecuteStatementResponse Parse(Document response) =>
new ExecuteStatementResponse
{
Items = response.TryGetValue("Items", out var items) ? items._documentListValue.Items : Array.Empty<Document>(),
LastEvaluatedKey = ParseLastEvaluatedKey(response),
NextToken = response.TryGetValue("NextToken", out var nextToken) ? nextToken.AsString() : string.Empty,
ConsumedCapacity = CapacityParser.ParseFullConsumedCapacity(response),
};

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static IReadOnlyDictionary<string, AttributeValue>? ParseLastEvaluatedKey(Document response)
{
if (!response.TryGetValue("LastEvaluatedKey", out var attribute))
return null;

var document = attribute.AsDocument();
return document.Count > 0 ? document : null;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using EfficientDynamoDb.Converters;
using EfficientDynamoDb.Internal.Extensions;
using EfficientDynamoDb.Internal.Operations.Shared;
using EfficientDynamoDb.Operations.ExecuteTransaction;
using EfficientDynamoDb.Operations.Shared;
using System.Threading.Tasks;

namespace EfficientDynamoDb.Internal.Operations.ExecuteTransaction
{
internal class ExecuteTransactionRequestHttpContent : DynamoDbHttpContent
{
private readonly ExecuteTransactionRequest _request;

public ExecuteTransactionRequestHttpContent(ExecuteTransactionRequest request) : base("DynamoDB_20120810.ExecuteTransaction")
{
_request = request;
}

protected override ValueTask WriteDataAsync(DdbWriter writer)
{
var json = writer.JsonWriter;
json.WriteStartObject();

json.WritePropertyName("TransactStatements");
json.WriteStartArray();
foreach (var statement in _request.TransactStatements)
{
json.WriteStartObject();

json.WriteString("Statement", statement.Statement);

json.WritePropertyName("Parameters");
json.WriteStartArray();
foreach (var parameter in statement.Parameters)
{
parameter.Write(json);
}
json.WriteEndArray();

json.WriteEndObject();
}
json.WriteEndArray();

if (_request.ClientRequestToken != null)
json.WriteString("ClientRequestToken", _request.ClientRequestToken);

if (_request.ReturnConsumedCapacity != ReturnConsumedCapacity.None)
json.WriteReturnConsumedCapacity(_request.ReturnConsumedCapacity);

json.WriteEndObject();

return default;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using EfficientDynamoDb.DocumentModel;
using EfficientDynamoDb.Internal.Operations.Shared;
using EfficientDynamoDb.Operations.ExecuteTransaction;
using System;
using System.Collections.Generic;

namespace EfficientDynamoDb.Internal.Operations.ExecuteTransaction
{
internal static class ExecuteTransactionResponseParser
{
public static ExecuteTransactionResponse Parse(Document response)
{
var responsesArray = response.TryGetValue("Responses", out var responsesAttribute)
? (IReadOnlyList<AttributeValue>)responsesAttribute.AsListAttribute().Items
: Array.Empty<AttributeValue>();

var items = new Document[responsesArray.Count];
for (var i = 0; i < responsesArray.Count; i++)
items[i] = responsesArray[i].AsDocument()["Item"].AsDocument();
ChrixApp marked this conversation as resolved.
Show resolved Hide resolved

return new ExecuteTransactionResponse
{
Responses = items,
ConsumedCapacity = CapacityParser.ParseFullConsumedCapacities(response)
};
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using EfficientDynamoDb.Operations.Shared;
using System;
using System.Collections.Generic;

namespace EfficientDynamoDb.Operations.BatchExecuteStatement
{
/// <summary>
/// This operation allows you to perform batch reads or writes on data stored in DynamoDB, using PartiQL. Each read statement in a BatchExecuteStatement must specify an equality condition on all key attributes. This enforces that each SELECT statement in a batch returns at most a single item.
/// </summary>
public class BatchExecuteStatementRequest
{
/// <summary>
/// Gets and sets the property Statements.
/// <para>
/// The list of PartiQL statements representing the batch to run.
/// </para>
/// </summary>
public IReadOnlyList<BatchStatementRequest> Statements { get; set; } = Array.Empty<BatchStatementRequest>();

/// <summary>
/// Determines the level of detail about provisioned throughput consumption that is returned in the response.
/// </summary>
public ReturnConsumedCapacity ReturnConsumedCapacity { get; set; }
}
}
Loading