Example #1
0
        public static RenderedProjectionDefinition <TResult> TranslateGroup <TKey, TDocument, TResult>(Expression <Func <TDocument, TKey> > idProjector, Expression <Func <IGrouping <TKey, TDocument>, TResult> > groupProjector, IBsonSerializer <TDocument> parameterSerializer, IBsonSerializerRegistry serializerRegistry)
        {
            var keyBinder          = new SerializationInfoBinder(serializerRegistry);
            var boundKeyExpression = BindSerializationInfo(keyBinder, idProjector, parameterSerializer);

            if (!(boundKeyExpression is ISerializationExpression))
            {
                var keySerializer = SerializerBuilder.Build(boundKeyExpression, serializerRegistry);
                boundKeyExpression = new SerializationExpression(
                    boundKeyExpression,
                    new BsonSerializationInfo(null, keySerializer, typeof(TKey)));
            }

            var idExpression = new GroupIdExpression(boundKeyExpression, ((ISerializationExpression)boundKeyExpression).SerializationInfo);

            var groupBinder = new AccumulatorBinder(serializerRegistry);

            groupBinder.RegisterMemberReplacement(typeof(IGrouping <TKey, TDocument>).GetProperty("Key"), idExpression);
            var groupSerializer      = new ArraySerializer <TDocument>(parameterSerializer);
            var boundGroupExpression = BindSerializationInfo(groupBinder, groupProjector, groupSerializer);
            var projectionSerializer = (IBsonSerializer <TResult>)SerializerBuilder.Build(boundGroupExpression, serializerRegistry);
            var projection           = AggregateLanguageTranslator.Translate(boundGroupExpression).AsBsonDocument;

            // must have an "_id" in a group document
            if (!projection.Contains("_id"))
            {
                var idProjection = AggregateLanguageTranslator.Translate(boundKeyExpression);
                projection.InsertAt(0, new BsonElement("_id", idProjection));
            }

            return(new RenderedProjectionDefinition <TResult>(projection, projectionSerializer));
        }
Example #2
0
        private Expression BindSelector(ProjectionExpression projection, ProjectionBindingContext context, Expression id, Expression node)
        {
            var lambda = ExtensionExpressionVisitor.GetLambda(node);
            var binder = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry);

            var serializer         = SerializerBuilder.Build(projection.Projector, context.SerializerRegistry);
            var sequenceSerializer = (IBsonSerializer)Activator.CreateInstance(
                typeof(ArraySerializer <>).MakeGenericType(projection.Projector.Type),
                new object[] { serializer });
            var sequenceInfo = new BsonSerializationInfo(
                null,
                sequenceSerializer,
                sequenceSerializer.ValueType);
            var sequenceExpression = new SerializationExpression(
                lambda.Parameters[1],
                sequenceInfo);

            binder.RegisterParameterReplacement(lambda.Parameters[0], id);
            binder.RegisterParameterReplacement(lambda.Parameters[1], sequenceExpression);
            var correlationId = Guid.NewGuid();

            context.GroupMap.Add(sequenceExpression, correlationId);
            var bound = binder.Bind(lambda.Body);

            return(CorrelatedAccumulatorRemover.Remove(bound, correlationId));
        }
Example #3
0
        public static Expression Bind(Expression node, IBsonSerializer rootSerializer, IBsonSerializerRegistry serializerRegistry)
        {
            var bindingContext = new PipelineBindingContext(serializerRegistry);
            var binder         = new PipelineBinder(bindingContext, rootSerializer);

            node = binder.Bind(node);
            node = AccumulatorBinder.Bind(node, bindingContext);
            node = CorrelatedGroupRewriter.Rewrite(node);
            return(node);
        }
Example #4
0
        public static Expression Bind(Expression node, IBindingContext parent)
        {
            var bindingContext = new EmbeddedPipelineBindingContext(parent);
            var binder         = new EmbeddedPipelineBinder(bindingContext);

            var bound = binder.Bind(node);

            bound = AccumulatorBinder.Bind(bound, bindingContext);
            return(CorrelatedGroupRewriter.Rewrite(bound));
        }
