コード例 #1
0
ファイル: AvgReduction.cs プロジェクト: mands/rethinkdb-net
        private string GetMemberName(IDatumConverterFactory datumConverterFactory)
        {
            var datumConverter = datumConverterFactory.Get <TObject>();
            var fieldConverter = datumConverter as IObjectDatumConverter;

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

            if (numericMemberReference.NodeType != ExpressionType.Lambda)
            {
                throw new NotSupportedException("Unsupported expression type " + numericMemberReference.Type + "; expected Lambda");
            }

            var body = ((LambdaExpression)numericMemberReference).Body;
            MemberExpression memberExpr;

            if (body.NodeType == ExpressionType.MemberAccess)
            {
                memberExpr = (MemberExpression)body;
            }
            else
            {
                throw new NotSupportedException("Unsupported expression type " + body.NodeType + "; expected MemberAccess");
            }

            if (memberExpr.Expression.NodeType != ExpressionType.Parameter)
            {
                throw new NotSupportedException("Unrecognized member access pattern");
            }

            return(fieldConverter.GetDatumFieldName(memberExpr.Member));
        }
コード例 #2
0
        public Term GenerateTerm(IDatumConverterFactory datumConverterFactory)
        {
            var getAllTerm = new Term()
            {
                type = Term.TermType.GET_ALL,
            };

            getAllTerm.args.Add(tableTerm.GenerateTerm(datumConverterFactory));
            getAllTerm.args.Add(new Term()
            {
                type  = Term.TermType.DATUM,
                datum = datumConverterFactory.Get <TKey>().ConvertObject(key)
            });
            if (!String.IsNullOrEmpty(indexName))
            {
                getAllTerm.optargs.Add(new Term.AssocPair()
                {
                    key = "index",
                    val = new Term()
                    {
                        type  = Term.TermType.DATUM,
                        datum = new Datum()
                        {
                            type  = Datum.DatumType.R_STR,
                            r_str = indexName
                        },
                    }
                });
            }
            return(getAllTerm);
        }
コード例 #3
0
ファイル: GroupByQuery.cs プロジェクト: mands/rethinkdb-net
        private Datum GetMemberName(Expression memberReference, IDatumConverterFactory datumConverterFactory)
        {
            var datumConverter = datumConverterFactory.Get <TObject>();
            var fieldConverter = datumConverter as IObjectDatumConverter;

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

            MemberExpression memberExpr;

            if (memberReference.NodeType == ExpressionType.MemberAccess)
            {
                memberExpr = (MemberExpression)memberReference;
            }
            else
            {
                throw new NotSupportedException("Unsupported expression type " + memberReference.NodeType + "; expected MemberAccess");
            }

            if (memberExpr.Expression.NodeType != ExpressionType.Parameter)
            {
                throw new NotSupportedException("Unrecognized member access pattern");
            }

            return(new Datum()
            {
                type = Datum.DatumType.R_STR,
                r_str = fieldConverter.GetDatumFieldName(memberExpr.Member)
            });
        }
コード例 #4
0
        public Term GenerateTerm(IDatumConverterFactory datumConverterFactory)
        {
            var retval = new Term()
            {
                type = Term.TermType.GROUPED_MAP_REDUCE,
            };

            retval.args.Add(sequenceQuery.GenerateTerm(datumConverterFactory));
            retval.args.Add(ExpressionUtils.CreateFunctionTerm(datumConverterFactory, grouping));
            retval.args.Add(ExpressionUtils.CreateFunctionTerm(datumConverterFactory, mapping));
            retval.args.Add(ExpressionUtils.CreateFunctionTerm(datumConverterFactory, reduction));

            if (this.baseProvided)
            {
                retval.optargs.Add(new Term.AssocPair()
                {
                    key = "base",
                    val = new Term()
                    {
                        type  = Term.TermType.DATUM,
                        datum = datumConverterFactory.Get <TMap>().ConvertObject(@base)
                    }
                });
            }

            return(retval);
        }
