コード例 #1
0
        private static string ComputeNewObject(Expression predicate, RequestBuilderConfiguration configuration)
        {
            var newPredicate = (predicate as NewExpression);

            var properties = newPredicate.Arguments.Select(a => ComputeMemberAccess(a, configuration));

            return(string.Join(",", properties));
        }
コード例 #2
0
 /// <summary>
 /// Converts fields case depending on configuration provided
 /// </summary>
 /// <param name="fieldName"></param>
 /// <param name="configuration"></param>
 /// <returns></returns>
 public static string Run(string fieldName, RequestBuilderConfiguration configuration)
 {
     return(configuration.CaseContract switch
     {
         CaseContract.SnakeCase => fieldName.ToSnakeCase(),
         CaseContract.PascalCase => fieldName.ToPascalCase(),
         CaseContract.CamelCase => fieldName.ToCamelCase(),
         _ => fieldName
     });
コード例 #3
0
        /// <summary>
        /// Interprets a list of fields and add to each of them a "desc" sort modificator
        /// </summary>
        /// <param name="predicate"></param>
        /// <param name="configuration"></param>
        /// <returns></returns>
        public static string Run(Expression predicate, RequestBuilderConfiguration configuration)
        {
            if (predicate is null)
            {
                throw new ArgumentNullException(nameof(predicate));
            }

            return(string.Join(",", MemberPredicateInterpreter.Run(predicate, configuration)
                               .Split(',').Select(s => s + " desc")));
        }
コード例 #4
0
        private static string UnrollMemberPath(MemberExpression predicate, RequestBuilderConfiguration configuration)
        {
            var path = "";

            if (predicate.Expression != null && predicate.Expression is MemberExpression)
            {
                path = UnrollMemberPath(predicate.Expression as MemberExpression, configuration) + ".";
            }

            return(path + FieldInterpreter.Run(predicate.Member.Name, configuration));
        }
 public void Setup()
 {
     snakeCaseConfiguration = new RequestBuilderConfiguration {
         CaseContract = CaseContract.SnakeCase
     };
     camelCaseConfiguration = new RequestBuilderConfiguration {
         CaseContract = CaseContract.CamelCase
     };
     pascalCaseConfiguration = new RequestBuilderConfiguration {
         CaseContract = CaseContract.PascalCase
     };
 }
コード例 #6
0
        /// <summary>
        /// Interprets the public properties of the generic type to generate a list of selects
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static string Run <T>(RequestBuilderConfiguration configuration)
        {
            var properties = typeof(T)
                             .GetProperties();

            var fields = new List <string>();

            foreach (var p in properties)
            {
                fields.Add(GetFields(p, configuration));
            }

            return(string.Join(",", fields.Where(f => !string.IsNullOrEmpty(f))));
        }
コード例 #7
0
        /// <summary>
        /// Assembles a request from the statements
        /// </summary>
        /// <param name="selects"></param>
        /// <param name="filters"></param>
        /// <param name="excludes"></param>
        /// <param name="orders"></param>
        /// <param name="search"></param>
        /// <param name="take"></param>
        /// <param name="skip"></param>
        /// <param name="configuration"></param>
        /// <returns></returns>
        public static string Run(
            string selects,
            string filters,
            string excludes,
            string orders,
            string search,
            int take,
            int skip,
            RequestBuilderConfiguration configuration
            )
        {
            if (string.IsNullOrEmpty(selects))
            {
                throw new ArgumentNullException(nameof(selects));
            }

            string body = $"fields {selects};";

            if (!string.IsNullOrEmpty(filters))
            {
                body += $"\nwhere {filters};";
            }

            if (!string.IsNullOrEmpty(excludes))
            {
                body += $"\nexclude {excludes};";
            }

            if (!string.IsNullOrEmpty(orders))
            {
                body += $"\nsort {orders};";
            }

            if (!string.IsNullOrEmpty(search))
            {
                body += $"\nsearch {search};";
            }

            if (take != default)
            {
                body += $"\nlimit {take.ToString(CultureInfo.InvariantCulture)};";
            }

            if (skip != default)
            {
                body += $"\noffset {skip.ToString(CultureInfo.InvariantCulture)};";
            }

            return(body);
        }
コード例 #8
0
        private static string ComputeMemberAccess(Expression predicate, RequestBuilderConfiguration configuration)
        {
            var memberExpression = (predicate as MemberExpression);

            switch (memberExpression.Member.MemberType)
            {
            case System.Reflection.MemberTypes.Property:
                var path = UnrollMemberPath(memberExpression, configuration);
                return(path);

            default:
                throw new NotImplementedException($"Works only with properties of the Generic object");
            }
        }
コード例 #9
0
        /// <summary>
        /// Returns a member or list of members as a string from a predicate
        /// </summary>
        /// <param name="predicate"></param>
        /// <param name="configuration"></param>
        /// <returns></returns>
        public static string Run(Expression predicate, RequestBuilderConfiguration configuration)
        {
            if (predicate is null)
            {
                throw new ArgumentNullException(nameof(predicate));
            }

            switch (predicate.NodeType)
            {
            case ExpressionType.MemberAccess:
                return(ComputeMemberAccess(predicate, configuration));

            case ExpressionType.New:
                return(ComputeNewObject(predicate, configuration));

            default:
                throw new Exception("Invalid predicate provided");
            }
        }
コード例 #10
0
        private static string GetFields(PropertyInfo property, RequestBuilderConfiguration configuration, string parentPath = "")
        {
            var fields = new List <string>();
            var path   = parentPath + FieldInterpreter.Run(property.Name, configuration);

            if (property.GetCustomAttribute <IncludeAttribute>() != null)
            {
                foreach (var p in property.PropertyType.GetProperties())
                {
                    fields.Add(GetFields(p, configuration, path + "."));
                }
            }
            else if (property.GetCustomAttribute <ExcludeAttribute>() == null)
            {
                fields.Add(path);
            }

            return(string.Join(",", fields));
        }
コード例 #11
0
        private static string ComputeConstant(Expression constant, RequestBuilderConfiguration configuration)
        {
            var value = (constant as ConstantExpression).Value;

            if (value is string)
            {
                return($"\"{(value as string).Replace("\"", "\\\"")}\"");
            }
            if (value is bool boolean)
            {
                return(boolean ? "true" : "false");
            }
            if (value is null)
            {
                return("null");
            }
            if (value is IConvertible)
            {
                return((value as IConvertible).ToString(CultureInfo.InvariantCulture));
            }

            return(value.ToString());
        }