Example #5
0
        public Expression Bind(ProjectionExpression projection, ProjectionBindingContext context, MethodCallExpression node, IEnumerable <Expression> arguments)
        {
            var collectionLambda = ExtensionExpressionVisitor.GetLambda(arguments.First());
            var binder           = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry);

            binder.RegisterParameterReplacement(collectionLambda.Parameters[0], projection.Projector);

            var collectionSelector = binder.Bind(collectionLambda.Body) as SerializationExpression;

            if (collectionSelector == null)
            {
                var message = string.Format("Unable to determine the collection selector in the tree: {0}", node.ToString());
                throw new NotSupportedException(message);
            }
            var collectionArraySerializer = collectionSelector.SerializationInfo.Serializer as IBsonArraySerializer;
            BsonSerializationInfo collectionItemSerializationInfo;

            if (collectionArraySerializer == null || !collectionArraySerializer.TryGetItemSerializationInfo(out collectionItemSerializationInfo))
            {
                var message = string.Format("The collection selector's serializer must implement IBsonArraySerializer: {0}", node.ToString());
                throw new NotSupportedException(message);
            }

            Expression resultSelector;

            if (arguments.Count() == 2)
            {
                var resultLambda = ExtensionExpressionVisitor.GetLambda(arguments.Last());

                binder.RegisterParameterReplacement(resultLambda.Parameters[0], projection.Projector);
                binder.RegisterParameterReplacement(
                    resultLambda.Parameters[1],
                    new SerializationExpression(
                        resultLambda.Parameters[1],
                        collectionItemSerializationInfo.WithNewName(collectionSelector.SerializationInfo.ElementName)));

                resultSelector = binder.Bind(resultLambda.Body);
            }
            else
            {
                resultSelector = new SerializationExpression(
                    collectionSelector,
                    collectionItemSerializationInfo.WithNewName(collectionSelector.SerializationInfo.ElementName));
            }

            var projector = BuildProjector(resultSelector, context);

            return(new ProjectionExpression(
                       new SelectManyExpression(
                           projection.Source,
                           collectionSelector,
                           resultSelector),
                       projector));
        }
        protected static Expression BindPredicate(ProjectionExpression projection, ProjectionBindingContext context, Expression source, Expression argument)
        {
            // this is actually a predicate that needs to be rendered as a WhereExpression
            var lambda = ExtensionExpressionVisitor.GetLambda(argument);
            var binder = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry);
            binder.RegisterParameterReplacement(lambda.Parameters[0], projection.Projector);
            var predicate = binder.Bind(lambda.Body);

            source = new WhereExpression(
                source,
                predicate);

            return source;
        }
        public Expression Bind(ProjectionExpression projection, ProjectionBindingContext context, MethodCallExpression node, IEnumerable<Expression> arguments)
        {
            var collectionLambda = ExtensionExpressionVisitor.GetLambda(arguments.First());
            var binder = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry);
            binder.RegisterParameterReplacement(collectionLambda.Parameters[0], projection.Projector);

            var collectionSelector = binder.Bind(collectionLambda.Body) as SerializationExpression;
            if (collectionSelector == null)
            {
                var message = string.Format("Unable to determine the collection selector in the tree: {0}", node.ToString());
                throw new NotSupportedException(message);
            }
            var collectionArraySerializer = collectionSelector.SerializationInfo.Serializer as IBsonArraySerializer;
            BsonSerializationInfo collectionItemSerializationInfo;
            if (collectionArraySerializer == null || !collectionArraySerializer.TryGetItemSerializationInfo(out collectionItemSerializationInfo))
            {
                var message = string.Format("The collection selector's serializer must implement IBsonArraySerializer: {0}", node.ToString());
                throw new NotSupportedException(message);
            }

            Expression resultSelector;
            if (arguments.Count() == 2)
            {
                var resultLambda = ExtensionExpressionVisitor.GetLambda(arguments.Last());

                binder.RegisterParameterReplacement(resultLambda.Parameters[0], projection.Projector);
                binder.RegisterParameterReplacement(
                    resultLambda.Parameters[1],
                    new SerializationExpression(
                        resultLambda.Parameters[1],
                        collectionItemSerializationInfo.WithNewName(collectionSelector.SerializationInfo.ElementName)));

                resultSelector = binder.Bind(resultLambda.Body);
            }
            else
            {
                resultSelector = new SerializationExpression(
                    collectionSelector,
                    collectionItemSerializationInfo.WithNewName(collectionSelector.SerializationInfo.ElementName));
            }

            var projector = BuildProjector(resultSelector, context);

            return new ProjectionExpression(
                new SelectManyExpression(
                    projection.Source,
                    collectionSelector,
                    resultSelector),
                projector);
        }
Example #8
0
        protected static Expression BindPredicate(ProjectionExpression projection, ProjectionBindingContext context, Expression source, Expression argument)
        {
            // this is actually a predicate that needs to be rendered as a WhereExpression
            var lambda = ExtensionExpressionVisitor.GetLambda(argument);
            var binder = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry);

            binder.RegisterParameterReplacement(lambda.Parameters[0], projection.Projector);
            var predicate = binder.Bind(lambda.Body);

            source = new WhereExpression(
                source,
                predicate);

            return(source);
        }
        public Expression Bind(ProjectionExpression projection, ProjectionBindingContext context, MethodCallExpression node, IEnumerable<Expression> arguments)
        {
            var lambda = ExtensionExpressionVisitor.GetLambda(arguments.Single());
            var binder = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry);
            binder.RegisterParameterReplacement(lambda.Parameters[0], projection.Projector);

            var predicate = binder.Bind(lambda.Body);

            return new ProjectionExpression(
                new WhereExpression(
                    projection.Source,
                    predicate),
                projection.Projector,
                projection.Aggregator);
        }