コード例 #5
0
ファイル: ReduceQuery.cs プロジェクト: mands/rethinkdb-net
        public Term GenerateTerm(IDatumConverterFactory datumConverterFactory)
        {
            var reduceTerm = new Term()
            {
                type = Term.TermType.REDUCE,
            };

            reduceTerm.args.Add(sequenceQuery.GenerateTerm(datumConverterFactory));
            reduceTerm.args.Add(ExpressionUtils.CreateFunctionTerm <T, T, T>(datumConverterFactory, reduceFunction));

            if (this.baseProvided)
            {
                reduceTerm.optargs.Add(new Term.AssocPair()
                {
                    key = "base",
                    val = new Term()
                    {
                        type  = Term.TermType.DATUM,
                        datum = datumConverterFactory.Get <T>().ConvertObject(@base)
                    }
                });
            }

            return(reduceTerm);
        }
コード例 #6
0
        public async Task <T> RunAsync <T>(IDatumConverterFactory datumConverterFactory, IScalarQuery <T> queryObject, CancellationToken cancellationToken)
        {
            var query = new Spec.Query();

            query.token = GetNextToken();
            query.type  = Spec.Query.QueryType.START;
            query.query = queryObject.GenerateTerm(datumConverterFactory);

            var response = await InternalRunQuery(query, cancellationToken);

            switch (response.type)
            {
            case Response.ResponseType.SUCCESS_SEQUENCE:
            case Response.ResponseType.SUCCESS_ATOM:
                if (response.response.Count != 1)
                {
                    throw new RethinkDbRuntimeException(String.Format("Expected 1 object, received {0}", response.response.Count));
                }
                return(datumConverterFactory.Get <T>().ConvertDatum(response.response[0]));

            case Response.ResponseType.CLIENT_ERROR:
            case Response.ResponseType.COMPILE_ERROR:
                throw new RethinkDbInternalErrorException("Client error: " + response.response[0].r_str);

            case Response.ResponseType.RUNTIME_ERROR:
                throw new RethinkDbRuntimeException("Runtime error: " + response.response[0].r_str);

            default:
                throw new RethinkDbInternalErrorException("Unhandled response type: " + response.type);
            }
        }
コード例 #7
0
        public Term GenerateTerm(IDatumConverterFactory datumConverterFactory)
        {
            var replaceTerm = new Term()
            {
                type = Term.TermType.REPLACE,
            };

            replaceTerm.args.Add(getTerm.GenerateTerm(datumConverterFactory));
            replaceTerm.args.Add(new Term()
            {
                type  = Term.TermType.DATUM,
                datum = datumConverterFactory.Get <T>().ConvertObject(newObject)
            });

            AddOptionalArguments(replaceTerm);
            if (nonAtomic)
            {
                replaceTerm.optargs.Add(new Term.AssocPair()
                {
                    key = "non_atomic",
                    val = new Term()
                    {
                        type  = Term.TermType.DATUM,
                        datum = new Datum()
                        {
                            type   = Datum.DatumType.R_BOOL,
                            r_bool = nonAtomic
                        }
                    }
                });
            }

            return(replaceTerm);
        }
コード例 #8
0
 public static IDatumConverter Get(this IDatumConverterFactory datumConverterFactory, Type datumType)
 {
     if (datumConverterFactory == null)
     {
         throw new ArgumentNullException("datumConverterFactory");
     }
     return(datumConverterFactory.Get(datumType, datumConverterFactory));
 }
コード例 #9
0
 public static IDatumConverter <T> Get <T>(this IDatumConverterFactory datumConverterFactory)
 {
     if (datumConverterFactory == null)
     {
         throw new ArgumentNullException("datumConverterFactory");
     }
     return(datumConverterFactory.Get <T>(datumConverterFactory));
 }
コード例 #10
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);
        }
コード例 #11
0
 public QueryEnumerator(Connection connection, IDatumConverterFactory datumConverterFactory, ISequenceQuery <T> queryObject)
 {
     this.connection            = connection;
     this.datumConverterFactory = datumConverterFactory;
     this.datumConverter        = datumConverterFactory.Get <T>();
     this.queryObject           = queryObject;
     this.stackTrace            = new StackTrace(true);
 }