コード例 #12
0
 private static string ComputeMemberAccess(Expression predicate, RequestBuilderConfiguration configuration)
 {
     return(MemberPredicateInterpreter.Run(predicate, configuration));
 }
コード例 #13
0
        /// <summary>
        /// Interpretes a predicate to convert it to a string usable by IGDB API
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public static string Run(Expression predicate, RequestBuilderConfiguration configuration, bool invert = false, ArrayPostfixMode arrayPostfixMode = ArrayPostfixMode.ContainsAny)
        {
            if (predicate is null)
            {
                throw new ArgumentNullException(nameof(predicate));
            }

            var binaryPredicate = predicate as BinaryExpression;

            switch (predicate.NodeType)
            {
            /*
             * First part of switch : binary operators
             * -------
             * if Node type referes to a binary operators we set the operator
             * and let the method continue after the switch to create the
             * expression.
             * binary operators are either logical operators (&& or ||),
             * relational operators (>, >=, <, <=) or equality operators (==, !=)
             */
            case ExpressionType.AndAlso:
                return(ComputeBinaryOperator(binaryPredicate.Left, binaryPredicate.Right, "&", configuration));

            case ExpressionType.OrElse:
                return(ComputeBinaryOperator(binaryPredicate.Left, binaryPredicate.Right, "|", configuration));

            case ExpressionType.GreaterThan:
                return(ComputeBinaryOperator(binaryPredicate.Left, binaryPredicate.Right, ">", configuration));

            case ExpressionType.GreaterThanOrEqual:
                return(ComputeBinaryOperator(binaryPredicate.Left, binaryPredicate.Right, ">=", configuration));

            case ExpressionType.LessThan:
                return(ComputeBinaryOperator(binaryPredicate.Left, binaryPredicate.Right, "<", configuration));

            case ExpressionType.LessThanOrEqual:
                return(ComputeBinaryOperator(binaryPredicate.Left, binaryPredicate.Right, "<=", configuration));

            case ExpressionType.NotEqual:
                return(ComputeBinaryOperator(binaryPredicate.Left, binaryPredicate.Right, "!=", configuration));

            case ExpressionType.Equal:
                return(ComputeBinaryOperator(binaryPredicate.Left, binaryPredicate.Right, "=", configuration));

            /*
             * Second part of switch : members
             * -------
             * If node type refers to a member, a constant or an array then
             * then return an interpretation.
             */
            case ExpressionType.MemberAccess:
                return(ComputeMemberAccess(predicate, configuration));

            case ExpressionType.Constant:
                return(ComputeConstant(predicate, configuration));

            case ExpressionType.NewArrayInit:
                return(ComputeArray(predicate, arrayPostfixMode, configuration));

            /*
             * Third part of switch : methods
             * -------
             * if node type referes to a method corresponding to
             */
            case ExpressionType.Not:
                return(ComputeNotCall(predicate, configuration));

            case ExpressionType.Call:
                return(ComputeMethodCall(predicate, configuration, invert));

            default:
                throw new InvalidPredicateException(predicate);
            }
        }
コード例 #14
0
        private static string ComputeArray(Expression array, ArrayPostfixMode arrayPostfixMode, RequestBuilderConfiguration configuration)
        {
            var list = string.Join(
                ",",
                (array as NewArrayExpression).Expressions.Select(e => Run(e as ConstantExpression, configuration))
                );

            return(arrayPostfixMode switch
            {
                ArrayPostfixMode.ContainsAny => $"({list})",
                ArrayPostfixMode.ContainsAll => $"[{list}]",
                ArrayPostfixMode.ExactMatch => $"{{{list}}}",
                _ => throw new Exception("Unknown array postfix mode"),
            });
コード例 #15
0
 public void Setup()
 {
     configuration = new RequestBuilderConfiguration {
         CaseContract = CaseContract.SnakeCase
     };
 }
コード例 #16
0
        private static string ComputeBinaryOperator(Expression left, Expression right, string binaryOperator, RequestBuilderConfiguration configuration)
        {
            var leftMember  = Run(left, configuration);
            var rightMember = Run(right, configuration);

            return($"{leftMember} {binaryOperator} {rightMember}");
        }
コード例 #17
0
 /// <summary>
 /// Constructor.
 /// </summary>
 public RequestBuilder(RequestBuilderConfiguration configuration)
 {
     selects            = "*";
     orders             = "";
     this.configuration = configuration;
 }