Example #10
0
        public Expression Bind(ProjectionExpression projection, ProjectionBindingContext context, MethodCallExpression node, IEnumerable <Expression> arguments)
        {
            var lambda = ExtensionExpressionVisitor.GetLambda(arguments.Single());
            var binder = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry);

            binder.RegisterParameterReplacement(lambda.Parameters[0], projection.Projector);

            var predicate = binder.Bind(lambda.Body);

            return(new ProjectionExpression(
                       new WhereExpression(
                           projection.Source,
                           predicate),
                       projection.Projector,
                       projection.Aggregator));
        }
        private GroupIdExpression BindId(ProjectionExpression projection, ProjectionBindingContext context, Expression node)
        {
            var lambda = ExtensionExpressionVisitor.GetLambda(node);
            var binder = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry);
            binder.RegisterParameterReplacement(lambda.Parameters[0], projection.Projector);
            var selector = binder.Bind(lambda.Body);

            if (!(selector is ISerializationExpression))
            {
                var serializer = SerializerBuilder.Build(selector, context.SerializerRegistry);
                selector = new SerializationExpression(
                    selector,
                    new BsonSerializationInfo(null, serializer, serializer.ValueType));
            }

            return new GroupIdExpression(selector, ((ISerializationExpression)selector).SerializationInfo);
        }
Example #12
0
        public override Expression Bind(Expressions.ProjectionExpression projection, ProjectionBindingContext context, System.Linq.Expressions.MethodCallExpression node, IEnumerable <System.Linq.Expressions.Expression> arguments)
        {
            var aggregatorName = "Single";
            var returnType     = node.Method.ReturnType;

            if (node.Method.Name.EndsWith("Async"))
            {
                aggregatorName += "Async";
                returnType      = returnType.GetGenericArguments()[0];
            }

            var aggregator = CreateAggregator(aggregatorName, returnType);

            var source   = projection.Source;
            var argument = arguments.FirstOrDefault();

            if (argument != null && ExtensionExpressionVisitor.IsLambda(argument))
            {
                var lambda = ExtensionExpressionVisitor.GetLambda(argument);
                var binder = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry);
                binder.RegisterParameterReplacement(lambda.Parameters[0], projection.Projector);
                argument = binder.Bind(lambda.Body);
            }
            else
            {
                argument = projection.Projector;
                var select = source as SelectExpression;
                if (select != null)
                {
                    source = select.Source;
                }
            }

            var serializer  = context.SerializerRegistry.GetSerializer(returnType);
            var accumulator = new AccumulatorExpression(returnType, AccumulatorType, argument);
            var serializationAccumulator = new SerializationExpression(
                accumulator,
                new BsonSerializationInfo("__agg0", serializer, serializer.ValueType));

            var rootAccumulator = new RootAccumulatorExpression(source, serializationAccumulator);

            return(new ProjectionExpression(
                       rootAccumulator,
                       serializationAccumulator,
                       aggregator));
        }
        private GroupIdExpression BindId(ProjectionExpression projection, ProjectionBindingContext context, Expression node)
        {
            var lambda = ExtensionExpressionVisitor.GetLambda(node);
            var binder = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry);

            binder.RegisterParameterReplacement(lambda.Parameters[0], projection.Projector);
            var selector = binder.Bind(lambda.Body);

            if (!(selector is ISerializationExpression))
            {
                var serializer = SerializerBuilder.Build(selector, context.SerializerRegistry);
                selector = new SerializationExpression(
                    selector,
                    new BsonSerializationInfo(null, serializer, serializer.ValueType));
            }

            return(new GroupIdExpression(selector, ((ISerializationExpression)selector).SerializationInfo));
        }
        public override Expression Bind(Expressions.ProjectionExpression projection, ProjectionBindingContext context, System.Linq.Expressions.MethodCallExpression node, IEnumerable<System.Linq.Expressions.Expression> arguments)
        {
            var aggregatorName = "Single";
            var returnType = node.Method.ReturnType;
            if (node.Method.Name.EndsWith("Async"))
            {
                aggregatorName += "Async";
                returnType = returnType.GetGenericArguments()[0];
            }

            var aggregator = CreateAggregator(aggregatorName, returnType);

            var source = projection.Source;
            var argument = arguments.FirstOrDefault();
            if (argument != null && ExtensionExpressionVisitor.IsLambda(argument))
            {
                var lambda = ExtensionExpressionVisitor.GetLambda(argument);
                var binder = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry);
                binder.RegisterParameterReplacement(lambda.Parameters[0], projection.Projector);
                argument = binder.Bind(lambda.Body);
            }
            else
            {
                argument = projection.Projector;
                var select = source as SelectExpression;
                if (select != null)
                {
                    source = select.Source;
                }
            }

            var serializer = context.SerializerRegistry.GetSerializer(returnType);
            var accumulator = new AccumulatorExpression(returnType, AccumulatorType, argument);
            var serializationAccumulator = new SerializationExpression(
                accumulator,
                new BsonSerializationInfo("__agg0", serializer, serializer.ValueType));

            var rootAccumulator = new RootAccumulatorExpression(source, serializationAccumulator);

            return new ProjectionExpression(
                rootAccumulator,
                serializationAccumulator,
                aggregator);
        }
        public Expression Bind(ProjectionExpression projection, ProjectionBindingContext context, MethodCallExpression node, IEnumerable<Expression> arguments)
        {
            var source = projection.Source;
            var sortClauses = GatherPreviousSortClauses(projection.Source, out source);

            var lambda = ExtensionExpressionVisitor.GetLambda(arguments.Single());
            var binder = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry);
            binder.RegisterParameterReplacement(lambda.Parameters[0], projection.Projector);

            var direction = GetDirection(node.Method.Name);
            var ordering = binder.Bind(lambda.Body);

            sortClauses.Add(new SortClause(ordering, direction));

            return new ProjectionExpression(
                new OrderByExpression(
                    source,
                    sortClauses),
                projection.Projector,
                projection.Aggregator);
        }
        public Expression Bind(ProjectionExpression projection, ProjectionBindingContext context, MethodCallExpression node, IEnumerable<Expression> arguments)
        {
            var lambda = ExtensionExpressionVisitor.GetLambda(arguments.Single());
            if (lambda.Body == lambda.Parameters[0])
            {
                // we can ignore identity projections
                return projection;
            }

            var binder = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry);
            binder.RegisterParameterReplacement(lambda.Parameters[0], projection.Projector);

            var selector = binder.Bind(lambda.Body);
            var projector = BuildProjector(selector, context);

            return new ProjectionExpression(
                new SelectExpression(
                    projection.Source,
                    selector),
                projector);
        }