コード例 #12
0
            public TupleConverter(IDatumConverterFactory rootDatumConverterFactory)
            {
                var typeArguments = typeof(T).GetGenericArguments();

                tupleConstructor = typeof(T).GetConstructor(typeArguments);
                itemConverters   = new IDatumConverter[typeArguments.Length];
                for (int i = 0; i < typeArguments.Length; i++)
                {
                    itemConverters[i] = rootDatumConverterFactory.Get(typeArguments[i]);
                }
            }
コード例 #13
0
        public override Object ConvertDatum(Spec.Datum datum)
        {
            if (datum.type == Datum.DatumType.R_NULL)
            {
                return(null);
            }

            Type valueType      = rootDatumConverterFactory.GetBestNativeTypeForDatum(datum);
            var  valueConverter = rootDatumConverterFactory.Get(valueType);

            return(valueConverter.ConvertDatum(datum));
        }
コード例 #14
0
            public AnonymousTypeConverter(IDatumConverterFactory innerTypeConverterFactory)
            {
                typeConstructor = typeof(T).GetConstructors()[0];

                properties = new List <PropertyInfo>();
                foreach (var property in typeof(T).GetProperties())
                {
                    var pi = new PropertyInfo();
                    pi.Name           = property.Name;
                    pi.Index          = properties.Count;
                    pi.DatumConverter = innerTypeConverterFactory.Get(property.PropertyType);
                    pi.GetMethod      = property.GetGetMethod();
                    properties.Add(pi);
                }
            }
コード例 #15
0
 public Term GenerateTerm(IDatumConverterFactory datumConverterFactory)
 {
     if (objectExpr != null)
     {
         return(ExpressionUtils.CreateValueTerm <T>(datumConverterFactory, objectExpr));
     }
     else
     {
         var datumTerm = new Term()
         {
             type  = Term.TermType.DATUM,
             datum = datumConverterFactory.Get <T>().ConvertObject(@object)
         };
         return(datumTerm);
     }
 }
コード例 #16
0
        private IEnumerable <Term> GetMembers(IDatumConverterFactory datumConverterFactory)
        {
            var datumConverter = datumConverterFactory.Get <T>();
            var fieldConverter = datumConverter as IObjectDatumConverter;

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

            foreach (var memberReferenceExpression in fields)
            {
                if (memberReferenceExpression.NodeType != ExpressionType.Lambda)
                {
                    throw new NotSupportedException("Unsupported expression type " + memberReferenceExpression.Type + "; expected Lambda");
                }

                var body = memberReferenceExpression.Body;
                MemberExpression memberExpr;

                if (body.NodeType == ExpressionType.MemberAccess)
                {
                    memberExpr = (MemberExpression)body;
                }
                else
                {
                    throw new NotSupportedException("Unsupported expression type " + body.NodeType + "; expected MemberAccess or Call");
                }

                if (memberExpr.Expression.NodeType != ExpressionType.Parameter)
                {
                    throw new NotSupportedException("Unrecognized member access pattern");
                }

                var fieldReference = new Term()
                {
                    type  = Term.TermType.DATUM,
                    datum = new Datum()
                    {
                        type  = Datum.DatumType.R_STR,
                        r_str = fieldConverter.GetDatumFieldName(memberExpr.Member)
                    }
                };

                yield return(fieldReference);
            }
        }
コード例 #17
0
 private Term AttemptClientSideConversion(IDatumConverterFactory datumConverterFactory, Expression expr)
 {
     try
     {
         var converter      = datumConverterFactory.Get(expr.Type);
         var clientSideFunc = Expression.Lambda(expr).Compile();
         return(new Term()
         {
             type = Term.TermType.DATUM,
             datum = converter.ConvertObject(clientSideFunc.DynamicInvoke())
         });
     }
     catch (InvalidOperationException ex)
     {
         throw new InvalidOperationException("Failed to perform client-side evaluation of expression tree node; often this is caused by refering to a server-side variable in a node that is only supported w/ client-side evaluation", ex);
     }
 }
