Ejemplo n.º 1
0
 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);
        }
Ejemplo n.º 7
0
        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);
        }
Ejemplo n.º 8
0
        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();
        }
Ejemplo n.º 9
0
        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);
        }
Ejemplo n.º 13
0
        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);
        }
Ejemplo n.º 14
0
        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));
        }
Ejemplo n.º 15
0
        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.");