public UpdateItemSaveHttpContent(DynamoDbContextConfig config, TEntity entity) : base("DynamoDB_20120810.UpdateItem") { _config = config; _entity = entity; _classInfo = _config.Metadata.GetOrAddClassInfo <TEntity>(); }
protected override Expression VisitMember(MemberExpression node) { if (node.Expression is ConstantExpression constantExpression && node.Member is FieldInfo fieldInfo) { var value = fieldInfo.GetValue(constantExpression.Value); _builder.Append(value); return(node); } if (node.Expression !.NodeType != ExpressionType.Parameter) { Visit(node.Expression); } if (_builder.Length > 0) { _builder.Append('.'); } _builder.Append("#f"); _builder.Append(_cachedAttributeNames !.Count); if (!ClassInfo.PropertiesMap.TryGetValue(node.Member.Name, out var ddbPropertyInfo)) { throw new DdbException( $"Property {node.Member.Name} does not exist in entity {ClassInfo.Type.Name} or it's not marked by {nameof(DynamoDbPropertyAttribute)} attribute"); } _cachedAttributeNames.Add(ddbPropertyInfo.AttributeName); ClassInfo = ddbPropertyInfo.RuntimeClassInfo; return(node); }
public UpdateItemHighLevelHttpContent(DynamoDbContext context, DdbClassInfo classInfo, BuilderNode?node) : base("DynamoDB_20120810.UpdateItem") { _context = context; _node = node; _classInfo = classInfo; }
public void Visit(DdbClassInfo classInfo, Expression expression) { ClassInfo = classInfo; _builder.Clear(); Visit(expression); }
internal async Task DeleteItemAsync(DdbClassInfo classInfo, BuilderNode node, CancellationToken cancellationToken = default) { using var httpContent = new DeleteItemHighLevelHttpContent(this, classInfo, node); using var response = await Api.SendAsync(Config, httpContent, cancellationToken).ConfigureAwait(false); await ReadAsync <object>(response, cancellationToken).ConfigureAwait(false); }
public void Visit <TEntity>(Expression expression) { var entityType = typeof(TEntity); ClassInfo = _metadata.GetOrAddClassInfo(entityType); _builder.Clear(); Visit(expression); }
internal async Task <TEntity?> GetItemAsync <TEntity>(DdbClassInfo classInfo, BuilderNode node, CancellationToken cancellationToken = default) where TEntity : class { using var httpContent = new GetItemHighLevelHttpContent(this, classInfo, node); using var response = await Api.SendAsync(Config, httpContent, cancellationToken).ConfigureAwait(false); var result = await ReadAsync <GetItemEntityProjection <TEntity> >(response, cancellationToken).ConfigureAwait(false); return(result.Item); }
public static void WriteEntity(this DdbWriter writer, DdbClassInfo entityClassInfo, object entity) { writer.JsonWriter.WriteStartObject(); foreach (var property in entityClassInfo.Properties) { property.Write(entity, writer); } writer.JsonWriter.WriteEndObject(); }
public static async ValueTask WriteEntityAsync(this DdbWriter writer, DdbClassInfo entityClassInfo, object entity) { writer.JsonWriter.WriteStartObject(); foreach (var property in entityClassInfo.Properties) { property.Write(entity, writer); if (writer.ShouldFlush) { await writer.FlushAsync().ConfigureAwait(false); } } writer.JsonWriter.WriteEndObject(); }
protected override Expression VisitBinary(BinaryExpression node) { if (node.NodeType == ExpressionType.ArrayIndex) { Visit(node.Left); _builder.Append('['); Visit(node.Right); _builder.Append(']'); ClassInfo = ClassInfo.ElementClassInfo !; } return(node); }
protected override Expression VisitMethodCall(MethodCallExpression node) { if (node.Method.IsSpecialName && node.Method.Name == "get_Item") { Visit(node.Object); _builder.Append('['); Visit(node.Arguments); _builder.Append(']'); ClassInfo = ClassInfo.ElementClassInfo !; } return(node); }
protected override Expression VisitIndex(IndexExpression node) { if (node.Object !.NodeType != ExpressionType.Parameter) { Visit(node.Object); } _builder.Append('['); Visit(node.Arguments); _builder.Append(']'); ClassInfo = ClassInfo.ElementClassInfo !; return(node); }
protected override Expression VisitMethodCall(MethodCallExpression node) { if (node.Method.IsSpecialName && node.Method.Name == "get_Item") { Visit(node.Object); if ((ClassInfo.ClassType & DdbClassType.Dictionary) != 0) { _builder.Append('.'); Visit(node.Arguments); } else { _builder.Append('['); Visit(node.Arguments); _builder.Append(']'); } ClassInfo = ClassInfo.ElementClassInfo !; } return(node); }
internal async Task <UpdateItemEntityResponse <TEntity> > UpdateItemResponseAsync <TEntity>(DdbClassInfo classInfo, BuilderNode?node, CancellationToken cancellationToken = default) where TEntity : class { using var httpContent = new UpdateItemHighLevelHttpContent(this, classInfo, node); using var response = await Api.SendAsync(Config, httpContent, cancellationToken).ConfigureAwait(false); return(await ReadAsync <UpdateItemEntityResponse <TEntity> >(response, cancellationToken).ConfigureAwait(false)); }
public static async ValueTask <ReadResult <TEntity> > ReadAsync <TEntity>(Stream utf8Json, DdbClassInfo classInfo, DynamoDbContextMetadata metadata, bool returnCrc, int defaultBufferSize = DefaultBufferSize, CancellationToken cancellationToken = default) where TEntity : class { var readerState = new JsonReaderState(); var readStack = new DdbEntityReadStack(DdbEntityReadStack.DefaultStackLength, metadata); try { readStack.GetCurrent().ClassInfo ??= classInfo; var buffer = ArrayPool <byte> .Shared.Rent(defaultBufferSize); var clearMax = 0; try { var bytesInBuffer = 0; uint crc = 0; var isFirstBlock = true; while (true) { var isFinalBlock = false; while (true) { var bytesRead = await utf8Json.ReadAsync(new Memory <byte>(buffer, bytesInBuffer, buffer.Length - bytesInBuffer), cancellationToken).ConfigureAwait(false); if (bytesRead == 0) { isFinalBlock = true; break; } if (returnCrc) { crc = Crc32Algorithm.Append(crc, buffer, bytesInBuffer, bytesRead); } bytesInBuffer += bytesRead; if (bytesInBuffer == buffer.Length) { break; } } if (bytesInBuffer > clearMax) { clearMax = bytesInBuffer; } readStack.UseFastPath = isFirstBlock && isFinalBlock; readStack.Buffer = buffer; readStack.BufferStart = 0; readStack.BufferLength = bytesInBuffer; ReadCore <TEntity>(ref readerState, isFinalBlock, new ReadOnlySpan <byte>(buffer, 0, bytesInBuffer), ref readStack); var bytesConsumed = (int)readStack.BytesConsumed; bytesInBuffer -= bytesConsumed; if (isFinalBlock) { break; } // Check if we need to shift or expand the buffer because there wasn't enough data to complete deserialization. if ((uint)bytesInBuffer > ((uint)buffer.Length / 2)) { // We have less than half the buffer available, double the buffer size. byte[] dest = ArrayPool <byte> .Shared.Rent((buffer.Length < (int.MaxValue / 2))?buffer.Length * 2 : int.MaxValue); // Copy the unprocessed data to the new buffer while shifting the processed bytes. Buffer.BlockCopy(buffer, bytesConsumed, dest, 0, bytesInBuffer); new Span <byte>(buffer, 0, clearMax).Clear(); ArrayPool <byte> .Shared.Return(buffer); clearMax = bytesInBuffer; buffer = dest; } else if (bytesInBuffer != 0) { // Shift the processed bytes to the beginning of buffer to make more room. Buffer.BlockCopy(buffer, bytesConsumed, buffer, 0, bytesInBuffer); } isFirstBlock = false; } return(new ReadResult <TEntity>((TEntity)readStack.GetCurrent().ReturnValue !, crc)); } finally { new Span <byte>(buffer, 0, clearMax).Clear(); ArrayPool <byte> .Shared.Return(buffer); } } finally { readStack.Dispose(); } }
public static string GetTableName(this DdbClassInfo classInfo) => classInfo.TableName ?? throw new DdbException($"Entity '{classInfo.Type.Name}' has no DynamoDbTable attribute applied.");