コード例 #18
0
        public Term GenerateTerm(IDatumConverterFactory datumConverterFactory)
        {
            var insertTerm = new Term()
            {
                type = Term.TermType.INSERT,
            };

            insertTerm.args.Add(tableTerm.GenerateTerm(datumConverterFactory));

            var objectArray = new Datum()
            {
                type = Datum.DatumType.R_ARRAY,
            };
            var converter = datumConverterFactory.Get <T>();

            foreach (var obj in objects)
            {
                objectArray.r_array.Add(converter.ConvertObject(obj));
            }
            insertTerm.args.Add(new Term()
            {
                type  = Term.TermType.DATUM,
                datum = objectArray,
            });

            if (upsert)
            {
                insertTerm.optargs.Add(new Term.AssocPair()
                {
                    key = "upsert",
                    val = new Term()
                    {
                        type  = Term.TermType.DATUM,
                        datum = new Datum()
                        {
                            type   = Datum.DatumType.R_BOOL,
                            r_bool = upsert,
                        }
                    }
                });
            }

            return(insertTerm);
        }
コード例 #19
0
        public Term GenerateTerm(IDatumConverterFactory datumConverterFactory)
        {
            var sequenceTerm = new Term()
            {
                type = Term.TermType.MAKE_ARRAY,
            };

            foreach (var obj in enumerable)
            {
                var datumTerm = new Term()
                {
                    type  = Term.TermType.DATUM,
                    datum = datumConverterFactory.Get <T>().ConvertObject(obj)
                };
                sequenceTerm.args.Add(datumTerm);
            }

            return(sequenceTerm);
        }
コード例 #20
0
            public override Datum ConvertObject(CompoundIndexKey compoundIndexKey)
            {
                if (compoundIndexKey == null)
                {
                    return new Datum {
                               type = Datum.DatumType.R_NULL
                    }
                }
                ;

                var retval = new Datum {
                    type = Datum.DatumType.R_ARRAY
                };

                foreach (var key in compoundIndexKey.KeyValues)
                {
                    var converter = rootDatumConverterFactory.Get(key.GetType());

                    retval.r_array.Add(converter.ConvertObject(key));
                }

                return(retval);
            }
        }
コード例 #21
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.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));
                }
                else
                {
                    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)
                        }
                    });
            }

            default:
            {
                return(AttemptClientSideConversion(datumConverterFactory, expr));
            }
            }
        }