Example #17
0
        public Expression Bind(ProjectionExpression projection, ProjectionBindingContext context, MethodCallExpression node, IEnumerable <Expression> arguments)
        {
            var source      = projection.Source;
            var sortClauses = GatherPreviousSortClauses(projection.Source, out source);

            var lambda = ExtensionExpressionVisitor.GetLambda(arguments.Single());
            var binder = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry);

            binder.RegisterParameterReplacement(lambda.Parameters[0], projection.Projector);

            var direction = GetDirection(node.Method.Name);
            var ordering  = binder.Bind(lambda.Body);

            sortClauses.Add(new SortClause(ordering, direction));

            return(new ProjectionExpression(
                       new OrderByExpression(
                           source,
                           sortClauses),
                       projection.Projector,
                       projection.Aggregator));
        }
Example #18
0
        public Expression Bind(ProjectionExpression projection, ProjectionBindingContext context, MethodCallExpression node, IEnumerable <Expression> arguments)
        {
            var lambda = ExtensionExpressionVisitor.GetLambda(arguments.Single());

            if (lambda.Body == lambda.Parameters[0])
            {
                // we can ignore identity projections
                return(projection);
            }

            var binder = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry);

            binder.RegisterParameterReplacement(lambda.Parameters[0], projection.Projector);

            var selector  = binder.Bind(lambda.Body);
            var projector = BuildProjector(selector, context);

            return(new ProjectionExpression(
                       new SelectExpression(
                           projection.Source,
                           selector),
                       projector));
        }
        private Expression BindSelector(ProjectionExpression projection, ProjectionBindingContext context, Expression id, Expression node)
        {
            var lambda = ExtensionExpressionVisitor.GetLambda(node);
            var binder = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry);

            var serializer = SerializerBuilder.Build(projection.Projector, context.SerializerRegistry);
            var sequenceSerializer = (IBsonSerializer)Activator.CreateInstance(
                typeof(ArraySerializer<>).MakeGenericType(projection.Projector.Type),
                new object[] { serializer });
            var sequenceInfo = new BsonSerializationInfo(
                null,
                sequenceSerializer,
                sequenceSerializer.ValueType);
            var sequenceExpression = new SerializationExpression(
                lambda.Parameters[1],
                sequenceInfo);

            binder.RegisterParameterReplacement(lambda.Parameters[0], id);
            binder.RegisterParameterReplacement(lambda.Parameters[1], sequenceExpression);
            var correlationId = Guid.NewGuid();
            context.GroupMap.Add(sequenceExpression, correlationId);
            var bound = binder.Bind(lambda.Body);
            return CorrelatedAccumulatorRemover.Remove(bound, correlationId);
        }