Esempio n. 1
0
        private Term.AssocPair MapMemberAssignmentToMakeObjArg(MemberAssignment memberAssignment)
        {
            var retval = new Term.AssocPair();

            var datumConverter = datumConverterFactory.Get <TReturn>();
            var fieldConverter = datumConverter as IObjectDatumConverter;

            if (fieldConverter == null)
            {
                throw new NotSupportedException("Cannot map member assignments into ReQL without implementing IObjectDatumConverter");
            }

            retval.key = fieldConverter.GetDatumFieldName(memberAssignment.Member);
            retval.val = MapExpressionToTerm(memberAssignment.Expression);

            return(retval);
        }
Esempio n. 2
0
        protected Term SimpleMap(IDatumConverterFactory datumConverterFactory, Expression expr)
        {
            switch (expr.NodeType)
            {
            case ExpressionType.Constant:
            {
                var constantExpression = (ConstantExpression)expr;
                var datumConverter     = datumConverterFactory.Get(constantExpression.Type);
                var datum = datumConverter.ConvertObject(constantExpression.Value);
                return(new Term()
                    {
                        type = Term.TermType.DATUM,
                        datum = datum
                    });
            }

            case ExpressionType.Add:
            case ExpressionType.Modulo:
            case ExpressionType.Divide:
            case ExpressionType.Multiply:
            case ExpressionType.Subtract:
            case ExpressionType.Equal:
            case ExpressionType.LessThan:
            case ExpressionType.LessThanOrEqual:
            case ExpressionType.GreaterThan:
            case ExpressionType.GreaterThanOrEqual:
            case ExpressionType.AndAlso:
            case ExpressionType.OrElse:
            case ExpressionType.NotEqual:
            case ExpressionType.ArrayIndex:
                return(ConvertBinaryExpressionToTerm((BinaryExpression)expr, datumConverterFactory));

            case ExpressionType.Not:
            case ExpressionType.ArrayLength:
                return(ConvertUnaryExpressionToTerm((UnaryExpression)expr, datumConverterFactory));

            case ExpressionType.New:
            {
                var newExpression = (NewExpression)expr;
                if (AnonymousTypeDatumConverterFactory.Instance.IsTypeSupported(newExpression.Type))
                {
                    var retval = new Term()
                    {
                        type = Term.TermType.MAKE_OBJ,
                    };
                    foreach (var property in newExpression.Type.GetProperties().Select((p, i) => new { Property = p, Index = i }))
                    {
                        var key   = property.Property.Name;
                        var value = RecursiveMap(newExpression.Arguments[property.Index]);
                        retval.optargs.Add(new Term.AssocPair()
                            {
                                key = key, val = value
                            });
                    }
                    return(retval);
                }

                DefaultExpressionConverterFactory.ExpressionMappingDelegate <NewExpression> newExpressionMapping;
                if (expressionConverterFactory.TryGetNewExpressionMapping(newExpression.Constructor, out newExpressionMapping))
                {
                    return(newExpressionMapping(newExpression, RecursiveMap, datumConverterFactory, expressionConverterFactory));
                }

                return(AttemptClientSideConversion(datumConverterFactory, expr));
            }

            case ExpressionType.NewArrayInit:
                var arrayExpression = (NewArrayExpression)expr;
                var array           = new Term {
                    type = Term.TermType.MAKE_ARRAY
                };

                foreach (var expression in arrayExpression.Expressions)
                {
                    array.args.Add(RecursiveMap(expression));
                }

                return(array);

            case ExpressionType.Call:
            {
                var callExpression = (MethodCallExpression)expr;
                var method         = callExpression.Method;

                DefaultExpressionConverterFactory.ExpressionMappingDelegate <MethodCallExpression> methodCallMapping;
                if (expressionConverterFactory.TryGetMethodCallMapping(method, out methodCallMapping))
                {
                    return(methodCallMapping(callExpression, RecursiveMap, datumConverterFactory, expressionConverterFactory));
                }
                else
                {
                    return(AttemptClientSideConversion(datumConverterFactory, expr));
                }
            }

            case ExpressionType.MemberAccess:
            {
                var memberExpression = (MemberExpression)expr;
                var member           = memberExpression.Member;

                DefaultExpressionConverterFactory.ExpressionMappingDelegate <MemberExpression> memberAccessMapping;
                if (expressionConverterFactory.TryGetMemberAccessMapping(member, out memberAccessMapping))
                {
                    return(memberAccessMapping(memberExpression, RecursiveMap, datumConverterFactory, expressionConverterFactory));
                }

                Term serverSideTerm;
                if (ServerSideMemberAccess(datumConverterFactory, memberExpression, out serverSideTerm))
                {
                    return(serverSideTerm);
                }

                return(AttemptClientSideConversion(datumConverterFactory, expr));
            }

            case ExpressionType.Conditional:
            {
                var conditionalExpression = (ConditionalExpression)expr;
                return(new Term()
                    {
                        type = Term.TermType.BRANCH,
                        args =
                        {
                            RecursiveMap(conditionalExpression.Test),
                            RecursiveMap(conditionalExpression.IfTrue),
                            RecursiveMap(conditionalExpression.IfFalse)
                        }
                    });
            }

            case ExpressionType.Convert:
            {
                // The use-case for this right now is automatic boxing that occurs when setting a Dictionary<string,object>'s value
                // to a primitive.  In that particular case, we don't actually need to generate any ReQL for the conversion, so we're
                // just ignoring the Convert and mapping the expression inside.  Might need other behavior here in the future...
                return(RecursiveMap(((UnaryExpression)expr).Operand));
            }

            case ExpressionType.MemberInit:
            {
                var memberInit = (MemberInitExpression)expr;
                var memberType = memberInit.Type;

                IDatumConverter datumConverter;
                if (!datumConverterFactory.TryGet(memberType, out datumConverter))
                {
                    return(AttemptClientSideConversion(datumConverterFactory, expr));
                }

                var fieldConverter = datumConverter as IObjectDatumConverter;
                if (fieldConverter == null)
                {
                    return(AttemptClientSideConversion(datumConverterFactory, expr));
                }

                var makeObjTerm = new Term()
                {
                    type = Term.TermType.MAKE_OBJ,
                };

                foreach (var binding in memberInit.Bindings)
                {
                    switch (binding.BindingType)
                    {
                    case MemberBindingType.Assignment:
                    {
                        var memberAssignment = (MemberAssignment)binding;
                        var pair             = new Term.AssocPair();

                        pair.key = fieldConverter.GetDatumFieldName(memberAssignment.Member);
                        pair.val = RecursiveMap(memberAssignment.Expression);

                        if (pair.key == null)
                        {
                            throw new NotSupportedException("Cannot map member assignments into ReQL without implementing IObjectDatumConverter");
                        }


                        makeObjTerm.optargs.Add(pair);
                        break;
                    }

                    case MemberBindingType.ListBinding:
                    case MemberBindingType.MemberBinding:
                        throw new NotSupportedException("Binding type not currently supported");
                    }
                }

                return(makeObjTerm);
            }

            default:
            {
                return(AttemptClientSideConversion(datumConverterFactory, expr));
            }
            }
        }