コード例 #22
0
ファイル: BaseExpression.cs プロジェクト: mands/rethinkdb-net
        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:
                return(ConvertBinaryExpressionToTerm((BinaryExpression)expr, Term.TermType.ADD));

            case ExpressionType.Modulo:
                return(ConvertBinaryExpressionToTerm((BinaryExpression)expr, Term.TermType.MOD));

            case ExpressionType.Divide:
                return(ConvertBinaryExpressionToTerm((BinaryExpression)expr, Term.TermType.DIV));

            case ExpressionType.Multiply:
                return(ConvertBinaryExpressionToTerm((BinaryExpression)expr, Term.TermType.MUL));

            case ExpressionType.Subtract:
                return(ConvertBinaryExpressionToTerm((BinaryExpression)expr, Term.TermType.SUB));

            case ExpressionType.Equal:
                return(ConvertBinaryExpressionToTerm((BinaryExpression)expr, Term.TermType.EQ));

            case ExpressionType.LessThan:
                return(ConvertBinaryExpressionToTerm((BinaryExpression)expr, Term.TermType.LT));

            case ExpressionType.LessThanOrEqual:
                return(ConvertBinaryExpressionToTerm((BinaryExpression)expr, Term.TermType.LE));

            case ExpressionType.GreaterThan:
                return(ConvertBinaryExpressionToTerm((BinaryExpression)expr, Term.TermType.GT));

            case ExpressionType.GreaterThanOrEqual:
                return(ConvertBinaryExpressionToTerm((BinaryExpression)expr, Term.TermType.GE));

            case ExpressionType.AndAlso:
                return(ConvertBinaryExpressionToTerm((BinaryExpression)expr, Term.TermType.ALL));

            case ExpressionType.OrElse:
                return(ConvertBinaryExpressionToTerm((BinaryExpression)expr, Term.TermType.ANY));

            case ExpressionType.NotEqual:
                return(ConvertBinaryExpressionToTerm((BinaryExpression)expr, Term.TermType.NE));

            case ExpressionType.Not:
                return(ConvertUnaryExpressionToTerm((UnaryExpression)expr, Term.TermType.NOT));

            case ExpressionType.ArrayLength:
                return(ConvertUnaryExpressionToTerm((UnaryExpression)expr, Term.TermType.COUNT));

            case ExpressionType.New:
            {
                var newExpression = (NewExpression)expr;
                if (!AnonymousTypeDatumConverterFactory.Instance.IsTypeSupported(newExpression.Type))
                {
                    return(AttemptClientSideConversion(datumConverterFactory, expr));
                }

                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);
            }

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

                if (method.IsGenericMethod && method.GetGenericMethodDefinition() == ReQLAppend.Value)
                {
                    var target = callExpression.Arguments[0];

                    var appendArray = callExpression.Arguments[1];
                    if (appendArray.NodeType != ExpressionType.NewArrayInit)
                    {
                        throw new NotSupportedException(String.Format("Expected second arg to ReQLExpression.Append to be NewArrayInit, but was: {0}", appendArray.NodeType));
                    }

                    var newArrayExpression = (NewArrayExpression)appendArray;
                    var term = RecursiveMap(target);
                    foreach (var datumExpression in newArrayExpression.Expressions)
                    {
                        var newTerm = new Term()
                        {
                            type = Term.TermType.APPEND
                        };
                        newTerm.args.Add(term);

                        if (datumExpression.NodeType == ExpressionType.MemberInit)
                        {
                            var memberInit = (MemberInitExpression)datumExpression;

                            var recursiveMapMethod = typeof(BaseExpression).GetMethod("RecursiveMapMemberInit", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                            recursiveMapMethod = recursiveMapMethod.MakeGenericMethod(new Type[] { memberInit.Type });
                            newTerm.args.Add((Term)recursiveMapMethod.Invoke(this, new object[] { memberInit }));
                        }
                        else
                        {
                            throw new NotSupportedException(String.Format("Expected ReQLExpression.Append to contain MemberInit additions, but was: {0}", datumExpression.NodeType));
                        }

                        term = newTerm;
                    }

                    return(term);
                }
                else if (method.IsGenericMethod && method.GetGenericMethodDefinition() == EnumerableWhereWithSimplePredicate.Value)
                {
                    var target    = callExpression.Arguments[0];
                    var predicate = callExpression.Arguments[1];

                    var filterTerm = new Term()
                    {
                        type = Term.TermType.FILTER
                    };

                    filterTerm.args.Add(RecursiveMap(target));

                    var enumerableElementType    = method.ReturnType.GetGenericArguments()[0];
                    var createFunctionTermMethod = typeof(ExpressionUtils)
                                                   .GetMethods(BindingFlags.Public | BindingFlags.Static)
                                                   .Single(m => m.Name == "CreateFunctionTerm" &&
                                                           m.GetGenericArguments().Length == 2);
                    createFunctionTermMethod = createFunctionTermMethod.MakeGenericMethod(enumerableElementType, typeof(bool));

                    var functionTerm = (Term)createFunctionTermMethod.Invoke(null, new object[] { datumConverterFactory, predicate });
                    filterTerm.args.Add(functionTerm);

                    return(filterTerm);
                }
                else if (method.IsGenericMethod && method.GetGenericMethodDefinition() == EnumerableCountWithNoPredicate.Value)
                {
                    var target = callExpression.Arguments[0];

                    var countTerm = new Term()
                    {
                        type = Term.TermType.COUNT,
                    };
                    countTerm.args.Add(RecursiveMap(target));
                    return(countTerm);
                }
                else if (method == DateTimeAddTimeSpan.Value)
                {
                    var addTerm = new Term()
                    {
                        type = Term.TermType.ADD,
                    };
                    addTerm.args.Add(RecursiveMap(callExpression.Object));
                    addTerm.args.Add(RecursiveMap(callExpression.Arguments[0]));
                    return(addTerm);
                }
                else if (method == DateTimeAddMinutes.Value)
                {
                    return(ConvertDateTimeAddFunctionToTerm(callExpression, TimeSpan.TicksPerMinute / TimeSpan.TicksPerSecond));
                }
                else if (method == DateTimeAddHours.Value)
                {
                    return(ConvertDateTimeAddFunctionToTerm(callExpression, TimeSpan.TicksPerHour / TimeSpan.TicksPerSecond));
                }
                else if (method == DateTimeAddMilliseconds.Value)
                {
                    return(ConvertDateTimeAddFunctionToTerm(callExpression, (double)TimeSpan.TicksPerMillisecond / TimeSpan.TicksPerSecond));
                }
                else if (method == DateTimeAddSeconds.Value)
                {
                    return(ConvertDateTimeAddFunctionToTerm(callExpression, 1));
                }
                else if (method == DateTimeAddTicks.Value)
                {
                    return(ConvertDateTimeAddFunctionToTerm(callExpression, 1.0 / TimeSpan.TicksPerSecond));
                }
                else if (method == DateTimeAddDays.Value)
                {
                    return(ConvertDateTimeAddFunctionToTerm(callExpression, TimeSpan.TicksPerDay / TimeSpan.TicksPerSecond));
                }
                else if (method == DateTimeOffsetAddTimeSpan.Value)
                {
                    var addTerm = new Term()
                    {
                        type = Term.TermType.ADD,
                    };
                    addTerm.args.Add(RecursiveMap(callExpression.Object));
                    addTerm.args.Add(RecursiveMap(callExpression.Arguments[0]));
                    return(addTerm);
                }
                else if (method == DateTimeOffsetAddMinutes.Value)
                {
                    return(ConvertDateTimeAddFunctionToTerm(callExpression, TimeSpan.TicksPerMinute / TimeSpan.TicksPerSecond));
                }
                else if (method == DateTimeOffsetAddHours.Value)
                {
                    return(ConvertDateTimeAddFunctionToTerm(callExpression, TimeSpan.TicksPerHour / TimeSpan.TicksPerSecond));
                }
                else if (method == DateTimeOffsetAddMilliseconds.Value)
                {
                    return(ConvertDateTimeAddFunctionToTerm(callExpression, (double)TimeSpan.TicksPerMillisecond / TimeSpan.TicksPerSecond));
                }
                else if (method == DateTimeOffsetAddSeconds.Value)
                {
                    return(ConvertDateTimeAddFunctionToTerm(callExpression, 1));
                }
                else if (method == DateTimeOffsetAddTicks.Value)
                {
                    return(ConvertDateTimeAddFunctionToTerm(callExpression, 1.0 / TimeSpan.TicksPerSecond));
                }
                else if (method == DateTimeOffsetAddDays.Value)
                {
                    return(ConvertDateTimeAddFunctionToTerm(callExpression, TimeSpan.TicksPerDay / TimeSpan.TicksPerSecond));
                }
                else
                {
                    return(AttemptClientSideConversion(datumConverterFactory, expr));
                }
            }

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

                if (member.DeclaringType.IsGenericType &&
                    (
                        member.DeclaringType.GetGenericTypeDefinition() == typeof(List <>) ||
                        member.DeclaringType.GetGenericTypeDefinition() == typeof(ICollection <>) ||
                        member.DeclaringType.GetGenericTypeDefinition() == typeof(Microsoft.FSharp.Collections.FSharpList <>)
                    ) &&
                    (member.Name == "Count" || member.Name == "Length"))
                {
                    var countTerm = new Term()
                    {
                        type = Term.TermType.COUNT,
                    };
                    countTerm.args.Add(RecursiveMap(memberExpression.Expression));
                    return(countTerm);
                }
                else
                {
                    return(AttemptClientSideConversion(datumConverterFactory, expr));
                }
            }

            default:
            {
                return(AttemptClientSideConversion(datumConverterFactory, expr));
            }
            }
        }
コード例 #23
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.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);
                }

                default:
                {
                    return AttemptClientSideConversion(datumConverterFactory, expr);
                }
            }
        }
コード例 #24
0
 private Term AttemptClientSideConversion(IDatumConverterFactory datumConverterFactory, Expression expr)
 {
     try
     {
         var converter = datumConverterFactory.Get(expr.Type);
         var clientSideFunc = Expression.Lambda(expr).Compile();
         return new Term() {
             type = Term.TermType.DATUM,
             datum = converter.ConvertObject(clientSideFunc.DynamicInvoke())
         };
     }
     catch (InvalidOperationException ex)
     {
         throw new InvalidOperationException(
             String.Format(
                 "Failed to perform client-side evaluation of expression tree node '{0}'; this is caused by refering to a server-side variable in an expression tree that isn't convertible to ReQL logic",
                 expr),
             ex);
     }
 }
コード例 #25
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);
                }
            }
        }
コード例 #26
0
 public NullableDatumConverter(IDatumConverterFactory rootDatumConverterFactory)
 {
     this.innerConverter = rootDatumConverterFactory.Get <T>(rootDatumConverterFactory);
 }
コード例 #27
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.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));
            }

            default:
            {
                return(AttemptClientSideConversion(datumConverterFactory, expr));
            }
            }
        }
コード例 #28
0
        public Term GenerateTerm(IDatumConverterFactory datumConverterFactory)
        {
            var datumConverter = datumConverterFactory.Get <TKey>();
            var betweenTerm    = new Term()
            {
                type = Term.TermType.BETWEEN,
            };

            betweenTerm.args.Add(tableTerm.GenerateTerm(datumConverterFactory));
            betweenTerm.args.Add(new Term()
            {
                type  = Term.TermType.DATUM,
                datum = datumConverter.ConvertObject(leftKey)
            });
            betweenTerm.args.Add(new Term()
            {
                type  = Term.TermType.DATUM,
                datum = datumConverter.ConvertObject(rightKey)
            });
            if (!String.IsNullOrEmpty(indexName))
            {
                betweenTerm.optargs.Add(new Term.AssocPair()
                {
                    key = "index",
                    val = new Term()
                    {
                        type  = Term.TermType.DATUM,
                        datum = new Datum()
                        {
                            type  = Datum.DatumType.R_STR,
                            r_str = indexName
                        },
                    }
                });
            }
            if (leftBound != Bound.Closed)
            {
                betweenTerm.optargs.Add(new Term.AssocPair()
                {
                    key = "left_bound",
                    val = new Term()
                    {
                        type  = Term.TermType.DATUM,
                        datum = new Datum()
                        {
                            type  = Datum.DatumType.R_STR,
                            r_str = "open"
                        },
                    }
                });
            }
            if (rightBound != Bound.Open)
            {
                betweenTerm.optargs.Add(new Term.AssocPair()
                {
                    key = "right_bound",
                    val = new Term()
                    {
                        type  = Term.TermType.DATUM,
                        datum = new Datum()
                        {
                            type  = Datum.DatumType.R_STR,
                            r_str = "closed"
                        },
                    }
                });
            }
            return(betweenTerm);
        }
 public NamedValueDictionaryKeysDatumConverter(IDatumConverterFactory rootDatumConverterFactory)
 {
     arrayDatumConverter = rootDatumConverterFactory.Get <string[]>();
 }
コード例 #30
0
ファイル: OrderByQuery.cs プロジェクト: mands/rethinkdb-net
        private IEnumerable <Term> GetMembers(IDatumConverterFactory datumConverterFactory, out Term indexOrderBy)
        {
            var datumConverter = datumConverterFactory.Get <T>();
            var fieldConverter = datumConverter as IObjectDatumConverter;

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

            indexOrderBy = null;
            List <Term> retval = new List <Term>(orderByMembers.Length);

            foreach (var orderByMember in orderByMembers)
            {
                var memberReferenceExpression = orderByMember.Expression;
                var direction = orderByMember.Direction;

                if (!String.IsNullOrEmpty(orderByMember.IndexName))
                {
                    if (indexOrderBy != null)
                    {
                        throw new InvalidOperationException("Sorting by multiple indexes is not supported");
                    }

                    var indexReference = new Term()
                    {
                        type  = Term.TermType.DATUM,
                        datum = new Datum()
                        {
                            type  = Datum.DatumType.R_STR,
                            r_str = orderByMember.IndexName
                        }
                    };
                    if (direction == OrderByDirection.Ascending)
                    {
                        var newFieldRef = new Term()
                        {
                            type = Term.TermType.ASC,
                        };
                        newFieldRef.args.Add(indexReference);
                        indexOrderBy = newFieldRef;
                    }
                    else if (direction == OrderByDirection.Descending)
                    {
                        var newFieldRef = new Term()
                        {
                            type = Term.TermType.DESC,
                        };
                        newFieldRef.args.Add(indexReference);
                        indexOrderBy = newFieldRef;
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }
                }
                else
                {
                    if (memberReferenceExpression.NodeType != ExpressionType.Lambda)
                    {
                        throw new NotSupportedException("Unsupported expression type " + memberReferenceExpression.Type + "; expected Lambda");
                    }

                    var body = memberReferenceExpression.Body;
                    MemberExpression memberExpr;

                    if (body.NodeType == ExpressionType.Convert)
                    {
                        // If we're order-bying a primitive, the expr will be a cast to object for the Asc/Desc method call
                        if (body.Type == typeof(object))
                        {
                            body = ((UnaryExpression)body).Operand;
                        }
                    }

                    if (body.NodeType == ExpressionType.MemberAccess)
                    {
                        memberExpr = (MemberExpression)body;
                    }
                    else
                    {
                        throw new NotSupportedException("Unsupported expression type " + body.NodeType + "; expected MemberAccess or Call");
                    }

                    if (memberExpr.Expression.NodeType != ExpressionType.Parameter)
                    {
                        throw new NotSupportedException("Unrecognized member access pattern");
                    }

                    var fieldReference = new Term()
                    {
                        type  = Term.TermType.DATUM,
                        datum = new Datum()
                        {
                            type  = Datum.DatumType.R_STR,
                            r_str = fieldConverter.GetDatumFieldName(memberExpr.Member)
                        }
                    };

                    if (direction == OrderByDirection.Ascending)
                    {
                        var newFieldRef = new Term()
                        {
                            type = Term.TermType.ASC,
                        };
                        newFieldRef.args.Add(fieldReference);
                        fieldReference = newFieldRef;
                    }
                    else if (direction == OrderByDirection.Descending)
                    {
                        var newFieldRef = new Term()
                        {
                            type = Term.TermType.DESC,
                        };
                        newFieldRef.args.Add(fieldReference);
                        fieldReference = newFieldRef;
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }

                    retval.Add(fieldReference);
                }
            }

            return(retval);
        }
コード例 #31
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.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);
                    else
                        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)
                        }
                    };
                }

                default:
                {
                    return AttemptClientSideConversion(datumConverterFactory, expr);
                }
            }
        }
コード例 #32
0
 public ArrayDatumConverter(IDatumConverterFactory rootDatumConverterFactory)
 {
     this.arrayTypeConverter = rootDatumConverterFactory.Get(typeof(T).GetElementType());
 }
 public GroupingDictionaryDatumConverter(IDatumConverterFactory rootDatumConverterFactory)
 {
     this.keyTypeConverter   = rootDatumConverterFactory.Get <TKey>();
     this.valueTypeConverter = rootDatumConverterFactory.Get <TValue>();
 }